[fractal/fractal-next] session: Track changes of room type
- From: Julian Sparber <jsparber src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [fractal/fractal-next] session: Track changes of room type
- Date: Thu, 20 May 2021 15:14:59 +0000 (UTC)
commit 5322e9bcdfd25cff6009b0120f03e50c532c42e6
Author: Julian Sparber <julian sparber net>
Date: Thu May 20 14:05:48 2021 +0200
session: Track changes of room type
src/session/categories/room_list.rs | 2 +-
src/session/mod.rs | 36 +++++++++----------
src/session/room/room.rs | 70 +++++++++++++++++++++++++------------
3 files changed, 65 insertions(+), 43 deletions(-)
---
diff --git a/src/session/categories/room_list.rs b/src/session/categories/room_list.rs
index 7b5056b5..d2848c11 100644
--- a/src/session/categories/room_list.rs
+++ b/src/session/categories/room_list.rs
@@ -103,7 +103,7 @@ impl RoomList {
room.connect_notify_local(
Some("category"),
clone!(@weak self as obj => move |r, _| {
- if let Some((position, _, _)) = obj.get_full(r.matrix_room().room_id()) {
+ if let Some((position, _, _)) = obj.get_full(&r.matrix_room_id()) {
obj.items_changed(position as u32, 1, 1);
}
}),
diff --git a/src/session/mod.rs b/src/session/mod.rs
index 65aa6586..c6b6147c 100644
--- a/src/session/mod.rs
+++ b/src/session/mod.rs
@@ -390,24 +390,16 @@ impl Session {
let priv_ = imp::Session::from_instance(self);
let rooms_map = priv_.categories.room_list();
- let new_rooms_id: Vec<RoomId> = {
- let new_left_rooms = response.rooms.leave.iter().filter_map(|(room_id, _)| {
- if !rooms_map.contains_key(room_id) {
- Some(room_id)
- } else {
- None
- }
- });
-
- let new_joined_rooms = response.rooms.join.iter().filter_map(|(room_id, _)| {
- if !rooms_map.contains_key(room_id) {
- Some(room_id)
- } else {
- None
- }
- });
- new_joined_rooms.chain(new_left_rooms).cloned().collect()
- };
+ 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();
@@ -417,6 +409,13 @@ impl Session {
}
}
+ 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 {
@@ -467,7 +466,6 @@ impl Session {
);
}
}
-
// TODO: handle StrippedStateEvents for invited rooms
}
}
diff --git a/src/session/room/room.rs b/src/session/room/room.rs
index f1782205..aa65b253 100644
--- a/src/session/room/room.rs
+++ b/src/session/room/room.rs
@@ -1,7 +1,7 @@
use comrak::{markdown_to_html, ComrakOptions};
use gettextrs::gettext;
use gtk::{gio, glib, glib::clone, prelude::*, subclass::prelude::*};
-use log::{error, warn};
+use log::{debug, error, warn};
use matrix_sdk::{
events::{
room::{
@@ -14,11 +14,12 @@ use matrix_sdk::{
tag::TagName,
AnyMessageEvent, AnyRoomEvent, AnyStateEvent, MessageEvent, StateEvent, Unsigned,
},
- identifiers::{EventId, UserId},
+ identifiers::{EventId, RoomId, UserId},
room::Room as MatrixRoom,
uuid::Uuid,
RoomMember,
};
+use std::cell::RefCell;
use std::time::SystemTime;
use crate::session::{
@@ -31,12 +32,12 @@ use crate::utils::do_async;
mod imp {
use super::*;
use once_cell::sync::{Lazy, OnceCell};
- use std::cell::{Cell, RefCell};
+ use std::cell::Cell;
use std::collections::HashMap;
#[derive(Debug, Default)]
pub struct Room {
- pub matrix_room: OnceCell<MatrixRoom>,
+ pub matrix_room: RefCell<Option<MatrixRoom>>,
pub user: OnceCell<User>,
pub name: RefCell<Option<String>>,
pub avatar: RefCell<Option<gio::LoadableIcon>>,
@@ -63,7 +64,7 @@ mod imp {
"Matrix room",
"The underlaying matrix room.",
BoxedMatrixRoom::static_type(),
- glib::ParamFlags::WRITABLE | glib::ParamFlags::CONSTRUCT_ONLY,
+ glib::ParamFlags::WRITABLE | glib::ParamFlags::CONSTRUCT,
),
glib::ParamSpec::new_string(
"display-name",
@@ -152,7 +153,8 @@ mod imp {
}
fn property(&self, obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
- let matrix_room = self.matrix_room.get().unwrap();
+ let matrix_room = self.matrix_room.borrow();
+ let matrix_room = matrix_room.as_ref().unwrap();
match pspec.name() {
"user" => obj.user().to_value(),
"display-name" => obj.display_name().to_value(),
@@ -192,21 +194,46 @@ impl Room {
.expect("Failed to create Room")
}
- pub fn matrix_room(&self) -> &MatrixRoom {
+ pub fn matrix_room_id(&self) -> RoomId {
let priv_ = imp::Room::from_instance(self);
- priv_.matrix_room.get().unwrap()
+ priv_
+ .matrix_room
+ .borrow()
+ .as_ref()
+ .unwrap()
+ .room_id()
+ .clone()
}
- fn set_matrix_room(&self, matrix_room: MatrixRoom) {
+ fn matrix_room(&self) -> MatrixRoom {
let priv_ = imp::Room::from_instance(self);
+ priv_.matrix_room.borrow().as_ref().unwrap().clone()
+ }
- priv_.matrix_room.set(matrix_room).unwrap();
- priv_.timeline.set(Timeline::new(self)).unwrap();
+ /// Set the new sdk room struct represented by this `Room`
+ pub fn set_matrix_room(&self, matrix_room: MatrixRoom) {
+ let priv_ = imp::Room::from_instance(self);
+
+ // Check if the previous type was different
+ if let Some(ref old_matrix_room) = *priv_.matrix_room.borrow() {
+ let changed = match old_matrix_room {
+ MatrixRoom::Joined(_) => !matches!(matrix_room, MatrixRoom::Joined(_)),
+ MatrixRoom::Left(_) => !matches!(matrix_room, MatrixRoom::Left(_)),
+ MatrixRoom::Invited(_) => !matches!(matrix_room, MatrixRoom::Invited(_)),
+ };
+ if changed {
+ debug!("The matrix room struct for `Room` changed");
+ } else {
+ return;
+ }
+ }
+
+ priv_.matrix_room.replace(Some(matrix_room));
+ // We create the timeline once
+ priv_.timeline.get_or_init(|| Timeline::new(self));
- // We only need to load the room members once, because updates we will receive via state events
self.load_members();
self.load_display_name();
- // TODO: change category when room type changes
self.load_category();
}
@@ -232,7 +259,7 @@ impl Room {
}
pub fn load_category(&self) {
- let matrix_room = self.matrix_room().clone();
+ let matrix_room = self.matrix_room();
match matrix_room {
MatrixRoom::Joined(_) => {
@@ -273,7 +300,8 @@ impl Room {
let priv_ = imp::Room::from_instance(&self);
let count = priv_
.matrix_room
- .get()
+ .borrow()
+ .as_ref()
.unwrap()
.unread_notification_counts()
.highlight_count;
@@ -303,8 +331,7 @@ impl Room {
}
fn load_display_name(&self) {
- let priv_ = imp::Room::from_instance(&self);
- let matrix_room = priv_.matrix_room.get().unwrap().clone();
+ let matrix_room = self.matrix_room();
do_async(
glib::PRIORITY_DEFAULT_IDLE,
async move { matrix_room.display_name().await },
@@ -390,9 +417,7 @@ impl Room {
}
fn load_members(&self) {
- let priv_ = imp::Room::from_instance(self);
-
- let matrix_room = priv_.matrix_room.get().unwrap().clone();
+ let matrix_room = self.matrix_room();
do_async(
glib::PRIORITY_LOW,
async move { matrix_room.active_members().await },
@@ -425,8 +450,7 @@ impl Room {
pub fn send_text_message(&self, body: &str, markdown_enabled: bool) {
use std::convert::TryFrom;
- let priv_ = imp::Room::from_instance(self);
- if let MatrixRoom::Joined(matrix_room) = priv_.matrix_room.get().unwrap().clone() {
+ if let MatrixRoom::Joined(matrix_room) = self.matrix_room() {
let is_emote = body.starts_with("/me ");
// Don't use markdown for emotes
@@ -482,7 +506,7 @@ impl Room {
let priv_ = imp::Room::from_instance(self);
let content = event.content();
- if let MatrixRoom::Joined(matrix_room) = priv_.matrix_room.get().unwrap().clone() {
+ if let MatrixRoom::Joined(matrix_room) = self.matrix_room() {
let pending_id = event.event_id().clone();
priv_
.timeline
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]