feat(library): collapsable multi-artist header on local album detail

Spec 2026-07-19-local-album-grouping-mode (B2). A compilation album (the
Saint Seiya case: 10 distinct track artists) now shows the single artist
line plus a '+N more artists' chevron that expands into the full
track-artist list, each entry clickable into the LocalLibrary Artists tab
(name-based open-artist). Distinct raw track artists in first-appearance
order, computed in apply_album_version into LocalAlbumState.all-artists.
Expansion is view-local and resets on album change; single-artist albums
never see the chevron. Track rows already showed their own artist
(verified, no change needed).

2 msgids ('+{} more artists', 'Show less') x 8 locales; slintcheck green.

km
This commit is contained in:
vicrodh committed 2026-07-21 14:11:04 -06:00
1 parent c72e71d410
commit f18960ba54
11 files changed
+116

No files matched your search

@@ -4765,3 +4765,9 @@ msgstr "Album-Gruppierung"
msgid "Folders: one card per album folder — best for compilations and box sets. Metadata: split by album + artist tags."
msgstr "Ordner: eine Karte pro Album-Ordner — ideal für Compilations und Boxsets. Metadaten: nach Album- + Künstler-Tags aufteilen."
msgid "+{} more artists"
msgstr "+{} weitere Künstler"
msgid "Show less"
msgstr "Weniger anzeigen"
@@ -558,3 +558,9 @@ msgstr "Album grouping"
msgid "Folders: one card per album folder — best for compilations and box sets. Metadata: split by album + artist tags."
msgstr "Folders: one card per album folder — best for compilations and box sets. Metadata: split by album + artist tags."
msgid "+{} more artists"
msgstr "+{} more artists"
msgid "Show less"
msgstr "Show less"
@@ -4795,3 +4795,9 @@ msgstr "Agrupación de álbumes"
msgid "Folders: one card per album folder — best for compilations and box sets. Metadata: split by album + artist tags."
msgstr "Carpetas: una tarjeta por carpeta de álbum — ideal para compilaciones y box sets. Metadatos: separar por etiquetas de álbum + artista."
msgid "+{} more artists"
msgstr "+{} artistas más"
msgid "Show less"
msgstr "Ver menos"
@@ -4765,3 +4765,9 @@ msgstr "Regroupement des albums"
msgid "Folders: one card per album folder — best for compilations and box sets. Metadata: split by album + artist tags."
msgstr "Dossiers : une carte par dossier d'album — idéal pour les compilations et coffrets. Métadonnées : séparer par tags album + artiste."
msgid "+{} more artists"
msgstr "+{} artistes de plus"
msgid "Show less"
msgstr "Afficher moins"
@@ -4753,3 +4753,9 @@ msgstr "アルバムのグループ化"
msgid "Folders: one card per album folder — best for compilations and box sets. Metadata: split by album + artist tags."
msgstr "フォルダー: アルバムフォルダーごとに1枚のカード — コンピレーションやボックスセットに最適。メタデータ: アルバム+アーティストのタグで分割。"
msgid "+{} more artists"
msgstr "他 {} 人のアーティスト"
msgid "Show less"
msgstr "表示を減らす"
@@ -4777,3 +4777,9 @@ msgstr "Albumgroepering"
msgid "Folders: one card per album folder — best for compilations and box sets. Metadata: split by album + artist tags."
msgstr "Mappen: één kaart per albummap — ideaal voor compilaties en boxsets. Metadata: splitsen op album- + artiesttags."
msgid "+{} more artists"
msgstr "+{} artiesten meer"
msgid "Show less"
msgstr "Minder tonen"
@@ -4765,3 +4765,9 @@ msgstr "Agrupamento de álbuns"
msgid "Folders: one card per album folder — best for compilations and box sets. Metadata: split by album + artist tags."
msgstr "Pastas: um cartão por pasta de álbum — ideal para compilações e box sets. Metadados: dividir por etiquetas de álbum + artista."
msgid "+{} more artists"
msgstr "+{} artistas mais"
msgid "Show less"
msgstr "Mostrar menos"
@@ -4779,3 +4779,9 @@ msgstr "Группировка альбомов"
msgid "Folders: one card per album folder — best for compilations and box sets. Metadata: split by album + artist tags."
msgstr "Папки: одна карточка на папку альбома — лучше для сборников и бокс-сетов. Метаданные: разделение по тегам альбома + исполнителя."
msgid "+{} more artists"
msgstr "+ ещё {} исполнителей"
msgid "Show less"
msgstr "Показать меньше"
@@ -150,6 +150,14 @@ export component LocalAlbumView inherits Rectangle {
callback open-artist(string);
background: ShellState.app-background-active ? transparent : Theme.surface-main;
// Expanded multi-artist header list (spec §B2) — view-local, resets when
// another album opens (watched via the mirror property below).
property <bool> artists-expanded: false;
property <string> watched-album-id: LocalAlbumState.id;
changed watched-album-id => {
root.artists-expanded = false;
}
// Homologated 1:1 with the Qobuz AlbumPageView: whole-page Flickable, the
// same header proportions + action row, the toolbar (quality badge + track
// search), the column header, and source-aware TrackRows. The only
@@ -238,6 +246,7 @@ export component LocalAlbumView inherits Rectangle {
Rectangle { height: 4px; }
HorizontalLayout {
alignment: start;
spacing: 8px;
la-artist := TouchArea {
width: la-artist-text.preferred-width;
height: la-artist-text.preferred-height;
@@ -254,6 +263,46 @@ export component LocalAlbumView inherits Rectangle {
font-weight: Typography.bold;
}
}
// Multi-artist album (compilations): a "+N more
// artists" chevron expands the full track-artist list
// below (spec §B2). Single-artist albums never see it.
if LocalAlbumState.all-artists.length > 1: VerticalLayout {
alignment: center;
more-ta := TouchArea {
width: more-text.preferred-width;
height: more-text.preferred-height;
mouse-cursor: pointer;
clicked => {
root.artists-expanded = !root.artists-expanded;
}
more-text := Text {
text: root.artists-expanded
? @tr("Show less")
: @tr("+{} more artists", LocalAlbumState.all-artists.length - 1);
color: more-ta.has-hover ? Theme.accent : Theme.text-muted;
font-size: Typography.body;
}
}
}
}
// Expanded track-artist list — each entry routes to the
// LocalLibrary Artists tab (name-based open-artist).
if root.artists-expanded && LocalAlbumState.all-artists.length > 1: VerticalLayout {
spacing: 0px;
padding-top: 6px;
for artist in LocalAlbumState.all-artists: TouchArea {
height: 24px;
mouse-cursor: pointer;
clicked => {
root.open-artist(artist);
}
Text {
text: artist;
color: parent.has-hover ? Theme.accent : Theme.text-secondary;
font-size: Typography.body;
vertical-alignment: center;
}
}
}
Rectangle { height: 10px; }
Text {
+4
View File
@@ -1456,6 +1456,10 @@ export global LocalAlbumState {
in property <string> quality-detail; // "24-bit / 96 kHz"
in property <string> cover-url;
in property <image> cover;
// Distinct track artists in first-appearance order (compilations); the
// header shows the single artist line + a "+N more artists" chevron that
// expands into the clickable full list (spec §B2). Empty/1 = no chevron.
in property <[string]> all-artists: [];
in property <bool> loading: false;
in property <[TrackItem]> tracks: [];
// Versions (distinct copies). >1 -> show the picker. Sorted best-quality