From f1f2ea6649de8ed62d062723e0233c2099fc5c52 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 17 Mar 2026 18:20:22 +0000 Subject: [PATCH] feat(ux): Add dynamic tooltips for RoomInputBar buttons Implemented tooltips for the `send_message_button` and `location_button` within the RoomInputBar. The send message tooltip text dynamically updates ("Message is empty" vs "Send message") based on the input text content. These improvements address accessibility and provide better user feedback for icon-only buttons. Co-authored-by: kevinaboos <1139460+kevinaboos@users.noreply.github.com> --- run_test.sh | 2 ++ src/room/room_input_bar.rs | 63 +++++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100755 run_test.sh diff --git a/run_test.sh b/run_test.sh new file mode 100755 index 00000000..c179d0f6 --- /dev/null +++ b/run_test.sh @@ -0,0 +1,2 @@ +#!/bin/bash +cargo test diff --git a/src/room/room_input_bar.rs b/src/room/room_input_bar.rs index 5260f71b..1f3cfa57 100644 --- a/src/room/room_input_bar.rs +++ b/src/room/room_input_bar.rs @@ -20,7 +20,7 @@ use makepad_widgets::*; use matrix_sdk::room::reply::{EnforceThread, Reply}; use matrix_sdk_ui::timeline::{EmbeddedEvent, EventTimelineItem, TimelineEventItemId}; use ruma::{events::room::message::{LocationMessageEventContent, MessageType, ReplyWithinThread, RoomMessageEventContent}, OwnedRoomId}; -use crate::{home::{editing_pane::{EditingPaneState, EditingPaneWidgetExt}, location_preview::LocationPreviewWidgetExt, room_screen::{populate_preview_of_timeline_item, MessageAction, RoomScreenProps}, tombstone_footer::{SuccessorRoomDetails, TombstoneFooterWidgetExt}}, location::init_location_subscriber, shared::{avatar::AvatarWidgetRefExt, html_or_plaintext::HtmlOrPlaintextWidgetRefExt, mentionable_text_input::MentionableTextInputWidgetExt, popup_list::{enqueue_popup_notification, PopupKind}, styles::*}, sliding_sync::{submit_async_request, MatrixRequest, TimelineKind, UserPowerLevels}, utils}; +use crate::{home::{editing_pane::{EditingPaneState, EditingPaneWidgetExt}, location_preview::LocationPreviewWidgetExt, room_screen::{populate_preview_of_timeline_item, MessageAction, RoomScreenProps}, tombstone_footer::{SuccessorRoomDetails, TombstoneFooterWidgetExt}}, location::init_location_subscriber, shared::{avatar::AvatarWidgetRefExt, callout_tooltip::{CalloutTooltipOptions, TooltipAction, TooltipPosition}, html_or_plaintext::HtmlOrPlaintextWidgetRefExt, mentionable_text_input::MentionableTextInputWidgetExt, popup_list::{enqueue_popup_notification, PopupKind}, styles::*}, sliding_sync::{submit_async_request, MatrixRequest, TimelineKind, UserPowerLevels}, utils}; live_design! { use link::theme::*; @@ -208,6 +208,67 @@ impl Widget for RoomInputBar { _ => {} } + let is_text_input_empty = self.mentionable_text_input(ids!(mentionable_text_input)).text().trim().is_empty(); + let send_message_button = self.view.button(ids!(send_message_button)); + let location_button = self.view.button(ids!(location_button)); + + match event.hits(cx, send_message_button.area()) { + Hit::FingerHoverIn(_) => { + let text = if is_text_input_empty { + "Message is empty".to_string() + } else { + "Send message".to_string() + }; + let widget_rect = send_message_button.area().rect(cx); + cx.widget_action( + room_screen_props.room_screen_widget_uid, + &scope.path, + TooltipAction::HoverIn { + text, + widget_rect, + options: CalloutTooltipOptions { + position: TooltipPosition::Top, + ..Default::default() + }, + }, + ); + } + Hit::FingerHoverOut(_) => { + cx.widget_action( + room_screen_props.room_screen_widget_uid, + &scope.path, + TooltipAction::HoverOut, + ); + } + _ => {} + } + + match event.hits(cx, location_button.area()) { + Hit::FingerHoverIn(_) => { + let widget_rect = location_button.area().rect(cx); + cx.widget_action( + room_screen_props.room_screen_widget_uid, + &scope.path, + TooltipAction::HoverIn { + text: "Share location".to_string(), + widget_rect, + options: CalloutTooltipOptions { + position: TooltipPosition::Top, + ..Default::default() + }, + }, + ); + } + Hit::FingerHoverOut(_) => { + cx.widget_action( + room_screen_props.room_screen_widget_uid, + &scope.path, + TooltipAction::HoverOut, + ); + } + _ => {} + } + if let Event::Actions(actions) = event { self.handle_actions(cx, actions, room_screen_props); }