diff --git a/src/home/room_screen.rs b/src/home/room_screen.rs index f327e8d3..d6b99c02 100644 --- a/src/home/room_screen.rs +++ b/src/home/room_screen.rs @@ -585,6 +585,14 @@ impl Widget for RoomScreen { } } + // Handle a typing action on the message input box. + if let Some(new_text) = self.text_input(id!(message_input)).changed(actions) { + submit_async_request(MatrixRequest::SendTypingNotice { + room_id: self.room_id.clone().unwrap(), + typing: !new_text.is_empty(), + }); + } + for action in actions { // Handle the action that requests to show the user profile sliding pane. if let ShowUserProfileAction::ShowUserProfile(avatar_info) = action.as_widget_action().cast() { diff --git a/src/sliding_sync.rs b/src/sliding_sync.rs index 6ef28314..72d9bed6 100644 --- a/src/sliding_sync.rs +++ b/src/sliding_sync.rs @@ -3,7 +3,7 @@ use clap::Parser; use eyeball_im::VectorDiff; use futures_util::{StreamExt, pin_mut}; use imbl::Vector; -use makepad_widgets::{SignalToUI, error, log}; +use makepad_widgets::{error, log, SignalToUI}; use matrix_sdk::{ config::RequestConfig, media::MediaRequest, room::RoomMember, ruma::{ api::client::{ @@ -158,6 +158,15 @@ pub enum MatrixRequest { SendMessage { room_id: OwnedRoomId, message: RoomMessageEventContent, + }, + /// Sends a notice to the given room that the current user is or is not typing. + /// + /// This request does not return a response or notify the UI thread, and + /// furthermore, there is no need to send a follow-up request to stop typing + /// (though you certainly can do so). + SendTypingNotice { + room_id: OwnedRoomId, + typing: bool, } } @@ -360,6 +369,18 @@ async fn async_worker(mut receiver: UnboundedReceiver) -> Result< } }); } + + MatrixRequest::SendTypingNotice { room_id, typing } => { + let Some(room) = CLIENT.get().and_then(|c| c.get_room(&room_id)) else { + error!("BUG: client/room not found for typing notice request {room_id}"); + continue; + }; + let _typing_task = Handle::current().spawn(async move { + if let Err(e) = room.typing_notice(typing).await { + error!("Failed to send typing notice to room {room_id}: {e:?}"); + } + }); + } MatrixRequest::ResolveRoomAlias(room_alias) => { let Some(client) = CLIENT.get() else { continue };