[fractal] backend: add a RoomMembership to Room type
- From: Julian Sparber <jsparber src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [fractal] backend: add a RoomMembership to Room type
- Date: Tue, 22 Jan 2019 16:45:06 +0000 (UTC)
commit 6f643c12c7fe28af3d4c053c7df9086c53475f89
Author: Julian Sparber <julian sparber net>
Date: Thu Jan 3 01:48:35 2019 +0100
backend: add a RoomMembership to Room type
This replaces some boolean properties of the Room Model with a single
property called membership. This makes the room membership (joined, left,
invited) and tag (favourties, low priority, etc) mutch more
understandable and gives the Model a better structure.
fractal-gtk/src/appop/room.rs | 18 ++++++---
fractal-gtk/src/appop/start_chat.rs | 5 ++-
fractal-gtk/src/widgets/roomlist.rs | 14 ++++---
fractal-gtk/src/widgets/roomrow.rs | 14 +++----
fractal-matrix-api/src/backend/directory.rs | 38 ++++++++++--------
fractal-matrix-api/src/backend/room.rs | 9 +++--
fractal-matrix-api/src/model/room.rs | 62 ++++++++++++++++++++++++-----
fractal-matrix-api/src/types.rs | 2 +
fractal-matrix-api/src/util.rs | 48 +++++++++++-----------
9 files changed, 134 insertions(+), 76 deletions(-)
---
diff --git a/fractal-gtk/src/appop/room.rs b/fractal-gtk/src/appop/room.rs
index d57fde7d..96c0e985 100644
--- a/fractal-gtk/src/appop/room.rs
+++ b/fractal-gtk/src/appop/room.rs
@@ -14,7 +14,7 @@ use crate::actions::AppState;
use crate::cache;
use crate::widgets;
-use crate::types::Room;
+use crate::types::{Room, RoomMembership, RoomTag};
use crate::util::markup_text;
@@ -42,7 +42,7 @@ impl AppOp {
}
let mut roomlist = vec![];
while let Some(room) = rooms.pop() {
- if room.left {
+ if room.membership.is_left() {
// removing left rooms
if self.active_room.as_ref().map_or(false, |x| x == &room.id) {
self.really_leave_active_room();
@@ -106,8 +106,8 @@ impl AppOp {
pub fn set_active_room_by_id(&mut self, id: String) {
if let Some(room) = self.rooms.get(&id) {
- if room.inv {
- self.show_inv_dialog(room.inv_sender.as_ref(), room.name.as_ref());
+ if let RoomMembership::Invited(ref sender) = room.membership {
+ self.show_inv_dialog(Some(sender), room.name.as_ref());
self.invitation_roomid = Some(room.id.clone());
return;
}
@@ -240,7 +240,8 @@ impl AppOp {
.send(BKCommand::NewRoom(n.clone(), p, internal_id.clone()))
.unwrap();
- let fakeroom = Room::new(internal_id.clone(), Some(n));
+ let mut fakeroom = Room::new(internal_id.clone(), RoomMembership::Joined(RoomTag::None));
+ fakeroom.name = Some(n);
self.new_room(fakeroom, None);
self.set_active_room_by_id(internal_id);
self.room_panel(RoomPanel::Room);
@@ -423,7 +424,12 @@ impl AppOp {
pub fn added_to_fav(&mut self, roomid: String, tofav: bool) {
if let Some(ref mut r) = self.rooms.get_mut(&roomid) {
- r.fav = tofav;
+ let tag = if tofav {
+ RoomTag::Favourite
+ } else {
+ RoomTag::None
+ };
+ r.membership = RoomMembership::Joined(tag);
}
}
diff --git a/fractal-gtk/src/appop/start_chat.rs b/fractal-gtk/src/appop/start_chat.rs
index 465f6c59..0c0855bf 100644
--- a/fractal-gtk/src/appop/start_chat.rs
+++ b/fractal-gtk/src/appop/start_chat.rs
@@ -6,7 +6,7 @@ use crate::appop::RoomPanel;
use crate::appop::SearchType;
use crate::backend::BKCommand;
-use crate::types::Room;
+use crate::types::{Room, RoomMembership, RoomTag};
use rand::distributions::Alphanumeric;
use rand::{thread_rng, Rng};
@@ -25,7 +25,8 @@ impl AppOp {
.unwrap();
self.close_direct_chat_dialog();
- let mut fakeroom = Room::new(internal_id.clone(), user.0.alias.clone());
+ let mut fakeroom = Room::new(internal_id.clone(), RoomMembership::Joined(RoomTag::None));
+ fakeroom.name = user.0.alias;
fakeroom.direct = true;
self.new_room(fakeroom, None);
diff --git a/fractal-gtk/src/widgets/roomlist.rs b/fractal-gtk/src/widgets/roomlist.rs
index 990217e2..0cb9a2f9 100644
--- a/fractal-gtk/src/widgets/roomlist.rs
+++ b/fractal-gtk/src/widgets/roomlist.rs
@@ -12,7 +12,7 @@ use std::collections::HashMap;
use url::Url;
use crate::globals;
-use crate::types::Room;
+use crate::types::{Room, RoomTag};
use crate::widgets::roomrow::RoomRow;
use std::sync::{Arc, Mutex, MutexGuard};
@@ -461,21 +461,21 @@ impl RoomList {
self.inv.get().add_rooms(
array
.iter()
- .filter(|r| r.inv)
+ .filter(|r| r.membership.is_invited())
.cloned()
.collect::<Vec<Room>>(),
);
self.fav.get().add_rooms(
array
.iter()
- .filter(|r| r.fav)
+ .filter(|r| r.membership.match_joined_tag(RoomTag::Favourite))
.cloned()
.collect::<Vec<Room>>(),
);
self.rooms.get().add_rooms(
array
.iter()
- .filter(|r| !r.fav && !r.inv)
+ .filter(|r| !r.membership.match_joined_tag(RoomTag::Favourite))
.cloned()
.collect::<Vec<Room>>(),
);
@@ -527,11 +527,13 @@ impl RoomList {
}
pub fn add_room(&mut self, r: Room) {
- if r.inv {
+ if r.membership.is_invited() {
self.inv.get().add_room(r);
- } else if r.fav {
+ } else if r.membership.match_joined_tag(RoomTag::Favourite) {
+ println!("We have fav rooms");
self.fav.get().add_room(r);
} else {
+ println!("We have non fav rooms");
self.rooms.get().add_room(r);
}
self.show_and_hide();
diff --git a/fractal-gtk/src/widgets/roomrow.rs b/fractal-gtk/src/widgets/roomrow.rs
index 008b12db..4cb65ae7 100644
--- a/fractal-gtk/src/widgets/roomrow.rs
+++ b/fractal-gtk/src/widgets/roomrow.rs
@@ -43,7 +43,7 @@ impl RoomRow {
let n = room.notifications;
let h = room.highlight;
- let ntext = if room.inv {
+ let ntext = if room.membership.is_invited() {
String::from("•")
} else {
format!("{}", n)
@@ -52,14 +52,14 @@ impl RoomRow {
if let Some(style) = notifications.get_style_context() {
style.add_class("notify-badge");
- if h > 0 || room.inv {
+ if h > 0 || room.membership.is_invited() {
style.add_class("notify-highlight");
} else {
style.remove_class("notify-highlight");
}
}
- if n > 0 || room.inv {
+ if n > 0 || room.membership.is_invited() {
notifications.show();
} else {
notifications.hide();
@@ -85,14 +85,14 @@ impl RoomRow {
self.room.notifications = n;
self.room.highlight = h;
self.notifications.set_text(&format!("{}", n));
- if n > 0 || self.room.inv {
+ if n > 0 || self.room.membership.is_invited() {
self.notifications.show();
} else {
self.notifications.hide();
}
if let Some(style) = self.notifications.get_style_context() {
- if h > 0 || self.room.inv {
+ if h > 0 || self.room.membership.is_invited() {
style.add_class("notify-highlight");
} else {
style.remove_class("notify-highlight");
@@ -112,7 +112,7 @@ impl RoomRow {
pub fn render_notifies(&self) {
let n = self.room.notifications;
- if n > 0 || self.room.inv {
+ if n > 0 || self.room.membership.is_invited() {
self.notifications.show();
} else {
self.notifications.hide();
@@ -169,7 +169,7 @@ impl RoomRow {
}
pub fn connect_dnd(&self) {
- if self.room.inv {
+ if self.room.membership.is_invited() {
return;
}
diff --git a/fractal-matrix-api/src/backend/directory.rs b/fractal-matrix-api/src/backend/directory.rs
index 30bf4131..8c71c0ea 100644
--- a/fractal-matrix-api/src/backend/directory.rs
+++ b/fractal-matrix-api/src/backend/directory.rs
@@ -15,7 +15,7 @@ use crate::util::json_q;
use crate::util::media;
use crate::types::Protocol;
-use crate::types::Room;
+use crate::types::{Room, RoomMembership};
pub fn protocols(bk: &Backend) {
let baseu = bk.get_base_url();
@@ -110,24 +110,28 @@ pub fn room_search(
let mut rooms: Vec<Room> = vec![];
for room in r["chunk"].as_array().unwrap() {
- let alias = String::from(room["canonical_alias"].as_str().unwrap_or_default());
- let id = String::from(room["room_id"].as_str().unwrap_or_default());
- let name = String::from(room["name"].as_str().unwrap_or_default());
- let mut r = Room::new(id.clone(), Some(name));
- r.alias = Some(alias);
- r.avatar = Some(String::from(
- room["avatar_url"].as_str().unwrap_or_default(),
- ));
- r.topic = Some(String::from(room["topic"].as_str().unwrap_or_default()));
- r.n_members = room["num_joined_members"].as_i64().unwrap_or_default() as i32;
- r.world_readable = room["world_readable"].as_bool().unwrap_or_default();
- r.guest_can_join = room["guest_can_join"].as_bool().unwrap_or_default();
- /* download the avatar */
- if let Some(avatar) = r.avatar.clone() {
- if let Ok(dest) = cache_path(&id) {
- media(&base.clone(), &avatar, Some(&dest)).unwrap_or_default();
+ // Panic when we have rooms without an id
+ let id = room["room_id"]
+ .as_str()
+ .expect("Couldn't handle room: no valid id");
+ let alias = room["canonical_alias"].as_str();
+ let name = room["name"].as_str();
+ let avatar = room["avatar_url"].as_str();
+ /* download the avatar for the room */
+ if let Some(avatar) = avatar {
+ if let Ok(dest) = cache_path(id) {
+ let _ = media(&base.clone(), avatar, Some(&dest));
}
}
+
+ let mut r = Room::new(id.to_string(), RoomMembership::None);
+ r.name = name.map(String::from);
+ r.alias = alias.map(String::from);
+ r.avatar = avatar.map(String::from);
+ r.topic = room["topic"].as_str().map(String::from);
+ r.n_members = room["num_joined_members"].as_i64().unwrap_or(0) as i32;
+ r.world_readable = room["world_readable"].as_bool().unwrap_or(false);
+ r.guest_can_join = room["guest_can_join"].as_bool().unwrap_or(false);
rooms.push(r);
}
diff --git a/fractal-matrix-api/src/backend/room.rs b/fractal-matrix-api/src/backend/room.rs
index e83ea8b6..27b737cf 100644
--- a/fractal-matrix-api/src/backend/room.rs
+++ b/fractal-matrix-api/src/backend/room.rs
@@ -24,7 +24,7 @@ use crate::backend::types::RoomType;
use crate::types::Member;
use crate::types::Message;
-use crate::types::Room;
+use crate::types::{Room, RoomMembership, RoomTag};
use serde_json::Value as JsonValue;
@@ -534,8 +534,8 @@ pub fn new_room(
&attrs,
move |r: JsonValue| {
let id = String::from(r["room_id"].as_str().unwrap_or_default());
- let name = n;
- let r = Room::new(id, Some(name));
+ let mut r = Room::new(id, RoomMembership::Joined(RoomTag::None));
+ r.name = Some(n);
tx.send(BKResponse::NewRoom(r, internal_id)).unwrap();
},
|err| {
@@ -566,7 +566,8 @@ pub fn direct_chat(bk: &Backend, user: &Member, internal_id: String) -> Result<(
&attrs,
move |r: JsonValue| {
let id = String::from(r["room_id"].as_str().unwrap_or_default());
- let mut r = Room::new(id.clone(), m.alias.clone());
+ let mut r = Room::new(id.clone(), RoomMembership::Joined(RoomTag::None));
+ r.name = m.alias.clone();
r.direct = true;
tx.send(BKResponse::NewRoom(r, internal_id)).unwrap();
diff --git a/fractal-matrix-api/src/model/room.rs b/fractal-matrix-api/src/model/room.rs
index 83aecd0b..19021e79 100644
--- a/fractal-matrix-api/src/model/room.rs
+++ b/fractal-matrix-api/src/model/room.rs
@@ -6,6 +6,54 @@ use crate::model::message::Message;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub enum RoomMembership {
+ // If the user hasn't yet joined a room, e.g. in the room directory
+ None,
+ Joined(RoomTag),
+ // An invite is send by some other user
+ Invited(Member),
+ Left,
+}
+
+impl RoomMembership {
+ pub fn is_joined(&self) -> bool {
+ if let RoomMembership::Joined(_) = self {
+ true
+ } else {
+ false
+ }
+ }
+
+ pub fn is_invited(&self) -> bool {
+ if let RoomMembership::Invited(_) = self {
+ true
+ } else {
+ false
+ }
+ }
+
+ pub fn is_left(&self) -> bool {
+ self == &RoomMembership::Left
+ }
+
+ pub fn match_joined_tag(&self, tag: RoomTag) -> bool {
+ if let RoomMembership::Joined(this_tag) = self {
+ this_tag == &tag
+ } else {
+ false
+ }
+ }
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub enum RoomTag {
+ None,
+ Favourite,
+ LowPriority,
+ Custom(String),
+}
+
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Room {
pub id: String,
@@ -20,12 +68,9 @@ pub struct Room {
pub notifications: i32,
pub highlight: i32,
pub messages: Vec<Message>,
- pub fav: bool,
- pub left: bool,
- pub inv: bool,
+ pub membership: RoomMembership,
pub direct: bool,
pub prev_batch: Option<String>,
- pub inv_sender: Option<Member>,
/// Hashmap with the room users power levels
/// the key will be the userid and the value will be the level
@@ -33,10 +78,10 @@ pub struct Room {
}
impl Room {
- pub fn new(id: String, name: Option<String>) -> Room {
+ pub fn new(id: String, membership: RoomMembership) -> Room {
Room {
id,
- name,
+ name: None,
avatar: None,
topic: None,
alias: None,
@@ -47,11 +92,8 @@ impl Room {
highlight: 0,
messages: vec![],
members: HashMap::new(),
- fav: false,
- left: false,
- inv: false,
+ membership,
direct: false,
- inv_sender: None,
power_levels: HashMap::new(),
prev_batch: None,
}
diff --git a/fractal-matrix-api/src/types.rs b/fractal-matrix-api/src/types.rs
index 854a413f..be276b39 100644
--- a/fractal-matrix-api/src/types.rs
+++ b/fractal-matrix-api/src/types.rs
@@ -5,6 +5,8 @@ pub use crate::model::message::Message;
pub use crate::model::protocol::Protocol;
pub use crate::model::room::Room;
pub use crate::model::room::RoomList;
+pub use crate::model::room::RoomMembership;
+pub use crate::model::room::RoomTag;
pub use crate::model::stickers::Sticker;
pub use crate::model::stickers::StickerGroup;
pub use crate::model::userinfo::UserInfo;
diff --git a/fractal-matrix-api/src/util.rs b/fractal-matrix-api/src/util.rs
index c2a0fbf1..9e457161 100644
--- a/fractal-matrix-api/src/util.rs
+++ b/fractal-matrix-api/src/util.rs
@@ -24,7 +24,7 @@ use crate::error::Error;
use crate::types::Event;
use crate::types::Member;
use crate::types::Message;
-use crate::types::Room;
+use crate::types::{Room, RoomMembership, RoomTag};
use reqwest::header::CONTENT_TYPE;
@@ -196,7 +196,17 @@ pub fn get_rooms_from_json(r: &JsonValue, userid: &str, baseu: &Url) -> Result<V
let ephemeral = &room["ephemeral"];
let dataevs = &room["account_data"]["events"];
let name = calculate_room_name(stevents, userid)?;
- let mut r = Room::new(k.clone(), name);
+ let mut room_tag = RoomTag::None;
+ if let Some(ev) = dataevs.as_array() {
+ for tag in ev.iter().filter(|x| x["type"] == "m.tag") {
+ if tag["content"]["tags"]["m.favourite"].as_object().is_some() {
+ room_tag = RoomTag::Favourite;
+ }
+ }
+ }
+
+ let mut r = Room::new(k.clone(), RoomMembership::Joined(room_tag));
+ r.name = name;
r.avatar = Some(evc(stevents, "m.room.avatar", "url"));
r.alias = Some(evc(stevents, "m.room.canonical_alias", "alias"));
@@ -211,14 +221,6 @@ pub fn get_rooms_from_json(r: &JsonValue, userid: &str, baseu: &Url) -> Result<V
r.prev_batch = timeline["prev_batch"].as_str().map(String::from);
- if let Some(ev) = dataevs.as_array() {
- for tag in ev.iter().filter(|x| x["type"] == "m.tag") {
- if tag["content"]["tags"]["m.favourite"].as_object().is_some() {
- r.fav = true;
- }
- }
- }
-
if let Some(evs) = timeline["events"].as_array() {
let ms = Message::from_json_events_iter(&k, evs.iter());
r.messages.extend(ms);
@@ -261,8 +263,7 @@ pub fn get_rooms_from_json(r: &JsonValue, userid: &str, baseu: &Url) -> Result<V
// left rooms
for k in leave.keys() {
- let mut r = Room::new(k.clone(), None);
- r.left = true;
+ let r = Room::new(k.clone(), RoomMembership::Left);
rooms.push(r);
}
@@ -271,14 +272,6 @@ pub fn get_rooms_from_json(r: &JsonValue, userid: &str, baseu: &Url) -> Result<V
let room = invite.get(k).ok_or(Error::BackendError)?;
let stevents = &room["invite_state"]["events"];
let name = calculate_room_name(stevents, userid)?;
- let mut r = Room::new(k.clone(), name);
- r.inv = true;
-
- r.avatar = Some(evc(stevents, "m.room.avatar", "url"));
- r.alias = Some(evc(stevents, "m.room.canonical_alias", "alias"));
- r.topic = Some(evc(stevents, "m.room.topic", "topic"));
- r.direct = direct.contains(k);
-
if let Some(arr) = stevents.as_array() {
if let Some(ev) = arr
.iter()
@@ -287,16 +280,23 @@ pub fn get_rooms_from_json(r: &JsonValue, userid: &str, baseu: &Url) -> Result<V
if let Ok((alias, avatar)) =
get_user_avatar(baseu, ev["sender"].as_str().unwrap_or_default())
{
- r.inv_sender = Some(Member {
+ let inv_sender = Member {
alias: Some(alias),
avatar: Some(avatar),
uid: String::from(userid),
- });
+ };
+ let mut r = Room::new(k.clone(), RoomMembership::Invited(inv_sender));
+ r.name = name;
+
+ r.avatar = Some(evc(stevents, "m.room.avatar", "url"));
+ r.alias = Some(evc(stevents, "m.room.canonical_alias", "alias"));
+ r.topic = Some(evc(stevents, "m.room.topic", "topic"));
+ r.direct = direct.contains(k);
+
+ rooms.push(r);
}
}
}
-
- rooms.push(r);
}
Ok(rooms)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]