Skip to content

Commit c35ada6

Browse files
committed
fix: implement dynamic positioning for mobile action menu in album song row
1 parent 7e5760b commit c35ada6

1 file changed

Lines changed: 22 additions & 2 deletions

File tree

src/components/views/album_song_row.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,20 @@ use crate::db::AppSettings;
77
use crate::offline_audio::{is_song_downloaded, prefetch_song_audio};
88
use dioxus::prelude::*;
99

10+
fn anchored_menu_style(
11+
anchor_x: f64,
12+
anchor_y: f64,
13+
menu_width: f64,
14+
menu_max_height: f64,
15+
) -> String {
16+
let preferred_top = (anchor_y + 8.0).max(8.0);
17+
let preferred_left = (anchor_x - menu_width).max(4.0);
18+
format!(
19+
"top: clamp(8px, {:.1}px, calc(100vh - {:.1}px - 8px)); left: clamp(4px, {:.1}px, calc(100vw - {:.1}px - 4px)); max-height: min({:.1}px, calc(100vh - 16px)); overflow-y: auto;",
20+
preferred_top, menu_max_height, preferred_left, menu_width, menu_max_height
21+
)
22+
}
23+
1024
/// Song row tailored for album detail pages: adds per-song favorite toggle.
1125
#[component]
1226
pub fn AlbumSongRow(song: Song, index: usize, onclick: EventHandler<MouseEvent>) -> Element {
@@ -20,6 +34,8 @@ pub fn AlbumSongRow(song: Song, index: usize, onclick: EventHandler<MouseEvent>)
2034
let is_favorited = use_signal(|| song.starred.is_some());
2135
let download_busy = use_signal(|| false);
2236
let mut show_mobile_actions = use_signal(|| false);
37+
let mut menu_x = use_signal(|| 0f64);
38+
let mut menu_y = use_signal(|| 0f64);
2339
let initially_downloaded = is_song_downloaded(&song);
2440
let downloaded = use_signal(move || initially_downloaded);
2541
let is_current = now_playing()
@@ -357,6 +373,9 @@ pub fn AlbumSongRow(song: Song, index: usize, onclick: EventHandler<MouseEvent>)
357373
aria_label: "Song actions",
358374
onclick: move |evt: MouseEvent| {
359375
evt.stop_propagation();
376+
let coords = evt.client_coordinates();
377+
menu_x.set(coords.x);
378+
menu_y.set(coords.y);
360379
show_mobile_actions.set(!show_mobile_actions());
361380
},
362381
Icon {
@@ -366,14 +385,15 @@ pub fn AlbumSongRow(song: Song, index: usize, onclick: EventHandler<MouseEvent>)
366385
}
367386
if show_mobile_actions() {
368387
div {
369-
class: "fixed inset-0 z-20",
388+
class: "fixed inset-0 z-[9998]",
370389
onclick: move |evt: MouseEvent| {
371390
evt.stop_propagation();
372391
show_mobile_actions.set(false);
373392
},
374393
}
375394
div {
376-
class: "absolute right-0 top-10 z-30 w-44 rounded-xl border border-zinc-700 bg-zinc-900/95 shadow-2xl p-1.5 space-y-1",
395+
class: "fixed z-[9999] w-44 rounded-xl border border-zinc-700 bg-zinc-900/95 shadow-2xl p-1.5 space-y-1",
396+
style: anchored_menu_style(menu_x(), menu_y(), 176.0, 360.0),
377397
onclick: move |evt: MouseEvent| evt.stop_propagation(),
378398
button {
379399
class: "w-full flex items-center gap-2 px-2.5 py-2 rounded-lg text-sm text-zinc-200 hover:bg-zinc-800/80 transition-colors",

0 commit comments

Comments
 (0)