feat(qt): Open containing album on cortinilla track rows
CortRow gains an albumId — the Qobuz album id for catalog tracks, the album group key for local ones (both are what crate::open_album routes), empty elsewhere. The track menu gates its new entry on the field, the action funnels through cortinillaMenuAction like its siblings, and the new msgid ships in the seven non-English locales. cc
This commit is contained in:
10 files changed
+67
-10
No files matched your search
@@ -446,6 +446,9 @@ msgstr "Entdecken Sie neue Musik aus Ihren meistgespielten Playlists."
|
|||||||
msgid "Open album"
|
msgid "Open album"
|
||||||
msgstr "Album öffnen"
|
msgstr "Album öffnen"
|
||||||
|
|
||||||
|
msgid "Open containing album"
|
||||||
|
msgstr "Zugehöriges Album öffnen"
|
||||||
|
|
||||||
msgid "Play"
|
msgid "Play"
|
||||||
msgstr "Abspielen"
|
msgstr "Abspielen"
|
||||||
|
|
||||||
|
|||||||
@@ -449,6 +449,9 @@ msgstr "Descubre música nueva a partir de tus listas más reproducidas."
|
|||||||
msgid "Open album"
|
msgid "Open album"
|
||||||
msgstr "Abrir álbum"
|
msgstr "Abrir álbum"
|
||||||
|
|
||||||
|
msgid "Open containing album"
|
||||||
|
msgstr "Abrir el álbum contenedor"
|
||||||
|
|
||||||
msgid "Play"
|
msgid "Play"
|
||||||
msgstr "Reproducir"
|
msgstr "Reproducir"
|
||||||
|
|
||||||
|
|||||||
@@ -446,6 +446,9 @@ msgstr "Découvrez de nouvelles musiques à partir de vos playlists les plus éc
|
|||||||
msgid "Open album"
|
msgid "Open album"
|
||||||
msgstr "Ouvrir l'album"
|
msgstr "Ouvrir l'album"
|
||||||
|
|
||||||
|
msgid "Open containing album"
|
||||||
|
msgstr "Ouvrir l'album d'origine"
|
||||||
|
|
||||||
msgid "Play"
|
msgid "Play"
|
||||||
msgstr "Lecture"
|
msgstr "Lecture"
|
||||||
|
|
||||||
|
|||||||
@@ -445,6 +445,9 @@ msgstr "よく再生するプレイリストから新しい音楽を見つけま
|
|||||||
msgid "Open album"
|
msgid "Open album"
|
||||||
msgstr "アルバムを開く"
|
msgstr "アルバムを開く"
|
||||||
|
|
||||||
|
msgid "Open containing album"
|
||||||
|
msgstr "収録アルバムを開く"
|
||||||
|
|
||||||
msgid "Play"
|
msgid "Play"
|
||||||
msgstr "再生"
|
msgstr "再生"
|
||||||
|
|
||||||
|
|||||||
@@ -446,6 +446,9 @@ msgstr "Ontdek nieuwe muziek op basis van je meest afgespeelde afspeellijsten."
|
|||||||
msgid "Open album"
|
msgid "Open album"
|
||||||
msgstr "Album openen"
|
msgstr "Album openen"
|
||||||
|
|
||||||
|
msgid "Open containing album"
|
||||||
|
msgstr "Bijbehorend album openen"
|
||||||
|
|
||||||
msgid "Play"
|
msgid "Play"
|
||||||
msgstr "Afspelen"
|
msgstr "Afspelen"
|
||||||
|
|
||||||
|
|||||||
@@ -446,6 +446,9 @@ msgstr "Descubra novas músicas a partir das suas playlists mais reproduzidas."
|
|||||||
msgid "Open album"
|
msgid "Open album"
|
||||||
msgstr "Abrir álbum"
|
msgstr "Abrir álbum"
|
||||||
|
|
||||||
|
msgid "Open containing album"
|
||||||
|
msgstr "Abrir o álbum de origem"
|
||||||
|
|
||||||
msgid "Play"
|
msgid "Play"
|
||||||
msgstr "Reproduzir"
|
msgstr "Reproduzir"
|
||||||
|
|
||||||
|
|||||||
@@ -445,6 +445,9 @@ msgstr "Откройте новую музыку из ваших любимых
|
|||||||
msgid "Open album"
|
msgid "Open album"
|
||||||
msgstr "Открыть альбом"
|
msgstr "Открыть альбом"
|
||||||
|
|
||||||
|
msgid "Open containing album"
|
||||||
|
msgstr "Открыть альбом трека"
|
||||||
|
|
||||||
msgid "Play"
|
msgid "Play"
|
||||||
msgstr "Воспроизвести"
|
msgstr "Воспроизвести"
|
||||||
|
|
||||||
|
|||||||
@@ -102,13 +102,20 @@ Item {
|
|||||||
artistRows.push({ "label": t("Play", r), "icon": "play-fill", "action": "play" })
|
artistRows.push({ "label": t("Play", r), "icon": "play-fill", "action": "play" })
|
||||||
return artistRows
|
return artistRows
|
||||||
}
|
}
|
||||||
if (row.kind === "track") return [
|
if (row.kind === "track") {
|
||||||
{ "label": t("Play", r), "icon": "play-fill", "action": "play" },
|
var trackRows = [
|
||||||
{ "label": t("Play next", r), "icon": "list-start", "action": "next" },
|
{ "label": t("Play", r), "icon": "play-fill", "action": "play" },
|
||||||
{ "label": t("Play later", r), "icon": "list-plus", "action": "later" },
|
{ "label": t("Play next", r), "icon": "list-start", "action": "next" },
|
||||||
{ "label": t("Add to queue", r), "icon": "list-end", "action": "queue" },
|
{ "label": t("Play later", r), "icon": "list-plus", "action": "later" },
|
||||||
{ "label": t("Add to playlist", r), "icon": "list-music", "action": "add-to-playlist" }
|
{ "label": t("Add to queue", r), "icon": "list-end", "action": "queue" },
|
||||||
]
|
{ "label": t("Add to playlist", r), "icon": "list-music", "action": "add-to-playlist" }
|
||||||
|
]
|
||||||
|
// QoL round: gated on the payload actually carrying the album
|
||||||
|
// (a Qobuz id or a local group key — search_qt::CortRow.albumId).
|
||||||
|
if ((row.albumId || "") !== "")
|
||||||
|
trackRows.push({ "label": t("Open containing album", r), "icon": "disc-3", "action": "open-album" })
|
||||||
|
return trackRows
|
||||||
|
}
|
||||||
if (row.kind === "playlist") return [
|
if (row.kind === "playlist") return [
|
||||||
{ "label": t("Open playlist", r), "icon": "list-music", "action": "open" },
|
{ "label": t("Open playlist", r), "icon": "list-music", "action": "open" },
|
||||||
{ "label": t("Play", r), "icon": "play-fill", "action": "play" },
|
{ "label": t("Play", r), "icon": "play-fill", "action": "play" },
|
||||||
@@ -124,8 +131,8 @@ Item {
|
|||||||
if (fi === undefined || fi === null)
|
if (fi === undefined || fi === null)
|
||||||
return
|
return
|
||||||
QbzSearch.cortinillaMenuAction(fi, action)
|
QbzSearch.cortinillaMenuAction(fi, action)
|
||||||
if ((action === "open" || action === "play" || action === "add-to-playlist")
|
if ((action === "open" || action === "open-album" || action === "play"
|
||||||
&& root.headerBar)
|
|| action === "add-to-playlist") && root.headerBar)
|
||||||
root.headerBar.clearSearch()
|
root.headerBar.clearSearch()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -206,6 +206,7 @@ pub(crate) fn derive_local_album_rows(
|
|||||||
quality_detail: local_quality_detail(t),
|
quality_detail: local_quality_detail(t),
|
||||||
art_url,
|
art_url,
|
||||||
art_path,
|
art_path,
|
||||||
|
album_id: String::new(),
|
||||||
flat_index: 0,
|
flat_index: 0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -259,6 +260,7 @@ pub(crate) fn derive_local_artist_rows(
|
|||||||
quality_detail: String::new(),
|
quality_detail: String::new(),
|
||||||
art_url,
|
art_url,
|
||||||
art_path,
|
art_path,
|
||||||
|
album_id: String::new(),
|
||||||
flat_index: 0,
|
flat_index: 0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -291,6 +293,9 @@ pub(crate) fn map_local_track_to_cort_row(t: &qbz_library::LocalTrack) -> CortRo
|
|||||||
quality_detail: local_quality_detail(t),
|
quality_detail: local_quality_detail(t),
|
||||||
art_url,
|
art_url,
|
||||||
art_path,
|
art_path,
|
||||||
|
// The same group key the local Albums section uses as its row id —
|
||||||
|
// what "Open containing album" hands to `crate::open_album`.
|
||||||
|
album_id: t.album_group_key.clone(),
|
||||||
flat_index: 0,
|
flat_index: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -566,6 +566,12 @@ pub struct CortRow {
|
|||||||
pub art_url: String,
|
pub art_url: String,
|
||||||
#[serde(rename = "artPath")]
|
#[serde(rename = "artPath")]
|
||||||
pub art_path: String,
|
pub art_path: String,
|
||||||
|
/// TRACK rows only ("Open containing album"): the containing album — a
|
||||||
|
/// Qobuz album id or a local album group key (both are what
|
||||||
|
/// `crate::open_album` routes). Empty when unknown; the QML menu gates
|
||||||
|
/// its entry on that.
|
||||||
|
#[serde(rename = "albumId")]
|
||||||
|
pub album_id: String,
|
||||||
#[serde(rename = "flatIndex")]
|
#[serde(rename = "flatIndex")]
|
||||||
pub flat_index: i32,
|
pub flat_index: i32,
|
||||||
}
|
}
|
||||||
@@ -673,6 +679,7 @@ fn map_search_all_to_cortinilla(query: &str, results: &SearchAllResults) -> Cort
|
|||||||
subtitle: m.artist,
|
subtitle: m.artist,
|
||||||
quality_detail,
|
quality_detail,
|
||||||
art_url: m.art_url,
|
art_url: m.art_url,
|
||||||
|
album_id: m.album_id,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1270,7 +1277,7 @@ pub fn row_menu_action(flat_index: i32, action: &str) {
|
|||||||
}
|
}
|
||||||
if !matches!(
|
if !matches!(
|
||||||
action,
|
action,
|
||||||
"play" | "next" | "later" | "queue" | "add-to-playlist"
|
"play" | "next" | "later" | "queue" | "add-to-playlist" | "open-album"
|
||||||
) {
|
) {
|
||||||
log::warn!("[qbz-qt] cortinilla menu: unknown action {action:?}");
|
log::warn!("[qbz-qt] cortinilla menu: unknown action {action:?}");
|
||||||
return;
|
return;
|
||||||
@@ -1298,6 +1305,23 @@ pub fn row_menu_action(flat_index: i32, action: &str) {
|
|||||||
row.source,
|
row.source,
|
||||||
row.id,
|
row.id,
|
||||||
);
|
);
|
||||||
|
if action == "open-album" {
|
||||||
|
set_cortinilla_open(false);
|
||||||
|
// `open_album` routes BOTH id spaces (its is_local_feed_id arm
|
||||||
|
// recognises local group keys), so no source split here. The QML
|
||||||
|
// entry is gated on a non-empty albumId; an empty one is a stale
|
||||||
|
// snapshot, not a user path.
|
||||||
|
if row.kind != "track" || row.album_id.is_empty() {
|
||||||
|
log::warn!(
|
||||||
|
"[qbz-qt] cortinilla menu open-album: kind={} albumId empty={}",
|
||||||
|
row.kind,
|
||||||
|
row.album_id.is_empty()
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
crate::open_album(row.album_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if action == "add-to-playlist" {
|
if action == "add-to-playlist" {
|
||||||
set_cortinilla_open(false);
|
set_cortinilla_open(false);
|
||||||
if row.kind != "track" {
|
if row.kind != "track" {
|
||||||
|
|||||||
Reference in new issue
Block a user