[polari] roomList: Use header popover for connection management
- From: Florian Müllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [polari] roomList: Use header popover for connection management
- Date: Fri, 29 Jan 2016 09:05:10 +0000 (UTC)
commit 6ef2e57371aab2393918b12a9dfb11744e621685
Author: Isabella Ribeiro <belinhacbr gmail com>
Date: Sun Jan 24 16:26:19 2016 -0200
roomList: Use header popover for connection management
We want to move away from a separate connection editor in favor of more direct
connection management. Creating new connections directly from the join dialog
has been possible for a while now, and the room list's headers provide a good
place for exposing connection editing/removal, so rework the existing error
popover to be usable for general connection management in non-error cases
as well.
https://bugzilla.gnome.org/show_bug.cgi?id=761057
data/resources/room-list-header.ui | 49 +++++++++---
src/application.js | 13 +++
src/roomList.js | 153 +++++++++++++++++++-----------------
3 files changed, 131 insertions(+), 84 deletions(-)
---
diff --git a/data/resources/room-list-header.ui b/data/resources/room-list-header.ui
index 3a80583..8857ffa 100644
--- a/data/resources/room-list-header.ui
+++ b/data/resources/room-list-header.ui
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="Gjs_RoomListHeader" parent="GtkMenuButton">
- <property name="popover">errorPopover</property>
+ <property name="popover">connectionPopover</property>
<property name="margin-bottom">4</property>
<property name="margin-start">7</property>
<property name="margin-end">7</property>
@@ -10,6 +10,7 @@
<style>
<class name="room-list-header"/>
<class name="activatable" />
+ <class name="dim-label" />
</style>
<child>
<object class="GtkBox">
@@ -61,39 +62,63 @@
</object>
</child>
</template>
- <object class="GtkPopover" id="errorPopover">
+ <object class="GtkPopoverMenu" id="connectionPopover">
<property name="position">bottom</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="margin">12</property>
- <property name="spacing">3</property>
<property name="visible">True</property>
<child>
- <object class="GtkLabel">
- <property name="label" translatable="yes">Connection Error</property>
+ <object class="GtkLabel" id="popoverTitle">
<property name="wrap">True</property>
<property name="max-width-chars">30</property>
+ <property name="width-chars">15</property>
<property name="xalign">0</property>
<property name="visible">True</property>
- <attributes>
- <attribute name="weight" value="PANGO_WEIGHT_BOLD"/>
- </attributes>
+ <property name="margin-start">6</property>
+ <property name="margin-end">6</property>
</object>
</child>
<child>
- <object class="GtkLabel" id="popoverLabel">
+ <object class="GtkLabel" id="popoverStatus">
<property name="wrap">True</property>
<property name="max-width-chars">30</property>
<property name="xalign">0</property>
<property name="visible">True</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">6</property>
</object>
</child>
<child>
- <object class="GtkButton" id="popoverButton">
- <property name="margin-top">15</property>
- <property name="halign">end</property>
+ <object class="GtkSeparator">
<property name="visible">True</property>
+ <property name="margin-top">6</property>
+ <property name="margin-bottom">6</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkModelButton" id="popoverReconnect">
+ <property name="xalign">0</property>
+ <property name="visible">True</property>
+ <property name="action-name">app.reconnect-account</property>
+ <property name="text" translatable="yes">Reconnect</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkModelButton" id="popoverRemove">
+ <property name="xalign">0</property>
+ <property name="visible">True</property>
+ <property name="action-name">app.remove-connection</property>
+ <property name="text" translatable="yes">Remove</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkModelButton" id="popoverProperties">
+ <property name="xalign">0</property>
+ <property name="visible">True</property>
+ <property name="action-name">app.edit-connection</property>
+ <property name="text" translatable="yes">Properties</property>
</object>
</child>
</object>
diff --git a/src/application.js b/src/application.js
index b433434..eedfeda 100644
--- a/src/application.js
+++ b/src/application.js
@@ -84,6 +84,9 @@ const Application = new Lang.Class({
create_hook: Lang.bind(this, this._userListCreateHook),
state: GLib.Variant.new('b', false),
accels: ['F9', '<Primary>u'] },
+ { name: 'remove-connection',
+ activate: Lang.bind(this, this._onRemoveConnection),
+ parameter_type: GLib.VariantType.new('o') },
{ name: 'edit-connection',
activate: Lang.bind(this, this._onEditConnection),
parameter_type: GLib.VariantType.new('o') },
@@ -431,6 +434,16 @@ const Application = new Lang.Class({
}));
},
+ _onRemoveConnection: function(action, parameter){
+ let accountPath = parameter.deep_unpack();
+ let factory = Tp.AccountManager.dup().get_factory();
+ let account = factory.ensure_account(accountPath, []);
+ account.remove_async(Lang.bind(this,
+ function(a, res) {
+ a.remove_finish(res); // TODO: Check for errors
+ }));
+ },
+
_onEditConnection: function(action, parameter) {
let accountPath = parameter.deep_unpack();
let factory = Tp.AccountManager.dup().get_factory();
diff --git a/src/roomList.js b/src/roomList.js
index 16670be..18beef4 100644
--- a/src/roomList.js
+++ b/src/roomList.js
@@ -163,9 +163,11 @@ const RoomListHeader = new Lang.Class({
Template: 'resource:///org/gnome/Polari/room-list-header.ui',
InternalChildren: ['label',
'iconStack',
- 'errorPopover',
- 'popoverLabel',
- 'popoverButton',
+ 'popoverStatus',
+ 'popoverTitle',
+ 'popoverReconnect',
+ 'popoverRemove',
+ 'popoverProperties',
'spinner'],
_init: function(params) {
@@ -176,12 +178,10 @@ const RoomListHeader = new Lang.Class({
this._app = Gio.Application.get_default();
this.parent(params);
-
- this._errorPopover.relative_to = this._iconStack;
- this._popoverButton.connect('clicked', Lang.bind(this,
- function() {
- this._errorPopover.hide();
- }));
+ let target = new GLib.Variant('o', this._account.get_object_path());
+ this._popoverReconnect.action_target = target;
+ this._popoverRemove.action_target = target;
+ this._popoverProperties.action_target = target;
let displayNameChangedId =
this._account.connect('notify::display-name',
@@ -190,8 +190,8 @@ const RoomListHeader = new Lang.Class({
let connectionStatusChangedId =
this._account.connect('notify::connection-status',
- Lang.bind(this, this._updateConnectionStatusIcon));
- this._updateConnectionStatusIcon();
+ Lang.bind(this, this._onConnectionStatusChanged));
+ this._onConnectionStatusChanged();
this.connect('destroy', Lang.bind(this, function() {
this._account.disconnect(displayNameChangedId);
@@ -214,80 +214,89 @@ const RoomListHeader = new Lang.Class({
this.get_accessible().set_name(accessibleName);
},
- _updateConnectionStatusIcon: function() {
+ _onConnectionStatusChanged: 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.sensitive = isError;
this._iconStack.visible_child_name = child;
this._spinner.active = (child == 'connecting');
+
+ this._popoverTitle.use_markup = isError;
+ this._popoverStatus.use_markup = !isError;
+
+ if (!isError) {
+ let styleContext = this._popoverStatus.get_style_context();
+ styleContext.add_class('dim-label');
+
+ let params = this._account.dup_parameters_vardict().deep_unpack();
+ let server = params['server'].deep_unpack();
+ let accountName = this._account.display_name;
+
+ /* Translators: This is an account name followed by a
+ server address, e.g. "GNOME (irc.gnome.org)" */
+ let fullTitle = _("%s (%s)").format(accountName, server);
+ this._popoverTitle.label = (accountName == server) ? accountName : fullTitle;
+ this._popoverStatus.label = '<sup>' + this._getStatusLabel() + '</sup>';
+ } else {
+ let styleContext = this._popoverStatus.get_style_context();
+ styleContext.remove_class('dim-label');
+
+ this._popoverTitle.label = '<b>' + _("Connection Problem") + '</b>';
+ this._popoverStatus.label = this._getErrorLabel();
+ }
+ },
+
+ _getStatusLabel: function() {
+ switch (this._account.connection_status) {
+ case Tp.ConnectionStatus.CONNECTED:
+ return _("Connected");
+ case Tp.ConnectionStatus.CONNECTING:
+ return _("Connecting...");
+ case Tp.ConnectionStatus.DISCONNECTED:
+ return _("Offline");
+ default:
+ return _("Unknown");
+ }
+ },
+
+ _getErrorLabel: function() {
+ switch (this._account.connection_error) {
+
+ 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):
+ return _("Could not connect to %s in a safe way.").format(this._account.display_name);
+
+ case Tp.error_get_dbus_name(Tp.Error.AUTHENTICATION_FAILED):
+ return _("Could not connect to %s. Authentication
failed.").format(this._account.display_name);
+
+ 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):
+ return _("Could not connect to %s. The server is busy.").format(this._account.display_name);
+
+ default:
+ return _("Could not connect to %s.").format(this._account.display_name);
+ }
},
});
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]