[fractal/fractal-next] content: Add property room



commit 8923b82b47365ad76ef8954f37229046606d9c70
Author: Julian Sparber <julian sparber net>
Date:   Mon May 3 12:37:04 2021 +0200

    content: Add property room
    
    This adds a new property to `Content` to keep track of the currently
    shown room.

 src/session/content/content.rs | 67 ++++++++++++++++++++++++++----------------
 src/session/mod.rs             |  7 ++---
 2 files changed, 43 insertions(+), 31 deletions(-)
---
diff --git a/src/session/content/content.rs b/src/session/content/content.rs
index 66ad426f..cc1f6c7e 100644
--- a/src/session/content/content.rs
+++ b/src/session/content/content.rs
@@ -1,20 +1,18 @@
 use adw::subclass::prelude::*;
 use gtk::{glib, glib::clone, prelude::*, subclass::prelude::*, CompositeTemplate};
 
-use crate::session::{
-    content::ItemRow,
-    room::{Room, Timeline},
-};
+use crate::session::{content::ItemRow, room::Room};
 
 mod imp {
     use super::*;
     use glib::subclass::InitializingObject;
-    use std::cell::Cell;
+    use std::cell::{Cell, RefCell};
 
     #[derive(Debug, Default, CompositeTemplate)]
     #[template(resource = "/org/gnome/FractalNext/content.ui")]
     pub struct Content {
         pub compact: Cell<bool>,
+        pub room: RefCell<Option<Room>>,
         #[template_child]
         pub headerbar: TemplateChild<adw::HeaderBar>,
         #[template_child]
@@ -44,13 +42,22 @@ mod imp {
         fn properties() -> &'static [glib::ParamSpec] {
             use once_cell::sync::Lazy;
             static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
-                vec![glib::ParamSpec::new_boolean(
-                    "compact",
-                    "Compact",
-                    "Wheter a compact view is used or not",
-                    false,
-                    glib::ParamFlags::READWRITE,
-                )]
+                vec![
+                    glib::ParamSpec::new_boolean(
+                        "compact",
+                        "Compact",
+                        "Wheter a compact view is used or not",
+                        false,
+                        glib::ParamFlags::READWRITE,
+                    ),
+                    glib::ParamSpec::new_object(
+                        "room",
+                        "Room",
+                        "The room currently shown",
+                        Room::static_type(),
+                        glib::ParamFlags::READWRITE | glib::ParamFlags::EXPLICIT_NOTIFY,
+                    ),
+                ]
             });
 
             PROPERTIES.as_ref()
@@ -58,7 +65,7 @@ mod imp {
 
         fn set_property(
             &self,
-            _obj: &Self::Type,
+            obj: &Self::Type,
             _id: usize,
             value: &glib::Value,
             pspec: &glib::ParamSpec,
@@ -68,13 +75,18 @@ mod imp {
                     let compact = value.get().unwrap();
                     self.compact.set(compact);
                 }
+                "room" => {
+                    let room = value.get().unwrap();
+                    obj.set_room(room);
+                }
                 _ => unimplemented!(),
             }
         }
 
-        fn property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
+        fn property(&self, obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
             match pspec.name() {
                 "compact" => self.compact.get().to_value(),
+                "room" => obj.room().to_value(),
                 _ => unimplemented!(),
             }
         }
@@ -111,22 +123,25 @@ impl Content {
         glib::Object::new(&[]).expect("Failed to create Content")
     }
 
-    pub fn set_room(&self, room: &Room) {
+    pub fn set_room(&self, room: Option<Room>) {
         let priv_ = imp::Content::from_instance(self);
+
+        if self.room() == room {
+            return;
+        }
+
         // TODO: use gtk::MultiSelection to allow selection
-        priv_
-            .listview
-            .set_model(Some(&gtk::NoSelection::new(Some(room.timeline()))));
+        let model = room
+            .as_ref()
+            .and_then(|room| Some(gtk::NoSelection::new(Some(room.timeline()))));
+
+        priv_.listview.set_model(model.as_ref());
+        priv_.room.replace(room);
+        self.notify("room");
     }
 
-    fn room(&self) -> Option<Room> {
+    pub fn room(&self) -> Option<Room> {
         let priv_ = imp::Content::from_instance(self);
-        priv_
-            .listview
-            .model()
-            .and_then(|model| model.downcast::<gtk::NoSelection>().ok())
-            .and_then(|model| model.model())
-            .and_then(|model| model.downcast::<Timeline>().ok())
-            .map(|timeline| timeline.room().to_owned())
+        priv_.room.borrow().clone()
     }
 }
diff --git a/src/session/mod.rs b/src/session/mod.rs
index a69afa02..f20959f0 100644
--- a/src/session/mod.rs
+++ b/src/session/mod.rs
@@ -331,11 +331,8 @@ impl Session {
 
     fn handle_show_room_action(&self, room_id: RoomId) {
         let priv_ = imp::Session::from_instance(self);
-        if let Some(room) = priv_.rooms.borrow().get(&room_id) {
-            priv_.content.set_room(room);
-        } else {
-            warn!("No room with {} was found", room_id);
-        }
+        let room = priv_.rooms.borrow().get(&room_id).cloned();
+        priv_.content.set_room(room);
     }
 
     fn handle_sync_response(&self, response: SyncResponse) {


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