mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-15 03:25:46 -04:00
feat(ffi): First step for RoomList in FFI bindings.
This commit is contained in:
@@ -29,7 +29,7 @@ eyeball-im = { workspace = true }
|
||||
extension-trait = "1.0.1"
|
||||
futures-core = { workspace = true }
|
||||
futures-util = { workspace = true }
|
||||
matrix-sdk-ui = { path = "../../crates/matrix-sdk-ui", default-features = false, features = ["e2e-encryption", "experimental-sliding-sync"] }
|
||||
matrix-sdk-ui = { path = "../../crates/matrix-sdk-ui" }
|
||||
mime = "0.3.16"
|
||||
# FIXME: we currently can't feature flag anything in the api.udl, therefore we must enforce experimental-sliding-sync being exposed here..
|
||||
# see https://github.com/matrix-org/matrix-rust-sdk/issues/1014
|
||||
|
||||
@@ -50,6 +50,7 @@ callback interface SlidingSyncListStateObserver {
|
||||
void did_receive_update(SlidingSyncState new_state);
|
||||
};
|
||||
|
||||
// Used by `SlidingSync` _and_ `RoomList`. Be careful.
|
||||
[Enum]
|
||||
interface RoomListEntry {
|
||||
Empty();
|
||||
@@ -167,3 +168,33 @@ callback interface SessionVerificationControllerDelegate {
|
||||
void did_cancel();
|
||||
void did_finish();
|
||||
};
|
||||
|
||||
enum RoomListState {
|
||||
"Init",
|
||||
"FirstRooms",
|
||||
"AllRooms",
|
||||
"CarryOn",
|
||||
"Terminated",
|
||||
};
|
||||
|
||||
callback interface RoomListStateObserver {
|
||||
void on_update(RoomListState state);
|
||||
};
|
||||
|
||||
[Enum]
|
||||
interface RoomListEntriesUpdate {
|
||||
Append(sequence<RoomListEntry> values);
|
||||
Clear();
|
||||
PushFront(RoomListEntry value);
|
||||
PushBack(RoomListEntry value);
|
||||
PopFront();
|
||||
PopBack();
|
||||
Insert(u32 index, RoomListEntry value);
|
||||
Set(u32 index, RoomListEntry value);
|
||||
Remove(u32 index);
|
||||
Reset(sequence<RoomListEntry> values);
|
||||
};
|
||||
|
||||
callback interface RoomListEntriesObserver {
|
||||
void on_update(RoomListEntriesUpdate room_entries_update);
|
||||
};
|
||||
|
||||
@@ -30,6 +30,7 @@ pub mod event;
|
||||
mod helpers;
|
||||
pub mod notification;
|
||||
pub mod room;
|
||||
pub mod room_list;
|
||||
pub mod room_member;
|
||||
pub mod session_verification;
|
||||
pub mod sliding_sync;
|
||||
@@ -45,8 +46,9 @@ pub use platform::*;
|
||||
// Re-exports for more convenient use inside other submodules
|
||||
use self::error::ClientError;
|
||||
pub use self::{
|
||||
authentication_service::*, client::*, event::*, notification::*, room::*, room_member::*,
|
||||
session_verification::*, sliding_sync::*, task_handle::TaskHandle, timeline::*, tracing::*,
|
||||
authentication_service::*, client::*, event::*, notification::*, room::*, room_list::*,
|
||||
room_member::*, session_verification::*, sliding_sync::*, task_handle::TaskHandle, timeline::*,
|
||||
tracing::*,
|
||||
};
|
||||
|
||||
uniffi::include_scaffolding!("api");
|
||||
|
||||
170
bindings/matrix-sdk-ffi/src/room_list.rs
Normal file
170
bindings/matrix-sdk-ffi/src/room_list.rs
Normal file
@@ -0,0 +1,170 @@
|
||||
use std::{fmt::Debug, sync::Arc};
|
||||
|
||||
use eyeball_im::VectorDiff;
|
||||
use futures_util::{pin_mut, StreamExt};
|
||||
|
||||
use crate::{Client, RoomListEntry, TaskHandle, RUNTIME};
|
||||
|
||||
#[uniffi::export]
|
||||
impl Client {
|
||||
/// Get a new `RoomList` instance.
|
||||
pub fn room_list(&self) -> Result<Arc<RoomList>, RoomListError> {
|
||||
Ok(Arc::new(RoomList {
|
||||
inner: Arc::new(
|
||||
RUNTIME
|
||||
.block_on(async { matrix_sdk_ui::RoomList::new(self.inner.clone()).await })
|
||||
.map_err(RoomListError::from)?,
|
||||
),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(uniffi::Error)]
|
||||
pub enum RoomListError {
|
||||
SlidingSync { error: String },
|
||||
UnknownList { list_name: String },
|
||||
InputHasNotBeenApplied,
|
||||
RoomNotFound { room_name: String },
|
||||
}
|
||||
|
||||
impl From<matrix_sdk_ui::room_list::Error> for RoomListError {
|
||||
fn from(value: matrix_sdk_ui::room_list::Error) -> Self {
|
||||
use matrix_sdk_ui::room_list::Error::*;
|
||||
|
||||
match value {
|
||||
SlidingSync(error) => Self::SlidingSync { error: error.to_string() },
|
||||
UnknownList(list_name) => Self::UnknownList { list_name },
|
||||
InputHasNotBeenApplied(_) => Self::InputHasNotBeenApplied,
|
||||
RoomNotFound(room_id) => Self::RoomNotFound { room_name: room_id.to_string() },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(uniffi::Object)]
|
||||
pub struct RoomList {
|
||||
inner: Arc<matrix_sdk_ui::RoomList>,
|
||||
}
|
||||
|
||||
#[uniffi::export]
|
||||
impl RoomList {
|
||||
fn sync(&self) -> Arc<TaskHandle> {
|
||||
let this = self.inner.clone();
|
||||
|
||||
Arc::new(TaskHandle::new(RUNTIME.spawn(async move {
|
||||
let sync_stream = this.sync();
|
||||
pin_mut!(sync_stream);
|
||||
|
||||
while let Some(_) = sync_stream.next().await {
|
||||
// keep going!
|
||||
}
|
||||
})))
|
||||
}
|
||||
|
||||
fn state(&self, observer: Box<dyn RoomListStateObserver>) -> Arc<TaskHandle> {
|
||||
let state_stream = self.inner.state();
|
||||
|
||||
Arc::new(TaskHandle::new(RUNTIME.spawn(async move {
|
||||
pin_mut!(state_stream);
|
||||
|
||||
while let Some(state) = state_stream.next().await {
|
||||
observer.on_update(state.into());
|
||||
}
|
||||
})))
|
||||
}
|
||||
|
||||
fn entries(
|
||||
&self,
|
||||
observer: Box<dyn RoomListEntriesObserver>,
|
||||
) -> Result<RoomListEntriesResult, RoomListError> {
|
||||
let (entries, entries_stream) =
|
||||
RUNTIME.block_on(async { self.inner.entries().await.map_err(RoomListError::from) })?;
|
||||
|
||||
Ok(RoomListEntriesResult {
|
||||
entries: entries.iter().map(Into::into).collect(),
|
||||
entries_stream: Arc::new(TaskHandle::new(RUNTIME.spawn(async move {
|
||||
pin_mut!(entries_stream);
|
||||
|
||||
while let Some(diff) = entries_stream.next().await {
|
||||
observer.on_update(diff.into());
|
||||
}
|
||||
}))),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(uniffi::Record)]
|
||||
pub struct RoomListEntriesResult {
|
||||
pub entries: Vec<RoomListEntry>,
|
||||
pub entries_stream: Arc<TaskHandle>,
|
||||
}
|
||||
|
||||
// Also declared in the UDL file.
|
||||
pub enum RoomListState {
|
||||
Init,
|
||||
FirstRooms,
|
||||
AllRooms,
|
||||
CarryOn,
|
||||
Terminated,
|
||||
}
|
||||
|
||||
impl From<matrix_sdk_ui::room_list::State> for RoomListState {
|
||||
fn from(value: matrix_sdk_ui::room_list::State) -> Self {
|
||||
use matrix_sdk_ui::room_list::State::*;
|
||||
|
||||
match value {
|
||||
Init => Self::Init,
|
||||
FirstRooms => Self::FirstRooms,
|
||||
AllRooms => Self::AllRooms,
|
||||
CarryOn => Self::CarryOn,
|
||||
Terminated { .. } => Self::Terminated,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Also declared in the UDL file.
|
||||
pub trait RoomListStateObserver: Send + Sync + Debug {
|
||||
fn on_update(&self, state: RoomListState);
|
||||
}
|
||||
|
||||
pub enum RoomListEntriesUpdate {
|
||||
Append { values: Vec<RoomListEntry> },
|
||||
Clear,
|
||||
PushFront { value: RoomListEntry },
|
||||
PushBack { value: RoomListEntry },
|
||||
PopFront,
|
||||
PopBack,
|
||||
Insert { index: u32, value: RoomListEntry },
|
||||
Set { index: u32, value: RoomListEntry },
|
||||
Remove { index: u32 },
|
||||
Reset { values: Vec<RoomListEntry> },
|
||||
}
|
||||
|
||||
impl From<VectorDiff<matrix_sdk::RoomListEntry>> for RoomListEntriesUpdate {
|
||||
fn from(other: VectorDiff<matrix_sdk::RoomListEntry>) -> Self {
|
||||
match other {
|
||||
VectorDiff::Append { values } => {
|
||||
Self::Append { values: values.into_iter().map(Into::into).collect() }
|
||||
}
|
||||
VectorDiff::Clear => Self::Clear,
|
||||
VectorDiff::PushFront { value } => Self::PushFront { value: value.into() },
|
||||
VectorDiff::PushBack { value } => Self::PushBack { value: value.into() },
|
||||
VectorDiff::PopFront => Self::PopFront,
|
||||
VectorDiff::PopBack => Self::PopBack,
|
||||
VectorDiff::Insert { index, value } => {
|
||||
Self::Insert { index: u32::try_from(index).unwrap(), value: value.into() }
|
||||
}
|
||||
VectorDiff::Set { index, value } => {
|
||||
Self::Set { index: u32::try_from(index).unwrap(), value: value.into() }
|
||||
}
|
||||
VectorDiff::Remove { index } => Self::Remove { index: u32::try_from(index).unwrap() },
|
||||
VectorDiff::Reset { values } => {
|
||||
Self::Reset { values: values.into_iter().map(Into::into).collect() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Also declared in the UDL file.
|
||||
pub trait RoomListEntriesObserver: Send + Sync + Debug {
|
||||
fn on_update(&self, room_entries_update: RoomListEntriesUpdate);
|
||||
}
|
||||
@@ -332,12 +332,20 @@ pub enum RoomListEntry {
|
||||
Filled { room_id: String },
|
||||
}
|
||||
|
||||
impl From<MatrixRoomEntry> for RoomListEntry {
|
||||
fn from(value: MatrixRoomEntry) -> Self {
|
||||
(&value).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&MatrixRoomEntry> for RoomListEntry {
|
||||
fn from(other: &MatrixRoomEntry) -> Self {
|
||||
match other {
|
||||
fn from(value: &MatrixRoomEntry) -> Self {
|
||||
match value {
|
||||
MatrixRoomEntry::Empty => Self::Empty,
|
||||
MatrixRoomEntry::Filled(b) => Self::Filled { room_id: b.to_string() },
|
||||
MatrixRoomEntry::Invalidated(b) => Self::Invalidated { room_id: b.to_string() },
|
||||
MatrixRoomEntry::Filled(room_id) => Self::Filled { room_id: room_id.to_string() },
|
||||
MatrixRoomEntry::Invalidated(room_id) => {
|
||||
Self::Invalidated { room_id: room_id.to_string() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user