[fractal/fractal-next] avatar: add property display-name



commit 872b3abaef61799f290b0a3b2520602381632a4a
Author: Julian Sparber <julian sparber net>
Date:   Mon Jun 7 22:13:24 2021 +0200

    avatar: add property display-name
    
    This makes it simpler to connect the Avatar to the ComponentAvatar

 data/resources/ui/components-avatar.ui | 18 ++----------------
 src/components/avatar.rs               | 34 +++++++---------------------------
 src/components/pill.rs                 |  8 ++++++--
 src/session/avatar.rs                  | 28 ++++++++++++++++++++++++++++
 src/session/content/message_row.rs     |  2 +-
 src/session/room/room.rs               |  5 +++++
 src/session/sidebar/room_row.rs        |  4 +++-
 src/session/user.rs                    |  5 +++++
 8 files changed, 57 insertions(+), 47 deletions(-)
---
diff --git a/data/resources/ui/components-avatar.ui b/data/resources/ui/components-avatar.ui
index a692dd5a..3c4489e2 100644
--- a/data/resources/ui/components-avatar.ui
+++ b/data/resources/ui/components-avatar.ui
@@ -4,28 +4,14 @@
     <property name="child">
       <object class="AdwAvatar" id="avatar">
         <property name="show-initials">True</property>
-        <binding name="text">
-          <lookup name="display-name" type="Room">
-            <lookup name="item">ComponentsAvatar</lookup>
-          </lookup>
-        </binding>
-        <binding name="text">
-          <lookup name="display-name" type="User">
-            <lookup name="item">ComponentsAvatar</lookup>
-          </lookup>
-        </binding>
         <binding name="custom-image">
           <lookup name="image" type="Avatar">
-            <lookup name="avatar" type="Room">
               <lookup name="item">ComponentsAvatar</lookup>
-            </lookup>
           </lookup>
         </binding>
-        <binding name="custom-image">
-          <lookup name="image" type="Avatar">
-            <lookup name="avatar" type="User">
+        <binding name="text">
+          <lookup name="display-name" type="Avatar">
               <lookup name="item">ComponentsAvatar</lookup>
-            </lookup>
           </lookup>
         </binding>
       </object>
diff --git a/src/components/avatar.rs b/src/components/avatar.rs
index 8a4f78af..fe804079 100644
--- a/src/components/avatar.rs
+++ b/src/components/avatar.rs
@@ -1,7 +1,7 @@
 use adw::subclass::prelude::*;
 use gtk::{glib, glib::clone, prelude::*, subclass::prelude::*, CompositeTemplate};
 
-use crate::session::{Room, User};
+use crate::session::Avatar as AvatarItem;
 
 mod imp {
     use super::*;
@@ -12,7 +12,7 @@ mod imp {
     #[template(resource = "/org/gnome/FractalNext/components-avatar.ui")]
     pub struct Avatar {
         /// A `Room` or `User`
-        pub item: RefCell<Option<glib::Object>>,
+        pub item: RefCell<Option<AvatarItem>>,
         #[template_child]
         pub avatar: TemplateChild<adw::Avatar>,
     }
@@ -40,8 +40,8 @@ mod imp {
                     glib::ParamSpec::new_object(
                         "item",
                         "Item",
-                        "The Room or User of this Avatar",
-                        glib::Object::static_type(),
+                        "The Avatar item displayed by this widget",
+                        AvatarItem::static_type(),
                         glib::ParamFlags::READWRITE | glib::ParamFlags::EXPLICIT_NOTIFY,
                     ),
                     glib::ParamSpec::new_int(
@@ -105,23 +105,7 @@ impl Avatar {
         glib::Object::new(&[]).expect("Failed to create Avatar")
     }
 
-    pub fn set_room(&self, room: Option<Room>) {
-        self.set_item(room.map(glib::object::Cast::upcast));
-    }
-
-    pub fn room(&self) -> Option<Room> {
-        self.item().and_then(|item| item.downcast().ok())
-    }
-
-    pub fn set_user(&self, user: Option<User>) {
-        self.set_item(user.map(glib::object::Cast::upcast));
-    }
-
-    pub fn user(&self) -> Option<User> {
-        self.item().and_then(|item| item.downcast().ok())
-    }
-
-    fn set_item(&self, item: Option<glib::Object>) {
+    pub fn set_item(&self, item: Option<AvatarItem>) {
         let priv_ = imp::Avatar::from_instance(self);
 
         if *priv_.item.borrow() == item {
@@ -137,7 +121,7 @@ impl Avatar {
         self.notify("item");
     }
 
-    fn item(&self) -> Option<glib::Object> {
+    pub fn item(&self) -> Option<AvatarItem> {
         let priv_ = imp::Avatar::from_instance(self);
         priv_.item.borrow().clone()
     }
@@ -145,11 +129,7 @@ impl Avatar {
     fn request_custom_avatar(&self) {
         let priv_ = imp::Avatar::from_instance(self);
         if let Some(item) = &*priv_.item.borrow() {
-            if let Some(room) = item.downcast_ref::<Room>() {
-                room.avatar().set_needed(true);
-            } else if let Some(user) = item.downcast_ref::<User>() {
-                user.avatar().set_needed(true);
-            }
+            item.set_needed(true);
         }
     }
 }
diff --git a/src/components/pill.rs b/src/components/pill.rs
index be2333f9..3bc98bce 100644
--- a/src/components/pill.rs
+++ b/src/components/pill.rs
@@ -125,7 +125,9 @@ impl Pill {
             priv_.bindings.borrow_mut().push(display_name_binding);
         }
 
-        priv_.avatar.set_user(user.clone());
+        priv_
+            .avatar
+            .set_item(user.clone().map(|user| user.avatar().clone()));
         priv_.user.replace(user);
 
         self.notify("user");
@@ -157,7 +159,9 @@ impl Pill {
             priv_.bindings.borrow_mut().push(display_name_binding);
         }
 
-        priv_.avatar.set_room(room.clone());
+        priv_
+            .avatar
+            .set_item(room.clone().map(|room| room.avatar().clone()));
         priv_.room.replace(room);
 
         self.notify("room");
diff --git a/src/session/avatar.rs b/src/session/avatar.rs
index 0cd91962..2d98a5b6 100644
--- a/src/session/avatar.rs
+++ b/src/session/avatar.rs
@@ -20,6 +20,7 @@ mod imp {
         pub image: RefCell<Option<gdk::Paintable>>,
         pub needed: Cell<bool>,
         pub url: RefCell<Option<MxcUri>>,
+        pub display_name: RefCell<Option<String>>,
         pub session: OnceCell<Session>,
     }
 
@@ -55,6 +56,13 @@ mod imp {
                         None,
                         glib::ParamFlags::READWRITE | glib::ParamFlags::EXPLICIT_NOTIFY,
                     ),
+                    glib::ParamSpec::new_string(
+                        "display-name",
+                        "Display Name",
+                        "The display name used for this avatar",
+                        None,
+                        glib::ParamFlags::READWRITE,
+                    ),
                     glib::ParamSpec::new_object(
                         "session",
                         "Session",
@@ -79,6 +87,9 @@ mod imp {
                 "needed" => obj.set_needed(value.get().unwrap()),
                 "url" => obj.set_url(value.get::<Option<&str>>().unwrap().map(Into::into)),
                 "session" => self.session.set(value.get().unwrap()).unwrap(),
+                "display-name" => {
+                    let _ = obj.set_display_name(value.get().unwrap());
+                }
                 _ => unimplemented!(),
             }
         }
@@ -94,6 +105,7 @@ mod imp {
                     },
                     |url| url.as_str().to_value(),
                 ),
+                "display-name" => obj.display_name().to_value(),
                 _ => unimplemented!(),
             }
         }
@@ -165,6 +177,22 @@ impl Avatar {
         }
     }
 
+    pub fn set_display_name(&self, display_name: Option<String>) {
+        let priv_ = imp::Avatar::from_instance(self);
+        if self.display_name() == display_name {
+            return;
+        }
+
+        priv_.display_name.replace(display_name);
+
+        self.notify("display-name");
+    }
+
+    pub fn display_name(&self) -> Option<String> {
+        let priv_ = imp::Avatar::from_instance(self);
+        priv_.display_name.borrow().clone()
+    }
+
     pub fn set_needed(&self, needed: bool) {
         let priv_ = imp::Avatar::from_instance(self);
         if self.needed() == needed {
diff --git a/src/session/content/message_row.rs b/src/session/content/message_row.rs
index 1a4c0c62..ebfee789 100644
--- a/src/session/content/message_row.rs
+++ b/src/session/content/message_row.rs
@@ -149,7 +149,7 @@ impl MessageRow {
             }
         }
 
-        priv_.avatar.set_user(Some(event.sender().clone()));
+        priv_.avatar.set_item(Some(event.sender().avatar().clone()));
 
         let display_name_binding = event
             .sender()
diff --git a/src/session/room/room.rs b/src/session/room/room.rs
index 9d9b3a89..3479b2b0 100644
--- a/src/session/room/room.rs
+++ b/src/session/room/room.rs
@@ -202,6 +202,11 @@ mod imp {
             self.avatar
                 .set(Avatar::new(obj.session(), obj.matrix_room().avatar_url()))
                 .unwrap();
+
+            obj.bind_property("display-name", obj.avatar(), "display-name")
+                .flags(glib::BindingFlags::SYNC_CREATE)
+                .build()
+                .unwrap();
         }
     }
 }
diff --git a/src/session/sidebar/room_row.rs b/src/session/sidebar/room_row.rs
index d592189e..1b5f8e21 100644
--- a/src/session/sidebar/room_row.rs
+++ b/src/session/sidebar/room_row.rs
@@ -158,7 +158,9 @@ impl RoomRow {
                 notification_count_vislbe_binding,
             ]);
         }
-        priv_.avatar.set_room(room.clone());
+        priv_
+            .avatar
+            .set_item(room.clone().map(|room| room.avatar().clone()));
         priv_.room.replace(room);
         self.notify("room");
     }
diff --git a/src/session/user.rs b/src/session/user.rs
index 82cfedcc..c3a6cc62 100644
--- a/src/session/user.rs
+++ b/src/session/user.rs
@@ -99,6 +99,11 @@ mod imp {
 
             let avatar = Avatar::new(obj.session(), None);
             self.avatar.set(avatar).unwrap();
+
+            obj.bind_property("display-name", obj.avatar(), "display-name")
+                .flags(glib::BindingFlags::SYNC_CREATE)
+                .build()
+                .unwrap();
         }
     }
 }


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