From 0cbca028ab0813132042fffd8ed2826888bc13bb Mon Sep 17 00:00:00 2001 From: Steven Vandevelde Date: Mon, 29 Apr 2019 21:21:56 +0200 Subject: [PATCH] Add basic queue screen --- elm.json | 2 +- src/Applications/UI.elm | 8 +- src/Applications/UI/Equalizer.elm | 8 +- src/Applications/UI/Kit.elm | 4 +- src/Applications/UI/List.elm | 16 +- src/Applications/UI/Navigation.elm | 6 +- src/Applications/UI/Page.elm | 3 + src/Applications/UI/Queue.elm | 190 +++++++++++++++++- src/Applications/UI/Queue/ContextMenu.elm | 18 ++ src/Applications/UI/Queue/Core.elm | 7 +- src/Applications/UI/Reply.elm | 1 + src/Applications/UI/Settings.elm | 2 +- src/Applications/UI/Settings/ImportExport.elm | 2 +- src/Applications/UI/Sources.elm | 11 +- src/Applications/UI/Sources/Form.elm | 20 +- src/Applications/UI/Tracks.elm | 7 +- 16 files changed, 266 insertions(+), 39 deletions(-) create mode 100644 src/Applications/UI/Queue/ContextMenu.elm diff --git a/elm.json b/elm.json index 0f70e409..71e7667b 100644 --- a/elm.json +++ b/elm.json @@ -51,4 +51,4 @@ "direct": {}, "indirect": {} } -} \ No newline at end of file +} diff --git a/src/Applications/UI.elm b/src/Applications/UI.elm index dd5ec1db..c694ec47 100644 --- a/src/Applications/UI.elm +++ b/src/Applications/UI.elm @@ -55,6 +55,7 @@ import UI.Page as Page import UI.Ports as Ports import UI.Queue as Queue import UI.Queue.Common +import UI.Queue.ContextMenu as Queue import UI.Queue.Core as Queue import UI.Reply as Reply exposing (Reply(..)) import UI.Settings as Settings @@ -531,6 +532,9 @@ translateReply reply model = ----------------------------------------- -- Context Menu ----------------------------------------- + ShowFutureQueueItemMenu coordinates queueItem -> + return { model | contextMenu = Just (Queue.futureItemMenu queueItem coordinates) } + ShowMoreAuthenticationOptions coordinates -> return { model | contextMenu = Just (Authentication.moreOptionsMenu coordinates) } @@ -935,8 +939,8 @@ defaultScreen model = Page.Index -> nothing - Page.Queue _ -> - nothing + Page.Queue subPage -> + Html.map QueueMsg (Queue.view subPage model.queue) Page.Settings subPage -> Settings.view subPage model diff --git a/src/Applications/UI/Equalizer.elm b/src/Applications/UI/Equalizer.elm index 90e19d37..2c9e2c94 100644 --- a/src/Applications/UI/Equalizer.elm +++ b/src/Applications/UI/Equalizer.elm @@ -19,7 +19,7 @@ import UI.Kit import UI.Navigation exposing (..) import UI.Page import UI.Ports as Ports -import UI.Reply exposing (Reply) +import UI.Reply exposing (Reply(..)) @@ -151,7 +151,7 @@ update msg model = DeactivateKnob _ -> Return.replyWithModel { model | activeKnob = Nothing } - UI.Reply.SaveEnclosedUserData + SaveEnclosedUserData ----------------------------------------- -- Reset @@ -207,7 +207,7 @@ reset : Model -> Knob -> Float -> Return Model Msg Reply reset newModel knobType value = ( newModel , adjustKnob knobType value - , [ UI.Reply.SaveEnclosedUserData ] + , [ SaveEnclosedUserData ] ) @@ -224,7 +224,7 @@ view model = UI.Navigation.local [ ( Icon Icons.arrow_back , Label "Back to list" Hidden - , GoToPage UI.Page.Index + , NavigateToPage UI.Page.Index ) ] diff --git a/src/Applications/UI/Kit.elm b/src/Applications/UI/Kit.elm index f095042c..1662fcc9 100644 --- a/src/Applications/UI/Kit.elm +++ b/src/Applications/UI/Kit.elm @@ -246,7 +246,7 @@ buttonWithOptions tag attributes buttonColor buttonType maybeMsg child = canister : List (Html msg) -> Html msg canister children = chunk - [ T.mh1, T.ph3, T.pb3 ] + [ T.mh1, T.ph3, T.pb4 ] children @@ -497,8 +497,6 @@ vessel = [ css vesselStyles ] [ borderRadius , T.bg_white - , T.flex - , T.flex_column , T.flex_grow_1 , T.overflow_scroll , T.relative diff --git a/src/Applications/UI/List.elm b/src/Applications/UI/List.elm index fce0af20..f7e03d4e 100644 --- a/src/Applications/UI/List.elm +++ b/src/Applications/UI/List.elm @@ -1,6 +1,7 @@ module UI.List exposing (Action, Item, view) import Chunky exposing (..) +import Classes as C import Color exposing (Color) import Color.Ext as Color import Css exposing (px, solid) @@ -24,7 +25,7 @@ type alias Action msg = type alias Item msg = - { label : String + { label : Html msg , actions : List (Action msg) } @@ -49,19 +50,24 @@ item { label, actions } = brick [ css itemStyles ] [ T.flex, T.fw6, T.items_center, T.pv3 ] - [ chunk + [ -- Label + -------- + chunk [ T.flex_grow_1 ] - [ Html.text label ] + [ label ] + + -- Actions + ---------- , chunk [ T.flex, T.items_center ] (List.map (\action -> brick [ Attributes.fromUnstyled (onClick action.msg) - , style "line-height" "0" , title action.title ] - [ T.ml2 + [ C.lh_0 + , T.ml2 , T.pointer ] [ fromUnstyled (action.icon UI.Kit.colors.text 16) ] diff --git a/src/Applications/UI/Navigation.elm b/src/Applications/UI/Navigation.elm index 9f448686..df4fec6b 100644 --- a/src/Applications/UI/Navigation.elm +++ b/src/Applications/UI/Navigation.elm @@ -21,7 +21,7 @@ import UI.Page as Page exposing (Page) type Action msg - = GoToPage Page + = NavigateToPage Page | PerformMsg msg @@ -134,14 +134,14 @@ localItem : Int -> ( Icon msg, Label, Action msg ) -> Html msg localItem tabindex_ ( Icon icon, Label labelText labelType, action ) = slab (case action of - GoToPage page -> + NavigateToPage page -> Html.a PerformMsg msg -> Html.button ) [ case action of - GoToPage page -> + NavigateToPage page -> href (Page.toString page) PerformMsg msg -> diff --git a/src/Applications/UI/Page.elm b/src/Applications/UI/Page.elm index e24acd6e..571a3824 100644 --- a/src/Applications/UI/Page.elm +++ b/src/Applications/UI/Page.elm @@ -98,6 +98,9 @@ sameBase a b = ( Index, Equalizer ) -> True + ( Index, Queue _ ) -> + True + _ -> a == b diff --git a/src/Applications/UI/Queue.elm b/src/Applications/UI/Queue.elm index 65df7ae1..8f2d9060 100644 --- a/src/Applications/UI/Queue.elm +++ b/src/Applications/UI/Queue.elm @@ -1,15 +1,26 @@ -module UI.Queue exposing (initialModel, update) +module UI.Queue exposing (initialModel, update, view) +import Chunky exposing (..) import Conditional exposing (..) +import Html.Styled as Html exposing (Html, fromUnstyled, text) import List.Extra as List +import Material.Icons.Action as Icons +import Material.Icons.Image as Icons +import Material.Icons.Navigation as Icons import Queue exposing (..) import Return3 as Return exposing (..) +import Tachyons.Classes as T import Time import Tracks exposing (IdentifiedTrack) +import UI.Kit +import UI.List +import UI.Navigation exposing (..) +import UI.Page as Page import UI.Ports as Ports import UI.Queue.Common exposing (makeItem) import UI.Queue.Core exposing (..) import UI.Queue.Fill as Fill +import UI.Queue.Page as Queue exposing (Page(..)) import UI.Reply exposing (Reply(..)) @@ -37,6 +48,22 @@ initialModel = update : Msg -> Model -> Return Model Msg Reply update msg model = case msg of + ShowFutureItemMenu item mouseEvent -> + let + coordinates = + ( mouseEvent.clientPos + , mouseEvent.offsetPos + ) + |> (\( ( a, b ), ( c, d ) ) -> + { x = a - c + 8 + , y = b - d + 8 + } + ) + in + item + |> ShowFutureQueueItemMenu coordinates + |> returnReplyWithModel model + ------------------------------------ -- Combos ------------------------------------ @@ -169,6 +196,13 @@ update msg model = ------------------------------------ -- Contents ------------------------------------ + -- # Clear + -- + Clear -> + returnRepliesWithModel + { model | future = [], ignored = [] } + [ FillQueue ] + -- # Fill -- > Fill the queue with items. -- @@ -247,3 +281,157 @@ fillQueue timestamp availableTracks model = True -> { m | future = Fill.shuffled timestamp nonMissingTracks m } ) + + + +-- 🗺 + + +view : Queue.Page -> Model -> Html Msg +view page model = + UI.Kit.receptacle + (case page of + History -> + historyView model + + Index -> + futureView model + ) + + + +-- 🗺 ░░ FUTURE + + +futureView : Model -> List (Html Msg) +futureView model = + [ ----------------------------------------- + -- Navigation + ----------------------------------------- + UI.Navigation.local + [ ( Icon Icons.arrow_back + , Label "Back to list" Hidden + , NavigateToPage Page.Index + ) + , ( Icon Icons.event_seat + , Label "History" Shown + , NavigateToPage (Page.Queue History) + ) + , ( Icon Icons.cancel + , Label "Clear all" Shown + , PerformMsg Clear + ) + , ( Icon Icons.restore + , Label "Clear ignored" Shown + , PerformMsg Reset + ) + ] + + ----------------------------------------- + -- Content + ----------------------------------------- + , UI.Kit.canister + [ UI.Kit.h1 "Up next" + , model.future + |> List.indexedMap futureItem + |> UI.List.view + |> chunky [ T.mt3 ] + ] + ] + + +futureItem : Int -> Queue.Item -> UI.List.Item Msg +futureItem idx item = + let + ( _, track ) = + item.identifiedTrack + in + { label = + inline + [ ifThenElse item.manualEntry T.o_100 T.o_50 ] + [ inline + [ T.dib, T.f7, T.mr2 ] + [ text (String.fromInt <| idx + 1), text "." ] + , text (track.tags.artist ++ " - " ++ track.tags.title) + ] + , actions = + [] + } + + + +-- 🗺 ░░ HISTORY + + +historyView : Model -> List (Html Msg) +historyView model = + [ ----------------------------------------- + -- Navigation + ----------------------------------------- + UI.Navigation.local + [ ( Icon Icons.arrow_back + , Label "Back to list" Hidden + , NavigateToPage Page.Index + ) + , ( Icon Icons.event_seat + , Label "Up next" Shown + , NavigateToPage (Page.Queue Index) + ) + ] + + ----------------------------------------- + -- Content + ----------------------------------------- + , if List.isEmpty model.past then + chunk + [ T.relative ] + [ chunk + [ T.absolute, T.left_0, T.top_0 ] + [ UI.Kit.canister [ UI.Kit.h1 "History" ] ] + ] + + else + UI.Kit.canister + [ UI.Kit.h1 "History" + , model.past + |> List.reverse + |> List.indexedMap historyItem + |> UI.List.view + |> chunky [ T.mt3 ] + ] + + -- + , if List.isEmpty model.past then + UI.Kit.centeredContent + [ chunk + [ T.o_30 ] + [ fromUnstyled (Icons.music_note UI.Kit.colors.text 64) ] + , chunk + [ T.lh_copy, T.mt2, T.o_40, T.tc ] + [ text "Nothing here yet," + , lineBreak + , text "play some music first." + ] + ] + + else + nothing + ] + + +historyItem : Int -> Queue.Item -> UI.List.Item Msg +historyItem idx { identifiedTrack, manualEntry } = + let + ( _, track ) = + identifiedTrack + in + { label = + inline + [ ifThenElse manualEntry T.o_100 T.o_50 ] + [ inline + [ T.dib, T.f7, T.mr2 ] + [ text (String.fromInt <| idx + 1), text "." ] + , text (track.tags.artist ++ " - " ++ track.tags.title) + ] + , actions = [] + } diff --git a/src/Applications/UI/Queue/ContextMenu.elm b/src/Applications/UI/Queue/ContextMenu.elm new file mode 100644 index 00000000..17d7b5ef --- /dev/null +++ b/src/Applications/UI/Queue/ContextMenu.elm @@ -0,0 +1,18 @@ +module UI.Queue.ContextMenu exposing (futureItemMenu) + +import ContextMenu exposing (..) +import Coordinates exposing (Coordinates) +import Material.Icons.Action as Icons +import Queue +import Sources exposing (Source) +import UI.Core exposing (Msg(..)) + + + +-- 🔱 + + +futureItemMenu : Queue.Item -> Coordinates -> ContextMenu Msg +futureItemMenu item = + ContextMenu + [] diff --git a/src/Applications/UI/Queue/Core.elm b/src/Applications/UI/Queue/Core.elm index 863349f0..2cae17a9 100644 --- a/src/Applications/UI/Queue/Core.elm +++ b/src/Applications/UI/Queue/Core.elm @@ -1,5 +1,6 @@ module UI.Queue.Core exposing (Model, Msg(..)) +import Html.Events.Extra.Mouse as Mouse import Queue exposing (..) import Time import Tracks exposing (IdentifiedTrack) @@ -26,10 +27,11 @@ type alias Model = type Msg - = ------------------------------------ + = ShowFutureItemMenu Item Mouse.Event + ------------------------------------ -- Combos ------------------------------------ - InjectFirstAndPlay IdentifiedTrack + | InjectFirstAndPlay IdentifiedTrack ------------------------------------ -- Future ------------------------------------ @@ -43,6 +45,7 @@ type Msg ------------------------------------ -- Contents ------------------------------------ + | Clear | Reset | Fill Time.Posix (List IdentifiedTrack) ------------------------------------ diff --git a/src/Applications/UI/Reply.elm b/src/Applications/UI/Reply.elm index 4a5ff158..e0ada97e 100644 --- a/src/Applications/UI/Reply.elm +++ b/src/Applications/UI/Reply.elm @@ -20,6 +20,7 @@ type Reply ----------------------------------------- -- Context Menu ----------------------------------------- + | ShowFutureQueueItemMenu Coordinates Queue.Item | ShowMoreAuthenticationOptions Coordinates | ShowSourceContextMenu Coordinates Source | ShowTracksContextMenu Coordinates (List IdentifiedTrack) diff --git a/src/Applications/UI/Settings.elm b/src/Applications/UI/Settings.elm index 0f9e7f16..13556b82 100644 --- a/src/Applications/UI/Settings.elm +++ b/src/Applications/UI/Settings.elm @@ -44,7 +44,7 @@ index model = UI.Navigation.local [ ( Icon Icons.import_export , Label "Import / Export" Shown - , GoToPage (UI.Page.Settings ImportExport) + , NavigateToPage (UI.Page.Settings ImportExport) ) , ( Icon Icons.exit_to_app , Label "Sign out" Shown diff --git a/src/Applications/UI/Settings/ImportExport.elm b/src/Applications/UI/Settings/ImportExport.elm index 2d72a343..01ef0c10 100644 --- a/src/Applications/UI/Settings/ImportExport.elm +++ b/src/Applications/UI/Settings/ImportExport.elm @@ -25,7 +25,7 @@ view = UI.Navigation.local [ ( Icon Icons.arrow_back , Label "Settings" Hidden - , GoToPage (UI.Page.Settings UI.Settings.Page.Index) + , NavigateToPage (UI.Page.Settings UI.Settings.Page.Index) ) ] diff --git a/src/Applications/UI/Sources.elm b/src/Applications/UI/Sources.elm index 5d34642a..ea87880b 100644 --- a/src/Applications/UI/Sources.elm +++ b/src/Applications/UI/Sources.elm @@ -221,7 +221,7 @@ index model = UI.Navigation.local [ ( Icon Icons.add , Label "Add a new source" Shown - , UI.Navigation.GoToPage (UI.Page.Sources New) + , NavigateToPage (UI.Page.Sources New) ) -- Process @@ -259,7 +259,12 @@ index model = -- List ------- , model.collection - |> List.map (\s -> { label = Dict.fetch "name" "" s.data, actions = sourceActions s }) + |> List.map + (\source -> + { label = Html.text (Dict.fetch "name" "" source.data) + , actions = sourceActions source + } + ) |> UI.List.view ] ] @@ -283,7 +288,7 @@ sourceActions source = } -- - , { icon = Icons.settings + , { icon = Icons.more_vert , msg = SourceContextMenu source , title = "Menu" } diff --git a/src/Applications/UI/Sources/Form.elm b/src/Applications/UI/Sources/Form.elm index 30d1d7d7..64ed98eb 100644 --- a/src/Applications/UI/Sources/Form.elm +++ b/src/Applications/UI/Sources/Form.elm @@ -20,7 +20,7 @@ import Tachyons.Classes as T import UI.Kit exposing (ButtonType(..), select) import UI.Navigation exposing (..) import UI.Page as Page -import UI.Reply as Reply exposing (Reply) +import UI.Reply as Reply exposing (Reply(..)) import UI.Sources.Page as Sources @@ -90,8 +90,8 @@ update msg model = in returnRepliesWithModel { model | step = Where, context = defaultContext } - [ Reply.GoToPage (Page.Sources Sources.Index) - , Reply.AddSourceToCollection cleanContext + [ GoToPage (Page.Sources Sources.Index) + , AddSourceToCollection cleanContext ] Bypass -> @@ -100,15 +100,15 @@ update msg model = EditSource -> returnRepliesWithModel { model | step = Where, context = defaultContext } - [ Reply.ReplaceSourceInCollection model.context - , Reply.ProcessSources - , Reply.GoToPage (Page.Sources Sources.Index) + [ ReplaceSourceInCollection model.context + , ProcessSources + , GoToPage (Page.Sources Sources.Index) ] ReturnToIndex -> returnRepliesWithModel model - [ Reply.GoToPage (Page.Sources Sources.Index) ] + [ GoToPage (Page.Sources Sources.Index) ] SelectService serviceKey -> case Services.keyToType serviceKey of @@ -145,13 +145,13 @@ update msg model = ( Where, Dropbox ) -> model.context.data |> Sources.Services.Dropbox.authorizationUrl - |> Reply.ExternalSourceAuthorization + |> ExternalSourceAuthorization |> returnReplyWithModel model ( Where, Google ) -> model.context.data |> Sources.Services.Google.authorizationUrl - |> Reply.ExternalSourceAuthorization + |> ExternalSourceAuthorization |> returnReplyWithModel model _ -> @@ -206,7 +206,7 @@ newWhere { context } = UI.Navigation.local [ ( Icon Icons.arrow_back , Label "Back to list" Hidden - , GoToPage (Page.Sources Sources.Index) + , NavigateToPage (Page.Sources Sources.Index) ) ] diff --git a/src/Applications/UI/Tracks.elm b/src/Applications/UI/Tracks.elm index 3c17f1ed..fc1d5446 100644 --- a/src/Applications/UI/Tracks.elm +++ b/src/Applications/UI/Tracks.elm @@ -33,6 +33,7 @@ import UI.Kit import UI.Navigation exposing (..) import UI.Page exposing (Page) import UI.Ports +import UI.Queue.Page import UI.Reply exposing (Reply(..)) import UI.Tracks.Core exposing (..) import UI.Tracks.Scene.List @@ -349,7 +350,7 @@ view core = chunk [ T.flex , T.flex_column - , T.flex_grow_1 + , T.h_100 ] [ lazy3 navigation @@ -488,11 +489,11 @@ navigation favouritesOnly searchTerm page = ) , ( Icon Icons.event_seat , Label "Queue" Hidden - , PerformMsg Bypass + , NavigateToPage (UI.Page.Queue UI.Queue.Page.Index) ) , ( Icon Icons.equalizer , Label "Equalizer" Hidden - , UI.Navigation.GoToPage UI.Page.Equalizer + , NavigateToPage UI.Page.Equalizer ) ] ] -- 2.51.2