diff --git a/src/browser_ffi.mjs b/src/browser_ffi.mjs index 91635a5..51d3122 100644 --- a/src/browser_ffi.mjs +++ b/src/browser_ffi.mjs @@ -1,3 +1,7 @@ export function requestAnimationFrame(callback) { globalThis.requestAnimationFrame(callback); } + +export function replaceHash(hash) { + globalThis.history.replaceState({}, document.title, hash); +} diff --git a/src/elekf/utils/browser.gleam b/src/elekf/utils/browser.gleam index dc62d1b..6563eaa 100644 --- a/src/elekf/utils/browser.gleam +++ b/src/elekf/utils/browser.gleam @@ -1,2 +1,5 @@ @external(javascript, "../../browser_ffi.mjs", "requestAnimationFrame") pub fn request_animation_frame(callback: fn() -> Nil) -> Nil + +@external(javascript, "../../browser_ffi.mjs", "replaceHash") +pub fn replace_hash(new_url: String) -> Nil diff --git a/src/elekf/web/authed_view.gleam b/src/elekf/web/authed_view.gleam index 66c9a05..8dfee27 100644 --- a/src/elekf/web/authed_view.gleam +++ b/src/elekf/web/authed_view.gleam @@ -38,6 +38,7 @@ import elekf/web/components/button_group import elekf/web/components/link import elekf/web/events/start_play import elekf/web/utils +import elekf/utils/browser import elekf/web/components/icon.{Alt, icon} import elektrofoni @@ -91,12 +92,22 @@ pub fn init(auth_data: common.AuthData) { effect.from(fn(dispatch) { router.init(dispatch) }) |> effect.map(Router) - let #(path, _query) = router.get_current_path() + let #(path, query) = router.get_current_path() + let route = result.unwrap(router.parse(path), router.default_route) + + // If we are initialising straight into the full screen player, remove the + // query argument (as the player is not open on init) + case set.contains(router.parse_query(query), router.FullScreen) { + True -> + browser.replace_hash( + router.queryless(route) + |> router.to_hash(), + ) + False -> Nil + } let initial_view = - path - |> router.parse() - |> result.unwrap(router.TrackList) + route |> route_to_view() |> result.unwrap(library_view.Tracks) diff --git a/src/elekf/web/components/library_views/single_album_view.gleam b/src/elekf/web/components/library_views/single_album_view.gleam index 1ccf08b..cc26522 100644 --- a/src/elekf/web/components/library_views/single_album_view.gleam +++ b/src/elekf/web/components/library_views/single_album_view.gleam @@ -77,7 +77,7 @@ fn init() { True, fn(_) -> List(LibraryItem(Track)) { [] }, shuffler, - track_utils.sort_by_name, + track_utils.sort_by_track_number, ) #( diff --git a/src/elekf/web/components/player/full_screen.gleam b/src/elekf/web/components/player/full_screen.gleam index 7d6436e..2ad0a2b 100644 --- a/src/elekf/web/components/player/full_screen.gleam +++ b/src/elekf/web/components/player/full_screen.gleam @@ -1,4 +1,5 @@ import gleam/int +import gleam/float import gleam/option import lustre/element.{text} import lustre/element/html.{div, input, p} @@ -40,6 +41,22 @@ pub fn view(model: Model) { p([attribute.id("full-player-track-name")], [text(model.track.title)]), p([attribute.id("full-player-artist-name")], [text(model.artist.name)]), p([attribute.id("full-player-album-name")], [text(model.album.name)]), + div([attribute.id("full-player-metas")], [ + meta("full-player-trackno", "Track", int.to_string(model.track.number)), + meta("full-player-discno", "Disc", int.to_string(model.album.disc)), + meta("full-player-genre", "Genre", model.track.genre), + meta("full-player-year", "Year", int.to_string(model.track.year)), + meta( + "full-player-replaygain", + "ReplayGain", + float.to_string(model.track.replay_gain), + ), + meta( + "full-player-rating", + "Rating", + int.to_string(model.track.rating) <> " / 5", + ), + ]), div([attribute.id("player-controls")], [ button_group.view("", [attribute.id("player-controls-buttons")], [ button.view( @@ -104,3 +121,10 @@ pub fn view(model: Model) { ], ) } + +fn meta(id: String, title: String, value: String) { + div([attribute.id(id), attribute.class("full-player-meta")], [ + p([], [text(title)]), + p([], [text(value)]), + ]) +} diff --git a/style.css b/style.css index 0dbf4f3..6ef5fcd 100644 --- a/style.css +++ b/style.css @@ -16,7 +16,7 @@ --background-gradient-top: rgba(252, 176, 69, 1); --text-color: #123456; - --glass-opacity: 0.3; + --glass-opacity: 0.5; --glass-opacity-active: 0.2; --glass-shadow-opacity: 0.1; --glass-background: rgba(255, 255, 255, var(--glass-opacity)); @@ -36,7 +36,7 @@ --track-thumb-size: 20px; --track-scale-factor: 4; - --library-top-nav-height: 45px; + --library-top-nav-height: 50px; --search-size: 1.6rem; } @@ -229,8 +229,16 @@ single-album-view { padding: var(--double-margin); display: grid; - grid-template: "art art" "track track" "artist artist" "album album" ". ." 1fr "controls controls" auto / 1fr 1fr; - gap: var(--side-margin); + grid-template: + "art art" + "track track" + "artist artist" + "album album" + "meta meta" + ". ." 1fr + "controls controls" auto + / 1fr 1fr; + gap: var(--double-margin); text-align: center; font-weight: 100; @@ -239,7 +247,15 @@ single-album-view { #full-player-artwork-wrapper img { margin: 0 auto; - padding-bottom: var(--side-margin); + padding-bottom: var(--double-margin); +} + +#full-player-metas { + grid-area: meta; + + display: grid; + gap: var(--double-margin); + grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); } #player-controls { @@ -332,8 +348,10 @@ single-album-view { } #library-top-nav .glass-button { - font-size: 2rem; padding: 0; + + font-size: 2rem; + line-height: var(--library-top-nav-height); } #library-loading-indicator { @@ -431,13 +449,6 @@ single-album-view { aspect-ratio: 1 / 1; } -.library-item-expanded { -} - -.library-item-expanded-contents { - grid-column: 1 / -1; -} - .library-item { cursor: pointer; }