feat(slint): NowPlayingBar rebuild, Settings constraints, Discover fixes

NowPlayingBar (start of the playback-bar work):
- height raised to 110px
- SeekBar component: three-line track (total / cached / progress), a
  hover thumb, elapsed/remaining times, and a hover time bubble with a
  downward caret marking the seek position
- song card: background and border dropped, gains the extra height,
  album/artist links and the context icon kept (context icon now
  always shown)
- transport + secondary buttons copied from Tauri (shuffle, prev,
  play, next, repeat, add, favorite; cast, picture-in-picture,
  fullscreen, normalization; volume cluster). Queue/Lyrics stay in the
  header — and the header now orders them lyrics-then-queue.

Settings constraints (1:1 with Tauri):
- Exclusive Mode enabled only on ALSA; DAC Passthrough only on
  PipeWire; Lock Output Device disabled while DAC Passthrough is on;
  Gapless disabled while Streaming Only is on
- backend change cascades: forces off DAC passthrough / force-bit-
  perfect / exclusive / gapless as appropriate; DAC-passthrough and
  streaming-only cascades; initial-buffer slider right-aligned

Discover fixes:
- navigation [<] [>] pair homologated to the same top/left margin
  across every view
- album/artist description moved back into the metadata column (it now
  fills the width there) with uniform secondary text color
- genre filter button hugs its label instead of stretching
- Recently Played Albums and Tracks modules always render, with a
  placeholder until the play history has data
- wider spacing between Discover rows; the Discover gear is no longer
  a Settings shortcut (it is the per-tab sort/show-hide control)

cc
This commit is contained in:
vicrodh committed 2026-05-18 21:22:40 -06:00
1 parent edca636a16
commit 99e3513d68
18 files changed
+589 -150

No files matched your search

+34 -31
View File
@@ -314,9 +314,11 @@ export component AlbumPageView inherits Rectangle {
page := VerticalLayout {
width: parent.width;
padding-left: 24px;
padding-right: 24px;
padding-top: 14px;
// padding matches Discover so the [<] [>] pair sits at the same
// top/left margin across every view.
padding-left: 32px;
padding-right: 32px;
padding-top: 11px;
padding-bottom: 100px;
spacing: 0px;
alignment: start;
@@ -386,11 +388,39 @@ export component AlbumPageView inherits Rectangle {
Rectangle { height: 10px; }
Text {
text: AlbumState.info-line;
color: Theme.text-muted;
color: Theme.text-secondary;
font-size: Typography.body;
overflow: elide;
}
// Editorial description — fills the metadata column's
// width (the dead space right of the artwork), truncated,
// with a Read more link to the full modal.
if AlbumState.description != "": Rectangle { height: 12px; }
if AlbumState.description != "": Text {
text: AlbumState.description-short;
color: Theme.text-secondary;
font-size: Typography.legal;
wrap: word-wrap;
}
if AlbumState.description != AlbumState.description-short: Rectangle { height: 4px; }
if AlbumState.description != AlbumState.description-short: read-more := TouchArea {
width: read-more-row.preferred-width;
height: 20px;
mouse-cursor: pointer;
clicked => {
root.show-description = true;
}
read-more-row := HorizontalLayout {
Text {
text: @tr("Read more");
color: read-more.has-hover ? Theme.accent-hover : Theme.accent;
font-size: Typography.legal;
vertical-alignment: center;
}
}
}
Rectangle { height: 20px; }
HorizontalLayout {
alignment: start;
@@ -444,33 +474,6 @@ export component AlbumPageView inherits Rectangle {
}
}
// Editorial description — full content width, pre-truncated so
// it wraps cleanly, with a Read more link to the full modal.
if AlbumState.description != "": Rectangle { height: 18px; }
if AlbumState.description != "": Text {
text: AlbumState.description-short;
color: Theme.text-secondary;
font-size: Typography.body;
wrap: word-wrap;
}
if AlbumState.description != AlbumState.description-short: Rectangle { height: 4px; }
if AlbumState.description != AlbumState.description-short: read-more := TouchArea {
width: read-more-row.preferred-width;
height: 22px;
mouse-cursor: pointer;
clicked => {
root.show-description = true;
}
read-more-row := HorizontalLayout {
Text {
text: @tr("Read more");
color: read-more.has-hover ? Theme.accent-hover : Theme.accent;
font-size: Typography.legal;
vertical-alignment: center;
}
}
}
Rectangle { height: 20px; }
Rectangle {
height: 1px;