Skip to content

Conversation

@TigerInYourDream
Copy link
Contributor

Bug Fix: Invited Room Names Not Displaying Correctly

Problem Description

When receiving room invitations in Robrix, the room names displayed as "Invite to unnamed room" instead of showing the actual room name (e.g., "room0", "room1").

Root Cause Analysis

1. Initial Problem: UpdateRoomName Not Handling Invited Rooms

The RoomsListUpdate::UpdateRoomName handler only searched in all_joined_rooms, but invited rooms are stored in a separate collection invited_rooms.

Location: src/home/rooms_list.rs:458-492

RoomsListUpdate::UpdateRoomName { room_id, new_room_name } => {
    if let Some(room) = self.all_joined_rooms.get_mut(&room_id) {
        // Updates joined room name
    }
    // ❌ Missing: check invited_rooms
}

2. Matrix Protocol Background: "Empty Room" Placeholder

According to the Matrix Client-Server API Specification:

Calculating Room Display Names:

If the room has an m.room.name state event, use the name given by that event.

If the room has an m.room.canonical_alias state event, use the alias given by that event.

If neither of the above events are present, a name should be composed based on the members of the room.

A complete absence of m.room.name, m.room.canonical_alias, and m.room.member events is likely to indicate a problem with creating the room or synchronising the state table; however clients should still handle this situation. A display name such as "Empty Room" (or a localised variant thereof) should be used in this situation.

The Matrix Rust SDK implements this specification in Room::display_name() and returns "Empty Room" as a placeholder when no room information is available yet.

3. Timing Issue with Sliding Sync

For invited rooms, there's a timing sequence:

  1. Initial sync: Robrix receives basic invitation info via sliding sync

    • At this point, room state events haven't been synchronized yet
    • room.display_name() returns Some("Empty Room") (Matrix SDK's placeholder)
  2. Subscription: We call room_list_service.subscribe_to_rooms(&[&room_id])

    • The SDK starts fetching complete room state
  3. State events arrive: Room name, alias, and member information arrive

    • room.display_name() updates to return the actual room name
    • update_room() is called with the new name

4. SDK Internal Architecture Issue

The RoomListServiceRoomInfo struct stores a reference to the SDK's Room object:

struct RoomListServiceRoomInfo {
    room: matrix_sdk::Room,  // ← Reference to SDK's internal Arc<RoomInfo>
}

When update_room() is called:

let old_cached_name = old_room.room.cached_display_name();  // ← Already updated!
let new_cached_name = new_room.cached_display_name();       // ← Same value!

Both old_room.room and new_room reference the same internal object in the Matrix SDK (via Arc), so cached_display_name() always returns the latest value, making it impossible to detect changes using this approach.

Solution

Change 1: Handle Invited Rooms in UpdateRoomName Handler

File: src/home/rooms_list.rs

RoomsListUpdate::UpdateRoomName { room_id, new_room_name } => {
    if let Some(room) = self.all_joined_rooms.get_mut(&room_id) {
        room.room_name = Some(new_room_name);
        self.redraw(cx);
    } else if let Some(invited_room) = self.invited_rooms.borrow_mut().get_mut(&room_id) {
        // ✅ Added: handle invited rooms
        invited_room.room_name = Some(new_room_name);
    } else {
        error!("Error: couldn't find room {room_id} to update room name");
    }
}

Change 2: Subscribe to Invited Rooms for State Updates

File: src/sliding_sync.rs:2116

RoomState::Invited => {
    // ... existing code ...

    // ✅ Added: Subscribe to receive state updates (like room name changes)
    room_list_service.subscribe_to_rooms(&[&room_id]).await;

    // ... send AddInvitedRoom update ...
}

Change 3: Handle "Empty Room" Placeholder

File: src/sliding_sync.rs:2079-2085

RoomState::Invited => {
    // For invited rooms with "Empty Room" name, set it to None
    // so UI shows "Invite to unnamed room"
    // The name will be updated later when we receive room state events
    let room_name = if room_name.as_deref() == Some("Empty Room") {
        None  // ✅ Convert SDK placeholder to None for better UX
    } else {
        room_name
    };

    // ... rest of invitation handling ...
}

Rationale: "Empty Room" is a placeholder indicating missing data, not an actual room name. Displaying "Invite to unnamed room" provides better user experience while waiting for the real name to arrive.

Change 4: Special Handling for Invited Room Name Updates

File: src/sliding_sync.rs:1984-2003

if let Some(new_room_name) = new_room_name {
    let old_cached_name = old_room.room.cached_display_name().map(|n| n.to_string());

    // For invited rooms, always send update if the name is not "Empty Room"
    // because we might have initially set the name to None in add_new_room,
    // but the Matrix SDK's cached_display_name() already reflects the updated name
    // (since old_room.room is a reference to SDK's internal object, not a snapshot).
    let should_update = if new_room_state == RoomState::Invited {
        new_room_name != "Empty Room"  // ✅ Skip placeholder, send real names
    } else {
        old_cached_name.as_ref() != Some(&new_room_name)
    };

    if should_update {
        enqueue_rooms_list_update(RoomsListUpdate::UpdateRoomName {
            room_id: new_room_id.clone(),
            new_room_name,
        });
    }
}

Trade-off: This may send duplicate updates (e.g., "room4" → "room4") during subsequent syncs. However, this is acceptable because:

  • The overhead is minimal (a few channel messages, ~100 bytes each)
  • It ensures the initial update is never skipped
  • UI frameworks typically handle redundant updates efficiently

Testing

Test Case 1: Fresh Invitation

  1. Start Robrix with clean database
  2. Send invitation for "testroom" from another client
  3. Expected: Robrix UI displays "testroom" (not "Invite to unnamed room")

Test Case 2: Restored Invitations

  1. Restart Robrix with existing invitations in database
  2. Expected: All invited rooms display correct names immediately

Test Results

✅ Tested with room0 through room9
✅ All room names display correctly
✅ No "Invite to unnamed room" for named rooms

Impact

Files Modified

  • src/home/rooms_list.rs (2 lines added)
  • src/sliding_sync.rs (multiple changes)

Behavior Changes

  • Before: Invited rooms always showed "Invite to unnamed room"
  • After: Invited rooms show actual room names within ~100ms of receiving invitation

Performance Impact

  • Minimal: Additional subscription per invited room
  • Small overhead: Possible duplicate name updates (acceptable trade-off)

Related Issues

Matrix SDK Behavior

  • The SDK's Room::display_name() returns "Empty Room" as per Matrix specification
  • The SDK uses Arc internally, making Room a reference to shared state
  • This means old_room.room.cached_display_name() always returns the latest value

Alternative Approaches Considered

  1. Track sent names in a separate Map

    • ❌ Rejected: Added complexity, potential memory leaks
    • ❌ Need to handle room removal edge cases
  2. Store sent name in RoomListServiceRoomInfo

    • ❌ Rejected: Requires snapshot of room state, not just reference
  3. Current approach: Accept duplicate updates

    • ✅ Chosen: Simple, correct, minimal overhead

References


Date: 2025-09-30
PR Branch: fix/invited-room-name-display

@TigerInYourDream TigerInYourDream changed the title # Bug Fix: Invited Room Names Not Displaying Correctly Bug Fix: Invited Room Names Not Displaying Correctly Sep 30, 2025
Copy link
Member

@kevinaboos kevinaboos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into this!

As I said on WeChat, this problem is not just with Invited rooms, but also other newly-joined or newly-added rooms within Robrix.

I think instead of trying to do string comparisons (like room_name == "Empty Room"), we should compare with the actual RoomDisplayName type.

In fact, we should go one step further: instead of sending room name updates as Option<String> values, we should send the actual RoomDisplayName type because it conveys much more information. By comparison, the Option<String> value is worse because it cannot distinguish between a room that has no name vs. a room whose name is not yet known.

Copy link
Member

@kevinaboos kevinaboos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Be sure to carefully consider all the ways a room name can change over time. My comments below highlight some potential issues in your recent changeset that might cause certain name updates to be missed.

// Handle room name display, including Empty/EmptyWas placeholders
let room_name_text = match &room_info.room_name {
Some(name) => match name {
RoomDisplayName::Empty | RoomDisplayName::EmptyWas(_) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not override EmptyWas variant, that is important.

If you want to, you can override Empty to print something like "Empty (Alias )" but that is not strictly necessary either. Remember, the goal here is to update the room names properly, not just override the way they're displayed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to keep EmptyWas unchanged and only fallback for Empty/None.

// For None (invited rooms that haven't loaded yet), use canonical alias or default
room_info.canonical_alias
.as_ref()
.map(|alias| alias.to_string())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, if the room name doesn't exist, you should use other values in this order:

  1. canonical alias
  2. The first alias in the list of aliases
  3. Room ID

Using "Room" as a default is not helpful.

You can also do this for Empty room (above) if you want, though it's not strictly necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to keep EmptyWas unchanged and only fallback for Empty/None.

// Always update the room name if it's not a placeholder.
// We can't reliably compare old vs new because old_room.room is a reference
// to the SDK's internal object which may have already been updated.
let should_update = !matches!(new_room_name, RoomDisplayName::Empty | RoomDisplayName::EmptyWas(_));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With your new change here, what happens when everyone leaves the room, and the room name changes to Empty or WasEmpty? You'll miss those updates.

The proper way to deal with this is to store the previous room name in the RoomListServiceRoomInfo and then compare the new name with that. We want to send an update any time the room name actually changes, not just when it's non-empty. Your comment on L2099-2101 is exactly why that struct exists.
(and then, don't forget to update the room_name in RoomListServiceRoomInfo whenever it has actually changed).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update

@kevinaboos kevinaboos added the waiting-on-author This issue is waiting on the original author for a response label Oct 17, 2025
@kevinaboos
Copy link
Member

Is this ready? If so (and in the future), please re-request a review from me and add the waiting-on-review label.

@kevinaboos
Copy link
Member

@TigerInYourDream I just happened to make some changes to the RoomsListServiceRoomInfo struct in #611 that are similar to what you need in this PR. Take a look, and ensure the merge conflicts are carefully resolved.

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 project-robius#590.

Signed-off-by: Alvin <[email protected]>
Copilot AI review requested due to automatic review settings October 23, 2025 16:13
@TigerInYourDream TigerInYourDream force-pushed the fix/invited-room-name-display branch from 70b98f8 to 612a10e Compare October 23, 2025 16:13
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes an issue where invited room names were not displaying correctly in the Robrix UI, appearing as "Invite to unnamed room" instead of showing the actual room name. The fix involves changing how room names are stored, retrieved, and displayed throughout the application.

  • Refactored room name handling to use RoomDisplayName type instead of Option<String>
  • Added utility functions for consistent room name fallback logic across the codebase
  • Updated room name display to properly handle the Matrix SDK's "Empty Room" placeholder

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/utils.rs Added preferred_room_name() and display_name_with_fallback() utilities for consistent room name handling with fallback to aliases or room ID
src/sliding_sync.rs Modified room name handling to use RoomDisplayName and preferred_room_name() for proper display name conversion
src/room/room_display_filter.rs Updated FilterableRoom implementations to use display_name_with_fallback() for consistent room name display
src/home/rooms_list.rs Changed room_name fields from Option<String> to RoomDisplayName, updated all room name usage sites to use display_name_with_fallback(), and added invited room handling in UpdateRoomName
src/home/room_preview.rs Updated room preview display to use display_name_with_fallback() for both joined and invited rooms
src/home/invite_screen.rs Modified invite details to use display_name_with_fallback() when displaying room information

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

src/utils.rs Outdated
Comment on lines 153 to 158
pub fn preferred_room_name(display_name: &RoomDisplayName) -> Option<String> {
match display_name {
RoomDisplayName::Empty => None,
_ => Some(display_name.to_string()),
}
}
Copy link

Copilot AI Oct 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function documentation states it 'Returns None when the display name is explicitly empty' but doesn't explain the purpose of the other variants. Add documentation explaining what happens for other RoomDisplayName variants (e.g., Calculated, Named, Aliased) and why they all return Some(display_name.to_string()).

Copilot uses AI. Check for mistakes.
if let Some(room) = self.all_joined_rooms.get_mut(&room_id) {
let was_displayed = (self.display_filter)(room);
room.room_name = new_room_name;
// Keep the full RoomDisplayName to preserve EmptyWas semantics
Copy link

Copilot AI Oct 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected spelling of 'EmptyWas' to 'Empty' (likely meant to say 'Empty semantics' or reference a specific variant).

Suggested change
// Keep the full RoomDisplayName to preserve EmptyWas semantics
// Keep the full RoomDisplayName to preserve Empty semantics

Copilot uses AI. Check for mistakes.
}
}
} else {
warning!("Warning: couldn't find invited room {} to update room name", room_id);
Copy link

Copilot AI Oct 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The warning message contains redundant 'Warning:' prefix since it's already logged using the warning! macro. Remove the 'Warning:' prefix from the message.

Suggested change
warning!("Warning: couldn't find invited room {} to update room name", room_id);
warning!("couldn't find invited room {} to update room name", room_id);

Copilot uses AI. Check for mistakes.
Copy link
Member

@kevinaboos kevinaboos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're duplicating a lot of functionality that is already offered by the SDK — that's the whole point of the RoomDisplayName enum. See my comments on the code.

At a high level, you should simply modify the existing room_name_or_id() function to accept a RoomDisplayName instead of an Option<String>. Then, you can use that function throughout Robrix once you change the rest of the code base to use RoomDisplayName instead of String/Option<String> for a room name.

The only possible modification we might want is to augment the RoomDisplayName::Empty variant with additional info, but the only fallback is the room ID. So, you should do something like this:

/// Returns a string representation of the room name or ID.
pub fn room_name_or_id(
    room_name: &RoomDisplayName,
    room_id: impl AsRef<RoomId>,
) -> String {
    match room_name {
        RoomDisplayName::Empty => format!("Empty (ID {})", room_id.as_ref()),
        other => other.to_string(),
    }
}

that's all you really need to do, let's keep it simple.

src/utils.rs Outdated
}

/// Returns the room name that should be shown to the user, falling back to aliases or the room ID.
pub fn display_name_with_fallback(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this function is completely unnecessary; the SDK already offers this functionality within the RoomDisplayName type itself. For ex, the Aliased variant is exactly what you've implemented here with canonical_alias and alt_aliases.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’ve updated the PR so room_name_or_id now takes RoomDisplayName directly and formats RoomDisplayName::Empty as Empty (ID …), and I’ve switched the relevant call sites to use it—no extra helper needed.

src/utils.rs Outdated
///
/// Returns `None` when the display name is explicitly empty so that callers can
/// fall back to aliases or the room ID.
pub fn preferred_room_name(display_name: &RoomDisplayName) -> Option<String> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we also don't need this function at all.

You should combine this functionality into the existing utility function room_name_or_id(), but change room_name_or_id() to accept a RoomDisplayName instead of an Option<String>. Then, change the rest of the code base to use RoomDisplayName instead of String/Option<String> for a room name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed this helper and updated all call sites to rely on the revised room_name_or_id

@kevinaboos kevinaboos added waiting-on-review This issue is waiting to be reviewed and removed waiting-on-author This issue is waiting on the original author for a response labels Oct 24, 2025
@kevinaboos kevinaboos changed the title Bug Fix: Invited Room Names Not Displaying Correctly Use RoomDisplayName everywhere to ensure that room names display correctly Oct 24, 2025
@kevinaboos kevinaboos added waiting-on-author This issue is waiting on the original author for a response and removed waiting-on-review This issue is waiting to be reviewed labels Oct 24, 2025
@TigerInYourDream TigerInYourDream force-pushed the fix/invited-room-name-display branch from 914f395 to af47d4b Compare October 29, 2025 03:13
@TigerInYourDream TigerInYourDream force-pushed the fix/invited-room-name-display branch from af47d4b to b7dbaef Compare October 30, 2025 03:52
TigerInYourDream added a commit to TigerInYourDream/robrix that referenced this pull request Oct 31, 2025
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 project-robius#590.

Signed-off-by: Alvin <[email protected]>
@TigerInYourDream TigerInYourDream force-pushed the fix/invited-room-name-display branch from 9d8b442 to b7dbaef Compare October 31, 2025 06:00
Copy link
Member

@kevinaboos kevinaboos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The proposed changes are generally good, but you can vastly simplify a lot of things by introducing a new RoomName newtype wrapper for RoomDisplayName, and then implementing a lot of traits for that.

Please disable your auto-formatter. There are tons of unrelated whitespace changes that make my job as a reviewer harder.

let mut restore_status_view = self.view.restore_status_view(ids!(restore_status_view));
restore_status_view.set_content(cx, self.all_rooms_loaded, &self.room_name);
let room_label = self.current_room_label();
restore_status_view.set_content(cx, self.all_rooms_loaded, &room_label);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just use the same RoomName struct here too. You can pass it directly to set_content() and change the function signature of set_content() to accept a RoomName parameter.

Comment on lines 1297 to 1309
error!("Pagination error ({direction}) in room \"{}\", {}: {error:?}", self.room_name, tl.room_id);
error!("Pagination error ({direction}) in room \"{}\", {}: {error:?}", room_label_cached, tl.room_id);
enqueue_popup_notification(PopupItem {
message: utils::stringify_pagination_error(&error, &self.room_name),
message: utils::stringify_pagination_error(&error, room_label_cached.as_str()),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment here: remove current_room_label() and just make the new RoomName wrapper struct implement the Display trait.

Copy link
Contributor Author

@TigerInYourDream TigerInYourDream Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. RestoreStatusView::set_content now takes a RoomName plus an optional RoomId, so the view itself handles the fallback text (Unnamed (ID …) when the name is empty). The RoomScreen call site just does
set_content(cx, self.all_rooms_loaded, RoomName::from(self.room_name.clone()), self.room_id.as_deref()), so we no longer build that label manually.

@TigerInYourDream TigerInYourDream force-pushed the fix/invited-room-name-display branch from 2521877 to 46773bb Compare November 11, 2025 03:39
@TigerInYourDream TigerInYourDream force-pushed the fix/invited-room-name-display branch from 46773bb to f1e970f Compare November 11, 2025 03:42
@kevinaboos kevinaboos added waiting-on-review This issue is waiting to be reviewed and removed waiting-on-author This issue is waiting on the original author for a response labels Nov 13, 2025
Copy link
Member

@kevinaboos kevinaboos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the new changes.

After going through a few files, I'm curious about the usage of RoomDisplayName everywhere instead of RoomName. I didn't expect to see that; I thought the goal was to use the new RoomName everywhere for ease of use?

Also, after seeing the new code, we should probably just make RoomName contain both a RoomDisplayName and and OwnedRoomId. That way you can impl Display for RoomName, in which the RoomDisplayName::Empty variant automatically uses the OwnedRoomId within the RoomName struct itself. You can then remove the utils::room_name_or_id() function, which is tedious to use.

/// This is used to wait for RoomsPanel
#[rust] room_id: Option<OwnedRoomId>,
#[rust] room_name: String,
#[rust(RoomDisplayName::Empty)] room_name: RoomDisplayName,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. I thought we were going to use RoomName everywhere. Is there a reason why we can't use it here?
  2. RoomName should impl Default, so you don't need the specific initial value here

impl InviteScreenRef {
/// See [`InviteScreen::set_displayed_invite()`].
pub fn set_displayed_invite<S: Into<Option<String>>>(&self, cx: &mut Cx, room_id: OwnedRoomId, room_name: S) {
pub fn set_displayed_invite(&self, cx: &mut Cx, room_id: OwnedRoomId, room_name: RoomDisplayName) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there any reason why this takes a RoomDisplayName parameter instead of RoomName?

@kevinaboos kevinaboos added waiting-on-author This issue is waiting on the original author for a response and removed waiting-on-review This issue is waiting to be reviewed labels Nov 13, 2025
@TigerInYourDream
Copy link
Contributor Author

After going through a few files, I'm curious about the usage of RoomDisplayName everywhere instead of RoomName. I didn't expect to see that; I thought the goal was to use the new RoomName everywhere for ease of use?

Also, after seeing the new code, we should probably just make RoomName contain both a RoomDisplayName and and OwnedRoomId. That way you can impl Display for RoomName, in which the RoomDisplayName::Empty variant automatically uses the OwnedRoomId within the RoomName struct itself. You can then remove the utils::room_name_or_id() function, which is tedious to use.

Thanks for taking another look. The reason the last PR still uses RoomDisplayName in most places is that RoomName is currently just a thin newtype over it (see utils::RoomName). Outside of the helpers that need
fallback logic (room_name_or_id, avatar generation, etc.), switching every struct to the wrapper would only add a layer of wrap/unwrap without giving us additional semantics—especially because many paths still
need to interact with the SDK’s RoomDisplayName variants directly (EmptyWas, Calculated, …) and to serialize/deserialize them as-is. I only used RoomName where the fallback behavior was actually needed, and left
the rest untouched to keep the churn down and preserve the SDK-facing types.

That said, I agree this leaves us with two types representing the same concept, which hurts consistency. I like your suggestion of evolving RoomName into a richer type that also carries an OwnedRoomId (or
introducing an equivalent “known room” struct), so we can implement Display once and drop room_name_or_id(). I’ll plan a follow-up patch to converge on that single type and update the call sites that currently
only know the display name to either provide the ID or opt into a different helper.

@kevinaboos
Copy link
Member

Please apply the suggested changes in this PR, in particular the RoomName type redesign. I've already spent a long time reviewing this PR in detail, and I don't think it's beneficial to save that for another PR, because it would end up touching all the same lines of code as this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

waiting-on-author This issue is waiting on the original author for a response

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants