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.

Fix search on Safari

+89 -40
+3 -1
CHANGELOG.md
··· 2 2 3 3 ## 3.4.0 4 4 5 - Allows you to make playlists public when using Fission / Webnative. 5 + - Adjusted search behaviour, now searches while typing (with a small delay). 6 + - Allows you to make playlists public when using Fission / Webnative. 7 + - Fixes issue with Safari where reloading after a search caused the loader to be shown indefinitely. 6 8 7 9 8 10 ## 3.3.0
+12 -4
src/Applications/UI.elm
··· 136 136 ----------------------------------------- 137 137 -- Debouncing 138 138 ----------------------------------------- 139 - , debounce = 139 + , resizeDebouncer = 140 140 0.25 141 + |> Debouncer.fromSeconds 142 + |> Debouncer.debounce 143 + |> Debouncer.toDebouncer 144 + , searchDebouncer = 145 + 0.5 141 146 |> Debouncer.fromSeconds 142 147 |> Debouncer.debounce 143 148 |> Debouncer.toDebouncer ··· 337 342 CopyToClipboard a -> 338 343 Interface.copyToClipboard a 339 344 340 - Debounce a -> 341 - Interface.debounce update a 342 - 343 345 DismissNotification a -> 344 346 Common.dismissNotification a 345 347 ··· 370 372 RemoveTrackSelection -> 371 373 Interface.removeTrackSelection 372 374 375 + ResizeDebounce a -> 376 + Interface.resizeDebounce update a 377 + 373 378 ResizedWindow a -> 374 379 Interface.resizedWindow a 380 + 381 + SearchDebounce a -> 382 + Interface.searchDebounce update a 375 383 376 384 SetIsTouchDevice a -> 377 385 Interface.setIsTouchDevice a
+24 -1
src/Applications/UI/Common/State.elm
··· 4 4 import Browser.Navigation as Nav 5 5 import Common exposing (..) 6 6 import ContextMenu exposing (ContextMenu) 7 + import Debouncer.Basic as Debouncer exposing (Debouncer) 7 8 import List.Extra as List 8 9 import Monocle.Lens as Lens exposing (Lens) 9 10 import Notifications exposing (Notification) ··· 16 17 import UI.Syncing.Types as Syncing 17 18 import UI.Tracks.Scene.Covers 18 19 import UI.Tracks.Scene.List 19 - import UI.Types as UI exposing (Manager, Msg) 20 + import UI.Types as UI exposing (Manager, Model, Msg) 20 21 import User.Layer exposing (Method) 21 22 22 23 ··· 30 31 |> Page.toString 31 32 |> Nav.pushUrl model.navKey 32 33 |> return model 34 + 35 + 36 + debounce : (Model -> Debouncer Msg Msg) -> (Debouncer Msg Msg -> Model -> Model) -> (Debouncer.Msg Msg -> Msg) -> (Msg -> Model -> ( Model, Cmd Msg )) -> Debouncer.Msg Msg -> Manager 37 + debounce getter setter debouncerMsgContainer update debouncerMsg model = 38 + let 39 + ( subModel, subCmd, emittedMsg ) = 40 + Debouncer.update debouncerMsg (getter model) 41 + 42 + mappedCmd = 43 + Cmd.map debouncerMsgContainer subCmd 44 + 45 + updatedModel = 46 + setter subModel model 47 + in 48 + case emittedMsg of 49 + Just emitted -> 50 + updatedModel 51 + |> update emitted 52 + |> Return.command mappedCmd 53 + 54 + Nothing -> 55 + return updatedModel mappedCmd 33 56 34 57 35 58 dismissNotification : { id : Int } -> Manager
+12
src/Applications/UI/Common/Types.elm
··· 1 + module UI.Common.Types exposing (..) 2 + 3 + import Debouncer.Basic as Debouncer 4 + import UI.Types exposing (Manager, Model, Msg) 5 + 6 + 7 + 8 + -- 🌳 9 + 10 + 11 + type alias DebounceManager = 12 + (Msg -> Model -> ( Model, Cmd Msg )) -> Debouncer.Msg Msg -> Manager
+16 -21
src/Applications/UI/Interface/State.elm
··· 7 7 import Return.Ext as Return 8 8 import Tracks 9 9 import UI.Common.State as Common 10 + import UI.Common.Types exposing (DebounceManager) 10 11 import UI.DnD as DnD 11 12 import UI.Page as Page 12 13 import UI.Playlists.State as Playlists ··· 38 39 |> Return.communicate 39 40 40 41 41 - debounce : (Msg -> Model -> ( Model, Cmd Msg )) -> Debouncer.Msg Msg -> Manager 42 - debounce update debouncerMsg model = 43 - let 44 - ( subModel, subCmd, emittedMsg ) = 45 - Debouncer.update debouncerMsg model.debounce 46 - 47 - mappedCmd = 48 - Cmd.map Debounce subCmd 49 - 50 - updatedModel = 51 - { model | debounce = subModel } 52 - in 53 - case emittedMsg of 54 - Just emitted -> 55 - updatedModel 56 - |> update emitted 57 - |> Return.command mappedCmd 58 - 59 - Nothing -> 60 - return updatedModel mappedCmd 42 + resizeDebounce : DebounceManager 43 + resizeDebounce = 44 + Common.debounce 45 + .resizeDebouncer 46 + (\d m -> { m | resizeDebouncer = d }) 47 + ResizeDebounce 61 48 62 49 63 50 dnd : DnD.Msg Int -> Manager ··· 187 174 } 188 175 189 176 177 + searchDebounce : DebounceManager 178 + searchDebounce = 179 + Common.debounce 180 + .searchDebouncer 181 + (\d m -> { m | searchDebouncer = d }) 182 + SearchDebounce 183 + 184 + 190 185 setIsTouchDevice : Bool -> Manager 191 186 setIsTouchDevice bool model = 192 187 Return.singleton { model | isTouchDevice = bool } ··· 220 215 ( w, h ) 221 216 |> ResizedWindow 222 217 |> Debouncer.provideInput 223 - |> Debounce 218 + |> ResizeDebounce
+15 -7
src/Applications/UI/Tracks/State.elm
··· 4 4 import Common exposing (..) 5 5 import ContextMenu 6 6 import Coordinates exposing (Coordinates) 7 + import Debouncer.Basic as Debouncer 7 8 import Dict 8 9 import Html.Events.Extra.Mouse as Mouse 9 10 import InfiniteList ··· 623 624 624 625 setSearchTerm : String -> Manager 625 626 setSearchTerm term model = 626 - User.saveEnclosedUserData 627 - (case String.trim term of 628 - "" -> 629 - { model | searchTerm = Nothing } 627 + (case String.trim term of 628 + "" -> 629 + { model | searchTerm = Nothing } 630 630 631 - _ -> 632 - { model | searchTerm = Just term } 633 - ) 631 + _ -> 632 + { model | searchTerm = Just term } 633 + ) 634 + |> Return.communicate 635 + (Search 636 + |> TracksMsg 637 + |> Debouncer.provideInput 638 + |> SearchDebounce 639 + |> Task.do 640 + ) 641 + |> Return.andThen User.saveEnclosedUserData 634 642 635 643 636 644 showCoverMenu : Cover -> Coordinates -> Manager
+1 -4
src/Applications/UI/Tracks/View.elm
··· 6 6 import Conditional exposing (ifThenElse) 7 7 import Html exposing (Html, text) 8 8 import Html.Attributes as A exposing (attribute, placeholder, style, tabindex, title, value) 9 - import Html.Events as E exposing (onBlur, onClick, onInput) 9 + import Html.Events as E exposing (onClick, onInput) 10 10 import Html.Events.Extra.Mouse as Mouse 11 - import Html.Ext exposing (onEnterKey) 12 11 import Html.Lazy exposing (..) 13 12 import Keyboard exposing (Key(..)) 14 13 import Material.Icons.Round as Icons ··· 184 183 Html.input 185 184 [ attribute "autocorrect" "off" 186 185 , attribute "autocapitalize" "none" 187 - , onBlur (TracksMsg Search) 188 - , onEnterKey (TracksMsg Search) 189 186 , onInput (TracksMsg << SetSearchTerm) 190 187 , placeholder "Search" 191 188 , tabindex tabindex_
+4 -2
src/Applications/UI/Types.elm
··· 102 102 ----------------------------------------- 103 103 -- Debouncing 104 104 ----------------------------------------- 105 - , debounce : Debouncer Msg Msg 105 + , resizeDebouncer : Debouncer Msg Msg 106 + , searchDebouncer : Debouncer Msg Msg 106 107 107 108 ----------------------------------------- 108 109 -- Equalizer ··· 227 228 | Blur 228 229 | ContextMenuConfirmation String Msg 229 230 | CopyToClipboard String 230 - | Debounce (Debouncer.Msg Msg) 231 231 | DismissNotification { id : Int } 232 232 | DnD (DnD.Msg Int) 233 233 | FocusedOnInput ··· 238 238 | RemoveNotification { id : Int } 239 239 | RemoveQueueSelection 240 240 | RemoveTrackSelection 241 + | ResizeDebounce (Debouncer.Msg Msg) 241 242 | ResizedWindow ( Int, Int ) 243 + | SearchDebounce (Debouncer.Msg Msg) 242 244 | ShowNotification (Notification Msg) 243 245 | SetIsTouchDevice Bool 244 246 | StoppedDragging
+2
src/Javascript/index.js
··· 5 5 // and connect the other bits to it. 6 6 7 7 8 + import "subworkers" 8 9 import "tocca" 10 + 9 11 import loadScript from "load-script2" 10 12 import JSZip from "jszip" 11 13 import { saveAs } from "file-saver"