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