From 12783fe59a7a1122845672b073aeebe14606abc9 Mon Sep 17 00:00:00 2001 From: Maciek <108873945+rozwader@users.noreply.github.com> Date: Fri, 4 Sep 2026 17:26:18 +0200 Subject: [PATCH] feat: added MB4/MB5 and Esc navigation globally (#742) --- .../oneclient_app/src/components/button.rs | 2 +- .../oneclient_app/src/components/dropdown.rs | 12 +- .../src/components/navbar/app_navbar.rs | 2 +- .../src/components/overlay_popup.rs | 4 + .../src/components/recents_row.rs | 4 +- .../src/components/segmented_control.rs | 2 +- .../oneclient_app/src/components/tab_bar.rs | 2 +- .../oneclient_app/src/components/toggle.rs | 2 +- .../src/components/version_card.rs | 2 +- packages/oneclient_app/src/hooks/mod.rs | 5 + .../oneclient_app/src/hooks/overlay_claims.rs | 64 +++++++++++ .../src/layout/animated_outlet.rs | 104 +++++++++++++++++- .../oneclient_app/src/layout/app_shell.rs | 12 +- .../oneclient_app/src/layout/root_layout.rs | 3 +- .../src/layout/settings_shell.rs | 2 +- .../src/view/app/browser/index/cards.rs | 9 +- .../src/view/app/browser/index/sidebar.rs | 2 +- .../src/view/app/browser/package/sidebar.rs | 6 +- .../src/view/app/cluster/logs.rs | 13 ++- .../view/app/cluster/package_manager/views.rs | 6 +- 20 files changed, 229 insertions(+), 29 deletions(-) create mode 100644 packages/oneclient_app/src/hooks/overlay_claims.rs diff --git a/packages/oneclient_app/src/components/button.rs b/packages/oneclient_app/src/components/button.rs index 8699a010..8b2c735a 100644 --- a/packages/oneclient_app/src/components/button.rs +++ b/packages/oneclient_app/src/components/button.rs @@ -327,7 +327,7 @@ impl Component for Button { }) .cursor(cursor_icon) .map(on_press.clone(), |rect, handler| { - rect.on_all_press(move |event: Event| { + rect.on_press(move |event: Event| { handler.call(event); }) }); diff --git a/packages/oneclient_app/src/components/dropdown.rs b/packages/oneclient_app/src/components/dropdown.rs index 5ebecd2c..4099d385 100644 --- a/packages/oneclient_app/src/components/dropdown.rs +++ b/packages/oneclient_app/src/components/dropdown.rs @@ -1,6 +1,7 @@ use freya::prelude::*; use crate::components::{Icon, IconType, ScrollArea}; +use crate::hooks::use_overlay_claim_when; use crate::theme::colors; use crate::ui::border_all_color; @@ -70,6 +71,8 @@ impl Component for Dropdown { let on_select = self.on_select.clone(); let is_open = open(); + use_overlay_claim_when(is_open); + if !is_open && list_size().is_some() { let _ = list_size.take(); } @@ -108,6 +111,11 @@ impl Component for Dropdown { rect() .width(self.width.clone()) + .on_global_key_down(move |e: Event| { + if e.key == Key::Named(NamedKey::Escape) { + open.set_if_modified(false); + } + }) .child( rect() .width(Size::fill()) @@ -130,7 +138,7 @@ impl Component for Dropdown { .on_sized(move |e: Event| { button_area.set_if_modified(Some(e.area)); }) - .on_all_press(move |e: Event| { + .on_press(move |e: Event| { e.prevent_default(); e.stop_propagation(); open.toggle(); @@ -237,7 +245,7 @@ impl Component for DropdownOption { }) .on_pointer_enter(move |_| hovering.set(true)) .on_pointer_leave(move |_| hovering.set(false)) - .on_all_press(self.on_press.clone()) + .on_press(self.on_press.clone()) .child( label() .text(self.text.clone()) diff --git a/packages/oneclient_app/src/components/navbar/app_navbar.rs b/packages/oneclient_app/src/components/navbar/app_navbar.rs index 76a148a7..a49a39fa 100644 --- a/packages/oneclient_app/src/components/navbar/app_navbar.rs +++ b/packages/oneclient_app/src/components/navbar/app_navbar.rs @@ -189,7 +189,7 @@ impl Component for NavLink { .a11y_id(a11y_id) .a11y_focusable(true) .a11y_role(AccessibilityRole::Button) - .on_all_press(move |e: Event| { + .on_press(move |e: Event| { e.prevent_default(); match &target { NavTarget::Route(route) => { diff --git a/packages/oneclient_app/src/components/overlay_popup.rs b/packages/oneclient_app/src/components/overlay_popup.rs index 3b2f776c..33e50c4d 100644 --- a/packages/oneclient_app/src/components/overlay_popup.rs +++ b/packages/oneclient_app/src/components/overlay_popup.rs @@ -3,6 +3,8 @@ use freya::{ prelude::*, }; +use crate::hooks::use_overlay_claim; + const SCRIM_ALPHA: f32 = 90.; #[derive(PartialEq)] @@ -61,6 +63,8 @@ impl KeyExt for OverlayPopup { impl Component for OverlayPopup { fn render(&self) -> impl IntoElement { + use_overlay_claim(); + let a11y_id = use_a11y(); let scrim_close = self.on_close.clone(); let key_close = self.on_close.clone(); diff --git a/packages/oneclient_app/src/components/recents_row.rs b/packages/oneclient_app/src/components/recents_row.rs index 9b735dcf..a7d613a4 100644 --- a/packages/oneclient_app/src/components/recents_row.rs +++ b/packages/oneclient_app/src/components/recents_row.rs @@ -173,7 +173,7 @@ impl Component for ClusterCard { .y(0.) .color(Color::from_af32rgb(0.3, 0, 0, 0)), ) - .on_all_press(on_press) + .on_press(on_press) .child( rect() .width(Size::fill()) @@ -281,7 +281,7 @@ impl Component for OtherVersionsTile { .y(0.) .color(Color::from_af32rgb(0.3, 0, 0, 0)), ) - .on_all_press(|_| { + .on_press(|_| { let _ = RouterContext::get().push(Route::Clusters {}); }) .child( diff --git a/packages/oneclient_app/src/components/segmented_control.rs b/packages/oneclient_app/src/components/segmented_control.rs index 917beb31..32b08452 100644 --- a/packages/oneclient_app/src/components/segmented_control.rs +++ b/packages/oneclient_app/src/components/segmented_control.rs @@ -185,7 +185,7 @@ impl Component for SegmentButton { }) .maybe(!disabled, |el| { el.cursor(CursorIcon::Pointer) - .on_all_press(move |_| *selected.write() = value) + .on_press(move |_| *selected.write() = value) }) .maybe_child(self.icon.map(|icon| { let mut ic = Icon::new(icon); diff --git a/packages/oneclient_app/src/components/tab_bar.rs b/packages/oneclient_app/src/components/tab_bar.rs index 636748fe..c56cb394 100644 --- a/packages/oneclient_app/src/components/tab_bar.rs +++ b/packages/oneclient_app/src/components/tab_bar.rs @@ -187,7 +187,7 @@ impl Component for TabButton { .cursor(CursorIcon::Pointer); if let Some(handler) = self.on_press.clone() { - el = el.on_all_press(move |e| handler.call(e)); + el = el.on_press(move |e| handler.call(e)); } el.child( diff --git a/packages/oneclient_app/src/components/toggle.rs b/packages/oneclient_app/src/components/toggle.rs index 30adb1d7..6055819b 100644 --- a/packages/oneclient_app/src/components/toggle.rs +++ b/packages/oneclient_app/src/components/toggle.rs @@ -106,7 +106,7 @@ impl Component for Switch { .a11y_focusable(!disabled) .a11y_role(AccessibilityRole::Button) .maybe(!disabled, |el| { - el.cursor(CursorIcon::Pointer).on_all_press(move |_| { + el.cursor(CursorIcon::Pointer).on_press(move |_| { on_press.call(()); }) }) diff --git a/packages/oneclient_app/src/components/version_card.rs b/packages/oneclient_app/src/components/version_card.rs index 8695627a..b8c806e7 100644 --- a/packages/oneclient_app/src/components/version_card.rs +++ b/packages/oneclient_app/src/components/version_card.rs @@ -79,7 +79,7 @@ impl Component for VersionCard { .a11y_id(a11y_id) .a11y_focusable(true) .a11y_role(AccessibilityRole::Button) - .on_all_press(move |e| on_press.call(e)) + .on_press(move |e| on_press.call(e)) .on_pointer_enter(move |_| { *hovering.write() = true; }) diff --git a/packages/oneclient_app/src/hooks/mod.rs b/packages/oneclient_app/src/hooks/mod.rs index 2787967e..d6ef8ff4 100644 --- a/packages/oneclient_app/src/hooks/mod.rs +++ b/packages/oneclient_app/src/hooks/mod.rs @@ -1,10 +1,15 @@ mod active_cluster; mod debounce; mod actions; +mod overlay_claims; mod queries; mod view_state; pub use debounce::use_debounced; +pub use overlay_claims::{ + OverlayClaims, use_overlay_claim, use_overlay_claim_when, use_overlay_claims, + use_provide_overlay_claims, +}; pub use view_state::{PersistedView, use_view_state}; pub use active_cluster::{ diff --git a/packages/oneclient_app/src/hooks/overlay_claims.rs b/packages/oneclient_app/src/hooks/overlay_claims.rs new file mode 100644 index 00000000..3d226f91 --- /dev/null +++ b/packages/oneclient_app/src/hooks/overlay_claims.rs @@ -0,0 +1,64 @@ +use std::cell::Cell; +use std::rc::Rc; + +use freya::prelude::*; + +#[derive(Clone, Default)] +pub struct OverlayClaims(Rc>); + +impl OverlayClaims { + /// Whether anything on screen currently owns Escape and mouse-back. + pub fn any(&self) -> bool { + self.0.get() > 0 + } + + fn acquire(&self) { + self.0.set(self.0.get() + 1); + } + + fn release(&self) { + let held = self.0.get(); + debug_assert!(held > 0, "overlay claim released without a matching acquire"); + self.0.set(held.saturating_sub(1)); + } +} + +pub fn use_provide_overlay_claims() { + use_provide_root_context(OverlayClaims::default); +} + +/// Falls back to a detached counter outside `RootLayout` so a claim raised there +/// degrades to "nothing claimed" instead of taking the app down. +pub fn use_overlay_claims() -> OverlayClaims { + try_consume_root_context::().unwrap_or_default() +} + +pub fn use_overlay_claim() { + let claims = use_hook(use_overlay_claims); + let released = claims.clone(); + + use_hook(move || claims.acquire()); + use_drop(move || released.release()); +} + +pub fn use_overlay_claim_when(active: bool) { + let claims = use_hook(use_overlay_claims); + let held = use_hook(|| Rc::new(Cell::new(false))); + + if held.get() != active { + held.set(active); + if active { + claims.acquire(); + } else { + claims.release(); + } + } + + let released = claims; + let held_at_drop = held; + use_drop(move || { + if held_at_drop.get() { + released.release(); + } + }); +} diff --git a/packages/oneclient_app/src/layout/animated_outlet.rs b/packages/oneclient_app/src/layout/animated_outlet.rs index 4ea329e3..859f97b4 100644 --- a/packages/oneclient_app/src/layout/animated_outlet.rs +++ b/packages/oneclient_app/src/layout/animated_outlet.rs @@ -2,8 +2,9 @@ use freya::animation::*; use freya::prelude::*; use freya::router::*; -use super::app_shell::{appshell_overlay, back_button, hides_overlay}; +use super::app_shell::{appshell_overlay, back_button, hides_overlay, navigate_back}; use crate::Route; +use crate::hooks::use_overlay_claims; use crate::theme; use crate::ui::entrance_motion_layer; @@ -46,6 +47,41 @@ fn is_cluster_route(route: &Route) -> bool { ) } +/// Checks if it should go back to home or somewhere else +fn escape_exits_section(route: &Route) -> bool { + is_cluster_route(route) || is_sidebar_route(route) +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +enum EscapeAction { + /// The root screen has nothing above it so Escape must not walk history + Ignore, + ExitSection, + Back, +} + +fn escape_action(route: &Route) -> EscapeAction { + if matches!(route, Route::Home {}) { + EscapeAction::Ignore + } else if escape_exits_section(route) { + EscapeAction::ExitSection + } else { + EscapeAction::Back + } +} + +/// Escape belongs to whatever the user is typing in before it belongs to the +/// router so a search field does not throw the page away mid-word +fn is_text_entry(role: AccessibilityRole) -> bool { + matches!( + role, + AccessibilityRole::TextInput + | AccessibilityRole::MultilineTextInput + | AccessibilityRole::SearchInput + | AccessibilityRole::PasswordInput + ) +} + fn enter_kind(from: &Route, to: &Route) -> Enter { if (is_sidebar_route(from) && is_sidebar_route(to)) || (is_cluster_route(from) && is_cluster_route(to)) @@ -66,6 +102,9 @@ impl Component for AnimatedAppOutlet { let mut router = use_animated_router::(); let route = use_route::(); + let at_home = matches!(&route, Route::Home {}); + let escape = escape_action(&route); + let mut origin_route = use_state(|| route.clone()); let mut last_route = use_state(|| route.clone()); @@ -79,6 +118,48 @@ impl Component for AnimatedAppOutlet { let back_title = origin_route.read().title(); + let platform = Platform::get(); + let focused_node = platform.focused_accessibility_node; + let focused_id = platform.focused_accessibility_id; + + let key_claims = use_overlay_claims(); + let pointer_claims = key_claims.clone(); + + let on_global_key = move |e: Event| { + if e.key != Key::Named(NamedKey::Escape) || key_claims.any() { + return; + } + + if is_text_entry(focused_node.peek().role()) { + focused_id.peek().request_unfocus(); + return; + } + + match escape { + EscapeAction::Ignore => {} + EscapeAction::ExitSection => { + let _ = RouterContext::get().push(Route::Home {}); + } + EscapeAction::Back => navigate_back(at_home), + } + }; + + let on_global_pointer = move |e: Event| { + if pointer_claims.any() { + return; + } + match e.button() { + Some(MouseButton::Back) => navigate_back(at_home), + Some(MouseButton::Forward) => { + let router = RouterContext::get(); + if router.can_go_forward() { + router.go_forward(); + } + } + _ => {} + } + }; + let anim = use_animation(|_conf| { AnimNum::new(0., 1.) .time(430) @@ -170,7 +251,28 @@ impl Component for AnimatedAppOutlet { .width(Size::fill()) .height(Size::fill()) .overflow(Overflow::Clip) + .on_global_key_down(on_global_key) + .on_global_pointer_press(on_global_pointer) .maybe_child(overlay) .child(column) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn escape_action_per_route() { + assert_eq!(escape_action(&Route::Home {}), EscapeAction::Ignore); + assert_eq!( + escape_action(&Route::ClusterSettings { cluster_id: 1 }), + EscapeAction::ExitSection + ); + assert_eq!( + escape_action(&Route::SettingsJava {}), + EscapeAction::ExitSection + ); + assert_eq!(escape_action(&Route::Clusters {}), EscapeAction::Back); + } +} diff --git a/packages/oneclient_app/src/layout/app_shell.rs b/packages/oneclient_app/src/layout/app_shell.rs index c45c9a58..f5df1122 100644 --- a/packages/oneclient_app/src/layout/app_shell.rs +++ b/packages/oneclient_app/src/layout/app_shell.rs @@ -600,12 +600,22 @@ pub(crate) fn gradient_overlay_radial() -> impl IntoElement { )) } +pub(crate) fn navigate_back(at_home: bool) { + let router = RouterContext::get(); + if router.can_go_back() { + router.go_back(); + } else if !at_home { + let _ = router.push(Route::Home {}); + } +} + pub(crate) fn back_button(destination: &str) -> impl IntoElement { Button::new() .ghost() .small() .on_press(|_| { - RouterContext::get().go_back(); + // Only rendered off home so the history-empty fallback is reachable + navigate_back(false); }) .margin(Gaps::new(0., 0., 0., 32.)) .child(Icon::new(IconType::ArrowLeft).size(12.)) diff --git a/packages/oneclient_app/src/layout/root_layout.rs b/packages/oneclient_app/src/layout/root_layout.rs index 06f0c851..092cd6ae 100644 --- a/packages/oneclient_app/src/layout/root_layout.rs +++ b/packages/oneclient_app/src/layout/root_layout.rs @@ -6,7 +6,7 @@ use crate::components::{ NotificationCenter, PackageUpdatePopup, SplashCurtain, StatusBar, Toasts, UpdatePromptOverlay, }; -use crate::hooks::{SplashState, use_provide_splash}; +use crate::hooks::{SplashState, use_provide_overlay_claims, use_provide_splash}; use crate::layout::HomeArtPrefetch; use crate::motion::AnimationClockDriver; use crate::routes::Route; @@ -21,6 +21,7 @@ impl Component for RootLayout { let active = use_state(|| false); let home_ready = use_state(|| false); use_provide_splash(SplashState { active, home_ready }); + use_provide_overlay_claims(); // macOS rounds the window natively so Freya must not round on top of it #[cfg(target_os = "macos")] diff --git a/packages/oneclient_app/src/layout/settings_shell.rs b/packages/oneclient_app/src/layout/settings_shell.rs index d3c726da..c1d44c5a 100644 --- a/packages/oneclient_app/src/layout/settings_shell.rs +++ b/packages/oneclient_app/src/layout/settings_shell.rs @@ -797,7 +797,7 @@ impl Component for SidebarItem { .on_pointer_enter(move |_| *hovering.write() = true) .on_pointer_leave(move |_| *hovering.write() = false) .map(route, |el, route| { - el.on_all_press(move |_| { + el.on_press(move |_| { let _ = RouterContext::get().replace(route.clone()); }) }); diff --git a/packages/oneclient_app/src/view/app/browser/index/cards.rs b/packages/oneclient_app/src/view/app/browser/index/cards.rs index b05f09bd..c5edbc32 100644 --- a/packages/oneclient_app/src/view/app/browser/index/cards.rs +++ b/packages/oneclient_app/src/view/app/browser/index/cards.rs @@ -125,14 +125,13 @@ impl Component for PackageCard { .a11y_focusable(true) .a11y_role(AccessibilityRole::Button) .cursor(CursorIcon::Pointer) - .on_all_press(move |_| open_package(cluster_id, &package_type, provider, &id)) + .on_press(move |_| open_package(cluster_id, &package_type, provider, &id)) .child( rect() .margin(Gaps::new_all(1.)) .corner_radius(CornerRadius::new(10., 10., 0., 0.)) .overflow(Overflow::Clip) .child(PackageBanner::new(icon_url, BANNER_H)) - // Top-left of the banner the first thing worth knowing about a result and the opposite corner is the install button's .maybe_child(self.installed.map(|installed| { rect() .position(Position::new_absolute().top(8.).left(8.)) @@ -258,7 +257,7 @@ impl Component for ListRow { .a11y_focusable(true) .a11y_role(AccessibilityRole::Button) .cursor(CursorIcon::Pointer) - .on_all_press(move |_| open_package(cluster_id, &package_type, provider, &id)) + .on_press(move |_| open_package(cluster_id, &package_type, provider, &id)) .child(Thumbnail::new(item.icon_url.clone(), 48.).radius(8.)) .child( rect() @@ -303,7 +302,6 @@ impl Component for ListRow { ), ) .child(downloads_row(item.downloads)) - // Kept once installed rather than dropped a row that loses its button leaves its neighbours misaligned .child(InstallButton::new( &self.item, self.cluster_id, @@ -313,7 +311,6 @@ impl Component for ListRow { } } -/// Same version pick and dispatch as the install button on the package page #[derive(PartialEq)] struct InstallButton { provider: ProviderId, @@ -372,7 +369,7 @@ impl Component for InstallButton { rect() // The card behind is one big press target stop here so the package page doesn't open on top of the install - .on_all_press(|e: Event| e.stop_propagation()) + .on_press(|e: Event| e.stop_propagation()) .child( Button::new() .primary() diff --git a/packages/oneclient_app/src/view/app/browser/index/sidebar.rs b/packages/oneclient_app/src/view/app/browser/index/sidebar.rs index 66b7dfdb..ad814631 100644 --- a/packages/oneclient_app/src/view/app/browser/index/sidebar.rs +++ b/packages/oneclient_app/src/view/app/browser/index/sidebar.rs @@ -100,7 +100,7 @@ impl Component for CategoryRow { .cursor(CursorIcon::Pointer) .on_pointer_enter(move |_| hovering.set(true)) .on_pointer_leave(move |_| hovering.set(false)) - .on_all_press(move |_| on_toggle.call(())) + .on_press(move |_| on_toggle.call(())) .child( label() .text(capitalize(&self.name)) diff --git a/packages/oneclient_app/src/view/app/browser/package/sidebar.rs b/packages/oneclient_app/src/view/app/browser/package/sidebar.rs index 04939b5d..628e8659 100644 --- a/packages/oneclient_app/src/view/app/browser/package/sidebar.rs +++ b/packages/oneclient_app/src/view/app/browser/package/sidebar.rs @@ -208,7 +208,7 @@ impl Component for ProviderTag { el.border(border_all_color(1., colors::brand())) }) .cursor(CursorIcon::Pointer) - .on_all_press(move |_| confirm.set(Some(url.clone()))) + .on_press(move |_| confirm.set(Some(url.clone()))) }) } } @@ -302,7 +302,7 @@ impl Component for AuthorRow { .a11y_focusable(true) .a11y_role(AccessibilityRole::Button) .cursor(CursorIcon::Pointer) - .on_all_press(move |_| confirm.set(Some(url.clone()))) + .on_press(move |_| confirm.set(Some(url.clone()))) }) .maybe(interactive && focused, |el| { el.border(border_all_color(1., colors::brand())) @@ -439,7 +439,7 @@ impl Component for LinkRow { el.border(border_all_color(1., colors::brand())) }) .cursor(CursorIcon::Pointer) - .on_all_press(move |_| confirm.set(Some(url.clone()))) + .on_press(move |_| confirm.set(Some(url.clone()))) .child( Icon::new(IconType::Link03) .size(14.) diff --git a/packages/oneclient_app/src/view/app/cluster/logs.rs b/packages/oneclient_app/src/view/app/cluster/logs.rs index 39725181..b21594d7 100644 --- a/packages/oneclient_app/src/view/app/cluster/logs.rs +++ b/packages/oneclient_app/src/view/app/cluster/logs.rs @@ -14,7 +14,7 @@ use crate::components::{ use crate::hooks::{ ClusterLogsQuery, LogAction, UploadLogKeys, UseLogAction, UseUploadLog, invalidate_logs_queries, try_cluster_logs, try_log_content, use_cluster_logs, use_log_action, - use_log_content, use_upload_log, + use_log_content, use_overlay_claim_when, use_upload_log, }; use crate::layout::cluster_content; use crate::theme::colors; @@ -377,6 +377,8 @@ impl Component for LogPicker { // Stays usable with an empty list the category selector lives inside the panel let is_open = open(); + use_overlay_claim_when(is_open); + let query = SearchQuery::new(&filter.read()); let no_files = files.is_empty(); let rows: Vec = files @@ -402,6 +404,11 @@ impl Component for LogPicker { rect() .width(Size::px(260.)) + .on_global_key_down(move |e: Event| { + if e.key == Key::Named(NamedKey::Escape) { + open.set_if_modified(false); + } + }) .child( rect() .width(Size::fill()) @@ -425,7 +432,7 @@ impl Component for LogPicker { }, )) .cursor(CursorIcon::Pointer) - .on_all_press(move |e: Event| { + .on_press(move |e: Event| { e.stop_propagation(); open.toggle(); }) @@ -555,7 +562,7 @@ impl Component for PickerRow { .cursor(CursorIcon::Pointer) .on_pointer_enter(move |_| hovering.set(true)) .on_pointer_leave(move |_| hovering.set(false)) - .on_all_press(self.on_press.clone()) + .on_press(self.on_press.clone()) .child( rect() .vertical() diff --git a/packages/oneclient_app/src/view/app/cluster/package_manager/views.rs b/packages/oneclient_app/src/view/app/cluster/package_manager/views.rs index c5b789e4..becfcf63 100644 --- a/packages/oneclient_app/src/view/app/cluster/package_manager/views.rs +++ b/packages/oneclient_app/src/view/app/cluster/package_manager/views.rs @@ -9,7 +9,7 @@ use crate::components::{ Button, CardLayout, Icon, IconType, PackageEntry, PackageRow, ScrollArea, ScrollAreaCtx, Segment, SegmentedControl, TabBar, TabItem, TextInput, }; -use crate::hooks::use_dispatch; +use crate::hooks::{use_dispatch, use_overlay_claim}; use crate::routes::Route; use crate::theme::colors; use crate::{Actions, utils}; @@ -311,6 +311,8 @@ struct FilterPopover { impl Component for FilterPopover { fn render(&self) -> impl IntoElement { + use_overlay_claim(); + let mut sort = self.sort; let current_sort = self.current_sort; let mut enabled_filter = self.enabled_filter; @@ -473,7 +475,7 @@ impl Component for ChoiceRow { el.border(crate::ui::border_all_color(1., colors::brand())) }) .cursor(CursorIcon::Pointer) - .on_all_press(self.on_press.clone()) + .on_press(self.on_press.clone()) .child( label() .text(text)