use leptos::prelude::*; use crate::components::ui::sheet::*; use crate::components::ui::tabs::*; use crate::components::ui::skeleton::*; use shared::Torrent; #[component] pub fn TorrentDetailsSheet() -> impl IntoView { let store = use_context::().expect("store not provided"); // Setup an effect to open the sheet when a torrent is selected Effect::new(move |_| { if store.selected_torrent.get().is_some() { if let Some(trigger) = document().get_element_by_id("torrent-details-trigger") { use wasm_bindgen::JsCast; let _ = trigger.dyn_into::().map(|el| el.click()); } } }); let selected_torrent = Memo::new(move |_| { let hash = store.selected_torrent.get()?; store.torrents.with(|map| map.get(&hash).cloned()) }); view! {
}>

{move || selected_torrent.get().unwrap().name}

}>

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

// Custom close button that also resets store.selected_torrent
"Genel" "Dosyalar" "İzleyiciler" "Eşler"
{move || { let t = selected_torrent.get().unwrap_or_else(|| shared::Torrent { hash: "----------------------------------------".to_string(), name: "Yükleniyor...".to_string(), size: 0, completed: 0, down_rate: 0, up_rate: 0, eta: 0, percent_complete: 0.0, status: shared::TorrentStatus::Downloading, error_message: "".to_string(), added_date: 0, label: None, }); view! {
} }}

"Dosya listesi yakında eklenecek"

"İzleyici listesi yakında eklenecek"

"Eş listesi yakında eklenecek"

} } #[component] fn InfoItem( label: &'static str, value: String, #[prop(optional)] class: &'static str ) -> impl IntoView { view! {
{label} {value}
} } fn format_bytes(bytes: i64) -> String { const UNITS: [&str; 6] = ["B", "KB", "MB", "GB", "TB", "PB"]; if bytes < 1024 { return format!("{} B", bytes); } let i = (bytes as f64).log2().div_euclid(10.0) as usize; format!("{:.1} {}", (bytes as f64) / 1024_f64.powi(i as i32), UNITS[i]) } fn format_speed(bytes_per_sec: i64) -> String { if bytes_per_sec == 0 { return "0 B/s".to_string(); } format!("{}/s", format_bytes(bytes_per_sec)) } fn format_duration(seconds: i64) -> String { if seconds <= 0 { return "∞".to_string(); } let days = seconds / 86400; let hours = (seconds % 86400) / 3600; let minutes = (seconds % 3600) / 60; let secs = seconds % 60; if days > 0 { format!("{}g {}s", days, hours) } else if hours > 0 { format!("{}s {}d", hours, minutes) } else if minutes > 0 { format!("{}d {}sn", minutes, secs) } else { format!("{}sn", secs) } } fn format_date(timestamp: i64) -> String { if timestamp <= 0 { return "N/A".to_string(); } let dt = chrono::DateTime::from_timestamp(timestamp, 0); match dt { Some(dt) => dt.format("%d/%m/%Y %H:%M").to_string(), None => "N/A".to_string() } }