feat(ui): add TimelineFocus associated values for defining whether threaded events should be hidden on those particular timeline instances.

This commit is contained in:
Stefan Ceriu
2025-06-05 15:33:48 +03:00
committed by Benjamin Bouvier
parent 669d91e7e9
commit 96afdeffad
9 changed files with 36 additions and 22 deletions

View File

@@ -63,8 +63,8 @@ impl From<FilterTimelineEventType> for TimelineEventType {
#[derive(uniffi::Enum)]
pub enum TimelineFocus {
Live,
Event { event_id: String, num_context_events: u16 },
Live { hide_threaded_events: bool },
Event { event_id: String, num_context_events: u16, hide_threaded_events: bool },
Thread { root_event_id: String, num_events: u16 },
PinnedEvents { max_events_to_load: u16, max_concurrent_requests: u16 },
}
@@ -76,15 +76,19 @@ impl TryFrom<TimelineFocus> for matrix_sdk_ui::timeline::TimelineFocus {
value: TimelineFocus,
) -> Result<matrix_sdk_ui::timeline::TimelineFocus, Self::Error> {
match value {
TimelineFocus::Live => Ok(Self::Live),
TimelineFocus::Event { event_id, num_context_events } => {
TimelineFocus::Live { hide_threaded_events } => Ok(Self::Live { hide_threaded_events }),
TimelineFocus::Event { event_id, num_context_events, hide_threaded_events } => {
let parsed_event_id =
EventId::parse(&event_id).map_err(|err| FocusEventError::InvalidEventId {
event_id: event_id.clone(),
err: err.to_string(),
})?;
Ok(Self::Event { target: parsed_event_id, num_context_events })
Ok(Self::Event {
target: parsed_event_id,
num_context_events,
hide_threaded_events,
})
}
TimelineFocus::Thread { root_event_id, num_events } => {
let parsed_root_event_id = EventId::parse(&root_event_id).map_err(|err| {

View File

@@ -63,7 +63,7 @@ impl TimelineBuilder {
room: room.clone(),
settings: TimelineSettings::default(),
unable_to_decrypt_hook: None,
focus: TimelineFocus::Live,
focus: TimelineFocus::Live { hide_threaded_events: false },
internal_id_prefix: None,
}
}
@@ -172,7 +172,7 @@ impl TimelineBuilder {
let (room_event_cache, event_cache_drop) = room.event_cache().await?;
let (_, event_subscriber) = room_event_cache.subscribe().await;
let is_live = matches!(focus, TimelineFocus::Live);
let is_live = matches!(focus, TimelineFocus::Live { .. });
let is_pinned_events = matches!(focus, TimelineFocus::PinnedEvents { .. });
let is_room_encrypted = room
.latest_encryption_state()

View File

@@ -183,8 +183,8 @@ impl Default for TimelineSettings {
#[derive(Debug, Clone)]
pub(super) enum TimelineFocusKind {
Live,
Event,
Live { hide_threaded_events: bool },
Event { hide_threaded_events: bool },
Thread { root_event_id: OwnedEventId },
PinnedEvents,
}
@@ -279,13 +279,15 @@ impl<P: RoomDataProvider, D: Decryptor> TimelineController<P, D> {
is_room_encrypted: bool,
) -> Self {
let (focus_data, focus_kind) = match focus {
TimelineFocus::Live => (TimelineFocusData::Live, TimelineFocusKind::Live),
TimelineFocus::Live { hide_threaded_events } => {
(TimelineFocusData::Live, TimelineFocusKind::Live { hide_threaded_events })
}
TimelineFocus::Event { target, num_context_events } => {
TimelineFocus::Event { target, num_context_events, hide_threaded_events } => {
let paginator = Paginator::new(room_data_provider.clone());
(
TimelineFocusData::Event { paginator, event_id: target, num_context_events },
TimelineFocusKind::Event,
TimelineFocusKind::Event { hide_threaded_events },
)
}

View File

@@ -199,13 +199,15 @@ impl TimelineState {
thread_root: &Option<OwnedEventId>,
) -> bool {
match &timeline_focus {
TimelineFocusKind::Live => thread_root.is_none(),
TimelineFocusKind::Live { hide_threaded_events } => {
thread_root.is_none() || thread_root.is_some() && !hide_threaded_events
}
TimelineFocusKind::Thread { root_event_id } => {
thread_root.as_ref().is_some_and(|r| r == root_event_id)
}
TimelineFocusKind::Event | TimelineFocusKind::PinnedEvents => false,
TimelineFocusKind::Event { .. } | TimelineFocusKind::PinnedEvents => false,
}
}

View File

@@ -408,8 +408,8 @@ impl<'a> TimelineStateTransaction<'a> {
room_data_provider.is_pinned_event(event.event_id())
}
TimelineFocusKind::Event => {
if thread_root.is_some() {
TimelineFocusKind::Event { hide_threaded_events } => {
if thread_root.is_some() && *hide_threaded_events {
return false;
}
@@ -433,7 +433,9 @@ impl<'a> TimelineStateTransaction<'a> {
}
}
TimelineFocusKind::Live => thread_root.is_none(),
TimelineFocusKind::Live { hide_threaded_events } => {
thread_root.is_none() || thread_root.is_some() && !hide_threaded_events
}
TimelineFocusKind::Thread { root_event_id } => {
event.event_id() == root_event_id

View File

@@ -126,10 +126,10 @@ pub struct Timeline {
pub enum TimelineFocus {
/// Focus on live events, i.e. receive events from sync and append them in
/// real-time.
Live,
Live { hide_threaded_events: bool },
/// Focus on a specific event, e.g. after clicking a permalink.
Event { target: OwnedEventId, num_context_events: u16 },
Event { target: OwnedEventId, num_context_events: u16, hide_threaded_events: bool },
/// Focus on a specific thread
Thread { root_event_id: OwnedEventId, num_events: u16 },
@@ -141,7 +141,7 @@ pub enum TimelineFocus {
impl TimelineFocus {
pub(super) fn debug_string(&self) -> String {
match self {
TimelineFocus::Live => "live".to_owned(),
TimelineFocus::Live { .. } => "live".to_owned(),
TimelineFocus::Event { target, .. } => format!("permalink:{target}"),
TimelineFocus::Thread { root_event_id, .. } => format!("thread:{root_event_id}"),
TimelineFocus::PinnedEvents { .. } => "pinned-events".to_owned(),

View File

@@ -249,7 +249,7 @@ pub mod skip {
/// Update the skip count if and only if the timeline has a live focus
/// ([`TimelineFocusKind::Live`]).
pub fn update(&self, count: usize, focus_kind: &TimelineFocusKind) {
if matches!(focus_kind, TimelineFocusKind::Live) {
if matches!(focus_kind, TimelineFocusKind::Live { .. }) {
self.count.set_if_not_eq(count);
}
}

View File

@@ -123,7 +123,7 @@ impl TestTimelineBuilder {
fn build(self) -> TestTimeline {
let mut controller = TimelineController::new(
self.provider.unwrap_or_default(),
TimelineFocus::Live,
TimelineFocus::Live { hide_threaded_events: false },
self.internal_id_prefix,
self.utd_hook,
self.is_room_encrypted,

View File

@@ -74,6 +74,7 @@ async fn test_new_focused() {
.with_focus(TimelineFocus::Event {
target: target_event.to_owned(),
num_context_events: 20,
hide_threaded_events: false,
})
.build()
.await
@@ -222,6 +223,7 @@ async fn test_live_aggregations_are_reflected_on_focused_timelines() {
.with_focus(TimelineFocus::Event {
target: target_event.to_owned(),
num_context_events: 20,
hide_threaded_events: false,
})
.build()
.await
@@ -304,6 +306,7 @@ async fn test_focused_timeline_local_echoes() {
.with_focus(TimelineFocus::Event {
target: target_event.to_owned(),
num_context_events: 20,
hide_threaded_events: false,
})
.build()
.await
@@ -383,6 +386,7 @@ async fn test_focused_timeline_doesnt_show_local_echoes() {
.with_focus(TimelineFocus::Event {
target: target_event.to_owned(),
num_context_events: 20,
hide_threaded_events: false,
})
.build()
.await