diff --git a/frontend/src/components/demos/mod.rs b/frontend/src/components/demos/mod.rs new file mode 100644 index 0000000..e4a68bf --- /dev/null +++ b/frontend/src/components/demos/mod.rs @@ -0,0 +1 @@ +pub mod demo_shimmer; diff --git a/frontend/src/components/hooks/use_random.rs b/frontend/src/components/hooks/use_random.rs index 049f410..d2f5617 100644 --- a/frontend/src/components/hooks/use_random.rs +++ b/frontend/src/components/hooks/use_random.rs @@ -1,5 +1,31 @@ -use leptos::prelude::*; +use std::collections::hash_map::DefaultHasher; +use std::hash::{Hash, Hasher}; +use std::sync::atomic::{AtomicUsize, Ordering}; -pub fn use_random_id_for(prefix: &str) -> String { - format!("{}_{}", prefix, js_sys::Math::random().to_string().replace(".", "")) +const PREFIX: &str = "rust_ui"; // Must NOT contain "/" or "-" + +pub fn use_random_id() -> String { + format!("_{PREFIX}_{}", generate_hash()) } + +pub fn use_random_id_for(element: &str) -> String { + format!("{}_{PREFIX}_{}", element, generate_hash()) +} + +pub fn use_random_transition_name() -> String { + let random_id = use_random_id(); + format!("view-transition-name: {random_id}") +} + +/* ========================================================== */ +/* ✨ FUNCTIONS ✨ */ +/* ========================================================== */ + +static COUNTER: AtomicUsize = AtomicUsize::new(1); + +fn generate_hash() -> u64 { + let mut hasher = DefaultHasher::new(); + let counter = COUNTER.fetch_add(1, Ordering::SeqCst); + counter.hash(&mut hasher); + hasher.finish() +} \ No newline at end of file diff --git a/frontend/src/components/mod.rs b/frontend/src/components/mod.rs index f9248ff..5219b5c 100644 --- a/frontend/src/components/mod.rs +++ b/frontend/src/components/mod.rs @@ -5,3 +5,4 @@ pub mod torrent; pub mod auth; // pub mod toast; (Removed) pub mod ui; +pub mod demos; diff --git a/frontend/src/components/torrent/details.rs b/frontend/src/components/torrent/details.rs index 45ee370..88c318a 100644 --- a/frontend/src/components/torrent/details.rs +++ b/frontend/src/components/torrent/details.rs @@ -35,13 +35,13 @@ pub fn TorrentDetailsSheet() -> impl IntoView {
}>

- {move || selected_torrent.get().unwrap().name} + {move || selected_torrent.get().map(|t| t.name).unwrap_or_default()}

}>

- {move || format!("{:?}", selected_torrent.get().unwrap().status)} - {move || format!("{:.1}%", selected_torrent.get().unwrap().percent_complete)} + {move || selected_torrent.get().map(|t| format!("{:?}", t.status)).unwrap_or_default()} + {move || selected_torrent.get().map(|t| format!("{:.1}%", t.percent_complete)).unwrap_or_default()}

diff --git a/frontend/src/components/ui/card.rs b/frontend/src/components/ui/card.rs index 149c0dd..1e238b3 100644 --- a/frontend/src/components/ui/card.rs +++ b/frontend/src/components/ui/card.rs @@ -3,13 +3,17 @@ use leptos_ui::clx; mod components { use super::*; - clx! {Card, div, "bg-card text-card-foreground flex flex-col gap-4 rounded-xl border py-6 shadow-sm"} - clx! {CardHeader, div, "@container/card-header flex flex-col items-start gap-1.5 px-6 [.border-b]:pb-6"} + // TODO. Change data-slot=card-action by data-name="CardAction". + clx! {CardHeader, div, "@container/card-header flex flex-col items-start gap-1.5 px-6 [.border-b]:pb-6 sm:grid sm:auto-rows-min sm:grid-rows-[auto_auto] has-data-[slot=card-action]:sm:grid-cols-[1fr_auto]"} clx! {CardTitle, h2, "leading-none font-semibold"} clx! {CardContent, div, "px-6"} clx! {CardDescription, p, "text-muted-foreground text-sm"} clx! {CardFooter, footer, "flex items-center px-6 [.border-t]:pt-6", "gap-2"} + + clx! {CardAction, div, "self-start sm:col-start-2 sm:row-span-2 sm:row-start-1 sm:justify-self-end"} + clx! {CardList, ul, "flex flex-col gap-4"} + clx! {CardItem, li, "flex items-center [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0"} } -pub use components::*; +pub use components::*; \ No newline at end of file