[geary/wip/17-noisy-problem-reports: 5/12] Add initial support for showing/hiding account status as it changes
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/wip/17-noisy-problem-reports: 5/12] Add initial support for showing/hiding account status as it changes
- Date: Tue, 1 Jan 2019 11:30:08 +0000 (UTC)
commit e7c6da94966bf4cf93c9e05eb1026eaebc945200
Author: Michael Gratton <mike vee net>
Date: Sun Dec 30 22:40:04 2018 +1100
Add initial support for showing/hiding account status as it changes
Add infobars for offline, service problems, auth & cert problems. Show
offline and service problem infobars as needed.
src/client/application/geary-controller.vala | 68 +++++-
src/client/components/main-window.vala | 54 ++++-
ui/main-window.ui | 349 ++++++++++++++++++++++++++-
3 files changed, 453 insertions(+), 18 deletions(-)
---
diff --git a/src/client/application/geary-controller.vala b/src/client/application/geary-controller.vala
index dda59ec8..3eb6a3d9 100644
--- a/src/client/application/geary-controller.vala
+++ b/src/client/application/geary-controller.vala
@@ -88,6 +88,29 @@ public class GearyController : Geary.BaseObject {
this.store = new Geary.App.EmailStore(account);
}
+ public Geary.Account.Status get_effective_status() {
+ Geary.Account.Status current = this.account.current_status;
+ Geary.Account.Status effective = 0;
+ if (current.is_online()) {
+ effective |= ONLINE;
+ }
+ if (current.has_service_problem()) {
+ // Only retain this flag if the problem isn't auth or
+ // cert related, that is handled elsewhere.
+ Geary.ClientService.Status incoming =
+ account.incoming.current_status;
+ Geary.ClientService.Status outgoing =
+ account.outgoing.current_status;
+ if (incoming != AUTHENTICATION_FAILED &&
+ incoming != TLS_VALIDATION_FAILED &&
+ outgoing != AUTHENTICATION_FAILED &&
+ outgoing != TLS_VALIDATION_FAILED) {
+ effective |= SERVICE_PROBLEM;
+ }
+ }
+ return effective;
+ }
+
}
@@ -601,6 +624,9 @@ public class GearyController : Geary.BaseObject {
}
private void open_account(Geary.Account account) {
+ account.notify["current-status"].connect(
+ on_account_status_notify
+ );
account.report_problem.connect(on_report_problem);
connect_account_async.begin(account, cancellable_open_account);
@@ -608,16 +634,18 @@ public class GearyController : Geary.BaseObject {
account.contacts_loaded.connect(list_store.set_sort_function);
}
- private async void close_account(Geary.AccountInformation info) {
- AccountContext? context = this.accounts.get(info);
+ private async void close_account(Geary.AccountInformation config) {
+ AccountContext? context = this.accounts.get(config);
if (context != null) {
- Geary.ContactStore contact_store = context.account.get_contact_store();
- ContactListStore list_store = this.contact_list_store_cache.get(contact_store);
+ Geary.Account account = context.account;
+ Geary.ContactStore contact_store = account.get_contact_store();
+ ContactListStore list_store =
+ this.contact_list_store_cache.get(contact_store);
- context.account.contacts_loaded.disconnect(list_store.set_sort_function);
+ account.contacts_loaded.disconnect(list_store.set_sort_function);
this.contact_list_store_cache.unset(contact_store);
- if (this.current_account == context.account) {
+ if (this.current_account == account) {
this.current_account = null;
previous_non_search_folder = null;
@@ -626,9 +654,12 @@ public class GearyController : Geary.BaseObject {
cancel_folder();
}
- // Stop showing errors when closing the account - the user
- // doesn't care
- context.account.report_problem.disconnect(on_report_problem);
+ // Stop updating status and showing errors when closing
+ // the account - the user doesn't care any more
+ account.report_problem.disconnect(on_report_problem);
+ account.notify["current-status"].disconnect(
+ on_account_status_notify
+ );
yield disconnect_account_async(context);
}
@@ -858,6 +889,21 @@ public class GearyController : Geary.BaseObject {
}
}
+ private void update_account_status() {
+ Geary.Account.Status effective_status =
+ this.accounts.values.fold<Geary.Account.Status>(
+ (ctx, status) => ctx.get_effective_status() | status,
+ 0
+ );
+
+ foreach (Gtk.Window window in this.application.get_windows()) {
+ MainWindow? main = window as MainWindow;
+ if (main != null) {
+ main.update_account_status(effective_status);
+ }
+ }
+ }
+
private void on_retry_problem(MainWindowInfoBar info_bar) {
Geary.ServiceProblemReport? service_report =
info_bar.report as Geary.ServiceProblemReport;
@@ -952,6 +998,10 @@ public class GearyController : Geary.BaseObject {
report_problem(problem);
}
+ private void on_account_status_notify() {
+ update_account_status();
+ }
+
private void on_account_email_removed(Geary.Folder folder, Gee.Collection<Geary.EmailIdentifier> ids) {
if (folder.special_folder_type == Geary.SpecialFolderType.OUTBOX) {
main_window.status_bar.deactivate_message(StatusBar.Message.OUTBOX_SEND_FAILURE);
diff --git a/src/client/components/main-window.vala b/src/client/components/main-window.vala
index dceb3f2a..25e83078 100644
--- a/src/client/components/main-window.vala
+++ b/src/client/components/main-window.vala
@@ -59,6 +59,19 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
[GtkChild]
private Gtk.Grid info_bar_container;
+ [GtkChild]
+ private Gtk.InfoBar offline_infobar;
+
+ [GtkChild]
+ private Gtk.InfoBar service_problem_infobar;
+
+ [GtkChild]
+ private Gtk.InfoBar auth_problem_infobar;
+
+ [GtkChild]
+ private Gtk.InfoBar cert_problem_infobar;
+
+
/** Fired when the shift key is pressed or released. */
public signal void on_shift_key(bool pressed);
@@ -87,6 +100,23 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
base_unref();
}
+ /** Updates the window's account status info bars. */
+ public void update_account_status(Geary.Account.Status status) {
+ // Only ever show one at a time. Offline is primary since
+ // nothing else can happen when offline. Service problems are
+ // secondary since auth and cert problems can't be resolved
+ // when the service isn't talking to the server. Auth and cert
+ // problems are enabled elsewhere, since the controller might
+ // be already prompting the user about it.
+ this.offline_infobar.set_visible(!status.is_online());
+ this.service_problem_infobar.set_visible(
+ status.is_online() && status.has_service_problem()
+ );
+ this.auth_problem_infobar.hide();
+ this.cert_problem_infobar.hide();
+ update_infobar_frame();
+ }
+
public void show_infobar(MainWindowInfoBar info_bar) {
this.info_bar_container.add(info_bar);
this.info_bar_frame.show();
@@ -443,6 +473,18 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
this.main_toolbar.folder = this.current_folder.get_display_name();
}
+ private void update_infobar_frame() {
+ // Ensure the info bar frame is shown only when it has visible
+ // children
+ bool show_frame = false;
+ info_bar_container.foreach((child) => {
+ if (child.visible) {
+ show_frame = true;
+ }
+ });
+ this.info_bar_frame.set_visible(show_frame);
+ }
+
private inline void check_shift_event(Gdk.EventKey event) {
// FIXME: it's possible the user will press two shift keys. We want
// the shift key to report as released when they release ALL of them.
@@ -474,13 +516,15 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
return Gdk.EVENT_STOP;
}
+ [GtkCallback]
+ private void on_offline_infobar_response() {
+ this.offline_infobar.hide();
+ update_infobar_frame();
+ }
+
[GtkCallback]
private void on_info_bar_container_remove() {
- // Ensure the info bar frame is hidden when the last info bar
- // is removed from the container.
- if (this.info_bar_container.get_children().length() == 0) {
- this.info_bar_frame.hide();
- }
+ update_infobar_frame();
}
}
diff --git a/ui/main-window.ui b/ui/main-window.ui
index 367e7566..811b886f 100644
--- a/ui/main-window.ui
+++ b/ui/main-window.ui
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.22.0 -->
+<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="MainWindow" parent="GtkApplicationWindow">
@@ -9,6 +9,9 @@
<property name="show_menubar">False</property>
<signal name="delete-event" handler="on_delete_event" swapped="no"/>
<signal name="focus-in-event" handler="on_focus_event" swapped="no"/>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
<child>
<object class="GtkOverlay" id="overlay">
<property name="visible">True</property>
@@ -143,6 +146,347 @@
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<signal name="remove" handler="on_info_bar_container_remove" swapped="no"/>
+ <child>
+ <object class="GtkInfoBar" id="offline_infobar">
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="show_close_button">True</property>
+ <signal name="response" handler="on_offline_infobar_response" swapped="no"/>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox">
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">end</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child internal-child="content_area">
+ <object class="GtkBox">
+ <property name="can_focus">False</property>
+ <property name="spacing">16</property>
+ <child>
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="offline_title">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" comments="Infobar title when
one or more accounts are offline">Working offline</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="offline_description">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes" comments="Label and
tooltip for offline infobar">Your computer does not appear to be connected to the Internet.
+You will not be able to send or receive email until it is re-connected.</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" comments="Label and tooltip
for offline infobar">You will not be able to send or receive email until re-connected.</property>
+ <property name="wrap">True</property>
+ <property name="ellipsize">end</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <style>
+ <class name="sigh"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkInfoBar" id="service_problem_infobar">
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="message_type">error</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox">
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">end</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child internal-child="content_area">
+ <object class="GtkBox">
+ <property name="can_focus">False</property>
+ <property name="spacing">16</property>
+ <child>
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="service_problem_title">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" comments="Infobar title when
one or more accounts have encounted an error">Account problem</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="service_problem_description">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes" comments="Label and
tooltip for account service problem infobar">Geary encountered a problem connecting to an account.
+Please check your Internet connection, the server configuration and try again.</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" comments="Label and tooltip
for account service problem infobar">Geary encountered a problem connecting to an account.</property>
+ <property name="wrap">True</property>
+ <property name="ellipsize">end</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <style>
+ <class name="sigh"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkInfoBar" id="auth_problem_infobar">
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="message_type">error</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox">
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">end</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child internal-child="content_area">
+ <object class="GtkBox">
+ <property name="can_focus">False</property>
+ <property name="spacing">16</property>
+ <child>
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="auth_problem_title">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" comments="Infobar title when
one or more accounts have a login error">Login problem</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="auth_problem_description">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes" comments="Label and
tooltip for authentication problem infobar">An account has reported an incorrect login or password.
+Please check your login name and try again.</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" comments="Label and tooltip
for authentication problem infobar">An account has reported an incorrect login or password.</property>
+ <property name="wrap">True</property>
+ <property name="ellipsize">end</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <style>
+ <class name="sigh"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkInfoBar" id="cert_problem_infobar">
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="message_type">warning</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox">
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">end</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child internal-child="content_area">
+ <object class="GtkBox">
+ <property name="can_focus">False</property>
+ <property name="spacing">16</property>
+ <child>
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="cert_problem_title">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" comments="Infobar title when
one or more accounts have a TLS cert validation error">Security problem</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="cert_problem_description">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes" comments="Label and
tooltip for TLS cert validation error infobar">An account has reported an untrusted server.
+Please check the server configuration and try again.</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" comments="Label and tooltip
for TLS cert validation error infobar">An account has reported an untrusted server.</property>
+ <property name="wrap">True</property>
+ <property name="ellipsize">end</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <style>
+ <class name="sigh"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
</object>
</child>
<child type="label_item">
@@ -165,8 +509,5 @@
</child>
</object>
</child>
- <child type="titlebar">
- <placeholder/>
- </child>
</template>
</interface>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]