base: Add initial left rooms handling.
This commit is contained in:
parent
0e563a9a81
commit
27b5bf3ddd
3 changed files with 75 additions and 35 deletions
|
@ -54,7 +54,7 @@ use zeroize::Zeroizing;
|
|||
|
||||
use crate::{
|
||||
error::Result,
|
||||
responses::{JoinedRoom, Rooms, State, SyncResponse, Timeline},
|
||||
responses::{JoinedRoom, LeftRoom, Presence, Rooms, State, SyncResponse, Timeline},
|
||||
session::Session,
|
||||
store::{InnerSummary, Room, RoomType, StateChanges, Store},
|
||||
};
|
||||
|
@ -539,7 +539,7 @@ impl BaseClient {
|
|||
// that case we already received this response and there's nothing to
|
||||
// do.
|
||||
if self.sync_token.read().await.as_ref() == Some(&response.next_batch) {
|
||||
return Ok(SyncResponse::new_empty(response.next_batch.clone()));
|
||||
return Ok(SyncResponse::new(response.next_batch));
|
||||
}
|
||||
|
||||
#[cfg(feature = "encryption")]
|
||||
|
@ -558,10 +558,11 @@ impl BaseClient {
|
|||
let mut changes = StateChanges::default();
|
||||
let mut rooms = Rooms::default();
|
||||
|
||||
for (room_id, room_info) in &response.rooms.join {
|
||||
let room = self.get_or_create_room(room_id, RoomType::Joined).await;
|
||||
|
||||
for (room_id, room_info) in response.rooms.join {
|
||||
let room = self.get_or_create_room(&room_id, RoomType::Joined).await;
|
||||
let mut summary = room.clone_summary();
|
||||
|
||||
summary.mark_as_joined();
|
||||
summary.update(&room_info.summary);
|
||||
summary.set_prev_batch(room_info.timeline.prev_batch.as_deref());
|
||||
|
||||
|
@ -583,27 +584,46 @@ impl BaseClient {
|
|||
// TODO if the room isn't encrypted but the new summary is,
|
||||
// add all the room users.
|
||||
if let Some(o) = self.olm_machine().await {
|
||||
if let Some(users) = changes.joined_user_ids.get(room_id) {
|
||||
if let Some(users) = changes.joined_user_ids.get(&room_id) {
|
||||
o.update_tracked_users(users).await
|
||||
}
|
||||
|
||||
if let Some(users) = changes.invited_user_ids.get(room_id) {
|
||||
if let Some(users) = changes.invited_user_ids.get(&room_id) {
|
||||
o.update_tracked_users(users).await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rooms
|
||||
.join
|
||||
.insert(room_id.to_owned(), JoinedRoom::new(timeline, state));
|
||||
|
||||
if room_info.timeline.limited {
|
||||
summary.mark_members_missing();
|
||||
}
|
||||
|
||||
rooms.join.insert(room_id, JoinedRoom::new(timeline, state));
|
||||
|
||||
changes.add_room(summary);
|
||||
}
|
||||
|
||||
for (room_id, room_info) in response.rooms.leave {
|
||||
let room = self.get_or_create_room(&room_id, RoomType::Left).await;
|
||||
let mut summary = room.clone_summary();
|
||||
summary.mark_as_left();
|
||||
|
||||
let state = self
|
||||
.handle_state(
|
||||
&room_id,
|
||||
&room_info.state.events,
|
||||
&mut summary,
|
||||
&mut changes,
|
||||
)
|
||||
.await;
|
||||
|
||||
let timeline = self
|
||||
.handle_timeline(&room_id, &room_info.timeline, &mut summary, &mut changes)
|
||||
.await;
|
||||
|
||||
rooms.leave.insert(room_id, LeftRoom::new(timeline, state));
|
||||
}
|
||||
|
||||
for event in &response.presence.events {
|
||||
if let Ok(e) = event.deserialize() {
|
||||
changes.add_presence_event(e);
|
||||
|
@ -614,7 +634,21 @@ impl BaseClient {
|
|||
*self.sync_token.write().await = Some(response.next_batch.clone());
|
||||
self.apply_changes(&changes).await;
|
||||
|
||||
Ok(SyncResponse::new(response, rooms, changes))
|
||||
Ok(SyncResponse {
|
||||
next_batch: response.next_batch,
|
||||
rooms,
|
||||
presence: Presence {
|
||||
events: changes.presence.into_iter().map(|(_, v)| v).collect(),
|
||||
},
|
||||
device_lists: response.device_lists,
|
||||
device_one_time_keys_count: response
|
||||
.device_one_time_keys_count
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k, v.into()))
|
||||
.collect(),
|
||||
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
async fn apply_changes(&self, changes: &StateChanges) {
|
||||
|
|
|
@ -2,13 +2,11 @@ use serde::{Deserialize, Serialize};
|
|||
use std::collections::BTreeMap;
|
||||
|
||||
use matrix_sdk_common::{
|
||||
api::r0::sync::sync_events::{self, DeviceLists},
|
||||
api::r0::sync::sync_events::DeviceLists,
|
||||
events::{presence::PresenceEvent, AnySyncRoomEvent, AnySyncStateEvent, AnyToDeviceEvent},
|
||||
identifiers::{DeviceKeyAlgorithm, RoomId},
|
||||
};
|
||||
|
||||
use crate::store::StateChanges;
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
pub struct SyncResponse {
|
||||
/// The batch token to supply in the `since` param of the next `/sync` request.
|
||||
|
@ -31,24 +29,7 @@ pub struct SyncResponse {
|
|||
}
|
||||
|
||||
impl SyncResponse {
|
||||
pub fn new(response: sync_events::Response, rooms: Rooms, changes: StateChanges) -> Self {
|
||||
Self {
|
||||
next_batch: response.next_batch,
|
||||
rooms,
|
||||
presence: Presence {
|
||||
events: changes.presence.into_iter().map(|(_, v)| v).collect(),
|
||||
},
|
||||
device_lists: response.device_lists,
|
||||
device_one_time_keys_count: response
|
||||
.device_one_time_keys_count
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k, v.into()))
|
||||
.collect(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_empty(next_batch: String) -> Self {
|
||||
pub fn new(next_batch: String) -> Self {
|
||||
Self {
|
||||
next_batch,
|
||||
..Default::default()
|
||||
|
@ -72,8 +53,8 @@ pub struct ToDevice {
|
|||
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
pub struct Rooms {
|
||||
// /// The rooms that the user has left or been banned from.
|
||||
// pub leave: BTreeMap<RoomId, LeftRoom>,
|
||||
/// The rooms that the user has left or been banned from.
|
||||
pub leave: BTreeMap<RoomId, LeftRoom>,
|
||||
/// The rooms that the user has joined.
|
||||
pub join: BTreeMap<RoomId, JoinedRoom>,
|
||||
// /// The rooms that the user has been invited to.
|
||||
|
@ -104,6 +85,23 @@ impl JoinedRoom {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct LeftRoom {
|
||||
/// The timeline of messages and state changes in the room up to the point
|
||||
/// when the user left.
|
||||
pub timeline: Timeline,
|
||||
/// Updates to the state, between the time indicated by the `since` parameter, and the start
|
||||
/// of the `timeline` (or all state up to the start of the `timeline`, if `since` is not
|
||||
/// given, or `full_state` is true).
|
||||
pub state: State,
|
||||
}
|
||||
|
||||
impl LeftRoom {
|
||||
pub fn new(timeline: Timeline, state: State) -> Self {
|
||||
Self { timeline, state }
|
||||
}
|
||||
}
|
||||
|
||||
/// Events in the room.
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
pub struct Timeline {
|
||||
|
|
|
@ -379,6 +379,14 @@ impl InnerSummary {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn mark_as_joined(&mut self) {
|
||||
self.room_type = RoomType::Joined;
|
||||
}
|
||||
|
||||
pub fn mark_as_left(&mut self) {
|
||||
self.room_type = RoomType::Left;
|
||||
}
|
||||
|
||||
pub fn mark_members_synced(&mut self) {
|
||||
self.members_synced = true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue