mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-18 21:52:30 -04:00
feat(ui): Add the RoomList Input API.
This patch lands the first design of the `Input` API. An `Input` is something external that can be understood by the `RoomList` state machine. The first inpuput is `Viewport` to change the “viewport” of the `RoomList`, which translates to the change of the ranges of one specific Sliding Sync list.
This commit is contained in:
@@ -10,7 +10,8 @@ use futures_util::{pin_mut, Stream, StreamExt};
|
||||
use imbl::Vector;
|
||||
pub use matrix_sdk::RoomListEntry;
|
||||
use matrix_sdk::{
|
||||
Client, Error as SlidingSyncError, SlidingSync, SlidingSyncList, SlidingSyncMode,
|
||||
sliding_sync::Ranges, Client, Error as SlidingSyncError, SlidingSync, SlidingSyncList,
|
||||
SlidingSyncMode,
|
||||
};
|
||||
use once_cell::sync::Lazy;
|
||||
use thiserror::Error;
|
||||
@@ -115,6 +116,25 @@ impl RoomList {
|
||||
.ok_or_else(|| Error::UnknownList(ALL_ROOMS_LIST_NAME.to_string()))
|
||||
}
|
||||
|
||||
pub async fn apply_input(&self, input: Input) -> Result<(), Error> {
|
||||
use Input::*;
|
||||
|
||||
match input {
|
||||
Viewport(ranges) => {
|
||||
self.sliding_sync
|
||||
.on_list(VISIBLE_ROOMS_LIST_NAME, |list| {
|
||||
ready(list.set_sync_mode(
|
||||
SlidingSyncMode::new_selective().add_ranges(ranges.clone()),
|
||||
))
|
||||
})
|
||||
.await
|
||||
.ok_or_else(|| Error::InputHasNotBeenApplied(Viewport(ranges)))?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "testing"))]
|
||||
pub fn sliding_sync(&self) -> &SlidingSync {
|
||||
&self.sliding_sync
|
||||
@@ -136,6 +156,9 @@ pub enum Error {
|
||||
|
||||
#[error("Failed to acquire a lock to update the entries filter")]
|
||||
CannotUpdateEntriesFilter,
|
||||
|
||||
#[error("The input has been not applied")]
|
||||
InputHasNotBeenApplied(Input),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
@@ -257,6 +280,11 @@ impl Actions {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Input {
|
||||
Viewport(Ranges),
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use matrix_sdk::{config::RequestConfig, Session};
|
||||
|
||||
@@ -5,7 +5,7 @@ use imbl::vector;
|
||||
use matrix_sdk_test::async_test;
|
||||
use matrix_sdk_ui::{
|
||||
room_list::{
|
||||
Error, RoomListEntry, State, ALL_ROOMS_LIST_NAME as ALL_ROOMS,
|
||||
Error, Input, RoomListEntry, State, ALL_ROOMS_LIST_NAME as ALL_ROOMS,
|
||||
VISIBLE_ROOMS_LIST_NAME as VISIBLE_ROOMS,
|
||||
},
|
||||
RoomList,
|
||||
@@ -724,3 +724,79 @@ async fn test_entries_stream_with_updated_filter() -> Result<(), Error> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
async fn test_input_viewport() -> Result<(), Error> {
|
||||
let (server, room_list) = new_room_list().await?;
|
||||
|
||||
let sync = room_list.sync();
|
||||
pin_mut!(sync);
|
||||
|
||||
// The input cannot be applied because the `VISIBLE_ROOMS_LIST_NAME` list isn't
|
||||
// present.
|
||||
assert_matches!(
|
||||
room_list.apply_input(Input::Viewport(vec![10..=15])).await,
|
||||
Err(Error::InputHasNotBeenApplied(_))
|
||||
);
|
||||
|
||||
sync_then_assert_request_and_fake_response! {
|
||||
[server, room_list, sync]
|
||||
states = Init -> FirstRooms,
|
||||
assert request = {
|
||||
"lists": {
|
||||
ALL_ROOMS: {
|
||||
"ranges": [[0, 19]],
|
||||
},
|
||||
},
|
||||
},
|
||||
respond with = {
|
||||
"pos": "0",
|
||||
"lists": {},
|
||||
"rooms": {},
|
||||
},
|
||||
};
|
||||
|
||||
sync_then_assert_request_and_fake_response! {
|
||||
[server, room_list, sync]
|
||||
states = FirstRooms -> AllRooms,
|
||||
assert request = {
|
||||
"lists": {
|
||||
ALL_ROOMS: {
|
||||
"ranges": [[0, 49]],
|
||||
},
|
||||
VISIBLE_ROOMS: {
|
||||
"ranges": [],
|
||||
}
|
||||
}
|
||||
},
|
||||
respond with = {
|
||||
"pos": "1",
|
||||
"lists": {},
|
||||
"rooms": {},
|
||||
},
|
||||
};
|
||||
|
||||
assert!(room_list.apply_input(Input::Viewport(vec![10..=15, 20..=25])).await.is_ok());
|
||||
|
||||
sync_then_assert_request_and_fake_response! {
|
||||
[server, room_list, sync]
|
||||
states = AllRooms -> Enjoy,
|
||||
assert request = {
|
||||
"lists": {
|
||||
ALL_ROOMS: {
|
||||
"ranges": [[0, 49]],
|
||||
},
|
||||
VISIBLE_ROOMS: {
|
||||
"ranges": [[10, 15], [20, 25]],
|
||||
}
|
||||
}
|
||||
},
|
||||
respond with = {
|
||||
"pos": "1",
|
||||
"lists": {},
|
||||
"rooms": {},
|
||||
},
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user