A music player that connects to your cloud/distributed storage.
at main 273 lines 6.7 kB view raw
1module Brain exposing (main) 2 3import Alien 4import Brain.Common.State as Common 5import Brain.Other.State as Other 6import Brain.Ports as Ports 7import Brain.Sources.Processing.State as Processing 8import Brain.Sources.Processing.Types as Processing 9import Brain.Tracks.State as Tracks 10import Brain.Types exposing (..) 11import Brain.User.State as User 12import Brain.User.Types as User 13import Debouncer.Basic as Debouncer 14import Json.Decode as Json 15import Return 16import Return.Ext as Return 17import Sources.Processing as Processing 18import Task 19import Time 20import Time.Ext as Time 21import Url 22import User.Layer as User 23 24 25 26-- 🧠 27 28 29main : Program Flags Model Msg 30main = 31 Platform.worker 32 { init = init 33 , update = update 34 , subscriptions = subscriptions 35 } 36 37 38 39-- 🌳 40 41 42init : Flags -> ( Model, Cmd Msg ) 43init flags = 44 let 45 hypDebouncer = 46 2.5 47 |> Debouncer.fromSeconds 48 |> Debouncer.debounce 49 |> Debouncer.accumulateWith Debouncer.allInputs 50 |> Debouncer.toDebouncer 51 52 initialUrl = 53 flags.initialUrl 54 |> Url.fromString 55 |> Maybe.withDefault 56 { protocol = Url.Http 57 , host = "" 58 , port_ = Nothing 59 , path = "" 60 , query = Nothing 61 , fragment = Nothing 62 } 63 in 64 ( ----------------------------------------- 65 -- Initial model 66 ----------------------------------------- 67 { currentTime = Time.default 68 , hypaethralDebouncer = hypDebouncer 69 , hypaethralRetrieval = Nothing 70 , hypaethralStorage = [] 71 , hypaethralUserData = User.emptyHypaethralData 72 , origin = "ORIGIN_UNKNOWN" 73 , processingStatus = Processing.NotProcessing 74 , userSyncMethod = Nothing 75 } 76 ----------------------------------------- 77 -- Initial command 78 ----------------------------------------- 79 , Cmd.batch 80 [ Task.perform SetCurrentTime Time.now 81 , User.initialCommand initialUrl 82 ] 83 ) 84 85 86 87-- 📣 88 89 90update : Msg -> Manager 91update msg = 92 case msg of 93 Bypass -> 94 Return.singleton 95 96 Cmd a -> 97 Return.communicate a 98 99 ----------------------------------------- 100 -- Tracks 101 ----------------------------------------- 102 DownloadTracks a -> 103 Tracks.download a 104 105 GotSearchResults a -> 106 Tracks.gotSearchResults a 107 108 MakeArtworkTrackUrls a -> 109 Tracks.makeArtworkTrackUrls a 110 111 RemoveTracksBySourceId a -> 112 Tracks.removeBySourceId a 113 114 RemoveTracksFromCache a -> 115 Tracks.removeFromCache a 116 117 ReplaceTrackTags a -> 118 Tracks.replaceTags a 119 120 Search a -> 121 Tracks.search a 122 123 StoreTracksInCache a -> 124 Tracks.storeInCache a 125 126 SyncTrackTags a -> 127 Tracks.syncTrackTags a 128 129 UpdateSearchIndex a -> 130 Tracks.updateSearchIndex a 131 132 ----------------------------------------- 133 -- 🦉 Nested 134 ----------------------------------------- 135 ProcessingMsg a -> 136 Processing.update a 137 138 UserMsg a -> 139 User.update a 140 141 ----------------------------------------- 142 -- 📭 Other 143 ----------------------------------------- 144 RefreshedAccessToken a -> 145 Other.refreshedAccessToken a 146 147 SetCurrentTime a -> 148 Other.setCurrentTime a 149 150 ToCache a -> 151 Other.toCache a 152 153 154 155-- 📰 156 157 158subscriptions : Model -> Sub Msg 159subscriptions _ = 160 Sub.batch 161 [ Ports.fromAlien alien 162 , Ports.makeArtworkTrackUrls MakeArtworkTrackUrls 163 , Ports.refreshedAccessToken RefreshedAccessToken 164 , Ports.receiveSearchResults GotSearchResults 165 , Ports.receiveTags (ProcessingMsg << Processing.TagsStep) 166 , Ports.replaceTags ReplaceTrackTags 167 168 -- 169 , Time.every (60 * 1000) SetCurrentTime 170 ] 171 172 173 174-- 👽 175 176 177alien : Alien.Event -> Msg 178alien event = 179 case ( event.error, Alien.tagFromString event.tag ) of 180 ( Nothing, Just tag ) -> 181 translateAlienData tag event.data 182 183 ( Just err, Just tag ) -> 184 translateAlienError tag event.data err 185 186 _ -> 187 Bypass 188 189 190translateAlienData : Alien.Tag -> Json.Value -> Msg 191translateAlienData tag data = 192 case tag of 193 Alien.EnclosedData -> 194 UserMsg (User.EnclosedDataRetrieved data) 195 196 Alien.SearchTracks -> 197 Search data 198 199 ----------------------------------------- 200 -- From UI 201 ----------------------------------------- 202 Alien.DownloadTracks -> 203 DownloadTracks data 204 205 Alien.ProcessSources -> 206 ProcessingMsg (Processing.Process data) 207 208 Alien.RefreshedAccessToken -> 209 RefreshedAccessToken data 210 211 Alien.RemoveEncryptionKey -> 212 UserMsg User.RemoveEncryptionKey 213 214 Alien.RemoveTracksBySourceId -> 215 RemoveTracksBySourceId data 216 217 Alien.RemoveTracksFromCache -> 218 RemoveTracksFromCache data 219 220 Alien.SaveEnclosedUserData -> 221 UserMsg (User.SaveEnclosedData data) 222 223 Alien.SaveFavourites -> 224 UserMsg (User.SaveFavourites data) 225 226 Alien.SavePlaylists -> 227 UserMsg (User.SavePlaylists data) 228 229 Alien.SaveProgress -> 230 UserMsg (User.SaveProgress data) 231 232 Alien.SaveSettings -> 233 UserMsg (User.SaveSettings data) 234 235 Alien.SaveSources -> 236 UserMsg (User.SaveSources data) 237 238 Alien.SaveTracks -> 239 UserMsg (User.SaveTracks data) 240 241 Alien.SetSyncMethod -> 242 UserMsg (User.SetSyncMethod data) 243 244 Alien.StopProcessing -> 245 ProcessingMsg Processing.StopProcessing 246 247 Alien.StoreTracksInCache -> 248 StoreTracksInCache data 249 250 Alien.SyncTrackTags -> 251 SyncTrackTags data 252 253 Alien.ToCache -> 254 ToCache data 255 256 Alien.UnsetSyncMethod -> 257 UserMsg User.UnsetSyncMethod 258 259 Alien.UpdateEncryptionKey -> 260 UserMsg (User.UpdateEncryptionKey data) 261 262 _ -> 263 Bypass 264 265 266translateAlienError : Alien.Tag -> Json.Value -> String -> Msg 267translateAlienError tag _ err = 268 case err of 269 "db is undefined" -> 270 Common.reportUICmdMsg tag "Can't connect to the browser's IndexedDB. FYI, this is __not supported in Firefox's private mode__." 271 272 _ -> 273 Common.reportUICmdMsg tag err