Skip to content

Commit 612a10e

Browse files
Fix room name display issues for invited rooms and newly joined rooms
This PR addresses room name display issues in three scenarios: 1. Room invitations showing "Empty Room" instead of actual names 2. Tombstoned room replacements not showing correct names without restart 3. Rooms joined from other clients not displaying names correctly Root cause: The comparison logic in `update_room()` was comparing references to SDK's internal state rather than cached snapshots, causing UI updates to be skipped when room names changed. Key changes: - Use `RoomDisplayName` enum instead of `Option<String>` for type safety - Properly preserve `EmptyWas` variant to maintain previous name semantics - Implement name fallback order: canonical_alias → alt_alias → room_id - Update invited room display list when names change - Store and compare cached display names to detect all changes - Only send updates when names actually change (not on every event) Addresses all review comments from #590. Signed-off-by: Alvin <[email protected]>
1 parent e0b96bf commit 612a10e

File tree

6 files changed

+179
-38
lines changed

6 files changed

+179
-38
lines changed

src/home/invite_screen.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::ops::Deref;
88
use makepad_widgets::*;
99
use matrix_sdk::ruma::OwnedRoomId;
1010

11-
use crate::{app::AppStateAction, home::rooms_list::RoomsListRef, join_leave_room_modal::{JoinLeaveModalKind, JoinLeaveRoomModalAction}, room::{BasicRoomDetails, RoomPreviewAvatar}, shared::{avatar::AvatarWidgetRefExt, popup_list::{enqueue_popup_notification, PopupItem, PopupKind}, restore_status_view::RestoreStatusViewWidgetExt}, sliding_sync::{submit_async_request, MatrixRequest}, utils::{self, room_name_or_id}};
11+
use crate::{app::AppStateAction, home::rooms_list::RoomsListRef, join_leave_room_modal::{JoinLeaveModalKind, JoinLeaveRoomModalAction}, room::{BasicRoomDetails, RoomPreviewAvatar}, shared::{avatar::AvatarWidgetRefExt, popup_list::{enqueue_popup_notification, PopupItem, PopupKind}, restore_status_view::RestoreStatusViewWidgetExt}, sliding_sync::{submit_async_request, MatrixRequest}, utils::{self, display_name_with_fallback, room_name_or_id}};
1212

1313
use super::rooms_list::{InviteState, InviterInfo};
1414

@@ -527,7 +527,12 @@ impl InviteScreen {
527527
self.info = Some(InviteDetails {
528528
room_info: BasicRoomDetails {
529529
room_id: room_id.clone(),
530-
room_name: invite.room_name.clone(),
530+
room_name: Some(display_name_with_fallback(
531+
&invite.room_name,
532+
invite.canonical_alias.as_ref(),
533+
&invite.alt_aliases,
534+
&invite.room_id,
535+
)),
531536
room_avatar: invite.room_avatar.clone(),
532537
},
533538
inviter: invite.inviter_info.clone(),

src/home/room_preview.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::{
55
room::RoomPreviewAvatar, shared::{
66
avatar::AvatarWidgetExt,
77
html_or_plaintext::HtmlOrPlaintextWidgetExt, unread_badge::UnreadBadgeWidgetExt as _,
8-
}, utils::{self, relative_format}
8+
}, utils::{self, display_name_with_fallback, relative_format}
99
};
1010

1111
use super::rooms_list::{InvitedRoomInfo, InviterInfo, JoinedRoomInfo, RoomsListScopeProps};
@@ -296,9 +296,13 @@ impl RoomPreviewContent {
296296
cx: &mut Cx,
297297
room_info: &JoinedRoomInfo,
298298
) {
299-
if let Some(ref name) = room_info.room_name {
300-
self.view.label(id!(room_name)).set_text(cx, name);
301-
}
299+
let display_name = display_name_with_fallback(
300+
&room_info.room_name,
301+
room_info.canonical_alias.as_ref(),
302+
&room_info.alt_aliases,
303+
&room_info.room_id,
304+
);
305+
self.view.label(id!(room_name)).set_text(cx, &display_name);
302306
if let Some((ts, msg)) = room_info.latest.as_ref() {
303307
if let Some(human_readable_date) = relative_format(*ts) {
304308
self.view
@@ -324,11 +328,13 @@ impl RoomPreviewContent {
324328
cx: &mut Cx,
325329
room_info: &InvitedRoomInfo,
326330
) {
327-
self.view.label(id!(room_name)).set_text(
328-
cx,
329-
room_info.room_name.as_deref()
330-
.unwrap_or("Invite to unnamed room"),
331+
let display_name = display_name_with_fallback(
332+
&room_info.room_name,
333+
room_info.canonical_alias.as_ref(),
334+
&room_info.alt_aliases,
335+
&room_info.room_id,
331336
);
337+
self.view.label(id!(room_name)).set_text(cx, &display_name);
332338
// Hide the timestamp field, and use the latest message field to show the inviter.
333339
self.view.label(id!(timestamp)).set_text(cx, "");
334340
let inviter_string = match &room_info.inviter_info {

src/home/rooms_list.rs

Lines changed: 86 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use std::{cell::RefCell, collections::HashMap, rc::Rc, sync::Arc};
22
use crossbeam_queue::SegQueue;
33
use makepad_widgets::*;
4-
use matrix_sdk::{ruma::{events::tag::Tags, MilliSecondsSinceUnixEpoch, OwnedRoomAliasId, OwnedRoomId, OwnedUserId}, RoomState};
4+
use matrix_sdk::{RoomDisplayName, ruma::{events::tag::Tags, MilliSecondsSinceUnixEpoch, OwnedRoomAliasId, OwnedRoomId, OwnedUserId}, RoomState};
55
use crate::{
66
app::{AppState, SelectedRoom},
77
room::{room_display_filter::{RoomDisplayFilter, RoomDisplayFilterBuilder, RoomFilterCriteria, SortFn}, RoomPreviewAvatar},
88
shared::{collapsible_header::{CollapsibleHeaderAction, CollapsibleHeaderWidgetRefExt, HeaderCategory}, jump_to_bottom_button::UnreadMessageCount, popup_list::{enqueue_popup_notification, PopupItem, PopupKind}, room_filter_input_bar::RoomFilterAction},
9-
sliding_sync::{submit_async_request, MatrixRequest, PaginationDirection}, utils::room_name_or_id,
9+
sliding_sync::{submit_async_request, MatrixRequest, PaginationDirection}, utils::display_name_with_fallback,
1010
};
1111
use super::room_preview::RoomPreviewAction;
1212

@@ -132,7 +132,7 @@ pub enum RoomsListUpdate {
132132
/// Update the displayable name for the given room.
133133
UpdateRoomName {
134134
room_id: OwnedRoomId,
135-
new_room_name: Option<String>,
135+
new_room_name: RoomDisplayName,
136136
},
137137
/// Update the avatar (image) for the given room.
138138
UpdateRoomAvatar {
@@ -201,7 +201,7 @@ pub struct JoinedRoomInfo {
201201
/// The matrix ID of this room.
202202
pub room_id: OwnedRoomId,
203203
/// The displayable name of this room, if known.
204-
pub room_name: Option<String>,
204+
pub room_name: RoomDisplayName,
205205
/// The number of unread messages in this room.
206206
pub num_unread_messages: u64,
207207
/// The number of unread mentions in this room.
@@ -240,7 +240,7 @@ pub struct InvitedRoomInfo {
240240
/// The matrix ID of this room.
241241
pub room_id: OwnedRoomId,
242242
/// The displayable name of this room, if known.
243-
pub room_name: Option<String>,
243+
pub room_name: RoomDisplayName,
244244
/// The canonical alias for this room, if any.
245245
pub canonical_alias: Option<OwnedRoomAliasId>,
246246
/// The alternative aliases for this room, if any.
@@ -399,7 +399,6 @@ impl RoomsList {
399399
RoomsListUpdate::AddJoinedRoom(joined_room) => {
400400
let room_id = joined_room.room_id.clone();
401401
let is_direct = joined_room.is_direct;
402-
let room_name = joined_room.room_name.clone();
403402
let should_display = (self.display_filter)(&joined_room);
404403
let replaced = self.all_joined_rooms.insert(room_id.clone(), joined_room);
405404
if replaced.is_none() {
@@ -425,10 +424,19 @@ impl RoomsList {
425424
self.displayed_invited_rooms.iter()
426425
.position(|r| r == &room_id)
427426
.map(|index| self.displayed_invited_rooms.remove(index));
427+
let new_room_name = self.all_joined_rooms.get(&room_id).map(|room| display_name_with_fallback(
428+
&room.room_name,
429+
room.canonical_alias.as_ref(),
430+
&room.alt_aliases,
431+
&room.room_id,
432+
));
428433
cx.widget_action(
429434
self.widget_uid(),
430435
&scope.path,
431-
RoomsListAction::InviteAccepted { room_id, room_name }
436+
RoomsListAction::InviteAccepted {
437+
room_id: room_id.clone(),
438+
room_name: new_room_name,
439+
}
432440
);
433441
}
434442
self.update_status_rooms_count();
@@ -460,9 +468,11 @@ impl RoomsList {
460468
}
461469
}
462470
RoomsListUpdate::UpdateRoomName { room_id, new_room_name } => {
471+
// Try to update joined room first
463472
if let Some(room) = self.all_joined_rooms.get_mut(&room_id) {
464473
let was_displayed = (self.display_filter)(room);
465-
room.room_name = new_room_name;
474+
// Keep the full RoomDisplayName to preserve EmptyWas semantics
475+
room.room_name = new_room_name.clone();
466476
let should_display = (self.display_filter)(room);
467477
match (was_displayed, should_display) {
468478
// No need to update the displayed rooms list.
@@ -482,24 +492,53 @@ impl RoomsList {
482492
// Room was not displayed but should now be displayed.
483493
(false, true) => {
484494
if room.is_direct {
485-
self.displayed_direct_rooms.push(room_id);
495+
self.displayed_direct_rooms.push(room_id.clone());
486496
} else {
487-
self.displayed_regular_rooms.push(room_id);
497+
self.displayed_regular_rooms.push(room_id.clone());
488498
}
489499
}
490500
}
491-
} else {
492-
error!("Error: couldn't find room {room_id} to update room name");
501+
}
502+
// If not a joined room, try to update invited room
503+
else {
504+
let invited_rooms_ref = get_invited_rooms(cx);
505+
let mut invited_rooms = invited_rooms_ref.borrow_mut();
506+
if let Some(invited_room) = invited_rooms.get_mut(&room_id) {
507+
let was_displayed = (self.display_filter)(invited_room);
508+
invited_room.room_name = new_room_name;
509+
let should_display = (self.display_filter)(invited_room);
510+
match (was_displayed, should_display) {
511+
(true, true) | (false, false) => { }
512+
(true, false) => {
513+
self.displayed_invited_rooms.iter()
514+
.position(|r| r == &room_id)
515+
.map(|index| self.displayed_invited_rooms.remove(index));
516+
}
517+
(false, true) => {
518+
if !self.displayed_invited_rooms.contains(&room_id) {
519+
self.displayed_invited_rooms.push(room_id.clone());
520+
}
521+
}
522+
}
523+
} else {
524+
warning!("Warning: couldn't find invited room {} to update room name", room_id);
525+
}
493526
}
494527
}
495528
RoomsListUpdate::UpdateIsDirect { room_id, is_direct } => {
496529
if let Some(room) = self.all_joined_rooms.get_mut(&room_id) {
497530
if room.is_direct == is_direct {
498531
continue;
499532
}
533+
let room_name_text = display_name_with_fallback(
534+
&room.room_name,
535+
room.canonical_alias.as_ref(),
536+
&room.alt_aliases,
537+
&room.room_id,
538+
);
500539
enqueue_popup_notification(PopupItem {
501540
message: format!("{} was changed from {} to {}.",
502-
room_name_or_id(room.room_name.as_ref(), &room_id),
541+
room_name_text,
503542
if room.is_direct { "direct" } else { "regular" },
504543
if is_direct { "direct" } else { "regular" }
505544
),
@@ -832,10 +871,30 @@ impl RoomsList {
832871
/// Returns a room's avatar and displayable name.
833872
pub fn get_room_avatar_and_name(&self, room_id: &OwnedRoomId) -> Option<(RoomPreviewAvatar, Option<String>)> {
834873
self.all_joined_rooms.get(room_id)
835-
.map(|room_info| (room_info.avatar.clone(), room_info.room_name.clone()))
874+
.map(|room_info| {
875+
(
876+
room_info.avatar.clone(),
877+
Some(display_name_with_fallback(
878+
&room_info.room_name,
879+
room_info.canonical_alias.as_ref(),
880+
&room_info.alt_aliases,
881+
&room_info.room_id,
882+
)),
883+
)
884+
})
836885
.or_else(|| {
837886
self.invited_rooms.borrow().get(room_id)
838-
.map(|room_info| (room_info.room_avatar.clone(), room_info.room_name.clone()))
887+
.map(|room_info| {
888+
(
889+
room_info.room_avatar.clone(),
890+
Some(display_name_with_fallback(
891+
&room_info.room_name,
892+
room_info.canonical_alias.as_ref(),
893+
&room_info.alt_aliases,
894+
&room_info.room_id,
895+
)),
896+
)
897+
})
839898
})
840899
}
841900
}
@@ -860,12 +919,22 @@ impl Widget for RoomsList {
860919
let new_selected_room = if let Some(jr) = self.all_joined_rooms.get(&clicked_room_id) {
861920
SelectedRoom::JoinedRoom {
862921
room_id: jr.room_id.clone().into(),
863-
room_name: jr.room_name.clone(),
922+
room_name: Some(display_name_with_fallback(
923+
&jr.room_name,
924+
jr.canonical_alias.as_ref(),
925+
&jr.alt_aliases,
926+
&jr.room_id,
927+
)),
864928
}
865929
} else if let Some(ir) = self.invited_rooms.borrow().get(&clicked_room_id) {
866930
SelectedRoom::InvitedRoom {
867931
room_id: ir.room_id.to_owned().into(),
868-
room_name: ir.room_name.clone(),
932+
room_name: Some(display_name_with_fallback(
933+
&ir.room_name,
934+
ir.canonical_alias.as_ref(),
935+
&ir.alt_aliases,
936+
&ir.room_id,
937+
)),
869938
}
870939
} else {
871940
error!("BUG: couldn't find clicked room details for room {clicked_room_id}");

src/room/room_display_filter.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use matrix_sdk::ruma::{
77
OwnedRoomAliasId, RoomAliasId, RoomId,
88
};
99

10-
use crate::home::rooms_list::{InvitedRoomInfo, JoinedRoomInfo};
10+
use crate::{home::rooms_list::{InvitedRoomInfo, JoinedRoomInfo}, utils::display_name_with_fallback};
1111

1212
static EMPTY_TAGS: Tags = BTreeMap::new();
1313

@@ -29,7 +29,12 @@ impl FilterableRoom for JoinedRoomInfo {
2929
}
3030

3131
fn room_name(&self) -> Cow<'_, str> {
32-
self.room_name.as_deref().map(Into::into).unwrap_or_default()
32+
Cow::Owned(display_name_with_fallback(
33+
&self.room_name,
34+
self.canonical_alias.as_ref(),
35+
&self.alt_aliases,
36+
&self.room_id,
37+
))
3338
}
3439

3540
fn unread_mentions(&self) -> u64 {
@@ -63,7 +68,12 @@ impl FilterableRoom for InvitedRoomInfo {
6368
}
6469

6570
fn room_name(&self) -> Cow<'_, str> {
66-
self.room_name.as_deref().map(Into::into).unwrap_or_default()
71+
Cow::Owned(display_name_with_fallback(
72+
&self.room_name,
73+
self.canonical_alias.as_ref(),
74+
&self.alt_aliases,
75+
&self.room_id,
76+
))
6777
}
6878

6979
fn unread_mentions(&self) -> u64 {

src/sliding_sync.rs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ use crate::{
4848
jump_to_bottom_button::UnreadMessageCount,
4949
popup_list::{enqueue_popup_notification, PopupItem, PopupKind}
5050
},
51-
utils::{self, avatar_from_room_name, AVATAR_THUMBNAIL_FORMAT},
51+
utils::{self, avatar_from_room_name, preferred_room_name, AVATAR_THUMBNAIL_FORMAT},
5252
verification::add_verification_event_handlers_and_sync_client
5353
};
5454

@@ -2167,9 +2167,15 @@ async fn update_room(
21672167
}
21682168
if old_room.display_name != new_room.display_name {
21692169
log!("Updating room {} name: {:?} --> {:?}", new_room_id, old_room.display_name, new_room.display_name);
2170+
2171+
let new_name = new_room
2172+
.display_name
2173+
.clone()
2174+
.unwrap_or(RoomDisplayName::Empty);
2175+
21702176
enqueue_rooms_list_update(RoomsListUpdate::UpdateRoomName {
21712177
room_id: new_room_id.clone(),
2172-
new_room_name: new_room.display_name.as_ref().map(|n| n.to_string()),
2178+
new_room_name: new_name,
21732179
});
21742180
}
21752181

@@ -2328,8 +2334,12 @@ async fn add_new_room(
23282334
let latest = latest_event.as_ref().map(
23292335
|ev| get_latest_event_details(ev, &new_room.room_id)
23302336
);
2331-
let room_name = new_room.display_name.as_ref().map(|n| n.to_string());
2332-
let room_avatar = room_avatar(&new_room.room, room_name.as_deref()).await;
2337+
let room_display_name = new_room
2338+
.display_name
2339+
.clone()
2340+
.unwrap_or(RoomDisplayName::Empty);
2341+
let room_name_text = preferred_room_name(&room_display_name);
2342+
let room_avatar = room_avatar(&new_room.room, room_name_text.as_deref()).await;
23332343

23342344
let inviter_info = if let Some(inviter) = invite_details.and_then(|d| d.inviter) {
23352345
Some(InviterInfo {
@@ -2347,7 +2357,7 @@ async fn add_new_room(
23472357
};
23482358
rooms_list::enqueue_rooms_list_update(RoomsListUpdate::AddInvitedRoom(InvitedRoomInfo {
23492359
room_id: new_room.room_id.clone(),
2350-
room_name,
2360+
room_name: room_display_name,
23512361
inviter_info,
23522362
room_avatar,
23532363
canonical_alias: new_room.room.canonical_alias(),
@@ -2406,7 +2416,11 @@ async fn add_new_room(
24062416
// We need to add the room to the `ALL_JOINED_ROOMS` list before we can
24072417
// send the `AddJoinedRoom` update to the UI, because the UI might immediately
24082418
// issue a `MatrixRequest` that relies on that room being in `ALL_JOINED_ROOMS`.
2409-
let room_name = new_room.display_name.as_ref().map(|n| n.to_string());
2419+
let room_display_name = new_room
2420+
.display_name
2421+
.clone()
2422+
.unwrap_or(RoomDisplayName::Empty);
2423+
let room_name = preferred_room_name(&room_display_name);
24102424
rooms_list::enqueue_rooms_list_update(RoomsListUpdate::AddJoinedRoom(JoinedRoomInfo {
24112425
room_id: new_room.room_id.clone(),
24122426
latest,
@@ -2415,7 +2429,7 @@ async fn add_new_room(
24152429
num_unread_mentions: new_room.num_unread_mentions,
24162430
// start with a basic text avatar; the avatar image will be fetched asynchronously below.
24172431
avatar: avatar_from_room_name(room_name.as_deref()),
2418-
room_name,
2432+
room_name: room_display_name,
24192433
canonical_alias: new_room.room.canonical_alias(),
24202434
alt_aliases: new_room.room.alt_aliases(),
24212435
has_been_paginated: false,

0 commit comments

Comments
 (0)