base: Store room account data.
parent
b36d907fac
commit
de61798d78
|
@ -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 {
|
||||||
|
|
|
@ -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,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
Loading…
Reference in New Issue