[fractal/multi-account: 8/9] Add account switcher




commit e162d319555805a70b3f1a37c3989706b2e7c00a
Author: Alejandro Domínguez <adomu net-c com>
Date:   Tue Jul 13 15:34:37 2021 +0200

    Add account switcher

 data/resources/resources.gresource.xml             |  2 ++
 data/resources/ui/sidebar-account-switcher-item.ui | 20 +++++++++++
 data/resources/ui/sidebar-account-switcher.ui      | 40 ++++++++++++++++++++++
 data/resources/ui/sidebar.ui                       |  8 +++++
 src/meson.build                                    |  1 +
 src/session/mod.rs                                 |  7 +++-
 src/session/sidebar/account_switcher.rs            | 34 ++++++++++++++++++
 src/session/sidebar/mod.rs                         |  1 +
 src/session/sidebar/sidebar.rs                     | 15 +++++++-
 src/window.rs                                      |  1 +
 10 files changed, 127 insertions(+), 2 deletions(-)
---
diff --git a/data/resources/resources.gresource.xml b/data/resources/resources.gresource.xml
index 2a6d9825..ed7d34af 100644
--- a/data/resources/resources.gresource.xml
+++ b/data/resources/resources.gresource.xml
@@ -18,6 +18,8 @@
     <file compressed="true" preprocess="xml-stripblanks" alias="login.ui">ui/login.ui</file>
     <file compressed="true" preprocess="xml-stripblanks" alias="session.ui">ui/session.ui</file>
     <file compressed="true" preprocess="xml-stripblanks" alias="sidebar.ui">ui/sidebar.ui</file>
+    <file compressed="true" preprocess="xml-stripblanks" 
alias="sidebar-account-switcher.ui">ui/sidebar-account-switcher.ui</file>
+    <file compressed="true" preprocess="xml-stripblanks" 
alias="sidebar-account-switcher-item.ui">ui/sidebar-account-switcher-item.ui</file>
     <file compressed="true" preprocess="xml-stripblanks" alias="sidebar-item.ui">ui/sidebar-item.ui</file>
     <file compressed="true" preprocess="xml-stripblanks" 
alias="sidebar-category-row.ui">ui/sidebar-category-row.ui</file>
     <file compressed="true" preprocess="xml-stripblanks" 
alias="sidebar-entry-row.ui">ui/sidebar-entry-row.ui</file>
diff --git a/data/resources/ui/sidebar-account-switcher-item.ui 
b/data/resources/ui/sidebar-account-switcher-item.ui
new file mode 100644
index 00000000..075705f8
--- /dev/null
+++ b/data/resources/ui/sidebar-account-switcher-item.ui
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="GtkListItem">
+    <property name="child">
+      <object class="GtkBox">
+        <child>
+          <object class="GtkLabel">
+            <binding name="label">
+              <lookup name="display-name" type="GtkStringObject">
+                <lookup name="user" type="User">
+                  <lookup name="item">GtkListItem</lookup>
+                </lookup>
+              </lookup>
+            </binding>
+          </object>
+        </child>
+      </object>
+    </property>
+  </template>
+</interface>
diff --git a/data/resources/ui/sidebar-account-switcher.ui b/data/resources/ui/sidebar-account-switcher.ui
new file mode 100644
index 00000000..fd998a14
--- /dev/null
+++ b/data/resources/ui/sidebar-account-switcher.ui
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="AccountSwitcher" parent="GtkPopover">
+    <child>
+      <object class="GtkBox">
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkListView" id="users">
+            <property name="single-click-activate">true</property>
+            <property name="factory">
+              <object class="GtkBuilderListItemFactory">
+                <property name="resource">/org/gnome/FractalNext/sidebar-account-switcher-item.ui</property>
+              </object>
+            </property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkSeparator"></object>
+        </child>
+        <child>
+          <object class="GtkBox">
+            <property name="orientation">horizontal</property>
+            <property name="spacing">10</property>
+            <child>
+              <object class="GtkButton">
+                <property name="icon-name">list-add-symbolic</property>
+                <property name="action-name">app.new-login</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="label" translatable="yes">_Add account</property>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/data/resources/ui/sidebar.ui b/data/resources/ui/sidebar.ui
index 5de728b5..06b3c2f9 100644
--- a/data/resources/ui/sidebar.ui
+++ b/data/resources/ui/sidebar.ui
@@ -29,6 +29,14 @@
               <object class="AdwWindowTitle"></object>
             </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>
+                </property>
+              </object>
+            </child>
             <child type="end">
               <object class="GtkMenuButton" id="appmenu_button">
                 <property name="icon-name">open-menu-symbolic</property>
diff --git a/src/meson.build b/src/meson.build
index b3e129b7..d50043c3 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -61,6 +61,7 @@ sources = files(
   'session/room/room_type.rs',
   'session/room_list.rs',
   'session/room/timeline.rs',
+  'session/sidebar/account_switcher.rs',
   'session/sidebar/item_list.rs',
   'session/sidebar/category.rs',
   'session/sidebar/category_row.rs',
diff --git a/src/session/mod.rs b/src/session/mod.rs
index 73eb6847..25a343a4 100644
--- a/src/session/mod.rs
+++ b/src/session/mod.rs
@@ -25,7 +25,7 @@ use adw;
 use adw::subclass::prelude::BinImpl;
 use gtk::subclass::prelude::*;
 use gtk::{self, prelude::*};
-use gtk::{gio, glib, glib::clone, glib::SyncSender, CompositeTemplate};
+use gtk::{gio, glib, glib::clone, glib::SyncSender, CompositeTemplate, SelectionModel};
 use gtk_macros::send;
 use log::error;
 use matrix_sdk::ruma::{
@@ -431,4 +431,9 @@ impl Session {
     fn handle_sync_response(&self, response: SyncResponse) {
         self.room_list().handle_response_rooms(response.rooms);
     }
+
+    pub fn set_logged_in_users(&self, logged_in_users: &SelectionModel) {
+        let priv_ = &imp::Session::from_instance(self);
+        priv_.sidebar.set_logged_in_users(logged_in_users);
+    }
 }
diff --git a/src/session/sidebar/account_switcher.rs b/src/session/sidebar/account_switcher.rs
new file mode 100644
index 00000000..a32da793
--- /dev/null
+++ b/src/session/sidebar/account_switcher.rs
@@ -0,0 +1,34 @@
+use gtk::{gio, glib, subclass::prelude::*, CompositeTemplate, ListView};
+
+mod imp {
+    use super::*;
+
+    #[derive(Debug, Default, CompositeTemplate)]
+    #[template(resource = "/org/gnome/FractalNext/sidebar-account-switcher.ui")]
+    pub struct AccountSwitcher {
+        #[template_child]
+        pub users: TemplateChild<ListView>,
+    }
+
+    #[glib::object_subclass]
+    impl ObjectSubclass for AccountSwitcher {
+        const NAME: &'static str = "AccountSwitcher";
+        type Type = super::AccountSwitcher;
+        type ParentType = gtk::Popover;
+    }
+
+    impl ObjectImpl for AccountSwitcher {}
+    impl WidgetImpl for AccountSwitcher {}
+    impl PopoverImpl for AccountSwitcher {}
+}
+
+glib::wrapper! {
+    pub struct AccountSwitcher(ObjectSubclass<imp::AccountSwitcher>)
+        @extends gtk::Widget, gtk::Popover, @implements gtk::Accessible, gio::ListModel;
+}
+
+impl AccountSwitcher {
+    pub fn users(&self) -> ListView {
+        imp::AccountSwitcher::from_instance(self).users.get()
+    }
+}
diff --git a/src/session/sidebar/mod.rs b/src/session/sidebar/mod.rs
index e9cc2def..ac8dc48d 100644
--- a/src/session/sidebar/mod.rs
+++ b/src/session/sidebar/mod.rs
@@ -1,3 +1,4 @@
+mod account_switcher;
 mod category;
 mod category_row;
 mod entry;
diff --git a/src/session/sidebar/sidebar.rs b/src/session/sidebar/sidebar.rs
index 04eebb41..0362e9ac 100644
--- a/src/session/sidebar/sidebar.rs
+++ b/src/session/sidebar/sidebar.rs
@@ -1,5 +1,5 @@
 use adw::subclass::prelude::BinImpl;
-use gtk::{gio, glib, prelude::*, subclass::prelude::*, CompositeTemplate};
+use gtk::{gio, glib, prelude::*, subclass::prelude::*, CompositeTemplate, SelectionModel};
 
 use crate::session::{
     content::ContentType,
@@ -8,6 +8,8 @@ use crate::session::{
     RoomList,
 };
 
+use super::account_switcher::AccountSwitcher;
+
 mod imp {
     use super::*;
     use glib::subclass::InitializingObject;
@@ -23,6 +25,8 @@ mod imp {
         #[template_child]
         pub headerbar: TemplateChild<adw::HeaderBar>,
         #[template_child]
+        pub account_switcher: TemplateChild<AccountSwitcher>,
+        #[template_child]
         pub listview: TemplateChild<gtk::ListView>,
         #[template_child]
         pub room_search_entry: TemplateChild<gtk::SearchEntry>,
@@ -254,4 +258,13 @@ impl Sidebar {
         priv_.selected_room.replace(selected_room);
         self.notify("selected-room");
     }
+
+    pub fn set_logged_in_users(&self, logged_in_users: &SelectionModel) {
+        let priv_ = imp::Sidebar::from_instance(self);
+
+        priv_
+            .account_switcher
+            .users()
+            .set_model(Some(logged_in_users));
+    }
 }
diff --git a/src/window.rs b/src/window.rs
index 266d0b07..570e1492 100644
--- a/src/window.rs
+++ b/src/window.rs
@@ -102,6 +102,7 @@ impl Window {
 
     fn add_session(&self, session: &Session) {
         let priv_ = &imp::Window::from_instance(self);
+        session.set_logged_in_users(&priv_.main_stack.pages());
         priv_.main_stack.add_child(session);
         priv_.main_stack.set_visible_child(session);
         self.install_session_actions(session);


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