Skip to content

Commit 6340eea

Browse files
authored
Merge pull request #3068 from Hywan/feat-roomlist-sorting
feat(base): Implement `Client::rooms_stream`
2 parents 565f974 + 717c68d commit 6340eea

File tree

6 files changed

+427
-20
lines changed

6 files changed

+427
-20
lines changed

crates/matrix-sdk-base/src/client.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ use std::{
2121
use std::{ops::Deref, sync::Arc};
2222

2323
use eyeball::{SharedObservable, Subscriber};
24+
#[cfg(not(target_arch = "wasm32"))]
25+
use eyeball_im::{Vector, VectorDiff};
26+
#[cfg(not(target_arch = "wasm32"))]
27+
use futures_util::Stream;
2428
use matrix_sdk_common::instant::Instant;
2529
#[cfg(feature = "e2e-encryption")]
2630
use matrix_sdk_crypto::{
@@ -169,6 +173,13 @@ impl BaseClient {
169173
self.store.rooms_filtered(filter)
170174
}
171175

176+
/// Get a stream of all the rooms changes, in addition to the existing
177+
/// rooms.
178+
#[cfg(not(target_arch = "wasm32"))]
179+
pub fn rooms_stream(&self) -> (Vector<Room>, impl Stream<Item = Vec<VectorDiff<Room>>>) {
180+
self.store.rooms_stream()
181+
}
182+
172183
/// Lookup the Room for the given RoomId, or create one, if it didn't exist
173184
/// yet in the store
174185
pub fn get_or_create_room(&self, room_id: &RoomId, room_state: RoomState) -> Room {
@@ -1668,6 +1679,8 @@ mod tests {
16681679
#[cfg(all(feature = "e2e-encryption", feature = "experimental-sliding-sync"))]
16691680
#[async_test]
16701681
async fn test_when_there_are_no_latest_encrypted_events_decrypting_them_does_nothing() {
1682+
use crate::StateChanges;
1683+
16711684
// Given a room
16721685
let user_id = user_id!("@u:u.to");
16731686
let room_id = room_id!("!r:u.to");
@@ -1679,7 +1692,7 @@ mod tests {
16791692
assert!(room.latest_event().is_none());
16801693

16811694
// When I tell it to do some decryption
1682-
let mut changes = crate::StateChanges::default();
1695+
let mut changes = StateChanges::default();
16831696
client.decrypt_latest_events(&room, &mut changes).await;
16841697

16851698
// Then nothing changed

crates/matrix-sdk-base/src/latest_event.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Utilities for working with events to decide whether they are suitable for
22
//! use as a [crate::Room::latest_event].
33
4-
#![cfg(feature = "experimental-sliding-sync")]
4+
#![cfg(any(feature = "e2e-encryption", feature = "experimental-sliding-sync"))]
55

66
use matrix_sdk_common::deserialized_responses::SyncTimelineEvent;
77
#[cfg(feature = "e2e-encryption")]

crates/matrix-sdk-base/src/store/mod.rs

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,22 @@ use std::{
2929
sync::{Arc, RwLock as StdRwLock},
3030
};
3131

32+
#[cfg(not(target_arch = "wasm32"))]
33+
use eyeball_im::{Vector, VectorDiff};
34+
#[cfg(not(target_arch = "wasm32"))]
35+
use futures_util::Stream;
3236
use once_cell::sync::OnceCell;
3337

3438
#[cfg(any(test, feature = "testing"))]
3539
#[macro_use]
3640
pub mod integration_tests;
41+
mod observable_map;
3742
mod traits;
3843

3944
#[cfg(feature = "e2e-encryption")]
4045
use matrix_sdk_crypto::store::{DynCryptoStore, IntoCryptoStore};
4146
pub use matrix_sdk_store_encryption::Error as StoreEncryptionError;
47+
use observable_map::ObservableMap;
4248
use ruma::{
4349
events::{
4450
presence::PresenceEvent,
@@ -139,7 +145,7 @@ pub(crate) struct Store {
139145
/// The current sync token that should be used for the next sync call.
140146
pub(super) sync_token: Arc<RwLock<Option<String>>>,
141147
/// All rooms the store knows about.
142-
rooms: Arc<StdRwLock<BTreeMap<OwnedRoomId, Room>>>,
148+
rooms: Arc<StdRwLock<ObservableMap<OwnedRoomId, Room>>>,
143149
/// A lock to synchronize access to the store, such that data by the sync is
144150
/// never overwritten.
145151
sync_lock: Arc<Mutex<()>>,
@@ -152,7 +158,7 @@ impl Store {
152158
inner,
153159
session_meta: Default::default(),
154160
sync_token: Default::default(),
155-
rooms: Default::default(),
161+
rooms: Arc::new(StdRwLock::new(ObservableMap::new())),
156162
sync_lock: Default::default(),
157163
}
158164
}
@@ -173,15 +179,22 @@ impl Store {
173179
session_meta: SessionMeta,
174180
roominfo_update_sender: &broadcast::Sender<RoomInfoUpdate>,
175181
) -> Result<()> {
176-
for info in self.inner.get_room_infos().await? {
177-
let room = Room::restore(
178-
&session_meta.user_id,
179-
self.inner.clone(),
180-
info,
181-
roominfo_update_sender.clone(),
182-
);
183-
184-
self.rooms.write().unwrap().insert(room.room_id().to_owned(), room);
182+
{
183+
let room_infos = self.inner.get_room_infos().await?;
184+
185+
let mut rooms = self.rooms.write().unwrap();
186+
187+
for room_info in room_infos {
188+
let new_room = Room::restore(
189+
&session_meta.user_id,
190+
self.inner.clone(),
191+
room_info,
192+
roominfo_update_sender.clone(),
193+
);
194+
let new_room_id = new_room.room_id().to_owned();
195+
196+
rooms.insert(new_room_id, new_room);
197+
}
185198
}
186199

187200
let token =
@@ -200,7 +213,7 @@ impl Store {
200213

201214
/// Get all the rooms this store knows about.
202215
pub fn rooms(&self) -> Vec<Room> {
203-
self.rooms.read().unwrap().values().cloned().collect()
216+
self.rooms.read().unwrap().iter().cloned().collect()
204217
}
205218

206219
/// Get all the rooms this store knows about, filtered by state.
@@ -209,18 +222,25 @@ impl Store {
209222
.read()
210223
.unwrap()
211224
.iter()
212-
.filter(|(_, room)| filter.matches(room.state()))
213-
.map(|(_, room)| room.clone())
225+
.filter(|room| filter.matches(room.state()))
226+
.cloned()
214227
.collect()
215228
}
216229

230+
/// Get a stream of all the rooms changes, in addition to the existing
231+
/// rooms.
232+
#[cfg(not(target_arch = "wasm32"))]
233+
pub fn rooms_stream(&self) -> (Vector<Room>, impl Stream<Item = Vec<VectorDiff<Room>>>) {
234+
self.rooms.read().unwrap().stream()
235+
}
236+
217237
/// Get the room with the given room id.
218238
pub fn room(&self, room_id: &RoomId) -> Option<Room> {
219239
self.rooms.read().unwrap().get(room_id).cloned()
220240
}
221241

222-
/// Lookup the Room for the given RoomId, or create one, if it didn't exist
223-
/// yet in the store.
242+
/// Lookup the `Room` for the given `RoomId`, or create one, if it didn't
243+
/// exist yet in the store
224244
pub fn get_or_create_room(
225245
&self,
226246
room_id: &RoomId,
@@ -233,8 +253,7 @@ impl Store {
233253
self.rooms
234254
.write()
235255
.unwrap()
236-
.entry(room_id.to_owned())
237-
.or_insert_with(|| {
256+
.get_or_create(room_id, || {
238257
Room::new(user_id, self.inner.clone(), room_id, room_type, roominfo_update_sender)
239258
})
240259
.clone()

0 commit comments

Comments
 (0)