base: Add presence storing.
This commit is contained in:
parent
ac2d90e92a
commit
38048a2043
3 changed files with 101 additions and 61 deletions
|
@ -579,18 +579,28 @@ impl BaseClient {
|
|||
changes.add_room(summary);
|
||||
}
|
||||
|
||||
for event in &response.presence.events {
|
||||
if let Ok(e) = event.deserialize() {
|
||||
changes.add_presence_event(e);
|
||||
}
|
||||
}
|
||||
|
||||
self.store.save_changes(&changes).await;
|
||||
*self.sync_token.write().await = Some(response.next_batch.clone());
|
||||
self.apply_changes(changes).await;
|
||||
self.apply_changes(&changes).await;
|
||||
|
||||
Ok(SyncResponse::new(response.next_batch.clone(), rooms))
|
||||
Ok(SyncResponse::new(
|
||||
response.next_batch.clone(),
|
||||
rooms,
|
||||
changes,
|
||||
))
|
||||
}
|
||||
|
||||
async fn apply_changes(&self, changes: StateChanges) {
|
||||
async fn apply_changes(&self, changes: &StateChanges) {
|
||||
// TODO emit room changes here
|
||||
for (room_id, summary) in changes.room_summaries {
|
||||
for (room_id, summary) in &changes.room_summaries {
|
||||
if let Some(room) = self.get_joined_room(&room_id) {
|
||||
room.update_summary(summary)
|
||||
room.update_summary(summary.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -638,7 +648,7 @@ impl BaseClient {
|
|||
changes.add_room(summary);
|
||||
|
||||
self.store.save_changes(&changes).await;
|
||||
self.apply_changes(changes).await;
|
||||
self.apply_changes(&changes).await;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -2,20 +2,20 @@ use serde::{Deserialize, Serialize};
|
|||
use std::collections::BTreeMap;
|
||||
|
||||
use matrix_sdk_common::{
|
||||
events::{AnySyncRoomEvent, AnySyncStateEvent},
|
||||
events::{presence::PresenceEvent, AnySyncRoomEvent, AnySyncStateEvent},
|
||||
identifiers::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.
|
||||
pub next_batch: String,
|
||||
/// Updates to rooms.
|
||||
pub rooms: Rooms,
|
||||
///// Updates to the presence status of other users.
|
||||
//#[serde(default, skip_serializing_if = "Presence::is_empty")]
|
||||
//pub presence: Presence,
|
||||
|
||||
/// Updates to the presence status of other users.
|
||||
pub presence: Presence,
|
||||
///// The global private data created by this user.
|
||||
//#[serde(default, skip_serializing_if = "AccountData::is_empty")]
|
||||
//pub account_data: AccountData,
|
||||
|
@ -37,8 +37,15 @@ pub struct SyncResponse {
|
|||
}
|
||||
|
||||
impl SyncResponse {
|
||||
pub fn new(next_batch: String, rooms: Rooms) -> Self {
|
||||
Self { next_batch, rooms }
|
||||
pub fn new(next_batch: String, rooms: Rooms, changes: StateChanges) -> Self {
|
||||
Self {
|
||||
next_batch,
|
||||
rooms,
|
||||
presence: Presence {
|
||||
events: changes.presence.into_iter().map(|(_, v)| v).collect(),
|
||||
},
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_empty(next_batch: String) -> Self {
|
||||
|
@ -49,6 +56,13 @@ impl SyncResponse {
|
|||
}
|
||||
}
|
||||
|
||||
/// Updates to the presence status of other users.
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
pub struct Presence {
|
||||
/// A list of events.
|
||||
pub events: Vec<PresenceEvent>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
pub struct Rooms {
|
||||
// /// The rooms that the user has left or been banned from.
|
||||
|
|
|
@ -12,6 +12,7 @@ use futures::{
|
|||
use matrix_sdk_common::{
|
||||
api::r0::sync::sync_events::RoomSummary as RumaSummary,
|
||||
events::{
|
||||
presence::PresenceEvent,
|
||||
room::{encryption::EncryptionEventContent, member::MemberEventContent},
|
||||
AnySyncStateEvent, EventContent, SyncStateEvent,
|
||||
},
|
||||
|
@ -32,20 +33,22 @@ pub struct Store {
|
|||
invited_user_ids: Tree,
|
||||
room_state: Tree,
|
||||
room_summaries: Tree,
|
||||
presence: Tree,
|
||||
}
|
||||
|
||||
use crate::{client::hoist_and_deserialize_state_event, Session};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct StateChanges {
|
||||
session: Option<Session>,
|
||||
members: BTreeMap<RoomId, BTreeMap<UserId, SyncStateEvent<MemberEventContent>>>,
|
||||
state: BTreeMap<RoomId, BTreeMap<String, AnySyncStateEvent>>,
|
||||
pub session: Option<Session>,
|
||||
pub members: BTreeMap<RoomId, BTreeMap<UserId, SyncStateEvent<MemberEventContent>>>,
|
||||
pub state: BTreeMap<RoomId, BTreeMap<String, AnySyncStateEvent>>,
|
||||
pub room_summaries: BTreeMap<RoomId, InnerSummary>,
|
||||
// display_names: BTreeMap<RoomId, BTreeMap<String, BTreeMap<UserId, ()>>>,
|
||||
pub joined_user_ids: BTreeMap<RoomId, Vec<UserId>>,
|
||||
pub invited_user_ids: BTreeMap<RoomId, Vec<UserId>>,
|
||||
removed_user_ids: BTreeMap<RoomId, UserId>,
|
||||
pub removed_user_ids: BTreeMap<RoomId, UserId>,
|
||||
pub presence: BTreeMap<UserId, PresenceEvent>,
|
||||
}
|
||||
|
||||
impl StateChanges {
|
||||
|
@ -65,6 +68,10 @@ impl StateChanges {
|
|||
.insert(user_id, event);
|
||||
}
|
||||
|
||||
pub fn add_presence_event(&mut self, event: PresenceEvent) {
|
||||
self.presence.insert(event.sender.clone(), event);
|
||||
}
|
||||
|
||||
pub fn add_invited_member(
|
||||
&mut self,
|
||||
room_id: &RoomId,
|
||||
|
@ -455,6 +462,7 @@ impl Store {
|
|||
|
||||
let room_state = db.open_tree("room_state").unwrap();
|
||||
let room_summaries = db.open_tree("room_summaries").unwrap();
|
||||
let presence = db.open_tree("presence").unwrap();
|
||||
|
||||
Self {
|
||||
inner: db,
|
||||
|
@ -462,6 +470,7 @@ impl Store {
|
|||
members,
|
||||
joined_user_ids,
|
||||
invited_user_ids,
|
||||
presence,
|
||||
room_state,
|
||||
room_summaries,
|
||||
}
|
||||
|
@ -501,60 +510,67 @@ impl Store {
|
|||
&self.invited_user_ids,
|
||||
&self.room_state,
|
||||
&self.room_summaries,
|
||||
&self.presence,
|
||||
)
|
||||
.transaction(|(session, members, joined, invited, state, summaries)| {
|
||||
if let Some(s) = &changes.session {
|
||||
session.insert("session", serde_json::to_vec(s).unwrap())?;
|
||||
}
|
||||
|
||||
for (room, events) in &changes.members {
|
||||
for (user_id, event) in events {
|
||||
members.insert(
|
||||
format!("{}{}", room.as_str(), user_id.as_str()).as_str(),
|
||||
serde_json::to_vec(&event).unwrap(),
|
||||
)?;
|
||||
.transaction(
|
||||
|(session, members, joined, invited, state, summaries, presence)| {
|
||||
if let Some(s) = &changes.session {
|
||||
session.insert("session", serde_json::to_vec(s).unwrap())?;
|
||||
}
|
||||
}
|
||||
|
||||
for (room, users) in &changes.joined_user_ids {
|
||||
for user in users {
|
||||
let key = format!("{}{}", room.as_str(), user.as_str());
|
||||
info!("SAVING joined {}", &key);
|
||||
joined.insert(key.as_bytes(), user.as_bytes())?;
|
||||
invited.remove(key.as_bytes())?;
|
||||
for (room, events) in &changes.members {
|
||||
for (user_id, event) in events {
|
||||
members.insert(
|
||||
format!("{}{}", room.as_str(), user_id.as_str()).as_str(),
|
||||
serde_json::to_vec(&event).unwrap(),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (room, users) in &changes.invited_user_ids {
|
||||
for user in users {
|
||||
let key = format!("{}{}", room.as_str(), user.as_str());
|
||||
info!("SAVING invited {}", &key);
|
||||
invited.insert(key.as_bytes(), user.as_bytes())?;
|
||||
joined.remove(key.as_bytes())?;
|
||||
for (room, users) in &changes.joined_user_ids {
|
||||
for user in users {
|
||||
let key = format!("{}{}", room.as_str(), user.as_str());
|
||||
info!("SAVING joined {}", &key);
|
||||
joined.insert(key.as_bytes(), user.as_bytes())?;
|
||||
invited.remove(key.as_bytes())?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (room, events) in &changes.state {
|
||||
for (state_key, event) in events {
|
||||
state.insert(
|
||||
format!(
|
||||
"{}{}{}",
|
||||
room.as_str(),
|
||||
event.content().event_type(),
|
||||
state_key
|
||||
)
|
||||
.as_bytes(),
|
||||
serde_json::to_vec(&event).unwrap(),
|
||||
)?;
|
||||
for (room, users) in &changes.invited_user_ids {
|
||||
for user in users {
|
||||
let key = format!("{}{}", room.as_str(), user.as_str());
|
||||
info!("SAVING invited {}", &key);
|
||||
invited.insert(key.as_bytes(), user.as_bytes())?;
|
||||
joined.remove(key.as_bytes())?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (room_id, summary) in &changes.room_summaries {
|
||||
summaries.insert(room_id.as_str().as_bytes(), summary.serialize())?;
|
||||
}
|
||||
for (room, events) in &changes.state {
|
||||
for (state_key, event) in events {
|
||||
state.insert(
|
||||
format!(
|
||||
"{}{}{}",
|
||||
room.as_str(),
|
||||
event.content().event_type(),
|
||||
state_key
|
||||
)
|
||||
.as_bytes(),
|
||||
serde_json::to_vec(&event).unwrap(),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
});
|
||||
for (room_id, summary) in &changes.room_summaries {
|
||||
summaries.insert(room_id.as_bytes(), summary.serialize())?;
|
||||
}
|
||||
|
||||
for (sender, event) in &changes.presence {
|
||||
presence.insert(sender.as_bytes(), serde_json::to_vec(&event).unwrap())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
},
|
||||
);
|
||||
|
||||
ret.unwrap();
|
||||
|
||||
|
|
Loading…
Reference in a new issue