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

Configure Feed

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

Add public field to `Playlist`

+107 -19
+1
src/Applications/UI/Playlists/Directory.elm
··· 44 44 (\n -> 45 45 { autoGenerated = True 46 46 , name = n 47 + , public = False 47 48 , tracks = [] 48 49 } 49 50 )
+2
src/Applications/UI/Playlists/State.elm
··· 61 61 (::) 62 62 { autoGenerated = False 63 63 , name = properPlaylistName 64 + , public = False 64 65 , tracks = tracks 65 66 } 66 67 model.playlists ··· 112 113 playlist = 113 114 { autoGenerated = False 114 115 , name = playlistName 116 + , public = False 115 117 , tracks = [] 116 118 } 117 119 in
+31 -10
src/Applications/UI/Playlists/View.elm
··· 24 24 -- 🗺 25 25 26 26 27 - view : Page -> List Playlist -> Maybe Playlist -> Maybe { oldName : String, newName : String } -> Maybe Color -> Html Msg 28 - view page playlists selectedPlaylist editContext bgColor = 27 + view : Page -> List Playlist -> Maybe Playlist -> Maybe { oldName : String, newName : String } -> Maybe Color -> Bool -> Html Msg 28 + view page playlists selectedPlaylist editContext bgColor authMethodSupportsPublicData = 29 29 UI.Kit.receptacle 30 30 { scrolling = True } 31 31 (case page of ··· 43 43 |> Maybe.withDefault [ nothing ] 44 44 45 45 Index -> 46 - index playlists selectedPlaylist bgColor 46 + index playlists selectedPlaylist bgColor authMethodSupportsPublicData 47 47 48 48 New -> 49 49 new ··· 54 54 -- INDEX 55 55 56 56 57 - index : List Playlist -> Maybe Playlist -> Maybe Color -> List (Html Msg) 58 - index playlists selectedPlaylist bgColor = 57 + index : List Playlist -> Maybe Playlist -> Maybe Color -> Bool -> List (Html Msg) 58 + index playlists selectedPlaylist bgColor authMethodSupportsPublicData = 59 59 let 60 60 selectedPlaylistName = 61 61 Maybe.map .name selectedPlaylist ··· 72 72 else 73 73 { label = text playlist.name 74 74 , actions = 75 - [ { icon = Icons.more_vert 76 - , msg = Just (ShowPlaylistListMenu playlist) 77 - , title = "Menu" 78 - } 79 - ] 75 + List.append 76 + (if authMethodSupportsPublicData then 77 + [ { icon = 78 + if playlist.public then 79 + Icons.public 80 + 81 + else 82 + Icons.public_off 83 + , msg = Nothing 84 + , title = 85 + if playlist.public then 86 + "Make private" 87 + 88 + else 89 + "Make public" 90 + } 91 + ] 92 + 93 + else 94 + [] 95 + ) 96 + [ { icon = Icons.more_vert 97 + , msg = Just (ShowPlaylistListMenu playlist) 98 + , title = "Menu" 99 + } 100 + ] 80 101 , msg = Just (ActivatePlaylist playlist) 81 102 , isSelected = False 82 103 }
+5 -1
src/Applications/UI/View.elm
··· 180 180 nothing 181 181 182 182 Page.Playlists subPage -> 183 - Lazy.lazy5 183 + Lazy.lazy6 184 184 Playlists.view 185 185 subPage 186 186 model.playlists 187 187 model.selectedPlaylist 188 188 model.editPlaylistContext 189 189 model.extractedBackdropColor 190 + (model.authentication 191 + |> Authentication.extractMethod 192 + |> Maybe.unwrap False User.Layer.methodSupportsPublicData 193 + ) 190 194 191 195 Page.Queue subPage -> 192 196 Queue.view subPage model
+9 -1
src/Javascript/Brain/user.js
··· 6 6 7 7 8 8 import * as crypto from "../crypto" 9 - import { WEBNATIVE_PERMISSIONS, identity } from "../common" 9 + import { WEBNATIVE_PERMISSIONS, WEBNATIVE_STAGING_MODE, identity } from "../common" 10 10 11 11 import { SECRET_KEY_LOCATION } from "./common" 12 12 import { decryptIfNeeded, encryptWithSecretKey } from "./common" ··· 112 112 113 113 if ([ "localhost", "nightly.diffuse.sh" ].includes(location.hostname)) { 114 114 wn.setup.debug({ enabled: true }) 115 + } 116 + 117 + if (WEBNATIVE_STAGING_MODE) { 118 + wn.setup.endpoints({ 119 + api: "https://runfission.net", 120 + lobby: "http://auth.runfission.net", 121 + user: "fissionuser.net" 122 + }) 115 123 } 116 124 117 125 return (
+9
src/Javascript/common.js
··· 15 15 } 16 16 17 17 18 + export const WEBNATIVE_STAGING_MODE = ( 19 + location.host === "localhost:5000" 20 + ) 21 + 22 + 23 + 24 + // FUNCTIONS 25 + 26 + 18 27 export const debounce = 19 28 (callback, time = 250, timeoutId) => 20 29 (...args) =>
+11 -1
src/Javascript/index.js
··· 15 15 16 16 import * as audioEngine from "./audio-engine" 17 17 import * as db from "./indexed-db" 18 - import { WEBNATIVE_PERMISSIONS, debounce, fileExtension } from "./common" 18 + import { WEBNATIVE_PERMISSIONS, WEBNATIVE_STAGING_MODE, debounce, fileExtension } from "./common" 19 19 20 20 21 21 // 🔐 ··· 298 298 299 299 function loadWebnative() { 300 300 if (wn) return Promise.resolve() 301 + 301 302 return loadScript("vendor/webnative.min.js").then(() => { 302 303 wn = window.webnative 304 + 303 305 if ([ "localhost", "nightly.diffuse.sh" ].includes(location.hostname)) { 304 306 wn.setup.debug({ enabled: true }) 307 + } 308 + 309 + if (WEBNATIVE_STAGING_MODE) { 310 + wn.setup.endpoints({ 311 + api: "https://runfission.net", 312 + lobby: "http://auth.runfission.net", 313 + user: "fissionuser.net" 314 + }) 305 315 } 306 316 }) 307 317 }
+15 -5
src/Library/Json/Decode/Ext.elm
··· 1 - module Json.Decode.Ext exposing (listIgnore) 1 + module Json.Decode.Ext exposing (listIgnore, optionalField) 2 2 3 - import Json.Decode exposing (Decoder) 3 + import Json.Decode as Decode exposing (Decoder) 4 4 import Maybe.Extra as Maybe 5 5 6 6 ··· 13 13 listIgnore : Decoder a -> Decoder (List a) 14 14 listIgnore decoder = 15 15 decoder 16 - |> Json.Decode.maybe 17 - |> Json.Decode.list 18 - |> Json.Decode.map Maybe.values 16 + |> Decode.maybe 17 + |> Decode.list 18 + |> Decode.map Maybe.values 19 + 20 + 21 + {-| Provide a default value for a field that might not be there. 22 + -} 23 + optionalField : String -> Decoder a -> a -> Decoder a 24 + optionalField field decoder defaultValue = 25 + decoder 26 + |> Decode.field field 27 + |> Decode.maybe 28 + |> Decode.map (Maybe.withDefault defaultValue)
+1
src/Library/Playlists.elm
··· 6 6 type alias Playlist = 7 7 { autoGenerated : Bool 8 8 , name : String 9 + , public : Bool 9 10 , tracks : List PlaylistTrack 10 11 } 11 12
+4 -1
src/Library/Playlists/Encoding.elm
··· 1 1 module Playlists.Encoding exposing (decoder, encode, encodePlaylistTrack, playlistTrackDecoder) 2 2 3 3 import Json.Decode as Decode 4 + import Json.Decode.Ext as Decode 4 5 import Json.Encode as Encode 5 6 import Playlists exposing (..) 6 7 ··· 14 15 Encode.object 15 16 [ ( "autoGenerated", Encode.bool playlist.autoGenerated ) 16 17 , ( "name", Encode.string playlist.name ) 18 + , ( "public", Encode.bool playlist.public ) 17 19 , ( "tracks", Encode.list encodePlaylistTrack playlist.tracks ) 18 20 ] 19 21 ··· 33 35 34 36 decoder : Decode.Decoder Playlist 35 37 decoder = 36 - Decode.map3 Playlist 38 + Decode.map4 Playlist 37 39 (Decode.field "autoGenerated" Decode.bool) 38 40 (Decode.field "name" Decode.string) 41 + (Decode.optionalField "public" Decode.bool False) 39 42 (Decode.field "tracks" <| Decode.list playlistTrackDecoder) 40 43 41 44
+19
src/Library/User/Layer.elm
··· 44 44 | RemoteStorage { userAddress : String, token : String } 45 45 46 46 47 + methodSupportsPublicData : Method -> Bool 48 + methodSupportsPublicData method = 49 + case method of 50 + Dropbox _ -> 51 + False 52 + 53 + Fission -> 54 + True 55 + 56 + Ipfs _ -> 57 + False 58 + 59 + Local -> 60 + False 61 + 62 + RemoteStorage _ -> 63 + False 64 + 65 + 47 66 48 67 -- 🌳 ░░ ENCLOSED 49 68