Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(base): Rewrite RoomNotableTags #3111

Merged
merged 14 commits into from
Feb 9, 2024
Merged
Show file tree
Hide file tree
Changes from 12 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
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 3 additions & 23 deletions bindings/matrix-sdk-ffi/src/room.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{convert::TryFrom, sync::Arc};
use anyhow::{Context, Result};
use matrix_sdk::{
room::{power_levels::RoomPowerLevelChanges, Room as SdkRoom},
RoomMemberships, RoomNotableTags, RoomState,
RoomMemberships, RoomState,
};
use matrix_sdk_ui::timeline::RoomExt;
use mime::Mime;
Expand Down Expand Up @@ -256,27 +256,12 @@ impl Room {
})))
}

pub fn subscribe_to_notable_tags(
self: Arc<Self>,
listener: Box<dyn RoomNotableTagsListener>,
) -> Arc<TaskHandle> {
Arc::new(TaskHandle::new(RUNTIME.spawn(async move {
let (initial, mut subscriber) = self.inner.notable_tags_stream().await;
// Send the initial value
listener.call(initial);
// Then wait for changes
while let Some(notable_tags) = subscriber.next().await {
listener.call(notable_tags);
}
})))
}

pub async fn set_is_favorite(
pub async fn set_is_favourite(
&self,
is_favorite: bool,
bnjbvr marked this conversation as resolved.
Show resolved Hide resolved
tag_order: Option<f64>,
) -> Result<(), ClientError> {
self.inner.set_is_favorite(is_favorite, tag_order).await?;
self.inner.set_is_favourite(is_favorite, tag_order).await?;
bnjbvr marked this conversation as resolved.
Show resolved Hide resolved
Ok(())
}

Expand Down Expand Up @@ -626,11 +611,6 @@ pub trait TypingNotificationsListener: Sync + Send {
fn call(&self, typing_user_ids: Vec<String>);
}

#[uniffi::export(callback_interface)]
pub trait RoomNotableTagsListener: Sync + Send {
fn call(&self, notable_tags: RoomNotableTags);
}

#[derive(uniffi::Object)]
pub struct RoomMembersIterator {
chunk_iterator: ChunkIterator<matrix_sdk::room::RoomMember>,
Expand Down
2 changes: 1 addition & 1 deletion crates/matrix-sdk-base/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ as_variant = { workspace = true }
assert_matches = { workspace = true, optional = true }
assert_matches2 = { workspace = true, optional = true }
async-trait = { workspace = true }
bitflags = "2.1.0"
bitflags = { version = "2.4.0", features = ["serde"] }
eyeball = { workspace = true }
eyeball-im = { workspace = true }
futures-util = { workspace = true }
Expand Down
111 changes: 70 additions & 41 deletions crates/matrix-sdk-base/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ use ruma::{
},
AnyGlobalAccountDataEvent, AnyRoomAccountDataEvent, AnyStrippedStateEvent,
AnySyncEphemeralRoomEvent, AnySyncMessageLikeEvent, AnySyncStateEvent,
AnySyncTimelineEvent, GlobalAccountDataEventType, RoomAccountDataEventType, StateEventType,
AnySyncTimelineEvent, GlobalAccountDataEventType, StateEventType,
},
push::{Action, PushConditionRoomCtx, Ruleset},
serde::Raw,
Expand All @@ -68,7 +68,7 @@ use crate::{
StateChanges, StateStoreDataKey, StateStoreDataValue, StateStoreExt, Store, StoreConfig,
},
sync::{JoinedRoom, LeftRoom, Notification, Rooms, SyncResponse, Timeline},
RoomNotableTags, RoomStateFilter, SessionMeta,
RoomStateFilter, SessionMeta,
};
#[cfg(feature = "e2e-encryption")]
use crate::{error::Error, RoomMemberships};
Expand Down Expand Up @@ -538,22 +538,56 @@ impl BaseClient {
events: &[Raw<AnyRoomAccountDataEvent>],
changes: &mut StateChanges,
) {
// Small helper to make the code easier to read.
//
// It finds the appropriate `RoomInfo`, allowing the caller to modify it, and
// save it in the correct place.
fn on_room_info<F>(
room_id: &RoomId,
changes: &mut StateChanges,
client: &BaseClient,
on_room_info: F,
) where
F: Fn(&mut RoomInfo),
{
// `StateChanges` has the `RoomInfo`.
if let Some(room_info) = changes.room_infos.get_mut(room_id) {
// Show time.
on_room_info(room_info);
}
// The `BaseClient` has the `Room`, which has the `RoomInfo`.
else if let Some(room) = client.store.get_room(room_id) {
// Clone the `RoomInfo`.
let mut room_info = room.clone_info();

// Show time.
on_room_info(&mut room_info);

// Update the `RoomInfo` via `StateChanges`.
changes.add_room(room_info);
}
}

// Handle new events.
for raw_event in events {
if let Ok(event) = raw_event.deserialize() {
changes.add_room_account_data(room_id, event.clone(), raw_event.clone());

// Rooms can either appear in the current request or already be
// known to the store. If neither of
// those are true then the room is `unknown` and we cannot
// process its account data
if let AnyRoomAccountDataEvent::MarkedUnread(e) = event {
if let Some(room) = changes.room_infos.get_mut(room_id) {
room.base_info.is_marked_unread = e.content.unread;
} else if let Some(room) = self.store.get_room(room_id) {
let mut info = room.clone_info();
info.base_info.is_marked_unread = e.content.unread;
changes.add_room(info);
match event {
AnyRoomAccountDataEvent::MarkedUnread(event) => {
on_room_info(room_id, changes, self, |room_info| {
room_info.base_info.is_marked_unread = event.content.unread;
});
}

AnyRoomAccountDataEvent::Tag(event) => {
on_room_info(room_id, changes, self, |room_info| {
room_info.base_info.handle_notable_tags(&event.content.tags);
});
}

// Nothing.
_ => {}
}
}
}
Expand Down Expand Up @@ -785,8 +819,8 @@ impl BaseClient {
for (room_id, new_info) in response.rooms.join {
let room = self.store.get_or_create_room(&room_id, RoomState::Joined);
let mut room_info = room.clone_info();
room_info.mark_as_joined();

room_info.mark_as_joined();
room_info.update_summary(&new_info.summary);
room_info.set_prev_batch(new_info.timeline.prev_batch.as_deref());
room_info.mark_state_fully_synced();
Expand Down Expand Up @@ -841,9 +875,19 @@ impl BaseClient {
)
.await?;

// Save the new `RoomInfo`.
changes.add_room(room_info);

self.handle_room_account_data(&room_id, &new_info.account_data.events, &mut changes)
.await;

// `Self::handle_room_account_data` might have updated the `RoomInfo`. Let's
// fetch it again.
//
// SAFETY: `unwrap` is safe because the `RoomInfo` has been inserted 2 lines
// above.
let mut room_info = changes.room_infos.get(&room_id).unwrap().clone();
Comment on lines +878 to +889
Copy link
Member

Choose a reason for hiding this comment

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

So the way it's done in the sliding-sync variant of this function, is that we edit the room_info, and don't mess at all with the changes until the end of the function where we put the room info into the changes. We should do that here too, for consistency at least. I'll write a followup.


#[cfg(feature = "e2e-encryption")]
if room_info.is_encrypted() {
if let Some(o) = self.olm_machine().await.as_ref() {
Expand Down Expand Up @@ -915,12 +959,14 @@ impl BaseClient {
)
.await?;

// Save the new `RoomInfo`.
changes.add_room(room_info);

self.handle_room_account_data(&room_id, &new_info.account_data.events, &mut changes)
.await;

let ambiguity_changes = ambiguity_cache.changes.remove(&room_id).unwrap_or_default();

changes.add_room(room_info);
new_rooms.leave.insert(
room_id,
LeftRoom::new(
Expand Down Expand Up @@ -998,24 +1044,7 @@ impl BaseClient {

for (room_id, room_info) in &changes.room_infos {
if let Some(room) = self.store.get_room(room_id) {
room.set_room_info(room_info.clone())
}
}

for (room_id, room_account_data) in &changes.room_account_data {
if let Some(room) = self.store.get_room(room_id) {
let tags = room_account_data.get(&RoomAccountDataEventType::Tag).and_then(|r| {
match r.deserialize() {
Ok(AnyRoomAccountDataEvent::Tag(event)) => Some(event.content.tags),
Err(e) => {
warn!("Room account data tag event failed to deserialize : {e}");
None
}
Ok(_) => None,
}
});
let notable_tags = RoomNotableTags::new(tags);
room.set_notable_tags(notable_tags)
room.set_room_info(room_info.clone());
}
}
}
Expand Down Expand Up @@ -1378,17 +1407,17 @@ impl Default for BaseClient {
#[cfg(test)]
mod tests {
use matrix_sdk_test::{
async_test, response_from_file, sync_timeline_event, InvitedRoomBuilder, JoinedRoomBuilder,
LeftRoomBuilder, StrippedStateTestEvent, SyncResponseBuilder,
async_test, response_from_file, sync_timeline_event, InvitedRoomBuilder, LeftRoomBuilder,
StrippedStateTestEvent, SyncResponseBuilder,
};
use ruma::{
api::{client as api, IncomingResponse},
room_id, user_id, RoomId, UserId,
room_id, user_id, UserId,
};
use serde_json::json;

use super::BaseClient;
use crate::{store::StateStoreExt, DisplayName, Room, RoomState, SessionMeta, StateChanges};
use crate::{store::StateStoreExt, DisplayName, RoomState, SessionMeta};

#[async_test]
async fn invite_after_leaving() {
Expand Down Expand Up @@ -1536,7 +1565,7 @@ mod tests {
assert!(room.latest_event().is_none());

// When I tell it to do some decryption
let mut changes = StateChanges::default();
let mut changes = crate::StateChanges::default();
client.decrypt_latest_events(&room, &mut changes).await;

// Then nothing changed
Expand Down Expand Up @@ -1565,13 +1594,13 @@ mod tests {
#[cfg(feature = "e2e-encryption")]
async fn process_room_join(
client: &BaseClient,
room_id: &RoomId,
room_id: &ruma::RoomId,
event_id: &str,
user_id: &UserId,
) -> Room {
) -> crate::Room {
let mut ev_builder = SyncResponseBuilder::new();
let response = ev_builder
.add_joined_room(JoinedRoomBuilder::new(room_id).add_timeline_event(
.add_joined_room(matrix_sdk_test::JoinedRoomBuilder::new(room_id).add_timeline_event(
sync_timeline_event!({
"content": {
"displayname": "Alice",
Expand Down
2 changes: 1 addition & 1 deletion crates/matrix-sdk-base/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub use matrix_sdk_crypto as crypto;
pub use once_cell;
pub use rooms::{
DisplayName, Room, RoomCreateWithCreatorEventContent, RoomInfo, RoomMember, RoomMemberships,
RoomNotableTags, RoomState, RoomStateFilter,
RoomState, RoomStateFilter,
};
pub use store::{StateChanges, StateStore, StateStoreDataKey, StateStoreDataValue, StoreError};
pub use utils::{
Expand Down
Loading
Loading