feat(qbz-qt): add global compact album headers
cx
This commit is contained in:
15 files changed
+287
-36
No files matched your search
@@ -5985,3 +5985,15 @@ msgstr "Titel-Wellenform"
|
||||
|
||||
msgid "Show the full-track waveform in the player seek bar."
|
||||
msgstr "Zeigt die Wellenform des gesamten Titels in der Suchleiste des Players an."
|
||||
|
||||
msgid "Compact header"
|
||||
msgstr "Kompakter Kopfbereich"
|
||||
|
||||
msgid "Show less data in album headers."
|
||||
msgstr "Weniger Daten in Albumkopfbereichen anzeigen."
|
||||
|
||||
msgid "Show full album header"
|
||||
msgstr "Vollständigen Albumkopf anzeigen"
|
||||
|
||||
msgid "Show compact album header"
|
||||
msgstr "Kompakten Albumkopf anzeigen"
|
||||
@@ -1587,3 +1587,15 @@ msgstr "Show the full-track waveform in the player seek bar."
|
||||
|
||||
msgid "The typeface used across the app. System follows your operating system; the other choices are bundled with QBZ (requires restart)"
|
||||
msgstr "The typeface used across the app. System follows your operating system; the other choices are bundled with QBZ (requires restart)"
|
||||
|
||||
msgid "Compact header"
|
||||
msgstr "Compact header"
|
||||
|
||||
msgid "Show less data in album headers."
|
||||
msgstr "Show less data in album headers."
|
||||
|
||||
msgid "Show full album header"
|
||||
msgstr "Show full album header"
|
||||
|
||||
msgid "Show compact album header"
|
||||
msgstr "Show compact album header"
|
||||
@@ -5991,3 +5991,15 @@ msgstr "Forma de onda de la pista"
|
||||
|
||||
msgid "Show the full-track waveform in the player seek bar."
|
||||
msgstr "Muestra la forma de onda completa de la pista en la barra de búsqueda del reproductor."
|
||||
|
||||
msgid "Compact header"
|
||||
msgstr "Encabezado compacto"
|
||||
|
||||
msgid "Show less data in album headers."
|
||||
msgstr "Muestra menos datos en los encabezados de los álbumes."
|
||||
|
||||
msgid "Show full album header"
|
||||
msgstr "Mostrar el encabezado completo del álbum"
|
||||
|
||||
msgid "Show compact album header"
|
||||
msgstr "Mostrar el encabezado compacto del álbum"
|
||||
@@ -5983,3 +5983,15 @@ msgstr "Forme d’onde du morceau"
|
||||
|
||||
msgid "Show the full-track waveform in the player seek bar."
|
||||
msgstr "Affiche la forme d’onde complète du morceau dans la barre de lecture."
|
||||
|
||||
msgid "Compact header"
|
||||
msgstr "En-tête compact"
|
||||
|
||||
msgid "Show less data in album headers."
|
||||
msgstr "Afficher moins d’informations dans les en-têtes d’album."
|
||||
|
||||
msgid "Show full album header"
|
||||
msgstr "Afficher l’en-tête complet de l’album"
|
||||
|
||||
msgid "Show compact album header"
|
||||
msgstr "Afficher l’en-tête compact de l’album"
|
||||
@@ -5967,3 +5967,15 @@ msgstr "トラック波形"
|
||||
|
||||
msgid "Show the full-track waveform in the player seek bar."
|
||||
msgstr "プレーヤーのシークバーにトラック全体の波形を表示します。"
|
||||
|
||||
msgid "Compact header"
|
||||
msgstr "コンパクトヘッダー"
|
||||
|
||||
msgid "Show less data in album headers."
|
||||
msgstr "アルバムヘッダーに表示する情報を減らします。"
|
||||
|
||||
msgid "Show full album header"
|
||||
msgstr "アルバムヘッダーをすべて表示"
|
||||
|
||||
msgid "Show compact album header"
|
||||
msgstr "アルバムヘッダーをコンパクトに表示"
|
||||
@@ -5973,3 +5973,15 @@ msgstr "Golfvorm van nummer"
|
||||
|
||||
msgid "Show the full-track waveform in the player seek bar."
|
||||
msgstr "Toon de golfvorm van het volledige nummer in de zoekbalk van de speler."
|
||||
|
||||
msgid "Compact header"
|
||||
msgstr "Compacte kop"
|
||||
|
||||
msgid "Show less data in album headers."
|
||||
msgstr "Toon minder gegevens in albumkoppen."
|
||||
|
||||
msgid "Show full album header"
|
||||
msgstr "Volledige albumkop tonen"
|
||||
|
||||
msgid "Show compact album header"
|
||||
msgstr "Compacte albumkop tonen"
|
||||
@@ -5983,3 +5983,15 @@ msgstr "Forma de onda da faixa"
|
||||
|
||||
msgid "Show the full-track waveform in the player seek bar."
|
||||
msgstr "Mostra a forma de onda completa da faixa na barra de busca do player."
|
||||
|
||||
msgid "Compact header"
|
||||
msgstr "Cabeçalho compacto"
|
||||
|
||||
msgid "Show less data in album headers."
|
||||
msgstr "Mostrar menos dados nos cabeçalhos de álbuns."
|
||||
|
||||
msgid "Show full album header"
|
||||
msgstr "Mostrar cabeçalho completo do álbum"
|
||||
|
||||
msgid "Show compact album header"
|
||||
msgstr "Mostrar cabeçalho compacto do álbum"
|
||||
@@ -6003,3 +6003,15 @@ msgstr "Форма волны трека"
|
||||
|
||||
msgid "Show the full-track waveform in the player seek bar."
|
||||
msgstr "Показывать форму волны всего трека на шкале воспроизведения."
|
||||
|
||||
msgid "Compact header"
|
||||
msgstr "Компактный заголовок"
|
||||
|
||||
msgid "Show less data in album headers."
|
||||
msgstr "Показывать меньше данных в заголовках альбомов."
|
||||
|
||||
msgid "Show full album header"
|
||||
msgstr "Показать полный заголовок альбома"
|
||||
|
||||
msgid "Show compact album header"
|
||||
msgstr "Показать компактный заголовок альбома"
|
||||
@@ -117,6 +117,14 @@ Column {
|
||||
onToggled: function (v) { QbzBridge.settingsBool("album-header-gradient", v) }
|
||||
}
|
||||
}
|
||||
SettingRow {
|
||||
label: QbzSession.tr("Compact header", QbzSession.trRev)
|
||||
description: QbzSession.tr("Show less data in album headers.", QbzSession.trRev)
|
||||
QbzToggle {
|
||||
checked: root.doc.compactAlbumHeader === true
|
||||
onToggled: function (v) { QbzBridge.settingsBool("compact-album-header", v) }
|
||||
}
|
||||
}
|
||||
SettingRow {
|
||||
label: QbzSession.tr("Dynamic background", QbzSession.trRev)
|
||||
description: QbzSession.tr("Animated album-art background behind the whole app. High resource use — GPU accelerated.", QbzSession.trRev)
|
||||
|
||||
@@ -48,7 +48,7 @@ Rectangle {
|
||||
/// twin and both text columns all measure off it — they drifted apart at
|
||||
/// five separate literals before. The Row has no explicit height, so the
|
||||
/// header grows with this on its own.
|
||||
readonly property int coverPx: 260
|
||||
readonly property int coverPx: compactHeaderPref ? 130 : 260
|
||||
|
||||
/// How far past the header divider the artwork atmosphere reaches: the 8px
|
||||
/// spacer below the divider plus half of the 52px track toolbar band, so
|
||||
@@ -106,6 +106,21 @@ Rectangle {
|
||||
|
||||
readonly property var albumHeader: album.header || ({})
|
||||
readonly property var tracks: album.tracks || []
|
||||
// One global opt-in for every album page. `settingsJson` is the live
|
||||
// channel (including clicks made in another open AlbumView); the album
|
||||
// document carries the persisted cold-start fallback until that snapshot
|
||||
// arrives.
|
||||
readonly property bool compactHeaderPref: {
|
||||
var raw = QbzBridge.settingsJson
|
||||
if (raw && raw.length > 2) {
|
||||
try {
|
||||
var d = JSON.parse(raw)
|
||||
if (d.compactAlbumHeader !== undefined)
|
||||
return d.compactAlbumHeader === true
|
||||
} catch (e) { /* fall through to the document copy */ }
|
||||
}
|
||||
return album.compactHeader === true
|
||||
}
|
||||
// `header.awards`, NOT `album.awards`. It is a field of AlbumHeader
|
||||
// (src/album_qt.rs:171), not of AlbumViewData — read one level too high it
|
||||
// is `undefined`, `|| []` swallows that, and the AWARDS block simply never
|
||||
@@ -785,13 +800,36 @@ Rectangle {
|
||||
anchors.topMargin: 4
|
||||
spacing: 0
|
||||
|
||||
Text {
|
||||
Item {
|
||||
width: parent.width
|
||||
text: albumHeader.title || ""
|
||||
color: root.hdrStrong
|
||||
font.pixelSize: theme.fontSection
|
||||
font.weight: theme.weightBold
|
||||
elide: Text.ElideRight
|
||||
height: Math.max(albumTitle.implicitHeight, 32)
|
||||
Text {
|
||||
id: albumTitle
|
||||
anchors.left: parent.left
|
||||
anchors.right: headerModeButton.left
|
||||
anchors.rightMargin: 12
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: albumHeader.title || ""
|
||||
color: root.hdrStrong
|
||||
font.pixelSize: theme.fontSection
|
||||
font.weight: theme.weightBold
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
QbzCircleAction {
|
||||
id: headerModeButton
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
name: root.compactHeaderPref ? "maximize-2" : "minimize-2"
|
||||
overlay: root.hdrOverlay
|
||||
onClicked: QbzBridge.settingsBool(
|
||||
"compact-album-header", !root.compactHeaderPref)
|
||||
HoverHandler { id: headerModeHover }
|
||||
ToolTip.visible: headerModeHover.hovered
|
||||
ToolTip.text: root.compactHeaderPref
|
||||
? QbzSession.tr("Show full album header", QbzSession.trRev)
|
||||
: QbzSession.tr("Show compact album header", QbzSession.trRev)
|
||||
ToolTip.delay: 350
|
||||
}
|
||||
}
|
||||
Item { width: 1; height: 4 }
|
||||
// Credited-artist line (links + role suffixes).
|
||||
@@ -799,7 +837,9 @@ Rectangle {
|
||||
width: parent.width
|
||||
spacing: 0
|
||||
Repeater {
|
||||
model: albumHeader.credits || []
|
||||
model: root.compactHeaderPref
|
||||
? [[albumHeader.artist || "", albumHeader.artistId || "", ""]]
|
||||
: (albumHeader.credits || [])
|
||||
delegate: Row {
|
||||
required property var modelData
|
||||
required property int index
|
||||
@@ -834,11 +874,13 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
}
|
||||
Item { width: 1; height: 10 }
|
||||
Item { width: 1; height: root.compactHeaderPref ? 4 : 10 }
|
||||
// Meta line (label as a clickable link when navigable).
|
||||
Row {
|
||||
spacing: 0
|
||||
visible: (albumHeader.labelId || "") !== "" && (albumHeader.label || "") !== ""
|
||||
visible: !root.compactHeaderPref
|
||||
&& (albumHeader.labelId || "") !== ""
|
||||
&& (albumHeader.label || "") !== ""
|
||||
Text {
|
||||
visible: (albumHeader.metaPre || "") !== ""
|
||||
text: (albumHeader.metaPre || "") + " • "
|
||||
@@ -865,27 +907,51 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
Text {
|
||||
visible: (albumHeader.labelId || "") === "" || (albumHeader.label || "") === ""
|
||||
visible: !root.compactHeaderPref
|
||||
&& ((albumHeader.labelId || "") === ""
|
||||
|| (albumHeader.label || "") === "")
|
||||
width: parent.width
|
||||
text: albumHeader.infoLine || ""
|
||||
color: root.hdrBody
|
||||
font.pixelSize: theme.fontBody
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
Text {
|
||||
visible: root.compactHeaderPref
|
||||
width: parent.width
|
||||
text: albumHeader.compactInfoLine || ""
|
||||
color: root.hdrBody
|
||||
font.pixelSize: theme.fontBody
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
// Editorial description + Read more.
|
||||
Item { visible: (albumHeader.description || "") !== ""; width: 1; height: 12 }
|
||||
Item {
|
||||
visible: !root.compactHeaderPref
|
||||
&& (albumHeader.description || "") !== ""
|
||||
width: 1
|
||||
height: 12
|
||||
}
|
||||
Text {
|
||||
visible: (albumHeader.description || "") !== ""
|
||||
visible: !root.compactHeaderPref
|
||||
&& (albumHeader.description || "") !== ""
|
||||
width: parent.width
|
||||
text: albumHeader.descriptionShort || ""
|
||||
color: root.hdrBody
|
||||
font.pixelSize: theme.fontLegal
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
Item { visible: (albumHeader.description || "") !== (albumHeader.descriptionShort || ""); width: 1; height: 4 }
|
||||
Item {
|
||||
visible: !root.compactHeaderPref
|
||||
&& (albumHeader.description || "")
|
||||
!== (albumHeader.descriptionShort || "")
|
||||
width: 1
|
||||
height: 4
|
||||
}
|
||||
Text {
|
||||
visible: (albumHeader.description || "") !== (albumHeader.descriptionShort || "")
|
||||
visible: !root.compactHeaderPref
|
||||
&& (albumHeader.description || "")
|
||||
!== (albumHeader.descriptionShort || "")
|
||||
text: QbzSession.tr("Read more", QbzSession.trRev)
|
||||
color: readMoreArea.containsMouse ? theme.accentHover : theme.accent
|
||||
font.pixelSize: theme.fontLegal
|
||||
@@ -902,7 +968,7 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
Item { width: 1; height: 20 }
|
||||
Item { width: 1; height: root.compactHeaderPref ? 8 : 20 }
|
||||
// Action row — AlbumPageView.slint:504-640. One shared
|
||||
// CircleAction for every button including Play (the
|
||||
// hand-rolled 44px disc it used to be drifted from the
|
||||
|
||||
@@ -44,6 +44,20 @@ Rectangle {
|
||||
readonly property var album: doc ? doc.album : null
|
||||
readonly property var tracks: doc ? doc.tracks : []
|
||||
readonly property var versions: album && album.versions ? album.versions : []
|
||||
// Same global preference as the Qobuz AlbumView. The document value is
|
||||
// only the cold-start fallback; settingsJson makes a toggle in any open
|
||||
// album update every other album immediately.
|
||||
readonly property bool compactHeaderPref: {
|
||||
var raw = QbzBridge.settingsJson
|
||||
if (raw && raw.length > 2) {
|
||||
try {
|
||||
var d = JSON.parse(raw)
|
||||
if (d.compactAlbumHeader !== undefined)
|
||||
return d.compactAlbumHeader === true
|
||||
} catch (e) { /* fall through to the document copy */ }
|
||||
}
|
||||
return doc && doc.compactHeader === true
|
||||
}
|
||||
readonly property var allArtists: {
|
||||
if (!album) return []
|
||||
var raw = (album.allArtists || "").split(",")
|
||||
@@ -66,6 +80,14 @@ Rectangle {
|
||||
if ((album.format || "") !== "") parts.push(album.format.toUpperCase())
|
||||
return parts.join(" • ")
|
||||
}
|
||||
readonly property string compactInfoLine: {
|
||||
if (!album) return ""
|
||||
var parts = []
|
||||
if ((album.year || "") !== "") parts.push(album.year)
|
||||
parts.push((album.trackCount || 0) + " "
|
||||
+ QbzSession.tr("tracks", QbzSession.trRev))
|
||||
return parts.join(" • ")
|
||||
}
|
||||
|
||||
property string trackQuery: ""
|
||||
// Client-side track search: an album's track list is bounded, so the
|
||||
@@ -378,9 +400,9 @@ Rectangle {
|
||||
visible: root.pageLoading && !root.album
|
||||
variant: "header"
|
||||
width: parent.width
|
||||
height: 224
|
||||
coverSize: 224
|
||||
coverGap: 32
|
||||
height: root.compactHeaderPref ? 128 : 224
|
||||
coverSize: root.compactHeaderPref ? 128 : 224
|
||||
coverGap: root.compactHeaderPref ? 20 : 32
|
||||
actionCount: 5
|
||||
phase: root.skelPhase
|
||||
}
|
||||
@@ -390,12 +412,16 @@ Rectangle {
|
||||
album: root.album
|
||||
allArtists: root.allArtists
|
||||
infoLine: root.infoLine
|
||||
compactInfoLine: root.compactInfoLine
|
||||
compact: root.compactHeaderPref
|
||||
versions: root.versions
|
||||
coverSource: root.album ? (root.artMap[root.album.artKey] || "") : ""
|
||||
coverPending: root.coverPending
|
||||
skelPhase: root.skelPhase
|
||||
artSettleMs: root.artSettleMs
|
||||
onOpenArtist: function (name) { root.openArtist(name) }
|
||||
onCompactToggled: QbzBridge.settingsBool(
|
||||
"compact-album-header", !root.compactHeaderPref)
|
||||
}
|
||||
|
||||
Item { width: 1; height: 20 }
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
// Slint watches its own mirror property for exactly this (:156).
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import com.blitzfc.qbz
|
||||
import "../../controls"
|
||||
import "../../theme"
|
||||
@@ -18,6 +19,8 @@ Row {
|
||||
/// De-duplicated contributor list (>1 turns the expander on).
|
||||
property var allArtists: []
|
||||
property string infoLine: ""
|
||||
property string compactInfoLine: ""
|
||||
property bool compact: false
|
||||
property var versions: []
|
||||
property string coverSource: ""
|
||||
/// Per-item cover state, owned by the page (LocalAlbumView).
|
||||
@@ -33,17 +36,19 @@ Row {
|
||||
property bool skelPhase: false
|
||||
property int artSettleMs: 0
|
||||
signal openArtist(string name)
|
||||
signal compactToggled()
|
||||
|
||||
QbzTheme { id: theme }
|
||||
|
||||
property bool artistsExpanded: false
|
||||
onAlbumChanged: artistsExpanded = false
|
||||
|
||||
spacing: 32
|
||||
readonly property int coverPx: compact ? 128 : 224
|
||||
spacing: compact ? 20 : 32
|
||||
|
||||
Rectangle {
|
||||
width: 224
|
||||
height: 224
|
||||
width: root.coverPx
|
||||
height: root.coverPx
|
||||
radius: 12
|
||||
color: theme.surfaceElevated
|
||||
clip: true
|
||||
@@ -68,17 +73,38 @@ Row {
|
||||
}
|
||||
|
||||
Column {
|
||||
width: parent.width - 224 - 32
|
||||
width: parent.width - root.coverPx - root.spacing
|
||||
topPadding: 4
|
||||
spacing: 0
|
||||
|
||||
Text {
|
||||
Item {
|
||||
width: parent.width
|
||||
text: root.album ? (root.album.title || "") : ""
|
||||
color: theme.textPrimary
|
||||
font.pixelSize: theme.fontSection
|
||||
font.weight: theme.weightBold
|
||||
elide: Text.ElideRight
|
||||
height: Math.max(localAlbumTitle.implicitHeight, 32)
|
||||
Text {
|
||||
id: localAlbumTitle
|
||||
anchors.left: parent.left
|
||||
anchors.right: localHeaderModeButton.left
|
||||
anchors.rightMargin: 12
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: root.album ? (root.album.title || "") : ""
|
||||
color: theme.textPrimary
|
||||
font.pixelSize: theme.fontSection
|
||||
font.weight: theme.weightBold
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
QbzCircleAction {
|
||||
id: localHeaderModeButton
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
name: root.compact ? "maximize-2" : "minimize-2"
|
||||
onClicked: root.compactToggled()
|
||||
HoverHandler { id: localHeaderModeHover }
|
||||
ToolTip.visible: localHeaderModeHover.hovered
|
||||
ToolTip.text: root.compact
|
||||
? QbzSession.tr("Show full album header", QbzSession.trRev)
|
||||
: QbzSession.tr("Show compact album header", QbzSession.trRev)
|
||||
ToolTip.delay: 350
|
||||
}
|
||||
}
|
||||
Item { width: 1; height: 4 }
|
||||
Row {
|
||||
@@ -99,7 +125,7 @@ Row {
|
||||
// Multi-artist album (compilations): "+N more artists" expands
|
||||
// the full track-artist list below.
|
||||
Text {
|
||||
visible: root.allArtists.length > 1
|
||||
visible: !root.compact && root.allArtists.length > 1
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: root.artistsExpanded
|
||||
? QbzSession.tr("Show less", QbzSession.trRev)
|
||||
@@ -119,7 +145,8 @@ Row {
|
||||
// Expanded track-artist list — each entry routes to the Local
|
||||
// Library Artists tab (name-based).
|
||||
Column {
|
||||
visible: root.artistsExpanded && root.allArtists.length > 1
|
||||
visible: !root.compact && root.artistsExpanded
|
||||
&& root.allArtists.length > 1
|
||||
width: parent.width
|
||||
topPadding: 6
|
||||
spacing: 0
|
||||
@@ -143,15 +170,15 @@ Row {
|
||||
}
|
||||
}
|
||||
}
|
||||
Item { width: 1; height: 10 }
|
||||
Item { width: 1; height: root.compact ? 4 : 10 }
|
||||
Text {
|
||||
width: parent.width
|
||||
text: root.infoLine
|
||||
text: root.compact ? root.compactInfoLine : root.infoLine
|
||||
color: theme.textSecondary
|
||||
font.pixelSize: theme.fontBody
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
Item { width: 1; height: 20 }
|
||||
Item { width: 1; height: root.compact ? 8 : 20 }
|
||||
|
||||
// ---- Local action row ----
|
||||
Row {
|
||||
@@ -186,12 +213,12 @@ Row {
|
||||
|
||||
// ---- Version picker (multiple physical copies only) ----
|
||||
Item {
|
||||
visible: root.versions.length > 1
|
||||
visible: !root.compact && root.versions.length > 1
|
||||
width: 1
|
||||
height: visible ? 16 : 0
|
||||
}
|
||||
Row {
|
||||
visible: root.versions.length > 1
|
||||
visible: !root.compact && root.versions.length > 1
|
||||
spacing: 8
|
||||
Text {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
@@ -166,6 +166,10 @@ pub struct AlbumHeader {
|
||||
pub credits: Vec<(String, String, String)>,
|
||||
#[serde(rename = "infoLine")]
|
||||
pub info_line: String,
|
||||
/// Compact header metadata: release date + track count only. Label,
|
||||
/// genre and duration intentionally stay in the expanded header.
|
||||
#[serde(rename = "compactInfoLine")]
|
||||
pub compact_info_line: String,
|
||||
#[serde(rename = "metaPre")]
|
||||
pub meta_pre: String,
|
||||
#[serde(rename = "metaPost")]
|
||||
@@ -234,6 +238,11 @@ pub struct AlbumHeader {
|
||||
pub struct AlbumViewData {
|
||||
pub header: AlbumHeader,
|
||||
pub tracks: Vec<TrackRow>,
|
||||
/// Cold-start fallback for the live `settingsJson` preference consumed by
|
||||
/// AlbumView.qml. The view switches to the settings document as soon as it
|
||||
/// is published, so toggling one open album updates every other instance.
|
||||
#[serde(rename = "compactHeader")]
|
||||
pub compact_header: bool,
|
||||
#[serde(rename = "moreFromArtist")]
|
||||
pub more_from_artist: Vec<AlbumCardData>,
|
||||
pub suggestions: Vec<AlbumCardData>,
|
||||
@@ -601,6 +610,11 @@ pub async fn load_album(
|
||||
}
|
||||
let meta_pre = pre_parts.join(" • ");
|
||||
let meta_post = post_parts.join(" • ");
|
||||
let mut compact_parts = pre_parts.clone();
|
||||
if let Some(tc) = &tracks_str {
|
||||
compact_parts.push(tc.clone());
|
||||
}
|
||||
let compact_info_line = compact_parts.join(" • ");
|
||||
let mut all_parts = pre_parts.clone();
|
||||
if let Some(l) = &label_name {
|
||||
all_parts.push(l.clone());
|
||||
@@ -679,6 +693,7 @@ pub async fn load_album(
|
||||
artist_id,
|
||||
credits,
|
||||
info_line,
|
||||
compact_info_line,
|
||||
meta_pre,
|
||||
meta_post,
|
||||
quality_tier: home_qt::quality_tier_from_depth(album.maximum_bit_depth).to_string(),
|
||||
@@ -1229,6 +1244,7 @@ pub async fn load_album_view(
|
||||
// lands as a patch a moment later. `headerColor` stays "" until then and
|
||||
// the band simply does not paint — no colour pop.
|
||||
data.header_gradient = crate::settings_qt::pref_bool("album_header_gradient", true);
|
||||
data.compact_header = crate::settings_qt::pref_bool("compact_album_header", false);
|
||||
let header_art = data.header.artwork_url.clone();
|
||||
|
||||
let json = serde_json::to_string(&data).map_err(|e| e.to_string())?;
|
||||
|
||||
@@ -116,6 +116,10 @@ pub struct AlbumDetailDoc {
|
||||
/// EMPTY for a single-disc album. Present only so a multi-disc box can
|
||||
/// label and illustrate its dividers — see `DiscRow`.
|
||||
pub discs: Vec<DiscRow>,
|
||||
/// Cold-start fallback for the global compact-header appearance pref.
|
||||
/// LocalAlbumView switches to the live settings document once published.
|
||||
#[serde(rename = "compactHeader")]
|
||||
pub compact_header: bool,
|
||||
}
|
||||
|
||||
/// The bounded payload consumed by one expanded row in the Genres browser.
|
||||
@@ -346,6 +350,7 @@ pub fn version_doc(id: &str, index: usize) -> Option<AlbumDetailDoc> {
|
||||
},
|
||||
tracks: rows,
|
||||
discs,
|
||||
compact_header: crate::settings_qt::pref_bool("compact_album_header", false),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1658,6 +1658,8 @@ pub struct SettingsDoc {
|
||||
// Appearance (phase 19; the ui_prefs defaults mirror ui_prefs.rs)
|
||||
#[serde(rename = "albumHeaderGradient")]
|
||||
pub album_header_gradient: bool,
|
||||
#[serde(rename = "compactAlbumHeader")]
|
||||
pub compact_album_header: bool,
|
||||
#[serde(rename = "appBackgroundModes")]
|
||||
pub app_background_modes: Vec<String>,
|
||||
#[serde(rename = "appBackgroundIndex")]
|
||||
@@ -2111,6 +2113,7 @@ pub async fn publish_snapshot() {
|
||||
qconnect_device_name: qconnect_load_device_name().unwrap_or_default(),
|
||||
qconnect_device_name_default: qconnect_default_name(),
|
||||
album_header_gradient: pref_bool("album_header_gradient", true),
|
||||
compact_album_header: pref_bool("compact_album_header", false),
|
||||
app_background_modes: APP_BACKGROUND_LABELS
|
||||
.iter()
|
||||
.map(|l| qbz_i18n::t(l))
|
||||
@@ -2401,6 +2404,10 @@ pub async fn settings_bool(runtime: &Arc<AppRuntime<LoggingAdapter>>, key: &str,
|
||||
save_pref("album_header_gradient", serde_json::json!(value));
|
||||
Ok(Apply::None)
|
||||
}
|
||||
"compact-album-header" => {
|
||||
save_pref("compact_album_header", serde_json::json!(value));
|
||||
Ok(Apply::None)
|
||||
}
|
||||
"intelligent-search" => {
|
||||
save_pref("intelligent_search", serde_json::json!(value));
|
||||
// Flip the LIVE kill switch too, not just the pref: the service is
|
||||
|
||||
Reference in new issue
Block a user