From 717958c220b03d9d5d34e6cf74e4f72cefae135e Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 19:42:05 +0000 Subject: [PATCH] Add tooltips to RoomsListHeader status icons Implemented tooltips for the `loading_spinner`, `offline_icon`, and `synced_icon` in `RoomsListHeader`. This provides users with clear feedback on the synchronization status of the application. The tooltips are triggered by detecting hover events on the respective icons within `handle_event`. We ensure tooltips are only shown for visible icons to prevent phantom tooltips. This change improves accessibility and clarity of the UI. Co-authored-by: kevinaboos <1139460+kevinaboos@users.noreply.github.com> --- .Jules/palette.md | 3 ++ src/home/rooms_list_header.rs | 77 ++++++++++++++++++++++++++++++++++- 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 .Jules/palette.md diff --git a/.Jules/palette.md b/.Jules/palette.md new file mode 100644 index 00000000..2cf6d2d0 --- /dev/null +++ b/.Jules/palette.md @@ -0,0 +1,3 @@ +## 2025-02-12 - Status Icon Tooltips +**Learning:** Status icons implemented as `View`s or `LoadingSpinner`s require manual hover detection in the parent widget's `handle_event` method, as they don't automatically support tooltips. +**Action:** Always check `visible()` before dispatching `TooltipAction::HoverIn` to avoid phantom tooltips for hidden elements. diff --git a/src/home/rooms_list_header.rs b/src/home/rooms_list_header.rs index 916eaac7..30e83357 100644 --- a/src/home/rooms_list_header.rs +++ b/src/home/rooms_list_header.rs @@ -8,7 +8,7 @@ use std::mem::discriminant; use makepad_widgets::*; use matrix_sdk_ui::sync_service::State; -use crate::{home::navigation_tab_bar::{NavigationBarAction, SelectedTab}, shared::{image_viewer::{ImageViewerAction, ImageViewerError, LoadState}, popup_list::{PopupKind, enqueue_popup_notification}}}; +use crate::{home::navigation_tab_bar::{NavigationBarAction, SelectedTab}, shared::{callout_tooltip::{CalloutTooltipOptions, TooltipAction, TooltipPosition}, image_viewer::{ImageViewerAction, ImageViewerError, LoadState}, popup_list::{PopupKind, enqueue_popup_notification}}}; live_design! { use link::theme::*; @@ -142,6 +142,81 @@ impl Widget for RoomsListHeader { } } + let loading_spinner = self.view.view(ids!(loading_spinner)); + if loading_spinner.visible() { + let area = loading_spinner.area(); + match event.hits(cx, area) { + Hit::FingerHoverIn(_) => { + cx.widget_action( + self.widget_uid(), + &scope.path, + TooltipAction::HoverIn { + text: "Syncing...".to_string(), + widget_rect: area.rect(cx), + options: CalloutTooltipOptions { + position: TooltipPosition::Bottom, + ..Default::default() + }, + }, + ); + } + Hit::FingerHoverOut(_) => { + cx.widget_action(self.widget_uid(), &scope.path, TooltipAction::HoverOut); + } + _ => {} + } + } + + let offline_icon = self.view.view(ids!(offline_icon)); + if offline_icon.visible() { + let area = offline_icon.area(); + match event.hits(cx, area) { + Hit::FingerHoverIn(_) => { + cx.widget_action( + self.widget_uid(), + &scope.path, + TooltipAction::HoverIn { + text: "Offline".to_string(), + widget_rect: area.rect(cx), + options: CalloutTooltipOptions { + position: TooltipPosition::Bottom, + ..Default::default() + }, + }, + ); + } + Hit::FingerHoverOut(_) => { + cx.widget_action(self.widget_uid(), &scope.path, TooltipAction::HoverOut); + } + _ => {} + } + } + + let synced_icon = self.view.view(ids!(synced_icon)); + if synced_icon.visible() { + let area = synced_icon.area(); + match event.hits(cx, area) { + Hit::FingerHoverIn(_) => { + cx.widget_action( + self.widget_uid(), + &scope.path, + TooltipAction::HoverIn { + text: "Synced".to_string(), + widget_rect: area.rect(cx), + options: CalloutTooltipOptions { + position: TooltipPosition::Bottom, + ..Default::default() + }, + }, + ); + } + Hit::FingerHoverOut(_) => { + cx.widget_action(self.widget_uid(), &scope.path, TooltipAction::HoverOut); + } + _ => {} + } + } + self.view.handle_event(cx, event, scope); }