chore: cleanup unused code, files, and improve code quality
Some checks failed
Build MIPS Binary / build (push) Failing after 1m53s
Some checks failed
Build MIPS Binary / build (push) Failing after 1m53s
This commit is contained in:
@@ -1,31 +1,5 @@
|
|||||||
use std::collections::hash_map::DefaultHasher;
|
use leptos::prelude::*;
|
||||||
use std::hash::{Hash, Hasher};
|
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
|
||||||
|
|
||||||
const PREFIX: &str = "rust_ui"; // Must NOT contain "/" or "-"
|
pub fn use_random_id_for(prefix: &str) -> String {
|
||||||
|
format!("{}_{}", prefix, js_sys::Math::random().to_string().replace(".", ""))
|
||||||
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()
|
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,6 @@ use crate::store::{get_action_messages, show_toast};
|
|||||||
use crate::api;
|
use crate::api;
|
||||||
use shared::NotificationLevel;
|
use shared::NotificationLevel;
|
||||||
use crate::components::context_menu::TorrentContextMenu;
|
use crate::components::context_menu::TorrentContextMenu;
|
||||||
use crate::components::ui::card::{Card, CardHeader, CardTitle, CardContent as CardBody};
|
|
||||||
use crate::components::ui::data_table::*;
|
use crate::components::ui::data_table::*;
|
||||||
use crate::components::ui::checkbox::Checkbox;
|
use crate::components::ui::checkbox::Checkbox;
|
||||||
use crate::components::ui::badge::{Badge, BadgeVariant};
|
use crate::components::ui::badge::{Badge, BadgeVariant};
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
use leptos::prelude::*;
|
|
||||||
use leptos_ui::clx;
|
|
||||||
|
|
||||||
mod components {
|
|
||||||
use super::*;
|
|
||||||
clx! {Draggable, div, "flex flex-col gap-4 w-full max-w-4xl"}
|
|
||||||
clx! {DraggableZone, div, "dragabble__container", "bg-neutral-600 p-4 mt-4"}
|
|
||||||
|
|
||||||
// TODO. ItemRoot (needs `draggable` as clx attribute).
|
|
||||||
}
|
|
||||||
|
|
||||||
pub use components::*;
|
|
||||||
|
|
||||||
/* ========================================================== */
|
|
||||||
/* ✨ FUNCTIONS ✨ */
|
|
||||||
/* ========================================================== */
|
|
||||||
|
|
||||||
#[component]
|
|
||||||
pub fn DraggableItem(#[prop(into)] text: String) -> impl IntoView {
|
|
||||||
view! {
|
|
||||||
<div class="p-4 border cursor-move border-input bg-card draggable" draggable="true">
|
|
||||||
{text}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,145 +0,0 @@
|
|||||||
use leptos::prelude::*;
|
|
||||||
use tw_merge::*;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Default, strum::Display)]
|
|
||||||
pub enum ToastType {
|
|
||||||
#[default]
|
|
||||||
Default,
|
|
||||||
Success,
|
|
||||||
Error,
|
|
||||||
Warning,
|
|
||||||
Info,
|
|
||||||
Loading,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Default, strum::Display)]
|
|
||||||
pub enum SonnerPosition {
|
|
||||||
TopLeft,
|
|
||||||
TopCenter,
|
|
||||||
TopRight,
|
|
||||||
#[default]
|
|
||||||
BottomRight,
|
|
||||||
BottomCenter,
|
|
||||||
BottomLeft,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Default, strum::Display)]
|
|
||||||
pub enum SonnerDirection {
|
|
||||||
TopDown,
|
|
||||||
#[default]
|
|
||||||
BottomUp,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[component]
|
|
||||||
pub fn SonnerTrigger(
|
|
||||||
children: Children,
|
|
||||||
#[prop(into, optional)] class: String,
|
|
||||||
#[prop(optional, default = ToastType::default())] variant: ToastType,
|
|
||||||
#[prop(into)] title: String,
|
|
||||||
#[prop(into)] description: String,
|
|
||||||
#[prop(into, optional)] position: String,
|
|
||||||
) -> impl IntoView {
|
|
||||||
let variant_classes = match variant {
|
|
||||||
ToastType::Default => "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
|
|
||||||
ToastType::Success => "bg-success text-success-foreground hover:bg-success/90",
|
|
||||||
ToastType::Error => "bg-destructive text-white shadow-xs hover:bg-destructive/90 dark:bg-destructive/60",
|
|
||||||
ToastType::Warning => "bg-warning text-warning-foreground hover:bg-warning/90",
|
|
||||||
ToastType::Info => "bg-info text-info-foreground shadow-xs hover:bg-info/90",
|
|
||||||
ToastType::Loading => "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
|
|
||||||
};
|
|
||||||
|
|
||||||
let merged_class = tw_merge!(
|
|
||||||
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] w-fit cursor-pointer h-9 px-4 py-2",
|
|
||||||
variant_classes,
|
|
||||||
class
|
|
||||||
);
|
|
||||||
|
|
||||||
// Only set position attribute if not empty
|
|
||||||
let position_attr = if position.is_empty() { None } else { Some(position) };
|
|
||||||
|
|
||||||
view! {
|
|
||||||
<button
|
|
||||||
class=merged_class
|
|
||||||
data-name="SonnerTrigger"
|
|
||||||
data-variant=variant.to_string()
|
|
||||||
data-toast-title=title
|
|
||||||
data-toast-description=description
|
|
||||||
data-toast-position=position_attr
|
|
||||||
>
|
|
||||||
{children()}
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[component]
|
|
||||||
pub fn SonnerContainer(
|
|
||||||
children: Children,
|
|
||||||
#[prop(into, optional)] class: String,
|
|
||||||
#[prop(optional, default = SonnerPosition::default())] position: SonnerPosition,
|
|
||||||
) -> impl IntoView {
|
|
||||||
let merged_class = tw_merge!("toast__container fixed z-50", class);
|
|
||||||
|
|
||||||
view! {
|
|
||||||
<div class=merged_class data-position=position.to_string()>
|
|
||||||
{children()}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[component]
|
|
||||||
pub fn SonnerList(
|
|
||||||
children: Children,
|
|
||||||
#[prop(into, optional)] class: String,
|
|
||||||
#[prop(optional, default = SonnerPosition::default())] position: SonnerPosition,
|
|
||||||
#[prop(optional, default = SonnerDirection::default())] direction: SonnerDirection,
|
|
||||||
#[prop(into, default = "false".to_string())] expanded: String,
|
|
||||||
#[prop(into, optional)] style: String,
|
|
||||||
) -> impl IntoView {
|
|
||||||
// pointer-events-none: container doesn't block clicks when empty
|
|
||||||
// [&>*]:pointer-events-auto: toast items still receive clicks
|
|
||||||
let merged_class = tw_merge!(
|
|
||||||
"flex relative flex-col opacity-100 gap-[15px] h-[100px] w-[400px] pointer-events-none [&>*]:pointer-events-auto",
|
|
||||||
class
|
|
||||||
);
|
|
||||||
|
|
||||||
view! {
|
|
||||||
<ol
|
|
||||||
class=merged_class
|
|
||||||
data-name="SonnerList"
|
|
||||||
data-sonner-toaster="true"
|
|
||||||
data-sonner-theme="light"
|
|
||||||
data-position=position.to_string()
|
|
||||||
data-expanded=expanded
|
|
||||||
data-direction=direction.to_string()
|
|
||||||
style=style
|
|
||||||
>
|
|
||||||
{children()}
|
|
||||||
</ol>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[component]
|
|
||||||
pub fn SonnerToaster(#[prop(default = SonnerPosition::default())] position: SonnerPosition) -> impl IntoView {
|
|
||||||
// Auto-derive direction from position
|
|
||||||
let direction = match position {
|
|
||||||
SonnerPosition::TopLeft | SonnerPosition::TopCenter | SonnerPosition::TopRight => SonnerDirection::TopDown,
|
|
||||||
_ => SonnerDirection::BottomUp,
|
|
||||||
};
|
|
||||||
|
|
||||||
let container_class = match position {
|
|
||||||
SonnerPosition::TopLeft => "left-6 top-6",
|
|
||||||
SonnerPosition::TopRight => "right-6 top-6",
|
|
||||||
SonnerPosition::TopCenter => "left-1/2 -translate-x-1/2 top-6",
|
|
||||||
SonnerPosition::BottomCenter => "left-1/2 -translate-x-1/2 bottom-6",
|
|
||||||
SonnerPosition::BottomLeft => "left-6 bottom-6",
|
|
||||||
SonnerPosition::BottomRight => "right-6 bottom-6",
|
|
||||||
};
|
|
||||||
|
|
||||||
view! {
|
|
||||||
<SonnerContainer class=container_class position=position>
|
|
||||||
<SonnerList position=position direction=direction>
|
|
||||||
""
|
|
||||||
</SonnerList>
|
|
||||||
</SonnerContainer>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -49,6 +49,7 @@ pub fn SonnerTrigger(
|
|||||||
is_expanded: Signal<bool>,
|
is_expanded: Signal<bool>,
|
||||||
#[prop(optional)] on_dismiss: Option<Callback<()>>,
|
#[prop(optional)] on_dismiss: Option<Callback<()>>,
|
||||||
) -> impl IntoView {
|
) -> impl IntoView {
|
||||||
|
let _ = is_expanded; // Silence unused warning while keeping prop name intact for builder
|
||||||
let variant_classes = match toast.variant {
|
let variant_classes = match toast.variant {
|
||||||
ToastType::Default => "bg-background text-foreground border-border",
|
ToastType::Default => "bg-background text-foreground border-border",
|
||||||
ToastType::Success => "bg-background text-foreground border-border [&_.icon]:text-green-500",
|
ToastType::Success => "bg-background text-foreground border-border [&_.icon]:text-green-500",
|
||||||
|
|||||||
Reference in New Issue
Block a user