base: Add presence storing.

This commit is contained in:
Damir Jelić 2020-11-30 14:42:08 +01:00
parent ac2d90e92a
commit 38048a2043
3 changed files with 101 additions and 61 deletions

View file

@ -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(())

View file

@ -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.

View file

@ -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();