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::{
api::r0 as api,
events::{
room::member::MemberEventContent, AnyStrippedStateEvent, AnySyncRoomEvent,
room::member::MemberEventContent, AnyBasicEvent, AnyStrippedStateEvent, AnySyncRoomEvent,
AnySyncStateEvent, StateEvent, SyncStateEvent,
},
identifiers::{RoomId, UserId},
@ -54,7 +54,9 @@ use zeroize::Zeroizing;
use crate::{
error::Result,
responses::{JoinedRoom, LeftRoom, Presence, Rooms, State, SyncResponse, Timeline},
responses::{
AccountData, JoinedRoom, LeftRoom, Presence, Rooms, State, SyncResponse, Timeline,
},
session::Session,
store::{InnerSummary, Room, RoomType, StateChanges, Store},
};
@ -529,6 +531,22 @@ impl BaseClient {
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.
///
/// # Arguments
@ -582,6 +600,10 @@ impl BaseClient {
.handle_timeline(&room_id, &room_info.timeline, &mut summary, &mut changes)
.await;
let account_data = self
.handle_room_account_data(&room_id, &room_info.account_data.events, &mut changes)
.await;
#[cfg(feature = "encryption")]
if summary.is_encrypted() {
// TODO if the room isn't encrypted but the new summary is,
@ -601,7 +623,9 @@ impl BaseClient {
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);
}
@ -624,7 +648,13 @@ impl BaseClient {
.handle_timeline(&room_id, &room_info.timeline, &mut summary, &mut changes)
.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 {

View File

@ -3,7 +3,10 @@ use std::collections::BTreeMap;
use matrix_sdk_common::{
api::r0::sync::sync_events::DeviceLists,
events::{presence::PresenceEvent, AnySyncRoomEvent, AnySyncStateEvent, AnyToDeviceEvent},
events::{
presence::PresenceEvent, AnyBasicEvent, AnySyncRoomEvent, AnySyncStateEvent,
AnyToDeviceEvent,
},
identifiers::{DeviceKeyAlgorithm, RoomId},
};
@ -44,6 +47,13 @@ pub struct Presence {
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.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
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
/// given, or `full_state` is true).
pub state: State,
// /// The private data that this user has attached to this room.
// pub account_data: AccountData,
/// The private data that this user has attached to this room.
pub account_data: AccountData,
// /// The ephemeral events in the room that aren't recorded in the timeline or state of the
// /// room. e.g. typing.
// pub ephemeral: Ephemeral,
}
impl JoinedRoom {
pub fn new(timeline: Timeline, state: State) -> Self {
Self { timeline, state }
pub fn new(timeline: Timeline, state: State, account_data: AccountData) -> Self {
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
/// given, or `full_state` is true).
pub state: State,
/// The private data that this user has attached to this room.
pub account_data: AccountData,
}
impl LeftRoom {
pub fn new(timeline: Timeline, state: State) -> Self {
Self { timeline, state }
pub fn new(timeline: Timeline, state: State, account_data: AccountData) -> Self {
Self {
timeline,
state,
account_data,
}
}
}

View File

@ -17,10 +17,9 @@ use matrix_sdk_common::{
encryption::EncryptionEventContent, member::MemberEventContent,
power_levels::PowerLevelsEventContent,
},
AnySyncStateEvent, EventContent, EventType, SyncStateEvent,
AnyBasicEvent, AnySyncStateEvent, EventContent, EventType, SyncStateEvent,
},
identifiers::{RoomAliasId, RoomId, UserId},
Raw,
};
use serde::{Deserialize, Serialize};
@ -34,18 +33,20 @@ pub struct Store {
members: Tree,
joined_user_ids: Tree,
invited_user_ids: Tree,
room_state: Tree,
room_summaries: Tree,
room_state: Tree,
room_account_data: Tree,
presence: Tree,
}
use crate::{client::hoist_and_deserialize_state_event, Session};
use crate::Session;
#[derive(Debug, Default)]
pub struct StateChanges {
pub session: Option<Session>,
pub members: BTreeMap<RoomId, BTreeMap<UserId, SyncStateEvent<MemberEventContent>>>,
pub state: BTreeMap<RoomId, BTreeMap<String, AnySyncStateEvent>>,
pub room_account_data: BTreeMap<RoomId, BTreeMap<String, AnyBasicEvent>>,
pub room_summaries: BTreeMap<RoomId, InnerSummary>,
// display_names: BTreeMap<RoomId, BTreeMap<String, BTreeMap<UserId, ()>>>,
pub joined_user_ids: BTreeMap<RoomId, Vec<UserId>>,
@ -96,6 +97,13 @@ impl StateChanges {
.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) {
self.state
.entry(room_id.to_owned())
@ -402,18 +410,6 @@ pub struct 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) {
self.room_type = RoomType::Joined;
}
@ -507,6 +503,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();
let room_account_data = db.open_tree("room_account_data").unwrap();
Self {
inner: db,
@ -514,6 +511,7 @@ impl Store {
members,
joined_user_ids,
invited_user_ids,
room_account_data,
presence,
room_state,
room_summaries,
@ -552,12 +550,22 @@ impl Store {
&self.members,
&self.joined_user_ids,
&self.invited_user_ids,
&self.room_state,
&self.room_summaries,
&self.room_state,
&self.room_account_data,
&self.presence,
)
.transaction(
|(session, members, joined, invited, state, summaries, presence)| {
|(
session,
members,
joined,
invited,
summaries,
state,
room_account_data,
presence,
)| {
if let Some(s) = &changes.session {
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 user in users {
let key = format!("{}{}", room.as_str(), user.as_str());