Compare commits

...

2 Commits

Author SHA1 Message Date
spinline
ba7f1ffd91 fix(ui): adjust context menu position for CSS transformed containers
All checks were successful
Build MIPS Binary / build (push) Successful in 1m59s
2026-02-21 01:22:31 +03:00
spinline
daa24dd7ec fix(ui): refactor FileContextMenu to auticlose and match homepage
All checks were successful
Build MIPS Binary / build (push) Successful in 1m59s
2026-02-21 01:13:57 +03:00
2 changed files with 163 additions and 126 deletions

View File

@@ -88,7 +88,6 @@ pub fn TorrentFilesTab(hash: String) -> impl IntoView {
#[component] #[component]
fn FileRow(file: TorrentFile, hash: String, refresh_action: Action<String, Vec<TorrentFile>>) -> impl IntoView { fn FileRow(file: TorrentFile, hash: String, refresh_action: Action<String, Vec<TorrentFile>>) -> impl IntoView {
let f_idx = file.index; let f_idx = file.index;
let context_id = format!("file-context-{}-{}", hash, f_idx);
let path_clone = file.path.clone(); let path_clone = file.path.clone();
let set_priority = Action::new(|req: &(String, u32, u8)| { let set_priority = Action::new(|req: &(String, u32, u8)| {
@@ -105,8 +104,12 @@ fn FileRow(file: TorrentFile, hash: String, refresh_action: Action<String, Vec<T
}); });
view! { view! {
<ContextMenu> <FileContextMenu
<ContextMenuTrigger attr:id=context_id.clone()> torrent_hash=hash
file_index=f_idx
refresh_action=refresh_action
set_priority=set_priority
>
<TableRow class="hover:bg-muted/50 transition-colors group"> <TableRow class="hover:bg-muted/50 transition-colors group">
<TableCell class="text-center text-xs text-muted-foreground">{file.index}</TableCell> <TableCell class="text-center text-xs text-muted-foreground">{file.index}</TableCell>
<TableCell class="font-medium text-xs break-all max-w-[200px] md:max-w-md" attr:title=move || path_clone.clone()> <TableCell class="font-medium text-xs break-all max-w-[200px] md:max-w-md" attr:title=move || path_clone.clone()>
@@ -129,17 +132,39 @@ fn FileRow(file: TorrentFile, hash: String, refresh_action: Action<String, Vec<T
} }
</TableCell> </TableCell>
</TableRow> </TableRow>
</FileContextMenu>
}
}
#[component]
fn FileContextMenu(
children: Children,
torrent_hash: String,
file_index: u32,
refresh_action: Action<String, Vec<TorrentFile>>,
set_priority: Action<(String, u32, u8), Result<(), ServerFnError>>,
) -> impl IntoView {
let hash_c1 = torrent_hash.clone();
let hash_c2 = torrent_hash.clone();
let hash_c3 = torrent_hash.clone();
view! {
<ContextMenu>
<ContextMenuTrigger>
{children()}
</ContextMenuTrigger> </ContextMenuTrigger>
<ContextMenuContent class="w-48"> <ContextMenuContent class="w-48">
<ContextMenuLabel>"Dosya Önceliği"</ContextMenuLabel> <ContextMenuLabel>"Dosya Önceliği"</ContextMenuLabel>
<ContextMenuGroup> <ContextMenuGroup>
<ContextMenuItem on:click={ <ContextMenuItem on:click={
let h = hash.clone(); let h = hash_c1;
let ra = refresh_action.clone(); let ra = refresh_action.clone();
let sp = set_priority.clone();
move |_| { move |_| {
set_priority.dispatch((h.clone(), f_idx, 2)); sp.dispatch((h.clone(), file_index, 2));
ra.dispatch(h.clone()); ra.dispatch(h.clone());
crate::components::ui::context_menu::close_context_menu();
} }
}> }>
<icons::ChevronsUp class="text-green-500" /> <icons::ChevronsUp class="text-green-500" />
@@ -147,11 +172,13 @@ fn FileRow(file: TorrentFile, hash: String, refresh_action: Action<String, Vec<T
</ContextMenuItem> </ContextMenuItem>
<ContextMenuItem on:click={ <ContextMenuItem on:click={
let h = hash.clone(); let h = hash_c2;
let ra = refresh_action.clone(); let ra = refresh_action.clone();
let sp = set_priority.clone();
move |_| { move |_| {
set_priority.dispatch((h.clone(), f_idx, 1)); sp.dispatch((h.clone(), file_index, 1));
ra.dispatch(h.clone()); ra.dispatch(h.clone());
crate::components::ui::context_menu::close_context_menu();
} }
}> }>
<icons::Minus class="text-blue-500" /> <icons::Minus class="text-blue-500" />
@@ -159,11 +186,13 @@ fn FileRow(file: TorrentFile, hash: String, refresh_action: Action<String, Vec<T
</ContextMenuItem> </ContextMenuItem>
<ContextMenuItem class="text-destructive focus:bg-destructive/10" on:click={ <ContextMenuItem class="text-destructive focus:bg-destructive/10" on:click={
let h = hash.clone(); let h = hash_c3;
let ra = refresh_action.clone(); let ra = refresh_action.clone();
let sp = set_priority.clone();
move |_| { move |_| {
set_priority.dispatch((h.clone(), f_idx, 0)); sp.dispatch((h.clone(), file_index, 0));
ra.dispatch(h.clone()); ra.dispatch(h.clone());
crate::components::ui::context_menu::close_context_menu();
} }
}> }>
<icons::X /> <icons::X />

View File

@@ -215,12 +215,20 @@ pub fn ContextMenuContent(
// Adjust if menu would go off right edge // Adjust if menu would go off right edge
if (x + menuRect.width > viewportWidth) {{ if (x + menuRect.width > viewportWidth) {{
left = x - menuRect.width; left = Math.max(0, x - menuRect.width);
}} }}
// Adjust if menu would go off bottom edge // Adjust if menu would go off bottom edge
if (y + menuRect.height > viewportHeight) {{ if (y + menuRect.height > viewportHeight) {{
top = y - menuRect.height; top = Math.max(0, y - menuRect.height);
}}
// Adjust for CSS transformed containing block
const offsetParent = menu.offsetParent;
if (offsetParent && offsetParent !== document.body && offsetParent !== document.documentElement) {{
const parentRect = offsetParent.getBoundingClientRect();
left -= parentRect.left;
top -= parentRect.top;
}} }}
menu.style.left = `${{left}}px`; menu.style.left = `${{left}}px`;