Ports the whole playlist-organisation domain, which had no counterpart in this frontend, plus the Library work the owner asked not to defer. Playlist Manager. New controller (playlist_manager_qt, _rows, _ops) over the already-ported folders_qt repository, which until now had zero consumers. Grid, list and folder-tree modes; sort, filter and search; folder cards and chips; drag reorder and up/down arrows. Reached from the sidebar's "..." menu, whose New folder / Manage playlists / Import rows had been rendering dimmed and inert behind a comment saying the seam did not exist. Folders. QbzFolderEdit plus the create/edit modals and PmFolderIcon: preset or custom-image icons, colour, hidden flag, delete. Deleting a folder nulls its LOCAL members' folder_id explicitly, because the app keeps the foreign_keys pragma off, so the schema's ON DELETE SET NULL never fires for them. QbzPlaylistEdit. One shared rename/description/delete editor replacing the inline popup in PlaylistView. Three corrections the old path had wrong: the description is carried through a rename instead of being written as NULL, a FOLLOWED playlist routes to unsubscribe (playlist/delete returns 200 and silently no-ops on a playlist you do not own), and the post-delete back navigation is conditional on actually being on that playlist's page, so deleting from the manager no longer navigates you off it. Importer. Spotify / Apple Music / Tidal / Deezer, over the shared qbz-playlist-import crate. Picker local mode. The reference's four-case matrix — target local or Qobuz, payload local refs or Qobuz ids. Local playlists list unconditionally and Qobuz ones only when online. Local refs onto a Qobuz playlist write the library.db sidecar at next_playlist_sidecar_position(pid, qobuz_count); the 0-based enumerate the reference used before collided slots and lost rows. The carried payload can no longer be parsed as a catalog id when it is a library row id. Unblocks the local bulk add-to-playlist. Library. A-Z jump strip, Albums list mode, Artists side panel, per-tab persistence and multi-select. Preferences land in the same <data-dir>/qbz/favorites_ui.json the shipping build writes, so switching between the two frontends keeps them. LibraryView is split into views/library/ on the way past 1800 lines. Local library. Group-by now persists; playback queues the order on screen rather than the SQL page order; switching album-identity mode invalidates the Artists tab; artist matching folds diacritics and compares normalized credit parts, so "Air" stops listing "Airbourne" and "Beyonce" stops being two artists. Offline. activate_offline never persisted a last-user marker, so every per-user path resolved to None and all local reads came back empty; a session that started offline saw no local playlists at all. The sidebar's load-once latch was function-local and therefore unreachable from the logout reset, so a second login never rebuilt the tree. Both are session-scoped now, and the sidebar Refresh row runs the local-safe verb instead of being dimmed with no way to recover. Also fixes, found while verifying rather than reported: artwork derivatives were written straight to their final path, so a QML Image resolving one mid-encode opened a truncated png and Qt cached that failure against the URL for the rest of the session; Library's track group separators referenced a Component declared in another delegate's scope and could never render; the genre filter was drawn on Tracks and Albums but applied only on All; an All-feed row called a player method that does not exist; and the sidebar's drop-hot highlight used Slint's #RRGGBBAA literals in Qt's #AARRGGBB slot. 17 new msgids across all 8 locales. cc
59 lines
2.3 KiB
QML
59 lines
2.3 KiB
QML
// PmLocalBadge — the 22 px availability disc on a grid card's artwork
|
|
// (PlaylistManagerView.slint:261-287). Three mutually exclusive glyphs:
|
|
//
|
|
// isLocal -> hard-drive, tint `accent` when the local playlist is
|
|
// offline-only, else `text-secondary`
|
|
// status all_local -> wifi, literal #22c55e
|
|
// status some_local -> cloud-download, literal #f59e0b
|
|
//
|
|
// INTERFACE NOTE (contract §2.5). The contract declares `status` only;
|
|
// `isLocal` / `offlineOnly` are ADDED because the reference badge takes both
|
|
// (`is-local-pl` :265, `offline-only` :266) and they select the glyph AND its
|
|
// tint — a first-class local playlist publishes `localStatus: ""` (§4.3), so
|
|
// with `status` alone the badge would be invisible on every local row. Reported
|
|
// as an interface addition.
|
|
//
|
|
// COLOUR TRAP (contract §0.1). Slint's 8-digit literals are #RRGGBBAA, Qt's are
|
|
// #AARRGGBB: the reference plate `#00000099` (:272) is black at 60 % alpha and
|
|
// is written `#99000000` here. Copied verbatim it would have been a nearly
|
|
// opaque near-black-blue.
|
|
//
|
|
// The two brand glyph colours are NOT theme tokens and QbzIcon takes a tint
|
|
// NAME, not a hex — they ride the `green` / `orange` one-off tint dirs the
|
|
// asset pass adds (contract §7.3), following the `amber` precedent.
|
|
|
|
import QtQuick
|
|
import com.blitzfc.qbz
|
|
import "../../theme"
|
|
|
|
Rectangle {
|
|
id: root
|
|
|
|
/// `"no" | "some_local" | "all_local"`; `""` on a first-class local row.
|
|
property string status: "no"
|
|
/// True for a `local:<uuid>` playlist (the hard-drive arm).
|
|
property bool isLocal: false
|
|
/// Locals only: an offline-only playlist tints its marker `accent`.
|
|
property bool offlineOnly: false
|
|
|
|
visible: root.isLocal || root.status === "all_local"
|
|
|| root.status === "some_local"
|
|
|
|
width: 22
|
|
height: 22
|
|
radius: 11
|
|
// Slint #00000099 -> Qt #AARRGGBB. See the header.
|
|
color: "#99000000"
|
|
|
|
QbzIcon {
|
|
anchors.centerIn: parent
|
|
width: 13
|
|
height: 13
|
|
name: root.isLocal ? "hard-drive"
|
|
: (root.status === "all_local" ? "wifi" : "cloud-download")
|
|
tintName: root.isLocal
|
|
? (root.offlineOnly ? "accent" : "secondary")
|
|
: (root.status === "all_local" ? "green" : "orange")
|
|
}
|
|
}
|