From 43252800208de5e920b6fff0c7025f68f448dea6 Mon Sep 17 00:00:00 2001 From: Amatsugu Date: Fri, 10 Apr 2026 13:54:56 -0400 Subject: [PATCH] context menu implementation testing --- .../src/components/context_menu/component.rs | 101 +++++++++--------- AobaClient/src/components/context_menu/mod.rs | 3 +- .../src/components/context_menu/props.rs | 33 ++++++ .../src/components/context_menu/style.css | 71 ------------ .../src/components/context_menu/style.scss | 0 AobaClient/src/components/media_item.rs | 29 +++-- AobaClient/src/components/mod.rs | 6 +- 7 files changed, 101 insertions(+), 142 deletions(-) create mode 100644 AobaClient/src/components/context_menu/props.rs delete mode 100644 AobaClient/src/components/context_menu/style.css create mode 100644 AobaClient/src/components/context_menu/style.scss diff --git a/AobaClient/src/components/context_menu/component.rs b/AobaClient/src/components/context_menu/component.rs index 0a1ee02..d4ca913 100644 --- a/AobaClient/src/components/context_menu/component.rs +++ b/AobaClient/src/components/context_menu/component.rs @@ -1,64 +1,63 @@ +use super::props::*; use dioxus::prelude::*; -use dioxus_primitives::context_menu::{ - self, ContextMenuContentProps, ContextMenuItemProps, ContextMenuProps, ContextMenuTriggerProps, -}; + +const CONTEXT_MENU_CSS: Asset = asset!("./style.scss"); #[component] -pub fn ContextMenu(props: ContextMenuProps) -> Element { - rsx! { - document::Link { rel: "stylesheet", href: asset!("./style.css") } - context_menu::ContextMenu { - disabled: props.disabled, - open: props.open, - default_open: props.default_open, - on_open_change: props.on_open_change, - roving_loop: props.roving_loop, - attributes: props.attributes, - {props.children} - } - } +pub fn ContextMenu(props: ContextMenuProps) -> Element +{ + rsx! { + document::Link { rel: "stylesheet", href: CONTEXT_MENU_CSS } + {props.children} + } } #[component] -pub fn ContextMenuTrigger(props: ContextMenuTriggerProps) -> Element { - rsx! { - context_menu::ContextMenuTrigger { - padding: "20px", - background: "var(--primary-color)", - border: "1px dashed var(--primary-color-6)", - border_radius: ".5rem", - cursor: "context-menu", - user_select: "none", - text_align: "center", - attributes: props.attributes, - {props.children} - } - } +pub fn ContextMenuTrigger(props: ContextMenuTriggerProps) -> Element +{ + rsx! { + div{ + class: "contextMenuTrigger", + oncontextmenu: move|e|{ + + }, + {props.children} + } + } } #[component] -pub fn ContextMenuContent(props: ContextMenuContentProps) -> Element { - rsx! { - context_menu::ContextMenuContent { - class: "context-menu-content", - id: props.id, - attributes: props.attributes, - {props.children} - } - } +pub fn ContextMenuContent(props: ContextMenuContentProps) -> Element +{ + rsx! { + div{ + class: "contextMenuContent", + {props.children} + } + } } #[component] -pub fn ContextMenuItem(props: ContextMenuItemProps) -> Element { - rsx! { - context_menu::ContextMenuItem { - class: "context-menu-item", - disabled: props.disabled, - value: props.value, - index: props.index, - on_select: props.on_select, - attributes: props.attributes, - {props.children} - } - } +pub fn ContextMenuItem(props: ContextMenuItemProps) -> Element +{ + rsx! { + div { + class: "contextMenuItem", + onclick: move |_|{ + props.on_select.call(props.value.clone()); + }, + div { + class: "content", + {props.children} + } + } + } +} + +#[component] +pub fn ContextMenuNestedContent(props: ContextMenuNestedProps) -> Element +{ + rsx! { + {props.children} + } } diff --git a/AobaClient/src/components/context_menu/mod.rs b/AobaClient/src/components/context_menu/mod.rs index 1723764..e54d26f 100644 --- a/AobaClient/src/components/context_menu/mod.rs +++ b/AobaClient/src/components/context_menu/mod.rs @@ -1,2 +1,3 @@ mod component; -pub use component::*; \ No newline at end of file +mod props; +pub use component::*; diff --git a/AobaClient/src/components/context_menu/props.rs b/AobaClient/src/components/context_menu/props.rs new file mode 100644 index 0000000..7797ea7 --- /dev/null +++ b/AobaClient/src/components/context_menu/props.rs @@ -0,0 +1,33 @@ +use dioxus::prelude::*; + +#[derive(Props, Clone, PartialEq)] +pub struct ContextMenuProps +{ + pub children: Element, +} + +#[derive(Props, Clone, PartialEq)] +pub struct ContextMenuItemProps +{ + pub value: String, + pub on_select: EventHandler, + pub children: Element, +} + +#[derive(Props, Clone, PartialEq)] +pub struct ContextMenuTriggerProps +{ + pub children: Element, +} + +#[derive(Props, Clone, PartialEq)] +pub struct ContextMenuContentProps +{ + pub children: Element, +} + +#[derive(Props, Clone, PartialEq)] +pub struct ContextMenuNestedProps +{ + pub children: Element, +} diff --git a/AobaClient/src/components/context_menu/style.css b/AobaClient/src/components/context_menu/style.css deleted file mode 100644 index a19ecb4..0000000 --- a/AobaClient/src/components/context_menu/style.css +++ /dev/null @@ -1,71 +0,0 @@ -.context-menu-content { - z-index: 1000; - min-width: 220px; - padding: 0.25rem; - border-radius: 0.5rem; - background: var(--dark, var(--primary-color-5)) - var(--light, var(--primary-color)); - box-shadow: inset 0 0 0 1px var(--dark, var(--primary-color-7)) - var(--light, var(--primary-color-6)); - opacity: 0; - pointer-events: none; - will-change: transform, opacity; -} - -.context-menu-content[data-state="closed"] { - animation: context-menu-animate-out 150ms ease-in forwards; -} - -@keyframes context-menu-animate-out { - 0% { - opacity: 1; - transform: scale(1) translateY(0); - } - - 100% { - opacity: 0; - transform: scale(0.95) translateY(-2px); - } -} - -.context-menu-content[data-state="open"] { - animation: context-menu-animate-in 150ms ease-out forwards; -} - -@keyframes context-menu-animate-in { - 0% { - opacity: 0; - transform: scale(0.95) translateY(-2px); - } - - 100% { - opacity: 1; - transform: scale(1) translateY(0); - } -} - -.context-menu-item { - display: flex; - align-items: center; - padding: 8px 12px; - border-radius: calc(0.5rem - 0.25rem); - color: var(--secondary-color-4); - cursor: pointer; - font-size: 14px; - outline: none; - transition: background-color 100ms ease-out; - user-select: none; -} - -.context-menu-item[data-disabled="true"] { - color: var(--secondary-color-5); - cursor: not-allowed; -} - -.context-menu-item:hover:not([data-disabled="true"]), -.context-menu-item:focus-visible { - background: var(--light, var(--primary-color-4)) - var(--dark, var(--primary-color-7)); - color: var(--light, var(--secondary-color-1)) - var(--dark, var(--secondary-color-4)); -} diff --git a/AobaClient/src/components/context_menu/style.scss b/AobaClient/src/components/context_menu/style.scss new file mode 100644 index 0000000..e69de29 diff --git a/AobaClient/src/components/media_item.rs b/AobaClient/src/components/media_item.rs index 404a964..35fe680 100644 --- a/AobaClient/src/components/media_item.rs +++ b/AobaClient/src/components/media_item.rs @@ -1,7 +1,5 @@ use dioxus::prelude::*; -use dioxus_primitives::context_menu::{ - ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger, -}; +use dioxus_primitives::context_menu::{ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger}; use tonic::{Response, Status}; use web_sys::window; @@ -13,13 +11,15 @@ use crate::{ }, }; -pub struct MediaClassChangeEvent { +pub struct MediaClassChangeEvent +{ pub index: usize, pub class: String, } #[derive(PartialEq, Clone, Props)] -pub struct MediaItemProps { +pub struct MediaItemProps +{ pub item: MediaModel, pub index: usize, pub on_class_changed: Option>, @@ -27,14 +27,16 @@ pub struct MediaItemProps { } #[component] -pub fn MediaItem(props: MediaItemProps) -> Element { +pub fn MediaItem(props: MediaItemProps) -> Element +{ let item = props.item; let mtype = item.media_type().as_str_name(); let filename = item.file_name; let id = item.id.unwrap().value; let thumb = item.thumb_url; let class = item.class; - let mut class_signal = use_signal(|| match class { + let mut class_signal = use_signal(|| match class + { 1 => "blur", 2 => "secret", _ => "", @@ -42,13 +44,6 @@ pub fn MediaItem(props: MediaItemProps) -> Element { let url = item.media_url; let download = format!("{HOST}{url}"); - // class_signal.set(match class - // { - // 1 => "blur", - // 2 => "secret", - // _ => "", - // }); - return rsx! { ContextMenu{ ContextMenuTrigger{ @@ -181,7 +176,8 @@ pub fn MediaItem(props: MediaItemProps) -> Element { } #[component] -pub fn MediaItemPlaceHolder() -> Element { +pub fn MediaItemPlaceHolder() -> Element +{ return rsx! { div { class: "mediaItem placeholder", img { }, @@ -196,7 +192,8 @@ pub fn MediaItemPlaceHolder() -> Element { }; } -async fn set_class(id: String, class: i32) -> Result, Status> { +async fn set_class(id: String, class: i32) -> Result, Status> +{ let mut client = get_rpc_client(); return client .set_media_class(SetMediaClassRequest { diff --git a/AobaClient/src/components/mod.rs b/AobaClient/src/components/mod.rs index c8c5993..394b519 100644 --- a/AobaClient/src/components/mod.rs +++ b/AobaClient/src/components/mod.rs @@ -1,5 +1,5 @@ pub mod basic; -// mod context_menu; +mod context_menu; mod icons; mod media_grid; mod media_item; @@ -9,7 +9,7 @@ mod notif; mod pagination; mod passkey; mod search; -// pub use context_menu::*; +pub use context_menu::*; pub use media_grid::*; pub use media_item::*; pub use metrics_token::*; @@ -18,4 +18,4 @@ pub use notif::*; pub use pagination::*; pub use passkey::*; pub use search::*; -pub mod radio_group; +pub mod radio_group;