A music player that connects to your cloud/distributed storage.
1module UI.Common.State exposing (..)
2
3import Browser.Navigation as Nav
4import Common exposing (..)
5import ContextMenu exposing (ContextMenu)
6import Debouncer.Basic as Debouncer exposing (Debouncer)
7import List.Extra as List
8import Maybe.Extra as Maybe
9import Monocle.Lens as Lens exposing (Lens)
10import Notifications exposing (Notification)
11import Return exposing (return)
12import UI.Notifications
13import UI.Page as Page exposing (Page)
14import UI.Playlists.Directory
15import UI.Syncing.Types as Syncing
16import UI.Types as UI exposing (Manager, Model, Msg)
17import User.Layer exposing (Method)
18
19
20
21-- 📣
22
23
24changeUrlUsingPage : Page -> Manager
25changeUrlUsingPage page model =
26 page
27 |> Page.toString
28 |> Nav.pushUrl model.navKey
29 |> return model
30
31
32debounce : (Model -> Debouncer Msg Msg) -> (Debouncer Msg Msg -> Model -> Model) -> (Debouncer.Msg Msg -> Msg) -> (Msg -> Model -> ( Model, Cmd Msg )) -> Debouncer.Msg Msg -> Manager
33debounce getter setter debouncerMsgContainer update debouncerMsg model =
34 let
35 ( subModel, subCmd, emittedMsg ) =
36 Debouncer.update debouncerMsg (getter model)
37
38 mappedCmd =
39 Cmd.map debouncerMsgContainer subCmd
40
41 updatedModel =
42 setter subModel model
43 in
44 case emittedMsg of
45 Just emitted ->
46 updatedModel
47 |> update emitted
48 |> Return.command mappedCmd
49
50 Nothing ->
51 return updatedModel mappedCmd
52
53
54dismissNotification : { id : Int } -> Manager
55dismissNotification options model =
56 options
57 |> UI.Notifications.dismiss model.notifications
58 |> Return.map (\n -> { model | notifications = n })
59
60
61forceTracksRerender : Manager
62forceTracksRerender model =
63 --
64 -- TODO:
65 --
66 -- let
67 -- containerId =
68 -- case model.scene of
69 -- Tracks.Covers ->
70 -- UI.Tracks.Scene.Covers.containerId
71 -- Tracks.List ->
72 -- UI.Tracks.Scene.List.containerId
73 -- in
74 -- Browser.Dom.setViewportOf containerId 0 1
75 -- |> Task.attempt (always UI.Bypass)
76 -- |> return model
77 --
78 Return.singleton model
79
80
81generateDirectoryPlaylists : Manager
82generateDirectoryPlaylists model =
83 let
84 nonDirectoryPlaylists =
85 List.filterNot
86 (.autoGenerated >> Maybe.isJust)
87 model.playlists
88
89 directoryPlaylists =
90 UI.Playlists.Directory.generate
91 model.sources
92 model.tracks.untouched
93 in
94 [ nonDirectoryPlaylists
95 , directoryPlaylists
96 ]
97 |> List.concat
98 |> (\c -> { model | playlists = c })
99 |> Return.singleton
100
101
102showContextMenuWithModel : UI.Model -> ContextMenu Msg -> ( UI.Model, Cmd UI.Msg )
103showContextMenuWithModel model contextMenu =
104 Return.singleton { model | contextMenu = Just contextMenu }
105
106
107showNotification : Notification Msg -> Manager
108showNotification notification model =
109 model.notifications
110 |> UI.Notifications.show notification
111 |> Return.map (\n -> { model | notifications = n })
112
113
114showNotificationWithModel : UI.Model -> Notification Msg -> ( UI.Model, Cmd UI.Msg )
115showNotificationWithModel model notification =
116 showNotification notification model
117
118
119showSyncingNotification : Method -> Manager
120showSyncingNotification method model =
121 let
122 notification =
123 Notifications.stickyCasual "Syncing user data ..."
124
125 syncing =
126 Syncing.Syncing { method = method, notificationId = Notifications.id notification }
127 in
128 showNotification
129 notification
130 { model | syncing = syncing }
131
132
133toggleLoadingScreen : Switch -> Manager
134toggleLoadingScreen switch model =
135 case switch of
136 On ->
137 Return.singleton { model | isLoading = True }
138
139 Off ->
140 Return.singleton { model | isLoading = False }
141
142
143
144-- 🛠
145
146
147modifySingleton : Lens a b -> (b -> b) -> a -> ( a, Cmd msg )
148modifySingleton lens modifier =
149 Lens.modify lens modifier >> Return.singleton