Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions bindings/matrix-sdk-ffi/src/room/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,14 @@ impl Room {
Ok(avatar_url_string)
}

pub async fn set_own_member_display_name(
&self,
display_name: Option<String>,
) -> Result<(), ClientError> {
self.inner.set_own_member_display_name(display_name).await?;
Ok(())
}

/// Get the membership details for the current user.
///
/// Returns:
Expand Down
3 changes: 3 additions & 0 deletions crates/matrix-sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ All notable changes to this project will be documented in this file.

### Features

- Add `Room::set_own_member_display_name` to set the current user's display name
within only the one single room (can be used for /myroomnick functionality).
[#5981](https://github.com/matrix-org/matrix-rust-sdk/pull/5981)
- Sending `MessageLike` and `RawMessageLike` events through a `Room` now returns
the used `EncryptionInfo`, if any.
([#5936](https://github.com/matrix-org/matrix-rust-sdk/pull/5936))
Expand Down
33 changes: 32 additions & 1 deletion crates/matrix-sdk/src/room/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ use ruma::{
avatar::{self, RoomAvatarEventContent},
encryption::RoomEncryptionEventContent,
history_visibility::HistoryVisibility,
member::{MembershipChange, SyncRoomMemberEvent},
member::{MembershipChange, RoomMemberEventContent, SyncRoomMemberEvent},
message::{
AudioInfo, AudioMessageEventContent, FileInfo, FileMessageEventContent,
ImageMessageEventContent, MessageType, RoomMessageEventContent,
Expand Down Expand Up @@ -1109,6 +1109,37 @@ impl Room {
.collect())
}

/// Sets the display name of the current user within this room.
///
/// *Note*: This is different to [`crate::Account::set_display_name`] which
/// updates the user's display name across all of their rooms.
pub async fn set_own_member_display_name(
&self,
display_name: Option<String>,
) -> Result<send_state_event::v3::Response> {
let user_id = self.own_user_id();
let member_event =
self.get_state_event_static_for_key::<RoomMemberEventContent, _>(user_id).await?;

let Some(member_event) = member_event else {
return Err(Error::InsufficientData);
};

let RawSyncOrStrippedState::Sync(raw_event) = member_event else {
return Err(Error::InsufficientData);
};
Comment on lines +1124 to +1130
Copy link
Collaborator

Choose a reason for hiding this comment

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

These two checks can be collapsed into a single one.


let event = raw_event.deserialize()?;

let SyncStateEvent::Original(ev) = event else {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Having a redacted event shouldn't prevent from changing the display name. We can create a new RoomMemberEventContent with the same membership.

return Err(Error::InsufficientData);
};

let mut content = ev.content;
content.displayname = display_name;
self.send_state_event_for_key(user_id, content).await
}

/// Get all state events of a given type in this room.
pub async fn get_state_events(
&self,
Expand Down
47 changes: 47 additions & 0 deletions crates/matrix-sdk/tests/integration/room/joined.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1456,3 +1456,50 @@ async fn test_report_room() {

room.report_room(reason.to_owned()).await.unwrap();
}

#[async_test]
async fn test_set_own_member_display_name() {
// Given a room with an existing member event for the current user.
let (client, server) = logged_in_client_with_server().await;
let mut sync_builder = SyncResponseBuilder::new();
let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
let room_id = &DEFAULT_TEST_ROOM_ID;
let user_id = client.user_id().unwrap();

let existing_name = "Old Name";
let existing_avatar_url = mxc_uri!("mxc://example.org/avA7ar");

let member_event = EventFactory::new()
.member(user_id)
.display_name(existing_name.to_owned())
.avatar_url(existing_avatar_url)
.membership(MembershipState::Join);

let response = sync_builder
.add_joined_room(JoinedRoomBuilder::new(room_id).add_state_event(member_event))
.build_json_sync_response();

mock_sync(&server, response, None).await;
client.sync_once(sync_settings).await.unwrap();

let room = client.get_room(room_id).unwrap();

// When setting a new display name.
let new_name = "New Name";

// Then the user's display name is updated without changing the avatar URL.
Mock::given(method("PUT"))
.and(path_regex(format!(r"^/_matrix/client/r0/rooms/.*/state/m.room.member/{user_id}")))
.and(header("authorization", "Bearer 1234"))
.and(body_partial_json(json!({
"displayname": new_name,
"avatar_url": existing_avatar_url.to_string(),
"membership": "join"
})))
.respond_with(ResponseTemplate::new(200).set_body_json(&*test_json::EVENT_ID))
.expect(1)
.mount(&server)
.await;

room.set_own_member_display_name(Some(new_name.to_owned())).await.unwrap();
}
Loading