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.
This commit is contained in:
parent
62665bf782
commit
e7c6da9496
3 changed files with 453 additions and 18 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue