fix(slint): smooth sticky scroll + artwork right-click menu
Two unrelated things landing together.
Sticky scroll fix:
- The natural-top binding on both jump-nav and the sidebar reads
from `body-row.absolute-position.y` (a live, scroll-aware
lookup). The y formula was `max(natural-top + viewport-y, ...)`
— adding viewport-y on top of an already scroll-aware value
double-counted the scroll. During mid-scroll the bar drifted
ahead of the body row, opening a visible gap and briefly
overlapping the header.
- Drops `+ viewport-y` from both formulas. natural-top alone IS
the viewport-relative y the elements want to occupy; the
max() clamp just keeps them from going above the top.
- Initial position and sticky position are unchanged; only the
transition is fixed.
Artwork right-click menu (artist portrait + album cover):
- Both headers get a TouchArea on the artwork that opens a
PopupWindow + ContextMenu on right-click, positioned at the
cursor. Mirrors Tauri's `oncontextmenu` flow on the artist
portrait and album cover.
- Menu items match Tauri 1:1: Add image / cover, Change + Remove
(when a custom image is registered), divider, Open in
browser, Save as.
- New `crate::custom_artwork` JSON-backed store at
`<data-dir>/qbz/custom_artwork.json` keyed by artist name +
album id (mirror of the Tauri library's
`v2_library_set/remove_custom_*` persistence).
- ArtistState / AlbumState expose `artwork-url` (network URL for
Open / Save) + `has-custom-image` / `has-custom-cover` (drives
the Add vs Change/Remove menu rendering), both populated from
Rust at apply_artist / apply_album time.
- ArtworkActions global + main.rs handlers:
* open-in-browser → `open::that(url)`.
* save-as → `rfd::AsyncFileDialog::save_file()` + reqwest
download + tokio::fs::write.
* add-custom → `rfd::AsyncFileDialog::pick_file()` then
`custom_artwork::set_*` + flip the has-custom flag.
* remove-custom → `custom_artwork::remove_*` + reset flag.
- rfd added with xdg-portal + tokio features. external-link and
image-plus SVGs ported from Lucide.
Custom-image RENDERING (using the picked file in place of the
network artwork) is deferred — the store persists the choice and
the menu reflects it, but the displayed image still comes from
Qobuz. Next pass.
cc
This commit is contained in:
12 files changed
+480
-15
No files matched your search
@@ -66,6 +66,10 @@ export global AlbumState {
|
||||
in property <string> title;
|
||||
in property <string> artist;
|
||||
in property <string> artist-id;
|
||||
// Network URL of the cover — used by the artwork right-click
|
||||
// menu for Open-in-browser and Save-as actions.
|
||||
in property <string> artwork-url;
|
||||
in property <bool> has-custom-cover: false;
|
||||
in property <string> info-line;
|
||||
in property <string> quality-tier;
|
||||
// "24-bit / 96 kHz" — quality-badge detail line.
|
||||
@@ -213,6 +217,13 @@ export struct SimilarEntry {
|
||||
export global ArtistState {
|
||||
in property <string> id;
|
||||
in property <string> name;
|
||||
// Network URL of the portrait — used by the artwork right-click
|
||||
// menu for Open-in-browser and Save-as actions.
|
||||
in property <string> artwork-url;
|
||||
// True when the user has registered a local image to override
|
||||
// the Qobuz-supplied portrait. Drives the menu's
|
||||
// "Add image" -> "Change image / Remove image" toggle.
|
||||
in property <bool> has-custom-image: false;
|
||||
in property <string> bio;
|
||||
// Truncated bio (word-boundary cut + ellipsis) for the at-rest view;
|
||||
// the full bio in `bio` is shown when the Read-more toggle expands.
|
||||
@@ -242,6 +253,19 @@ export global ArtistState {
|
||||
in property <bool> loading: false;
|
||||
}
|
||||
|
||||
// Artwork right-click actions — shared by ArtistPageView and
|
||||
// AlbumPageView for their respective headers. `kind` is "artist" or
|
||||
// "album"; `key` is the artist name or album id; `url` is the
|
||||
// current network URL (for open-in-browser and save-as).
|
||||
export global ArtworkActions {
|
||||
callback open-in-browser(string /* url */);
|
||||
callback save-as(string /* url */, string /* default file name */);
|
||||
// Opens the system file picker and registers the chosen image
|
||||
// as the custom override for this artist/album.
|
||||
callback add-custom(string /* kind */, string /* key */);
|
||||
callback remove-custom(string /* kind */, string /* key */);
|
||||
}
|
||||
|
||||
// Artist-view actions wired to Rust callbacks.
|
||||
export global ArtistActions {
|
||||
// Filter the visible Popular Tracks and release-section albums by
|
||||
|
||||
Reference in new issue
Block a user