[fractal] fractal-gtk: Disable text entry if the user doesn't have send permission



commit e1c2153caa5d11ffab0bca792db8588f299fb0ae
Author: Alistair Francis <alistair alistair23 me>
Date:   Sun Jul 7 23:08:45 2019 -0700

    fractal-gtk: Disable text entry if the user doesn't have send permission
    
    Disable the ability to write text in rooms where the user doesn't have
    write permission.
    
    This fixes: https://gitlab.gnome.org/GNOME/fractal/issues/500
    
    Signed-off-by: Alistair Francis <alistair alistair23 me>

 fractal-gtk/src/appop/room.rs            | 47 ++++++++++++++++++++++----------
 fractal-gtk/src/widgets/members_list.rs  |  3 ++
 fractal-gtk/src/widgets/room_settings.rs |  7 ++++-
 fractal-matrix-api/src/model/room.rs     | 12 ++++++++
 4 files changed, 53 insertions(+), 16 deletions(-)
---
diff --git a/fractal-gtk/src/appop/room.rs b/fractal-gtk/src/appop/room.rs
index 8eaa3024..5e3eaa7e 100644
--- a/fractal-gtk/src/appop/room.rs
+++ b/fractal-gtk/src/appop/room.rs
@@ -138,27 +138,44 @@ impl AppOp {
                 self.invitation_roomid = Some(room.id.clone());
                 return;
             }
-        }
 
-        let msg_entry = self.ui.sventry.view.clone();
-        if let Some(buffer) = msg_entry.get_buffer() {
-            let start = buffer.get_start_iter();
-            let end = buffer.get_end_iter();
+            let msg_entry = self.ui.sventry.view.clone();
 
-            if let Some(msg) = buffer.get_text(&start, &end, false) {
-                if let Some(ref active_room) = self.active_room {
-                    if msg.len() > 0 {
-                        if let Some(mark) = buffer.get_insert() {
-                            let iter = buffer.get_iter_at_mark(&mark);
-                            let msg_position = iter.get_offset();
+            let user_power = match room.admins.get(&self.uid.clone().unwrap_or_default()) {
+                Some(p) => *p,
+                None => room
+                    .power_levels
+                    .get("users_default")
+                    .map(|x| *x)
+                    .unwrap_or(-1),
+            };
 
-                            self.unsent_messages
-                                .insert(active_room.clone(), (msg.to_string(), msg_position));
+            if user_power >= 0 {
+                msg_entry.set_editable(true);
+                if let Some(buffer) = msg_entry.get_buffer() {
+                    let start = buffer.get_start_iter();
+                    let end = buffer.get_end_iter();
+
+                    if let Some(msg) = buffer.get_text(&start, &end, false) {
+                        if let Some(ref active_room) = self.active_room {
+                            if msg.len() > 0 {
+                                if let Some(mark) = buffer.get_insert() {
+                                    let iter = buffer.get_iter_at_mark(&mark);
+                                    let msg_position = iter.get_offset();
+
+                                    self.unsent_messages.insert(
+                                        active_room.clone(),
+                                        (msg.to_string(), msg_position),
+                                    );
+                                }
+                            } else {
+                                self.unsent_messages.remove(active_room);
+                            }
                         }
-                    } else {
-                        self.unsent_messages.remove(active_room);
                     }
                 }
+            } else {
+                msg_entry.set_editable(false);
             }
         }
 
diff --git a/fractal-gtk/src/widgets/members_list.rs b/fractal-gtk/src/widgets/members_list.rs
index ad34b703..9b665dda 100644
--- a/fractal-gtk/src/widgets/members_list.rs
+++ b/fractal-gtk/src/widgets/members_list.rs
@@ -19,12 +19,14 @@ pub struct MembersList {
     error: gtk::Label,
     members: Vec<Member>,
     admins: HashMap<String, i32>,
+    power_levels: HashMap<String, i32>,
 }
 
 impl MembersList {
     pub fn new(
         m: Vec<Member>,
         admins: HashMap<String, i32>,
+        power_levels: HashMap<String, i32>,
         entry: gtk::SearchEntry,
     ) -> MembersList {
         MembersList {
@@ -33,6 +35,7 @@ impl MembersList {
             members: m,
             search_entry: entry,
             admins: admins,
+            power_levels: power_levels,
         }
     }
 
diff --git a/fractal-gtk/src/widgets/room_settings.rs b/fractal-gtk/src/widgets/room_settings.rs
index 466140d3..d6474172 100644
--- a/fractal-gtk/src/widgets/room_settings.rs
+++ b/fractal-gtk/src/widgets/room_settings.rs
@@ -630,7 +630,12 @@ impl RoomSettings {
             )
             .as_str(),
         );
-        let list = widgets::MembersList::new(members.clone(), self.room.admins.clone(), entry);
+        let list = widgets::MembersList::new(
+            members.clone(),
+            self.room.admins.clone(),
+            self.room.power_levels.clone(),
+            entry,
+        );
         let w = list.create()?;
         b.add(&w);
         self.members_list = Some(list);
diff --git a/fractal-matrix-api/src/model/room.rs b/fractal-matrix-api/src/model/room.rs
index 1104e03b..a7f9fe1a 100644
--- a/fractal-matrix-api/src/model/room.rs
+++ b/fractal-matrix-api/src/model/room.rs
@@ -98,6 +98,7 @@ pub struct Room {
     /// Hashmap with the room users power levels
     /// the key will be the userid and the value will be the level
     pub admins: HashMap<String, i32>,
+    pub power_levels: HashMap<String, i32>,
 }
 
 impl Room {
@@ -142,6 +143,7 @@ impl Room {
                 prev_batch: timeline.prev_batch.clone(),
                 messages: Message::from_json_events_iter(&k, timeline.events.iter()),
                 admins: get_admins(stevents),
+                power_levels: get_power_levels(stevents),
                 members: stevents
                     .iter()
                     .filter(|x| x["type"] == "m.room.member")
@@ -316,6 +318,16 @@ fn get_admins(stevents: &Vec<JsonValue>) -> HashMap<String, i32> {
         .collect()
 }
 
+fn get_power_levels(stevents: &Vec<JsonValue>) -> HashMap<String, i32> {
+    stevents
+        .iter()
+        .filter(|x| x["type"] == "m.room.power_levels")
+        .filter_map(|ev| ev["content"].as_object())
+        .flatten()
+        .map(|(k, v)| (k.clone(), v.as_i64().map(|v| v as i32).unwrap_or_default()))
+        .collect()
+}
+
 fn calculate_room_name(events: &Vec<JsonValue>, userid: &str) -> Option<String> {
     // looking for "m.room.name" event
     if let Some(name) = events


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]