From 94b76168e89cb1f9a26bcdbf5c8016b6b059e8da Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 6 May 2025 16:21:02 +0200 Subject: [PATCH] refactor(ui): Add `ObservableItemsTransaction::has_local`. 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. --- .../src/timeline/controller/observable_items.rs | 9 ++++++++- .../src/timeline/controller/state_transaction.rs | 4 +--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/crates/matrix-sdk-ui/src/timeline/controller/observable_items.rs b/crates/matrix-sdk-ui/src/timeline/controller/observable_items.rs index 84d55e716..bf586dfcb 100644 --- a/crates/matrix-sdk-ui/src/timeline/controller/observable_items.rs +++ b/crates/matrix-sdk-ui/src/timeline/controller/observable_items.rs @@ -320,11 +320,18 @@ impl<'observable_items> ObservableItemsTransaction<'observable_items> { self.push_back(timeline_item, None); } + /// Check whether there is at least one [`Local`] timeline item. + /// + /// [`Local`]: super::EventTimelineItemKind::Local + pub fn has_local(&self) -> bool { + matches!(self.items.last(), Some(timeline_item) if timeline_item.is_local_echo()) + } + /// Push a new [`TimelineStart`] virtual timeline item. /// /// # Invariant /// - /// A [`TimelineStart`] is always the first item if present.. + /// A [`TimelineStart`] is always the first item if present. /// /// # Panics /// diff --git a/crates/matrix-sdk-ui/src/timeline/controller/state_transaction.rs b/crates/matrix-sdk-ui/src/timeline/controller/state_transaction.rs index 5ae342b67..97b29792d 100644 --- a/crates/matrix-sdk-ui/src/timeline/controller/state_transaction.rs +++ b/crates/matrix-sdk-ui/src/timeline/controller/state_transaction.rs @@ -476,14 +476,12 @@ impl<'a> TimelineStateTransaction<'a> { } pub(super) fn clear(&mut self) { - let has_local_echoes = self.items.iter().any(|item| item.is_local_echo()); - // By first checking if there are any local echoes first, we do a bit // more work in case some are found, but it should be worth it because // there will often not be any, and only emitting a single // `VectorDiff::Clear` should be much more efficient to process for // subscribers. - if has_local_echoes { + if self.items.has_local() { // Remove all remote events and virtual items that aren't date dividers. self.items.for_each(|entry| { if entry.is_remote_event()