[polari] Indicate server status in the roomList instead
- From: Bastian Ilsø Hougaard <bastianilso src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [polari] Indicate server status in the roomList instead
- Date: Sun, 16 Aug 2015 23:14:46 +0000 (UTC)
commit 320f87932d0825268bd31294b7a93cbcc3049be7
Author: Bastian Ilsø <bastianilso src gnome org>
Date: Sun Aug 2 17:05:24 2015 +0200
Indicate server status in the roomList instead
Instead of displaying notifications when connecting to
a server, use less attention grabbing status indicators in
the roomlist for displaying status of the servers
individually.
src/appNotifications.js | 34 ----------
src/application.js | 19 +++++-
src/chatroomManager.js | 10 +++
src/mainWindow.js | 24 -------
src/roomList.js | 158 ++++++++++++++++++++++++++++++++++++++++++++---
5 files changed, 178 insertions(+), 67 deletions(-)
---
diff --git a/src/appNotifications.js b/src/appNotifications.js
index 694c422..24d6009 100644
--- a/src/appNotifications.js
+++ b/src/appNotifications.js
@@ -89,40 +89,6 @@ const GridOutput = new Lang.Class({
}
});
-const ConnectingNotification = new Lang.Class({
- Name: 'ConnectingNotification',
- Extends: AppNotification,
-
- _init: function(account) {
- this.parent();
-
- this._grid = new Gtk.Grid({ orientation: Gtk.Orientation.HORIZONTAL,
- column_spacing: 12 });
-
- this._grid.add(new Gtk.Spinner({ active: true }));
-
- let text = _("Connecting to %s").format(account.display_name);
- let label = new Gtk.Label({ label: text });
- this._grid.add(label);
-
- this.widget.add(this._grid);
- this.widget.show_all();
-
- let id = account.connect('notify::connection-status',
- Lang.bind(this, this._onConnectionStatusChanged));
- this.widget.connect('destroy',
- function() {
- account.disconnect(id);
- });
- },
-
- _onConnectionStatusChanged: function(account) {
- if (account.connection_status == Tp.ConnectionStatus.CONNECTING)
- return;
- this.close();
- }
-});
-
const NotificationQueue = new Lang.Class({
Name: 'NotificationQueue',
diff --git a/src/application.js b/src/application.js
index 64ea113..aeb432d 100644
--- a/src/application.js
+++ b/src/application.js
@@ -13,7 +13,6 @@ const MainWindow = imports.mainWindow;
const PasteManager = imports.pasteManager;
const Utils = imports.utils;
-
const MAX_RETRIES = 3;
const ConnectionError = {
@@ -78,11 +77,16 @@ const Application = new Lang.Class({
activate: Lang.bind(this, this._onLeaveCurrentRoom),
create_hook: Lang.bind(this, this._leaveRoomCreateHook),
accels: ['<Primary>w'] },
+ { name: 'reconnect-account',
+ parameter_type: GLib.VariantType.new('o') },
{ name: 'user-list',
activate: Lang.bind(this, this._onToggleAction),
create_hook: Lang.bind(this, this._userListCreateHook),
state: GLib.Variant.new('b', false),
accels: ['F9', '<Primary>u'] },
+ { name: 'edit-connection',
+ activate: Lang.bind(this, this._onEditConnection),
+ parameter_type: GLib.VariantType.new('o') },
{ name: 'connections',
activate: Lang.bind(this, this._onListConnections) },
{ name: 'preferences',
@@ -401,6 +405,19 @@ const Application = new Lang.Class({
}));
},
+ _onEditConnection: function(action, parameter) {
+ let accountPath = parameter.deep_unpack();
+ let factory = Tp.AccountManager.dup().get_factory();
+ let account = factory.ensure_account(accountPath, []);
+ let dialog = new Connections.ConnectionDetailsDialog(account);
+ dialog.widget.transient_for = this._window.window;
+ dialog.widget.connect('response', Lang.bind(this,
+ function(w, response) {
+ w.destroy();
+ }));
+ dialog.widget.show();
+ },
+
_onShowPreferences: function() {
},
diff --git a/src/chatroomManager.js b/src/chatroomManager.js
index 55ca5b3..ebfec1d 100644
--- a/src/chatroomManager.js
+++ b/src/chatroomManager.js
@@ -65,6 +65,9 @@ const _ChatroomManager = new Lang.Class({
let leaveAction = this._app.lookup_action('leave-room');
leaveAction.connect('activate', Lang.bind(this, this._onLeaveActivated));
+ let reconnectAction = this._app.lookup_action('reconnect-account');
+ reconnectAction.connect('activate', Lang.bind(this, this._onReconnectAccountActivated));
+
this._client = new Client(am, this);
let filters = [];
@@ -150,6 +153,13 @@ const _ChatroomManager = new Lang.Class({
action.activate(parameter);
},
+ _onReconnectAccountActivated: function(action, parameter) {
+ let accountPath = parameter.deep_unpack();
+ let factory = Tp.AccountManager.dup().get_factory();
+ let account = factory.ensure_account(accountPath, []);
+ this._restoreSavedChannels(account);
+ },
+
_onJoinActivated: function(action, parameter) {
let [accountPath, channelName, time] = parameter.deep_unpack();
let factory = Tp.AccountManager.dup().get_factory();
diff --git a/src/mainWindow.js b/src/mainWindow.js
index f53e483..1891e59 100644
--- a/src/mainWindow.js
+++ b/src/mainWindow.js
@@ -54,12 +54,6 @@ const MainWindow = new Lang.Class({
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
);
- this._accountsMonitor = AccountsMonitor.getDefault();
- this._accountsMonitor.connect('account-status-changed',
- Lang.bind(this, this._onAccountChanged));
- this._accountsMonitor.connect('account-added',
- Lang.bind(this, this._onAccountChanged));
-
this._roomManager = ChatroomManager.getDefault();
this._roomManager.connect('active-changed',
Lang.bind(this, this._activeRoomChanged));
@@ -119,24 +113,6 @@ const MainWindow = new Lang.Class({
GLib.Variant.new('ai', this._currentSize));
},
- _onAccountChanged: function(am, account) {
- if (account.connection_status != Tp.ConnectionStatus.CONNECTING)
- return;
-
- if (account._connectingNotification)
- return;
-
- let app = Gio.Application.get_default();
- let notification = new AppNotifications.ConnectingNotification(account);
- app.notificationQueue.addNotification(notification);
-
- account._connectingNotification = notification;
- notification.widget.connect('destroy',
- function() {
- delete account._connectingNotification;
- });
- },
-
_updateDecorations: function() {
let layoutLeft = null;
let layoutRight = null;
diff --git a/src/roomList.js b/src/roomList.js
index e6d276b..6592838 100644
--- a/src/roomList.js
+++ b/src/roomList.js
@@ -138,6 +138,154 @@ const RoomRow = new Lang.Class({
}
});
+const RoomListHeader = new Lang.Class({
+ Name: 'RoomListHeader',
+
+ _init: function(account) {
+ this._account = account;
+
+ this._networkMonitor = Gio.NetworkMonitor.get_default();
+
+ this._app = Gio.Application.get_default();
+
+ this.widget = new Gtk.Button({ sensitive: false, margin_bottom: 4,
+ hexpand: true, focus_on_click: false })
+ this.widget.get_style_context().remove_class('button');
+ this.widget.get_style_context().add_class('room-list-header');
+ this.widget.connect('clicked', Lang.bind(this, function () {
+ this._popover.show_all();
+ }));
+
+ let headerBox = new Gtk.Box({ spacing: 2, hexpand: true,
+ orientation: Gtk.Orientation.HORIZONTAL });
+ this.widget.add(headerBox);
+ let label = new Gtk.Label({ xalign: 0, hexpand: true, max_width_chars: 15,
+ ellipsize: Pango.EllipsizeMode.END });
+ this.widget.get_style_context().remove_class('button');
+ account.bind_property('display-name', label, 'label',
+ GObject.BindingFlags.SYNC_CREATE);
+ headerBox.add(label);
+
+ this._iconStack = new Gtk.Stack({ vhomogeneous: true, valign: Gtk.Align.CENTER,
+ margin_end: 4 });
+ this._iconStack.transition_type = Gtk.StackTransitionType.CROSSFADE;
+
+ let errorIcon = new Gtk.Image({ icon_name: 'dialog-error-symbolic',
+ halign: Gtk.Align.END });
+
+ this._popover = new Gtk.Popover({ modal: true,
+ position: Gtk.PositionType.BOTTOM });
+ let popoverBox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL,
+ margin: 12, spacing: 3 });
+ this._popoverLabel = new Gtk.Label({ wrap: true, max_width_chars: 30,
+ halign: Gtk.Align.START, xalign: 0 });
+ this._popoverTitle = new Gtk.Label({ wrap: true, max_width_chars: 30,
+ use_markup: true, xalign: 0,
+ halign: Gtk.Align.START });
+ this._popoverTitle.label = '<b>' + _("Connection Error") + '</b>';
+ this._popoverButton = new Gtk.Button({ valign: Gtk.Align.CENTER, hexpand: true,
+ margin_top: 15, halign: Gtk.Align.END });
+ this._popoverButton.connect('clicked', Lang.bind(this,
+ function() {
+ this._popover.hide();
+ }));
+ popoverBox.add(this._popoverTitle);
+ popoverBox.add(this._popoverLabel);
+ popoverBox.add(this._popoverButton);
+ this._popover.add(popoverBox);
+ this._popover.relative_to = errorIcon;
+
+ this._iconStack.add_named(errorIcon, 'error');
+
+ let connecting = new Gtk.Spinner({ active: true, halign: Gtk.Align.START });
+ this._iconStack.add_named(connecting, 'connecting');
+
+ this._iconStack.add_named(new Gtk.Box(), 'none');
+
+ this._account.connect('notify::connection-status', Lang.bind(this,
this._updateConnectionStatusIcon));
+ headerBox.add(this._iconStack);
+ this.widget.show_all();
+
+ this._updateConnectionStatusIcon();
+
+ },
+
+ _updateConnectionStatusIcon: function() {
+ let status = this._account.connection_status;
+ let reason = this._account.connection_status_reason;
+ let isError = (status == Tp.ConnectionStatus.DISCONNECTED &&
+ reason != Tp.ConnectionStatusReason.REQUESTED);
+
+ let child = 'none';
+ if (status == Tp.ConnectionStatus.CONNECTING) {
+ if (this._networkMonitor.network_available)
+ child = 'connecting';
+ } else if (isError) {
+ child = 'error';
+ switch (this._account.connection_error) {
+
+ case Tp.error_get_dbus_name(Tp.Error.CONNECTION_REFUSED):
+ case Tp.error_get_dbus_name(Tp.Error.NETWORK_ERROR): {
+ this._popoverLabel.label = _("Please check your connection details.")
+
+ this._popoverButton.label = _("Edit Connection");
+ this._popoverButton.action_name = 'app.edit-connection';
+ this._popoverButton.action_target = new GLib.Variant('o',
this._account.get_object_path());
+ break;
+ }
+
+ case Tp.error_get_dbus_name(Tp.Error.CERT_REVOKED):
+ case Tp.error_get_dbus_name(Tp.Error.CERT_INSECURE):
+ case Tp.error_get_dbus_name(Tp.Error.CERT_LIMIT_EXCEEDED):
+ case Tp.error_get_dbus_name(Tp.Error.CERT_INVALID):
+ case Tp.error_get_dbus_name(Tp.Error.ENCRYPTION_ERROR):
+ case Tp.error_get_dbus_name(Tp.Error.CERT_NOT_PROVIDED):
+ case Tp.error_get_dbus_name(Tp.Error.ENCRYPTION_NOT_AVAILABLE):
+ case Tp.error_get_dbus_name(Tp.Error.CERT_UNTRUSTED):
+ case Tp.error_get_dbus_name(Tp.Error.CERT_EXPIRED):
+ case Tp.error_get_dbus_name(Tp.Error.CERT_NOT_ACTIVATED):
+ case Tp.error_get_dbus_name(Tp.Error.CERT_HOSTNAME_MISMATCH):
+ case Tp.error_get_dbus_name(Tp.Error.CERT_FINGERPRINT_MISMATCH):
+ case Tp.error_get_dbus_name(Tp.Error.CERT_SELF_SIGNED): {
+ this._popoverLabel.label = _("Could not make connection in a safe way.");
+ this._popoverButton.label = _("Edit Connection");
+ this._popoverButton.action_name = 'app.edit-connection';
+ this._popoverButton.action_target = GLib.Variant.new('o',
this._account.get_object_path());
+ break;
+ }
+
+ case Tp.error_get_dbus_name(Tp.Error.AUTHENTICATION_FAILED): {
+ this._popoverLabel.label = _("Authentication failed.");
+ this._popoverButton.label = _("Try again");
+ this._popoverButton.action_name = 'app.reconnect-account';
+ this._popoverButton.action_target = GLib.Variant.new('o',
this._account.get_object_path());
+ break;
+ }
+
+ case Tp.error_get_dbus_name(Tp.Error.CONNECTION_FAILED):
+ case Tp.error_get_dbus_name(Tp.Error.CONNECTION_LOST):
+ case Tp.error_get_dbus_name(Tp.Error.CONNECTION_REPLACED):
+ case Tp.error_get_dbus_name(Tp.Error.SERVICE_BUSY): {
+ this._popoverLabel.label = _("The server is busy.");
+ this._popoverButton.label = _("Try again");
+ this._popoverButton.action_name = 'app.reconnect-account';
+ this._popoverButton.action_target = GLib.Variant.new('o',
this._account.get_object_path());
+ break;
+ }
+
+ default:
+ this._popoverLabel.label = _("Failed to connect for an unknown reason.");
+ this._popoverButton.label = _("Try again");
+ this._popoverButton.action_name = 'app.reconnect-account';
+ this._popoverButton.action_target = GLib.Variant.new('o',
this._account.get_object_path());
+ break;
+ }
+ }
+ this.widget.sensitive = isError;
+ this._iconStack.visible_child_name = child;
+ },
+});
+
const RoomList = new Lang.Class({
Name: 'RoomList',
@@ -303,14 +451,8 @@ const RoomList = new Lang.Class({
if (row.get_header())
return;
- let label = new Gtk.Label({ margin_bottom: 4, xalign: 0,
- max_width_chars: 15,
- ellipsize: Pango.EllipsizeMode.END });
- label.get_style_context().add_class('room-list-header');
-
- account.bind_property('display-name', label, 'label',
- GObject.BindingFlags.SYNC_CREATE);
- row.set_header(label);
+ let roomListHeader = new RoomListHeader(account);
+ row.set_header(roomListHeader.widget);
},
_sort: function(row1, row2) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]