base: Add a common room info struct for normal and stripped rooms.
This commit is contained in:
parent
3a76cf7692
commit
45db95742a
4 changed files with 145 additions and 124 deletions
|
@ -30,8 +30,10 @@ use futures::StreamExt;
|
|||
use matrix_sdk_common::{
|
||||
api::r0 as api,
|
||||
events::{
|
||||
presence::PresenceEvent, room::member::{MemberEventContent, MembershipState}, AnyBasicEvent,
|
||||
AnyStrippedStateEvent, AnySyncRoomEvent, AnySyncStateEvent, EventContent, StateEvent,
|
||||
presence::PresenceEvent,
|
||||
room::member::{MemberEventContent, MembershipState},
|
||||
AnyBasicEvent, AnyStrippedStateEvent, AnySyncRoomEvent, AnySyncStateEvent, EventContent,
|
||||
StateEvent,
|
||||
},
|
||||
identifiers::{RoomId, UserId},
|
||||
locks::RwLock,
|
||||
|
@ -40,10 +42,7 @@ use matrix_sdk_common::{
|
|||
#[cfg(feature = "encryption")]
|
||||
use matrix_sdk_common::{
|
||||
api::r0::keys::claim_keys::Request as KeysClaimRequest,
|
||||
events::{
|
||||
room::encrypted::EncryptedEventContent,
|
||||
AnyMessageEventContent, AnySyncMessageEvent,
|
||||
},
|
||||
events::{room::encrypted::EncryptedEventContent, AnyMessageEventContent, AnySyncMessageEvent},
|
||||
identifiers::DeviceId,
|
||||
locks::Mutex,
|
||||
uuid::Uuid,
|
||||
|
@ -456,7 +455,7 @@ impl BaseClient {
|
|||
&self,
|
||||
room_id: &RoomId,
|
||||
ruma_timeline: api::sync::sync_events::Timeline,
|
||||
summary: &mut RoomInfo,
|
||||
room_info: &mut RoomInfo,
|
||||
changes: &mut StateChanges,
|
||||
user_ids: &mut BTreeSet<UserId>,
|
||||
) -> Timeline {
|
||||
|
@ -485,7 +484,7 @@ impl BaseClient {
|
|||
}
|
||||
}
|
||||
_ => {
|
||||
summary.handle_state_event(&s);
|
||||
room_info.handle_state_event(&s);
|
||||
changes.add_state_event(room_id, s.clone());
|
||||
}
|
||||
},
|
||||
|
@ -668,40 +667,39 @@ impl BaseClient {
|
|||
let mut changes = StateChanges::default();
|
||||
let mut rooms = Rooms::default();
|
||||
|
||||
for (room_id, room_info) in response.rooms.join {
|
||||
for (room_id, new_info) in response.rooms.join {
|
||||
let room = self.get_or_create_room(&room_id, RoomType::Joined).await;
|
||||
let mut summary = room.clone_summary();
|
||||
let mut room_info = room.clone_info();
|
||||
|
||||
summary.mark_as_joined();
|
||||
summary.update(&room_info.summary);
|
||||
summary.set_prev_batch(room_info.timeline.prev_batch.as_deref());
|
||||
room_info.update_summary(&new_info.summary);
|
||||
room_info.set_prev_batch(new_info.timeline.prev_batch.as_deref());
|
||||
|
||||
let (state, members, state_events, mut user_ids) =
|
||||
self.handle_state(room_info.state.events, &mut summary);
|
||||
self.handle_state(new_info.state.events, &mut room_info);
|
||||
|
||||
changes.members.insert(room_id.clone(), members);
|
||||
changes.state.insert(room_id.clone(), state_events);
|
||||
|
||||
if room_info.timeline.limited {
|
||||
summary.mark_members_missing();
|
||||
if new_info.timeline.limited {
|
||||
room_info.mark_members_missing();
|
||||
}
|
||||
|
||||
let timeline = self
|
||||
.handle_timeline(
|
||||
&room_id,
|
||||
room_info.timeline,
|
||||
&mut summary,
|
||||
new_info.timeline,
|
||||
&mut room_info,
|
||||
&mut changes,
|
||||
&mut user_ids,
|
||||
)
|
||||
.await;
|
||||
|
||||
let account_data = self
|
||||
.handle_room_account_data(&room_id, &room_info.account_data.events, &mut changes)
|
||||
.handle_room_account_data(&room_id, &new_info.account_data.events, &mut changes)
|
||||
.await;
|
||||
|
||||
#[cfg(feature = "encryption")]
|
||||
if summary.is_encrypted() {
|
||||
if room_info.is_encrypted() {
|
||||
if let Some(o) = self.olm_machine().await {
|
||||
if !room.is_encrypted() {
|
||||
// The room turned on encryption in this sync, we need
|
||||
|
@ -719,12 +717,12 @@ impl BaseClient {
|
|||
}
|
||||
}
|
||||
|
||||
let notification_count = room_info.unread_notifications.into();
|
||||
summary.update_notification_count(notification_count);
|
||||
let notification_count = new_info.unread_notifications.into();
|
||||
room_info.update_notification_count(notification_count);
|
||||
|
||||
// TODO should we store this?
|
||||
let ephemeral = Ephemeral {
|
||||
events: room_info
|
||||
events: new_info
|
||||
.ephemeral
|
||||
.events
|
||||
.into_iter()
|
||||
|
@ -737,16 +735,16 @@ impl BaseClient {
|
|||
JoinedRoom::new(timeline, state, account_data, ephemeral, notification_count),
|
||||
);
|
||||
|
||||
changes.add_room(summary);
|
||||
changes.add_room(room_info);
|
||||
}
|
||||
|
||||
for (room_id, room_info) in response.rooms.leave {
|
||||
for (room_id, new_info) in response.rooms.leave {
|
||||
let room = self.get_or_create_room(&room_id, RoomType::Left).await;
|
||||
let mut summary = room.clone_summary();
|
||||
summary.mark_as_left();
|
||||
let mut room_info = room.clone_info();
|
||||
room_info.mark_as_left();
|
||||
|
||||
let (state, members, state_events, mut user_ids) =
|
||||
self.handle_state(room_info.state.events, &mut summary);
|
||||
self.handle_state(new_info.state.events, &mut room_info);
|
||||
|
||||
changes.members.insert(room_id.clone(), members);
|
||||
changes.state.insert(room_id.clone(), state_events);
|
||||
|
@ -754,15 +752,15 @@ impl BaseClient {
|
|||
let timeline = self
|
||||
.handle_timeline(
|
||||
&room_id,
|
||||
room_info.timeline,
|
||||
&mut summary,
|
||||
new_info.timeline,
|
||||
&mut room_info,
|
||||
&mut changes,
|
||||
&mut user_ids,
|
||||
)
|
||||
.await;
|
||||
|
||||
let account_data = self
|
||||
.handle_room_account_data(&room_id, &room_info.account_data.events, &mut changes)
|
||||
.handle_room_account_data(&room_id, &new_info.account_data.events, &mut changes)
|
||||
.await;
|
||||
|
||||
rooms
|
||||
|
@ -770,19 +768,19 @@ impl BaseClient {
|
|||
.insert(room_id, LeftRoom::new(timeline, state, account_data));
|
||||
}
|
||||
|
||||
for (room_id, invited) in response.rooms.invite {
|
||||
for (room_id, new_info) in response.rooms.invite {
|
||||
{
|
||||
let room = self.get_or_create_room(&room_id, RoomType::Invited).await;
|
||||
let mut room_info = room.clone_summary();
|
||||
let mut room_info = room.clone_info();
|
||||
room_info.mark_as_invited();
|
||||
changes.add_room(room_info);
|
||||
}
|
||||
|
||||
let room = self.get_or_create_stripped_room(&room_id).await;
|
||||
let mut room_info = room.clone_summary();
|
||||
let mut room_info = room.clone_info();
|
||||
|
||||
let (state, members, state_events) =
|
||||
self.handle_invited_state(invited.invite_state.events, &mut room_info);
|
||||
self.handle_invited_state(new_info.invite_state.events, &mut room_info);
|
||||
|
||||
changes.stripped_members.insert(room_id.clone(), members);
|
||||
changes.stripped_state.insert(room_id.clone(), state_events);
|
||||
|
@ -846,9 +844,9 @@ impl BaseClient {
|
|||
|
||||
async fn apply_changes(&self, changes: &StateChanges) {
|
||||
// TODO emit room changes here
|
||||
for (room_id, summary) in &changes.room_infos {
|
||||
for (room_id, room_info) in &changes.room_infos {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
room.update_summary(summary.clone())
|
||||
room.update_summary(room_info.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -859,8 +857,8 @@ impl BaseClient {
|
|||
response: &api::membership::get_member_events::Response,
|
||||
) -> Result<()> {
|
||||
if let Some(room) = self.get_room(room_id) {
|
||||
let mut summary = room.clone_summary();
|
||||
summary.mark_members_synced();
|
||||
let mut room_info = room.clone_info();
|
||||
room_info.mark_members_synced();
|
||||
|
||||
let mut members = BTreeMap::new();
|
||||
|
||||
|
@ -877,7 +875,7 @@ impl BaseClient {
|
|||
.store
|
||||
.get_member_event(&room_id, &member.state_key)
|
||||
.await
|
||||
.is_some()
|
||||
.is_none()
|
||||
{
|
||||
#[cfg(feature = "encryption")]
|
||||
match member.content.membership {
|
||||
|
@ -895,13 +893,13 @@ impl BaseClient {
|
|||
changes.members.insert(room_id.clone(), members);
|
||||
|
||||
#[cfg(feature = "encryption")]
|
||||
if summary.is_encrypted() {
|
||||
if room_info.is_encrypted() {
|
||||
if let Some(o) = self.olm_machine().await {
|
||||
o.update_tracked_users(&user_ids).await
|
||||
}
|
||||
}
|
||||
|
||||
changes.add_room(summary);
|
||||
changes.add_room(room_info);
|
||||
|
||||
self.store.save_changes(&changes).await;
|
||||
self.apply_changes(&changes).await;
|
||||
|
|
|
@ -6,3 +6,79 @@ pub use normal::{Room, RoomInfo, RoomType};
|
|||
pub use stripped::{StrippedRoom, StrippedRoomInfo};
|
||||
|
||||
pub use members::RoomMember;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cmp::max;
|
||||
|
||||
use matrix_sdk_common::{
|
||||
events::{
|
||||
room::{encryption::EncryptionEventContent, tombstone::TombstoneEventContent},
|
||||
AnyStateEventContent,
|
||||
},
|
||||
identifiers::RoomAliasId,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct BaseRoomInfo {
|
||||
pub name: Option<String>,
|
||||
pub canonical_alias: Option<RoomAliasId>,
|
||||
pub avatar_url: Option<String>,
|
||||
pub topic: Option<String>,
|
||||
pub encryption: Option<EncryptionEventContent>,
|
||||
pub tombstone: Option<TombstoneEventContent>,
|
||||
pub max_power_level: i64,
|
||||
}
|
||||
|
||||
impl BaseRoomInfo {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn handle_state_event(&mut self, content: &AnyStateEventContent) -> bool {
|
||||
match content {
|
||||
AnyStateEventContent::RoomEncryption(encryption) => {
|
||||
self.encryption = Some(encryption.clone());
|
||||
true
|
||||
}
|
||||
AnyStateEventContent::RoomName(n) => {
|
||||
self.name = n.name().map(|n| n.to_string());
|
||||
true
|
||||
}
|
||||
AnyStateEventContent::RoomCanonicalAlias(a) => {
|
||||
self.canonical_alias = a.alias.clone();
|
||||
true
|
||||
}
|
||||
AnyStateEventContent::RoomTopic(t) => {
|
||||
self.topic = Some(t.topic.clone());
|
||||
true
|
||||
}
|
||||
AnyStateEventContent::RoomTombstone(t) => {
|
||||
self.tombstone = Some(t.clone());
|
||||
true
|
||||
}
|
||||
AnyStateEventContent::RoomPowerLevels(p) => {
|
||||
let max_power_level = p
|
||||
.users
|
||||
.values()
|
||||
.fold(self.max_power_level, |acc, p| max(acc, (*p).into()));
|
||||
self.max_power_level = max_power_level;
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for BaseRoomInfo {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: None,
|
||||
canonical_alias: None,
|
||||
avatar_url: None,
|
||||
topic: None,
|
||||
encryption: None,
|
||||
tombstone: None,
|
||||
max_power_level: 100,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,14 +23,14 @@ use futures::{
|
|||
};
|
||||
use matrix_sdk_common::{
|
||||
api::r0::sync::sync_events::RoomSummary as RumaSummary,
|
||||
events::{room::encryption::EncryptionEventContent, AnySyncStateEvent, EventType},
|
||||
identifiers::{RoomAliasId, RoomId, UserId},
|
||||
events::{AnySyncStateEvent, EventType},
|
||||
identifiers::{RoomId, UserId},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{responses::UnreadNotificationsCount, store::Store};
|
||||
|
||||
use super::RoomMember;
|
||||
use super::{BaseRoomInfo, RoomMember};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Room {
|
||||
|
@ -69,15 +69,11 @@ impl Room {
|
|||
inner: Arc::new(SyncMutex::new(RoomInfo {
|
||||
room_id,
|
||||
room_type,
|
||||
encryption: None,
|
||||
summary: Default::default(),
|
||||
last_prev_batch: None,
|
||||
members_synced: false,
|
||||
name: None,
|
||||
canonical_alias: None,
|
||||
avatar_url: None,
|
||||
topic: None,
|
||||
notification_counts: Default::default(),
|
||||
summary: Default::default(),
|
||||
members_synced: false,
|
||||
last_prev_batch: None,
|
||||
base_info: BaseRoomInfo::new(),
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
@ -128,10 +124,10 @@ impl Room {
|
|||
pub async fn calculate_name(&self) -> String {
|
||||
let inner = self.inner.lock().unwrap();
|
||||
|
||||
if let Some(name) = &inner.name {
|
||||
if let Some(name) = &inner.base_info.name {
|
||||
let name = name.trim();
|
||||
name.to_string()
|
||||
} else if let Some(alias) = &inner.canonical_alias {
|
||||
} else if let Some(alias) = &inner.base_info.canonical_alias {
|
||||
let alias = alias.alias().trim();
|
||||
alias.to_string()
|
||||
} else {
|
||||
|
@ -210,7 +206,7 @@ impl Room {
|
|||
&self.own_user_id
|
||||
}
|
||||
|
||||
pub(crate) fn clone_summary(&self) -> RoomInfo {
|
||||
pub(crate) fn clone_info(&self) -> RoomInfo {
|
||||
(*self.inner.lock().unwrap()).clone()
|
||||
}
|
||||
|
||||
|
@ -219,7 +215,7 @@ impl Room {
|
|||
}
|
||||
|
||||
pub fn is_encrypted(&self) -> bool {
|
||||
self.inner.lock().unwrap().encryption.is_some()
|
||||
self.inner.lock().unwrap().is_encrypted()
|
||||
}
|
||||
|
||||
pub fn update_summary(&self, summary: RoomInfo) {
|
||||
|
@ -270,17 +266,12 @@ pub struct RoomInfo {
|
|||
pub room_id: Arc<RoomId>,
|
||||
pub room_type: RoomType,
|
||||
|
||||
pub name: Option<String>,
|
||||
pub canonical_alias: Option<RoomAliasId>,
|
||||
pub avatar_url: Option<String>,
|
||||
pub topic: Option<String>,
|
||||
|
||||
pub notification_counts: UnreadNotificationsCount,
|
||||
pub summary: RoomSummary,
|
||||
pub members_synced: bool,
|
||||
|
||||
pub encryption: Option<EncryptionEventContent>,
|
||||
pub last_prev_batch: Option<String>,
|
||||
|
||||
pub base_info: BaseRoomInfo,
|
||||
}
|
||||
|
||||
impl RoomInfo {
|
||||
|
@ -313,37 +304,19 @@ impl RoomInfo {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn handle_state_event(&mut self, event: &AnySyncStateEvent) -> bool {
|
||||
match event {
|
||||
AnySyncStateEvent::RoomEncryption(encryption) => {
|
||||
self.encryption = Some(encryption.content.clone());
|
||||
true
|
||||
}
|
||||
AnySyncStateEvent::RoomName(n) => {
|
||||
self.name = n.content.name().map(|n| n.to_string());
|
||||
true
|
||||
}
|
||||
AnySyncStateEvent::RoomCanonicalAlias(a) => {
|
||||
self.canonical_alias = a.content.alias.clone();
|
||||
true
|
||||
}
|
||||
AnySyncStateEvent::RoomTopic(t) => {
|
||||
self.topic = Some(t.content.topic.clone());
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
pub fn is_encrypted(&self) -> bool {
|
||||
self.base_info.encryption.is_some()
|
||||
}
|
||||
|
||||
pub fn is_encrypted(&self) -> bool {
|
||||
self.encryption.is_some()
|
||||
pub fn handle_state_event(&mut self, event: &AnySyncStateEvent) -> bool {
|
||||
self.base_info.handle_state_event(&event.content())
|
||||
}
|
||||
|
||||
pub fn update_notification_count(&mut self, notification_counts: UnreadNotificationsCount) {
|
||||
self.notification_counts = notification_counts;
|
||||
}
|
||||
|
||||
pub(crate) fn update(&mut self, summary: &RumaSummary) -> bool {
|
||||
pub(crate) fn update_summary(&mut self, summary: &RumaSummary) -> bool {
|
||||
let mut changed = false;
|
||||
|
||||
if !summary.is_empty() {
|
||||
|
|
|
@ -15,13 +15,15 @@
|
|||
use std::sync::{Arc, Mutex as SyncMutex};
|
||||
|
||||
use matrix_sdk_common::{
|
||||
events::{room::encryption::EncryptionEventContent, AnyStrippedStateEvent},
|
||||
identifiers::{RoomAliasId, RoomId, UserId},
|
||||
events::AnyStrippedStateEvent,
|
||||
identifiers::{RoomId, UserId},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::store::Store;
|
||||
|
||||
use super::BaseRoomInfo;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct StrippedRoom {
|
||||
room_id: Arc<RoomId>,
|
||||
|
@ -40,11 +42,7 @@ impl StrippedRoom {
|
|||
store,
|
||||
inner: Arc::new(SyncMutex::new(StrippedRoomInfo {
|
||||
room_id,
|
||||
encryption: None,
|
||||
name: None,
|
||||
canonical_alias: None,
|
||||
avatar_url: None,
|
||||
topic: None,
|
||||
base_info: BaseRoomInfo::new(),
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
@ -59,10 +57,10 @@ impl StrippedRoom {
|
|||
pub async fn calculate_name(&self) -> String {
|
||||
let inner = self.inner.lock().unwrap();
|
||||
|
||||
if let Some(name) = &inner.name {
|
||||
if let Some(name) = &inner.base_info.name {
|
||||
let name = name.trim();
|
||||
name.to_string()
|
||||
} else if let Some(alias) = &inner.canonical_alias {
|
||||
} else if let Some(alias) = &inner.base_info.canonical_alias {
|
||||
let alias = alias.alias().trim();
|
||||
alias.to_string()
|
||||
} else {
|
||||
|
@ -142,12 +140,12 @@ impl StrippedRoom {
|
|||
&self.own_user_id
|
||||
}
|
||||
|
||||
pub(crate) fn clone_summary(&self) -> StrippedRoomInfo {
|
||||
pub(crate) fn clone_info(&self) -> StrippedRoomInfo {
|
||||
(*self.inner.lock().unwrap()).clone()
|
||||
}
|
||||
|
||||
pub fn is_encrypted(&self) -> bool {
|
||||
self.inner.lock().unwrap().encryption.is_some()
|
||||
self.inner.lock().unwrap().base_info.encryption.is_some()
|
||||
}
|
||||
|
||||
pub fn room_id(&self) -> &RoomId {
|
||||
|
@ -162,35 +160,11 @@ impl StrippedRoom {
|
|||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct StrippedRoomInfo {
|
||||
pub room_id: Arc<RoomId>,
|
||||
|
||||
pub name: Option<String>,
|
||||
pub canonical_alias: Option<RoomAliasId>,
|
||||
pub avatar_url: Option<String>,
|
||||
pub topic: Option<String>,
|
||||
|
||||
pub encryption: Option<EncryptionEventContent>,
|
||||
pub base_info: BaseRoomInfo,
|
||||
}
|
||||
|
||||
impl StrippedRoomInfo {
|
||||
pub(crate) fn handle_state_event(&mut self, event: &AnyStrippedStateEvent) -> bool {
|
||||
match event {
|
||||
AnyStrippedStateEvent::RoomEncryption(encryption) => {
|
||||
self.encryption = Some(encryption.content.clone());
|
||||
true
|
||||
}
|
||||
AnyStrippedStateEvent::RoomName(n) => {
|
||||
self.name = n.content.name().map(|n| n.to_string());
|
||||
true
|
||||
}
|
||||
AnyStrippedStateEvent::RoomCanonicalAlias(a) => {
|
||||
self.canonical_alias = a.content.alias.clone();
|
||||
true
|
||||
}
|
||||
AnyStrippedStateEvent::RoomTopic(t) => {
|
||||
self.topic = Some(t.content.topic.clone());
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
self.base_info.handle_state_event(&event.content())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue