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:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user