base: Add presence storing.

master
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); 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.store.save_changes(&changes).await;
*self.sync_token.write().await = Some(response.next_batch.clone()); *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 // 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) { 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); changes.add_room(summary);
self.store.save_changes(&changes).await; self.store.save_changes(&changes).await;
self.apply_changes(changes).await; self.apply_changes(&changes).await;
} }
Ok(()) Ok(())

View File

@ -2,20 +2,20 @@ use serde::{Deserialize, Serialize};
use std::collections::BTreeMap; use std::collections::BTreeMap;
use matrix_sdk_common::{ use matrix_sdk_common::{
events::{AnySyncRoomEvent, AnySyncStateEvent}, events::{presence::PresenceEvent, AnySyncRoomEvent, AnySyncStateEvent},
identifiers::RoomId, identifiers::RoomId,
}; };
use crate::store::StateChanges;
#[derive(Clone, Debug, Default, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct SyncResponse { pub struct SyncResponse {
/// The batch token to supply in the `since` param of the next `/sync` request. /// The batch token to supply in the `since` param of the next `/sync` request.
pub next_batch: String, pub next_batch: String,
/// Updates to rooms. /// Updates to rooms.
pub rooms: Rooms, pub rooms: Rooms,
///// Updates to the presence status of other users. /// Updates to the presence status of other users.
//#[serde(default, skip_serializing_if = "Presence::is_empty")] pub presence: Presence,
//pub presence: Presence,
///// The global private data created by this user. ///// The global private data created by this user.
//#[serde(default, skip_serializing_if = "AccountData::is_empty")] //#[serde(default, skip_serializing_if = "AccountData::is_empty")]
//pub account_data: AccountData, //pub account_data: AccountData,
@ -37,8 +37,15 @@ pub struct SyncResponse {
} }
impl SyncResponse { impl SyncResponse {
pub fn new(next_batch: String, rooms: Rooms) -> Self { pub fn new(next_batch: String, rooms: Rooms, changes: StateChanges) -> Self {
Self { next_batch, rooms } 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 { 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)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct Rooms { pub struct Rooms {
// /// The rooms that the user has left or been banned from. // /// The rooms that the user has left or been banned from.

View File

@ -12,6 +12,7 @@ use futures::{
use matrix_sdk_common::{ use matrix_sdk_common::{
api::r0::sync::sync_events::RoomSummary as RumaSummary, api::r0::sync::sync_events::RoomSummary as RumaSummary,
events::{ events::{
presence::PresenceEvent,
room::{encryption::EncryptionEventContent, member::MemberEventContent}, room::{encryption::EncryptionEventContent, member::MemberEventContent},
AnySyncStateEvent, EventContent, SyncStateEvent, AnySyncStateEvent, EventContent, SyncStateEvent,
}, },
@ -32,20 +33,22 @@ pub struct Store {
invited_user_ids: Tree, invited_user_ids: Tree,
room_state: Tree, room_state: Tree,
room_summaries: Tree, room_summaries: Tree,
presence: Tree,
} }
use crate::{client::hoist_and_deserialize_state_event, Session}; use crate::{client::hoist_and_deserialize_state_event, Session};
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct StateChanges { pub struct StateChanges {
session: Option<Session>, pub session: Option<Session>,
members: BTreeMap<RoomId, BTreeMap<UserId, SyncStateEvent<MemberEventContent>>>, pub members: BTreeMap<RoomId, BTreeMap<UserId, SyncStateEvent<MemberEventContent>>>,
state: BTreeMap<RoomId, BTreeMap<String, AnySyncStateEvent>>, pub state: BTreeMap<RoomId, BTreeMap<String, AnySyncStateEvent>>,
pub room_summaries: BTreeMap<RoomId, InnerSummary>, pub room_summaries: BTreeMap<RoomId, InnerSummary>,
// display_names: BTreeMap<RoomId, BTreeMap<String, BTreeMap<UserId, ()>>>, // display_names: BTreeMap<RoomId, BTreeMap<String, BTreeMap<UserId, ()>>>,
pub joined_user_ids: BTreeMap<RoomId, Vec<UserId>>, pub joined_user_ids: BTreeMap<RoomId, Vec<UserId>>,
pub invited_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 { impl StateChanges {
@ -65,6 +68,10 @@ impl StateChanges {
.insert(user_id, event); .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( pub fn add_invited_member(
&mut self, &mut self,
room_id: &RoomId, room_id: &RoomId,
@ -455,6 +462,7 @@ impl Store {
let room_state = db.open_tree("room_state").unwrap(); let room_state = db.open_tree("room_state").unwrap();
let room_summaries = db.open_tree("room_summaries").unwrap(); let room_summaries = db.open_tree("room_summaries").unwrap();
let presence = db.open_tree("presence").unwrap();
Self { Self {
inner: db, inner: db,
@ -462,6 +470,7 @@ impl Store {
members, members,
joined_user_ids, joined_user_ids,
invited_user_ids, invited_user_ids,
presence,
room_state, room_state,
room_summaries, room_summaries,
} }
@ -501,60 +510,67 @@ impl Store {
&self.invited_user_ids, &self.invited_user_ids,
&self.room_state, &self.room_state,
&self.room_summaries, &self.room_summaries,
&self.presence,
) )
.transaction(|(session, members, joined, invited, state, summaries)| { .transaction(
if let Some(s) = &changes.session { |(session, members, joined, invited, state, summaries, presence)| {
session.insert("session", serde_json::to_vec(s).unwrap())?; 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(),
)?;
} }
}
for (room, users) in &changes.joined_user_ids { for (room, events) in &changes.members {
for user in users { for (user_id, event) in events {
let key = format!("{}{}", room.as_str(), user.as_str()); members.insert(
info!("SAVING joined {}", &key); format!("{}{}", room.as_str(), user_id.as_str()).as_str(),
joined.insert(key.as_bytes(), user.as_bytes())?; serde_json::to_vec(&event).unwrap(),
invited.remove(key.as_bytes())?; )?;
}
} }
}
for (room, users) in &changes.invited_user_ids { for (room, users) in &changes.joined_user_ids {
for user in users { for user in users {
let key = format!("{}{}", room.as_str(), user.as_str()); let key = format!("{}{}", room.as_str(), user.as_str());
info!("SAVING invited {}", &key); info!("SAVING joined {}", &key);
invited.insert(key.as_bytes(), user.as_bytes())?; joined.insert(key.as_bytes(), user.as_bytes())?;
joined.remove(key.as_bytes())?; invited.remove(key.as_bytes())?;
}
} }
}
for (room, events) in &changes.state { for (room, users) in &changes.invited_user_ids {
for (state_key, event) in events { for user in users {
state.insert( let key = format!("{}{}", room.as_str(), user.as_str());
format!( info!("SAVING invited {}", &key);
"{}{}{}", invited.insert(key.as_bytes(), user.as_bytes())?;
room.as_str(), joined.remove(key.as_bytes())?;
event.content().event_type(), }
state_key
)
.as_bytes(),
serde_json::to_vec(&event).unwrap(),
)?;
} }
}
for (room_id, summary) in &changes.room_summaries { for (room, events) in &changes.state {
summaries.insert(room_id.as_str().as_bytes(), summary.serialize())?; 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(); ret.unwrap();