[fractal/fractal-next] Show errors as in-app-notifications



commit 70824766b7155527b0161192a1c2e302b94f200b
Author: Julian Sparber <julian sparber net>
Date:   Thu May 27 15:29:49 2021 +0200

    Show errors as in-app-notifications

 data/resources/ui/content.ui   | 26 ++++++++----
 data/resources/ui/session.ui   | 91 +++++++++++++++++++++++-------------------
 src/session/content/content.rs | 14 ++++++-
 src/session/content/invite.rs  | 23 +++--------
 src/session/mod.rs             |  2 +
 src/session/room/room.rs       |  6 +--
 6 files changed, 92 insertions(+), 70 deletions(-)
---
diff --git a/data/resources/ui/content.ui b/data/resources/ui/content.ui
index f30599b8..a8c96a95 100644
--- a/data/resources/ui/content.ui
+++ b/data/resources/ui/content.ui
@@ -4,17 +4,27 @@
     <property name="vexpand">True</property>
     <property name="hexpand">True</property>
     <property name="child">
-      <object class="GtkStack" id="stack">
-        <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 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>
         <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 class="GtkStack" id="stack">
+            <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>
           </object>
         </child>
       </object>
diff --git a/data/resources/ui/session.ui b/data/resources/ui/session.ui
index f5688197..1a2a052c 100644
--- a/data/resources/ui/session.ui
+++ b/data/resources/ui/session.ui
@@ -1,56 +1,65 @@
 <?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="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 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>
         <child>
-          <object class="AdwLeaflet" id="content">
+          <object class="GtkStack" id="stack">
+            <property name="visible-child">loading</property>
+            <property name="transition-type">crossfade</property>
             <child>
-              <object class="Sidebar">
-                <property name="compact" bind-source="content" bind-property="folded" 
bind-flags="sync-create"/>
-                <property name="categories" bind-source="Session" bind-property="categories" 
bind-flags="sync-create"/>
-                <property name="selected-room" bind-source="Session" bind-property="selected-room" 
bind-flags="sync-create | bidirectional"/>
+              <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="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="error-list">
-                  <object class="GListStore" id="error_list">
-                    <property name="item-type">Error</property>
+              <object class="AdwLeaflet" id="content">
+                <child>
+                  <object class="Sidebar">
+                    <property name="compact" bind-source="content" bind-property="folded" 
bind-flags="sync-create"/>
+                    <property name="categories" bind-source="Session" bind-property="categories" 
bind-flags="sync-create"/>
+                    <property name="selected-room" bind-source="Session" bind-property="selected-room" 
bind-flags="sync-create | bidirectional"/>
                   </object>
-                </property>
+                </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="error-list">error_list</property>
+                  </object>
+                </child>
               </object>
             </child>
           </object>
diff --git a/src/session/content/content.rs b/src/session/content/content.rs
index af97a437..e6dfc5c0 100644
--- a/src/session/content/content.rs
+++ b/src/session/content/content.rs
@@ -1,6 +1,6 @@
 use crate::session::{categories::CategoryType, content::Invite, content::RoomHistory, room::Room};
 use adw::subclass::prelude::*;
-use gtk::{glib, glib::clone, prelude::*, subclass::prelude::*, CompositeTemplate};
+use gtk::{gio, glib, glib::clone, prelude::*, subclass::prelude::*, CompositeTemplate};
 
 mod imp {
     use super::*;
@@ -12,6 +12,7 @@ mod imp {
     pub struct Content {
         pub compact: Cell<bool>,
         pub room: RefCell<Option<Room>>,
+        pub error_list: RefCell<Option<gio::ListStore>>,
         pub category_handler: RefCell<Option<SignalHandlerId>>,
         #[template_child]
         pub stack: TemplateChild<gtk::Stack>,
@@ -62,6 +63,13 @@ mod imp {
                         Room::static_type(),
                         glib::ParamFlags::READWRITE | glib::ParamFlags::EXPLICIT_NOTIFY,
                     ),
+                    glib::ParamSpec::new_object(
+                        "error-list",
+                        "Error List",
+                        "A list of errors shown as in-app-notification",
+                        gio::ListStore::static_type(),
+                        glib::ParamFlags::READWRITE,
+                    ),
                 ]
             });
 
@@ -84,6 +92,9 @@ mod imp {
                     let room = value.get().unwrap();
                     obj.set_room(room);
                 }
+                "error-list" => {
+                    self.error_list.replace(value.get().unwrap());
+                }
                 _ => unimplemented!(),
             }
         }
@@ -92,6 +103,7 @@ mod imp {
             match pspec.name() {
                 "compact" => self.compact.get().to_value(),
                 "room" => obj.room().to_value(),
+                "error-list" => self.error_list.borrow().to_value(),
                 _ => unimplemented!(),
             }
         }
diff --git a/src/session/content/invite.rs b/src/session/content/invite.rs
index e08456f1..a04fdaca 100644
--- a/src/session/content/invite.rs
+++ b/src/session/content/invite.rs
@@ -5,7 +5,6 @@ use crate::{
 use adw::subclass::prelude::*;
 use gtk::{glib, glib::clone, prelude::*, subclass::prelude::*, CompositeTemplate};
 use gtk_macros::spawn;
-use log::error;
 
 mod imp {
     use super::*;
@@ -216,14 +215,9 @@ impl Invite {
             clone!(@weak self as obj, @strong room => move || async move {
                     let priv_ = imp::Invite::from_instance(&obj);
                     let result = room.accept_invite().await;
-                    match result {
-                            Ok(_) => {},
-                            Err(error) => {
-                                // FIXME: display an error to the user
-                                error!("Accepting invitiation failed: {}", error);
-                                priv_.accept_requests.borrow_mut().remove(&room);
-                                obj.reset();
-                            },
+                    if result.is_err() {
+                        priv_.accept_requests.borrow_mut().remove(&room);
+                        obj.reset();
                     }
             })()
         );
@@ -244,14 +238,9 @@ impl Invite {
             clone!(@weak self as obj, @strong room => move || async move {
                     let priv_ = imp::Invite::from_instance(&obj);
                     let result = room.reject_invite().await;
-                    match result {
-                            Ok(_) => {},
-                            Err(error) => {
-                                // FIXME: display an error to the user
-                                error!("Rejecting invitiation failed: {}", error);
-                                priv_.reject_requests.borrow_mut().remove(&room);
-                                obj.reset();
-                            },
+                    if result.is_err() {
+                        priv_.reject_requests.borrow_mut().remove(&room);
+                        obj.reset();
                     }
             })()
         );
diff --git a/src/session/mod.rs b/src/session/mod.rs
index 705a96e8..abf65411 100644
--- a/src/session/mod.rs
+++ b/src/session/mod.rs
@@ -12,6 +12,7 @@ use self::room_list::RoomList;
 use self::sidebar::Sidebar;
 pub use self::user::User;
 
+use crate::components::InAppNotification;
 use crate::secret;
 use crate::secret::StoredSession;
 use crate::utils::do_async;
@@ -74,6 +75,7 @@ mod imp {
             Sidebar::static_type();
             Content::static_type();
             Error::static_type();
+            InAppNotification::static_type();
             obj.init_template();
         }
     }
diff --git a/src/session/room/room.rs b/src/session/room/room.rs
index 864bfac7..bcd86f31 100644
--- a/src/session/room/room.rs
+++ b/src/session/room/room.rs
@@ -22,7 +22,7 @@ use matrix_sdk::{
 };
 use std::cell::RefCell;
 
-use crate::components::{LabelWithWidgets, UserPill};
+use crate::components::{LabelWithWidgets, Pill};
 use crate::event_from_sync_event;
 use crate::session::{
     categories::CategoryType,
@@ -593,7 +593,7 @@ impl Room {
                         error,
                         clone!(@strong self as room => move |_| {
                                 let error_message = gettext("Failed to accept invitation for <widget>. Try 
again later.");
-                                let room_pill = UserPill::new();
+                                let room_pill = Pill::new();
                                 room_pill.set_room(Some(room.clone()));
                                 let error_label = LabelWithWidgets::new(&error_message, vec![room_pill]);
                                 Some(error_label.upcast())
@@ -623,7 +623,7 @@ impl Room {
                         error,
                         clone!(@strong self as room => move |_| {
                                 let error_message = gettext("Failed to reject invitation for <widget>. Try 
again later.");
-                                let room_pill = UserPill::new();
+                                let room_pill = Pill::new();
                                 room_pill.set_room(Some(room.clone()));
                                 let error_label = LabelWithWidgets::new(&error_message, vec![room_pill]);
                                 Some(error_label.upcast())


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