@@ -13,7 +13,7 @@ use matrix_sdk::{room::{reply::{EnforceThread, Reply}, RoomMember}, ruma::{
1313 } , ImageInfo , MediaSource
1414 } ,
1515 sticker:: { StickerEventContent , StickerMediaSource } , Mentions } , matrix_uri:: MatrixId , uint, EventId , MatrixToUri , MatrixUri , OwnedEventId , OwnedMxcUri , OwnedRoomId , UserId
16- } , OwnedServerName } ;
16+ } , OwnedServerName , RoomState } ;
1717use matrix_sdk_ui:: timeline:: {
1818 self , EmbeddedEvent , EncryptedMessage , EventTimelineItem , InReplyToDetails , MemberProfileChange , MsgLikeContent , MsgLikeKind , PollState , RoomMembershipChange , TimelineDetails , TimelineEventItemId , TimelineItem , TimelineItemContent , TimelineItemKind , VirtualTimelineItem
1919} ;
@@ -1001,41 +1001,81 @@ impl Widget for RoomScreen {
10011001 }
10021002
10031003 // Handle resolved room alias actions - only for requests from this widget
1004- if let Some ( ResolveRoomAliasAction :: Resolved { requester_uid, room_alias : _ , room_id, servers : _ } ) = action. downcast_ref ( ) {
1005- // Only handle this action if it was requested by this widget
1006- if * requester_uid == room_screen_widget_uid {
1007- if let Some ( known_room) = get_client ( ) . and_then ( |c| c. get_room ( room_id) ) {
1008- if known_room. is_space ( ) {
1009- enqueue_popup_notification ( PopupItem {
1010- message : format ! ( "Found space {} but it is a space, not a regular room." , room_id) ,
1011- auto_dismissal_duration : Some ( 3.0 )
1012- } ) ;
1013- } else {
1014- cx. widget_action ( room_screen_widget_uid, & scope. path , RoomsListAction :: Selected (
1015- SelectedRoom :: JoinedRoom {
1004+ if let Some ( resolve_action) = action. downcast_ref :: < ResolveRoomAliasAction > ( ) {
1005+ let Some ( self_room_id) = & self . room_id else {
1006+ error ! ( "RoomScreen received a ResolveRoomAliasAction but has no room_id set." ) ;
1007+ continue ;
1008+ } ;
1009+
1010+ match resolve_action {
1011+ ResolveRoomAliasAction :: Resolved { requester_room_id, room_alias : _ , room_id, servers : _ } => {
1012+ // Only handle this action if it was requested by this widget
1013+ if requester_room_id == self_room_id {
1014+ if let Some ( known_room) = get_client ( ) . and_then ( |c| c. get_room ( room_id) ) {
1015+ if known_room. is_space ( ) {
1016+ enqueue_popup_notification ( PopupItem {
1017+ message : format ! ( "Found space {} but it is a space, not a regular room." , room_id) ,
1018+ auto_dismissal_duration : Some ( 3.0 )
1019+ } ) ;
1020+ } else if known_room. state ( ) == RoomState :: Joined {
1021+ cx. widget_action ( room_screen_widget_uid, & scope. path , RoomsListAction :: Selected (
1022+ SelectedRoom :: JoinedRoom {
1023+ room_id : room_id. clone ( ) . into ( ) ,
1024+ room_name : known_room. name ( )
1025+ }
1026+ ) ) ;
1027+ } else {
1028+ // Room exists but we're not joined - show join modal
1029+ use crate :: join_leave_room_modal:: { JoinLeaveRoomModalAction , JoinLeaveModalKind } ;
1030+ use crate :: room:: { BasicRoomDetails , RoomPreviewAvatar } ;
1031+
1032+ let room_details = BasicRoomDetails {
1033+ room_id : room_id. clone ( ) . into ( ) ,
1034+ room_name : known_room. name ( ) ,
1035+ room_avatar : RoomPreviewAvatar :: default ( ) ,
1036+ } ;
1037+
1038+ cx. widget_action ( room_screen_widget_uid, & scope. path , JoinLeaveRoomModalAction :: Open (
1039+ JoinLeaveModalKind :: JoinRoom ( room_details)
1040+ ) ) ;
1041+ }
1042+ } else {
1043+ // Room was resolved but we don't have it locally - show join modal with basic info
1044+ use crate :: join_leave_room_modal:: { JoinLeaveRoomModalAction , JoinLeaveModalKind } ;
1045+ use crate :: room:: { BasicRoomDetails , RoomPreviewAvatar } ;
1046+ let room_details = BasicRoomDetails {
10161047 room_id : room_id. clone ( ) . into ( ) ,
1017- room_name : known_room. name ( )
1048+ room_name : None ,
1049+ room_avatar : RoomPreviewAvatar :: default ( ) ,
1050+ } ;
1051+ cx. widget_action ( room_screen_widget_uid, & scope. path , JoinLeaveRoomModalAction :: Open (
1052+ JoinLeaveModalKind :: JoinRoom ( room_details)
1053+ ) ) ;
1054+ }
1055+ }
1056+ }
1057+ ResolveRoomAliasAction :: Failed { requester_room_id, room_alias, error } => {
1058+ if requester_room_id == self_room_id {
1059+ error ! ( "Failed to resolve room alias {}: {:?}" , room_alias, error) ;
1060+ // Provide more helpful error messages based on the error type
1061+ let error_message = match error {
1062+ matrix_sdk:: Error :: Http ( http_error) => {
1063+ if http_error. to_string ( ) . contains ( "404" ) {
1064+ format ! ( "Room alias '{}' not found. It may have been deleted or never existed." , room_alias)
1065+ } else {
1066+ format ! ( "Network error while resolving '{}': {}" , room_alias, http_error)
1067+ }
10181068 }
1019- ) ) ;
1069+ _ => format ! ( "Could not resolve room alias: {}" , room_alias)
1070+ } ;
1071+ enqueue_popup_notification ( PopupItem {
1072+ message : error_message,
1073+ auto_dismissal_duration : Some ( 8.0 )
1074+ } ) ;
10201075 }
1021- } else {
1022- enqueue_popup_notification ( PopupItem {
1023- message : format ! ( "Found room {} but you are not joined to it yet." , room_id) ,
1024- auto_dismissal_duration : Some ( 3.0 )
1025- } ) ;
10261076 }
10271077 }
10281078 }
1029-
1030- if let Some ( ResolveRoomAliasAction :: Failed { requester_uid, room_alias, error } ) = action. downcast_ref ( ) {
1031- if * requester_uid == room_screen_widget_uid {
1032- error ! ( "Failed to resolve room alias {}: {:?}" , room_alias, error) ;
1033- enqueue_popup_notification ( PopupItem {
1034- message : format ! ( "Could not find room with alias: {}" , room_alias) ,
1035- auto_dismissal_duration : None
1036- } ) ;
1037- }
1038- }
10391079 }
10401080
10411081 /*
@@ -1813,60 +1853,95 @@ impl RoomScreen {
18131853 return true ;
18141854 }
18151855 if let Some ( known_room) = get_client ( ) . and_then ( |c| c. get_room ( room_id) ) {
1816- cx. widget_action ( uid, & Scope :: empty ( ) . path , RoomsListAction :: Selected (
1817- SelectedRoom :: JoinedRoom {
1856+ // Check if we're already joined to this room
1857+ if known_room. state ( ) == RoomState :: Joined {
1858+ cx. widget_action ( uid, & Scope :: empty ( ) . path , RoomsListAction :: Selected (
1859+ SelectedRoom :: JoinedRoom {
1860+ room_id : room_id. clone ( ) . into ( ) ,
1861+ room_name : known_room. name ( )
1862+ }
1863+ ) ) ;
1864+ } else {
1865+ // Room exists but we're not joined - show join modal
1866+ use crate :: join_leave_room_modal:: { JoinLeaveRoomModalAction , JoinLeaveModalKind } ;
1867+ use crate :: room:: { BasicRoomDetails , RoomPreviewAvatar } ;
1868+
1869+ let room_details = BasicRoomDetails {
18181870 room_id : room_id. clone ( ) . into ( ) ,
1819- room_name : known_room. name ( )
1820- }
1821- ) ) ;
1871+ room_name : known_room. name ( ) ,
1872+ room_avatar : RoomPreviewAvatar :: default ( ) ,
1873+ } ;
1874+
1875+ cx. widget_action ( uid, & Scope :: empty ( ) . path , JoinLeaveRoomModalAction :: Open (
1876+ JoinLeaveModalKind :: JoinRoom ( room_details)
1877+ ) ) ;
1878+ }
18221879 } else {
1823- // TODO: fetch and display a room preview for the given room ID.
1880+ // Room doesn't exist locally - show informative message
18241881 enqueue_popup_notification ( PopupItem {
1825- message : "You are not joined to this room yet." . into ( ) ,
1882+ message : format ! ( "Room {} not found. You may need to join it first." , room_id ) ,
18261883 auto_dismissal_duration : Some ( 3.0 )
18271884 } ) ;
18281885 }
18291886 true
18301887 }
18311888 MatrixId :: RoomAlias ( room_alias) => {
1832- // Check if we already have this room alias in the client
1833- if let Some ( known_room) = get_client ( ) . and_then ( |c| {
1834- c. rooms ( ) . into_iter ( ) . find ( |room| {
1835- room. canonical_alias ( ) . as_ref ( ) == Some ( room_alias) ||
1836- room. alt_aliases ( ) . contains ( room_alias)
1837- } )
1838- } ) {
1839- let room_id = known_room. room_id ( ) ;
1840- if self . room_id . as_ref ( ) == Some ( & room_id. to_owned ( ) ) {
1889+ submit_async_request ( MatrixRequest :: ResolveRoomAlias {
1890+ requester_room_id : self . room_id . clone ( ) . unwrap ( ) ,
1891+ room_alias : room_alias. clone ( )
1892+ } ) ;
1893+ true
1894+ }
1895+ MatrixId :: Event ( room_or_alias_id, event_id) => {
1896+ log ! ( "Attempting to navigate to event {} in room {}" , event_id, room_or_alias_id) ;
1897+ // Check if room_or_alias_id is a room ID (not an alias)
1898+ if room_or_alias_id. is_room_id ( ) {
1899+ // Convert to RoomId for get_room() call
1900+ use matrix_sdk:: ruma:: RoomId ;
1901+ if let Ok ( room_id) = RoomId :: parse ( room_or_alias_id. as_str ( ) ) {
1902+ // First check if we have the room
1903+ if let Some ( known_room) = get_client ( ) . and_then ( |c| c. get_room ( & room_id) ) {
1904+ if known_room. state ( ) == RoomState :: Joined {
1905+ // If we're joined to the room, try to navigate to it first
1906+ cx. widget_action ( uid, & Scope :: empty ( ) . path , RoomsListAction :: Selected (
1907+ SelectedRoom :: JoinedRoom {
1908+ room_id : room_id. to_owned ( ) . into ( ) ,
1909+ room_name : known_room. name ( )
1910+ }
1911+ ) ) ;
1912+ // TODO: After navigating to the room, scroll to the specific event
1913+ // This would require calling Room::event_with_context() to get the event
1914+ // and its context (surrounding events), then scrolling to it
1915+ enqueue_popup_notification ( PopupItem {
1916+ message : format ! ( "Navigated to room. Event navigation not yet implemented." ) ,
1917+ auto_dismissal_duration : Some ( 3.0 )
1918+ } ) ;
1919+ } else {
1920+ enqueue_popup_notification ( PopupItem {
1921+ message : format ! ( "Cannot view event: you are not joined to room {}" , room_id) ,
1922+ auto_dismissal_duration : Some ( 5.0 )
1923+ } ) ;
1924+ }
1925+ } else {
1926+ enqueue_popup_notification ( PopupItem {
1927+ message : format ! ( "Cannot view event: room {} not found" , room_id) ,
1928+ auto_dismissal_duration : Some ( 5.0 )
1929+ } ) ;
1930+ }
1931+ } else {
18411932 enqueue_popup_notification ( PopupItem {
1842- message : "You are already viewing that room." . into ( ) ,
1843- auto_dismissal_duration : Some ( 3 .0)
1933+ message : format ! ( "Cannot parse room ID: {}" , room_or_alias_id ) ,
1934+ auto_dismissal_duration : Some ( 5 .0)
18441935 } ) ;
1845- } else {
1846- cx. widget_action ( uid, & Scope :: empty ( ) . path , RoomsListAction :: Selected (
1847- SelectedRoom :: JoinedRoom {
1848- room_id : room_id. to_owned ( ) . into ( ) ,
1849- room_name : known_room. name ( )
1850- }
1851- ) ) ;
18521936 }
1853- return true ;
1937+ } else {
1938+ enqueue_popup_notification ( PopupItem {
1939+ message : format ! ( "Event navigation with room aliases not yet supported: {}" , room_or_alias_id) ,
1940+ auto_dismissal_duration : Some ( 5.0 )
1941+ } ) ;
18541942 }
1855- // TODO: open a room loading screen that shows a spinner.
1856- // Submit async request to resolve the room alias
1857- submit_async_request ( MatrixRequest :: ResolveRoomAlias {
1858- room_alias : room_alias. clone ( ) ,
1859- requester_uid : uid,
1860- } ) ;
18611943 true
18621944 }
1863- MatrixId :: Event ( room_id, event_id) => {
1864- log ! ( "TODO: open event {} in room {}" , event_id, room_id) ;
1865- // TODO: this requires the same first step as the `MatrixId::Room` case above,
1866- // but then we need to call Room::event_with_context() to get the event
1867- // and its context (surrounding events ?).
1868- false
1869- }
18701945 _ => false ,
18711946 }
18721947 } ;
0 commit comments