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).
This commit is contained in:
@@ -121,7 +121,7 @@ impl RoomListService {
|
||||
})))
|
||||
}
|
||||
|
||||
fn subscribe_to_rooms(&self, room_ids: Vec<String>) -> Result<(), RoomListError> {
|
||||
async fn subscribe_to_rooms(&self, room_ids: Vec<String>) -> Result<(), RoomListError> {
|
||||
let room_ids = room_ids
|
||||
.into_iter()
|
||||
.map(|room_id| {
|
||||
@@ -129,7 +129,9 @@ impl RoomListService {
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
self.inner.subscribe_to_rooms(&room_ids.iter().map(AsRef::as_ref).collect::<Vec<_>>());
|
||||
self.inner
|
||||
.subscribe_to_rooms(&room_ids.iter().map(AsRef::as_ref).collect::<Vec<_>>())
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ use ruma::{
|
||||
};
|
||||
pub use state::*;
|
||||
use thiserror::Error;
|
||||
use tracing::debug;
|
||||
use tracing::{debug, error};
|
||||
|
||||
/// The default `required_state` constant value for sliding sync lists and
|
||||
/// sliding sync room subscriptions.
|
||||
@@ -393,7 +393,15 @@ impl RoomListService {
|
||||
///
|
||||
/// It means that all events from these rooms will be received every time,
|
||||
/// no matter how the `RoomList` is configured.
|
||||
pub fn subscribe_to_rooms(&self, room_ids: &[&RoomId]) {
|
||||
///
|
||||
/// [`LatestEvents::listen_to_room`][listen_to_room] will be called for each
|
||||
/// room in `room_ids`, so that the [`LatestEventValue`] will automatically
|
||||
/// be calculated and updated for these rooms, for free.
|
||||
///
|
||||
/// [listen_to_room]: matrix_sdk::latest_events::LatestEvents::listen_to_room
|
||||
/// [`LatestEventValue`]: matrix_sdk::latest_events::LatestEventValue
|
||||
pub async fn subscribe_to_rooms(&self, room_ids: &[&RoomId]) {
|
||||
// Calculate the settings for the room subscriptions.
|
||||
let settings = assign!(http::request::RoomSubscription::default(), {
|
||||
required_state: DEFAULT_REQUIRED_STATE.iter().map(|(state_event, value)| {
|
||||
(state_event.clone(), (*value).to_owned())
|
||||
@@ -407,6 +415,7 @@ impl RoomListService {
|
||||
timeline_limit: UInt::from(DEFAULT_ROOM_SUBSCRIPTION_TIMELINE_LIMIT),
|
||||
});
|
||||
|
||||
// Decide whether the in-flight request (if any) should be cancelled if needed.
|
||||
let cancel_in_flight_request = match self.state_machine.get() {
|
||||
State::Init | State::Recovering | State::Error { .. } | State::Terminated { .. } => {
|
||||
false
|
||||
@@ -414,6 +423,19 @@ impl RoomListService {
|
||||
State::SettingUp | State::Running => true,
|
||||
};
|
||||
|
||||
// Before subscribing, let's listen these rooms to calculate their latest
|
||||
// events.
|
||||
let latest_events = self.client.latest_events().await;
|
||||
|
||||
for room_id in room_ids {
|
||||
if let Err(error) = latest_events.listen_to_room(room_id).await {
|
||||
// Let's not fail the room subscription. Instead, emit a log because it's very
|
||||
// unlikely to happen.
|
||||
error!(?error, ?room_id, "Failed to listen to the latest event for this room");
|
||||
}
|
||||
}
|
||||
|
||||
// Subscribe to the rooms.
|
||||
self.sliding_sync.subscribe_to_rooms(room_ids, Some(settings), cancel_in_flight_request)
|
||||
}
|
||||
|
||||
|
||||
@@ -2247,7 +2247,7 @@ async fn test_room_subscription() -> Result<(), Error> {
|
||||
|
||||
// Subscribe.
|
||||
|
||||
room_list.subscribe_to_rooms(&[room_id_1]);
|
||||
room_list.subscribe_to_rooms(&[room_id_1]).await;
|
||||
|
||||
sync_then_assert_request_and_fake_response! {
|
||||
[server, room_list, sync]
|
||||
@@ -2290,7 +2290,7 @@ async fn test_room_subscription() -> Result<(), Error> {
|
||||
|
||||
// Subscribe to another room.
|
||||
|
||||
room_list.subscribe_to_rooms(&[room_id_2]);
|
||||
room_list.subscribe_to_rooms(&[room_id_2]).await;
|
||||
|
||||
sync_then_assert_request_and_fake_response! {
|
||||
[server, room_list, sync]
|
||||
@@ -2333,7 +2333,7 @@ async fn test_room_subscription() -> Result<(), Error> {
|
||||
|
||||
// Subscribe to an already subscribed room. Nothing happens.
|
||||
|
||||
room_list.subscribe_to_rooms(&[room_id_1]);
|
||||
room_list.subscribe_to_rooms(&[room_id_1]).await;
|
||||
|
||||
sync_then_assert_request_and_fake_response! {
|
||||
[server, room_list, sync]
|
||||
|
||||
@@ -325,7 +325,7 @@ impl App {
|
||||
modifiers: KeyModifiers::CONTROL,
|
||||
..
|
||||
}) => {
|
||||
self.room_list.next_room();
|
||||
self.room_list.next_room().await;
|
||||
let room_id = self.room_list.get_selected_room_id();
|
||||
self.room_view.set_selected_room(room_id);
|
||||
}
|
||||
@@ -333,7 +333,7 @@ impl App {
|
||||
Event::Key(KeyEvent {
|
||||
code: Char('k') | Up, modifiers: KeyModifiers::CONTROL, ..
|
||||
}) => {
|
||||
self.room_list.previous_room();
|
||||
self.room_list.previous_room().await;
|
||||
let room_id = self.room_list.get_selected_room_id();
|
||||
self.room_view.set_selected_room(room_id);
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ impl RoomList {
|
||||
/// Focus the list on the next item, wraps around if needs be.
|
||||
///
|
||||
/// Returns the index only if there was a meaningful change.
|
||||
pub fn next_room(&mut self) {
|
||||
pub async fn next_room(&mut self) {
|
||||
let num_items = self.rooms.lock().len();
|
||||
|
||||
// If there's no item to select, leave early.
|
||||
@@ -83,14 +83,14 @@ impl RoomList {
|
||||
|
||||
if prev != Some(new) {
|
||||
self.state.select(Some(new));
|
||||
self.subscribe_to_room(new);
|
||||
self.subscribe_to_room(new).await;
|
||||
}
|
||||
}
|
||||
|
||||
/// Focus the list on the previous item, wraps around if needs be.
|
||||
///
|
||||
/// Returns the index only if there was a meaningful change.
|
||||
pub fn previous_room(&mut self) {
|
||||
pub async fn previous_room(&mut self) {
|
||||
let num_items = self.rooms.lock().len();
|
||||
|
||||
// If there's no item to select, leave early.
|
||||
@@ -105,7 +105,7 @@ impl RoomList {
|
||||
|
||||
if prev != Some(new) {
|
||||
self.state.select(Some(new));
|
||||
self.subscribe_to_room(new);
|
||||
self.subscribe_to_room(new).await;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ impl RoomList {
|
||||
}
|
||||
|
||||
/// Subscribe to room that is shown at the given `index`.
|
||||
fn subscribe_to_room(&mut self, index: usize) {
|
||||
async fn subscribe_to_room(&mut self, index: usize) {
|
||||
// Cancel the subscription to the previous room, if any.
|
||||
self.current_room_subscription.take();
|
||||
|
||||
@@ -129,7 +129,7 @@ impl RoomList {
|
||||
if let Some(room) =
|
||||
self.get_room_id_of_entry(index).and_then(|room_id| self.client.get_room(&room_id))
|
||||
{
|
||||
self.sync_service.room_list_service().subscribe_to_rooms(&[room.room_id()]);
|
||||
self.sync_service.room_list_service().subscribe_to_rooms(&[room.room_id()]).await;
|
||||
self.current_room_subscription = Some(room);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user