[fractal/fractal-next] session: Load rooms and handle sync response in RoomList and Room
- From: Julian Sparber <jsparber src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [fractal/fractal-next] session: Load rooms and handle sync response in RoomList and Room
- Date: Wed, 26 May 2021 12:37:10 +0000 (UTC)
commit d356745f1d57726ab389fb16781221dc2c08bcaa
Author: Kévin Commaille <zecakeh tedomum fr>
Date: Wed May 26 08:29:04 2021 +0200
session: Load rooms and handle sync response in RoomList and Room
src/session/categories/room_list.rs | 121 +++++++++++++++++++++++++++--------
src/session/mod.rs | 124 +++---------------------------------
src/session/room/room.rs | 73 ++++++++++++++++++++-
3 files changed, 173 insertions(+), 145 deletions(-)
---
diff --git a/src/session/categories/room_list.rs b/src/session/categories/room_list.rs
index 3cc09788..fc9e4394 100644
--- a/src/session/categories/room_list.rs
+++ b/src/session/categories/room_list.rs
@@ -1,6 +1,6 @@
use gtk::{gio, glib, glib::clone, prelude::*, subclass::prelude::*};
use indexmap::map::IndexMap;
-use matrix_sdk::{identifiers::RoomId, Client};
+use matrix_sdk::{deserialized_responses::Rooms as ResponseRooms, identifiers::RoomId, Client};
use crate::session::{room::Room, user::User};
@@ -84,51 +84,116 @@ impl RoomList {
priv_.list.borrow().contains_key(room_id)
}
- pub fn insert(&self, rooms: Vec<(RoomId, Room)>) {
+ pub fn remove(&self, room_id: &RoomId) {
let priv_ = imp::RoomList::from_instance(&self);
- let rooms: Vec<(RoomId, Room)> = {
- rooms
- .into_iter()
- .filter(|(room_id, _)| !priv_.list.borrow().contains_key(room_id))
- .collect()
+ let removed = {
+ let mut list = priv_.list.borrow_mut();
+
+ list.shift_remove_full(room_id)
};
- let added = rooms.len();
+ if let Some((position, _, _)) = removed {
+ self.items_changed(position as u32, 1, 0);
+ }
+ }
- if added > 0 {
- let position = priv_.list.borrow().len();
+ fn items_added(&self, added: usize) {
+ let priv_ = imp::RoomList::from_instance(&self);
+ let list = priv_.list.borrow();
+
+ let position = list.len() - added;
+
+ for (_room_id, room) in list.iter().skip(position) {
+ room.connect_notify_local(
+ Some("category"),
+ clone!(@weak self as obj => move |r, _| {
+ if let Some((position, _, _)) = obj.get_full(&r.matrix_room_id()) {
+ obj.items_changed(position as u32, 1, 1);
+ }
+ }),
+ );
+ }
+
+ self.items_changed(position as u32, 0, added as u32);
+ }
+
+ pub fn load(&self) {
+ let priv_ = imp::RoomList::from_instance(&self);
+
+ let matrix_rooms = priv_.client.get().unwrap().rooms();
+ let added = matrix_rooms.len();
+
+ if added > 0 {
{
let mut list = priv_.list.borrow_mut();
- for (room_id, room) in rooms {
- room.connect_notify_local(
- Some("category"),
- clone!(@weak self as obj => move |r, _| {
- if let Some((position, _, _)) = obj.get_full(&r.matrix_room_id()) {
- obj.items_changed(position as u32, 1, 1);
- }
- }),
- );
- list.insert(room_id, room);
+ for matrix_room in matrix_rooms {
+ let room = Room::new(matrix_room, priv_.user.get().unwrap());
+
+ list.insert(room.matrix_room_id(), room);
}
}
- self.items_changed(position as u32, 0, added as u32);
+ self.items_added(added);
}
}
- pub fn remove(&self, room_id: &RoomId) {
+ pub fn handle_response_rooms(&self, rooms: ResponseRooms) {
let priv_ = imp::RoomList::from_instance(&self);
- let removed = {
- let mut list = priv_.list.borrow_mut();
+ let mut added = 0;
- list.shift_remove_full(room_id)
- };
+ for (room_id, left_room) in rooms.leave {
+ let matrix_room = priv_.client.get().unwrap().get_room(&room_id).unwrap();
- if let Some((position, _, _)) = removed {
- self.items_changed(position as u32, 1, 0);
+ let room = priv_
+ .list
+ .borrow_mut()
+ .entry(room_id)
+ .or_insert_with(|| {
+ added += 1;
+ Room::new(matrix_room.clone(), priv_.user.get().unwrap())
+ })
+ .clone();
+
+ room.handle_left_response(left_room, matrix_room);
+ }
+
+ for (room_id, joined_room) in rooms.join {
+ let matrix_room = priv_.client.get().unwrap().get_room(&room_id).unwrap();
+
+ let room = priv_
+ .list
+ .borrow_mut()
+ .entry(room_id)
+ .or_insert_with(|| {
+ added += 1;
+ Room::new(matrix_room.clone(), priv_.user.get().unwrap())
+ })
+ .clone();
+
+ room.handle_joined_response(joined_room, matrix_room);
+ }
+
+ for (room_id, invited_room) in rooms.invite {
+ let matrix_room = priv_.client.get().unwrap().get_room(&room_id).unwrap();
+
+ let room = priv_
+ .list
+ .borrow_mut()
+ .entry(room_id)
+ .or_insert_with(|| {
+ added += 1;
+ Room::new(matrix_room.clone(), priv_.user.get().unwrap())
+ })
+ .clone();
+
+ room.handle_invited_response(invited_room, matrix_room);
+ }
+
+ if added > 0 {
+ self.items_added(added);
}
}
}
diff --git a/src/session/mod.rs b/src/session/mod.rs
index 4e48e929..af99f7ab 100644
--- a/src/session/mod.rs
+++ b/src/session/mod.rs
@@ -10,7 +10,6 @@ use self::room::Room;
use self::sidebar::Sidebar;
pub use self::user::User;
-use crate::event_from_sync_event;
use crate::secret;
use crate::secret::StoredSession;
use crate::utils::do_async;
@@ -25,12 +24,8 @@ use gtk_macros::send;
use log::error;
use matrix_sdk::api::r0::filter::{FilterDefinition, LazyLoadOptions, RoomEventFilter, RoomFilter};
use matrix_sdk::{
- self, assign,
- deserialized_responses::SyncResponse,
- events::{AnyRoomEvent, AnySyncRoomEvent},
- identifiers::RoomId,
- uuid::Uuid,
- Client, ClientConfig, RequestConfig, SyncSettings,
+ self, assign, deserialized_responses::SyncResponse, uuid::Uuid, Client, ClientConfig,
+ RequestConfig, SyncSettings,
};
use rand::{distributions::Alphanumeric, thread_rng, Rng};
use std::fs;
@@ -329,6 +324,8 @@ impl Session {
priv_.user.set(user).unwrap();
}
+ // FIXME: Leaving this method for now, if it's never used it should be removed at some point.
+ #[allow(dead_code)]
fn user(&self) -> &User {
let priv_ = &imp::Session::from_instance(self);
priv_.user.get().unwrap()
@@ -358,18 +355,8 @@ impl Session {
/// loading much via this function.
pub fn load(&self) {
let priv_ = imp::Session::from_instance(self);
- let rooms = priv_.client.get().unwrap().rooms();
- let mut new_rooms = Vec::with_capacity(rooms.len());
-
- for matrix_room in rooms {
- new_rooms.push((
- matrix_room.room_id().clone(),
- Room::new(matrix_room, self.user()),
- ));
- }
-
- priv_.categories.room_list().insert(new_rooms);
+ priv_.categories.room_list().load();
}
/// Returns and consumes the `error` that was generated when the session failed to login,
@@ -393,103 +380,10 @@ impl Session {
fn handle_sync_response(&self, response: SyncResponse) {
let priv_ = imp::Session::from_instance(self);
- let rooms_map = priv_.categories.room_list();
-
- let rooms_id = response
- .rooms
- .join
- .iter()
- .map(|(room_id, _)| room_id)
- .chain(response.rooms.leave.iter().map(|(room_id, _)| room_id))
- .chain(response.rooms.invite.iter().map(|(room_id, _)| room_id));
- let (old_rooms_id, new_rooms_id): (Vec<RoomId>, Vec<RoomId>) = rooms_id
- .cloned()
- .partition(|room_id| rooms_map.contains_key(room_id));
-
- let mut new_rooms = Vec::new();
-
- for room_id in new_rooms_id {
- if let Some(matrix_room) = priv_.client.get().unwrap().get_room(&room_id) {
- new_rooms.push((room_id, Room::new(matrix_room, self.user())));
- }
- }
-
- for room_id in old_rooms_id {
- let room = rooms_map.get(&room_id).unwrap();
- if let Some(matrix_room) = priv_.client.get().unwrap().get_room(&room_id) {
- room.set_matrix_room(matrix_room);
- }
- }
-
- rooms_map.insert(new_rooms);
-
- for (room_id, matrix_room) in response.rooms.leave {
- if matrix_room.timeline.events.is_empty() {
- continue;
- }
- if let Some(room) = rooms_map.get(&room_id) {
- room.append_events(
- matrix_room
- .timeline
- .events
- .into_iter()
- .filter_map(|event| {
- if let Ok(event) = event.event.deserialize() {
- Some(event)
- } else {
- error!("Couldn't deserialize event: {:?}", event);
- None
- }
- })
- .map(|event| event_from_sync_event!(event, room_id))
- .collect(),
- );
- }
- }
-
- for (room_id, matrix_room) in response.rooms.join {
- if matrix_room.timeline.events.is_empty() {
- continue;
- }
- if let Some(room) = rooms_map.get(&room_id) {
- room.append_events(
- matrix_room
- .timeline
- .events
- .into_iter()
- .filter_map(|event| {
- if let Ok(event) = event.event.deserialize() {
- Some(event)
- } else {
- error!("Couldn't deserialize event: {:?}", event);
- None
- }
- })
- .map(|event| event_from_sync_event!(event, room_id))
- .collect(),
- );
- }
- }
-
- for (room_id, matrix_room) in response.rooms.invite {
- if let Some(room) = rooms_map.get(&room_id) {
- room.handle_invite_events(
- matrix_room
- .invite_state
- .events
- .into_iter()
- .filter_map(|event| {
- if let Ok(event) = event.deserialize() {
- Some(event)
- } else {
- error!("Couldn't deserialize event: {:?}", event);
- None
- }
- })
- .collect(),
- )
- }
- }
+ priv_
+ .categories
+ .room_list()
+ .handle_response_rooms(response.rooms);
}
}
diff --git a/src/session/room/room.rs b/src/session/room/room.rs
index 63e7f045..2a6f52ac 100644
--- a/src/session/room/room.rs
+++ b/src/session/room/room.rs
@@ -2,6 +2,8 @@ use gettextrs::gettext;
use gtk::{gio, glib, glib::clone, prelude::*, subclass::prelude::*};
use log::{debug, error, warn};
use matrix_sdk::{
+ api::r0::sync::sync_events::InvitedRoom,
+ deserialized_responses::{JoinedRoom, LeftRoom},
events::{
room::{
member::{MemberEventContent, MembershipState},
@@ -10,8 +12,8 @@ use matrix_sdk::{
},
},
tag::TagName,
- AnyMessageEvent, AnyRoomEvent, AnyStateEvent, AnyStrippedStateEvent, MessageEvent,
- StateEvent, Unsigned,
+ AnyMessageEvent, AnyRoomEvent, AnyStateEvent, AnyStrippedStateEvent, AnySyncRoomEvent,
+ MessageEvent, StateEvent, Unsigned,
},
identifiers::{EventId, RoomId, UserId},
room::Room as MatrixRoom,
@@ -20,6 +22,7 @@ use matrix_sdk::{
};
use std::cell::RefCell;
+use crate::event_from_sync_event;
use crate::session::{
categories::CategoryType,
room::{HighlightFlags, Timeline},
@@ -586,4 +589,70 @@ impl Room {
Ok(())
}
}
+
+ pub fn handle_left_response(&self, response_room: LeftRoom, matrix_room: MatrixRoom) {
+ self.set_matrix_room(matrix_room);
+
+ let room_id = self.matrix_room_id();
+
+ self.append_events(
+ response_room
+ .timeline
+ .events
+ .into_iter()
+ .filter_map(|event| {
+ if let Ok(event) = event.event.deserialize() {
+ Some(event)
+ } else {
+ error!("Couldn't deserialize event: {:?}", event);
+ None
+ }
+ })
+ .map(|event| event_from_sync_event!(event, room_id))
+ .collect(),
+ );
+ }
+
+ pub fn handle_joined_response(&self, response_room: JoinedRoom, matrix_room: MatrixRoom) {
+ self.set_matrix_room(matrix_room);
+
+ let room_id = self.matrix_room_id();
+
+ self.append_events(
+ response_room
+ .timeline
+ .events
+ .into_iter()
+ .filter_map(|event| {
+ if let Ok(event) = event.event.deserialize() {
+ Some(event)
+ } else {
+ error!("Couldn't deserialize event: {:?}", event);
+ None
+ }
+ })
+ .map(|event| event_from_sync_event!(event, room_id))
+ .collect(),
+ );
+ }
+
+ pub fn handle_invited_response(&self, response_room: InvitedRoom, matrix_room: MatrixRoom) {
+ self.set_matrix_room(matrix_room);
+
+ self.handle_invite_events(
+ response_room
+ .invite_state
+ .events
+ .into_iter()
+ .filter_map(|event| {
+ if let Ok(event) = event.deserialize() {
+ Some(event)
+ } else {
+ error!("Couldn't deserialize event: {:?}", event);
+ None
+ }
+ })
+ .collect(),
+ )
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]