[fractal/822-account-switcher-papercuts] account-switcher: Show user avatar on button




commit 53cf5fe49252e944b37e7ed107e4cc9e42522631
Author: Julian Sparber <julian sparber net>
Date:   Fri Sep 10 16:37:33 2021 +0200

    account-switcher: Show user avatar on button

 data/resources/style.css     |  5 +++++
 data/resources/ui/session.ui |  1 +
 data/resources/ui/sidebar.ui | 18 +++++++++++++++---
 src/session/mod.rs           |  5 +++--
 src/session/room/mod.rs      |  6 +++---
 src/session/sidebar/mod.rs   | 31 +++++++++++++++++++++++++++++++
 6 files changed, 58 insertions(+), 8 deletions(-)
---
diff --git a/data/resources/style.css b/data/resources/style.css
index 28a968c9..8aa848d5 100644
--- a/data/resources/style.css
+++ b/data/resources/style.css
@@ -248,3 +248,8 @@ button.cutout:hover {
 button.cutout:active {
   background-color: #c4c5c4;
 }
+
+menubutton.account-switcher > button {
+       padding-left: 8px;
+  padding-right: 8px;
+}
diff --git a/data/resources/ui/session.ui b/data/resources/ui/session.ui
index 6efb6e53..4874b8c8 100644
--- a/data/resources/ui/session.ui
+++ b/data/resources/ui/session.ui
@@ -51,6 +51,7 @@
                 <child>
                   <object class="Sidebar" id="sidebar">
                     <property name="compact" bind-source="content" bind-property="folded" 
bind-flags="sync-create"/>
+                    <property name="user" bind-source="Session" bind-property="user" 
bind-flags="sync-create"/>
                     <property name="room-list" bind-source="Session" bind-property="room-list" 
bind-flags="sync-create"/>
                     <property name="selected-room" bind-source="Session" bind-property="selected-room" 
bind-flags="sync-create | bidirectional"/>
                     <property name="selected-type" bind-source="Session" 
bind-property="selected-content-type" bind-flags="sync-create | bidirectional"/>
diff --git a/data/resources/ui/sidebar.ui b/data/resources/ui/sidebar.ui
index f86a2f57..3e4aecac 100644
--- a/data/resources/ui/sidebar.ui
+++ b/data/resources/ui/sidebar.ui
@@ -26,14 +26,26 @@
         <child>
           <object class="AdwHeaderBar" id="headerbar">
             <property name="title-widget">
-              <object class="AdwWindowTitle"></object>
+              <object class="AdwWindowTitle"/>
             </property>
             <property name="show-end-title-buttons" bind-source="Sidebar" bind-property="compact" 
bind-flags="sync-create"/>
             <child type="start">
               <object class="GtkMenuButton" id="accounts_button">
-                <property name="icon-name">system-users-symbolic</property>
                 <property name="popover">
-                  <object class="AccountSwitcher" id="account_switcher"></object>
+                  <object class="AccountSwitcher" id="account_switcher"/>
+                </property>
+                <style>
+                  <class name="account-switcher"/>
+                </style>
+                <property name="child">
+                  <object class="ComponentsAvatar">
+                    <property name="size">20</property>
+                    <binding name="item">
+                      <lookup name="avatar" type="User">
+                        <lookup name="user">Sidebar</lookup>
+                      </lookup>
+                    </binding>
+                  </object>
                 </property>
               </object>
             </child>
diff --git a/src/session/mod.rs b/src/session/mod.rs
index a52f87ee..beea6d6c 100644
--- a/src/session/mod.rs
+++ b/src/session/mod.rs
@@ -331,6 +331,7 @@ impl Session {
                 priv_.client.set(client.clone()).unwrap();
                 let user = User::new(self, &session.user_id);
                 priv_.user.set(user.clone()).unwrap();
+                self.notify("user");
 
                 do_async(
                     glib::PRIORITY_LOW,
@@ -415,9 +416,9 @@ impl Session {
         priv_.room_list.get_or_init(|| RoomList::new(self))
     }
 
-    pub fn user(&self) -> &User {
+    pub fn user(&self) -> Option<&User> {
         let priv_ = &imp::Session::from_instance(self);
-        priv_.user.get().unwrap()
+        priv_.user.get()
     }
 
     pub fn client(&self) -> &Client {
diff --git a/src/session/room/mod.rs b/src/session/room/mod.rs
index 2e300119..7e6a1330 100644
--- a/src/session/room/mod.rs
+++ b/src/session/room/mod.rs
@@ -640,7 +640,7 @@ impl Room {
             .find(|event| {
                 if let AnyStrippedStateEvent::RoomMember(event) = event {
                     event.content.membership == MembershipState::Invite
-                        && event.state_key == self.session().user().user_id().as_str()
+                        && event.state_key == self.session().user().unwrap().user_id().as_str()
                 } else {
                     false
                 }
@@ -817,7 +817,7 @@ impl Room {
         let pending_event = AnySyncMessageEvent::RoomMessage(SyncMessageEvent {
             content,
             event_id: EventId::try_from(format!("${}:fractal.gnome.org", txn_id)).unwrap(),
-            sender: self.session().user().user_id().clone(),
+            sender: self.session().user().unwrap().user_id().clone(),
             origin_server_ts: MilliSecondsSinceUnixEpoch::now(),
             unsigned: Unsigned::default(),
         });
@@ -853,7 +853,7 @@ impl Room {
 
     /// Creates an expression that is true when the user is allowed the given action.
     pub fn new_allowed_expr(&self, room_action: RoomAction) -> gtk::Expression {
-        let user_id = self.session().user().user_id();
+        let user_id = self.session().user().unwrap().user_id();
         let member = self.member_by_id(user_id);
         self.power_levels().new_allowed_expr(&member, room_action)
     }
diff --git a/src/session/sidebar/mod.rs b/src/session/sidebar/mod.rs
index 76262b61..45f6d773 100644
--- a/src/session/sidebar/mod.rs
+++ b/src/session/sidebar/mod.rs
@@ -20,10 +20,12 @@ use self::selection::Selection;
 use adw::subclass::prelude::BinImpl;
 use gtk::{gio, glib, prelude::*, subclass::prelude::*, CompositeTemplate, SelectionModel};
 
+use crate::components::Avatar;
 use crate::session::content::ContentType;
 use crate::session::room::Room;
 use crate::session::RoomList;
 use crate::session::Session;
+use crate::session::User;
 use account_switcher::AccountSwitcher;
 
 mod imp {
@@ -48,6 +50,7 @@ mod imp {
         pub room_search_entry: TemplateChild<gtk::SearchEntry>,
         #[template_child]
         pub room_search: TemplateChild<gtk::SearchBar>,
+        pub user: RefCell<Option<User>>,
     }
 
     #[glib::object_subclass]
@@ -59,6 +62,7 @@ mod imp {
         fn class_init(klass: &mut Self::Class) {
             RoomRow::static_type();
             Row::static_type();
+            Avatar::static_type();
             Self::bind_template(klass);
         }
 
@@ -71,6 +75,13 @@ mod imp {
         fn properties() -> &'static [glib::ParamSpec] {
             static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
                 vec![
+                    glib::ParamSpec::new_object(
+                        "user",
+                        "User",
+                        "The logged in user",
+                        User::static_type(),
+                        glib::ParamFlags::READWRITE | glib::ParamFlags::EXPLICIT_NOTIFY,
+                    ),
                     glib::ParamSpec::new_boolean(
                         "compact",
                         "Compact",
@@ -118,6 +129,9 @@ mod imp {
                     let compact = value.get().unwrap();
                     self.compact.set(compact);
                 }
+                "user" => {
+                    obj.set_user(value.get().unwrap());
+                }
                 "room-list" => {
                     let room_list = value.get().unwrap();
                     obj.set_room_list(room_list);
@@ -134,6 +148,7 @@ mod imp {
         fn property(&self, obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
             match pspec.name() {
                 "compact" => self.compact.get().to_value(),
+                "user" => obj.user().to_value(),
                 "selected-room" => obj.selected_room().to_value(),
                 "selected-type" => obj.selected_type().to_value(),
                 _ => unimplemented!(),
@@ -269,6 +284,22 @@ impl Sidebar {
         self.notify("selected-room");
     }
 
+    pub fn user(&self) -> Option<User> {
+        let priv_ = &imp::Sidebar::from_instance(self);
+        priv_.user.borrow().clone()
+    }
+
+    fn set_user(&self, user: Option<User>) {
+        let priv_ = imp::Sidebar::from_instance(self);
+
+        if self.user() == user {
+            return;
+        }
+
+        priv_.user.replace(user);
+        self.notify("user");
+    }
+
     pub fn set_logged_in_users(
         &self,
         sessions_stack_pages: &SelectionModel,


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