From 76f31a312979b7ed6ba1a7d4afe797336beb4a9f Mon Sep 17 00:00:00 2001 From: Steven Vandevelde Date: Sat, 14 Sep 2024 17:09:53 +0200 Subject: [PATCH] Basic setup for theming (#427) * feat: Reorganise Elm views into something that resembles themes * feat: Add 'change theme' item to command palette * feat: Add 'change theme' nav button * feat: Store & load selected theme --- Justfile | 10 +- elm.json | 123 +++++++++--------- src/{Applications => Core}/Brain.elm | 0 .../Brain/Common/State.elm | 0 .../Brain/Other/State.elm | 0 src/{Applications => Core}/Brain/Ports.elm | 0 .../Brain/Sources/Processing/Common.elm | 0 .../Brain/Sources/Processing/State.elm | 0 .../Brain/Sources/Processing/Steps.elm | 0 .../Brain/Sources/Processing/Types.elm | 0 .../Brain/Task/Ports.elm | 0 .../Brain/Tracks/State.elm | 0 src/{Applications => Core}/Brain/Types.elm | 0 .../Brain/User/Hypaethral.elm | 0 .../Brain/User/State.elm | 0 .../Brain/User/Types.elm | 0 .../Themes/Sunrise}/Alfred/View.elm | 2 +- .../UI => Core/Themes/Sunrise}/Console.elm | 2 +- .../Themes/Sunrise}/ContextMenu.elm | 2 +- .../UI => Core/Themes/Sunrise}/Kit.elm | 2 +- .../UI => Core/Themes/Sunrise}/List.elm | 2 +- .../UI => Core/Themes/Sunrise}/Navigation.elm | 28 +--- .../Themes/Sunrise}/Notifications.elm | 65 +-------- .../Themes/Sunrise}/Playlists/View.elm | 59 ++++----- .../UI => Core/Themes/Sunrise}/Queue/View.elm | 41 +++--- .../UI => Core/Themes/Sunrise}/Settings.elm | 55 ++++---- .../Themes/Sunrise}/Settings/Common.elm | 2 +- .../Themes/Sunrise}/Settings/Data.elm | 19 +-- .../Themes/Sunrise}/Settings/Sync.elm | 21 +-- .../Themes/Sunrise}/Sources/Form.elm | 97 +++++--------- .../Themes/Sunrise}/Sources/View.elm | 31 ++--- .../Themes/Sunrise}/Syncing/View.elm | 36 ++--- .../Themes/Sunrise/Theme.elm} | 82 +++++------- .../Themes/Sunrise}/Tracks/Scene.elm | 2 +- .../Themes/Sunrise}/Tracks/Scene/Covers.elm | 10 +- .../Themes/Sunrise}/Tracks/Scene/List.elm | 16 +-- .../Themes/Sunrise}/Tracks/View.elm | 43 +++--- src/{Applications => Core}/UI.elm | 7 + src/{Applications => Core}/UI/Adjunct.elm | 0 .../UI/Alfred/State.elm | 0 src/{Applications => Core}/UI/Audio/State.elm | 0 src/{Applications => Core}/UI/Audio/Types.elm | 0 src/{Applications => Core}/UI/Backdrop.elm | 0 .../UI/Commands/Alfred.elm | 6 +- .../UI/Commands/State.elm | 0 .../UI/Common/State.elm | 33 +++-- .../UI/Common/Types.elm | 0 src/{Applications => Core}/UI/Demo.elm | 0 src/{Applications => Core}/UI/DnD.elm | 0 .../UI/Equalizer/State.elm | 0 .../UI/Interface/State.elm | 43 ++++++ src/Core/UI/Navigation.elm | 30 +++++ src/Core/UI/Notifications.elm | 66 ++++++++++ src/{Applications => Core}/UI/Other/State.elm | 0 src/{Applications => Core}/UI/Page.elm | 0 .../UI/Playlists/Alfred.elm | 0 .../UI/Playlists/ContextMenu.elm | 0 .../UI/Playlists/Directory.elm | 0 .../UI/Playlists/Page.elm | 0 .../UI/Playlists/State.elm | 0 src/{Applications => Core}/UI/Ports.elm | 0 .../UI/Queue/ContextMenu.elm | 0 src/{Applications => Core}/UI/Queue/Fill.elm | 0 src/{Applications => Core}/UI/Queue/Page.elm | 0 src/{Applications => Core}/UI/Queue/State.elm | 0 src/{Applications => Core}/UI/Queue/Types.elm | 0 .../UI/Routing/State.elm | 0 .../UI/Services/State.elm | 0 .../UI/Settings/Page.elm | 0 .../UI/Sources/ContextMenu.elm | 0 src/Core/UI/Sources/Form.elm | 31 +++++ .../UI/Sources/Page.elm | 0 .../UI/Sources/Query.elm | 0 .../UI/Sources/State.elm | 0 .../UI/Sources/Types.elm | 0 .../UI/Svg/Elements.elm | 0 .../UI/Syncing/Common.elm | 20 ++- .../UI/Syncing/ContextMenu.elm | 0 .../UI/Syncing/State.elm | 32 +++-- .../UI/Syncing/Types.elm | 2 +- src/Core/UI/Theme.elm | 114 ++++++++++++++++ .../UI/Tracks/ContextMenu.elm | 0 .../UI/Tracks/Covers.elm | 0 .../UI/Tracks/State.elm | 21 +-- .../UI/Tracks/Types.elm | 0 src/{Applications => Core}/UI/Types.elm | 4 + .../UI/User/State/Export.elm | 1 + .../UI/User/State/Import.elm | 1 + src/Core/UI/View.elm | 16 +++ src/Library/Theme.elm | 28 ++++ src/Library/User/Layer.elm | 6 +- src/README.md | 12 +- 92 files changed, 716 insertions(+), 507 deletions(-) rename src/{Applications => Core}/Brain.elm (100%) rename src/{Applications => Core}/Brain/Common/State.elm (100%) rename src/{Applications => Core}/Brain/Other/State.elm (100%) rename src/{Applications => Core}/Brain/Ports.elm (100%) rename src/{Applications => Core}/Brain/Sources/Processing/Common.elm (100%) rename src/{Applications => Core}/Brain/Sources/Processing/State.elm (100%) rename src/{Applications => Core}/Brain/Sources/Processing/Steps.elm (100%) rename src/{Applications => Core}/Brain/Sources/Processing/Types.elm (100%) rename src/{Applications => Core}/Brain/Task/Ports.elm (100%) rename src/{Applications => Core}/Brain/Tracks/State.elm (100%) rename src/{Applications => Core}/Brain/Types.elm (100%) rename src/{Applications => Core}/Brain/User/Hypaethral.elm (100%) rename src/{Applications => Core}/Brain/User/State.elm (100%) rename src/{Applications => Core}/Brain/User/Types.elm (100%) rename src/{Applications/UI => Core/Themes/Sunrise}/Alfred/View.elm (99%) rename src/{Applications/UI => Core/Themes/Sunrise}/Console.elm (99%) rename src/{Applications/UI => Core/Themes/Sunrise}/ContextMenu.elm (98%) rename src/{Applications/UI => Core/Themes/Sunrise}/Kit.elm (99%) rename src/{Applications/UI => Core/Themes/Sunrise}/List.elm (98%) rename src/{Applications/UI => Core/Themes/Sunrise}/Navigation.elm (93%) rename src/{Applications/UI => Core/Themes/Sunrise}/Notifications.elm (66%) rename src/{Applications/UI => Core/Themes/Sunrise}/Playlists/View.elm (90%) rename src/{Applications/UI => Core/Themes/Sunrise}/Queue/View.elm (90%) rename src/{Applications/UI => Core/Themes/Sunrise}/Settings.elm (92%) rename src/{Applications/UI => Core/Themes/Sunrise}/Settings/Common.elm (86%) rename src/{Applications/UI => Core/Themes/Sunrise}/Settings/Data.elm (83%) rename src/{Applications/UI => Core/Themes/Sunrise}/Settings/Sync.elm (91%) rename src/{Applications/UI => Core/Themes/Sunrise}/Sources/Form.elm (89%) rename src/{Applications/UI => Core/Themes/Sunrise}/Sources/View.elm (92%) rename src/{Applications/UI => Core/Themes/Sunrise}/Syncing/View.elm (89%) rename src/{Applications/UI/View.elm => Core/Themes/Sunrise/Theme.elm} (83%) rename src/{Applications/UI => Core/Themes/Sunrise}/Tracks/Scene.elm (96%) rename src/{Applications/UI => Core/Themes/Sunrise}/Tracks/Scene/Covers.elm (98%) rename src/{Applications/UI => Core/Themes/Sunrise}/Tracks/Scene/List.elm (98%) rename src/{Applications/UI => Core/Themes/Sunrise}/Tracks/View.elm (94%) rename src/{Applications => Core}/UI.elm (99%) rename src/{Applications => Core}/UI/Adjunct.elm (100%) rename src/{Applications => Core}/UI/Alfred/State.elm (100%) rename src/{Applications => Core}/UI/Audio/State.elm (100%) rename src/{Applications => Core}/UI/Audio/Types.elm (100%) rename src/{Applications => Core}/UI/Backdrop.elm (100%) rename src/{Applications => Core}/UI/Commands/Alfred.elm (98%) rename src/{Applications => Core}/UI/Commands/State.elm (100%) rename src/{Applications => Core}/UI/Common/State.elm (88%) rename src/{Applications => Core}/UI/Common/Types.elm (100%) rename src/{Applications => Core}/UI/Demo.elm (100%) rename src/{Applications => Core}/UI/DnD.elm (100%) rename src/{Applications => Core}/UI/Equalizer/State.elm (100%) rename src/{Applications => Core}/UI/Interface/State.elm (82%) create mode 100644 src/Core/UI/Navigation.elm create mode 100644 src/Core/UI/Notifications.elm rename src/{Applications => Core}/UI/Other/State.elm (100%) rename src/{Applications => Core}/UI/Page.elm (100%) rename src/{Applications => Core}/UI/Playlists/Alfred.elm (100%) rename src/{Applications => Core}/UI/Playlists/ContextMenu.elm (100%) rename src/{Applications => Core}/UI/Playlists/Directory.elm (100%) rename src/{Applications => Core}/UI/Playlists/Page.elm (100%) rename src/{Applications => Core}/UI/Playlists/State.elm (100%) rename src/{Applications => Core}/UI/Ports.elm (100%) rename src/{Applications => Core}/UI/Queue/ContextMenu.elm (100%) rename src/{Applications => Core}/UI/Queue/Fill.elm (100%) rename src/{Applications => Core}/UI/Queue/Page.elm (100%) rename src/{Applications => Core}/UI/Queue/State.elm (100%) rename src/{Applications => Core}/UI/Queue/Types.elm (100%) rename src/{Applications => Core}/UI/Routing/State.elm (100%) rename src/{Applications => Core}/UI/Services/State.elm (100%) rename src/{Applications => Core}/UI/Settings/Page.elm (100%) rename src/{Applications => Core}/UI/Sources/ContextMenu.elm (100%) create mode 100644 src/Core/UI/Sources/Form.elm rename src/{Applications => Core}/UI/Sources/Page.elm (100%) rename src/{Applications => Core}/UI/Sources/Query.elm (100%) rename src/{Applications => Core}/UI/Sources/State.elm (100%) rename src/{Applications => Core}/UI/Sources/Types.elm (100%) rename src/{Applications => Core}/UI/Svg/Elements.elm (100%) rename src/{Applications => Core}/UI/Syncing/Common.elm (79%) rename src/{Applications => Core}/UI/Syncing/ContextMenu.elm (100%) rename src/{Applications => Core}/UI/Syncing/State.elm (94%) rename src/{Applications => Core}/UI/Syncing/Types.elm (97%) create mode 100644 src/Core/UI/Theme.elm rename src/{Applications => Core}/UI/Tracks/ContextMenu.elm (100%) rename src/{Applications => Core}/UI/Tracks/Covers.elm (100%) rename src/{Applications => Core}/UI/Tracks/State.elm (97%) rename src/{Applications => Core}/UI/Tracks/Types.elm (100%) rename src/{Applications => Core}/UI/Types.elm (98%) rename src/{Applications => Core}/UI/User/State/Export.elm (99%) rename src/{Applications => Core}/UI/User/State/Import.elm (99%) create mode 100644 src/Core/UI/View.elm create mode 100644 src/Library/Theme.elm diff --git a/Justfile b/Justfile index ffda525d..3cf21c47 100644 --- a/Justfile +++ b/Justfile @@ -65,7 +65,7 @@ check-versions: {{NPM_DIR}}/.bin/tailwind \ --input {{SRC_DIR}}/Css/Application.css \ --output {{BUILD_DIR}}/application.css \ - --content "{{SRC_DIR}}/Static/Html/**/*.*,{{SRC_DIR}}/Applications/UI/**/*.elm,{{SRC_DIR}}/Applications/UI.elm,{{SRC_DIR}}/Library/**/*.elm,{{SRC_DIR}}/Javascript/**/*.ts" \ + --content "{{SRC_DIR}}/Static/Html/**/*.*,{{SRC_DIR}}/Core/Themes/**/*.elm,{{SRC_DIR}}/Core/UI/**/*.elm,{{SRC_DIR}}/Core/UI.elm,{{SRC_DIR}}/Library/**/*.elm,{{SRC_DIR}}/Javascript/**/*.ts" \ --config {{SYSTEM_DIR}}/Css/Tailwind.js \ --postcss {{SYSTEM_DIR}}/Css/PostCSS.js \ --jit \ @@ -74,14 +74,14 @@ check-versions: @elm: echo "> Compiling Elm application" - {{NPM_DIR}}/.bin/elm make {{SRC_DIR}}/Applications/Brain.elm --output {{BUILD_DIR}}/js/brain.elm.js - {{NPM_DIR}}/.bin/elm make {{SRC_DIR}}/Applications/UI.elm --output {{BUILD_DIR}}/js/ui.elm.js + {{NPM_DIR}}/.bin/elm make {{SRC_DIR}}/Core/Brain.elm --output {{BUILD_DIR}}/js/brain.elm.js + {{NPM_DIR}}/.bin/elm make {{SRC_DIR}}/Core/UI.elm --output {{BUILD_DIR}}/js/ui.elm.js @elm-prod: echo "> Compiling Elm application (optimised)" - {{NPM_DIR}}/.bin/elm make {{SRC_DIR}}/Applications/Brain.elm --output {{BUILD_DIR}}/js/brain.elm.js --optimize - {{NPM_DIR}}/.bin/elm make {{SRC_DIR}}/Applications/UI.elm --output {{BUILD_DIR}}/js/ui.elm.js --optimize + {{NPM_DIR}}/.bin/elm make {{SRC_DIR}}/Core/Brain.elm --output {{BUILD_DIR}}/js/brain.elm.js --optimize + {{NPM_DIR}}/.bin/elm make {{SRC_DIR}}/Core/UI.elm --output {{BUILD_DIR}}/js/ui.elm.js --optimize {{NPM_DIR}}/.bin/esbuild {{BUILD_DIR}}/js/brain.elm.js \ --minify --outfile={{BUILD_DIR}}/js/brain.elm.tmp.js diff --git a/elm.json b/elm.json index 8e330c2a..0d5c346f 100644 --- a/elm.json +++ b/elm.json @@ -1,67 +1,64 @@ { - "type": "application", - "source-directories": [ - "src/Applications", - "src/Library" - ], - "elm-version": "0.19.1", - "dependencies": { - "direct": { - "FabienHenon/elm-infinite-list-view": "3.2.0", - "Fresheyeball/elm-return": "7.1.0", - "Gizra/elm-all-set": "1.0.1", - "Gizra/elm-debouncer": "2.0.0", - "Herteby/enum": "1.0.1", - "NoRedInk/elm-json-decode-pipeline": "1.0.1", - "arturopala/elm-monocle": "2.2.0", - "avh4/elm-color": "1.0.0", - "elm/browser": "1.0.2", - "elm/core": "1.0.5", - "elm/file": "1.0.5", - "elm/html": "1.0.0", - "elm/http": "2.0.0", - "elm/json": "1.1.3", - "elm/random": "1.0.0", - "elm/regex": "1.0.0", - "elm/svg": "1.0.1", - "elm/time": "1.0.0", - "elm/url": "1.0.0", - "elm/virtual-dom": "1.0.3", - "elm-community/dict-extra": "2.4.0", - "elm-community/html-extra": "3.4.0", - "elm-community/list-extra": "8.7.0", - "elm-community/maybe-extra": "5.3.0", - "elm-explorations/markdown": "1.0.0", - "icidasset/elm-binary": "2.1.0", - "icidasset/elm-material-icons": "11.0.0", - "icidasset/elm-sha": "2.0.2", - "jinjor/elm-xml-parser": "2.0.0", - "jzxhuang/http-extras": "2.1.0", - "lobanov/elm-taskport": "2.0.1", - "mpizenberg/elm-pointer-events": "4.0.2", - "newlandsvalley/elm-binary-base64": "1.0.3", - "noahzgordon/elm-color-extra": "1.0.2", - "ohanhi/keyboard": "2.0.1", - "prozacchiwawa/elm-urlbase64": "1.0.6", - "robinheghan/murmur3": "1.0.0", - "rtfeldman/elm-hex": "1.0.0", - "ryannhg/date-format": "2.3.0", - "truqu/elm-base64": "2.0.4", - "truqu/elm-md5": "1.1.0", - "wernerdegroot/listzipper": "4.0.0", - "ymtszw/elm-xml-decode": "3.2.2" - }, - "indirect": { - "elm/bytes": "1.0.8", - "elm/parser": "1.1.0", - "fredcy/elm-parseint": "2.0.1", - "miniBill/elm-xml-parser": "1.0.1", - "pzp1997/assoc-list": "1.0.0", - "zwilias/elm-utf-tools": "2.0.1" - } + "type": "application", + "source-directories": ["src/Core", "src/Library"], + "elm-version": "0.19.1", + "dependencies": { + "direct": { + "FabienHenon/elm-infinite-list-view": "3.2.0", + "Fresheyeball/elm-return": "7.1.0", + "Gizra/elm-all-set": "1.0.1", + "Gizra/elm-debouncer": "2.0.0", + "Herteby/enum": "1.0.1", + "NoRedInk/elm-json-decode-pipeline": "1.0.1", + "arturopala/elm-monocle": "2.2.0", + "avh4/elm-color": "1.0.0", + "elm/browser": "1.0.2", + "elm/core": "1.0.5", + "elm/file": "1.0.5", + "elm/html": "1.0.0", + "elm/http": "2.0.0", + "elm/json": "1.1.3", + "elm/random": "1.0.0", + "elm/regex": "1.0.0", + "elm/svg": "1.0.1", + "elm/time": "1.0.0", + "elm/url": "1.0.0", + "elm/virtual-dom": "1.0.3", + "elm-community/dict-extra": "2.4.0", + "elm-community/html-extra": "3.4.0", + "elm-community/list-extra": "8.7.0", + "elm-community/maybe-extra": "5.3.0", + "elm-explorations/markdown": "1.0.0", + "icidasset/elm-binary": "2.1.0", + "icidasset/elm-material-icons": "11.0.0", + "icidasset/elm-sha": "2.0.2", + "jinjor/elm-xml-parser": "2.0.0", + "jzxhuang/http-extras": "2.1.0", + "lobanov/elm-taskport": "2.0.1", + "mpizenberg/elm-pointer-events": "4.0.2", + "newlandsvalley/elm-binary-base64": "1.0.3", + "noahzgordon/elm-color-extra": "1.0.2", + "ohanhi/keyboard": "2.0.1", + "prozacchiwawa/elm-urlbase64": "1.0.6", + "robinheghan/murmur3": "1.0.0", + "rtfeldman/elm-hex": "1.0.0", + "ryannhg/date-format": "2.3.0", + "truqu/elm-base64": "2.0.4", + "truqu/elm-md5": "1.1.0", + "wernerdegroot/listzipper": "4.0.0", + "ymtszw/elm-xml-decode": "3.2.2" }, - "test-dependencies": { - "direct": {}, - "indirect": {} + "indirect": { + "elm/bytes": "1.0.8", + "elm/parser": "1.1.0", + "fredcy/elm-parseint": "2.0.1", + "miniBill/elm-xml-parser": "1.0.1", + "pzp1997/assoc-list": "1.0.0", + "zwilias/elm-utf-tools": "2.0.1" } + }, + "test-dependencies": { + "direct": {}, + "indirect": {} + } } diff --git a/src/Applications/Brain.elm b/src/Core/Brain.elm similarity index 100% rename from src/Applications/Brain.elm rename to src/Core/Brain.elm diff --git a/src/Applications/Brain/Common/State.elm b/src/Core/Brain/Common/State.elm similarity index 100% rename from src/Applications/Brain/Common/State.elm rename to src/Core/Brain/Common/State.elm diff --git a/src/Applications/Brain/Other/State.elm b/src/Core/Brain/Other/State.elm similarity index 100% rename from src/Applications/Brain/Other/State.elm rename to src/Core/Brain/Other/State.elm diff --git a/src/Applications/Brain/Ports.elm b/src/Core/Brain/Ports.elm similarity index 100% rename from src/Applications/Brain/Ports.elm rename to src/Core/Brain/Ports.elm diff --git a/src/Applications/Brain/Sources/Processing/Common.elm b/src/Core/Brain/Sources/Processing/Common.elm similarity index 100% rename from src/Applications/Brain/Sources/Processing/Common.elm rename to src/Core/Brain/Sources/Processing/Common.elm diff --git a/src/Applications/Brain/Sources/Processing/State.elm b/src/Core/Brain/Sources/Processing/State.elm similarity index 100% rename from src/Applications/Brain/Sources/Processing/State.elm rename to src/Core/Brain/Sources/Processing/State.elm diff --git a/src/Applications/Brain/Sources/Processing/Steps.elm b/src/Core/Brain/Sources/Processing/Steps.elm similarity index 100% rename from src/Applications/Brain/Sources/Processing/Steps.elm rename to src/Core/Brain/Sources/Processing/Steps.elm diff --git a/src/Applications/Brain/Sources/Processing/Types.elm b/src/Core/Brain/Sources/Processing/Types.elm similarity index 100% rename from src/Applications/Brain/Sources/Processing/Types.elm rename to src/Core/Brain/Sources/Processing/Types.elm diff --git a/src/Applications/Brain/Task/Ports.elm b/src/Core/Brain/Task/Ports.elm similarity index 100% rename from src/Applications/Brain/Task/Ports.elm rename to src/Core/Brain/Task/Ports.elm diff --git a/src/Applications/Brain/Tracks/State.elm b/src/Core/Brain/Tracks/State.elm similarity index 100% rename from src/Applications/Brain/Tracks/State.elm rename to src/Core/Brain/Tracks/State.elm diff --git a/src/Applications/Brain/Types.elm b/src/Core/Brain/Types.elm similarity index 100% rename from src/Applications/Brain/Types.elm rename to src/Core/Brain/Types.elm diff --git a/src/Applications/Brain/User/Hypaethral.elm b/src/Core/Brain/User/Hypaethral.elm similarity index 100% rename from src/Applications/Brain/User/Hypaethral.elm rename to src/Core/Brain/User/Hypaethral.elm diff --git a/src/Applications/Brain/User/State.elm b/src/Core/Brain/User/State.elm similarity index 100% rename from src/Applications/Brain/User/State.elm rename to src/Core/Brain/User/State.elm diff --git a/src/Applications/Brain/User/Types.elm b/src/Core/Brain/User/Types.elm similarity index 100% rename from src/Applications/Brain/User/Types.elm rename to src/Core/Brain/User/Types.elm diff --git a/src/Applications/UI/Alfred/View.elm b/src/Core/Themes/Sunrise/Alfred/View.elm similarity index 99% rename from src/Applications/UI/Alfred/View.elm rename to src/Core/Themes/Sunrise/Alfred/View.elm index 495cd6d1..afddc1cb 100644 --- a/src/Applications/UI/Alfred/View.elm +++ b/src/Core/Themes/Sunrise/Alfred/View.elm @@ -1,4 +1,4 @@ -module UI.Alfred.View exposing (view) +module Themes.Sunrise.Alfred.View exposing (view) import Alfred exposing (..) import Chunky exposing (..) diff --git a/src/Applications/UI/Console.elm b/src/Core/Themes/Sunrise/Console.elm similarity index 99% rename from src/Applications/UI/Console.elm rename to src/Core/Themes/Sunrise/Console.elm index a66216ca..5629bcca 100644 --- a/src/Applications/UI/Console.elm +++ b/src/Core/Themes/Sunrise/Console.elm @@ -1,4 +1,4 @@ -module UI.Console exposing (view) +module Themes.Sunrise.Console exposing (view) import Chunky exposing (..) import Conditional exposing (..) diff --git a/src/Applications/UI/ContextMenu.elm b/src/Core/Themes/Sunrise/ContextMenu.elm similarity index 98% rename from src/Applications/UI/ContextMenu.elm rename to src/Core/Themes/Sunrise/ContextMenu.elm index b4cea294..777675e8 100644 --- a/src/Applications/UI/ContextMenu.elm +++ b/src/Core/Themes/Sunrise/ContextMenu.elm @@ -1,4 +1,4 @@ -module UI.ContextMenu exposing (view) +module Themes.Sunrise.ContextMenu exposing (view) import Chunky exposing (..) import Conditional exposing (..) diff --git a/src/Applications/UI/Kit.elm b/src/Core/Themes/Sunrise/Kit.elm similarity index 99% rename from src/Applications/UI/Kit.elm rename to src/Core/Themes/Sunrise/Kit.elm index 6f67fe89..bf7e1996 100644 --- a/src/Applications/UI/Kit.elm +++ b/src/Core/Themes/Sunrise/Kit.elm @@ -1,4 +1,4 @@ -module UI.Kit exposing (..) +module Themes.Sunrise.Kit exposing (..) import Chunky exposing (..) import Color diff --git a/src/Applications/UI/List.elm b/src/Core/Themes/Sunrise/List.elm similarity index 98% rename from src/Applications/UI/List.elm rename to src/Core/Themes/Sunrise/List.elm index 450d3f76..b0da73a0 100644 --- a/src/Applications/UI/List.elm +++ b/src/Core/Themes/Sunrise/List.elm @@ -1,4 +1,4 @@ -module UI.List exposing (Action, Item, Variant(..), view) +module Themes.Sunrise.List exposing (Action, Item, Variant(..), view) import Chunky exposing (..) import Conditional exposing (..) diff --git a/src/Applications/UI/Navigation.elm b/src/Core/Themes/Sunrise/Navigation.elm similarity index 93% rename from src/Applications/UI/Navigation.elm rename to src/Core/Themes/Sunrise/Navigation.elm index e9469237..001a1a97 100644 --- a/src/Applications/UI/Navigation.elm +++ b/src/Core/Themes/Sunrise/Navigation.elm @@ -1,4 +1,4 @@ -module UI.Navigation exposing (Action(..), Icon(..), Label(..), LabelType(..), global, local, localWithTabindex) +module Themes.Sunrise.Navigation exposing (global, local, localWithTabindex) import Alfred exposing (Alfred) import Chunky exposing (..) @@ -10,35 +10,11 @@ import Html.Events exposing (onClick) import Html.Events.Extra.Mouse as Mouse import Material.Icons.Types exposing (Coloring(..)) import Maybe.Extra as Maybe -import Svg exposing (Svg) +import UI.Navigation exposing (..) import UI.Page as Page exposing (Page) --- 🌳 - - -type Action msg - = NavigateToPage Page - | OpenLinkInNewPage String - | PerformMsg msg - | PerformMsgWithMouseEvent (Mouse.Event -> msg) - - -type Icon msg - = Icon (Int -> Coloring -> Svg msg) - - -type Label - = Label String LabelType - - -type LabelType - = Hidden - | Shown - - - -- GLOBAL diff --git a/src/Applications/UI/Notifications.elm b/src/Core/Themes/Sunrise/Notifications.elm similarity index 66% rename from src/Applications/UI/Notifications.elm rename to src/Core/Themes/Sunrise/Notifications.elm index 8b4e6343..b28bf72e 100644 --- a/src/Applications/UI/Notifications.elm +++ b/src/Core/Themes/Sunrise/Notifications.elm @@ -1,4 +1,4 @@ -module UI.Notifications exposing (Model, dismiss, show, showWithModel, view) +module Themes.Sunrise.Notifications exposing (view) import Chunky exposing (..) import Color exposing (Color) @@ -10,72 +10,11 @@ import Html.Ext exposing (onDoubleTap, onTap) import Html.Lazy import Maybe.Extra as Maybe import Notifications exposing (..) -import Process -import Task +import UI.Notifications exposing (Model) import UI.Types exposing (Msg(..)) --- 🌳 - - -type alias Model = - List (Notification Msg) - - - --- 📣 - - -dismiss : Model -> { id : Int } -> ( Model, Cmd Msg ) -dismiss collection { id } = - ( List.map - (\notification -> - if Notifications.id notification == id then - Notifications.dismiss notification - - else - notification - ) - collection - , Task.perform - (\_ -> RemoveNotification { id = id }) - (Process.sleep 500) - ) - - -show : Notification Msg -> Model -> ( Model, Cmd Msg ) -show notification collection = - let - existingNotificationIds = - List.map Notifications.id collection - in - if List.member (Notifications.id notification) existingNotificationIds then - -- Don't show duplicate notifications - ( collection - , Cmd.none - ) - - else - ( notification :: collection - -- Hide notification after a certain amount of time, - -- unless it's a sticky notification. - , if (Notifications.options notification).sticky then - Cmd.none - - else - Task.perform - (\_ -> DismissNotification { id = Notifications.id notification }) - (Process.sleep 7500) - ) - - -showWithModel : Model -> Notification Msg -> ( Model, Cmd Msg ) -showWithModel model notification = - show notification model - - - -- 🗺 diff --git a/src/Applications/UI/Playlists/View.elm b/src/Core/Themes/Sunrise/Playlists/View.elm similarity index 90% rename from src/Applications/UI/Playlists/View.elm rename to src/Core/Themes/Sunrise/Playlists/View.elm index e86c61f4..f0d17722 100644 --- a/src/Applications/UI/Playlists/View.elm +++ b/src/Core/Themes/Sunrise/Playlists/View.elm @@ -1,4 +1,4 @@ -module UI.Playlists.View exposing (view) +module Themes.Sunrise.Playlists.View exposing (view) import Chunky exposing (..) import Color exposing (Color) @@ -10,8 +10,9 @@ import List.Extra as List import Material.Icons.Round as Icons import Material.Icons.Types exposing (Coloring(..)) import Playlists exposing (..) -import UI.Kit exposing (ButtonType(..)) -import UI.List +import Themes.Sunrise.Kit as Kit exposing (ButtonType(..)) +import Themes.Sunrise.List +import Themes.Sunrise.Navigation as Navigation import UI.Navigation exposing (..) import UI.Page as Page import UI.Playlists.Page exposing (..) @@ -25,7 +26,7 @@ import Url view : Page -> List Playlist -> Maybe Playlist -> Maybe { oldName : String, newName : String } -> Maybe Color -> Bool -> Html Msg view page playlists selectedPlaylist editContext bgColor authMethodSupportsPublicData = - UI.Kit.receptacle + Kit.receptacle { scrolling = True } (case page of Edit encodedName -> @@ -126,7 +127,7 @@ index playlists selectedPlaylist bgColor authMethodSupportsPublicData = [ ----------------------------------------- -- Navigation ----------------------------------------- - UI.Navigation.local + Navigation.local [ ( Icon Icons.arrow_back , Label Common.backToIndex Hidden , NavigateToPage Page.Index @@ -145,12 +146,12 @@ index playlists selectedPlaylist bgColor authMethodSupportsPublicData = [ "relative" ] [ chunk [ "absolute", "left-0", "top-0" ] - [ UI.Kit.canister [ UI.Kit.h1 "Playlists" ] ] + [ Kit.canister [ Kit.h1 "Playlists" ] ] ] else - UI.Kit.canister - [ UI.Kit.h1 "Playlists" + Kit.canister + [ Kit.h1 "Playlists" -- Intro -------- @@ -164,8 +165,8 @@ index playlists selectedPlaylist bgColor authMethodSupportsPublicData = else raw [ category "Your Playlists" - , UI.List.view - UI.List.Normal + , Themes.Sunrise.List.view + Themes.Sunrise.List.Normal (List.map customPlaylistListItem customPlaylists) ] @@ -177,15 +178,15 @@ index playlists selectedPlaylist bgColor authMethodSupportsPublicData = else raw [ category "Autogenerated Directory Playlists" - , UI.List.view - UI.List.Normal + , Themes.Sunrise.List.view + Themes.Sunrise.List.Normal (List.map directoryPlaylistListItem directoryPlaylists) ] ] -- , if List.isEmpty playlists then - UI.Kit.centeredContent + Kit.centeredContent [ slab Html.a [ href (Page.toString <| Page.Playlists New) ] @@ -223,7 +224,7 @@ intro = , text "There's also directory playlists, which are playlists derived from root directories." ] |> raw - |> UI.Kit.intro + |> Kit.intro category : String -> Html Msg @@ -242,16 +243,16 @@ category cat = ------------ , "dark:text-base04" ] - [ UI.Kit.inlineIcon Icons.folder + [ Kit.inlineIcon Icons.folder , inline [ "font-bold", "ml-2" ] [ text cat ] ] -selectedPlaylistListItem : Playlist -> Maybe Color -> UI.List.Item Msg +selectedPlaylistListItem : Playlist -> Maybe Color -> Themes.Sunrise.List.Item Msg selectedPlaylistListItem playlist bgColor = let selectionColor = - Maybe.withDefault UI.Kit.colors.selection bgColor + Maybe.withDefault Kit.colors.selection bgColor in { label = brick @@ -285,7 +286,7 @@ new = [ ----------------------------------------- -- Navigation ----------------------------------------- - UI.Navigation.local + Navigation.local [ ( Icon Icons.arrow_back , Label "Back to list" Hidden , NavigateToPage (Page.Playlists Index) @@ -295,28 +296,28 @@ new = ----------------------------------------- -- Content ----------------------------------------- - , [ UI.Kit.h2 "Name your playlist" + , [ Kit.h2 "Name your playlist" -- , [ onInput SetPlaylistCreationContext , placeholder "The Classics" ] - |> UI.Kit.textField + |> Kit.textField |> chunky [ "max-w-md", "mx-auto" ] -- Button --------- , chunk [ "mt-10" ] - [ UI.Kit.button + [ Kit.button Normal Bypass (text "Create playlist") ] ] - |> UI.Kit.canisterForm + |> Kit.canisterForm |> List.singleton - |> UI.Kit.centeredContent + |> Kit.centeredContent |> List.singleton |> slab Html.form @@ -337,7 +338,7 @@ edit editContext playlist = [ ----------------------------------------- -- Navigation ----------------------------------------- - UI.Navigation.local + Navigation.local [ ( Icon Icons.arrow_back , Label "Back to list" Hidden , NavigateToPage (Page.Playlists Index) @@ -347,7 +348,7 @@ edit editContext playlist = ----------------------------------------- -- Content ----------------------------------------- - , [ UI.Kit.h2 "Name your playlist" + , [ Kit.h2 "Name your playlist" -- , [ onInput (SetPlaylistModificationContext playlist.name) @@ -365,22 +366,22 @@ edit editContext playlist = Nothing -> value playlist.name ] - |> UI.Kit.textField + |> Kit.textField |> chunky [ "max-w-md", "mx-auto" ] -- Button --------- , chunk [ "mt-10" ] - [ UI.Kit.button + [ Kit.button Normal Bypass (text "Save") ] ] - |> UI.Kit.canisterForm + |> Kit.canisterForm |> List.singleton - |> UI.Kit.centeredContent + |> Kit.centeredContent |> List.singleton |> slab Html.form diff --git a/src/Applications/UI/Queue/View.elm b/src/Core/Themes/Sunrise/Queue/View.elm similarity index 90% rename from src/Applications/UI/Queue/View.elm rename to src/Core/Themes/Sunrise/Queue/View.elm index 3e58e49e..b6ac02ad 100644 --- a/src/Applications/UI/Queue/View.elm +++ b/src/Core/Themes/Sunrise/Queue/View.elm @@ -1,4 +1,4 @@ -module UI.Queue.View exposing (view) +module Themes.Sunrise.Queue.View exposing (view) import Chunky exposing (..) import Common @@ -10,9 +10,10 @@ import Icons import Material.Icons.Round as Icons import Material.Icons.Types exposing (Coloring(..)) import Queue exposing (..) +import Themes.Sunrise.Kit as Kit +import Themes.Sunrise.List +import Themes.Sunrise.Navigation as Navigation import UI.DnD as DnD -import UI.Kit -import UI.List import UI.Navigation exposing (..) import UI.Page as Page import UI.Queue.Page as Queue exposing (Page(..)) @@ -48,12 +49,12 @@ view page model = futureView : List Queue.Item -> Maybe Queue.Item -> DnD.Model Int -> Html UI.Msg futureView playingNext selectedQueueItem dnd = - UI.Kit.receptacle + Kit.receptacle { scrolling = not (DnD.isDragging dnd) } [ ----------------------------------------- -- Navigation ----------------------------------------- - UI.Navigation.local + Navigation.local [ ( Icon Icons.arrow_back , Label Common.backToIndex Hidden , NavigateToPage Page.Index @@ -80,16 +81,16 @@ futureView playingNext selectedQueueItem dnd = [ "relative" ] [ chunk [ "absolute", "left-0", "top-0" ] - [ UI.Kit.canister [ UI.Kit.h1 "Up next" ] ] + [ Kit.canister [ Kit.h1 "Up next" ] ] ] else - UI.Kit.canister - [ UI.Kit.h1 "Up next" + Kit.canister + [ Kit.h1 "Up next" , playingNext |> List.indexedMap (futureItem selectedQueueItem) - |> UI.List.view - (UI.List.Draggable + |> Themes.Sunrise.List.view + (Themes.Sunrise.List.Draggable { model = dnd , toMsg = UI.DnD } @@ -99,7 +100,7 @@ futureView playingNext selectedQueueItem dnd = -- , if List.isEmpty playingNext then - UI.Kit.centeredContent + Kit.centeredContent [ slab Html.a [ href (Page.toString <| Page.Sources UI.Sources.Page.New) ] @@ -120,7 +121,7 @@ futureView playingNext selectedQueueItem dnd = ] -futureItem : Maybe Item -> Int -> Queue.Item -> UI.List.Item UI.Msg +futureItem : Maybe Item -> Int -> Queue.Item -> Themes.Sunrise.List.Item UI.Msg futureItem selectedQueueItem idx item = let ( identifiers, track ) = @@ -222,12 +223,12 @@ subtleFutureIconClasses = historyView : List Queue.Item -> DnD.Model Int -> Html UI.Msg historyView playedPreviously dnd = - UI.Kit.receptacle + Kit.receptacle { scrolling = not (DnD.isDragging dnd) } [ ----------------------------------------- -- Navigation ----------------------------------------- - UI.Navigation.local + Navigation.local [ ( Icon Icons.arrow_back , Label Common.backToIndex Hidden , NavigateToPage Page.Index @@ -246,22 +247,22 @@ historyView playedPreviously dnd = [ "relative" ] [ chunk [ "absolute", "left-0", "top-0" ] - [ UI.Kit.canister [ UI.Kit.h1 "History" ] ] + [ Kit.canister [ Kit.h1 "History" ] ] ] else - UI.Kit.canister - [ UI.Kit.h1 "History" + Kit.canister + [ Kit.h1 "History" , playedPreviously |> List.reverse |> List.indexedMap historyItem - |> UI.List.view UI.List.Normal + |> Themes.Sunrise.List.view Themes.Sunrise.List.Normal |> chunky [ "mt-3" ] ] -- , if List.isEmpty playedPreviously then - UI.Kit.centeredContent + Kit.centeredContent [ chunk [ "opacity-30" ] [ Icons.music_note 64 Inherit ] @@ -278,7 +279,7 @@ historyView playedPreviously dnd = ] -historyItem : Int -> Queue.Item -> UI.List.Item UI.Msg +historyItem : Int -> Queue.Item -> Themes.Sunrise.List.Item UI.Msg historyItem idx ({ identifiedTrack } as item) = let ( _, track ) = diff --git a/src/Applications/UI/Settings.elm b/src/Core/Themes/Sunrise/Settings.elm similarity index 92% rename from src/Applications/UI/Settings.elm rename to src/Core/Themes/Sunrise/Settings.elm index 326cad0b..6eaa3bc1 100644 --- a/src/Applications/UI/Settings.elm +++ b/src/Core/Themes/Sunrise/Settings.elm @@ -1,4 +1,4 @@ -module UI.Settings exposing (Dependencies, view) +module Themes.Sunrise.Settings exposing (Dependencies, view) import Chunky exposing (..) import Color exposing (Color) @@ -13,14 +13,15 @@ import LastFm import Material.Icons.Round as Icons import Material.Icons.Types exposing (Coloring(..)) import Maybe.Extra as Maybe +import Themes.Sunrise.Kit as Kit +import Themes.Sunrise.Navigation as Navigation +import Themes.Sunrise.Settings.Data +import Themes.Sunrise.Settings.Sync import Time import UI.Backdrop as Backdrop exposing (backgroundPositioning) -import UI.Kit import UI.Navigation exposing (..) import UI.Page as Page -import UI.Settings.Data import UI.Settings.Page as Settings exposing (..) -import UI.Settings.Sync import UI.Sources.Types as Sources import UI.Tracks.Types as Tracks import UI.Types exposing (Msg(..)) @@ -51,13 +52,13 @@ view : Settings.Page -> Dependencies -> Html Msg view page deps = case page of Data -> - UI.Settings.Data.view deps.syncMethod + Themes.Sunrise.Settings.Data.view deps.syncMethod Index -> - UI.Kit.receptacle { scrolling = True } (index deps) + Kit.receptacle { scrolling = True } (index deps) Sync -> - UI.Settings.Sync.view deps.syncMethod + Themes.Sunrise.Settings.Sync.view deps.syncMethod @@ -69,11 +70,15 @@ index deps = [ ----------------------------------------- -- Navigation ----------------------------------------- - UI.Navigation.local + Navigation.local [ ( Icon Icons.account_circle , Label "Data & Sync" Shown , NavigateToPage (Page.Settings Sync) ) + , ( Icon Icons.brush + , Label "Change theme" Shown + , PerformMsg AssistWithChangingTheme + ) , ( Icon Icons.help_outline , Label "Help" Shown , OpenLinkInNewPage "about/" @@ -87,7 +92,7 @@ index deps = |> content |> chunk [ "pb-4" ] |> List.singleton - |> UI.Kit.canister + |> Kit.canister ] @@ -96,7 +101,7 @@ content deps = [ ----------------------------------------- -- Title ----------------------------------------- - UI.Kit.h1 "Settings" + Kit.h1 "Settings" ----------------------------------------- -- Version @@ -229,9 +234,9 @@ content deps = [ chunk [ "w-full", "md:w-1/2" ] [ label "Downloaded tracks" - , UI.Kit.buttonWithColor - UI.Kit.Gray - UI.Kit.Normal + , Kit.buttonWithColor + Kit.Gray + Kit.Normal (TracksMsg Tracks.ClearCache) (text "Clear cache") ] @@ -245,22 +250,22 @@ content deps = -- , case ( deps.lastFm.authenticating, deps.lastFm.sessionKey ) of ( _, Just _ ) -> - UI.Kit.checkbox + Kit.checkbox { checked = True , toggleMsg = DisconnectLastFm } ( True, Nothing ) -> - UI.Kit.buttonWithColor - UI.Kit.Gray - UI.Kit.Normal + Kit.buttonWithColor + Kit.Gray + Kit.Normal Bypass (text "Connecting") ( False, Nothing ) -> - UI.Kit.buttonWithColor - UI.Kit.Gray - UI.Kit.Normal + Kit.buttonWithColor + Kit.Gray + Kit.Normal ConnectLastFm (text "Connect") ] @@ -274,7 +279,7 @@ content deps = [ chunk [ "w-full", "md:w-1/2" ] [ label "Hide Duplicates" - , UI.Kit.checkbox + , Kit.checkbox { checked = deps.hideDuplicateTracks , toggleMsg = TracksMsg Tracks.ToggleHideDuplicates } @@ -282,7 +287,7 @@ content deps = , chunk [ "w-full", "md:w-1/2" ] [ label "Process sources automatically" - , UI.Kit.checkbox + , Kit.checkbox { checked = deps.processAutomatically , toggleMsg = SourcesMsg Sources.ToggleProcessAutomatically } @@ -297,7 +302,7 @@ content deps = [ chunk [ "w-full", "md:w-1/2" ] [ label "Remember position on long tracks" - , UI.Kit.checkbox + , Kit.checkbox { checked = deps.rememberProgress , toggleMsg = ToggleRememberProgress } @@ -305,7 +310,7 @@ content deps = , chunk [ "w-full", "md:w-1/2" ] [ label "Cover selection reduces track pool" - , UI.Kit.checkbox + , Kit.checkbox { checked = deps.coverSelectionReducesPool , toggleMsg = TracksMsg Tracks.ToggleCoverSelectionReducesPool } @@ -318,7 +323,7 @@ label : String -> Html msg label l = chunk [ "mb-3", "mt-6", "pb-px" ] - [ UI.Kit.label [] l ] + [ Kit.label [] l ] diff --git a/src/Applications/UI/Settings/Common.elm b/src/Core/Themes/Sunrise/Settings/Common.elm similarity index 86% rename from src/Applications/UI/Settings/Common.elm rename to src/Core/Themes/Sunrise/Settings/Common.elm index 6fb765a4..9c763cb2 100644 --- a/src/Applications/UI/Settings/Common.elm +++ b/src/Core/Themes/Sunrise/Settings/Common.elm @@ -1,4 +1,4 @@ -module UI.Settings.Common exposing (..) +module Themes.Sunrise.Settings.Common exposing (..) import Material.Icons.Round as Icons import UI.Navigation exposing (..) diff --git a/src/Applications/UI/Settings/Data.elm b/src/Core/Themes/Sunrise/Settings/Data.elm similarity index 83% rename from src/Applications/UI/Settings/Data.elm rename to src/Core/Themes/Sunrise/Settings/Data.elm index e56bc4a7..cc74382e 100644 --- a/src/Applications/UI/Settings/Data.elm +++ b/src/Core/Themes/Sunrise/Settings/Data.elm @@ -1,12 +1,13 @@ -module UI.Settings.Data exposing (view) +module Themes.Sunrise.Settings.Data exposing (view) import Chunky exposing (..) import Html exposing (Html, text) import Material.Icons.Round as Icons -import UI.Kit exposing (ButtonColor(..), ButtonType(..)) +import Themes.Sunrise.Kit as Kit exposing (ButtonColor(..), ButtonType(..)) +import Themes.Sunrise.Navigation as Navigation +import Themes.Sunrise.Settings.Common exposing (changePassphrase) import UI.Navigation exposing (..) import UI.Page as Page -import UI.Settings.Common exposing (changePassphrase) import UI.Settings.Page exposing (Page(..)) import UI.Types exposing (Msg(..)) import User.Layer exposing (Method(..)) @@ -18,7 +19,7 @@ import User.Layer exposing (Method(..)) view : Maybe Method -> Html Msg view activeMethod = - UI.Kit.receptacle + Kit.receptacle { scrolling = True } [ ----------------------------------------- -- Navigation @@ -49,7 +50,7 @@ view activeMethod = , NavigateToPage (Page.Settings Sync) ) ] - |> UI.Navigation.local + |> Navigation.local ----------------------------------------- -- Content @@ -58,11 +59,11 @@ view activeMethod = [ "relative" ] [ chunk [ "absolute", "left-0", "top-0" ] - [ UI.Kit.canister [ UI.Kit.h1 "Data Backup" ] ] + [ Kit.canister [ Kit.h1 "Data Backup" ] ] ] -- - , UI.Kit.focusScreen + , Kit.focusScreen { icon = Icons.archive , iconHref = Nothing , text = @@ -75,13 +76,13 @@ view activeMethod = } [ chunk [ "flex", "space-x-2.5" ] - [ UI.Kit.button + [ Kit.button Normal RequestImport (text "Import snapshot") -- - , UI.Kit.buttonWithColor + , Kit.buttonWithColor Accent Filled Export diff --git a/src/Applications/UI/Settings/Sync.elm b/src/Core/Themes/Sunrise/Settings/Sync.elm similarity index 91% rename from src/Applications/UI/Settings/Sync.elm rename to src/Core/Themes/Sunrise/Settings/Sync.elm index 8a32f4b0..d762c3b7 100644 --- a/src/Applications/UI/Settings/Sync.elm +++ b/src/Core/Themes/Sunrise/Settings/Sync.elm @@ -1,14 +1,15 @@ -module UI.Settings.Sync exposing (view) +module Themes.Sunrise.Settings.Sync exposing (view) import Chunky exposing (..) import Html exposing (Html, text) import Material.Icons.Round as Icons import Maybe.Extra as Maybe -import UI.Kit -import UI.List +import Themes.Sunrise.Kit as Kit +import Themes.Sunrise.List +import Themes.Sunrise.Navigation as Navigation +import Themes.Sunrise.Settings.Common exposing (changePassphrase) import UI.Navigation exposing (..) import UI.Page as Page -import UI.Settings.Common exposing (changePassphrase) import UI.Settings.Page exposing (Page(..)) import UI.Svg.Elements import UI.Syncing.Common exposing (startDropbox, startFission, startIpfs, startRemoteStorage) @@ -23,7 +24,7 @@ import User.Layer exposing (Method(..), dropboxMethod, fissionMethod, ipfsMethod view : Maybe Method -> Html Msg view activeMethod = - UI.Kit.receptacle + Kit.receptacle { scrolling = True } [ ----------------------------------------- -- Navigation @@ -54,7 +55,7 @@ view activeMethod = , NavigateToPage (Page.Settings Data) ) ] - |> UI.Navigation.local + |> Navigation.local ----------------------------------------- -- Content @@ -63,11 +64,11 @@ view activeMethod = [ "relative" ] [ chunk [ "absolute", "left-0", "top-0" ] - [ UI.Kit.canister [ UI.Kit.h1 "Storage Service" ] ] + [ Kit.canister [ Kit.h1 "Storage Service" ] ] ] -- - , UI.Kit.focusScreen + , Kit.focusScreen { icon = Icons.account_circle , iconHref = Nothing , text = @@ -84,14 +85,14 @@ view activeMethod = , ipfsMethod ] |> List.map (methodView activeMethod) - |> UI.List.view UI.List.Normal + |> Themes.Sunrise.List.view Themes.Sunrise.List.Normal |> List.singleton |> chunk [ "max-w-full", "w-96" ] ] ] -methodInfoAction : Bool -> Maybe Method -> Method -> UI.List.Action Msg +methodInfoAction : Bool -> Maybe Method -> Method -> Themes.Sunrise.List.Action Msg methodInfoAction isSelected activeMethod method = { icon = \a b -> diff --git a/src/Applications/UI/Sources/Form.elm b/src/Core/Themes/Sunrise/Sources/Form.elm similarity index 89% rename from src/Applications/UI/Sources/Form.elm rename to src/Core/Themes/Sunrise/Sources/Form.elm index 0649179f..80142fa3 100644 --- a/src/Applications/UI/Sources/Form.elm +++ b/src/Core/Themes/Sunrise/Sources/Form.elm @@ -1,4 +1,4 @@ -module UI.Sources.Form exposing (..) +module Themes.Sunrise.Sources.Form exposing (..) import Chunky exposing (..) import Common exposing (boolFromString, boolToString) @@ -12,7 +12,8 @@ import Material.Icons.Round as Icons import Material.Icons.Types exposing (Coloring(..)) import Sources exposing (..) import Sources.Services as Services -import UI.Kit exposing (ButtonType(..), select) +import Themes.Sunrise.Kit as Kit exposing (ButtonType(..), select) +import Themes.Sunrise.Navigation as Navigation import UI.Navigation exposing (..) import UI.Page as Page import UI.Sources.Page as Sources @@ -20,32 +21,6 @@ import UI.Sources.Types exposing (..) --- 🌳 - - -initialModel : Form -initialModel = - { step = Where - , context = defaultContext - } - - -defaultContext : Source -defaultContext = - { id = "CHANGE_ME_PLEASE" - , data = Services.initialData defaultService - , directoryPlaylists = True - , enabled = True - , service = defaultService - } - - -defaultService : Service -defaultService = - Dropbox - - - -- NEW @@ -71,7 +46,7 @@ newWhere { onboarding } { context } = [ ----------------------------------------- -- Navigation ----------------------------------------- - UI.Navigation.local + Navigation.local [ ( Icon Icons.arrow_back , Label "Back to list" Hidden -- @@ -88,9 +63,9 @@ newWhere { onboarding } { context } = ----------------------------------------- , (\h -> form TakeStep - [ UI.Kit.canisterForm h ] + [ Kit.canisterForm h ] ) - [ UI.Kit.h2 "Where is your music stored?" + [ Kit.h2 "Where is your music stored?" -- Dropdown ----------- @@ -111,7 +86,7 @@ newWhere { onboarding } { context } = --------- , chunk [ "mt-10" ] - [ UI.Kit.button + [ Kit.button IconOnly Bypass (Icons.arrow_forward 17 Inherit) @@ -125,7 +100,7 @@ newHow { context } = [ ----------------------------------------- -- Navigation ----------------------------------------- - UI.Navigation.local + Navigation.local [ ( Icon Icons.arrow_back , Label "Take a step back" Shown , PerformMsg TakeStepBackwards @@ -139,10 +114,10 @@ newHow { context } = form TakeStep [ chunk [ "text-left", "w-full" ] - [ UI.Kit.canister h ] + [ Kit.canister h ] ] ) - [ UI.Kit.h3 "Where exactly?" + [ Kit.h3 "Where exactly?" -- Note ------- @@ -174,7 +149,7 @@ newHow { context } = --------- , chunk [ "mt-3", "text-center" ] - [ UI.Kit.button + [ Kit.button IconOnly Bypass (Icons.arrow_forward 17 Inherit) @@ -199,7 +174,7 @@ newBy { context } = [ ----------------------------------------- -- Navigation ----------------------------------------- - UI.Navigation.local + Navigation.local [ ( Icon Icons.arrow_back , Label "Take a step back" Shown , PerformMsg TakeStepBackwards @@ -211,10 +186,10 @@ newBy { context } = ----------------------------------------- , (\h -> form AddSourceUsingForm - [ UI.Kit.canisterForm h ] + [ Kit.canisterForm h ] ) - [ UI.Kit.h2 "One last thing" - , UI.Kit.label [] "What are we going to call this source?" + [ Kit.h2 "One last thing" + , Kit.label [] "What are we going to call this source?" -- Input -------- @@ -230,7 +205,7 @@ newBy { context } = , "justify-center" , "w-full" ] - [ UI.Kit.textField + [ Kit.textField [ name "name" , onInput (SetFormData "name") , value nameValue @@ -269,7 +244,7 @@ newBy { context } = -- Button --------- - , UI.Kit.button + , Kit.button Normal Bypass (text "Add source") @@ -281,7 +256,7 @@ corsWarning : String -> List (Html Msg) corsWarning id = [ chunk [ "text-sm", "flex", "items-center", "justify-center", "leading-snug", "opacity-50" ] - [ UI.Kit.inlineIcon Icons.warning + [ Kit.inlineIcon Icons.warning , inline [ "font-semibold" ] [ text "Make sure CORS is enabled" ] @@ -289,7 +264,7 @@ corsWarning id = , chunk [ "text-sm", "leading-snug", "mb-8", "mt-1", "opacity-50" ] [ text "You can find the instructions over " - , UI.Kit.link { label = "here", url = "about/cors/#" ++ id } + , Kit.link { label = "here", url = "about/cors/#" ++ id } ] ] @@ -303,7 +278,7 @@ edit { context } = [ ----------------------------------------- -- Navigation ----------------------------------------- - UI.Navigation.local + Navigation.local [ ( Icon Icons.arrow_back , Label "Go Back" Shown , PerformMsg ReturnToIndex @@ -317,10 +292,10 @@ edit { context } = form EditSourceUsingForm [ chunk [ "text-left", "w-full" ] - [ UI.Kit.canister h ] + [ Kit.canister h ] ] ) - [ UI.Kit.h3 "Edit source" + [ Kit.h3 "Edit source" -- Note ------- @@ -352,7 +327,7 @@ edit { context } = --------- , chunk [ "mt-3", "text-center" ] - [ UI.Kit.button + [ Kit.button Normal Bypass (text "Save") @@ -369,7 +344,7 @@ renderProperty : Source -> Property -> Html Msg renderProperty context property = chunk [ "mb-8" ] - [ UI.Kit.label + [ Kit.label [ for property.key ] property.label @@ -386,7 +361,7 @@ renderProperty context property = in chunk [ "mt-2", "pt-1" ] - [ UI.Kit.checkbox + [ Kit.checkbox { checked = bool , toggleMsg = bool @@ -397,7 +372,7 @@ renderProperty context property = ] else - UI.Kit.textField + Kit.textField [ name property.key , onInput (SetFormData property.key) , placeholder property.placeholder @@ -425,7 +400,7 @@ form msg html = , "flex-shrink-0" , "text-center" ] - [ UI.Kit.centeredContent html ] + [ Kit.centeredContent html ] note : Service -> Html Msg @@ -501,9 +476,9 @@ note service = howNote [ inline [ "font-semibold" ] - [ UI.Kit.inlineIcon Icons.warning + [ Kit.inlineIcon Icons.warning , text "This app requires a proper implementation of " - , UI.Kit.link + , Kit.link { label = "CORS" , url = "https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" } @@ -514,12 +489,12 @@ note service = , text " CORS properly, if at all." , lineBreak , text " Some servers, like " - , UI.Kit.link + , Kit.link { label = "this one" , url = "https://github.com/hacdias/webdav" } , text ", do. You can find the configuration for that server " - , UI.Kit.link + , Kit.link { label = "here" , url = "about/cors/#CORS__WebDAV" } @@ -536,7 +511,7 @@ rename { context } = [ ----------------------------------------- -- Navigation ----------------------------------------- - UI.Navigation.local + Navigation.local [ ( Icon Icons.arrow_back , Label "Go Back" Shown , PerformMsg ReturnToIndex @@ -548,9 +523,9 @@ rename { context } = ----------------------------------------- , (\h -> form RenameSourceUsingForm - [ UI.Kit.canisterForm h ] + [ Kit.canisterForm h ] ) - [ UI.Kit.h2 "Name your source" + [ Kit.h2 "Name your source" -- Input -------- @@ -558,14 +533,14 @@ rename { context } = , onInput (SetFormData "name") , value (Dict.fetch "name" "" context.data) ] - |> UI.Kit.textField + |> Kit.textField |> chunky [ "max-w-md", "mx-auto" ] -- Button --------- , chunk [ "mt-10" ] - [ UI.Kit.button + [ Kit.button Normal Bypass (text "Save") diff --git a/src/Applications/UI/Sources/View.elm b/src/Core/Themes/Sunrise/Sources/View.elm similarity index 92% rename from src/Applications/UI/Sources/View.elm rename to src/Core/Themes/Sunrise/Sources/View.elm index d521f488..4c21f7ee 100644 --- a/src/Applications/UI/Sources/View.elm +++ b/src/Core/Themes/Sunrise/Sources/View.elm @@ -1,4 +1,4 @@ -module UI.Sources.View exposing (view) +module Themes.Sunrise.Sources.View exposing (view) import Chunky exposing (..) import Conditional exposing (ifThenElse) @@ -10,11 +10,12 @@ import List.Extra as List import Material.Icons.Round as Icons import Material.Icons.Types exposing (Coloring(..)) import Sources exposing (..) -import UI.Kit -import UI.List +import Themes.Sunrise.Kit as Kit +import Themes.Sunrise.List +import Themes.Sunrise.Navigation as Navigation +import Themes.Sunrise.Sources.Form as Form import UI.Navigation exposing (..) import UI.Page as Page -import UI.Sources.Form as Form import UI.Sources.Page as Sources exposing (..) import UI.Sources.Types exposing (Msg(..)) import UI.Types as UI exposing (Model) @@ -70,7 +71,7 @@ lazyForm model formView = receptacle = - UI.Kit.receptacle { scrolling = True } + Kit.receptacle { scrolling = True } @@ -83,7 +84,7 @@ index amountOfTracks model = -- Navigation ----------------------------------------- if List.isEmpty model.sources then - UI.Navigation.local + Navigation.local [ ( Icon Icons.add , Label "Add a new source" Shown , NavigateToPage (Page.Sources New) @@ -91,7 +92,7 @@ index amountOfTracks model = ] else - UI.Navigation.local + Navigation.local [ ( Icon Icons.add , Label "Add a new source" Shown , NavigateToPage (Page.Sources New) @@ -120,12 +121,12 @@ index amountOfTracks model = [ "relative" ] [ chunk [ "absolute", "left-0", "top-0" ] - [ UI.Kit.canister [ UI.Kit.h1 "Sources" ] ] + [ Kit.canister [ Kit.h1 "Sources" ] ] ] else - UI.Kit.canister - [ UI.Kit.h1 "Sources" + Kit.canister + [ Kit.h1 "Sources" -- Intro -------- @@ -144,12 +145,12 @@ index amountOfTracks model = , isSelected = False } ) - |> UI.List.view UI.List.Normal + |> Themes.Sunrise.List.view Themes.Sunrise.List.Normal ] -- , if List.isEmpty model.sources then - UI.Kit.centeredContent + Kit.centeredContent [ slab Html.a [ href (Page.toString <| Page.Sources New) ] @@ -195,10 +196,10 @@ intro amountOfTracks = , text " in your collection." ] |> raw - |> UI.Kit.intro + |> Kit.intro -sourceActions : List ( String, Float ) -> Maybe { error : String, sourceId : String } -> Source -> List (UI.List.Action Msg) +sourceActions : List ( String, Float ) -> Maybe { error : String, sourceId : String } -> Source -> List (Themes.Sunrise.List.Action Msg) sourceActions processingContext processingError source = let processIndex = @@ -243,7 +244,7 @@ sourceActions processingContext processingError source = ( Nothing, Just { error, sourceId } ) -> if sourceId == source.id then - [ { icon = \size _ -> Icons.error_outline size (Color UI.Kit.colors.error) + [ { icon = \size _ -> Icons.error_outline size (Color Kit.colors.error) , msg = Nothing , title = error } diff --git a/src/Applications/UI/Syncing/View.elm b/src/Core/Themes/Sunrise/Syncing/View.elm similarity index 89% rename from src/Applications/UI/Syncing/View.elm rename to src/Core/Themes/Sunrise/Syncing/View.elm index 0eb64115..b2843ca8 100644 --- a/src/Applications/UI/Syncing/View.elm +++ b/src/Core/Themes/Sunrise/Syncing/View.elm @@ -1,4 +1,4 @@ -module UI.Syncing.View exposing (view) +module Themes.Sunrise.Syncing.View exposing (view) import Chunky exposing (..) import Html exposing (Html, text) @@ -10,7 +10,7 @@ import Html.Lazy as Lazy import Json.Decode import Material.Icons.Round as Icons import Material.Icons.Types exposing (Coloring(..)) -import UI.Kit +import Themes.Sunrise.Kit as Kit import UI.Syncing.Types as Syncing exposing (..) import UI.Types as UI exposing (..) @@ -28,12 +28,12 @@ view_ : State -> Html Syncing.Msg view_ state = case state of InputScreen _ opts -> - UI.Kit.receptacle + Kit.receptacle { scrolling = False } [ inputScreen opts ] NewEncryptionKeyScreen method pass -> - UI.Kit.receptacle + Kit.receptacle { scrolling = False } [ encryptionKeyScreen { ableToCancel = False @@ -43,7 +43,7 @@ view_ state = ] UpdateEncryptionKeyScreen method pass -> - UI.Kit.receptacle + Kit.receptacle { scrolling = False } [ encryptionKeyScreen { ableToCancel = True @@ -62,7 +62,7 @@ view_ state = encryptionKeyScreen : { ableToCancel : Bool, withEncryption : Syncing.Msg, withoutEncryption : Syncing.Msg } -> Html Syncing.Msg encryptionKeyScreen { ableToCancel, withEncryption, withoutEncryption } = - UI.Kit.focusScreen + Kit.focusScreen { icon = Icons.lock , iconHref = Nothing , text = [ text "Optional passphrase to encrypt/decrypt your data" ] @@ -80,7 +80,7 @@ encryptionKeyScreen { ableToCancel, withEncryption, withoutEncryption } = -- , "sm:px-0" ] - [ UI.Kit.textArea + [ Kit.textArea [ attribute "autocapitalize" "none" , attribute "autocomplete" "off" , attribute "autocorrect" "off" @@ -102,23 +102,23 @@ encryptionKeyScreen { ableToCancel, withEncryption, withoutEncryption } = , "items-stretch" , "space-x-2.5" ] - [ UI.Kit.buttonWithOptions + [ Kit.buttonWithOptions Html.button [ A.class "flex-1" ] - UI.Kit.Gray - UI.Kit.Filled + Kit.Gray + Kit.Filled (Just Syncing.Bypass) (text "Continue") -- , if ableToCancel then - UI.Kit.buttonWithOptions + Kit.buttonWithOptions Html.button [ A.class "flex-1" , E.stopPropagationOn "click" (Json.Decode.succeed ( CancelInput, True )) ] - UI.Kit.Gray - UI.Kit.Normal + Kit.Gray + Kit.Normal Nothing (text "Cancel") @@ -149,10 +149,10 @@ encryptionKeyScreen { ableToCancel, withEncryption, withoutEncryption } = inputScreen : Question -> Html Syncing.Msg inputScreen question = - UI.Kit.focusScreen + Kit.focusScreen { icon = question.icon , iconHref = Nothing - , text = [ question.question ] + , text = [ Kit.askForInput question.question ] , textHref = Nothing } [ slab @@ -167,15 +167,15 @@ inputScreen question = -- , "sm:px-0" ] - [ UI.Kit.textFieldAlt + [ Kit.textFieldAlt [ attribute "autocapitalize" "off" , placeholder question.placeholder , A.class "shadow" , E.onInput Input , value question.value ] - , UI.Kit.button - UI.Kit.Filled + , Kit.button + Kit.Filled Syncing.Bypass (text "Continue") ] diff --git a/src/Applications/UI/View.elm b/src/Core/Themes/Sunrise/Theme.elm similarity index 83% rename from src/Applications/UI/View.elm rename to src/Core/Themes/Sunrise/Theme.elm index f578939c..5b06e672 100644 --- a/src/Applications/UI/View.elm +++ b/src/Core/Themes/Sunrise/Theme.elm @@ -1,7 +1,6 @@ -module UI.View exposing (view) +module Themes.Sunrise.Theme exposing (theme) import Alfred exposing (Alfred) -import Browser import Chunky exposing (..) import Common exposing (Switch(..)) import Conditional exposing (..) @@ -11,41 +10,45 @@ import Html.Attributes exposing (class, style) import Html.Events exposing (on) import Html.Lazy as Lazy import Json.Decode +import Material.Icons as Icons import Maybe.Extra as Maybe -import UI.Alfred.View as Alfred +import Theme exposing (Theme) +import Themes.Sunrise.Alfred.View as Alfred +import Themes.Sunrise.Console +import Themes.Sunrise.ContextMenu as ContextMenu +import Themes.Sunrise.Navigation as Navigation +import Themes.Sunrise.Notifications as Notifications +import Themes.Sunrise.Playlists.View as Playlists +import Themes.Sunrise.Queue.View as Queue +import Themes.Sunrise.Settings as Settings +import Themes.Sunrise.Sources.View as Sources +import Themes.Sunrise.Syncing.View as Syncing +import Themes.Sunrise.Tracks.View as Tracks import UI.Backdrop as Backdrop -import UI.Console -import UI.ContextMenu -import UI.Navigation as Navigation -import UI.Notifications import UI.Page as Page -import UI.Playlists.View as Playlists -import UI.Queue.View as Queue -import UI.Settings as Settings import UI.Settings.Page import UI.Sources.Page -import UI.Sources.View as Sources import UI.Svg.Elements import UI.Syncing.Common as Syncing -import UI.Syncing.View as Syncing -import UI.Tracks.View as Tracks import UI.Types exposing (..) import User.Layer +theme : Theme Msg Model +theme = + { id = "sunrise" + , title = "Sunrise" + , icon = Icons.wb_sunny + , view = view + } --- 🗺 -view : Model -> Browser.Document Msg -view model = - { title = "Diffuse" - , body = [ body model ] - } +-- ㊙️ -body : Model -> Html Msg -body model = +view : Model -> Html Msg +view model = section (if Maybe.isJust model.contextMenu || Maybe.isJust model.alfred then [ on "tap" (Json.Decode.succeed HideOverlay) ] @@ -82,12 +85,12 @@ body model = ----------------------------------------- -- Context Menu ----------------------------------------- - , Lazy.lazy2 UI.ContextMenu.view model.viewport.width model.contextMenu + , Lazy.lazy2 ContextMenu.view model.viewport.width model.contextMenu ----------------------------------------- -- Notifications ----------------------------------------- - , Lazy.lazy2 UI.Notifications.view model.extractedBackdropColor model.notifications + , Lazy.lazy2 Notifications.view model.extractedBackdropColor model.notifications ----------------------------------------- -- Overlay @@ -97,27 +100,11 @@ body model = ----------------------------------------- -- Content ----------------------------------------- - , let - opts = - { justifyCenter = False - , scrolling = not model.isDragging - } - in - if model.isLoading then - content - { opts | justifyCenter = True } - [ loadingAnimation - , chunk - [ "italic" - , "mt-5" - , "text-white" - , "text-opacity-30" - ] - [ Html.text "Transmitting particles" ] - ] - - else - content opts (defaultScreen model) + , content + { justifyCenter = False + , scrolling = not model.isDragging + } + (defaultScreen model) ] @@ -189,7 +176,7 @@ defaultScreen model = ----------------------------------------- -- Controls ----------------------------------------- - , UI.Console.view + , Themes.Sunrise.Console.view model.nowPlaying model.repeat model.shuffle @@ -253,11 +240,6 @@ inputFocusDecoder = ) -loadingAnimation : Html msg -loadingAnimation = - Html.map never UI.Svg.Elements.loading - - overlay : Maybe (Alfred Msg) -> Maybe (ContextMenu Msg) -> Html Msg overlay maybeAlfred maybeContextMenu = let diff --git a/src/Applications/UI/Tracks/Scene.elm b/src/Core/Themes/Sunrise/Tracks/Scene.elm similarity index 96% rename from src/Applications/UI/Tracks/Scene.elm rename to src/Core/Themes/Sunrise/Tracks/Scene.elm index ece4e854..ac285941 100644 --- a/src/Applications/UI/Tracks/Scene.elm +++ b/src/Core/Themes/Sunrise/Tracks/Scene.elm @@ -1,4 +1,4 @@ -module UI.Tracks.Scene exposing (..) +module Themes.Sunrise.Tracks.Scene exposing (..) import Chunky exposing (..) import Conditional exposing (..) diff --git a/src/Applications/UI/Tracks/Scene/Covers.elm b/src/Core/Themes/Sunrise/Tracks/Scene/Covers.elm similarity index 98% rename from src/Applications/UI/Tracks/Scene/Covers.elm rename to src/Core/Themes/Sunrise/Tracks/Scene/Covers.elm index 23a71621..d814c36b 100644 --- a/src/Applications/UI/Tracks/Scene/Covers.elm +++ b/src/Core/Themes/Sunrise/Tracks/Scene/Covers.elm @@ -1,4 +1,4 @@ -module UI.Tracks.Scene.Covers exposing (containerId, scrollToNowPlaying, scrollToTop, view) +module Themes.Sunrise.Tracks.Scene.Covers exposing (containerId, scrollToNowPlaying, scrollToTop, view) import Browser.Dom as Dom import Chunky exposing (..) @@ -16,9 +16,9 @@ import Material.Icons.Round as Icons import Material.Icons.Types exposing (Coloring(..)) import Maybe.Extra as Maybe import Task +import Themes.Sunrise.Tracks.Scene as Scene +import Themes.Sunrise.Tracks.Scene.List import Tracks exposing (..) -import UI.Tracks.Scene as Scene -import UI.Tracks.Scene.List import UI.Tracks.Types exposing (Msg(..)) import UI.Types as UI exposing (Msg(..)) @@ -226,7 +226,7 @@ singleCoverView : Cover -> Dependencies -> Html Msg singleCoverView cover deps = let derivedColors = - UI.Tracks.Scene.List.deriveColors + Themes.Sunrise.Tracks.Scene.List.deriveColors { bgColor = deps.bgColor , darkMode = deps.darkMode } @@ -298,7 +298,7 @@ singleCoverView cover deps = -- , cover.tracks |> List.indexedMap - (UI.Tracks.Scene.List.defaultItemView + (Themes.Sunrise.Tracks.Scene.List.defaultItemView { derivedColors = derivedColors , favouritesOnly = deps.favouritesOnly , nowPlaying = deps.nowPlaying diff --git a/src/Applications/UI/Tracks/Scene/List.elm b/src/Core/Themes/Sunrise/Tracks/Scene/List.elm similarity index 98% rename from src/Applications/UI/Tracks/Scene/List.elm rename to src/Core/Themes/Sunrise/Tracks/Scene/List.elm index 18264e26..f3dd46ea 100644 --- a/src/Applications/UI/Tracks/Scene/List.elm +++ b/src/Core/Themes/Sunrise/Tracks/Scene/List.elm @@ -1,4 +1,4 @@ -module UI.Tracks.Scene.List exposing (Dependencies, DerivedColors, containerId, defaultItemView, deriveColors, scrollToNowPlaying, scrollToTop, view) +module Themes.Sunrise.Tracks.Scene.List exposing (Dependencies, DerivedColors, containerId, defaultItemView, deriveColors, scrollToNowPlaying, scrollToTop, view) import Browser.Dom as Dom import Chunky exposing (..) @@ -17,11 +17,11 @@ import Material.Icons.Round as Icons import Material.Icons.Types exposing (Coloring(..)) import Maybe.Extra as Maybe import Task +import Themes.Sunrise.Kit as Kit +import Themes.Sunrise.Tracks.Scene as Scene import Tracks exposing (..) import UI.DnD as DnD -import UI.Kit import UI.Queue.Types as Queue -import UI.Tracks.Scene as Scene import UI.Tracks.Types exposing (Msg(..)) import UI.Types as UI exposing (Msg(..)) @@ -327,7 +327,7 @@ deriveColors : { bgColor : Maybe Color, darkMode : Bool } -> DerivedColors deriveColors { bgColor, darkMode } = let color = - Maybe.withDefault UI.Kit.colors.text bgColor + Maybe.withDefault Kit.colors.text bgColor in if darkMode then { background = Color.toCssString color @@ -828,12 +828,12 @@ otherColumnStyles columnWidth = favColors = { gray = Color.toCssString (Color.rgb255 220 220 220) - , red = Color.toCssString UI.Kit.colorKit.base08 + , red = Color.toCssString Kit.colorKit.base08 } rowFontColors = - { gray = Color.toCssString UI.Kit.colorKit.base04 + { gray = Color.toCssString Kit.colorKit.base04 , white = Color.toCssString (Color.rgb 1 1 1) } @@ -843,9 +843,9 @@ dragIndicator darkMode = let color = if darkMode then - UI.Kit.colors.gray_300 + Kit.colors.gray_300 else - UI.Kit.colorKit.base03 + Kit.colorKit.base03 in style "box-shadow" ("0 1px 0 0 " ++ Color.toCssString color ++ " inset") diff --git a/src/Applications/UI/Tracks/View.elm b/src/Core/Themes/Sunrise/Tracks/View.elm similarity index 94% rename from src/Applications/UI/Tracks/View.elm rename to src/Core/Themes/Sunrise/Tracks/View.elm index 992dff73..3a98d57a 100644 --- a/src/Applications/UI/Tracks/View.elm +++ b/src/Core/Themes/Sunrise/Tracks/View.elm @@ -1,4 +1,4 @@ -module UI.Tracks.View exposing (view) +module Themes.Sunrise.Tracks.View exposing (view) import Chunky exposing (..) import Color exposing (Color) @@ -14,9 +14,12 @@ import Material.Icons.Round as Icons import Material.Icons.Types exposing (Coloring(..)) import Maybe.Extra as Maybe import Playlists exposing (Playlist) +import Themes.Sunrise.Kit as Kit +import Themes.Sunrise.Navigation as Navigation +import Themes.Sunrise.Tracks.Scene.Covers +import Themes.Sunrise.Tracks.Scene.List import Tracks exposing (..) import UI.Audio.Types exposing (nowPlayingIdentifiedTrack) -import UI.Kit import UI.Navigation exposing (..) import UI.Page as Page import UI.Playlists.Page @@ -24,8 +27,6 @@ import UI.Queue.Page import UI.Sources.Page as Sources import UI.Syncing.Common as Syncing import UI.Syncing.Types as Syncing -import UI.Tracks.Scene.Covers -import UI.Tracks.Scene.List import UI.Tracks.Types exposing (..) import UI.Types as UI exposing (..) import User.Layer as User @@ -88,7 +89,7 @@ view model = else case model.scene of Covers -> - UI.Tracks.Scene.Covers.view + Themes.Sunrise.Tracks.Scene.Covers.view { bgColor = model.extractedBackdropColor , cachedCovers = model.cachedCovers , covers = model.covers.harvested @@ -116,7 +117,7 @@ view model = else Just model.dnd ) - |> UI.Tracks.Scene.List.view + |> Themes.Sunrise.Tracks.Scene.List.view { bgColor = model.extractedBackdropColor , darkMode = model.darkMode , height = model.viewport.height @@ -267,7 +268,7 @@ navigation { bgColor, favouritesOnly, grouping, isOnIndexPage, pressedShift, sce ] [ "cursor-pointer" ] [ if favouritesOnly then - Icons.favorite 16 (Color UI.Kit.colorKit.base08) + Icons.favorite 16 (Color Kit.colorKit.base08) else Icons.favorite_border 16 Inherit @@ -325,7 +326,7 @@ navigation { bgColor, favouritesOnly, grouping, isOnIndexPage, pressedShift, sce -- , bgColor - |> Maybe.withDefault UI.Kit.colorKit.base01 + |> Maybe.withDefault Kit.colorKit.base01 |> Color.toCssString |> style "background-color" ] @@ -358,7 +359,7 @@ navigation { bgColor, favouritesOnly, grouping, isOnIndexPage, pressedShift, sce , ----------------------------------------- -- Part 2 ----------------------------------------- - UI.Navigation.localWithTabindex + Navigation.localWithTabindex tabindex_ [ ( Icon Icons.waves , Label "Playlists" Hidden @@ -453,7 +454,7 @@ noTracksView processingContext amountOfSources amountOfTracks _ userLayerMethod , "flex" , "flex-grow" ] - [ UI.Kit.centeredContent + [ Kit.centeredContent [ if List.length processingContext > 0 then message "Processing Tracks" @@ -506,29 +507,29 @@ cloud/distributed storage service you use. -- , chunk [ "flex", "mt-5", "space-x-3" ] - [ UI.Kit.button - UI.Kit.Normal + [ Kit.button + Kit.Normal InsertDemo (Html.text "Insert Demo") - , UI.Kit.buttonWithColor - UI.Kit.Accent - UI.Kit.Filled + , Kit.buttonWithColor + Kit.Accent + Kit.Filled (ChangeUrlUsingPage <| Page.Sources Sources.New) (Html.text "Add Music") , case userLayerMethod of Just method -> - UI.Kit.buttonWithColor - UI.Kit.Gray - UI.Kit.Filled + Kit.buttonWithColor + Kit.Gray + Kit.Filled (SyncingMsg Syncing.StopSync) (text "Stop syncing") Nothing -> - UI.Kit.buttonWithOptions + Kit.buttonWithOptions Html.button [ Mouse.onClick (SyncingMsg << Syncing.ShowSyncDataMenu) ] - UI.Kit.Gray - UI.Kit.Filled + Kit.Gray + Kit.Filled Nothing (Html.text "Sync data") ] diff --git a/src/Applications/UI.elm b/src/Core/UI.elm similarity index 99% rename from src/Applications/UI.elm rename to src/Core/UI.elm index 04f48730..37eac515 100644 --- a/src/Applications/UI.elm +++ b/src/Core/UI.elm @@ -109,6 +109,7 @@ init flags url key = , pressedKeys = [] , processAutomatically = True , serviceWorkerStatus = serviceWorkerStatus + , theme = Nothing , uuidSeed = Random.initialSeed flags.initialTime , url = url , version = flags.version @@ -352,9 +353,15 @@ update msg = ----------------------------------------- -- Interface ----------------------------------------- + AssistWithChangingTheme -> + Interface.assistWithChangingTheme + Blur -> Interface.blur + ChangeTheme a -> + Interface.changeTheme a + ContextMenuConfirmation a b -> Interface.contextMenuConfirmation a b diff --git a/src/Applications/UI/Adjunct.elm b/src/Core/UI/Adjunct.elm similarity index 100% rename from src/Applications/UI/Adjunct.elm rename to src/Core/UI/Adjunct.elm diff --git a/src/Applications/UI/Alfred/State.elm b/src/Core/UI/Alfred/State.elm similarity index 100% rename from src/Applications/UI/Alfred/State.elm rename to src/Core/UI/Alfred/State.elm diff --git a/src/Applications/UI/Audio/State.elm b/src/Core/UI/Audio/State.elm similarity index 100% rename from src/Applications/UI/Audio/State.elm rename to src/Core/UI/Audio/State.elm diff --git a/src/Applications/UI/Audio/Types.elm b/src/Core/UI/Audio/Types.elm similarity index 100% rename from src/Applications/UI/Audio/Types.elm rename to src/Core/UI/Audio/Types.elm diff --git a/src/Applications/UI/Backdrop.elm b/src/Core/UI/Backdrop.elm similarity index 100% rename from src/Applications/UI/Backdrop.elm rename to src/Core/UI/Backdrop.elm diff --git a/src/Applications/UI/Commands/Alfred.elm b/src/Core/UI/Commands/Alfred.elm similarity index 98% rename from src/Applications/UI/Commands/Alfred.elm rename to src/Core/UI/Commands/Alfred.elm index 747b045c..8d47deb1 100644 --- a/src/Applications/UI/Commands/Alfred.elm +++ b/src/Core/UI/Commands/Alfred.elm @@ -301,7 +301,11 @@ viewCommands model = list ) in - [ { icon = Just (Icons.favorite 14) + [ { icon = Just (Icons.brush 14) + , title = "Change application theme" + , value = Command UI.AssistWithChangingTheme + } + , { icon = Just (Icons.favorite 14) , title = toggle model.favouritesOnly "favourites-only mode" , value = Command (UI.TracksMsg Tracks.ToggleFavouritesOnly) } diff --git a/src/Applications/UI/Commands/State.elm b/src/Core/UI/Commands/State.elm similarity index 100% rename from src/Applications/UI/Commands/State.elm rename to src/Core/UI/Commands/State.elm diff --git a/src/Applications/UI/Common/State.elm b/src/Core/UI/Common/State.elm similarity index 88% rename from src/Applications/UI/Common/State.elm rename to src/Core/UI/Common/State.elm index db3a45fd..6b8d244e 100644 --- a/src/Applications/UI/Common/State.elm +++ b/src/Core/UI/Common/State.elm @@ -1,6 +1,5 @@ module UI.Common.State exposing (..) -import Browser.Dom import Browser.Navigation as Nav import Common exposing (..) import ContextMenu exposing (ContextMenu) @@ -9,14 +8,10 @@ import List.Extra as List import Monocle.Lens as Lens exposing (Lens) import Notifications exposing (Notification) import Return exposing (return) -import Task -import Tracks import UI.Notifications import UI.Page as Page exposing (Page) import UI.Playlists.Directory import UI.Syncing.Types as Syncing -import UI.Tracks.Scene.Covers -import UI.Tracks.Scene.List import UI.Types as UI exposing (Manager, Model, Msg) import User.Layer exposing (Method) @@ -64,18 +59,22 @@ dismissNotification options model = forceTracksRerender : Manager forceTracksRerender model = - let - containerId = - case model.scene of - Tracks.Covers -> - UI.Tracks.Scene.Covers.containerId - - Tracks.List -> - UI.Tracks.Scene.List.containerId - in - Browser.Dom.setViewportOf containerId 0 1 - |> Task.attempt (always UI.Bypass) - |> return model + -- + -- TODO: + -- + -- let + -- containerId = + -- case model.scene of + -- Tracks.Covers -> + -- UI.Tracks.Scene.Covers.containerId + -- Tracks.List -> + -- UI.Tracks.Scene.List.containerId + -- in + -- Browser.Dom.setViewportOf containerId 0 1 + -- |> Task.attempt (always UI.Bypass) + -- |> return model + -- + Return.singleton model generateDirectoryPlaylists : Manager diff --git a/src/Applications/UI/Common/Types.elm b/src/Core/UI/Common/Types.elm similarity index 100% rename from src/Applications/UI/Common/Types.elm rename to src/Core/UI/Common/Types.elm diff --git a/src/Applications/UI/Demo.elm b/src/Core/UI/Demo.elm similarity index 100% rename from src/Applications/UI/Demo.elm rename to src/Core/UI/Demo.elm diff --git a/src/Applications/UI/DnD.elm b/src/Core/UI/DnD.elm similarity index 100% rename from src/Applications/UI/DnD.elm rename to src/Core/UI/DnD.elm diff --git a/src/Applications/UI/Equalizer/State.elm b/src/Core/UI/Equalizer/State.elm similarity index 100% rename from src/Applications/UI/Equalizer/State.elm rename to src/Core/UI/Equalizer/State.elm diff --git a/src/Applications/UI/Interface/State.elm b/src/Core/UI/Interface/State.elm similarity index 82% rename from src/Applications/UI/Interface/State.elm rename to src/Core/UI/Interface/State.elm index 0494c4ad..ac80ec94 100644 --- a/src/Applications/UI/Interface/State.elm +++ b/src/Core/UI/Interface/State.elm @@ -1,11 +1,14 @@ module UI.Interface.State exposing (..) +import Alfred import Debouncer.Basic as Debouncer import Maybe.Extra as Maybe import Notifications import Return exposing (return) import Return.Ext as Return +import Theme import Tracks +import UI.Alfred.State as Alfred import UI.Common.State as Common import UI.Common.Types exposing (DebounceManager) import UI.DnD as DnD @@ -13,18 +16,58 @@ import UI.Page as Page import UI.Playlists.State as Playlists import UI.Ports as Ports import UI.Queue.State as Queue +import UI.Theme import UI.Types exposing (..) +import UI.User.State.Export exposing (saveEnclosedUserData) -- 🔱 +assistWithChangingTheme : Manager +assistWithChangingTheme model = + { action = + \{ result } -> + case result of + Just { value } -> + value + |> Alfred.command + |> Maybe.map List.singleton + |> Maybe.withDefault [] + + Nothing -> + [] + , index = + [ { name = Just "Themes" + , items = + List.map + (\theme -> + { icon = Just (theme.icon 16) + , title = theme.title + , value = Alfred.Command (ChangeTheme { id = theme.id }) + } + ) + UI.Theme.list + } + ] + , message = "Choose a theme." + , operation = Alfred.Query + } + |> Alfred.create + |> (\a -> Alfred.assign a model) + + blur : Manager blur model = Return.singleton { model | focusedOnInput = False, pressedKeys = [] } +changeTheme : Theme.Id -> Manager +changeTheme id model = + saveEnclosedUserData { model | theme = Just id } + + contextMenuConfirmation : String -> Msg -> Manager contextMenuConfirmation conf msg model = return diff --git a/src/Core/UI/Navigation.elm b/src/Core/UI/Navigation.elm new file mode 100644 index 00000000..28c80194 --- /dev/null +++ b/src/Core/UI/Navigation.elm @@ -0,0 +1,30 @@ +module UI.Navigation exposing (Action(..), Icon(..), Label(..), LabelType(..)) + +import Html.Events.Extra.Mouse as Mouse +import Material.Icons.Types exposing (Coloring) +import Svg exposing (Svg) +import UI.Page exposing (Page) + + + +-- 🌳 + + +type Action msg + = NavigateToPage Page + | OpenLinkInNewPage String + | PerformMsg msg + | PerformMsgWithMouseEvent (Mouse.Event -> msg) + + +type Icon msg + = Icon (Int -> Coloring -> Svg msg) + + +type Label + = Label String LabelType + + +type LabelType + = Hidden + | Shown diff --git a/src/Core/UI/Notifications.elm b/src/Core/UI/Notifications.elm new file mode 100644 index 00000000..106df8c5 --- /dev/null +++ b/src/Core/UI/Notifications.elm @@ -0,0 +1,66 @@ +module UI.Notifications exposing (Model, dismiss, show, showWithModel) + +import Notifications exposing (..) +import Process +import Task +import UI.Types exposing (Msg(..)) + + + +-- 🌳 + + +type alias Model = + List (Notification Msg) + + + +-- 📣 + + +dismiss : Model -> { id : Int } -> ( Model, Cmd Msg ) +dismiss collection { id } = + ( List.map + (\notification -> + if Notifications.id notification == id then + Notifications.dismiss notification + + else + notification + ) + collection + , Task.perform + (\_ -> RemoveNotification { id = id }) + (Process.sleep 500) + ) + + +show : Notification Msg -> Model -> ( Model, Cmd Msg ) +show notification collection = + let + existingNotificationIds = + List.map Notifications.id collection + in + if List.member (Notifications.id notification) existingNotificationIds then + -- Don't show duplicate notifications + ( collection + , Cmd.none + ) + + else + ( notification :: collection + -- Hide notification after a certain amount of time, + -- unless it's a sticky notification. + , if (Notifications.options notification).sticky then + Cmd.none + + else + Task.perform + (\_ -> DismissNotification { id = Notifications.id notification }) + (Process.sleep 7500) + ) + + +showWithModel : Model -> Notification Msg -> ( Model, Cmd Msg ) +showWithModel model notification = + show notification model diff --git a/src/Applications/UI/Other/State.elm b/src/Core/UI/Other/State.elm similarity index 100% rename from src/Applications/UI/Other/State.elm rename to src/Core/UI/Other/State.elm diff --git a/src/Applications/UI/Page.elm b/src/Core/UI/Page.elm similarity index 100% rename from src/Applications/UI/Page.elm rename to src/Core/UI/Page.elm diff --git a/src/Applications/UI/Playlists/Alfred.elm b/src/Core/UI/Playlists/Alfred.elm similarity index 100% rename from src/Applications/UI/Playlists/Alfred.elm rename to src/Core/UI/Playlists/Alfred.elm diff --git a/src/Applications/UI/Playlists/ContextMenu.elm b/src/Core/UI/Playlists/ContextMenu.elm similarity index 100% rename from src/Applications/UI/Playlists/ContextMenu.elm rename to src/Core/UI/Playlists/ContextMenu.elm diff --git a/src/Applications/UI/Playlists/Directory.elm b/src/Core/UI/Playlists/Directory.elm similarity index 100% rename from src/Applications/UI/Playlists/Directory.elm rename to src/Core/UI/Playlists/Directory.elm diff --git a/src/Applications/UI/Playlists/Page.elm b/src/Core/UI/Playlists/Page.elm similarity index 100% rename from src/Applications/UI/Playlists/Page.elm rename to src/Core/UI/Playlists/Page.elm diff --git a/src/Applications/UI/Playlists/State.elm b/src/Core/UI/Playlists/State.elm similarity index 100% rename from src/Applications/UI/Playlists/State.elm rename to src/Core/UI/Playlists/State.elm diff --git a/src/Applications/UI/Ports.elm b/src/Core/UI/Ports.elm similarity index 100% rename from src/Applications/UI/Ports.elm rename to src/Core/UI/Ports.elm diff --git a/src/Applications/UI/Queue/ContextMenu.elm b/src/Core/UI/Queue/ContextMenu.elm similarity index 100% rename from src/Applications/UI/Queue/ContextMenu.elm rename to src/Core/UI/Queue/ContextMenu.elm diff --git a/src/Applications/UI/Queue/Fill.elm b/src/Core/UI/Queue/Fill.elm similarity index 100% rename from src/Applications/UI/Queue/Fill.elm rename to src/Core/UI/Queue/Fill.elm diff --git a/src/Applications/UI/Queue/Page.elm b/src/Core/UI/Queue/Page.elm similarity index 100% rename from src/Applications/UI/Queue/Page.elm rename to src/Core/UI/Queue/Page.elm diff --git a/src/Applications/UI/Queue/State.elm b/src/Core/UI/Queue/State.elm similarity index 100% rename from src/Applications/UI/Queue/State.elm rename to src/Core/UI/Queue/State.elm diff --git a/src/Applications/UI/Queue/Types.elm b/src/Core/UI/Queue/Types.elm similarity index 100% rename from src/Applications/UI/Queue/Types.elm rename to src/Core/UI/Queue/Types.elm diff --git a/src/Applications/UI/Routing/State.elm b/src/Core/UI/Routing/State.elm similarity index 100% rename from src/Applications/UI/Routing/State.elm rename to src/Core/UI/Routing/State.elm diff --git a/src/Applications/UI/Services/State.elm b/src/Core/UI/Services/State.elm similarity index 100% rename from src/Applications/UI/Services/State.elm rename to src/Core/UI/Services/State.elm diff --git a/src/Applications/UI/Settings/Page.elm b/src/Core/UI/Settings/Page.elm similarity index 100% rename from src/Applications/UI/Settings/Page.elm rename to src/Core/UI/Settings/Page.elm diff --git a/src/Applications/UI/Sources/ContextMenu.elm b/src/Core/UI/Sources/ContextMenu.elm similarity index 100% rename from src/Applications/UI/Sources/ContextMenu.elm rename to src/Core/UI/Sources/ContextMenu.elm diff --git a/src/Core/UI/Sources/Form.elm b/src/Core/UI/Sources/Form.elm new file mode 100644 index 00000000..9f675e4a --- /dev/null +++ b/src/Core/UI/Sources/Form.elm @@ -0,0 +1,31 @@ +module UI.Sources.Form exposing (..) + +import Sources exposing (..) +import Sources.Services as Services +import UI.Sources.Types exposing (..) + + + +-- 🌳 + + +initialModel : Form +initialModel = + { step = Where + , context = defaultContext + } + + +defaultContext : Source +defaultContext = + { id = "CHANGE_ME_PLEASE" + , data = Services.initialData defaultService + , directoryPlaylists = True + , enabled = True + , service = defaultService + } + + +defaultService : Service +defaultService = + Dropbox diff --git a/src/Applications/UI/Sources/Page.elm b/src/Core/UI/Sources/Page.elm similarity index 100% rename from src/Applications/UI/Sources/Page.elm rename to src/Core/UI/Sources/Page.elm diff --git a/src/Applications/UI/Sources/Query.elm b/src/Core/UI/Sources/Query.elm similarity index 100% rename from src/Applications/UI/Sources/Query.elm rename to src/Core/UI/Sources/Query.elm diff --git a/src/Applications/UI/Sources/State.elm b/src/Core/UI/Sources/State.elm similarity index 100% rename from src/Applications/UI/Sources/State.elm rename to src/Core/UI/Sources/State.elm diff --git a/src/Applications/UI/Sources/Types.elm b/src/Core/UI/Sources/Types.elm similarity index 100% rename from src/Applications/UI/Sources/Types.elm rename to src/Core/UI/Sources/Types.elm diff --git a/src/Applications/UI/Svg/Elements.elm b/src/Core/UI/Svg/Elements.elm similarity index 100% rename from src/Applications/UI/Svg/Elements.elm rename to src/Core/UI/Svg/Elements.elm diff --git a/src/Applications/UI/Syncing/Common.elm b/src/Core/UI/Syncing/Common.elm similarity index 79% rename from src/Applications/UI/Syncing/Common.elm rename to src/Core/UI/Syncing/Common.elm index 6fabf8ef..bdf3f311 100644 --- a/src/Applications/UI/Syncing/Common.elm +++ b/src/Core/UI/Syncing/Common.elm @@ -3,7 +3,6 @@ module UI.Syncing.Common exposing (..) import Chunky exposing (..) import Html import Svg -import UI.Kit import UI.Svg.Elements import UI.Syncing.Types exposing (..) import UI.Types exposing (Msg(..)) @@ -34,16 +33,15 @@ startRemoteStorage = { icon = \size _ -> Svg.map never (UI.Svg.Elements.remoteStorageLogo size) , placeholder = "example@5apps.com" , question = - UI.Kit.askForInput - { question = - "What's your user address?" - , info = - [ Html.text "The format is " - , inline - [] - [ Html.text "username@server.domain" ] - ] - } + { question = + "What's your user address?" + , info = + [ Html.text "The format is " + , inline + [] + [ Html.text "username@server.domain" ] + ] + } , value = "" } |> AskForInput remoteStorageMethod diff --git a/src/Applications/UI/Syncing/ContextMenu.elm b/src/Core/UI/Syncing/ContextMenu.elm similarity index 100% rename from src/Applications/UI/Syncing/ContextMenu.elm rename to src/Core/UI/Syncing/ContextMenu.elm diff --git a/src/Applications/UI/Syncing/State.elm b/src/Core/UI/Syncing/State.elm similarity index 94% rename from src/Applications/UI/Syncing/State.elm rename to src/Core/UI/Syncing/State.elm index fd54c3b2..e8e9ad27 100644 --- a/src/Applications/UI/Syncing/State.elm +++ b/src/Core/UI/Syncing/State.elm @@ -26,7 +26,6 @@ import Svg import Time import UI.Backdrop as Backdrop import UI.Common.State as Common exposing (showNotification, showNotificationWithModel) -import UI.Kit import UI.Ports as Ports import UI.Sources.State as Sources import UI.Svg.Elements @@ -546,23 +545,22 @@ pingIpfsCallback result = { icon = \size _ -> Svg.map never (UI.Svg.Elements.ipfsLogo size) , placeholder = "//localhost:5001" , question = - UI.Kit.askForInput - { question = - "Where's your IPFS API located?" - , info = - [ Html.text "You can find this address on the IPFS Web UI." - , Html.br [] [] - , Html.text "Most likely you'll also need to setup CORS." - , Html.br [] [] - , Html.text "You can find the instructions for that " - , Html.a - [ Html.Attributes.class "border-b border-current-color font-semibold inline-block leading-tight" - , Html.Attributes.href "about/cors/#CORS__IPFS" - , Html.Attributes.target "_blank" - ] - [ Html.text "here" ] + { question = + "Where's your IPFS API located?" + , info = + [ Html.text "You can find this address on the IPFS Web UI." + , Html.br [] [] + , Html.text "Most likely you'll also need to setup CORS." + , Html.br [] [] + , Html.text "You can find the instructions for that " + , Html.a + [ Html.Attributes.class "border-b border-current-color font-semibold inline-block leading-tight" + , Html.Attributes.href "about/cors/#CORS__IPFS" + , Html.Attributes.target "_blank" ] - } + [ Html.text "here" ] + ] + } , value = "//localhost:5001" } diff --git a/src/Applications/UI/Syncing/Types.elm b/src/Core/UI/Syncing/Types.elm similarity index 97% rename from src/Applications/UI/Syncing/Types.elm rename to src/Core/UI/Syncing/Types.elm index 78b2abd1..55109861 100644 --- a/src/Applications/UI/Syncing/Types.elm +++ b/src/Core/UI/Syncing/Types.elm @@ -27,7 +27,7 @@ type State type alias Question = { icon : Int -> Coloring -> Svg Msg , placeholder : String - , question : Html Msg + , question : { question : String, info : List (Html Msg) } , value : String } diff --git a/src/Core/UI/Theme.elm b/src/Core/UI/Theme.elm new file mode 100644 index 00000000..69d64b2e --- /dev/null +++ b/src/Core/UI/Theme.elm @@ -0,0 +1,114 @@ +module UI.Theme exposing (..) + +import Chunky exposing (..) +import Dict exposing (Dict) +import Html exposing (Html) +import Material.Icons.Types exposing (Icon) +import Theme exposing (Theme) +import Themes.Sunrise.Theme as Sunrise +import Themes.Sunrise.Tracks.Scene.Covers +import Themes.Sunrise.Tracks.Scene.List +import Tracks exposing (IdentifiedTrack, Scene) +import UI.Svg.Elements +import UI.Types exposing (Model, Msg(..)) + + + +-- 🔮 + + +list : List (Theme Msg Model) +list = + [ Sunrise.theme + ] + + +default : Theme Msg Model +default = + Sunrise.theme + + + +-- 🚧 + + +dict : Dict String (Theme Msg Model) +dict = + list + |> List.map + (\theme -> + ( theme.id, theme ) + ) + |> Dict.fromList + + +view : Model -> Html Msg +view model = + if model.isLoading then + loadingAnimation + + else + case model.theme of + Just { id } -> + case Dict.get id dict of + Just theme -> + theme.view model + + Nothing -> + default.view model + + Nothing -> + default.view model + + +loadingAnimation = + chunk + [ "flex" + , "flex-col" + , "items-center" + , "justify-center" + , "screen-height" + , "w-screen" + ] + [ loadingAnimationSvg + , chunk + [ "italic" + , "mt-5" + , "text-white" + , "text-opacity-30" + ] + [ Html.text "Transmitting particles" ] + ] + + +loadingAnimationSvg = + Html.map never UI.Svg.Elements.loading + + + +-- TODO + + +scrollTracksToTop : Scene -> Cmd Msg +scrollTracksToTop scene = + case scene of + Tracks.Covers -> + Themes.Sunrise.Tracks.Scene.List.scrollToTop + + Tracks.List -> + Themes.Sunrise.Tracks.Scene.Covers.scrollToTop + + +scrollToNowPlaying : Scene -> IdentifiedTrack -> Model -> Cmd Msg +scrollToNowPlaying scene ( identifiers, track ) model = + case scene of + Tracks.Covers -> + Themes.Sunrise.Tracks.Scene.Covers.scrollToNowPlaying + model.viewport.width + model.covers.harvested + ( identifiers, track ) + + Tracks.List -> + Themes.Sunrise.Tracks.Scene.List.scrollToNowPlaying + model.tracks.harvested + ( identifiers, track ) diff --git a/src/Applications/UI/Tracks/ContextMenu.elm b/src/Core/UI/Tracks/ContextMenu.elm similarity index 100% rename from src/Applications/UI/Tracks/ContextMenu.elm rename to src/Core/UI/Tracks/ContextMenu.elm diff --git a/src/Applications/UI/Tracks/Covers.elm b/src/Core/UI/Tracks/Covers.elm similarity index 100% rename from src/Applications/UI/Tracks/Covers.elm rename to src/Core/UI/Tracks/Covers.elm diff --git a/src/Applications/UI/Tracks/State.elm b/src/Core/UI/Tracks/State.elm similarity index 97% rename from src/Applications/UI/Tracks/State.elm rename to src/Core/UI/Tracks/State.elm index 21acebd3..84d30a1f 100644 --- a/src/Applications/UI/Tracks/State.elm +++ b/src/Core/UI/Tracks/State.elm @@ -31,10 +31,9 @@ import UI.DnD as DnD import UI.Page import UI.Ports as Ports import UI.Queue.State as Queue +import UI.Theme import UI.Tracks.ContextMenu as Tracks import UI.Tracks.Covers as Covers -import UI.Tracks.Scene.Covers -import UI.Tracks.Scene.List import UI.Tracks.Types as Tracks exposing (..) import UI.Types exposing (Manager, Model, Msg(..)) import UI.User.State.Export as User @@ -775,11 +774,7 @@ scrollToNowPlaying model = if List.member Keyboard.Shift model.pressedKeys then return { model | selectedCover = Nothing } - (UI.Tracks.Scene.Covers.scrollToNowPlaying - model.viewport.width - model.covers.harvested - ( identifiers, track ) - ) + (UI.Theme.scrollToNowPlaying Covers ( identifiers, track ) model) else model.covers.harvested @@ -790,10 +785,7 @@ scrollToNowPlaying model = List -> return { model | selectedCover = Nothing } - (UI.Tracks.Scene.List.scrollToNowPlaying - model.tracks.harvested - ( identifiers, track ) - ) + (UI.Theme.scrollToNowPlaying List ( identifiers, track ) model) ) |> Maybe.map (UI.Page.Index @@ -1071,12 +1063,7 @@ resolveParcel ( deps, newCollection ) model = -- Command ----------------------------------------- , if scrollContextChanged then - case model.scene of - Covers -> - UI.Tracks.Scene.Covers.scrollToTop - - List -> - UI.Tracks.Scene.List.scrollToTop + UI.Theme.scrollTracksToTop model.scene else Cmd.none diff --git a/src/Applications/UI/Tracks/Types.elm b/src/Core/UI/Tracks/Types.elm similarity index 100% rename from src/Applications/UI/Tracks/Types.elm rename to src/Core/UI/Tracks/Types.elm diff --git a/src/Applications/UI/Types.elm b/src/Core/UI/Types.elm similarity index 98% rename from src/Applications/UI/Types.elm rename to src/Core/UI/Types.elm index 004eeffa..d8df930a 100644 --- a/src/Applications/UI/Types.elm +++ b/src/Core/UI/Types.elm @@ -24,6 +24,7 @@ import Playlists exposing (Playlist, PlaylistTrack) import Queue import Random import Sources exposing (Source) +import Theme import Time import Tracks exposing (..) import UI.Audio.Types exposing (DurationChangeEvent, ErrorAudioEvent, GenericAudioEvent, NowPlaying, PlaybackStateEvent, TimeUpdatedEvent) @@ -76,6 +77,7 @@ type alias Model = , pressedKeys : List Keyboard.Key , processAutomatically : Bool , serviceWorkerStatus : ServiceWorkerStatus + , theme : Maybe Theme.Id , uuidSeed : Random.Seed , url : Url , version : String @@ -228,7 +230,9 @@ type Msg ----------------------------------------- -- Interface ----------------------------------------- + | AssistWithChangingTheme | Blur + | ChangeTheme Theme.Id | ContextMenuConfirmation String Msg | CopyToClipboard String | DismissNotification { id : Int } diff --git a/src/Applications/UI/User/State/Export.elm b/src/Core/UI/User/State/Export.elm similarity index 99% rename from src/Applications/UI/User/State/Export.elm rename to src/Core/UI/User/State/Export.elm index fdb8def6..bb9d60b6 100644 --- a/src/Applications/UI/User/State/Export.elm +++ b/src/Core/UI/User/State/Export.elm @@ -65,6 +65,7 @@ saveEnclosedUserData model = , shuffle = model.shuffle , sortBy = model.sortBy , sortDirection = model.sortDirection + , theme = model.theme } |> encodeEnclosedData |> Alien.broadcast Alien.SaveEnclosedUserData diff --git a/src/Applications/UI/User/State/Import.elm b/src/Core/UI/User/State/Import.elm similarity index 99% rename from src/Applications/UI/User/State/Import.elm rename to src/Core/UI/User/State/Import.elm index ccc5d78a..5905d71a 100644 --- a/src/Applications/UI/User/State/Import.elm +++ b/src/Core/UI/User/State/Import.elm @@ -220,6 +220,7 @@ importEnclosed value model = , searchTerm = data.searchTerm , sortBy = data.sortBy , sortDirection = data.sortDirection + , theme = data.theme } -- , Equalizer.adjustAllKnobs newEqualizerSettings diff --git a/src/Core/UI/View.elm b/src/Core/UI/View.elm new file mode 100644 index 00000000..1f3cefd3 --- /dev/null +++ b/src/Core/UI/View.elm @@ -0,0 +1,16 @@ +module UI.View exposing (view) + +import Browser +import UI.Theme +import UI.Types exposing (Model, Msg) + + + +-- 🗺 + + +view : Model -> Browser.Document Msg +view model = + { title = "Diffuse" + , body = [ UI.Theme.view model ] + } diff --git a/src/Library/Theme.elm b/src/Library/Theme.elm new file mode 100644 index 00000000..ff61848b --- /dev/null +++ b/src/Library/Theme.elm @@ -0,0 +1,28 @@ +module Theme exposing (..) + +import Html exposing (Html) +import Json.Decode as Decode +import Json.Encode as Encode +import Material.Icons.Types exposing (Icon) + + +type alias Id = + { id : String } + + +type alias Theme msg model = + { id : String + , title : String + , icon : Icon msg + , view : model -> Html msg + } + + +idDecoder : Decode.Decoder Id +idDecoder = + Decode.map (\s -> { id = s }) Decode.string + + +encodeId : Id -> Encode.Value +encodeId { id } = + Encode.string id diff --git a/src/Library/User/Layer.elm b/src/Library/User/Layer.elm index 3cb973ed..392e485c 100644 --- a/src/Library/User/Layer.elm +++ b/src/Library/User/Layer.elm @@ -30,6 +30,7 @@ import Settings import Sources import Sources.Encoding as Sources import Task exposing (Task) +import Theme import Time import Time.Ext as Time import Tracks @@ -84,6 +85,7 @@ type alias EnclosedData = , shuffle : Bool , sortBy : Tracks.SortBy , sortDirection : Tracks.SortDirection + , theme : Maybe Theme.Id } @@ -260,10 +262,11 @@ enclosedDataDecoder = |> optional "shuffle" Json.bool False |> optional "sortBy" Tracks.sortByDecoder Tracks.Album |> optional "sortDirection" Tracks.sortDirectionDecoder Tracks.Asc + |> optional "theme" (Json.maybe Theme.idDecoder) Nothing encodeEnclosedData : EnclosedData -> Json.Value -encodeEnclosedData { cachedTracks, equalizerSettings, grouping, onlyShowCachedTracks, onlyShowFavourites, repeat, scene, searchTerm, selectedPlaylist, shuffle, sortBy, sortDirection } = +encodeEnclosedData { cachedTracks, equalizerSettings, grouping, onlyShowCachedTracks, onlyShowFavourites, repeat, scene, searchTerm, selectedPlaylist, shuffle, sortBy, sortDirection, theme } = Json.Encode.object [ ( "cachedTracks", Json.Encode.list Json.Encode.string cachedTracks ) , ( "equalizerSettings", Equalizer.encodeSettings equalizerSettings ) @@ -277,6 +280,7 @@ encodeEnclosedData { cachedTracks, equalizerSettings, grouping, onlyShowCachedTr , ( "shuffle", Json.Encode.bool shuffle ) , ( "sortBy", Tracks.encodeSortBy sortBy ) , ( "sortDirection", Tracks.encodeSortDirection sortDirection ) + , ( "theme", Maybe.unwrap Json.Encode.null Theme.encodeId theme ) ] diff --git a/src/README.md b/src/README.md index a8271f8d..17b2300e 100644 --- a/src/README.md +++ b/src/README.md @@ -1,12 +1,10 @@ -# Infrastructure +# Elm code Elm directories: +- src/Core +- src/Library -- Applications/Brain -- Applications/UI -- Library - -`UI` is the Elm application that'll be executed on the main thread (ie. the UI thread) and `Brain` is the Elm application that'll live inside a web worker. `UI` will be the main application and `Brain` does the heavy lifting. The code shared between these two applications lives in `Library`. The library also contains the more "generic" code that's not necessarily tied to one or the other. +`UI` is the Elm application that'll be executed on the main thread (ie. the UI thread) and `Brain` is the Elm application that'll live inside a web worker. `UI` will be the main application and `Brain` does the heavy lifting. The code shared between these two applications lives in `Library`. The library also contains the more "generic" code that's not necessarily tied to one or the other. Additionally you have `Themes` which is a layer on top of the UI code. @@ -20,7 +18,7 @@ Elm directories: 🗺 Views 🧠 Brain -🔱 Functions +🛠️ Functions 🖼 Styles ㊙️ Secret ``` -- 2.51.2