added context menu

This commit is contained in:
2025-08-02 13:38:02 -04:00
parent d094f7bbef
commit 7b2ed32043
5 changed files with 56 additions and 7 deletions

View File

@@ -7,7 +7,7 @@ pub struct InputProps {
pub label: Option<String>, pub label: Option<String>,
pub placeholder: Option<String>, pub placeholder: Option<String>,
pub name: String, pub name: String,
pub oninput: Option<EventHandler<FormEvent>>, pub oninput: Option<EventHandler<Event<FormData>>>,
pub required: Option<bool>, pub required: Option<bool>,
} }
@@ -25,6 +25,9 @@ pub fn Input(props: InputProps) -> Element {
if let Some(mut s) = props.value { if let Some(mut s) = props.value {
s.set(e.value()); s.set(e.value());
} }
if let Some(handler) = props.oninput{
handler.call(e);
}
}, },
name: props.name, name: props.name,
placeholder: ph, placeholder: ph,

View File

@@ -0,0 +1,20 @@
use core::str;
use dioxus::prelude::*;
#[derive(PartialEq, Clone, Props)]
pub struct ContextMenuProps {
pub top: f64,
pub left: f64,
pub items: Option<Vec<()>>,
}
#[component]
pub fn ContextMenu(props: ContextMenuProps) -> Element {
rsx! {
div {
style: "background:#000; position: absolute; left: {props.left}px; top: {props.top}px;",
"Contect Menu"
}
}
}

View File

@@ -2,7 +2,7 @@ use dioxus::prelude::*;
use tonic::IntoRequest; use tonic::IntoRequest;
use crate::{ use crate::{
components::MediaItem, components::{ContextMenu, MediaItem},
rpc::{aoba::PageFilter, get_rpc_client}, rpc::{aoba::PageFilter, get_rpc_client},
}; };
@@ -46,15 +46,32 @@ pub fn MediaGrid(props: MediaGridProps) -> Element {
} }
})); }));
let mut context_menu: Signal<Element> = use_signal(|| rsx! {});
let oncontext = move |event: Event<MouseData>| {
event.prevent_default();
let data = event.data();
let pos = data.coordinates().client();
let left = pos.x;
let top = pos.y;
context_menu.set(rsx! { ContextMenu{
left: left,
top: top
}});
};
match media_result.cloned() { match media_result.cloned() {
Some(value) => match value { Some(value) => match value {
Ok(result) => rsx! { Ok(result) => rsx! {
div { div {
class: "mediaGrid", class: "mediaGrid",
onclick: move |_e| {
context_menu.set(rsx!{});
},
{result.items.iter().map(|itm| rsx!{ {result.items.iter().map(|itm| rsx!{
MediaItem { item: Some(itm.clone()) } MediaItem { item: Some(itm.clone()), oncontextmenu: oncontext }
})}, })},
} }
{context_menu.cloned()}
}, },
Err(msg) => rsx! { Err(msg) => rsx! {
div { div {

View File

@@ -5,6 +5,7 @@ use crate::{HOST, rpc::aoba::MediaModel};
#[derive(PartialEq, Clone, Props)] #[derive(PartialEq, Clone, Props)]
pub struct MediaItemProps { pub struct MediaItemProps {
pub item: Option<MediaModel>, pub item: Option<MediaModel>,
pub oncontextmenu: Option<EventHandler<Event<MouseData>>>,
} }
#[component] #[component]
@@ -15,11 +16,17 @@ pub fn MediaItem(props: MediaItemProps) -> Element {
let id = item.id.unwrap().value; let id = item.id.unwrap().value;
let thumb = item.thumb_url; let thumb = item.thumb_url;
let url = item.media_url; let url = item.media_url;
return rsx! { return rsx! {
a { a {
class: "mediaItem", class: "mediaItem",
href: "{HOST}/{url}", href: "{HOST}/{url}",
target: "_blank", target: "_blank",
oncontextmenu: move |e| {
if let Some(handler) = props.oncontextmenu{
handler.call(e);
}
},
"data-id" : id, "data-id" : id,
img { src: "{HOST}{thumb}" } img { src: "{HOST}{thumb}" }
span { class: "info", span { class: "info",
@@ -29,7 +36,7 @@ pub fn MediaItem(props: MediaItemProps) -> Element {
span { "{item.view_count}" } span { "{item.view_count}" }
} }
} }
} },
}; };
} else { } else {
return rsx! { return rsx! {

View File

@@ -1,10 +1,12 @@
pub mod basic; pub mod basic;
mod context_menu;
mod media_grid; mod media_grid;
mod media_item; mod media_item;
mod metrics_token; mod metrics_token;
mod navbar; mod navbar;
mod notif; mod notif;
mod search; mod search;
pub use context_menu::*;
pub use media_grid::*; pub use media_grid::*;
pub use media_item::*; pub use media_item::*;
pub use metrics_token::*; pub use metrics_token::*;