[fractal/fractal-next] error: Use only a single in-app-notifcation



commit 3346669c37a5c119ecb786f6a65daabb564deb1c
Author: Julian Sparber <julian sparber net>
Date:   Sat Sep 25 12:40:15 2021 +0200

    error: Use only a single in-app-notifcation
    
    This simplifies the code and allows easier emittion of errors

 data/resources/ui/content.ui        | 90 +++++++++++++++-------------------
 data/resources/ui/session.ui        | 98 ++++++++++++++++---------------------
 data/resources/ui/window.ui         | 81 +++++++++++++++++-------------
 src/session/account_settings/mod.rs |  4 +-
 src/session/mod.rs                  | 19 ++-----
 src/session/room/mod.rs             | 16 ++++--
 src/session/room_list.rs            |  5 +-
 src/window.rs                       | 14 +++++-
 8 files changed, 165 insertions(+), 162 deletions(-)
---
diff --git a/data/resources/ui/content.ui b/data/resources/ui/content.ui
index 560c8669..748f4a21 100644
--- a/data/resources/ui/content.ui
+++ b/data/resources/ui/content.ui
@@ -4,68 +4,58 @@
     <property name="vexpand">True</property>
     <property name="hexpand">True</property>
     <property name="child">
-      <object class="GtkOverlay">
-        <child type="overlay">
-          <object class="InAppNotification">
-            <property name="error-list" bind-source="Content" bind-property="error-list" 
bind-flags="sync-create"/>
-            <property name="visible" bind-source="Content" bind-property="compact" bind-flags="sync-create | 
invert-boolean"/>
-          </object>
-        </child>
+      <object class="GtkStack" id="stack">
+        <property name="transition-type">crossfade</property>
         <child>
-          <object class="GtkStack" id="stack">
-            <property name="transition-type">crossfade</property>
+          <object class="GtkBox" id="empty_page">
+            <property name="orientation">vertical</property>
             <child>
-              <object class="GtkBox" id="empty_page">
-                <property name="orientation">vertical</property>
-                <child>
-                  <object class="AdwHeaderBar" id="headerbar">
-                    <property name="show-start-title-buttons" bind-source="Content" bind-property="compact" 
bind-flags="sync-create"/>
-                    <child type="start">
-                      <object class="GtkRevealer">
-                        <property name="transition-type">crossfade</property>
-                        <property name="reveal-child" bind-source="Content" bind-property="compact" 
bind-flags="sync-create"/>
-                        <property name="child">
-                          <object class="GtkButton" id="back">
-                            <property name="icon-name">go-previous-symbolic</property>
-                            <property name="action-name">content.go-back</property>
-                          </object>
-                        </property>
+              <object class="AdwHeaderBar" id="headerbar">
+                <property name="show-start-title-buttons" bind-source="Content" bind-property="compact" 
bind-flags="sync-create"/>
+                <child type="start">
+                  <object class="GtkRevealer">
+                    <property name="transition-type">crossfade</property>
+                    <property name="reveal-child" bind-source="Content" bind-property="compact" 
bind-flags="sync-create"/>
+                    <property name="child">
+                      <object class="GtkButton" id="back">
+                        <property name="icon-name">go-previous-symbolic</property>
+                        <property name="action-name">content.go-back</property>
                       </object>
-                    </child>
+                    </property>
                   </object>
                 </child>
-                <child>
-                  <object class="AdwStatusPage">
-                    <property name="visible">True</property>
-                    <property name="hexpand">True</property>
-                    <property name="vexpand">True</property>
-                    <property name="icon-name">empty-page</property>
-                    <property name="title" translatable="yes">No Room Selected</property>
-                    <property name="description" translatable="yes">Join a room to start chatting.</property>
-                  </object>
-                </child>
-              </object>
-            </child>
-            <child>
-              <object class="ContentRoomHistory" id="room_history">
-                <property name="compact" bind-source="Content" bind-property="compact" 
bind-flags="sync-create"/>
-                <property name="room" bind-source="Content" bind-property="room" bind-flags="sync-create"/>
-              </object>
-            </child>
-            <child>
-              <object class="ContentInvite" id="invite">
-                <property name="compact" bind-source="Content" bind-property="compact" 
bind-flags="sync-create"/>
-                <property name="room" bind-source="Content" bind-property="room" bind-flags="sync-create"/>
               </object>
             </child>
             <child>
-              <object class="ContentExplore" id="explore">
-                <property name="compact" bind-source="Content" bind-property="compact" 
bind-flags="sync-create"/>
-                <property name="session" bind-source="Content" bind-property="session" 
bind-flags="sync-create"/>
+              <object class="AdwStatusPage">
+                <property name="visible">True</property>
+                <property name="hexpand">True</property>
+                <property name="vexpand">True</property>
+                <property name="icon-name">empty-page</property>
+                <property name="title" translatable="yes">No Room Selected</property>
+                <property name="description" translatable="yes">Join a room to start chatting.</property>
               </object>
             </child>
           </object>
         </child>
+        <child>
+          <object class="ContentRoomHistory" id="room_history">
+            <property name="compact" bind-source="Content" bind-property="compact" bind-flags="sync-create"/>
+            <property name="room" bind-source="Content" bind-property="room" bind-flags="sync-create"/>
+          </object>
+        </child>
+        <child>
+          <object class="ContentInvite" id="invite">
+            <property name="compact" bind-source="Content" bind-property="compact" bind-flags="sync-create"/>
+            <property name="room" bind-source="Content" bind-property="room" bind-flags="sync-create"/>
+          </object>
+        </child>
+        <child>
+          <object class="ContentExplore" id="explore">
+            <property name="compact" bind-source="Content" bind-property="compact" bind-flags="sync-create"/>
+            <property name="session" bind-source="Content" bind-property="session" bind-flags="sync-create"/>
+          </object>
+        </child>
       </object>
     </property>
   </template>
diff --git a/data/resources/ui/session.ui b/data/resources/ui/session.ui
index 4874b8c8..a137d8f3 100644
--- a/data/resources/ui/session.ui
+++ b/data/resources/ui/session.ui
@@ -1,72 +1,58 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <object class="GListStore" id="error_list">
-    <property name="item-type">Error</property>
-  </object>
   <template class="Session" parent="AdwBin">
     <property name="focusable">true</property>
     <property name="child">
-      <object class="GtkOverlay">
-        <child type="overlay">
-          <object class="InAppNotification">
-            <property name="error-list">error_list</property>
-            <property name="visible" bind-source="content" bind-property="folded" bind-flags="sync-create"/>
-          </object>
-        </child>
+      <object class="GtkStack" id="stack">
+        <property name="visible-child">loading</property>
+        <property name="transition-type">crossfade</property>
         <child>
-          <object class="GtkStack" id="stack">
-            <property name="visible-child">loading</property>
-            <property name="transition-type">crossfade</property>
-            <child>
-              <object class="GtkWindowHandle" id="loading">
-                <property name="child">
-                  <object class="GtkBox">
-                    <property name="orientation">vertical</property>
-                    <child>
-                      <object class="GtkHeaderBar">
-                        <property name="show-title-buttons">True</property>
-                        <style>
-                          <class name="flat"/>
-                        </style>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkSpinner">
-                        <property name="spinning">True</property>
-                        <property name="valign">center</property>
-                        <property name="halign">center</property>
-                        <property name="vexpand">True</property>
-                        <style>
-                          <class name="session-loading-spinner"/>
-                        </style>
-                      </object>
-                    </child>
-                  </object>
-                </property>
-              </object>
-            </child>
-            <child>
-              <object class="AdwLeaflet" id="content">
-                <property name="fold-threshold-policy">minimum</property>
+          <object class="GtkWindowHandle" id="loading">
+            <property name="child">
+              <object class="GtkBox">
+                <property name="orientation">vertical</property>
                 <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"/>
+                  <object class="GtkHeaderBar">
+                    <property name="show-title-buttons">True</property>
+                    <style>
+                      <class name="flat"/>
+                    </style>
                   </object>
                 </child>
                 <child>
-                  <object class="Content">
-                    <property name="compact" bind-source="content" bind-property="folded" 
bind-flags="sync-create"/>
-                    <property name="room" bind-source="Session" bind-property="selected-room" 
bind-flags="sync-create | bidirectional"/>
-                    <property name="content-type" bind-source="Session" 
bind-property="selected-content-type" bind-flags="sync-create | bidirectional"/>
-                    <property name="session">Session</property>
-                    <property name="error-list">error_list</property>
+                  <object class="GtkSpinner">
+                    <property name="spinning">True</property>
+                    <property name="valign">center</property>
+                    <property name="halign">center</property>
+                    <property name="vexpand">True</property>
+                    <style>
+                      <class name="session-loading-spinner"/>
+                    </style>
                   </object>
                 </child>
               </object>
+            </property>
+          </object>
+        </child>
+        <child>
+          <object class="AdwLeaflet" id="content">
+            <property name="fold-threshold-policy">minimum</property>
+            <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"/>
+              </object>
+            </child>
+            <child>
+              <object class="Content">
+                <property name="compact" bind-source="content" bind-property="folded" 
bind-flags="sync-create"/>
+                <property name="room" bind-source="Session" bind-property="selected-room" 
bind-flags="sync-create | bidirectional"/>
+                <property name="content-type" bind-source="Session" bind-property="selected-content-type" 
bind-flags="sync-create | bidirectional"/>
+                <property name="session">Session</property>
+              </object>
             </child>
           </object>
         </child>
diff --git a/data/resources/ui/window.ui b/data/resources/ui/window.ui
index 0973a47e..7cdee88e 100644
--- a/data/resources/ui/window.ui
+++ b/data/resources/ui/window.ui
@@ -3,48 +3,61 @@
   <template class="Window" parent="AdwApplicationWindow">
     <property name="default-width">600</property>
     <property name="default-height">400</property>
-    <child>
-      <object class="GtkStack" id="main_stack">
-        <property name="visible-child">login</property>
-        <property name="transition-type">crossfade</property>
-        <child>
-          <object class="Login" id="login"/>
-        </child>
-        <child>
-          <object class="GtkStack" id="sessions">
-            <property name="transition-type">crossfade</property>
+    <property name="content">
+      <object class="GtkOverlay">
+        <child type="overlay">
+          <object class="InAppNotification">
+            <property name="error-list">
+              <object class="GListStore" id="error_list">
+                <property name="item-type">Error</property>
+              </object>
+            </property>
           </object>
         </child>
         <child>
-          <object class="GtkWindowHandle" id="loading_page">
-            <property name="child">
-              <object class="GtkBox">
-                <property name="orientation">vertical</property>
-                <child>
-                  <object class="GtkHeaderBar">
-                    <property name="show-title-buttons">True</property>
-                    <style>
-                      <class name="flat"/>
-                    </style>
-                  </object>
-                </child>
-                <child>
-                  <object class="GtkSpinner">
-                    <property name="spinning">True</property>
-                    <property name="valign">center</property>
-                    <property name="halign">center</property>
-                    <property name="vexpand">True</property>
-                    <style>
-                      <class name="session-loading-spinner"/>
-                    </style>
+          <object class="GtkStack" id="main_stack">
+            <property name="visible-child">login</property>
+            <property name="transition-type">crossfade</property>
+            <child>
+              <object class="Login" id="login"/>
+            </child>
+            <child>
+              <object class="GtkStack" id="sessions">
+                <property name="transition-type">crossfade</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkWindowHandle" id="loading_page">
+                <property name="child">
+                  <object class="GtkBox">
+                    <property name="orientation">vertical</property>
+                    <child>
+                      <object class="GtkHeaderBar">
+                        <property name="show-title-buttons">True</property>
+                        <style>
+                          <class name="flat"/>
+                        </style>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkSpinner">
+                        <property name="spinning">True</property>
+                        <property name="valign">center</property>
+                        <property name="halign">center</property>
+                        <property name="vexpand">True</property>
+                        <style>
+                          <class name="session-loading-spinner"/>
+                        </style>
+                      </object>
+                    </child>
                   </object>
-                </child>
+                </property>
               </object>
-            </property>
+            </child>
           </object>
         </child>
       </object>
-    </child>
+    </property>
   </template>
 </interface>
 
diff --git a/src/session/account_settings/mod.rs b/src/session/account_settings/mod.rs
index c19cd442..a22c7d87 100644
--- a/src/session/account_settings/mod.rs
+++ b/src/session/account_settings/mod.rs
@@ -83,8 +83,8 @@ glib::wrapper! {
 }
 
 impl AccountSettings {
-    pub fn new(parent_window: &Option<gtk::Window>, user: &User) -> Self {
-        glib::Object::new(&[("transient-for", parent_window), ("user", user)])
+    pub fn new(parent_window: Option<&impl IsA<gtk::Window>>, user: &User) -> Self {
+        glib::Object::new(&[("transient-for", &parent_window), ("user", user)])
             .expect("Failed to create AccountSettings")
     }
 
diff --git a/src/session/mod.rs b/src/session/mod.rs
index 74e3efef..f2a6b480 100644
--- a/src/session/mod.rs
+++ b/src/session/mod.rs
@@ -15,11 +15,10 @@ use self::room_list::RoomList;
 use self::sidebar::Sidebar;
 pub use self::user::{User, UserExt};
 
-use crate::components::InAppNotification;
 use crate::secret;
 use crate::secret::StoredSession;
 use crate::utils::do_async;
-use crate::Error;
+use crate::Window;
 use crate::RUNTIME;
 
 use crate::login::LoginError;
@@ -27,7 +26,7 @@ use crate::session::content::ContentType;
 use adw::subclass::prelude::BinImpl;
 use gtk::subclass::prelude::*;
 use gtk::{self, prelude::*};
-use gtk::{gdk, gio, glib, glib::clone, glib::SyncSender, CompositeTemplate, SelectionModel};
+use gtk::{gdk, glib, glib::clone, glib::SyncSender, CompositeTemplate, SelectionModel};
 use gtk_macros::send;
 use log::error;
 use matrix_sdk::ruma::{
@@ -54,8 +53,6 @@ mod imp {
     #[derive(Debug, Default, CompositeTemplate)]
     #[template(resource = "/org/gnome/FractalNext/session.ui")]
     pub struct Session {
-        #[template_child]
-        pub error_list: TemplateChild<gio::ListStore>,
         #[template_child]
         pub stack: TemplateChild<gtk::Stack>,
         #[template_child]
@@ -115,8 +112,6 @@ mod imp {
         fn instance_init(obj: &InitializingObject<Self>) {
             Sidebar::static_type();
             Content::static_type();
-            Error::static_type();
-            InAppNotification::static_type();
             obj.init_template();
         }
     }
@@ -457,12 +452,6 @@ impl Session {
         sender
     }
 
-    /// This appends a new error to the list of errors
-    pub fn append_error(&self, error: &Error) {
-        let priv_ = imp::Session::from_instance(self);
-        priv_.error_list.append(error);
-    }
-
     /// Returns and consumes the `error` that was generated when the session failed to login,
     /// on a successful login this will be `None`.
     /// Unfortunately it's not possible to connect the Error directly to the `prepared` signals.
@@ -494,13 +483,13 @@ impl Session {
     }
 
     /// Returns the parent GtkWindow containing this widget.
-    fn parent_window(&self) -> Option<gtk::Window> {
+    fn parent_window(&self) -> Option<Window> {
         self.root()?.downcast().ok()
     }
 
     fn open_account_settings(&self) {
         if let Some(user) = self.user() {
-            let window = AccountSettings::new(&self.parent_window(), &user);
+            let window = AccountSettings::new(self.parent_window().as_ref(), &user);
             window.show();
         }
     }
diff --git a/src/session/room/mod.rs b/src/session/room/mod.rs
index 7e6a1330..a5fb480b 100644
--- a/src/session/room/mod.rs
+++ b/src/session/room/mod.rs
@@ -429,7 +429,9 @@ impl Room {
                                         }),
                                 );
 
-                                obj.session().append_error(&error);
+                                if let Some(window) = obj.session().parent_window() {
+                                    window.append_error(&error);
+                                }
 
                                 // Load the previous category
                                 obj.load_category();
@@ -897,7 +899,11 @@ impl Room {
                                 Some(error_label.upcast())
                         }),
                     );
-                    self.session().append_error(&error);
+
+                    if let Some(window) = self.session().parent_window() {
+                        window.append_error(&error);
+                    }
+
                     Err(error)
                 }
             }
@@ -927,7 +933,11 @@ impl Room {
                                 Some(error_label.upcast())
                         }),
                     );
-                    self.session().append_error(&error);
+
+                    if let Some(window) = self.session().parent_window() {
+                        window.append_error(&error);
+                    }
+
                     Err(error)
                 }
             }
diff --git a/src/session/room_list.rs b/src/session/room_list.rs
index 0f52603c..e67fd247 100644
--- a/src/session/room_list.rs
+++ b/src/session/room_list.rs
@@ -338,7 +338,10 @@ impl RoomList {
                                     Some(error_label.upcast())
                             }),
                         );
-                        obj.session().append_error(&error);
+
+                        if let Some(window) = obj.session().parent_window() {
+                            window.append_error(&error);
+                        }
                     }
                 }
             }),
diff --git a/src/window.rs b/src/window.rs
index cbcecc60..513a8e5c 100644
--- a/src/window.rs
+++ b/src/window.rs
@@ -1,6 +1,8 @@
+use crate::components::InAppNotification;
 use crate::config::{APP_ID, PROFILE};
 use crate::secret;
 use crate::Application;
+use crate::Error;
 use crate::Login;
 use crate::Session;
 use adw::subclass::prelude::AdwApplicationWindowImpl;
@@ -25,6 +27,8 @@ mod imp {
         pub sessions: TemplateChild<gtk::Stack>,
         #[template_child]
         pub loading_page: TemplateChild<gtk::WindowHandle>,
+        #[template_child]
+        pub error_list: TemplateChild<gio::ListStore>,
     }
 
     #[glib::object_subclass]
@@ -34,6 +38,8 @@ mod imp {
         type ParentType = adw::ApplicationWindow;
 
         fn class_init(klass: &mut Self::Class) {
+            Error::static_type();
+            InAppNotification::static_type();
             Self::bind_template(klass);
         }
 
@@ -88,7 +94,7 @@ mod imp {
 
 glib::wrapper! {
     pub struct Window(ObjectSubclass<imp::Window>)
-        @extends gtk::Widget, gtk::Window, gtk::ApplicationWindow, adw::ApplicationWindow, @implements 
gio::ActionMap, gio::ActionGroup;
+        @extends gtk::Widget, gtk::Window, gtk::Root, gtk::ApplicationWindow, adw::ApplicationWindow, 
@implements gio::ActionMap, gio::ActionGroup;
 }
 
 impl Window {
@@ -180,4 +186,10 @@ impl Window {
             .show_back_to_session_button(priv_.sessions.get().pages().n_items() > 0);
         priv_.main_stack.set_visible_child(&priv_.login.get());
     }
+
+    /// This appends a new error to the list of errors
+    pub fn append_error(&self, error: &Error) {
+        let priv_ = imp::Window::from_instance(self);
+        priv_.error_list.append(error);
+    }
 }


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