matrix_sdk_ffi/timeline/
configuration.rs

1use std::sync::Arc;
2
3use matrix_sdk_ui::timeline::event_type_filter::TimelineEventTypeFilter as InnerTimelineEventTypeFilter;
4use ruma::{
5    events::{AnySyncTimelineEvent, TimelineEventType},
6    EventId,
7};
8
9use super::FocusEventError;
10use crate::{
11    error::ClientError,
12    event::{MessageLikeEventType, RoomMessageEventMessageType, StateEventType},
13};
14
15#[derive(uniffi::Object)]
16pub struct TimelineEventTypeFilter {
17    inner: InnerTimelineEventTypeFilter,
18}
19
20#[matrix_sdk_ffi_macros::export]
21impl TimelineEventTypeFilter {
22    #[uniffi::constructor]
23    pub fn include(event_types: Vec<FilterTimelineEventType>) -> Arc<Self> {
24        let event_types: Vec<TimelineEventType> =
25            event_types.iter().map(|t| t.clone().into()).collect();
26        Arc::new(Self { inner: InnerTimelineEventTypeFilter::Include(event_types) })
27    }
28
29    #[uniffi::constructor]
30    pub fn exclude(event_types: Vec<FilterTimelineEventType>) -> Arc<Self> {
31        let event_types: Vec<TimelineEventType> =
32            event_types.iter().map(|t| t.clone().into()).collect();
33        Arc::new(Self { inner: InnerTimelineEventTypeFilter::Exclude(event_types) })
34    }
35}
36
37impl TimelineEventTypeFilter {
38    /// Filters an [`event`] to decide whether it should be part of the timeline
39    /// based on [`AnySyncTimelineEvent::event_type()`].
40    pub(crate) fn filter(&self, event: &AnySyncTimelineEvent) -> bool {
41        self.inner.filter(event)
42    }
43}
44
45#[derive(uniffi::Enum, Clone)]
46pub enum FilterTimelineEventType {
47    MessageLike { event_type: MessageLikeEventType },
48    State { event_type: StateEventType },
49}
50
51impl From<FilterTimelineEventType> for TimelineEventType {
52    fn from(value: FilterTimelineEventType) -> TimelineEventType {
53        match value {
54            FilterTimelineEventType::MessageLike { event_type } => {
55                ruma::events::MessageLikeEventType::from(event_type).into()
56            }
57            FilterTimelineEventType::State { event_type } => {
58                ruma::events::StateEventType::from(event_type).into()
59            }
60        }
61    }
62}
63
64#[derive(uniffi::Enum)]
65pub enum TimelineFocus {
66    Live,
67    Event { event_id: String, num_context_events: u16 },
68    PinnedEvents { max_events_to_load: u16, max_concurrent_requests: u16 },
69}
70
71impl TryFrom<TimelineFocus> for matrix_sdk_ui::timeline::TimelineFocus {
72    type Error = ClientError;
73
74    fn try_from(
75        value: TimelineFocus,
76    ) -> Result<matrix_sdk_ui::timeline::TimelineFocus, Self::Error> {
77        match value {
78            TimelineFocus::Live => Ok(Self::Live),
79            TimelineFocus::Event { event_id, num_context_events } => {
80                let parsed_event_id =
81                    EventId::parse(&event_id).map_err(|err| FocusEventError::InvalidEventId {
82                        event_id: event_id.clone(),
83                        err: err.to_string(),
84                    })?;
85
86                Ok(Self::Event { target: parsed_event_id, num_context_events })
87            }
88            TimelineFocus::PinnedEvents { max_events_to_load, max_concurrent_requests } => {
89                Ok(Self::PinnedEvents { max_events_to_load, max_concurrent_requests })
90            }
91        }
92    }
93}
94
95/// Changes how date dividers get inserted, either in between each day or in
96/// between each month
97#[derive(uniffi::Enum)]
98pub enum DateDividerMode {
99    Daily,
100    Monthly,
101}
102
103impl From<DateDividerMode> for matrix_sdk_ui::timeline::DateDividerMode {
104    fn from(value: DateDividerMode) -> Self {
105        match value {
106            DateDividerMode::Daily => Self::Daily,
107            DateDividerMode::Monthly => Self::Monthly,
108        }
109    }
110}
111
112#[derive(uniffi::Enum)]
113pub enum TimelineFilter {
114    /// Show all the events in the timeline, independent of their type.
115    All,
116    /// Show only `m.room.messages` of the given room message types.
117    OnlyMessage {
118        /// A list of [`RoomMessageEventMessageType`] that will be allowed to
119        /// appear in the timeline.
120        types: Vec<RoomMessageEventMessageType>,
121    },
122    /// Show only events which match this filter.
123    EventTypeFilter { filter: Arc<TimelineEventTypeFilter> },
124}
125
126/// Various options used to configure the timeline's behavior.
127#[derive(uniffi::Record)]
128pub struct TimelineConfiguration {
129    /// What should the timeline focus on?
130    pub focus: TimelineFocus,
131
132    /// How should we filter out events from the timeline?
133    pub filter: TimelineFilter,
134
135    /// An optional String that will be prepended to
136    /// all the timeline item's internal IDs, making it possible to
137    /// distinguish different timeline instances from each other.
138    pub internal_id_prefix: Option<String>,
139
140    /// How often to insert date dividers
141    pub date_divider_mode: DateDividerMode,
142
143    /// Should the read receipts and read markers be tracked for the timeline
144    /// items in this instance?
145    ///
146    /// As this has a non negligible performance impact, make sure to enable it
147    /// only when you need it.
148    pub track_read_receipts: bool,
149}