Skip to content

Commit 6ed213a

Browse files
committed
feat(ffi): bindings for global search
1 parent ac2207f commit 6ed213a

File tree

1 file changed

+80
-15
lines changed

1 file changed

+80
-15
lines changed

bindings/matrix-sdk-ffi/src/search.rs

Lines changed: 80 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@
1313
// limitations under the License.
1414

1515
use matrix_sdk::deserialized_responses::TimelineEvent;
16-
use matrix_sdk_ui::search::RoomSearch;
16+
use matrix_sdk_ui::search::{GlobalSearch, RoomSearch};
1717
use ruma::OwnedUserId;
1818
use tokio::sync::Mutex;
1919

2020
use crate::{
21+
client::Client,
2122
error::ClientError,
2223
room::Room,
2324
timeline::{ProfileDetails, TimelineItemContent},
@@ -42,23 +43,10 @@ pub struct RoomSearchIterator {
4243

4344
#[matrix_sdk_ffi_macros::export]
4445
impl RoomSearchIterator {
45-
/// Return a list of event ids for the next batch of search results, or
46-
/// `None` if there are no more results.
47-
pub async fn next(&self) -> Option<Vec<String>> {
48-
match self.inner.lock().await.next().await {
49-
Ok(Some(event_ids)) => Some(event_ids.into_iter().map(|id| id.to_string()).collect()),
50-
Ok(None) => None,
51-
Err(e) => {
52-
eprintln!("Error during search: {e}");
53-
None
54-
}
55-
}
56-
}
57-
5846
/// Return a list of events for the next batch of search results, or `None`
5947
/// if there are no more results.
6048
pub async fn next_events(&self) -> Result<Option<Vec<RoomSearchResult>>, ClientError> {
61-
let Some(events) = self.inner.lock().await.next_events().await? else {
49+
let Some(events) = self.inner.lock().await.next_events(20).await? else {
6250
return Ok(None);
6351
};
6452

@@ -106,3 +94,80 @@ impl RoomSearchResult {
10694
})
10795
}
10896
}
97+
98+
#[derive(Clone, uniffi::Enum)]
99+
pub enum SearchRoomFilter {
100+
/// All the joined rooms (= DMs + groups).
101+
AllJoinedRooms,
102+
/// Only DM rooms.
103+
AllJoinedDms,
104+
/// Only non-DM (group) rooms.
105+
AllJoinedGroups,
106+
}
107+
108+
#[matrix_sdk_ffi_macros::export]
109+
impl Client {
110+
pub async fn search(
111+
&self,
112+
query: String,
113+
filter: SearchRoomFilter,
114+
) -> Result<GlobalSearchIterator, ClientError> {
115+
let sdk_client = (*self.inner).clone();
116+
let mut search = GlobalSearch::builder(sdk_client.clone(), query);
117+
118+
match filter {
119+
SearchRoomFilter::AllJoinedRooms => {}
120+
SearchRoomFilter::AllJoinedDms => search = search.only_dm_rooms().await?,
121+
SearchRoomFilter::AllJoinedGroups => search = search.only_groups().await?,
122+
}
123+
124+
Ok(GlobalSearchIterator { sdk_client, inner: Mutex::new(search.build()) })
125+
}
126+
}
127+
128+
#[derive(uniffi::Record)]
129+
pub struct BasicGlobalSearchResult {
130+
room_id: String,
131+
event_id: String,
132+
}
133+
134+
#[derive(uniffi::Record)]
135+
pub struct GlobalSearchResult {
136+
room_id: String,
137+
result: RoomSearchResult,
138+
}
139+
140+
#[derive(uniffi::Object)]
141+
pub struct GlobalSearchIterator {
142+
sdk_client: matrix_sdk::Client,
143+
inner: Mutex<GlobalSearch>,
144+
}
145+
146+
#[matrix_sdk_ffi_macros::export]
147+
impl GlobalSearchIterator {
148+
/// Return a list of events for the next batch of search results, or `None`
149+
/// if there are no more results.
150+
pub async fn next_events(
151+
&self,
152+
num_results: u64,
153+
) -> Result<Option<Vec<GlobalSearchResult>>, ClientError> {
154+
let Some(events) = self.inner.lock().await.next_events(num_results as usize).await? else {
155+
return Ok(None);
156+
};
157+
158+
let mut results = Vec::with_capacity(events.len());
159+
160+
for (room_id, event) in events {
161+
let Some(room) = self.sdk_client.get_room(&room_id) else {
162+
continue;
163+
};
164+
if let Some(result) = RoomSearchResult::from(&room, event).await {
165+
results.push(GlobalSearchResult { room_id: room_id.to_string(), result });
166+
}
167+
}
168+
169+
results.shrink_to_fit();
170+
171+
Ok(Some(results))
172+
}
173+
}

0 commit comments

Comments
 (0)