diff --git a/crates/qbz-slint/ui/album/AlbumPageView.slint b/crates/qbz-slint/ui/album/AlbumPageView.slint index 0228b91e9..5074f1e02 100644 --- a/crates/qbz-slint/ui/album/AlbumPageView.slint +++ b/crates/qbz-slint/ui/album/AlbumPageView.slint @@ -15,6 +15,7 @@ import { ContextMenu } from "../primitives/ContextMenu.slint"; import { ContextMenuItem } from "../primitives/ContextMenuItem.slint"; import { QualityBadgeFull } from "../primitives/QualityBadgeFull.slint"; import { TrackPlayCell } from "../primitives/TrackPlayCell.slint"; +import { TrackContextMenu } from "../primitives/TrackContextMenu.slint"; import { NavButtons } from "../shell/NavButtons.slint"; component CircleAction inherits Rectangle { @@ -239,40 +240,12 @@ component TrackRow inherits Rectangle { } } - track-menu := PopupWindow { - x: parent.width - 208px; - y: 46px; - width: 196px; - height: 109px; - ContextMenu { - ContextMenuItem { - icon: @image-url("../assets/icons/play.svg"); - label: @tr("Play"); - clicked => { - root.media-action("track", root.track.id, "play"); - } - } - ContextMenuItem { - icon: @image-url("../assets/icons/list-plus.svg"); - label: @tr("Play next"); - clicked => { - root.media-action("track", root.track.id, "play-next"); - } - } - ContextMenuItem { - icon: @image-url("../assets/icons/list-end.svg"); - label: @tr("Add to queue"); - clicked => { - root.media-action("track", root.track.id, "queue"); - } - } - ContextMenuItem { - icon: @image-url("../assets/icons/heart.svg"); - label: @tr("Add to favorites"); - clicked => { - root.media-action("track", root.track.id, "favorite"); - } - } + track-menu := TrackContextMenu { + x: parent.width - self.width - 12px; + y: 48px; + track-id: root.track.id; + media-action(k, i, a) => { + root.media-action(k, i, a); } } } diff --git a/crates/qbz-slint/ui/artist/ArtistPageView.slint b/crates/qbz-slint/ui/artist/ArtistPageView.slint index 6db78411b..8bd061cbb 100644 --- a/crates/qbz-slint/ui/artist/ArtistPageView.slint +++ b/crates/qbz-slint/ui/artist/ArtistPageView.slint @@ -13,6 +13,7 @@ import { QbzIcon } from "../primitives/QbzIcon.slint"; import { ContextMenu } from "../primitives/ContextMenu.slint"; import { ContextMenuItem } from "../primitives/ContextMenuItem.slint"; import { TrackPlayCell } from "../primitives/TrackPlayCell.slint"; +import { TrackContextMenu } from "../primitives/TrackContextMenu.slint"; import { Carousel } from "../discover/Carousel.slint"; import { NavButtons } from "../shell/NavButtons.slint"; @@ -147,40 +148,12 @@ component TrackRow inherits Rectangle { } } - track-menu := PopupWindow { - x: parent.width - 208px; + track-menu := TrackContextMenu { + x: parent.width - self.width - 12px; y: 44px; - width: 196px; - height: 109px; - ContextMenu { - ContextMenuItem { - icon: @image-url("../assets/icons/play.svg"); - label: @tr("Play"); - clicked => { - root.media-action("track", root.track.id, "play"); - } - } - ContextMenuItem { - icon: @image-url("../assets/icons/list-plus.svg"); - label: @tr("Play next"); - clicked => { - root.media-action("track", root.track.id, "play-next"); - } - } - ContextMenuItem { - icon: @image-url("../assets/icons/list-end.svg"); - label: @tr("Add to queue"); - clicked => { - root.media-action("track", root.track.id, "queue"); - } - } - ContextMenuItem { - icon: @image-url("../assets/icons/heart.svg"); - label: @tr("Add to favorites"); - clicked => { - root.media-action("track", root.track.id, "favorite"); - } - } + track-id: root.track.id; + media-action(k, i, a) => { + root.media-action(k, i, a); } } } diff --git a/crates/qbz-slint/ui/assets/icons/link.svg b/crates/qbz-slint/ui/assets/icons/link.svg new file mode 100644 index 000000000..f2d15541f --- /dev/null +++ b/crates/qbz-slint/ui/assets/icons/link.svg @@ -0,0 +1 @@ + diff --git a/crates/qbz-slint/ui/primitives/TrackContextMenu.slint b/crates/qbz-slint/ui/primitives/TrackContextMenu.slint new file mode 100644 index 000000000..32bacbec0 --- /dev/null +++ b/crates/qbz-slint/ui/primitives/TrackContextMenu.slint @@ -0,0 +1,109 @@ +// Track-row "more" context menu — flat, ported 1:1 from the Tauri +// TrackMenu component. Items that have no Slint wiring yet emit a +// media-action with an action string the runtime currently ignores +// (no-op until backend wiring lands). + +import { ContextMenu } from "ContextMenu.slint"; +import { ContextMenuItem } from "ContextMenuItem.slint"; + +export component TrackContextMenu inherits PopupWindow { + in property track-id; + callback media-action(string, string, string); + + width: 224px; + height: 392px; + + ContextMenu { + ContextMenuItem { + icon: @image-url("../assets/icons/play.svg"); + label: @tr("Play now"); + clicked => { + root.media-action("track", root.track-id, "play"); + } + } + ContextMenuItem { + icon: @image-url("../assets/icons/list-plus.svg"); + label: @tr("Play next"); + clicked => { + root.media-action("track", root.track-id, "play-next"); + } + } + ContextMenuItem { + icon: @image-url("../assets/icons/list-end.svg"); + label: @tr("Add to queue"); + clicked => { + root.media-action("track", root.track-id, "queue"); + } + } + ContextMenuItem { + icon: @image-url("../assets/icons/radio.svg"); + label: @tr("Create radio"); + clicked => { + root.media-action("track", root.track-id, "create-radio"); + } + } + ContextMenuItem { + icon: @image-url("../assets/icons/heart.svg"); + label: @tr("Add to library"); + clicked => { + root.media-action("track", root.track-id, "favorite"); + } + } + ContextMenuItem { + icon: @image-url("../assets/icons/cassette-tape.svg"); + label: @tr("Add to mixtape"); + clicked => { + root.media-action("track", root.track-id, "add-to-mixtape"); + } + } + ContextMenuItem { + icon: @image-url("../assets/icons/list-music.svg"); + label: @tr("Add to playlist"); + clicked => { + root.media-action("track", root.track-id, "add-to-playlist"); + } + } + ContextMenuItem { + icon: @image-url("../assets/icons/link.svg"); + label: @tr("Share Qobuz link"); + clicked => { + root.media-action("track", root.track-id, "share-qobuz"); + } + } + ContextMenuItem { + icon: @image-url("../assets/icons/link.svg"); + label: @tr("Share Song.link"); + clicked => { + root.media-action("track", root.track-id, "share-songlink"); + } + } + ContextMenuItem { + icon: @image-url("../assets/icons/cloud-download.svg"); + label: @tr("Make available offline"); + clicked => { + root.media-action("track", root.track-id, "download"); + } + } + ContextMenuItem { + icon: @image-url("../assets/icons/disc-3.svg"); + label: @tr("Go to album"); + clicked => { + root.media-action("track", root.track-id, "go-to-album"); + } + } + ContextMenuItem { + icon: @image-url("../assets/icons/user.svg"); + label: @tr("Go to artist"); + clicked => { + root.media-action("track", root.track-id, "go-to-artist"); + } + } + ContextMenuItem { + icon: @image-url("../assets/icons/info.svg"); + label: @tr("Track info"); + clicked => { + root.media-action("track", root.track-id, "track-info"); + } + } + } +} diff --git a/crates/qbz-slint/ui/search/SearchTrackRow.slint b/crates/qbz-slint/ui/search/SearchTrackRow.slint index 6a24993f0..f216e6590 100644 --- a/crates/qbz-slint/ui/search/SearchTrackRow.slint +++ b/crates/qbz-slint/ui/search/SearchTrackRow.slint @@ -10,9 +10,8 @@ import { Typography } from "../foundation/typography.slint"; import { Radius } from "../foundation/radius.slint"; import { SearchTrackItem } from "../state.slint"; import { QbzIcon } from "../primitives/QbzIcon.slint"; -import { ContextMenu } from "../primitives/ContextMenu.slint"; -import { ContextMenuItem } from "../primitives/ContextMenuItem.slint"; import { TrackPlayCell } from "../primitives/TrackPlayCell.slint"; +import { TrackContextMenu } from "../primitives/TrackContextMenu.slint"; export component SearchTrackRow inherits Rectangle { in property track; @@ -153,40 +152,12 @@ export component SearchTrackRow inherits Rectangle { } } - track-menu := PopupWindow { - x: parent.width - 208px; - y: 46px; - width: 196px; - height: 109px; - ContextMenu { - ContextMenuItem { - icon: @image-url("../assets/icons/play.svg"); - label: @tr("Play"); - clicked => { - root.media-action("track", root.track.id, "play"); - } - } - ContextMenuItem { - icon: @image-url("../assets/icons/list-plus.svg"); - label: @tr("Play next"); - clicked => { - root.media-action("track", root.track.id, "play-next"); - } - } - ContextMenuItem { - icon: @image-url("../assets/icons/list-end.svg"); - label: @tr("Add to queue"); - clicked => { - root.media-action("track", root.track.id, "queue"); - } - } - ContextMenuItem { - icon: @image-url("../assets/icons/heart.svg"); - label: @tr("Add to favorites"); - clicked => { - root.media-action("track", root.track.id, "favorite"); - } - } + track-menu := TrackContextMenu { + x: parent.width - self.width - 12px; + y: 48px; + track-id: root.track.id; + media-action(k, i, a) => { + root.media-action(k, i, a); } } }