Skip to content

Commit d7550ec

Browse files
committed
feat(ui): RoomListService::subscribe_to_rooms calls LatestEvents::listen_to_room.
This patch updates `RoomListService::subscribe_to_rooms` to call `LatestEvents::listen_to_room` automatically. This method becomes async, which propagates to a couple of callers. The idea is that when one is interested by a specific room, a subscription will be applied. This is an opportunity to also “activate” the computation of the `LatestEvent` for this specific room, so that the user doesn't have to do that manually (except if room subscription is never used).
1 parent ea56458 commit d7550ec

File tree

5 files changed

+39
-15
lines changed

5 files changed

+39
-15
lines changed

bindings/matrix-sdk-ffi/src/room_list.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,15 +121,17 @@ impl RoomListService {
121121
})))
122122
}
123123

124-
fn subscribe_to_rooms(&self, room_ids: Vec<String>) -> Result<(), RoomListError> {
124+
async fn subscribe_to_rooms(&self, room_ids: Vec<String>) -> Result<(), RoomListError> {
125125
let room_ids = room_ids
126126
.into_iter()
127127
.map(|room_id| {
128128
RoomId::parse(&room_id).map_err(|_| RoomListError::InvalidRoomId { error: room_id })
129129
})
130130
.collect::<Result<Vec<_>, _>>()?;
131131

132-
self.inner.subscribe_to_rooms(&room_ids.iter().map(AsRef::as_ref).collect::<Vec<_>>());
132+
self.inner
133+
.subscribe_to_rooms(&room_ids.iter().map(AsRef::as_ref).collect::<Vec<_>>())
134+
.await;
133135

134136
Ok(())
135137
}

crates/matrix-sdk-ui/src/room_list_service/mod.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ use ruma::{
7272
};
7373
pub use state::*;
7474
use thiserror::Error;
75-
use tracing::debug;
75+
use tracing::{debug, error};
7676

7777
/// The default `required_state` constant value for sliding sync lists and
7878
/// sliding sync room subscriptions.
@@ -393,7 +393,15 @@ impl RoomListService {
393393
///
394394
/// It means that all events from these rooms will be received every time,
395395
/// no matter how the `RoomList` is configured.
396-
pub fn subscribe_to_rooms(&self, room_ids: &[&RoomId]) {
396+
///
397+
/// [`LatestEvents::listen_to_room`][listen_to_room] will be called for each
398+
/// room in `room_ids`, so that the [`LatestEventValue`] will automatically
399+
/// be calculated and updated for these rooms, for free.
400+
///
401+
/// [listen_to_room]: matrix_sdk::latest_events::LatestEvents::listen_to_room
402+
/// [`LatestEventValue`]: matrix_sdk::latest_events::LatestEventValue
403+
pub async fn subscribe_to_rooms(&self, room_ids: &[&RoomId]) {
404+
// Calculate the settings for the room subscriptions.
397405
let settings = assign!(http::request::RoomSubscription::default(), {
398406
required_state: DEFAULT_REQUIRED_STATE.iter().map(|(state_event, value)| {
399407
(state_event.clone(), (*value).to_owned())
@@ -407,13 +415,27 @@ impl RoomListService {
407415
timeline_limit: UInt::from(DEFAULT_ROOM_SUBSCRIPTION_TIMELINE_LIMIT),
408416
});
409417

418+
// Decide whether the in-flight request (if any) should be cancelled if needed.
410419
let cancel_in_flight_request = match self.state_machine.get() {
411420
State::Init | State::Recovering | State::Error { .. } | State::Terminated { .. } => {
412421
false
413422
}
414423
State::SettingUp | State::Running => true,
415424
};
416425

426+
// Before subscribing, let's listen these rooms to calculate their latest
427+
// events.
428+
let latest_events = self.client.latest_events().await;
429+
430+
for room_id in room_ids {
431+
if let Err(error) = latest_events.listen_to_room(room_id).await {
432+
// Let's not fail the room subscription. Instead, emit a log because it's very
433+
// unlikely to happen.
434+
error!(?error, ?room_id, "Failed to listen to the latest event for this room");
435+
}
436+
}
437+
438+
// Subscribe to the rooms.
417439
self.sliding_sync.subscribe_to_rooms(room_ids, Some(settings), cancel_in_flight_request)
418440
}
419441

crates/matrix-sdk-ui/tests/integration/room_list_service.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2247,7 +2247,7 @@ async fn test_room_subscription() -> Result<(), Error> {
22472247

22482248
// Subscribe.
22492249

2250-
room_list.subscribe_to_rooms(&[room_id_1]);
2250+
room_list.subscribe_to_rooms(&[room_id_1]).await;
22512251

22522252
sync_then_assert_request_and_fake_response! {
22532253
[server, room_list, sync]
@@ -2290,7 +2290,7 @@ async fn test_room_subscription() -> Result<(), Error> {
22902290

22912291
// Subscribe to another room.
22922292

2293-
room_list.subscribe_to_rooms(&[room_id_2]);
2293+
room_list.subscribe_to_rooms(&[room_id_2]).await;
22942294

22952295
sync_then_assert_request_and_fake_response! {
22962296
[server, room_list, sync]
@@ -2333,7 +2333,7 @@ async fn test_room_subscription() -> Result<(), Error> {
23332333

23342334
// Subscribe to an already subscribed room. Nothing happens.
23352335

2336-
room_list.subscribe_to_rooms(&[room_id_1]);
2336+
room_list.subscribe_to_rooms(&[room_id_1]).await;
23372337

23382338
sync_then_assert_request_and_fake_response! {
23392339
[server, room_list, sync]

labs/multiverse/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,15 +325,15 @@ impl App {
325325
modifiers: KeyModifiers::CONTROL,
326326
..
327327
}) => {
328-
self.room_list.next_room();
328+
self.room_list.next_room().await;
329329
let room_id = self.room_list.get_selected_room_id();
330330
self.room_view.set_selected_room(room_id);
331331
}
332332

333333
Event::Key(KeyEvent {
334334
code: Char('k') | Up, modifiers: KeyModifiers::CONTROL, ..
335335
}) => {
336-
self.room_list.previous_room();
336+
self.room_list.previous_room().await;
337337
let room_id = self.room_list.get_selected_room_id();
338338
self.room_view.set_selected_room(room_id);
339339
}

labs/multiverse/src/widgets/room_list.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ impl RoomList {
6868
/// Focus the list on the next item, wraps around if needs be.
6969
///
7070
/// Returns the index only if there was a meaningful change.
71-
pub fn next_room(&mut self) {
71+
pub async fn next_room(&mut self) {
7272
let num_items = self.rooms.lock().len();
7373

7474
// If there's no item to select, leave early.
@@ -83,14 +83,14 @@ impl RoomList {
8383

8484
if prev != Some(new) {
8585
self.state.select(Some(new));
86-
self.subscribe_to_room(new);
86+
self.subscribe_to_room(new).await;
8787
}
8888
}
8989

9090
/// Focus the list on the previous item, wraps around if needs be.
9191
///
9292
/// Returns the index only if there was a meaningful change.
93-
pub fn previous_room(&mut self) {
93+
pub async fn previous_room(&mut self) {
9494
let num_items = self.rooms.lock().len();
9595

9696
// If there's no item to select, leave early.
@@ -105,7 +105,7 @@ impl RoomList {
105105

106106
if prev != Some(new) {
107107
self.state.select(Some(new));
108-
self.subscribe_to_room(new);
108+
self.subscribe_to_room(new).await;
109109
}
110110
}
111111

@@ -121,15 +121,15 @@ impl RoomList {
121121
}
122122

123123
/// Subscribe to room that is shown at the given `index`.
124-
fn subscribe_to_room(&mut self, index: usize) {
124+
async fn subscribe_to_room(&mut self, index: usize) {
125125
// Cancel the subscription to the previous room, if any.
126126
self.current_room_subscription.take();
127127

128128
// Subscribe to the new room.
129129
if let Some(room) =
130130
self.get_room_id_of_entry(index).and_then(|room_id| self.client.get_room(&room_id))
131131
{
132-
self.sync_service.room_list_service().subscribe_to_rooms(&[room.room_id()]);
132+
self.sync_service.room_list_service().subscribe_to_rooms(&[room.room_id()]).await;
133133
self.current_room_subscription = Some(room);
134134
}
135135
}

0 commit comments

Comments
 (0)