Skip to content

Commit

Permalink
ffi: add FFI bindings for creating the new pinned events focused time…
Browse files Browse the repository at this point in the history
…line
  • Loading branch information
jmartinesp committed Aug 2, 2024
1 parent ab12f2f commit 1ca4377
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 54 deletions.
19 changes: 19 additions & 0 deletions bindings/matrix-sdk-ffi/src/room.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,25 @@ impl Room {
Ok(Timeline::new(timeline))
}

pub async fn pinned_events_timeline(
&self,
internal_id_prefix: Option<String>,
max_events_to_load: u16,
) -> Result<Arc<Timeline>, ClientError> {
let room = &self.inner;

let mut builder = matrix_sdk_ui::timeline::Timeline::builder(room);

if let Some(internal_id_prefix) = internal_id_prefix {
builder = builder.with_internal_id_prefix(internal_id_prefix);
}

let timeline =
builder.with_focus(TimelineFocus::PinnedEvents { max_events_to_load }).build().await?;

Ok(Timeline::new(timeline))
}

pub fn is_encrypted(&self) -> Result<bool, ClientError> {
Ok(RUNTIME.block_on(self.inner.is_encrypted())?)
}
Expand Down
2 changes: 1 addition & 1 deletion bindings/matrix-sdk-ffi/src/room_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl RoomInfo {
for (id, level) in power_levels_map.iter() {
user_power_levels.insert(id.to_string(), *level);
}
let pinned_event_ids = room.pinned_events().iter().map(|id| id.to_string()).collect();
let pinned_event_ids = room.pinned_event_ids().iter().map(|id| id.to_string()).collect();

Ok(Self {
id: room.room_id().to_string(),
Expand Down
39 changes: 21 additions & 18 deletions crates/matrix-sdk-base/src/rooms/normal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -949,11 +949,6 @@ impl Room {
self.inner.read().recency_stamp
}

/// Get the list of event ids for pinned events in this room.
pub fn pinned_event_ids(&self) -> Vec<OwnedEventId> {
self.inner.get().base_info.pinned_events.map(|content| content.pinned).unwrap_or_default()
}

/// Get a `Stream` of loaded pinned events for this room.
/// If no pinned events are found a single empty `Vec` will be returned.
pub fn pinned_event_ids_stream(&self) -> impl Stream<Item = Vec<OwnedEventId>> {
Expand All @@ -962,19 +957,9 @@ impl Room {
.map(|i| i.base_info.pinned_events.map(|c| c.pinned).unwrap_or_default())
}

/// Checks if an `EventId` is currently pinned.
/// It avoids having to clone the whole list of event ids to check a single
/// value.
///
/// Returns `true` if the provided `event_id` is pinned, `false` otherwise.
pub fn is_pinned_event(&self, event_id: &EventId) -> bool {
self.inner
.read()
.base_info
.pinned_events
.as_ref()
.map(|p| p.pinned.contains(&event_id.to_owned()))
.unwrap_or_default()
/// Returns the current pinned event ids for this room.
pub fn pinned_event_ids(&self) -> Vec<OwnedEventId> {
self.inner.read().pinned_event_ids()
}
}

Expand Down Expand Up @@ -1495,6 +1480,24 @@ impl RoomInfo {
pub(crate) fn update_recency_stamp(&mut self, stamp: u64) {
self.recency_stamp = Some(stamp);
}

/// Returns the current pinned event ids for this room.
pub fn pinned_event_ids(&self) -> Vec<OwnedEventId> {
self.base_info.pinned_events.clone().map(|c| c.pinned).unwrap_or_default()
}

/// Checks if an `EventId` is currently pinned.
/// It avoids having to clone the whole list of event ids to check a single
/// value.
///
/// Returns `true` if the provided `event_id` is pinned, `false` otherwise.
pub fn is_pinned_event(&self, event_id: &EventId) -> bool {
self.base_info
.pinned_events
.as_ref()
.map(|p| p.pinned.contains(&event_id.to_owned()))
.unwrap_or_default()
}
}

#[cfg(feature = "experimental-sliding-sync")]
Expand Down
35 changes: 16 additions & 19 deletions crates/matrix-sdk-ui/src/timeline/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,12 @@ impl TimelineBuilder {
let room = inner.room();
let client = room.client();

let mut pinned_event_ids_stream = room.pinned_event_ids_stream();
let pinned_events_join_handle = if is_pinned_events {
let mut pinned_event_ids_stream = room.pinned_event_ids_stream();
Some(spawn({
let inner = inner.clone();
async move {
while let Some(_) = pinned_event_ids_stream.next().await {
while pinned_event_ids_stream.next().await.is_some() {
if let Ok(events) = inner.pinned_events_load_events().await {
inner
.replace_with_initial_remote_events(
Expand Down Expand Up @@ -263,24 +263,21 @@ impl TimelineBuilder {
RoomEventCacheUpdate::AddTimelineEvents { events, origin } => {
trace!("Received new timeline events.");

// Special case for pinned events: when we receive new events what we'll do is
// updated the cache for those events that are pinned and reload the
// list.
match &*focus.clone() {
TimelineFocus::PinnedEvents { .. } => {
if let Ok(events) = inner.pinned_events_load_events().await {
inner.replace_with_initial_remote_events(events, RemoteEventOrigin::Sync).await;
}
}
_ => {
inner.add_events_at(
events,
TimelineEnd::Back,
match origin {
EventsOrigin::Sync => RemoteEventOrigin::Sync,
}
).await;
// Special case for pinned events: when we receive new events what we'll do is, instead of adding the
// events, update the pinned events cache with them, reload the list of pinned event ids and reload
// the list of pinned events with this info.
if let TimelineFocus::PinnedEvents { .. } = &*focus.clone() {
if let Ok(events) = inner.pinned_events_load_events().await {
inner.replace_with_initial_remote_events(events, RemoteEventOrigin::Sync).await;
}
} else {
inner.add_events_at(
events,
TimelineEnd::Back,
match origin {
EventsOrigin::Sync => RemoteEventOrigin::Sync,
}
).await;
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/matrix-sdk-ui/src/timeline/event_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ impl<'a, 'o> TimelineEventHandler<'a, 'o> {
// events in an event-focused timeline.
let can_add_to_live = match self.live_timeline_updates_type {
LiveTimelineUpdatesAllowed::PinnedEvents => {
room_data_provider.room_is_pinned_event_id(event_id)
room_data_provider.is_pinned_event(event_id)
}
LiveTimelineUpdatesAllowed::All => true,
LiveTimelineUpdatesAllowed::None => false,
Expand Down
2 changes: 2 additions & 0 deletions crates/matrix-sdk-ui/src/timeline/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ use ruma::{
use thiserror::Error;
use tracing::{error, instrument, trace, warn};

use crate::timeline::pinned_events_loader::PinnedEventsRoom;

mod builder;
mod day_dividers;
mod error;
Expand Down
25 changes: 14 additions & 11 deletions crates/matrix-sdk-ui/src/timeline/pinned_events_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl PinnedEventsLoader {
pub async fn load_events(&self) -> Result<Vec<SyncTimelineEvent>, PinnedEventsLoaderError> {
let pinned_event_ids: Vec<OwnedEventId> = self
.room
.room_pinned_event_ids()
.pinned_event_ids()
.into_iter()
.rev()
.take(self.max_events_to_load)
Expand Down Expand Up @@ -71,7 +71,7 @@ impl PinnedEventsLoader {
.await
.map_err(|_| PinnedEventsLoaderError::SemaphoreNotAcquired)?;
let ret = provider
.room_event(&id)
.event(&id)
.await
.map_err(|_| PinnedEventsLoaderError::EventNotFound(id.to_owned()));
drop(permit);
Expand Down Expand Up @@ -118,7 +118,7 @@ impl PinnedEventsLoader {
for ev in events {
let ev = ev.into();
if let Some(ev_id) = ev.event_id() {
if self.room.room_is_pinned_event_id(&ev_id) {
if self.room.is_pinned_event(&ev_id) {
to_update.push(ev);
}
}
Expand All @@ -137,31 +137,34 @@ impl PinnedEventsLoader {
#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
pub trait PinnedEventsRoom: SendOutsideWasm + SyncOutsideWasm {
/// Load a single room event.
async fn room_event(&self, event_id: &EventId) -> Result<SyncTimelineEvent, PaginatorError>;
async fn event(&self, event_id: &EventId) -> Result<SyncTimelineEvent, PaginatorError>;

/// Get the pinned event ids for a room.
fn room_pinned_event_ids(&self) -> Vec<OwnedEventId>;
fn pinned_event_ids(&self) -> Vec<OwnedEventId>;

/// Checks whether an event id is pinned in this room.
fn room_is_pinned_event_id(&self, event_id: &EventId) -> bool;
///
/// It avoids having to clone the whole list of event ids to check a single
/// value.
fn is_pinned_event(&self, event_id: &EventId) -> bool;
}

#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
impl PinnedEventsRoom for Room {
async fn room_event(&self, event_id: &EventId) -> Result<SyncTimelineEvent, PaginatorError> {
async fn event(&self, event_id: &EventId) -> Result<SyncTimelineEvent, PaginatorError> {
self.event(event_id)
.await
.map(|e| e.into())
.map_err(|err| PaginatorError::SdkError(Box::new(err)))
}

fn room_pinned_event_ids(&self) -> Vec<OwnedEventId> {
self.pinned_event_ids()
fn pinned_event_ids(&self) -> Vec<OwnedEventId> {
self.clone_info().pinned_event_ids()
}

fn room_is_pinned_event_id(&self, event_id: &EventId) -> bool {
self.is_pinned_event(event_id)
fn is_pinned_event(&self, event_id: &EventId) -> bool {
self.subscribe_info().read().is_pinned_event(event_id)
}
}

Expand Down
6 changes: 3 additions & 3 deletions crates/matrix-sdk-ui/src/timeline/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,15 +321,15 @@ impl PaginableRoom for TestRoomDataProvider {
#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
impl PinnedEventsRoom for TestRoomDataProvider {
async fn room_event(&self, _event_id: &EventId) -> Result<SyncTimelineEvent, PaginatorError> {
async fn event(&self, _event_id: &EventId) -> Result<SyncTimelineEvent, PaginatorError> {
unimplemented!();
}

fn room_pinned_event_ids(&self) -> Vec<OwnedEventId> {
fn pinned_event_ids(&self) -> Vec<OwnedEventId> {
unimplemented!();
}

fn room_is_pinned_event_id(&self, _event_id: &EventId) -> bool {
fn is_pinned_event(&self, _event_id: &EventId) -> bool {
unimplemented!();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ async fn test_new_pinned_events_are_added_on_sync() {
assert_matches!(timeline_stream.next().await.unwrap(), VectorDiff::PushFront { value } => {
assert!(value.is_day_divider());
});
assert_pending!(timeline_stream);
test_helper.server.reset().await;
}

Expand Down

0 comments on commit 1ca4377

Please sign in to comment.