base: Add presence storing.
parent
ac2d90e92a
commit
38048a2043
|
@ -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(())
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue