From 42e726225e9ab0886c5a4d9acb7716bcbb20d4a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa=20Moreno?= Date: Fri, 2 Feb 2018 19:07:58 +0100 Subject: [PATCH] Reload memberlist on every room selection Fix #60 --- fractal-api/src/backend/mod.rs | 4 ++ fractal-api/src/backend/room.rs | 24 ++++----- fractal-api/src/backend/types.rs | 1 + fractal-gtk/src/app.rs | 85 ++++++++++++++++++++++---------- 4 files changed, 74 insertions(+), 40 deletions(-) diff --git a/fractal-api/src/backend/mod.rs b/fractal-api/src/backend/mod.rs index 40454c61..7a7569a1 100644 --- a/fractal-api/src/backend/mod.rs +++ b/fractal-api/src/backend/mod.rs @@ -138,6 +138,10 @@ impl Backend { // Room module + Ok(BKCommand::GetRoomMembers(room)) => { + let r = room::get_room_members(self, room); + bkerror!(r, tx, BKResponse::RoomMembersError); + } Ok(BKCommand::GetRoomMessages(room)) => { let r = room::get_room_messages(self, room); bkerror!(r, tx, BKResponse::RoomMessagesError); diff --git a/fractal-api/src/backend/room.rs b/fractal-api/src/backend/room.rs index 3049c298..54cdcf99 100644 --- a/fractal-api/src/backend/room.rs +++ b/fractal-api/src/backend/room.rs @@ -37,6 +37,7 @@ use self::serde_json::Value as JsonValue; pub fn set_room(bk: &Backend, room: Room) -> Result<(), Error> { get_room_detail(bk, room.id.clone(), String::from("m.room.topic"))?; get_room_avatar(bk, room.id.clone())?; + get_room_members(bk, room.id.clone())?; Ok(()) } @@ -102,29 +103,22 @@ pub fn get_room_avatar(bk: &Backend, roomid: String) -> Result<(), Error> { Ok(()) } -#[allow(dead_code)] pub fn get_room_members(bk: &Backend, roomid: String) -> Result<(), Error> { - let url = bk.url(&format!("rooms/{}/members", roomid), vec![])?; + let url = bk.url(&format!("rooms/{}/joined_members", roomid), vec![])?; let tx = bk.tx.clone(); get!(&url, |r: JsonValue| { - //println!("{:#?}", r); + let joined = r["joined"].as_object().unwrap(); let mut ms: Vec = vec![]; - for member in r["chunk"].as_array().unwrap().iter().rev() { - if member["type"].as_str().unwrap() != "m.room.member" { - continue; - } - - let content = &member["content"]; - if content["membership"].as_str().unwrap() != "join" { - continue; - } + for memberid in joined.keys() { + let alias = &joined[memberid]["display_name"]; + let avatar = &joined[memberid]["avatar_url"]; let m = Member { - alias: Some(String::from(content["displayname"].as_str().unwrap_or(""))), - uid: String::from(member["sender"].as_str().unwrap()), - avatar: Some(String::from(content["avatar_url"].as_str().unwrap_or(""))), + alias: match alias.as_str() { None => None, Some(a) => Some(strn!(a)) }, + avatar: match avatar.as_str() { None => None, Some(a) => Some(strn!(a)) }, + uid: memberid.to_string(), }; ms.push(m); } diff --git a/fractal-api/src/backend/types.rs b/fractal-api/src/backend/types.rs index fbc2b364..2d20e2dd 100644 --- a/fractal-api/src/backend/types.rs +++ b/fractal-api/src/backend/types.rs @@ -24,6 +24,7 @@ pub enum BKCommand { GetAvatar, Sync, SyncForced, + GetRoomMembers(String), GetRoomMessages(String), GetMessageContext(Message), GetRoomAvatar(String), diff --git a/fractal-gtk/src/app.rs b/fractal-gtk/src/app.rs index 348bf6ee..cbad6bb8 100644 --- a/fractal-gtk/src/app.rs +++ b/fractal-gtk/src/app.rs @@ -848,19 +848,7 @@ impl AppOp { // getting room details self.backend.send(BKCommand::SetRoom(room.clone())).unwrap(); - - let members = self.gtk_builder - .get_object::("members_store") - .expect("Can't find members_store in ui file."); - members.clear(); - - self.clean_member_list(); - - for (_, m) in room.members.iter() { - self.add_room_member(m.clone()); - } - - self.show_all_members(); + self.reload_members(&room); self.set_room_topic_label(room.topic.clone()); @@ -1637,8 +1625,29 @@ impl AppOp { // NOTE: maybe we should show this events in the message list to notify enters and leaves // to the user + let sender = ev.sender.clone(); + match ev.content["membership"].as_str() { + Some("leave") => { + if let Some(r) = self.rooms.get_mut(&self.active_room.clone().unwrap_or_default()) { + r.members.remove(&sender); + } + } + Some("join") => { + let m = Member { + avatar: Some(strn!(ev.content["avatar_url"].as_str().unwrap_or(""))), + alias: Some(strn!(ev.content["displayname"].as_str().unwrap_or(""))), + uid: sender.clone(), + }; + if let Some(r) = self.rooms.get_mut(&self.active_room.clone().unwrap_or_default()) { + r.members.insert(m.uid.clone(), m.clone()); + } + } + // ignoring other memberships + _ => {} + } + if ev.room != self.active_room.clone().unwrap_or_default() { - // if it's the current room, this event is not important for me + // if it isn't the current room, this event is not important for me return; } @@ -1646,12 +1655,8 @@ impl AppOp { .get_object::("members_store") .expect("Can't find members_store in ui file."); - let sender = ev.sender.clone(); match ev.content["membership"].as_str() { Some("leave") => { - if let Some(r) = self.rooms.get_mut(&self.active_room.clone().unwrap_or_default()) { - r.members.remove(&sender); - } if let Some(iter) = store.get_iter_first() { loop { let v1 = store.get_value(&iter, 1); @@ -1672,16 +1677,11 @@ impl AppOp { alias: Some(strn!(ev.content["displayname"].as_str().unwrap_or(""))), uid: sender.clone(), }; - if let Some(r) = self.rooms.get_mut(&self.active_room.clone().unwrap_or_default()) { - r.members.insert(m.uid.clone(), m.clone()); - } self.add_room_member(m); self.show_all_members(); } - Some(_) => { - // ignoring other memberships - } - None => {} + // ignoring other memberships + _ => {} } } @@ -1934,6 +1934,38 @@ impl AppOp { pub fn filter_rooms(&self, term: Option) { self.roomlist.filter_rooms(term); } + + pub fn set_room_members(&mut self, members: Vec) { + if let Some(aroom) = self.active_room.clone() { + let mut room: Option = None; + if let Some(r) = self.rooms.get_mut(&aroom) { + r.members = HashMap::new(); + for m in members { + r.members.insert(m.uid.clone(), m); + } + room = Some(r.clone()); + } + + if let Some(r) = room { + self.reload_members(&r); + } + } + } + + pub fn reload_members(&mut self, room: &Room) { + let members = self.gtk_builder + .get_object::("members_store") + .expect("Can't find members_store in ui file."); + members.clear(); + + self.clean_member_list(); + + for (_, m) in room.members.iter() { + self.add_room_member(m.clone()); + } + + self.show_all_members(); + } } /// State for the main thread. @@ -2574,6 +2606,9 @@ fn backend_loop(rx: Receiver) { let a = Some(avatar); APPOP!(set_room_avatar, (room, a)); } + Ok(BKResponse::RoomMembers(members)) => { + APPOP!(set_room_members, (members)); + } Ok(BKResponse::RoomMessages(msgs)) => { let init = false; APPOP!(show_room_messages, (msgs, init));