A music player that connects to your cloud/distributed storage.
at main 6.7 kB view raw
1module UI.Interface.State exposing (..) 2 3import Alfred 4import Debouncer.Basic as Debouncer 5import Maybe.Extra as Maybe 6import Notifications 7import Return exposing (return) 8import Return.Ext as Return 9import Theme 10import Tracks 11import UI.Alfred.State as Alfred 12import UI.Common.State as Common 13import UI.Common.Types exposing (DebounceManager) 14import UI.DnD as DnD 15import UI.Page as Page 16import UI.Playlists.State as Playlists 17import UI.Ports as Ports 18import UI.Queue.State as Queue 19import UI.Theme 20import UI.Types exposing (..) 21import UI.User.State.Export exposing (saveEnclosedUserData) 22 23 24 25-- 🔱 26 27 28assistWithChangingTheme : Manager 29assistWithChangingTheme model = 30 { action = 31 \{ result } -> 32 case result of 33 Just { value } -> 34 value 35 |> Alfred.command 36 |> Maybe.map List.singleton 37 |> Maybe.withDefault [] 38 39 Nothing -> 40 [] 41 , index = 42 [ { name = Just "Themes" 43 , items = 44 List.map 45 (\theme -> 46 { icon = Just (theme.icon 16) 47 , title = theme.title 48 , value = Alfred.Command (ChangeTheme { id = theme.id }) 49 } 50 ) 51 UI.Theme.list 52 } 53 ] 54 , message = "Choose a theme." 55 , operation = Alfred.Query 56 } 57 |> Alfred.create 58 |> (\a -> Alfred.assign a model) 59 60 61blur : Manager 62blur model = 63 Return.singleton { model | focusedOnInput = False, pressedKeys = [] } 64 65 66changeTheme : Theme.Id -> Manager 67changeTheme id model = 68 saveEnclosedUserData { model | theme = Just id } 69 70 71contextMenuConfirmation : String -> Msg -> Manager 72contextMenuConfirmation conf msg model = 73 return 74 { model | confirmation = Just conf } 75 (Return.task msg) 76 77 78copyToClipboard : String -> Manager 79copyToClipboard string = 80 string 81 |> Ports.copyToClipboard 82 |> Return.communicate 83 84 85resizeDebounce : DebounceManager 86resizeDebounce = 87 Common.debounce 88 .resizeDebouncer 89 (\d m -> { m | resizeDebouncer = d }) 90 ResizeDebounce 91 92 93dnd : DnD.Msg Int -> Manager 94dnd dragMsg model = 95 let 96 ( d, { initiated } ) = 97 DnD.update dragMsg model.dnd 98 99 m = 100 if initiated then 101 { model | dnd = d, isDragging = True } 102 103 else 104 { model | dnd = d } 105 in 106 if DnD.hasDropped d then 107 case m.page of 108 Page.Queue _ -> 109 let 110 ( from, to ) = 111 ( Maybe.withDefault 0 <| DnD.modelSubject d 112 , Maybe.withDefault 0 <| DnD.modelTarget d 113 ) 114 115 newFuture = 116 Queue.moveItem 117 { from = from, to = to, shuffle = m.shuffle } 118 m.playingNext 119 in 120 Queue.fill { m | playingNext = newFuture } 121 122 Page.Index -> 123 let 124 trackCanBeMoved = 125 not m.favouritesOnly && Maybe.isNothing m.searchTerm 126 in 127 case m.scene of 128 Tracks.Covers -> 129 -- TODO 130 Return.singleton m 131 132 Tracks.List -> 133 if trackCanBeMoved then 134 Playlists.moveTrackInSelected 135 { to = Maybe.withDefault 0 (DnD.modelTarget d) } 136 m 137 138 else 139 "Can't move tracks in a playlist whilst using favourites-only mode, or while searching." 140 |> Notifications.casual 141 |> Common.showNotificationWithModel m 142 143 _ -> 144 Return.singleton m 145 146 else 147 Return.singleton m 148 149 150focusedOnInput : Manager 151focusedOnInput model = 152 Return.singleton { model | focusedOnInput = True } 153 154 155hideOverlay : Manager 156hideOverlay model = 157 if Maybe.isJust model.contextMenu then 158 Return.singleton { model | contextMenu = Nothing } 159 160 else if Maybe.isJust model.confirmation then 161 Return.singleton { model | confirmation = Nothing } 162 163 else if Maybe.isJust model.alfred then 164 Return.singleton { model | alfred = Nothing } 165 166 else 167 Return.singleton model 168 169 170lostWindowFocus : Manager 171lostWindowFocus model = 172 Return.singleton { model | focusedOnInput = False, pressedKeys = [] } 173 174 175preferredColorSchemaChanged : { dark : Bool } -> Manager 176preferredColorSchemaChanged { dark } model = 177 Return.singleton { model | darkMode = dark } 178 179 180msgViaContextMenu : Msg -> Manager 181msgViaContextMenu msg model = 182 return 183 (case msg of 184 ContextMenuConfirmation _ _ -> 185 model 186 187 _ -> 188 { model | confirmation = Nothing, contextMenu = Nothing } 189 ) 190 (Return.task msg) 191 192 193removeNotification : { id : Int } -> Manager 194removeNotification { id } model = 195 model.notifications 196 |> List.filter (Notifications.id >> (/=) id) 197 |> (\n -> { model | notifications = n }) 198 |> Return.singleton 199 200 201removeQueueSelection : Manager 202removeQueueSelection model = 203 Return.singleton { model | selectedQueueItem = Nothing } 204 205 206removeTrackSelection : Manager 207removeTrackSelection model = 208 Return.singleton { model | selectedTrackIndexes = [] } 209 210 211resizedWindow : ( Int, Int ) -> Manager 212resizedWindow ( width, height ) model = 213 Return.singleton 214 { model 215 | contextMenu = Nothing 216 , viewport = { height = toFloat height, width = toFloat width } 217 } 218 219 220searchDebounce : DebounceManager 221searchDebounce = 222 Common.debounce 223 .searchDebouncer 224 (\d m -> { m | searchDebouncer = d }) 225 SearchDebounce 226 227 228setIsTouchDevice : Bool -> Manager 229setIsTouchDevice bool model = 230 Return.singleton { model | isTouchDevice = bool } 231 232 233stoppedDragging : Manager 234stoppedDragging model = 235 let 236 notDragging = 237 { model | isDragging = False } 238 in 239 -- Depending on where we stopped dragging something, 240 -- do the appropriate thing. 241 case model.page of 242 Page.Queue _ -> 243 dnd DnD.stoppedDragging notDragging 244 245 Page.Index -> 246 dnd DnD.stoppedDragging notDragging 247 248 _ -> 249 Return.singleton notDragging 250 251 252 253-- MESSAGES 254 255 256onResize : Int -> Int -> Msg 257onResize w h = 258 ( w, h ) 259 |> ResizedWindow 260 |> Debouncer.provideInput 261 |> ResizeDebounce