fix: resolve context menu positioning issue and integrate it into table rows
Some checks failed
Build MIPS Binary / build (push) Has been cancelled

This commit is contained in:
spinline
2026-02-12 00:29:44 +03:00
parent 555505b80e
commit 04cb7d51cb
2 changed files with 88 additions and 84 deletions

View File

@@ -171,11 +171,8 @@ pub fn TorrentTable() -> impl IntoView {
<For each=move || filtered_hashes.get() key=|hash| hash.clone() children={
let on_action = on_action.clone();
move |hash| {
let h = hash.clone();
view! {
<TorrentContextMenu torrent_hash=h on_action=on_action.clone()>
<TorrentRow hash=hash.clone() />
</TorrentContextMenu>
<TorrentRow hash=hash.clone() on_action=on_action.clone() />
}
}
} />
@@ -191,12 +188,9 @@ pub fn TorrentTable() -> impl IntoView {
<For each=move || filtered_hashes.get() key=|hash| hash.clone() children={
let on_action = on_action.clone();
move |hash| {
let h = hash.clone();
view! {
<div class="pb-3">
<TorrentContextMenu torrent_hash=h on_action=on_action.clone()>
<TorrentCard hash=hash.clone() />
</TorrentContextMenu>
<TorrentCard hash=hash.clone() on_action=on_action.clone() />
</div>
}
}
@@ -210,6 +204,7 @@ pub fn TorrentTable() -> impl IntoView {
#[component]
fn TorrentRow(
hash: String,
on_action: Callback<(String, String)>,
) -> impl IntoView {
let store = use_context::<crate::store::TorrentStore>().expect("store not provided");
let h = hash.clone();
@@ -220,6 +215,7 @@ fn TorrentRow(
view! {
<Show when=move || torrent.get().is_some() fallback=|| ()>
{
let on_action = on_action.clone();
move || {
let t = torrent.get().unwrap();
let t_name = t.name.clone();
@@ -232,8 +228,10 @@ fn TorrentRow(
let t_name_for_title = t_name.clone();
let t_name_for_content = t_name.clone();
let h_for_menu = stored_hash.get_value();
view! {
<TorrentContextMenu torrent_hash=h_for_menu on_action=on_action.clone()>
<TableRow
class="cursor-pointer h-12"
attr:data-state=move || if is_selected.get() { "selected" } else { "" }
@@ -269,16 +267,18 @@ fn TorrentRow(
{format_date(t.added_date)}
</TableCell>
</TableRow>
</TorrentContextMenu>
}.into_any()
}
}
</Show>
}
}.into_any()
}
#[component]
fn TorrentCard(
hash: String,
on_action: Callback<(String, String)>,
) -> impl IntoView {
let store = use_context::<crate::store::TorrentStore>().expect("store not provided");
let h = hash.clone();
@@ -289,12 +289,15 @@ fn TorrentCard(
view! {
<Show when=move || torrent.get().is_some() fallback=|| ()>
{
let on_action = on_action.clone();
move || {
let t = torrent.get().unwrap();
let t_name = t.name.clone();
let status_badge_class = match t.status { shared::TorrentStatus::Seeding => "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400 border-green-200 dark:border-green-800", shared::TorrentStatus::Downloading => "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400 border-blue-200 dark:border-blue-800", shared::TorrentStatus::Paused => "bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400 border-yellow-200 dark:border-yellow-800", shared::TorrentStatus::Error => "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400 border-red-200 dark:border-red-800", _ => "bg-muted text-muted-foreground" };
let h_for_menu = stored_hash.get_value();
view! {
<TorrentContextMenu torrent_hash=h_for_menu on_action=on_action.clone()>
<div
class=move || {
let selected = store.selected_torrent.get();
@@ -333,9 +336,10 @@ fn TorrentCard(
</CardBody>
</Card>
</div>
}
</TorrentContextMenu>
}.into_any()
}
}
</Show>
}
}.into_any()
}

View File

@@ -202,14 +202,14 @@ pub fn ContextMenuTrigger(
#[prop(optional)] on_open: Option<Callback<()>>,
) -> impl IntoView {
let ctx = expect_context::<ContextMenuContext>();
let trigger_class = tw_merge!("contents", class);
let trigger_class = tw_merge!("block w-full h-full", class);
view! {
<div
class=trigger_class
data-name="ContextMenuTrigger"
data-context-trigger=ctx.target_id
on:contextmenu=move |_| {
on:contextmenu=move |e: web_sys::MouseEvent| {
if let Some(cb) = on_open {
cb.run(());
}
@@ -230,7 +230,7 @@ pub fn ContextMenuContent(
) -> impl IntoView {
let ctx = expect_context::<ContextMenuContext>();
let base_classes = "z-50 min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md transition-all duration-200 data-[state=closed]:opacity-0 data-[state=closed]:scale-95 data-[state=open]:opacity-100 data-[state=open]:scale-100";
let base_classes = "fixed z-50 min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md transition-all duration-200 data-[state=closed]:opacity-0 data-[state=closed]:scale-95 data-[state=open]:opacity-100 data-[state=open]:scale-100";
let class = tw_merge!(base_classes, class);