Compare commits

..

3 Commits

Author SHA1 Message Date
spinline
322e0ab4a3 fix: make torrent status bar visible on mobile
All checks were successful
Build MIPS Binary / build (push) Successful in 1m52s
2026-02-13 14:05:07 +03:00
spinline
89f0a5423d style: make footer even more minimal and elegant
Some checks failed
Build MIPS Binary / build (push) Has been cancelled
2026-02-13 14:03:54 +03:00
spinline
80f9e5cda2 fix: resolve race condition in ButtonAction using a generation counter for safety
All checks were successful
Build MIPS Binary / build (push) Successful in 1m52s
2026-02-13 13:50:47 +03:00
3 changed files with 19 additions and 25 deletions

View File

@@ -6,24 +6,12 @@ pub fn Footer() -> impl IntoView {
let year = chrono::Local::now().format("%Y").to_string(); let year = chrono::Local::now().format("%Y").to_string();
view! { view! {
<footer class="mt-auto px-4 py-6 md:px-8"> <footer class="mt-auto pb-6 px-4">
<Separator class="mb-6 opacity-50" /> <Separator class="mb-4 opacity-30" />
<div class="flex flex-col items-center justify-between gap-4 md:flex-row"> <div class="flex items-center justify-center gap-2 text-[10px] uppercase tracking-widest text-muted-foreground/60 font-medium">
<p class="text-center text-sm leading-loose text-muted-foreground md:text-left"> <span>{format!("© {} VibeTorrent", year)}</span>
{format!("© {} VibeTorrent. Tüm hakları saklıdır.", year)} <span class="size-1 rounded-full bg-muted-foreground/30" />
</p> <span>"v3.0.0-beta"</span>
<div class="flex items-center gap-4 text-sm font-medium text-muted-foreground">
<a
href="https://git.karatatar.com/admin/vibetorrent"
target="_blank"
rel="noreferrer"
class="underline underline-offset-4 hover:text-foreground transition-colors"
>
"Gitea"
</a>
<span class="size-1 rounded-full bg-muted-foreground/30" />
<span class="text-[10px] tracking-widest uppercase opacity-70">"v3.0.0-beta"</span>
</div>
</div> </div>
</footer> </footer>
} }

View File

@@ -544,14 +544,14 @@ pub fn TorrentTable() -> impl IntoView {
</div> </div>
</div> </div>
<div class="hidden md:flex items-center justify-between px-2 py-1 text-[11px] text-muted-foreground bg-muted/20 border rounded-md"> <div class="flex items-center justify-between px-2 py-1.5 text-[10px] md:text-[11px] text-muted-foreground bg-muted/20 border rounded-md">
<div class="flex gap-4"> <div class="flex gap-3 md:gap-4">
<span>{move || format!("Toplam: {} torrent", filtered_hashes.get().len())}</span> <span>{move || format!("Toplam: {} torrent", filtered_hashes.get().len())}</span>
<Show when=move || has_selection.get()> <Show when=move || has_selection.get()>
<span class="text-primary font-medium">{move || format!("{} torrent seçili", selected_count.get())}</span> <span class="text-primary font-bold">{move || format!("{} seçili", selected_count.get())}</span>
</Show> </Show>
</div> </div>
<div>"VibeTorrent v3"</div> <div class="opacity-50">"VibeTorrent v3"</div>
</div> </div>
</div> </div>
}.into_any() }.into_any()

View File

@@ -11,16 +11,22 @@ pub fn ButtonAction(
#[prop(default = ButtonVariant::Default)] variant: ButtonVariant, #[prop(default = ButtonVariant::Default)] variant: ButtonVariant,
) -> impl IntoView { ) -> impl IntoView {
let is_holding = RwSignal::new(false); let is_holding = RwSignal::new(false);
let generation = StoredValue::new(0u64);
let on_down = move |_| {
generation.update_value(|g| *g += 1);
is_holding.set(true);
};
// Explicitly define handlers to avoid type mismatches between Mouse and Touch events
let on_down = move |_| is_holding.set(true);
let on_up = move |_| is_holding.set(false); let on_up = move |_| is_holding.set(false);
Effect::new(move |_| { Effect::new(move |_| {
if is_holding.get() { if is_holding.get() {
let current_gen = generation.get_value();
leptos::task::spawn_local(async move { leptos::task::spawn_local(async move {
gloo_timers::future::TimeoutFuture::new(hold_duration as u32).await; gloo_timers::future::TimeoutFuture::new(hold_duration as u32).await;
if is_holding.get_untracked() { // Double validation: Is user still holding AND is it the SAME hold attempt?
if is_holding.get_untracked() && generation.get_value() == current_gen {
on_action.run(()); on_action.run(());
is_holding.set(false); is_holding.set(false);
} }