fix: fixed statusbar at bottom, fix dropdown toggle race, fix theme buttons on iOS

- StatusBar now uses fixed positioning at viewport bottom (z-[99])
- Dropdown toggle uses skip_next_close guard to prevent close-then-reopen
- Global close listener uses click instead of pointerdown (fires after toggle)
- Theme/limit buttons use on:pointerdown instead of on:click for iOS compat
- Main content has pb-8 to prevent overlap with fixed statusbar
- Rebuilt tailwind.css
This commit is contained in:
spinline
2026-02-06 17:17:07 +03:00
parent 2c25d3bdf1
commit 2a919211d9
3 changed files with 36 additions and 22 deletions

View File

@@ -1366,6 +1366,9 @@
.right-0 {
right: calc(var(--spacing) * 0);
}
.bottom-0 {
bottom: calc(var(--spacing) * 0);
}
.bottom-full {
bottom: 100%;
}
@@ -2172,6 +2175,9 @@
.pt-1 {
padding-top: calc(var(--spacing) * 1);
}
.pb-8 {
padding-bottom: calc(var(--spacing) * 8);
}
.pb-20 {
padding-bottom: calc(var(--spacing) * 20);
}

View File

@@ -64,22 +64,19 @@ pub fn App() -> impl IntoView {
<div class="drawer lg:drawer-open h-full w-full">
<input id="my-drawer" type="checkbox" class="drawer-toggle" />
<div class="drawer-content flex flex-col h-full bg-base-100 text-base-content text-sm select-none">
// Toolbar + main wrapped so overflow-hidden doesn't clip StatusBar dropdowns
<div class="flex-1 flex flex-col overflow-hidden">
<Toolbar />
<div class="drawer-content flex flex-col h-full overflow-hidden bg-base-100 text-base-content text-sm select-none">
<Toolbar />
<main class="flex-1 flex flex-col min-w-0 bg-base-100 overflow-hidden">
<Router>
<Routes>
<Route path="/" view=move || view! { <TorrentTable /> } />
<Route path="/settings" view=move || view! { <div class="p-4">"Settings Page (Coming Soon)"</div> } />
</Routes>
</Router>
</main>
</div>
<main class="flex-1 flex flex-col min-w-0 bg-base-100 overflow-hidden pb-8">
<Router>
<Routes>
<Route path="/" view=move || view! { <TorrentTable /> } />
<Route path="/settings" view=move || view! { <div class="p-4">"Settings Page (Coming Soon)"</div> } />
</Routes>
</Router>
</main>
// Status Bar at the bottom - outside overflow-hidden so dropdowns can open upward
// StatusBar is rendered via fixed positioning, just mount it here
<StatusBar />
</div>

View File

@@ -111,13 +111,18 @@ pub fn StatusBar() -> impl IntoView {
// Signal-based dropdown state: 0=none, 1=download, 2=upload, 3=theme
let (active_dropdown, set_active_dropdown) = create_signal(0u8);
// Guard to prevent global close from firing right after toggle opens
let skip_next_close = store_value(false);
// Toggle a specific dropdown
let toggle = move |id: u8| {
if active_dropdown.get_untracked() == id {
let current = active_dropdown.get_untracked();
if current == id {
set_active_dropdown.set(0);
} else {
set_active_dropdown.set(id);
// Mark that the next global close should be skipped
skip_next_close.set_value(true);
}
};
@@ -126,14 +131,17 @@ pub fn StatusBar() -> impl IntoView {
set_active_dropdown.set(0);
};
// Close dropdowns when tapping outside
let _ = window_event_listener(ev::pointerdown, move |_| {
// This fires first; dropdown buttons call stop_propagation to prevent closing
// Close dropdowns when tapping outside — uses click (fires after pointerdown)
let _ = window_event_listener(ev::click, move |_| {
if skip_next_close.get_value() {
skip_next_close.set_value(false);
return;
}
set_active_dropdown.set(0);
});
view! {
<div class="h-8 min-h-8 bg-base-200 border-t border-base-300 flex items-center px-4 text-xs gap-4 text-base-content/70">
<div class="fixed bottom-0 left-0 right-0 h-8 min-h-8 bg-base-200 border-t border-base-300 flex items-center px-4 text-xs gap-4 text-base-content/70 z-[99]">
// --- DOWNLOAD SPEED DROPDOWN ---
<div class="relative">
@@ -171,7 +179,8 @@ pub fn StatusBar() -> impl IntoView {
<li>
<button
class=move || if is_active() { "bg-primary/10 text-primary font-bold text-xs flex justify-between" } else { "text-xs flex justify-between" }
on:click=move |_| {
on:pointerdown=move |e| {
e.stop_propagation();
set_limit("down", val);
close_all();
}
@@ -224,7 +233,8 @@ pub fn StatusBar() -> impl IntoView {
<li>
<button
class=move || if is_active() { "bg-primary/10 text-primary font-bold text-xs flex justify-between" } else { "text-xs flex justify-between" }
on:click=move |_| {
on:pointerdown=move |e| {
e.stop_propagation();
set_limit("up", val);
close_all();
}
@@ -270,7 +280,8 @@ pub fn StatusBar() -> impl IntoView {
<li>
<button
class=move || if current_theme.get() == theme { "bg-primary/10 text-primary font-bold text-xs capitalize" } else { "text-xs capitalize" }
on:click=move |_| {
on:pointerdown=move |e| {
e.stop_propagation();
set_current_theme.set(theme.to_string());
if let Some(win) = web_sys::window() {
if let Some(doc) = win.document() {