@@ -19,14 +19,15 @@ use matrix_sdk_ui::timeline::{
19
19
} ;
20
20
21
21
use crate :: {
22
- app:: RoomsPanelRestoreAction , avatar_cache, event_preview:: { plaintext_body_of_timeline_item, text_preview_of_encrypted_message, text_preview_of_member_profile_change, text_preview_of_other_state, text_preview_of_redacted_message, text_preview_of_room_membership_change, text_preview_of_timeline_item} , home:: { edited_indicator:: EditedIndicatorWidgetRefExt , editing_pane:: EditingPaneState , loading_pane:: { LoadingPaneState , LoadingPaneWidgetExt } , rooms_list:: RoomsListRef } , location:: init_location_subscriber, media_cache:: { MediaCache , MediaCacheEntry } , profile:: {
22
+ app:: { RoomsPanelRestoreAction , SelectedRoom } , avatar_cache, event_preview:: { plaintext_body_of_timeline_item, text_preview_of_encrypted_message, text_preview_of_member_profile_change, text_preview_of_other_state, text_preview_of_redacted_message, text_preview_of_room_membership_change, text_preview_of_timeline_item} , home:: { edited_indicator:: EditedIndicatorWidgetRefExt , editing_pane:: EditingPaneState , loading_pane:: { LoadingPaneState , LoadingPaneWidgetExt } , rooms_list:: { RoomsListAction , RoomsListRef } } , location:: init_location_subscriber, media_cache:: { MediaCache , MediaCacheEntry } , profile:: {
23
23
user_profile:: { AvatarState , ShowUserProfileAction , UserProfile , UserProfileAndRoomId , UserProfilePaneInfo , UserProfileSlidingPaneRef , UserProfileSlidingPaneWidgetExt } ,
24
24
user_profile_cache,
25
25
} , shared:: {
26
26
avatar:: AvatarWidgetRefExt , callout_tooltip:: TooltipAction , html_or_plaintext:: { HtmlOrPlaintextRef , HtmlOrPlaintextWidgetRefExt , RobrixHtmlLinkAction } , jump_to_bottom_button:: { JumpToBottomButtonWidgetExt , UnreadMessageCount } , popup_list:: { enqueue_popup_notification, PopupItem } , styles:: COLOR_DANGER_RED , text_or_image:: { TextOrImageRef , TextOrImageWidgetRefExt } , timestamp:: TimestampWidgetRefExt , typing_animation:: TypingAnimationWidgetExt
27
27
} , sliding_sync:: { get_client, submit_async_request, take_timeline_endpoints, BackwardsPaginateUntilEventRequest , MatrixRequest , PaginationDirection , TimelineRequestSender , UserPowerLevels } , utils:: { self , room_name_or_id, unix_time_millis_to_datetime, ImageFormat , MEDIA_THUMBNAIL_FORMAT }
28
28
} ;
29
29
use crate :: home:: event_reaction_list:: ReactionListWidgetRefExt ;
30
+ use crate :: room:: ResolveRoomAliasAction ;
30
31
use crate :: home:: room_read_receipt:: AvatarRowWidgetRefExt ;
31
32
use crate :: room:: room_input_bar:: RoomInputBarWidgetExt ;
32
33
use crate :: shared:: mentionable_text_input:: MentionableTextInputWidgetRefExt ;
@@ -995,6 +996,43 @@ impl Widget for RoomScreen {
995
996
) ;
996
997
}
997
998
}
999
+
1000
+ // Handle resolved room alias actions - only for requests from this widget
1001
+ if let Some ( ResolveRoomAliasAction :: Resolved { requester_uid, room_alias : _ , room_id, servers : _ } ) = action. downcast_ref ( ) {
1002
+ // Only handle this action if it was requested by this widget
1003
+ if * requester_uid == room_screen_widget_uid {
1004
+ if let Some ( known_room) = get_client ( ) . and_then ( |c| c. get_room ( room_id) ) {
1005
+ if known_room. is_space ( ) {
1006
+ enqueue_popup_notification ( PopupItem {
1007
+ message : format ! ( "Found space {} but it is a space, not a regular room." , room_id) ,
1008
+ auto_dismissal_duration : Some ( 3.0 )
1009
+ } ) ;
1010
+ } else {
1011
+ cx. widget_action ( room_screen_widget_uid, & scope. path , RoomsListAction :: Selected (
1012
+ SelectedRoom :: JoinedRoom {
1013
+ room_id : room_id. clone ( ) . into ( ) ,
1014
+ room_name : known_room. name ( )
1015
+ }
1016
+ ) ) ;
1017
+ }
1018
+ } else {
1019
+ enqueue_popup_notification ( PopupItem {
1020
+ message : format ! ( "Found room {} but you are not joined to it yet." , room_id) ,
1021
+ auto_dismissal_duration : Some ( 3.0 )
1022
+ } ) ;
1023
+ }
1024
+ }
1025
+ }
1026
+
1027
+ if let Some ( ResolveRoomAliasAction :: Failed { requester_uid, room_alias, error } ) = action. downcast_ref ( ) {
1028
+ if * requester_uid == room_screen_widget_uid {
1029
+ error ! ( "Failed to resolve room alias {}: {:?}" , room_alias, error) ;
1030
+ enqueue_popup_notification ( PopupItem {
1031
+ message : format ! ( "Could not find room with alias: {}" , room_alias) ,
1032
+ auto_dismissal_duration : None
1033
+ } ) ;
1034
+ }
1035
+ }
998
1036
}
999
1037
1000
1038
/*
@@ -1731,6 +1769,7 @@ impl RoomScreen {
1731
1769
action : & Action ,
1732
1770
pane : & UserProfileSlidingPaneRef ,
1733
1771
) -> bool {
1772
+ let uid = self . widget_uid ( ) ;
1734
1773
// A closure that handles both MatrixToUri and MatrixUri links,
1735
1774
// and returns whether the link was handled.
1736
1775
let mut handle_matrix_link = |id : & MatrixId , _via : & [ OwnedServerName ] | -> bool {
@@ -1763,26 +1802,59 @@ impl RoomScreen {
1763
1802
}
1764
1803
MatrixId :: Room ( room_id) => {
1765
1804
if self . room_id . as_ref ( ) == Some ( room_id) {
1766
- enqueue_popup_notification ( PopupItem {
1767
- message : "You are already viewing that room." . into ( ) ,
1768
- auto_dismissal_duration : None
1805
+ enqueue_popup_notification ( PopupItem {
1806
+ message : "You are already viewing that room." . into ( ) ,
1807
+ auto_dismissal_duration : Some ( 3.0 )
1769
1808
} ) ;
1770
1809
return true ;
1771
1810
}
1772
- if let Some ( _known_room) = get_client ( ) . and_then ( |c| c. get_room ( room_id) ) {
1773
- log ! ( "TODO: jump to known room {}" , room_id) ;
1811
+ if let Some ( known_room) = get_client ( ) . and_then ( |c| c. get_room ( room_id) ) {
1812
+ cx. widget_action ( uid, & Scope :: empty ( ) . path , RoomsListAction :: Selected (
1813
+ SelectedRoom :: JoinedRoom {
1814
+ room_id : room_id. clone ( ) . into ( ) ,
1815
+ room_name : known_room. name ( )
1816
+ }
1817
+ ) ) ;
1774
1818
} else {
1775
- log ! ( "TODO: fetch and display room preview for room {}" , room_id) ;
1819
+ // TODO: fetch and display a room preview for the given room ID.
1820
+ enqueue_popup_notification ( PopupItem {
1821
+ message : "You are not joined to this room yet." . into ( ) ,
1822
+ auto_dismissal_duration : Some ( 3.0 )
1823
+ } ) ;
1776
1824
}
1777
- false
1825
+ true
1778
1826
}
1779
1827
MatrixId :: RoomAlias ( room_alias) => {
1780
- log ! ( "TODO: open room alias {}" , room_alias) ;
1781
- // TODO: open a room loading screen that shows a spinner
1782
- // while our background async task calls Client::resolve_room_alias()
1783
- // and then either jumps to the room if known, or fetches and displays
1784
- // a room preview for that room.
1785
- false
1828
+ // Check if we already have this room alias in the client
1829
+ if let Some ( known_room) = get_client ( ) . and_then ( |c| {
1830
+ c. rooms ( ) . into_iter ( ) . find ( |room| {
1831
+ room. canonical_alias ( ) . as_ref ( ) == Some ( room_alias) ||
1832
+ room. alt_aliases ( ) . contains ( room_alias)
1833
+ } )
1834
+ } ) {
1835
+ let room_id = known_room. room_id ( ) ;
1836
+ if self . room_id . as_ref ( ) == Some ( & room_id. to_owned ( ) ) {
1837
+ enqueue_popup_notification ( PopupItem {
1838
+ message : "You are already viewing that room." . into ( ) ,
1839
+ auto_dismissal_duration : Some ( 3.0 )
1840
+ } ) ;
1841
+ } else {
1842
+ cx. widget_action ( uid, & Scope :: empty ( ) . path , RoomsListAction :: Selected (
1843
+ SelectedRoom :: JoinedRoom {
1844
+ room_id : room_id. to_owned ( ) . into ( ) ,
1845
+ room_name : known_room. name ( )
1846
+ }
1847
+ ) ) ;
1848
+ }
1849
+ return true ;
1850
+ }
1851
+ // TODO: open a room loading screen that shows a spinner.
1852
+ // Submit async request to resolve the room alias
1853
+ submit_async_request ( MatrixRequest :: ResolveRoomAlias {
1854
+ room_alias : room_alias. clone ( ) ,
1855
+ requester_uid : uid,
1856
+ } ) ;
1857
+ true
1786
1858
}
1787
1859
MatrixId :: Event ( room_id, event_id) => {
1788
1860
log ! ( "TODO: open event {} in room {}" , event_id, room_id) ;
@@ -1795,15 +1867,10 @@ impl RoomScreen {
1795
1867
}
1796
1868
} ;
1797
1869
1798
- if let HtmlLinkAction :: Clicked { url, .. } = action. as_widget_action ( ) . cast ( ) {
1799
- let mut link_was_handled = false ;
1800
- if let Ok ( matrix_to_uri) = MatrixToUri :: parse ( & url) {
1801
- link_was_handled |= handle_matrix_link ( matrix_to_uri. id ( ) , matrix_to_uri. via ( ) ) ;
1802
- }
1803
- else if let Ok ( matrix_uri) = MatrixUri :: parse ( & url) {
1804
- link_was_handled |= handle_matrix_link ( matrix_uri. id ( ) , matrix_uri. via ( ) ) ;
1805
- }
1806
-
1870
+ // Prioritize handling RobrixHtmlLinkAction::ClickedMatrixLink over HtmlLinkAction::Clicked
1871
+ // to avoid duplicate processing of the same Matrix link
1872
+ if let RobrixHtmlLinkAction :: ClickedMatrixLink { url, matrix_id, via, .. } = action. as_widget_action ( ) . cast ( ) {
1873
+ let link_was_handled = handle_matrix_link ( & matrix_id, & via) ;
1807
1874
if !link_was_handled {
1808
1875
log ! ( "Opening URL \" {}\" " , url) ;
1809
1876
if let Err ( e) = robius_open:: Uri :: new ( & url) . open ( ) {
@@ -1816,8 +1883,15 @@ impl RoomScreen {
1816
1883
}
1817
1884
true
1818
1885
}
1819
- else if let RobrixHtmlLinkAction :: ClickedMatrixLink { url, matrix_id, via, .. } = action. as_widget_action ( ) . cast ( ) {
1820
- let link_was_handled = handle_matrix_link ( & matrix_id, & via) ;
1886
+ else if let HtmlLinkAction :: Clicked { url, .. } = action. as_widget_action ( ) . cast ( ) {
1887
+ let mut link_was_handled = false ;
1888
+ if let Ok ( matrix_to_uri) = MatrixToUri :: parse ( & url) {
1889
+ link_was_handled |= handle_matrix_link ( matrix_to_uri. id ( ) , matrix_to_uri. via ( ) ) ;
1890
+ }
1891
+ else if let Ok ( matrix_uri) = MatrixUri :: parse ( & url) {
1892
+ link_was_handled |= handle_matrix_link ( matrix_uri. id ( ) , matrix_uri. via ( ) ) ;
1893
+ }
1894
+
1821
1895
if !link_was_handled {
1822
1896
log ! ( "Opening URL \" {}\" " , url) ;
1823
1897
if let Err ( e) = robius_open:: Uri :: new ( & url) . open ( ) {
0 commit comments