-
Notifications
You must be signed in to change notification settings - Fork 290
fix(ui): Introduce Timeline
regions
#5000
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(ui): Introduce Timeline
regions
#5000
Conversation
This patch fixes the insertion of a new `TimelineItem` in the presence of a `TimelineStart` that shifts/offsets the timeline index of 1.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5000 +/- ##
==========================================
- Coverage 85.86% 85.85% -0.01%
==========================================
Files 325 325
Lines 35851 35929 +78
==========================================
+ Hits 30783 30848 +65
- Misses 5068 5081 +13 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
This patch improves the `assert_timeline_stream` macro by adding a bunch of assert messages in case it fails.
This patch adds a regression test ensuring [this bug][4976] cannot happen anymore. [4976]: matrix-org#4976
TimelineStart
Timeline
regions
…_missing`. This patch adds the `push_timeline_start_if_missing` method on `ObservableItemsTransaction` to add semantics and hardcode the invariant in a single place for the different timeline items.
This patch adds the `push_local` method on `ObservableItemsTransaction` to add semantics and hardcode the invariant in a single place for the different timeline items.
This patch implements the `has_local` method on `ObservableItemsTransaction`, which is way faster than the previous the previous solution which was to iterate over all items to find at least one local timeline item.
This patch defines a new concept in the `Timeline`: Regions. The `ObservableItems` holds all the invariants about the _position_ of the items. It defines three regions where items can live: 1. the _start_ region, which can only contain a single `TimelineStart`, 2. the _remotes_ region, which can only contain many `Remote` timeline items with their decorations (only `DateDivider`s and `ReadMarker`s), 3. the _locals_ region, which can only contain many `Local` timeline items with their decorations (only `DateDivider`s). The `iter_all_regions` method allows to iterate over all regions. `iter_remotes_region` will restrict the iterator over the _remotes_ region, and so on. These iterators provide the absolute indices of the items, so that it's harder to make mistakes when manipulating the indices of items with operations like `insert`, `remove`, `replace` etc. Other methods like `push_local` or `push_date_divider` insert the items in the correct region, and check a couple of invariants.
…egions. This patch updates `DateDividerAdjuster` to work on _remotes_ and _locals_ regions only, excluding the _start_ region. It helps to reduce the risk of inserting a `DateDivider` inside the _start_ region. This patch also uses the new `push_date_divider` method, which provides a couple of invariants.
This patch updates `ReadReceiptTimelineUpdate` to work on the _remotes_ region only, excluding the _start_ and the _lcoals_ regions. It helps to reduce the risk of inserting a `ReadMarker` inside the _start_ or the _locals_ regions.
This patch updates `TimelineMetadata` to work on the _remotes_ region only, excluding the _start_ and the _locals_ regions. It helps to reduce the risk of inserting items in an incorrect regions. This patch also removes on more `rfind_event_by_id` usage, which is nice.
… regions. This patch updates `TimelineStateTransaction` to work on the correct regions, _remotes_ in one place, and all regions in another place.
…id bugs. This patch updates `EventHandler` to use the correct regions where appropriate, thus reducing the complexity of the code, and removing classes of bugs. In the case of `Flow::Remote { position: TimelineItemPosition::At { … }}`, we no longer need to skip the local timeline items, and to handle the presence of the `TimelineStart` timeline item. The code is less complex. In the case of `Flow::Remote { position: TimelineItemPosition::End { … }}`, that's exactly the same at the previous case. In the case of `recycle_local_or_create_item`, the `try_fold` approach is replaced entirely with a simple `iter_locals_region`, reducing the size of the comments explaining the code, reducing the complexity of the code, and reducing the surface of bugs.
466eee2
to
0122d11
Compare
4f88a34
to
29ae0eb
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really good change, thanks!
/// Return the index where to insert the first remote timeline | ||
/// item. | ||
pub fn first_remotes_region_index(&self) -> usize { | ||
if self.items.get(0).is_some_and(|item| item.is_timeline_start()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be nice to have a method for this check too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What check would you like to add?
This patch is twofold.
First part
This patch fixes the insertion of a new
TimelineItem
in the presence of aTimelineStart
that shifts/offsets the timeline index of 1. It fixes #4976. It also contains a regression test.Second part
Based on #4816 (review), I'm proposing a new concept in
timeline::controller::ObservableItems
: regions.The
ObservableItems
holds all the invariants about the position of the items. It defines three regions where items can live:TimelineStart
,Remote
timeline items with their decorations (onlyDateDivider
s andReadMarker
s),Local
timeline items with their decorations (onlyDateDivider
s).The
iter_all_regions
method allows to iterate over all regions.iter_remotes_region
will restrict the iterator over the remotes region, and so on. These iterators provide the absolute indices of the items, so that it's harder to make mistakes when manipulating the indices of items with operations likeinsert
,remove
,replace
etc.Other methods like
push_local
orpush_date_divider
insert the items in the correct region, and check a couple of invariants. I've first introduced the invariants, then 12 tests were failing, which indicates that theTimelineStart
could have been a problem in multiple situations. Moving the code to useiter_remotes_regions
& siblings have fixed the tests, which indicates that this class of bugs has been fixed.Review
It's better to review patch-by-patch. There are quite small and I hope easy to understand. The concept of regions removes an entire class of bugs in our
Timeline
, and I'm pretty happy with that 🙂.Timeline
only containsTimelineStart
, new events are pushed in front ofTimelineStart
#4976