base: Store room account data.

master
Damir Jelić 2020-12-07 14:13:31 +01:00
parent b36d907fac
commit de61798d78
3 changed files with 96 additions and 29 deletions

View File

@ -29,7 +29,7 @@ use matrix_sdk_common::locks::Mutex;
use matrix_sdk_common::{ use matrix_sdk_common::{
api::r0 as api, api::r0 as api,
events::{ events::{
room::member::MemberEventContent, AnyStrippedStateEvent, AnySyncRoomEvent, room::member::MemberEventContent, AnyBasicEvent, AnyStrippedStateEvent, AnySyncRoomEvent,
AnySyncStateEvent, StateEvent, SyncStateEvent, AnySyncStateEvent, StateEvent, SyncStateEvent,
}, },
identifiers::{RoomId, UserId}, identifiers::{RoomId, UserId},
@ -54,7 +54,9 @@ use zeroize::Zeroizing;
use crate::{ use crate::{
error::Result, error::Result,
responses::{JoinedRoom, LeftRoom, Presence, Rooms, State, SyncResponse, Timeline}, responses::{
AccountData, JoinedRoom, LeftRoom, Presence, Rooms, State, SyncResponse, Timeline,
},
session::Session, session::Session,
store::{InnerSummary, Room, RoomType, StateChanges, Store}, store::{InnerSummary, Room, RoomType, StateChanges, Store},
}; };
@ -529,6 +531,22 @@ impl BaseClient {
state state
} }
async fn handle_room_account_data(
&self,
room_id: &RoomId,
events: &[Raw<AnyBasicEvent>],
changes: &mut StateChanges,
) -> AccountData {
let events: Vec<AnyBasicEvent> =
events.iter().filter_map(|e| e.deserialize().ok()).collect();
for event in &events {
changes.add_room_account_data(room_id, event.clone());
}
AccountData { events }
}
/// Receive a response from a sync call. /// Receive a response from a sync call.
/// ///
/// # Arguments /// # Arguments
@ -582,6 +600,10 @@ impl BaseClient {
.handle_timeline(&room_id, &room_info.timeline, &mut summary, &mut changes) .handle_timeline(&room_id, &room_info.timeline, &mut summary, &mut changes)
.await; .await;
let account_data = self
.handle_room_account_data(&room_id, &room_info.account_data.events, &mut changes)
.await;
#[cfg(feature = "encryption")] #[cfg(feature = "encryption")]
if summary.is_encrypted() { if summary.is_encrypted() {
// TODO if the room isn't encrypted but the new summary is, // TODO if the room isn't encrypted but the new summary is,
@ -601,7 +623,9 @@ impl BaseClient {
summary.mark_members_missing(); summary.mark_members_missing();
} }
rooms.join.insert(room_id, JoinedRoom::new(timeline, state)); rooms
.join
.insert(room_id, JoinedRoom::new(timeline, state, account_data));
changes.add_room(summary); changes.add_room(summary);
} }
@ -624,7 +648,13 @@ impl BaseClient {
.handle_timeline(&room_id, &room_info.timeline, &mut summary, &mut changes) .handle_timeline(&room_id, &room_info.timeline, &mut summary, &mut changes)
.await; .await;
rooms.leave.insert(room_id, LeftRoom::new(timeline, state)); let account_data = self
.handle_room_account_data(&room_id, &room_info.account_data.events, &mut changes)
.await;
rooms
.leave
.insert(room_id, LeftRoom::new(timeline, state, account_data));
} }
for event in &response.presence.events { for event in &response.presence.events {

View File

@ -3,7 +3,10 @@ use std::collections::BTreeMap;
use matrix_sdk_common::{ use matrix_sdk_common::{
api::r0::sync::sync_events::DeviceLists, api::r0::sync::sync_events::DeviceLists,
events::{presence::PresenceEvent, AnySyncRoomEvent, AnySyncStateEvent, AnyToDeviceEvent}, events::{
presence::PresenceEvent, AnyBasicEvent, AnySyncRoomEvent, AnySyncStateEvent,
AnyToDeviceEvent,
},
identifiers::{DeviceKeyAlgorithm, RoomId}, identifiers::{DeviceKeyAlgorithm, RoomId},
}; };
@ -44,6 +47,13 @@ pub struct Presence {
pub events: Vec<PresenceEvent>, pub events: Vec<PresenceEvent>,
} }
/// Data that the user has attached to either the account or a specific room.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct AccountData {
/// The list of account data events.
pub events: Vec<AnyBasicEvent>,
}
/// Messages sent dirrectly between devices. /// Messages sent dirrectly between devices.
#[derive(Clone, Debug, Default, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct ToDevice { pub struct ToDevice {
@ -72,16 +82,20 @@ pub struct JoinedRoom {
/// of the `timeline` (or all state up to the start of the `timeline`, if `since` is not /// of the `timeline` (or all state up to the start of the `timeline`, if `since` is not
/// given, or `full_state` is true). /// given, or `full_state` is true).
pub state: State, pub state: State,
// /// The private data that this user has attached to this room. /// The private data that this user has attached to this room.
// pub account_data: AccountData, pub account_data: AccountData,
// /// The ephemeral events in the room that aren't recorded in the timeline or state of the // /// The ephemeral events in the room that aren't recorded in the timeline or state of the
// /// room. e.g. typing. // /// room. e.g. typing.
// pub ephemeral: Ephemeral, // pub ephemeral: Ephemeral,
} }
impl JoinedRoom { impl JoinedRoom {
pub fn new(timeline: Timeline, state: State) -> Self { pub fn new(timeline: Timeline, state: State, account_data: AccountData) -> Self {
Self { timeline, state } Self {
timeline,
state,
account_data,
}
} }
} }
@ -94,11 +108,17 @@ pub struct LeftRoom {
/// of the `timeline` (or all state up to the start of the `timeline`, if `since` is not /// of the `timeline` (or all state up to the start of the `timeline`, if `since` is not
/// given, or `full_state` is true). /// given, or `full_state` is true).
pub state: State, pub state: State,
/// The private data that this user has attached to this room.
pub account_data: AccountData,
} }
impl LeftRoom { impl LeftRoom {
pub fn new(timeline: Timeline, state: State) -> Self { pub fn new(timeline: Timeline, state: State, account_data: AccountData) -> Self {
Self { timeline, state } Self {
timeline,
state,
account_data,
}
} }
} }

View File

@ -17,10 +17,9 @@ use matrix_sdk_common::{
encryption::EncryptionEventContent, member::MemberEventContent, encryption::EncryptionEventContent, member::MemberEventContent,
power_levels::PowerLevelsEventContent, power_levels::PowerLevelsEventContent,
}, },
AnySyncStateEvent, EventContent, EventType, SyncStateEvent, AnyBasicEvent, AnySyncStateEvent, EventContent, EventType, SyncStateEvent,
}, },
identifiers::{RoomAliasId, RoomId, UserId}, identifiers::{RoomAliasId, RoomId, UserId},
Raw,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -34,18 +33,20 @@ pub struct Store {
members: Tree, members: Tree,
joined_user_ids: Tree, joined_user_ids: Tree,
invited_user_ids: Tree, invited_user_ids: Tree,
room_state: Tree,
room_summaries: Tree, room_summaries: Tree,
room_state: Tree,
room_account_data: Tree,
presence: Tree, presence: Tree,
} }
use crate::{client::hoist_and_deserialize_state_event, Session}; use crate::Session;
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct StateChanges { pub struct StateChanges {
pub session: Option<Session>, pub session: Option<Session>,
pub members: BTreeMap<RoomId, BTreeMap<UserId, SyncStateEvent<MemberEventContent>>>, pub members: BTreeMap<RoomId, BTreeMap<UserId, SyncStateEvent<MemberEventContent>>>,
pub state: BTreeMap<RoomId, BTreeMap<String, AnySyncStateEvent>>, pub state: BTreeMap<RoomId, BTreeMap<String, AnySyncStateEvent>>,
pub room_account_data: BTreeMap<RoomId, BTreeMap<String, AnyBasicEvent>>,
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>>,
@ -96,6 +97,13 @@ impl StateChanges {
.insert(room.room_id.as_ref().to_owned(), room); .insert(room.room_id.as_ref().to_owned(), room);
} }
pub fn add_room_account_data(&mut self, room_id: &RoomId, event: AnyBasicEvent) {
self.room_account_data
.entry(room_id.to_owned())
.or_insert_with(BTreeMap::new)
.insert(event.content().event_type().to_owned(), event);
}
pub fn add_state_event(&mut self, room_id: &RoomId, event: AnySyncStateEvent) { pub fn add_state_event(&mut self, room_id: &RoomId, event: AnySyncStateEvent) {
self.state self.state
.entry(room_id.to_owned()) .entry(room_id.to_owned())
@ -402,18 +410,6 @@ pub struct InnerSummary {
} }
impl InnerSummary { impl InnerSummary {
pub fn handle_state_events(&mut self, state_events: &[Raw<AnySyncStateEvent>]) {
for e in state_events {
if let Ok(event) = hoist_and_deserialize_state_event(e) {
match event {
_ => {
self.handle_state_event(&event);
}
}
}
}
}
pub fn mark_as_joined(&mut self) { pub fn mark_as_joined(&mut self) {
self.room_type = RoomType::Joined; self.room_type = RoomType::Joined;
} }
@ -507,6 +503,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(); let presence = db.open_tree("presence").unwrap();
let room_account_data = db.open_tree("room_account_data").unwrap();
Self { Self {
inner: db, inner: db,
@ -514,6 +511,7 @@ impl Store {
members, members,
joined_user_ids, joined_user_ids,
invited_user_ids, invited_user_ids,
room_account_data,
presence, presence,
room_state, room_state,
room_summaries, room_summaries,
@ -552,12 +550,22 @@ impl Store {
&self.members, &self.members,
&self.joined_user_ids, &self.joined_user_ids,
&self.invited_user_ids, &self.invited_user_ids,
&self.room_state,
&self.room_summaries, &self.room_summaries,
&self.room_state,
&self.room_account_data,
&self.presence, &self.presence,
) )
.transaction( .transaction(
|(session, members, joined, invited, state, summaries, presence)| { |(
session,
members,
joined,
invited,
summaries,
state,
room_account_data,
presence,
)| {
if let Some(s) = &changes.session { if let Some(s) = &changes.session {
session.insert("session", serde_json::to_vec(s).unwrap())?; session.insert("session", serde_json::to_vec(s).unwrap())?;
} }
@ -571,6 +579,15 @@ impl Store {
} }
} }
for (room, events) in &changes.room_account_data {
for (event_type, event) in events {
room_account_data.insert(
format!("{}{}", room.as_str(), event_type).as_str(),
serde_json::to_vec(&event).unwrap(),
)?;
}
}
for (room, users) in &changes.joined_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());