Files
qbz/crates/qbz-slint/ui/primitives/AlbumContextMenu.slint
T
vicrodh 999ded11ff feat(slint): post-lyrics UI polish sweep + correctness fixes
- TrackRow: Korean/CJK titles render via layout-assigned width+height
  (SongCard parity, never femtovg-measured); explicit "E" badge hugs the
  title text; duration + position number dropped to 13px so they read
  smaller than the 14px title.
- AlbumView: label/awards rail 214->160px with smaller card/icon/padding
  and centered headings in the compact rail; removed the dark right gutter
  (full-width Flickable, content clears the scrollbar via the 32px page
  padding); column headers homologated to Playlist casing (Title/Duration/
  Quality), same in LocalAlbumView.
- ArtistView: network sidebar auto-collapses on ShellState.content-
  constrained (the AlbumView signal) and no longer re-opens on artist->
  artist navigation (reset_network_sidebar respects the constraint).
- Hero titles homologated to Typography.section (18px) across MyQBZ detail,
  Musician, Label releases, Artists-by-location, Offline Manager.
- Lyrics: Qobuz || LRCLIB parallel fetch, next-track prefetch, source
  footer, asymmetric line fade.

cc
2026-06-11 22:03:46 -06:00

103 lines
4.0 KiB
Plaintext

// Album header "more" (⋯) context menu — ported 1:1 from the Tauri
// `AlbumMenu` (src/lib/components/AlbumMenu.svelte) as wired by the album
// detail header. Tauri nests Share/Download as submenus; we render them
// FLAT (the same cosmetic-flat convention as TrackContextMenu) with group
// separators matching Tauri's menu grouping.
//
// Item -> media-action("album", <album-id>, <action>) mapping:
// Play next -> "play-next"
// Add to queue -> "queue"
// --
// Add to playlist -> "add-to-playlist"
// Add to Mixtape/Coll. -> "add-to-mixtape"
// --
// Share Qobuz link -> "share-qobuz"
// Share Album.link -> "share-songlink"
// --
// Make available offline -> "cache" (album NOT fully cached)
// Refresh offline copy -> "recache" (album fully cached)
//
// Tauri's onMakeOffline ("download.makeAvailable") item is NOT passed by
// the album detail header, so it is intentionally absent (1:1). The last
// row swaps Make-available-offline <-> Refresh-offline-copy on
// `fully-cached`, the flat form of Tauri's isAlbumFullyDownloaded submenu
// (which only carries Refresh — no Remove at album level).
import { Theme } from "../foundation/semantic-colors.slint";
import { ContextMenu } from "ContextMenu.slint";
import { ContextMenuItem } from "ContextMenuItem.slint";
export component AlbumContextMenu inherits PopupWindow {
in property <string> album-id;
// Every track of the album already has a ready offline copy.
in property <bool> fully-cached: false;
callback media-action(string, string, string);
width: 224px;
// 7 rows x 33px + 3 separators x 1px + ContextMenu's 5/5 padding. The
// offline row swaps label/action on `fully-cached` — count is constant.
height: 7 * 33px + 3 * 1px + 10px;
ContextMenu {
ContextMenuItem {
icon: @image-url("../assets/icons/list-plus.svg");
label: @tr("Play next");
clicked => {
root.media-action("album", root.album-id, "play-next");
}
}
ContextMenuItem {
icon: @image-url("../assets/icons/list-end.svg");
label: @tr("Add to queue");
clicked => {
root.media-action("album", root.album-id, "queue");
}
}
Rectangle { height: 1px; background: Theme.border-subtle; }
ContextMenuItem {
icon: @image-url("../assets/icons/list-music.svg");
label: @tr("Add to playlist");
clicked => {
root.media-action("album", root.album-id, "add-to-playlist");
}
}
ContextMenuItem {
icon: @image-url("../assets/icons/cassette-tape.svg");
label: @tr("Add to mixtape");
clicked => {
root.media-action("album", root.album-id, "add-to-mixtape");
}
}
Rectangle { height: 1px; background: Theme.border-subtle; }
ContextMenuItem {
icon: @image-url("../assets/icons/link.svg");
label: @tr("Share Qobuz link");
clicked => {
root.media-action("album", root.album-id, "share-qobuz");
}
}
ContextMenuItem {
icon: @image-url("../assets/icons/link.svg");
label: @tr("Share Album.link");
clicked => {
root.media-action("album", root.album-id, "share-songlink");
}
}
Rectangle { height: 1px; background: Theme.border-subtle; }
if !root.fully-cached: ContextMenuItem {
icon: @image-url("../assets/icons/cloud-download.svg");
label: @tr("Make available offline");
clicked => {
root.media-action("album", root.album-id, "cache");
}
}
if root.fully-cached: ContextMenuItem {
icon: @image-url("../assets/icons/refresh-cw.svg");
label: @tr("Refresh offline copy");
clicked => {
root.media-action("album", root.album-id, "recache");
}
}
}
}