Commit Graph

13223 Commits

Author SHA1 Message Date
Kévin Commaille
0f4b3aa187 Merge branch 'main' into media-cache-auto-cleanup 2025-02-05 00:12:18 +01:00
Ivan Enderlin
8a7658745d chore: Fallback to jplatte/eyeball instead of Hywan/eyeball's fork. 2025-02-04 19:43:38 +01:00
Ivan Enderlin
2ea39877cc fix: Add github.com/Hywan/eyeball in the allow-git list. 2025-02-04 19:43:38 +01:00
Ivan Enderlin
4212691cf0 fix(ui): Don't use 0 as the initial value for Skip.
This patch fixes an issue where 0 was used as the initial value for
the `Skip` higher-order stream in the `TimelineSubscriber`. This is
wrong, as the `SkipCount` value may have been modified before the
`TimelineSubscriber` is created.

This patch provides a test to reproduce the problem.
2025-02-04 19:43:38 +01:00
Ivan Enderlin
d66fe79579 task(ui): Create TimelineSubscriber.
This patch gathers the logic of the `Timeline::subscribe` into a single
type: `TimelineSubscriber`.

The `TimelineController::subscribe_batched_and_limited` method is
renamed `subscribe` to match `Timeline::subscribe`. Things are simpler
to apprehend.

The `TimelineSubscriber` type configures the subscriber/stream in a
single place. It takes an `&ObservableItems` and a `&SkipCount`, and
configures everything. It also provides a single place to document the
behaviour of the subscriber, with the `Skip` higher-order stream.
2025-02-04 19:43:38 +01:00
Ivan Enderlin
88caf11842 chore(ui): Rename Timeline::subscribe to subscribe_raw.
This patch renames the (test only) `Timeline::subscribe` method to
`Timeline::subscribe_raw`.
2025-02-04 19:43:38 +01:00
Ivan Enderlin
5320d952e5 test(ui): Test the Timeline lazy backwards pagination. 2025-02-04 19:43:38 +01:00
Ivan Enderlin
7eae832b8c test: set_timeline_prev_batch takes anything that implements Into<String>. 2025-02-04 19:43:38 +01:00
Ivan Enderlin
1d18ab03d7 test(ui): Improve the assert_timeline_stream macro. 2025-02-04 19:43:38 +01:00
Ivan Enderlin
337bc2c097 doc(ui): Fix a typo. 2025-02-04 19:43:38 +01:00
Ivan Enderlin
7e59ae99d0 featui): Timeline::subscribe() supports lazy backwards pagination.
This patch updates the pagination mechanism of the `Timeline` to support
lazy backwards pagination.

`Timeline::paginate_backwards` already does different things whether the
timeline focus is live or focused. When it's live, the method will first
try to paginate backwards lazily, by adjusting the `count` value of the
`Skip` stream used by the `Timeline::subscribe` method. If there is not
enough items to provide, the greedy pagination will run.
2025-02-04 19:43:38 +01:00
Ivan Enderlin
51feda1042 task(ui): TimelineStateTransaction::commit adjusts the Skip's count.
This patch updates `TimelineStateTransaction::commit` to adjust the
count value of the `Skip` higher-order stream.

This patch also creates `TimelineStateTransaction::new` to simplify the
creation of a state transaction.
2025-02-04 19:43:38 +01:00
Ivan Enderlin
0a520e4f9f task(ui): Apply the Skip higher-order stream for the Timeline.
This patch applies the `Skip` higher-order stream on the `Timeline`
subscriber. The method `TimelineController::subscribe_batched` is
renamed `subscribe_batched_and_limited` at the same time.

The `Skip` stream uses the `TimelineMetadata::subscriber_skip_count`
observable value as the `count_stream`. The initial count value is 0.

No test needs to be changed so far.
2025-02-04 19:43:38 +01:00
Ivan Enderlin
e07212d356 task(ui): Add TimelineMetadata::subscriber_skip_count.
This patch adds the `subscriber_skip_count` field to `TimelineMetadata`.
It's going to be used to define the `count` value of the `Skip`
higher-order stream that is going to be applied to the `Timeline`
subscriber.
2025-02-04 19:43:38 +01:00
Ivan Enderlin
1d52073b45 task(ui): Add the SkipCount type to help computing the count for Skip.
This patch adds functions like `compute_next`,
`compute_next_when_paginating_backwards` and
`compute_next_when_paginating_forwards`, which are necessary to
correctly compute the `count` value for the `Skip` higher-order stream.

This patch adds the associated test suite.
2025-02-04 19:43:38 +01:00
Ivan Enderlin
d85d6cfbca refactor(ui): Rename TimelineStream to TimelineWithDropHandle.
This patch renames `TimelineStream` to `TimelineWithDropHandle`, as the
former name was too vague and was not clarify what the type was doing.
The new name makes it clear that it attaches a `TimelineDropHandle` to a
subscriber (since it is part of the `subscriber` module!).
2025-02-04 19:43:38 +01:00
Ivan Enderlin
892cb9116c refactor(ui): Move TimelineStream into the new subscriber module.
This patch moves the `TimelineStream` type into the new `subscriber`
module. The idea is to add more code related to subscribers in the next
patches.
2025-02-04 19:43:38 +01:00
Ivan Enderlin
5e9d291ca3 chore(ui): Clone items only once when subscribing.
This patch updates `TimelineController::subscribe` to use
`VectorSubscriber::into_values_and_batched_stream`. It returns
the cloned items along with the stream. It saves the need to call
`ObservableItems::clone_items`, thus saving the clone of all items.

tl;dr: `clone_items()` clones… items… and `subscribe()` also clones the
items. There is 2 clones. With `into_values_and_batched_stream()`, there
is 1 clone.
2025-02-04 19:43:38 +01:00
Benjamin Bouvier
b74d64a456 test(timeline): use the MatrixMockServer in integration/timeline/edit 2025-02-04 17:20:02 +01:00
Benjamin Bouvier
cd8f5cf5d4 test(timeline): use the MatrixMockServer in integration/timeline/echo 2025-02-04 17:20:02 +01:00
Benjamin Bouvier
1dc20aa9aa test(timeline): use the MatrixMockServer in integration/timeline/reactions 2025-02-04 17:20:02 +01:00
Ivan Enderlin
bdab9951af doc(changelog): Add entries for the performance improvement patches.
This patch adds #4601, #4608, #4612 and #4616 in their respective
`CHANGELOG.md`s.
2025-02-04 16:59:13 +01:00
Damir Jelić
4c46e42201 chore: Release matrix-sdk version 0.10.0 matrix-sdk-ui-0.10.0 matrix-sdk-0.10.0 matrix-sdk-sqlite-0.10.0 matrix-sdk-indexeddb-0.10.0 matrix-sdk-base-0.10.0 matrix-sdk-store-encryption-0.10.0 matrix-sdk-crypto-0.10.0 matrix-sdk-test-0.10.0 matrix-sdk-test-macros-0.10.0 matrix-sdk-qrcode-0.10.0 matrix-sdk-common-0.10.0 2025-02-04 16:32:55 +01:00
Damir Jelić
0d4bc65e28 chore: Enable releases for the test crates 2025-02-04 16:32:55 +01:00
Jorge Martín
5e1bae02fe feat(ffi): Add RoomPreview::forget action in the FFI layer 2025-02-04 16:26:15 +01:00
Ivan Enderlin
77a67de7df fix(ui): Fix performance of ReadReceiptTimelineUpdate::apply.
This patch improves the performance of
`ReadReceiptTimelineUpdate::apply`, which does 2 things: it calls
`remove_old_receipt` and `add_new_receipt`. Both of them need an
timeline item position. Until this patch, `rfind_event_by_id` was used
and was the bottleneck. The improvement is twofold as is as follows.

First off, when collecting data to create `ReadReceiptTimelineUpdate`,
the timeline item position can be known ahead of time by using
`EventMeta::timeline_item_index`. This data is not always available, for
example if the timeline item isn't created yet. But let's try to collect
these data if there are some.

Second, inside `ReadReceiptTimelineUpdate::remove_old_receipt`, we use
the timeline item position collected from `EventMeta` if it exists.
Otherwise, let's fallback to a similar `rfind_event_by_id` pattern,
without using intermediate types. It's more straightforward here: we
don't need an `EventTimelineItemWithId`, we only need the position.
Once the position is known, it is stored in `Self` (!), this is the
biggest improvement here. Le't see why.

Finally, inside `ReadReceiptTimelineUpdate::add_new_receipt`, we use
the timeline item position collected from `EventMeta` if it exists,
similarly to what `remove_old_receipt` does. Otherwise, let's fallback
to an iterator to find the position. However, instead of iterating over
**all** items, we can skip the first ones, up to the position of the
timeline item holding the old receipt, so up to the position found by
`remove_old_receipt`.

I'm testing this patch with the `test_lazy_back_pagination` test in
https://github.com/matrix-org/matrix-rust-sdk/pull/4594. With 10_000
events in the sync, the `ReadReceipts::maybe_update_read_receipt` method
was taking 52% of the whole execution time. With this patch, it takes
8.1%.
2025-02-04 16:02:29 +01:00
JoFrost
f27eb4d1c8 fix[oidc]: fix docstring in oidc module 2025-02-04 15:33:28 +01:00
Jorge Martín
05814c5559 refactor(ffi): Map client API errors to ClientError::MatrixApi, containing the error kind, their error code and the associated message 2025-02-04 12:25:51 +01:00
Kévin Commaille
d5d9898fb4 feat: Upgrade Ruma to 0.12.1
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2025-02-04 12:00:40 +01:00
Kévin Commaille
f641a639cd Merge branch 'main' into media-cache-auto-cleanup 2025-02-04 11:56:32 +01:00
Ivan Enderlin
3f71d9a379 fix(sdk): Improve performance of RoomEvents::maybe_apply_new_redaction.
This patch improves the performance of
`RoomEvents::maybe_apply_new_redaction`. This method deserialises
all the events it receives, entirely. If the event is not an
`m.room.redaction`, then the method returns early. Most of the time,
the event is deserialised for nothing because most events aren't of kind
`m.room.redaction`!

This patch first uses `Raw::get_field("type")` to detect the type of
the event. If it's a `m.room.redaction`, then the event is entirely
deserialized, otherwise the method returns.

When running the `test_lazy_back_pagination` from
https://github.com/matrix-org/matrix-rust-sdk/pull/4594 with 10'000
events, prior to this patch, this method takes 11% of the execution
time. With this patch, this method takes 2.5%.
2025-02-04 09:49:58 +01:00
Jorge Martín
b077f45e78 test(room_preview): Add tests for where get_room_preview gets its data from for each room state 2025-02-04 09:33:31 +01:00
Jorge Martín
648d527f2f fix(room_preview): Return room preview info based on local data for banned rooms too
Any remote endpoint would just return a `403` status code so we have no other choice than trusting the local room info we already have.
2025-02-04 09:33:31 +01:00
Jorge Martín
8513547e92 feat(ffi): Add FFI bindings for Room::forget.
Also make sure rooms the user has been banned from can also be forgotten, not only left ones.
2025-02-03 19:48:27 +01:00
dependabot[bot]
d18669e8d9 chore(deps): bump crate-ci/typos from 1.29.4 to 1.29.5
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.29.4 to 1.29.5.
- [Release notes](https://github.com/crate-ci/typos/releases)
- [Changelog](https://github.com/crate-ci/typos/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crate-ci/typos/compare/v1.29.4...v1.29.5)

---
updated-dependencies:
- dependency-name: crate-ci/typos
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-03 16:52:27 +01:00
Benjamin Bouvier
a0426251a3 test(timeline): test that editing a replied-to doesn't lose the latest edit JSON 2025-02-03 16:52:12 +01:00
Benjamin Bouvier
2739c5bf27 test(timeline): test that adding a response or ending a poll doesn't clear the latest edit JSON 2025-02-03 16:52:12 +01:00
Benjamin Bouvier
381f4d419f fix(timeline): don't clear the latest_edit_json under certain conditions 2025-02-03 16:52:12 +01:00
Kévin Commaille
049021fe27 refactor(auth-qrcode): Inline declaration of oauth2 client type
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2025-02-03 11:30:57 +01:00
Kévin Commaille
4db32b15ba chore(auth-qrcode): Update copyright date
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2025-02-03 11:27:58 +01:00
Ivan Enderlin
9ab5547065 fix(ui): Fix performance of AllRemoteEvents::(in|de)crement_all_timeline_item_index_after.
This patch fixes the performance of
`AllRemoteEvents::increment_all_timeline_item_index_after` and
`decrment_all_timeline_item_index_after`.

It appears that the code was previously iterating over all items. This
is a waste of time. This patch updates the code to iterate over all
items in reverse order:

- if `new_timeline_item_index` is 0, we need to shift all items anyways,
  so all items must be traversed, the iterator direction doesn't matter,
- otherwise, it's unlikely we want to traverse all items: the item has
  been either inserted or pushed back, so there is no need to traverse
  the first items; we can also break the iteration as soon as all
  timeline item index after `new_timeline_item_index` has been updated.

I'm testing this patch with the `test_lazy_back_pagination` test in
https://github.com/matrix-org/matrix-rust-sdk/pull/4594. With 10_000
events in the sync, the `ObservableItems::push_back` method (that uses
`AllRemoteEvents::increment_all_timeline_item_index_after`) was taking
7% of the whole execution time. With this patch, it takes 0.7%.
2025-02-03 11:25:48 +01:00
Kévin Commaille
df3cb002a5 chore: Add changelog entries
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2025-02-03 11:22:23 +01:00
Kévin Commaille
6ebd4295b9 feat(sqlite): Limit size of WAL file
The WAL file can grow depending on the transactions that are run. A
critical case is VACUUM which basically writes the content of the DB
file to the WAL file before writing it back to the DB file.

SQLite doesn't try to reduce the size of the file after that unless we
set an explicit limit,
so we could end up taking twice the size of the database on the
filesystem.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2025-02-03 11:22:23 +01:00
Kévin Commaille
c5104d68fd feat(sqlite): Run PRAGMA optimize regularly
As recommended by the SQLite docs.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2025-02-03 11:22:23 +01:00
Kévin Commaille
0064839283 fix(sqlite): Vaccum the SqliteStateStore
It should have been done in the migration of version 7, to reduce the
size of the database on the filesystem after the media cache was moved
to the SqliteEventCacheStore. Better late than never.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2025-02-03 11:22:23 +01:00
Kévin Commaille
2727d72916 fix(timeline): Do not filter out own receipts in load_read_receipts_for_event
Fixes #4517.

It turns out that the bugs found in that test were due to 2 causes:

- First commit: `TestRoomDataProvider` didn't use `initial_user_receipts` but returned hardcoded values.
- Second commit: Our own read receipts were ignored in `TimelineStateTransaction::load_read_receipts_for_event`, although we need to process all read receipts via `ReadReceipts::maybe_update_read_receipt` because it knows how to filter out our own read receipts were needed.
2025-02-03 10:15:25 +00:00
Ivan Enderlin
33a2cc3031 chore(cargo): Bump the minimum stable rust version (MSRV). 2025-02-03 10:27:45 +01:00
Ivan Enderlin
38097f90b2 fix(ui): Fix performance of TimelineEventHandler::deduplicate_local_timeline_item.
This patch drastically improves the performance of
`TimelineEventHandler::deduplicate_local_timeline_item`.

Before this patch, `rfind_event_item` was used to iterate over all
timeline items: for each item in reverse order, if it was an event
timeline item, and if it was a local event timeline item, and if it was
matching the event ID or transaction ID, then a duplicate was found.

The problem is the following: all items are traversed.

However, local event timeline items are always at the back of the items.
Even virtual timeline items are before local event timeline items. Thus,
it is not necessary to traverse all items. It is possible to stop the
iteration as soon as (i) a non event timeline item is met, or (ii) a non
local event timeline item is met.

This patch updates
`TimelineEventHandler::deduplicate_local_timeline_item` to replace to
use of `rfind_event_item` by a custom iterator that stops as soon as a
non event timeline item, or a non local event timeline item, is met, or
—of course— when a local event timeline item is a duplicate.

To do so, [`Iterator::try_fold`] is probably the best companion.
[`Iterator::try_find`] would have been nice, but it is available on
nightlies, not on stable versions of Rust. However, many methods in
`Iterator` are using `try_fold`, like `find` or any other methods that
need to do a “short-circuit”. Anyway, `try_fold` works pretty nice here,
and does exactly what we need.

Our use of `try_fold` is to return a `ControlFlow<Option<(usize,
TimelineItem)>, ()>`. After `try_fold`, we call
`ControlFlow::break_value`, which returns an `Option`. Hence the need
to call `Option::flatten` at the end to get a single `Option` instead of
having an `Option<Option<(usize, TimelineItem)>>`.

I'm testing this patch with the `test_lazy_back_pagination` test in
https://github.com/matrix-org/matrix-rust-sdk/pull/4594. With 10_000
events in the sync, the test was taking 13s to run on my machine. With
this patch, it takes 10s to run. It's a 23% improvement. This
`deduplicate_local_timeline_item` method was taking a large part of the
computation according to the profiler. With this patch, this method is
barely visible in the profiler it is so small.

[`Iterator::try_fold`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.try_fold
[`Iterator::try_find`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.try_find
2025-02-03 10:27:45 +01:00
Ivan Enderlin
47d08683a2 fix(security): Update OpenSSL.
See this note https://rustsec.org/advisories/RUSTSEC-2025-0004.

This patch updates OpenSSL to 0.10.70.
2025-02-03 09:42:58 +01:00
Kévin Commaille
619346acad chore: Add changelog entry for oauth2
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2025-02-02 19:48:50 +01:00