feat(ui): Use an initial limit in room list dynamic entries.

In `RoomList::entries_with_dynamic_adapters`, we were using the
`Limit::dynamic` constructor. It builds a `Limit` stream adapter where
the limits come from a `Stream`. The immediate impact is that this
constructor does only return a new `Stream`, but it cannot return
the initial items of the vector. Thus, it wasn't possible to reset
the final `Stream` with a `VectorDiff::Reset { values }`. Instead, we
were emitting a `Clear` (from this code) then a `Append` (from the
`Limit` stream). Sadly, for some client apps, like Element X iOS, these
2 diffs (`Clear` and `Append`) result in a “rendering blink”.

Hopefully for us, now there is new constructors for `Limit`! One of them
is `Limit::dynamic_with_initial_limit`, which returns the initial items
along with the new `Stream`. That's perfect, we can reset the final
`Stream` with `Reset { values }` again, thus removing the “UI blinking”
effect in Element X iOS.

This patch switches `Limit::dynamic` to
`Limit::dynamic_with_initial_limit`, and updates/simplifies the tests
accordingly.
This commit is contained in:
Ivan Enderlin
2023-09-18 09:42:50 +02:00
parent b7240b898c
commit 0f7e5ba4b0
2 changed files with 12 additions and 48 deletions
@@ -132,13 +132,13 @@ impl RoomList {
let filter_fn_cell = AsyncCell::shared();
let dynamic_limit = SharedObservable::<usize>::new(0);
let dynamic_limit_stream = dynamic_limit.subscribe();
let limit = SharedObservable::<usize>::new(page_size);
let limit_stream = limit.subscribe();
let dynamic_entries_controller = RoomListDynamicEntriesController::new(
filter_fn_cell.clone(),
page_size,
dynamic_limit.clone(),
limit.clone(),
list.maximum_number_of_rooms_stream(),
);
@@ -146,12 +146,10 @@ impl RoomList {
loop {
let filter_fn = filter_fn_cell.take().await;
let (items, stream) = list.room_list_filtered_stream(filter_fn);
let stream = Limit::dynamic(items, stream, dynamic_limit_stream.clone());
dynamic_limit.set(page_size);
let (items, stream) = Limit::dynamic_with_initial_limit(items, stream, page_size, limit_stream.clone());
// Clearing the stream before chaining with the real stream.
yield stream::once(ready(vec![VectorDiff::Clear]))
yield stream::once(ready(vec![VectorDiff::Reset { values: items }]))
.chain(stream);
}
}
@@ -190,22 +190,6 @@ macro_rules! assert_entries_batch {
)
};
// `clear`
( @_ [ $entries:ident ] [ clear ; $( $rest:tt )* ] [ $( $accumulator:tt )* ] ) => {
assert_entries_batch!(
@_
[ $entries ]
[ $( $rest )* ]
[
$( $accumulator )*
assert_eq!(
$entries.next(),
Some(&VectorDiff::Clear),
);
]
)
};
// `truncate [$length]`
( @_ [ $entries:ident ] [ truncate [ $length:literal ] ; $( $rest:tt )* ] [ $( $accumulator:tt )* ] ) => {
assert_entries_batch!(
@@ -1659,14 +1643,8 @@ async fn test_dynamic_entries_stream() -> Result<(), Error> {
// Assert the dynamic entries.
assert_entries_batch! {
[dynamic_entries_stream]
// Receive a `clear` because the filter has been reset/set for the first time.
clear;
end;
};
assert_entries_batch! {
[dynamic_entries_stream]
// Receive the initial values.
append [ F("!r0:bar.org") ];
// Receive a `reset` because the filter has been reset/set for the first time.
reset [ F("!r0:bar.org") ];
end;
};
assert_pending!(dynamic_entries_stream);
@@ -1821,16 +1799,10 @@ async fn test_dynamic_entries_stream() -> Result<(), Error> {
// Assert the dynamic entries.
assert_entries_batch! {
[dynamic_entries_stream]
// Receive a `clear` again because the filter has been reset.
clear;
// Receive a `reset` again because the filter has been reset.
reset [ F("!r2:bar.org"), F("!r3:bar.org"), F("!r6:bar.org") ];
end;
}
assert_entries_batch! {
[dynamic_entries_stream]
// Receive the new initial values.
append [ F("!r2:bar.org"), F("!r3:bar.org"), F("!r6:bar.org") ];
end;
};
assert_pending!(dynamic_entries_stream);
// Now, let's change again the dynamic filter!
@@ -1839,14 +1811,8 @@ async fn test_dynamic_entries_stream() -> Result<(), Error> {
// Assert the dynamic entries.
assert_entries_batch! {
[dynamic_entries_stream]
// Receive a `clear` again because the filter has been reset.
clear;
end;
}
assert_entries_batch! {
[dynamic_entries_stream]
// Receive the new initial values.
append [
// Receive a `reset` again because the filter has been reset.
reset [
F("!r0:bar.org"),
F("!r1:bar.org"),
F("!r2:bar.org"),
@@ -1855,7 +1821,7 @@ async fn test_dynamic_entries_stream() -> Result<(), Error> {
// Stop! The page is full :-).
];
end;
};
}
assert_pending!(dynamic_entries_stream);
// Let's ask one more page.