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.

Add `insertedAt` field to tracks

+51 -13
+3 -1
src/Applications/Brain/Sources/Processing.elm
··· 13 13 import Task 14 14 import Task.Extra exposing (do) 15 15 import Time 16 + import Time.Ext as Time 16 17 import Tracks.Encoding 17 18 18 19 ··· 22 23 23 24 initialModel : Model 24 25 initialModel = 25 - { currentTime = Time.millisToPosix 0 26 + { currentTime = Time.default 26 27 , origin = "ORIGIN_UNKNOWN" 27 28 , status = NotProcessing 28 29 } ··· 162 163 False -> 163 164 tagsContext 164 165 |> tracksFromTagsContext 166 + |> List.map (\track -> { track | insertedAt = model.currentTime }) 165 167 |> Encode.list Tracks.Encoding.encodeTrack 166 168 |> GiveUI Alien.AddTracks 167 169 |> List.singleton
+1 -1
src/Applications/UI/Queue/Common.elm
··· 15 15 16 16 makeEngineItem : Time.Posix -> List Source -> IdentifiedTrack -> EngineItem 17 17 makeEngineItem timestamp sources ( _, track ) = 18 - { track = track 18 + { trackId = track.id 19 19 , url = 20 20 sources 21 21 |> List.find (.id >> (==) track.sourceId)
+2 -1
src/Applications/UI/Sources.elm
··· 19 19 import Sources.Encoding 20 20 import Tachyons.Classes as T 21 21 import Time 22 + import Time.Ext as Time 22 23 import UI.Kit exposing (ButtonType(..)) 23 24 import UI.List 24 25 import UI.Navigation exposing (..) ··· 45 46 initialModel : Model 46 47 initialModel = 47 48 { collection = [] 48 - , currentTime = Time.millisToPosix 0 49 + , currentTime = Time.default 49 50 , form = Form.initialModel 50 51 , isProcessing = False 51 52 , processingError = Nothing
+3 -3
src/Javascript/audio-engine.js
··· 92 92 93 93 function insertTrack(orchestrion, queueItem) { 94 94 if (!queueItem.url) console.error("insertTrack, missing `url`"); 95 - if (!queueItem.track && !queueItem.track.id) console.error("insertTrack, missing `track.id`"); 95 + if (!queueItem.trackId) console.error("insertTrack, missing `trackId`"); 96 96 97 97 // Reset progress-bar width 98 98 setProgressBarWidth(0) ··· 130 130 audio.setAttribute("crossorigin", "anonymous") 131 131 audio.setAttribute("preload", "none") 132 132 audio.setAttribute("src", queueItem.url) 133 - audio.setAttribute("rel", queueItem.track.id) 133 + audio.setAttribute("rel", queueItem.trackId) 134 134 audio.setAttribute("data-timestamp", timestampInMilliseconds) 135 135 136 136 audio.crossorigin = "anonymous" ··· 270 270 271 271 function isActiveAudioElement(orchestrion, node) { 272 272 if (!orchestrion.activeQueueItem || !node) return false; 273 - return orchestrion.activeQueueItem.track.id === audioElementTrackId(node) 273 + return orchestrion.activeQueueItem.trackId === audioElementTrackId(node) 274 274 } 275 275 276 276
+1 -1
src/Library/Authentication.elm
··· 3 3 import Equalizer 4 4 import Json.Decode as Json 5 5 import Json.Decode.Ext as Json 6 - import Json.Decode.Pipeline exposing (optional, required) 6 + import Json.Decode.Pipeline exposing (optional) 7 7 import Json.Encode 8 8 import Maybe.Extra as Maybe 9 9 import Sources
+1 -1
src/Library/Queue.elm
··· 14 14 15 15 16 16 type alias EngineItem = 17 - { track : Track 17 + { trackId : String 18 18 , url : String 19 19 }
+24
src/Library/Time/Ext.elm
··· 1 + module Time.Ext exposing (decoder, default, encode) 2 + 3 + import Json.Decode as Decode exposing (Decoder) 4 + import Json.Encode as Json 5 + import Time 6 + 7 + 8 + 9 + -- 🔱 10 + 11 + 12 + decoder : Decoder Time.Posix 13 + decoder = 14 + Decode.map Time.millisToPosix Decode.int 15 + 16 + 17 + default : Time.Posix 18 + default = 19 + Time.millisToPosix 0 20 + 21 + 22 + encode : Time.Posix -> Json.Value 23 + encode time = 24 + Json.int (Time.posixToMillis time)
+5
src/Library/Tracks.elm
··· 2 2 3 3 import Base64 4 4 import String.Ext as String 5 + import Time 6 + import Time.Ext as Time 5 7 6 8 7 9 ··· 10 12 11 13 type alias Track = 12 14 { id : String 15 + , insertedAt : Time.Posix 13 16 , path : String 14 17 , sourceId : String 15 18 , tags : Tags ··· 119 122 emptyTrack : Track 120 123 emptyTrack = 121 124 { id = "" 125 + , insertedAt = Time.default 122 126 , path = "" 123 127 , sourceId = "" 124 128 , tags = emptyTags ··· 171 175 (sourceId ++ "//" ++ path) 172 176 |> Base64.encode 173 177 |> String.chopEnd "=" 178 + , insertedAt = Time.default 174 179 , path = path 175 180 , sourceId = sourceId 176 181 , tags = tags
+2
src/Library/Tracks/Collection/Internal/Identify.elm
··· 1 1 module Tracks.Collection.Internal.Identify exposing (identify) 2 2 3 3 import List.Extra as List 4 + import Time.Ext as Time 4 5 import Tracks exposing (..) 5 6 import Tracks.Favourites as Favourites 6 7 ··· 134 135 } 135 136 , { tags = tags 136 137 , id = missingId 138 + , insertedAt = Time.default 137 139 , path = missingId 138 140 , sourceId = missingId 139 141 }
+9 -5
src/Library/Tracks/Encoding.elm
··· 1 1 module Tracks.Encoding exposing (decodeFavourite, decodeTrack, encodeFavourite, encodeMaybe, encodeSortBy, encodeSortDirection, encodeTags, encodeTrack, favouriteDecoder, sortByDecoder, sortDirectionDecoder, tagsDecoder, trackDecoder) 2 2 3 3 import Json.Decode as Decode 4 + import Json.Decode.Pipeline exposing (optional, required) 4 5 import Json.Encode as Encode 6 + import Time.Ext as Time 5 7 import Tracks exposing (..) 6 8 7 9 ··· 47 49 encodeTrack track = 48 50 Encode.object 49 51 [ ( "id", Encode.string track.id ) 52 + , ( "insertedAt", Time.encode track.insertedAt ) 50 53 , ( "path", Encode.string track.path ) 51 54 , ( "sourceId", Encode.string track.sourceId ) 52 55 , ( "tags", encodeTags track.tags ) ··· 156 159 157 160 trackDecoder : Decode.Decoder Track 158 161 trackDecoder = 159 - Decode.map4 Track 160 - (Decode.field "id" Decode.string) 161 - (Decode.field "path" Decode.string) 162 - (Decode.field "sourceId" Decode.string) 163 - (Decode.field "tags" tagsDecoder) 162 + Decode.succeed Track 163 + |> required "id" Decode.string 164 + |> optional "insertedAt" Time.decoder Time.default 165 + |> required "path" Decode.string 166 + |> required "sourceId" Decode.string 167 + |> required "tags" tagsDecoder