A music player that connects to your cloud/distributed storage.
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

Store sources

+212 -3
+27 -1
src/Applications/UI.elm
··· 21 21 import Tachyons.Classes as T 22 22 import UI.Authentication 23 23 import UI.Backdrop 24 - import UI.Core exposing (Flags, Model, Msg(..), Switch(..)) 24 + import UI.Core as Core exposing (Flags, Model, Msg(..), Switch(..)) 25 25 import UI.Kit 26 26 import UI.Navigation 27 27 import UI.Page as Page ··· 29 29 import UI.Reply as Reply exposing (Reply(..)) 30 30 import UI.Settings 31 31 import UI.Sources 32 + import UI.UserData 32 33 import Url exposing (Url) 33 34 34 35 ··· 93 94 94 95 LoadHypaethralUserData json -> 95 96 ( { model | isAuthenticated = True, isLoading = False } 97 + |> UI.UserData.importHypaethral json 96 98 , Cmd.none 97 99 ) 98 100 ··· 132 134 ----------------------------------------- 133 135 -- Brain 134 136 ----------------------------------------- 137 + NotifyBrain alienEvent -> 138 + ( model 139 + , Ports.toBrain alienEvent 140 + ) 141 + 142 + Core.SaveEnclosedUserData -> 143 + ( model 144 + , Cmd.none 145 + ) 146 + 147 + Core.SaveHypaethralUserData -> 148 + ( model 149 + , model 150 + |> UI.UserData.exportHypaethral 151 + |> Alien.broadcast Alien.SaveHypaethralUserData 152 + |> Ports.toBrain 153 + ) 154 + 135 155 SignIn method -> 136 156 ( model 137 157 , method ··· 192 212 193 213 GoToPage page -> 194 214 ChangeUrlUsingPage page 215 + 216 + Reply.SaveEnclosedUserData -> 217 + Core.SaveEnclosedUserData 218 + 219 + Reply.SaveHypaethralUserData -> 220 + Core.SaveHypaethralUserData 195 221 196 222 197 223 updateChild =
+3
src/Applications/UI/Core.elm
··· 55 55 ----------------------------------------- 56 56 -- Brain 57 57 ----------------------------------------- 58 + | NotifyBrain Alien.Event 59 + | SaveEnclosedUserData 60 + | SaveHypaethralUserData 58 61 | SignIn Authentication.Method 59 62 | SignOut 60 63 -----------------------------------------
+2
src/Applications/UI/Reply.elm
··· 12 12 = AddSourceToCollection Source 13 13 | Chill 14 14 | GoToPage Page 15 + | SaveEnclosedUserData 16 + | SaveHypaethralUserData
+3 -1
src/Applications/UI/Sources.elm
··· 7 7 import Material.Icons.Navigation as Icons 8 8 import Material.Icons.Notification as Icons 9 9 import Replying exposing (R3D3) 10 + import Return2 10 11 import Return3 11 12 import Sources exposing (..) 12 13 import Sources.Services as Services ··· 67 68 |> List.singleton 68 69 |> List.append model.collection 69 70 |> (\c -> { model | collection = c }) 70 - |> Return3.withNothing 71 + |> Return2.withNoCmd 72 + |> Return3.withReply [ UI.Reply.SaveHypaethralUserData ] 71 73 72 74 ----------------------------------------- 73 75 -- Children
+90
src/Applications/UI/UserData.elm
··· 1 + module UI.UserData exposing (HypaethralBundle, exportHypaethral, importHypaethral) 2 + 3 + {-| Import user data into or export user data from the UI.Core.Model 4 + -} 5 + 6 + import Authentication exposing (..) 7 + import Json.Decode as Decode 8 + import Json.Encode as Encode 9 + import Sources.Encoding as Sources 10 + import UI.Core 11 + import UI.Sources 12 + 13 + 14 + 15 + ----------------------------------------- 16 + -- 📭 17 + ----------------------------------------- 18 + 19 + 20 + type alias HypaethralBundle = 21 + ( HypaethralUserData, Decode.Value ) 22 + 23 + 24 + importHypaethral : Decode.Value -> UI.Core.Model -> UI.Core.Model 25 + importHypaethral value model = 26 + let 27 + data = 28 + Result.withDefault emptyHypaethralUserData (decode value) 29 + 30 + bundle = 31 + ( data 32 + , Encode.null 33 + ) 34 + in 35 + { model | sources = importSources model.sources bundle } 36 + 37 + 38 + 39 + -- 📭 | Importing Hypaethral 40 + 41 + 42 + importSources : UI.Sources.Model -> HypaethralBundle -> UI.Sources.Model 43 + importSources model ( data, _ ) = 44 + { model | collection = Maybe.withDefault [] data.sources } 45 + 46 + 47 + 48 + -- 📭 | Decoding 49 + 50 + 51 + decode : Decode.Value -> Result Decode.Error HypaethralUserData 52 + decode = 53 + Decode.decodeValue decoder 54 + 55 + 56 + decoder : Decode.Decoder HypaethralUserData 57 + decoder = 58 + Decode.map 59 + HypaethralUserData 60 + (Decode.maybe <| Decode.field "sources" <| Decode.list Sources.decoder) 61 + 62 + 63 + 64 + -- 📭 | Fallbacks 65 + 66 + 67 + emptyHypaethralUserData : HypaethralUserData 68 + emptyHypaethralUserData = 69 + { sources = Nothing } 70 + 71 + 72 + 73 + ----------------------------------------- 74 + -- 📮 75 + ----------------------------------------- 76 + 77 + 78 + exportHypaethral : UI.Core.Model -> Encode.Value 79 + exportHypaethral = 80 + encode 81 + 82 + 83 + 84 + -- 📮 | Encoding 85 + 86 + 87 + encode : UI.Core.Model -> Encode.Value 88 + encode model = 89 + Encode.object 90 + [ ( "sources", Encode.list Sources.encode model.sources.collection ) ]
+14 -1
src/Library/Authentication.elm
··· 1 - module Authentication exposing (Method(..), methodFromString, methodToString) 1 + module Authentication exposing (EnclosedUserData, HypaethralUserData, Method(..), methodFromString, methodToString) 2 + 3 + import Sources 4 + 5 + 2 6 3 7 -- 🌳 4 8 5 9 6 10 type Method 7 11 = Local 12 + 13 + 14 + type alias EnclosedUserData = 15 + {} 16 + 17 + 18 + type alias HypaethralUserData = 19 + { sources : Maybe (List Sources.Source) 20 + } 8 21 9 22 10 23
+73
src/Library/Sources/Encoding.elm
··· 1 + module Sources.Encoding exposing (decode, decoder, encode, encodeData, serviceDecoder) 2 + 3 + {-| Encoding. 4 + -} 5 + 6 + import Dict 7 + import Json.Decode as Decode 8 + import Json.Encode as Encode 9 + import Sources exposing (..) 10 + import Sources.Services as Services 11 + 12 + 13 + 14 + -- ENCODE 15 + 16 + 17 + encode : Source -> Encode.Value 18 + encode source = 19 + Encode.object 20 + [ ( "id", Encode.string source.id ) 21 + , ( "data", encodeData source.data ) 22 + , ( "directoryPlaylists", Encode.bool source.directoryPlaylists ) 23 + , ( "enabled", Encode.bool source.enabled ) 24 + , ( "service", Encode.string (Services.typeToKey source.service) ) 25 + ] 26 + 27 + 28 + encodeData : SourceData -> Encode.Value 29 + encodeData data = 30 + data 31 + |> Dict.toList 32 + |> List.map (Tuple.mapSecond Encode.string) 33 + |> Encode.object 34 + 35 + 36 + 37 + -- DECODE 38 + 39 + 40 + decode : Decode.Value -> Maybe Source 41 + decode value = 42 + Decode.decodeValue decoder value 43 + |> Result.toMaybe 44 + 45 + 46 + decoder : Decode.Decoder Source 47 + decoder = 48 + Decode.map5 Source 49 + (Decode.field "id" Decode.string) 50 + (Decode.field "data" (Decode.dict Decode.string)) 51 + (Decode.field "directoryPlaylists" Decode.bool 52 + |> Decode.maybe 53 + |> Decode.map (Maybe.withDefault True) 54 + ) 55 + (Decode.field "enabled" Decode.bool 56 + |> Decode.maybe 57 + |> Decode.map (Maybe.withDefault True) 58 + ) 59 + (Decode.field "service" serviceDecoder) 60 + 61 + 62 + serviceDecoder : Decode.Decoder Service 63 + serviceDecoder = 64 + Decode.andThen 65 + (\key -> 66 + case Services.keyToType key of 67 + Just service -> 68 + Decode.succeed service 69 + 70 + Nothing -> 71 + Decode.fail "Unrecognizable source service" 72 + ) 73 + Decode.string