fix(slint): album view layout and a working track search
Four album-view corrections from review: - Explicit badge: the title row now uses `alignment: start`, so the E badge sits right after the track name instead of being stretched out to a fake column position. - Label/awards sidebar: dropped `alignment: start` on the track/sidebar row — it had defeated the track list's stretch and left the sidebar floating mid-row with dead space. The list now stretches and the 254px sidebar is flush right; it rides the content region inward when a main sidebar opens. - Track search: now a real client-side filter — a TextInput drives the AlbumActions.search global callback; album.rs keeps the unfiltered list and filter_tracks() matches title/artist case-insensitively. - Description modal: the Flickable is vertical-stretch bounded so long text scrolls, and strip_html keeps paragraph breaks as newlines. cc
This commit is contained in:
5 files changed
+123
-28
No files matched your search
@@ -9,7 +9,7 @@ import { Theme } from "../foundation/semantic-colors.slint";
|
||||
import { Typography } from "../foundation/typography.slint";
|
||||
import { Radius } from "../foundation/radius.slint";
|
||||
import { Spacing } from "../foundation/spacing.slint";
|
||||
import { AlbumState, AlbumTrackItem, NavState, ContentView } from "../state.slint";
|
||||
import { AlbumState, AlbumTrackItem, AlbumActions, NavState, ContentView } from "../state.slint";
|
||||
import { QbzIcon } from "../primitives/QbzIcon.slint";
|
||||
import { ContextMenu } from "../primitives/ContextMenu.slint";
|
||||
import { ContextMenuItem } from "../primitives/ContextMenuItem.slint";
|
||||
@@ -83,7 +83,11 @@ component TrackRow inherits Rectangle {
|
||||
horizontal-stretch: 1;
|
||||
spacing: 2px;
|
||||
|
||||
// alignment: start packs the title and the explicit badge at
|
||||
// their natural sizes, so the badge sits right after the name
|
||||
// instead of being stretched out to a column position.
|
||||
HorizontalLayout {
|
||||
alignment: start;
|
||||
spacing: 6px;
|
||||
Text {
|
||||
text: root.track.title;
|
||||
@@ -93,19 +97,21 @@ component TrackRow inherits Rectangle {
|
||||
vertical-alignment: center;
|
||||
overflow: elide;
|
||||
}
|
||||
if root.track.explicit: Rectangle {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
y: (parent.height - self.height) / 2;
|
||||
border-radius: 3px;
|
||||
background: Theme.surface-elevated;
|
||||
Text {
|
||||
text: "E";
|
||||
color: Theme.text-muted;
|
||||
font-size: 9px;
|
||||
font-weight: Typography.semibold;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
if root.track.explicit: VerticalLayout {
|
||||
alignment: center;
|
||||
Rectangle {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 3px;
|
||||
background: Theme.surface-elevated;
|
||||
Text {
|
||||
text: "E";
|
||||
color: Theme.text-muted;
|
||||
font-size: 9px;
|
||||
font-weight: Typography.semibold;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -347,7 +353,6 @@ export component AlbumPageView inherits Rectangle {
|
||||
// --- Album header ------------------------------------------------
|
||||
HorizontalLayout {
|
||||
spacing: 32px;
|
||||
alignment: start;
|
||||
|
||||
Rectangle {
|
||||
width: 224px;
|
||||
@@ -498,9 +503,14 @@ export component AlbumPageView inherits Rectangle {
|
||||
Rectangle { height: 8px; }
|
||||
|
||||
// --- Track list + label/awards sidebar --------------------------
|
||||
// No `alignment: start` here: it would defeat the track list's
|
||||
// horizontal-stretch and leave the sidebar floating mid-row
|
||||
// with dead space to its right. The track list stretches and
|
||||
// the 254px sidebar is pushed flush to the right edge; when a
|
||||
// main right sidebar opens, the whole content region narrows
|
||||
// and the sidebar rides along with it.
|
||||
HorizontalLayout {
|
||||
spacing: 32px;
|
||||
alignment: start;
|
||||
|
||||
VerticalLayout {
|
||||
horizontal-stretch: 1;
|
||||
@@ -547,12 +557,27 @@ export component AlbumPageView inherits Rectangle {
|
||||
tint: Theme.text-muted;
|
||||
}
|
||||
}
|
||||
Text {
|
||||
text: @tr("Search tracks...");
|
||||
color: Theme.text-muted;
|
||||
font-size: 13px;
|
||||
vertical-alignment: center;
|
||||
// Functional client-side filter.
|
||||
Rectangle {
|
||||
horizontal-stretch: 1;
|
||||
track-search := TextInput {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: Theme.text-primary;
|
||||
font-size: 13px;
|
||||
vertical-alignment: center;
|
||||
single-line: true;
|
||||
edited => {
|
||||
AlbumActions.search(self.text);
|
||||
}
|
||||
}
|
||||
Text {
|
||||
visible: track-search.text == "";
|
||||
text: @tr("Search tracks...");
|
||||
color: Theme.text-muted;
|
||||
font-size: 13px;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -723,7 +748,10 @@ export component AlbumPageView inherits Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
// vertical-stretch bounds the Flickable to the leftover
|
||||
// panel height so a long description actually scrolls.
|
||||
Flickable {
|
||||
vertical-stretch: 1;
|
||||
viewport-width: self.width;
|
||||
viewport-height: desc-text.preferred-height;
|
||||
desc-text := Text {
|
||||
|
||||
@@ -10,7 +10,7 @@ import { LoginScreen } from "login/LoginScreen.slint";
|
||||
import { AppShell } from "shell/AppShell.slint";
|
||||
|
||||
// Re-export the state globals so the Rust layer can populate them.
|
||||
export { HomeState, AlbumState, ArtistState, NavState, SessionState, SettingsState } from "state.slint";
|
||||
export { HomeState, AlbumState, ArtistState, NavState, SessionState, SettingsState, AlbumActions } from "state.slint";
|
||||
|
||||
// Which top-level screen is shown. The app starts on `splash` while it
|
||||
// restores a saved session, then resolves to `shell` or `login`.
|
||||
|
||||
@@ -73,6 +73,12 @@ export global AlbumState {
|
||||
in property <bool> loading: false;
|
||||
}
|
||||
|
||||
// Album-view actions wired to Rust callbacks.
|
||||
export global AlbumActions {
|
||||
// Filter the visible track list by a query (client-side).
|
||||
callback search(string);
|
||||
}
|
||||
|
||||
// Which content view the shell shows.
|
||||
export enum ContentView { home, album, artist, settings }
|
||||
|
||||
|
||||
Reference in new issue
Block a user