From 3a25608a6e91c90a52de3e40c55fa9757b3ff087 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 10 May 2023 13:31:52 +0200 Subject: [PATCH] feat(sdk): Rethink the `SlidingSyncList::state` after a reset. A `SlidingSyncList` has a state, which can be either `NotLoaded`, `Preloaded`, `PartiallyLoaded`, or `FullyLoaded`. A `SlidingSyncList` can be reset, either manually when `SlidingSyncList::reset` is called, or when a range is updated for example. Resetting a list is modifying its state. Prior to this patch, the state was set to `NotLoaded`. However, it's not entirely true. This patch updates this behavior to the following rules: * When the state is `NotLoaded`, it's kept at this state as nothing has happened yet, * When the state is `Preloaded`, the list is restored from the cache, but nothing has happened yet too, so it's kept at this state, * When the state is `PartiallyLoaded` or `FullyLoaded`, it means some (or all) updates have been done, so the new state is `PartiallyLoaded` after the reset. The list' state is used mostly by the client to know whether a loader should be prompted to the users. The ranges are modified when the users scroll inside the room list for example: scrolling in the room list doesn't imply the state should go to `NotLoaded`. Some data have potentially be loaded, so changing the ranges should result in a `PartiallyLoaded` state. It seems more logical once explained like this. --- .../matrix-sdk/src/sliding_sync/list/mod.rs | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/crates/matrix-sdk/src/sliding_sync/list/mod.rs b/crates/matrix-sdk/src/sliding_sync/list/mod.rs index 91a370ca7..54528c0bd 100644 --- a/crates/matrix-sdk/src/sliding_sync/list/mod.rs +++ b/crates/matrix-sdk/src/sliding_sync/list/mod.rs @@ -311,7 +311,19 @@ impl SlidingSyncListInner { /// Call this method when it's necessary to reset `Self`. fn reset(&self) { self.request_generator.write().unwrap().reset(); - Observable::set(&mut self.state.write().unwrap(), SlidingSyncState::NotLoaded); + { + let mut state = self.state.write().unwrap(); + + let next_state = match **state { + SlidingSyncState::NotLoaded => SlidingSyncState::NotLoaded, + SlidingSyncState::Preloaded => SlidingSyncState::Preloaded, + SlidingSyncState::PartiallyLoaded | SlidingSyncState::FullyLoaded => { + SlidingSyncState::PartiallyLoaded + } + }; + + Observable::set(&mut state, next_state); + } } // Update the state to the next request, and return it. @@ -1439,7 +1451,7 @@ mod tests { assert_ranges! { list = list, - list_state = NotLoaded, + list_state = PartiallyLoaded, maximum_number_of_rooms = 25, next => { ranges = [3; 7], @@ -1452,7 +1464,7 @@ mod tests { assert_ranges! { list = list, - list_state = NotLoaded, + list_state = PartiallyLoaded, maximum_number_of_rooms = 25, next => { ranges = [3; 7], [10; 23], @@ -1465,7 +1477,7 @@ mod tests { assert_ranges! { list = list, - list_state = NotLoaded, + list_state = PartiallyLoaded, maximum_number_of_rooms = 25, next => { ranges = [42; 77], @@ -1478,12 +1490,12 @@ mod tests { assert_ranges! { list = list, - list_state = NotLoaded, + list_state = PartiallyLoaded, maximum_number_of_rooms = 25, next => { ranges = , is_fully_loaded = true, - list_state = NotLoaded, // Is this correct? + list_state = PartiallyLoaded, }, }; }