[polari/wip/dmoelgaard/initial-setup: 227/228] initial Setup
- From: Bastian Ilsø Hougaard <bastianilso src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [polari/wip/dmoelgaard/initial-setup: 227/228] initial Setup
- Date: Tue, 1 Aug 2017 19:55:41 +0000 (UTC)
commit 9cd38f95a2ae7659c3e96d03981c7491d55d5755
Author: Danny Mølgaard <moelgaard dmp gmail com>
Date: Mon Jan 16 20:02:25 2017 +0100
initial Setup
...s-Change-message-button-label-in-userDeta.patch | 32 ++
data/resources/init-setup.ui | 170 ++++--
src/.goutputstream-AQH6QY | 563 ++++++++++++++++++++
src/application.js | 23 +-
src/initSetup.js | 121 ++++-
src/networksManager.js | 9 +
src/serverRoomManager.js | 1 +
7 files changed, 828 insertions(+), 91 deletions(-)
---
diff --git a/0001-user-details-Change-message-button-label-in-userDeta.patch
b/0001-user-details-Change-message-button-label-in-userDeta.patch
new file mode 100644
index 0000000..0126cb3
--- /dev/null
+++ b/0001-user-details-Change-message-button-label-in-userDeta.patch
@@ -0,0 +1,32 @@
+From 64664581bd4fb5fdedd800d52b717f1727117635 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Danny=20M=C3=B8lgaard?= <moelgaard dmp gmail com>
+Date: Thu, 10 Nov 2016 20:30:04 +0100
+Subject: [PATCH] user-details: Change message button label in userDetails
+
+'Message' can be both a noun and verb, thus resulting in confusion
+in terms of its translation to other languages. It also makes more
+sense to have the label correspond with the 'End Conversation'
+available in the sidebar's right-click menu.
+
+This commit changes the message button label in userDetails used by
+userPopover and userList from 'Message' to 'Start Conversation'.
+---
+ data/resources/user-details.ui | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/data/resources/user-details.ui b/data/resources/user-details.ui
+index 003768b..5be9597 100644
+--- a/data/resources/user-details.ui
++++ b/data/resources/user-details.ui
+@@ -178,7 +178,7 @@
+ </child>
+ <child>
+ <object class="GtkModelButton" id="messageButton">
+- <property name="text" translatable="yes">Message</property>
++ <property name="text" translatable="yes">Start Conversation</property>
+ <property name="halign">fill</property>
+ <property name="hexpand">True</property>
+ <property name="visible">True</property>
+--
+2.7.4
+
diff --git a/data/resources/init-setup.ui b/data/resources/init-setup.ui
index e51afcd..d43b3d0 100644
--- a/data/resources/init-setup.ui
+++ b/data/resources/init-setup.ui
@@ -4,8 +4,6 @@
<property name="icon-name">org.gnome.Polari</property>
<property name="default-width">500</property>
<property name="default-height">500</property>
-
- <!-- HEADERBAR START -->
<child type="titlebar">
<object class="GtkBox">
<property name="visible">True</property>
@@ -18,6 +16,7 @@
<property name="title">Polari Setup</property>
<child>
<object class="GtkStack" id="leftHeaderStack">
+ <property name="hhomogeneous">False</property>
<property name="visible">True</property>
<property name="transition-type">crossfade</property>
<child>
@@ -54,6 +53,7 @@
</child>
<child>
<object class="GtkStack" id="rightHeaderStack">
+ <property name="hhomogeneous">False</property>
<property name="visible">True</property>
<property name="transition-type">crossfade</property>
<child>
@@ -73,6 +73,9 @@
<property name="visible">True</property>
<property name="halign">end</property>
<property name="valign">center</property>
+ <style>
+ <class name="suggested-action"/>
+ </style>
</object>
<packing>
<property name="name">doneButton</property>
@@ -87,50 +90,55 @@
</child>
</object>
</child>
- <!-- HEADERBAR END -->
-
- <!-- CONTENT WINDOW START -->
<child>
<object class="GtkStack" id="contentStack">
<property name="visible">True</property>
<property name="transition-type">slide-left-right</property>
- <!-- MAIN STACK PAGE 1 START -->
+ <property name="vexpand">True</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="visible">True</property>
<property name="valign">center</property>
+ <property name="margin">30</property>
+ <property name="margin-bottom">24</property>
+ <property name="spacing">25</property>
<child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="label">Welcome to Polari</property>
- <style>
- <class name="polari-background-title"/>
- </style>
- </object>
- </child>
- <child>
- <object class="GtkLabel">
+ <object class="GtkBox">
<property name="visible">True</property>
- <property name="label">Polari is an easy way to chat using IRC.</property>
- <style>
- <class name="polari-background-description"/>
- </style>
- </object>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="label">Select a connection to get started.</property>
- <style>
- <class name="polari-background-description"/>
- </style>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="label">Welcome to Polari</property>
+ <style>
+ <class name="polari-background-title"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="label">Polari is an easy way to chat using IRC.</property>
+ <style>
+ <class name="polari-background-description"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="label">Select a connection to get started.</property>
+ <style>
+ <class name="polari-background-description"/>
+ </style>
+ </object>
+ </child>
</object>
</child>
<child>
<object class="Gjs_InitSetupConnectionsList" id="connectionPageList">
<property name="visible">True</property>
- <property name="vexpand">True</property>
</object>
</child>
</object>
@@ -138,38 +146,95 @@
<property name="name">connectionPage</property>
</packing>
</child>
- <!-- MAIN STACK PAGE 1 END -->
- <!-- MAIN STACK PAGE 2 START -->
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="visible">True</property>
<property name="valign">center</property>
+ <property name="margin">30</property>
+ <property name="margin-bottom">24</property>
+ <property name="spacing">25</property>
<child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="label">Welcome to Polari</property>
- <style>
- <class name="polari-background-title"/>
- </style>
- </object>
- </child>
- <child>
- <object class="GtkLabel">
+ <object class="GtkBox">
<property name="visible">True</property>
- <property name="label">Select rooms you want to connect to. You can add more</property>
- <style>
- <class name="polari-background-description"/>
- </style>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="label">Welcome to Polari</property>
+ <style>
+ <class name="polari-background-title"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="label">Select rooms you want to connect to. You can add more</property>
+ <style>
+ <class name="polari-background-description"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="label">connections and rooms later, by clicking the + button.</property>
+ <style>
+ <class name="polari-background-description"/>
+ </style>
+ </object>
+ </child>
</object>
</child>
<child>
- <object class="GtkLabel">
+ <object class="GtkBox">
<property name="visible">True</property>
- <property name="label">connections and rooms later, by clicking the + button.</property>
- <style>
- <class name="polari-background-description"/>
- </style>
+ <property name="orientation">vertical</property>
+ <property name="spacing">18</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <style>
+ <class name="linked"/>
+ <class name="frame"/>
+ </style>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <style>
+ <class name="polari-listbox-filterbar"/>
+ </style>
+ <child>
+ <object class="GtkSearchEntry" id="nameEntry">
+ <property name="visible">True</property>
+ <property name="hexpand">True</property>
+ <property name="margin">60</property>
+ <property name="margin-top">6</property>
+ <property name="margin-bottom">6</property>
+ <property name="margin-end">22</property>
+ <property name="placeholder-text" translatable="yes">Enter room name to
add</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSpinner" id="spinner">
+ <property name="visible">True</property>
+ <property name="margin-end">22</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="Gjs_ServerRoomList" id="serverRoomList">
+ <property name="min-content-height">274</property>
+ <property name="visible">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar-policy">never</property>
+ </object>
+ </child>
+ </object>
+ </child>
</object>
</child>
</object>
@@ -177,10 +242,7 @@
<property name="name">roomPage</property>
</packing>
</child>
- <!-- MAIN STACK PAGE 2 END -->
</object>
</child>
- <!-- CONTENT WINDOW END -->
-
</template>
</interface>
diff --git a/src/.goutputstream-AQH6QY b/src/.goutputstream-AQH6QY
new file mode 100644
index 0000000..7aa1f16
--- /dev/null
+++ b/src/.goutputstream-AQH6QY
@@ -0,0 +1,563 @@
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
+const Gtk = imports.gi.Gtk;
+const Polari = imports.gi.Polari;
+const Tp = imports.gi.TelepathyGLib;
+
+const AccountsMonitor = imports.accountsMonitor;
+const AppNotifications = imports.appNotifications;
+const Connections = imports.connections;
+const Lang = imports.lang;
+const MainWindow = imports.mainWindow;
+const PasteManager = imports.pasteManager;
+const RoomManager = imports.roomManager;
+const TelepathyClient = imports.telepathyClient;
+const UserTracker = imports.userTracker;
+const Utils = imports.utils;
+const NetworksManager = imports.networksManager;
+const InitSetup = imports.initSetup;
+
+const MAX_RETRIES = 3;
+
+const IRC_SCHEMA_REGEX = /^(irc?:\/\/)([\da-z\.-]+):?(\d+)?\/(?:%23)?([\w\.\+-]+)/i;
+
+const Application = new Lang.Class({
+ Name: 'Application',
+ Extends: Gtk.Application,
+ Signals: { 'prepare-shutdown': {},
+ 'room-focus-changed': {} },
+
+ _init: function() {
+ this.parent({ application_id: 'org.gnome.Polari',
+ flags: Gio.ApplicationFlags.HANDLES_OPEN });
+
+ GLib.set_application_name('Polari');
+ GLib.set_prgname('org.gnome.Polari');
+ this._retryData = new Map();
+
+ this.add_main_option('start-client', 0,
+ GLib.OptionFlags.NONE, GLib.OptionArg.NONE,
+ _("Start Telephathy client"), null);
+ this.connect('handle-local-options', (o, dict) => {
+ try {
+ this.register(null);
+ } catch(e) {
+ return 1;
+ }
+
+ let v = dict.lookup_value('start-client', null);
+ if (v && v.get_boolean()) {
+ this.activate_action('start-client', null);
+ return 0;
+ }
+
+ return -1;
+ });
+ },
+
+ isRoomFocused: function(room) {
+ return this.active_window &&
+ this.active_window.is_active &&
+ this.active_window.active_room == room;
+ },
+
+ vfunc_startup: function() {
+ this.parent();
+
+ let actionEntries = [
+ { name: 'show-join-dialog',
+ activate: Lang.bind(this, this._onShowJoinDialog),
+ accels: ['<Primary>n'] },
+ { name: 'join-room',
+ activate: Lang.bind(this, this._onJoinRoom),
+ parameter_type: GLib.VariantType.new('(ssu)') },
+ { name: 'message-user',
+ activate: Lang.bind(this, this._onMessageUser),
+ parameter_type: GLib.VariantType.new('(sssu)') },
+ { name: 'leave-room',
+ parameter_type: GLib.VariantType.new('(ss)') },
+ { name: 'leave-current-room',
+ activate: Lang.bind(this, this._onLeaveCurrentRoom),
+ create_hook: (a) => { a.enabled = false; },
+ accels: ['<Primary>w'] },
+ { name: 'authenticate-account',
+ parameter_type: GLib.VariantType.new('(os)') },
+ { name: 'connect-account',
+ activate: Lang.bind(this, this._onConnectAccount),
+ parameter_type: GLib.VariantType.new('o') },
+ { name: 'reconnect-account',
+ activate: Lang.bind(this, this._onConnectAccount),
+ 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: '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') },
+ { name: 'save-identify-password',
+ parameter_type: GLib.VariantType.new('o') },
+ { name: 'discard-identify-password',
+ parameter_type: GLib.VariantType.new('o') },
+ { name: 'start-client',
+ activate: Lang.bind(this, this._onStartClient) },
+ { name: 'help',
+ activate: Lang.bind(this, this._onShowHelp),
+ accels: ['F1'] },
+ { name: 'about',
+ activate: Lang.bind(this, this._onShowAbout) },
+ { name: 'quit',
+ activate: Lang.bind(this, this._onQuit),
+ accels: ['<Primary>q'] },
+ { name: 'next-room',
+ accels: ['<Primary>Page_Down', '<Alt>Down'] },
+ { name: 'previous-room',
+ accels: ['<Primary>Page_Up', '<Alt>Up'] },
+ { name: 'first-room',
+ accels: ['<Primary>Home'] },
+ { name: 'last-room',
+ accels: ['<Primary>End'] },
+ { name: 'nth-room',
+ parameter_type: GLib.VariantType.new('i') },
+ { name: 'next-pending-room',
+ accels: ['<Alt><Shift>Down', '<Primary><Shift>Page_Down']},
+ { name: 'previous-pending-room',
+ accels: ['<Alt><Shift>Up', '<Primary><Shift>Page_Up']}
+ ];
+ actionEntries.forEach(Lang.bind(this,
+ function(actionEntry) {
+ let props = {};
+ ['name', 'state', 'parameter_type'].forEach(
+ function(prop) {
+ if (actionEntry[prop])
+ props[prop] = actionEntry[prop];
+ });
+ let action = new Gio.SimpleAction(props);
+ if (actionEntry.create_hook)
+ actionEntry.create_hook(action);
+ if (actionEntry.activate)
+ action.connect('activate', actionEntry.activate);
+ if (actionEntry.change_state)
+ action.connect('change-state', actionEntry.change_state);
+ if (actionEntry.accels)
+ this.set_accels_for_action('app.' + actionEntry.name,
+ actionEntry.accels);
+ this.add_action(action);
+ }));
+
+ for (let i = 1; i < 10; i++)
+ this.set_accels_for_action('app.nth-room(%d)'.format(i), ['<Alt>' + i]);
+
+ this._telepathyClient = null;
+
+ this._roomManager = RoomManager.getDefault();
+ this._accountsMonitor = AccountsMonitor.getDefault();
+ this._userStatusMonitor = UserTracker.getUserStatusMonitor();
+ this._networksManager = NetworksManager.getDefault();
+
+ this._accountsMonitor.connect('account-status-changed',
+ Lang.bind(this, this._onAccountStatusChanged));
+
+ this.pasteManager = new PasteManager.PasteManager();
+ this.notificationQueue = new AppNotifications.NotificationQueue();
+ this.commandOutputQueue = new AppNotifications.CommandOutputQueue();
+ },
+
+ vfunc_activate: function() {
+ this.activate_action('start-client', null);
+
+ if (!this.active_window) {
+ if (true /*first time startup*/) {
+ while (true /*until setup is complete or cancelled*/) {
+ let setupDialog = new InitSetup.InitSetup({ application: this });
+ setupDialog.show_all();
+ }
+ }
+
+ let window = new MainWindow.MainWindow({ application: this });
+ window.connect('destroy',
+ () => { this.emit('prepare-shutdown'); });
+ window.connect('notify::active-room',
+ () => { this.emit('room-focus-changed'); });
+ window.connect('notify::is-active',
+ () => { this.emit('room-focus-changed'); });
+ window.show_all();
+ }
+ this.active_window.present();
+ },
+
+ vfunc_window_added: function(window) {
+ this.parent(window);
+
+ let action = this.lookup_action('leave-current-room');
+ window.connect('notify::active-room', () => {
+ action.enabled = window.active_room != null;
+ });
+ action.enabled = window.active_room != null;
+
+ window.connect('active-room-state-changed',
+ Lang.bind(this, this._updateUserListAction));
+ this._updateUserListAction();
+ },
+
+ vfunc_open: function(files) {
+ this.activate();
+
+ let time = Utils.getTpEventTime();
+ let uris = files.map(function(f) { return f.get_uri(); });
+
+ this._accountsMonitor.prepare(() => {
+ this._openURIs(uris, time);
+ });
+ },
+
+ _openURIs: function(uris, time) {
+ let map = {};
+
+ this._accountsMonitor.enabledAccounts.forEach(a => {
+ let params = a.dup_parameters_vardict().deep_unpack();
+ map[a.get_object_path()] = {
+ server: params.server.deep_unpack(),
+ service: a.service
+ };
+ });
+
+ let joinAction = this.lookup_action('join-room');
+ uris.forEach(Lang.bind(this, function(uri) {
+ let [success, server, port, room] = this._parseURI(uri);
+ if (!success)
+ return;
+
+ let matchedId = this._networksManager.findByServer(server);
+ let matches = Object.keys(map).filter(function(a) {
+ return GLib.ascii_strcasecmp(map[a].server, server) == 0 ||
+ map[a].service == matchedId;
+ });
+
+ if (matches.length)
+ joinAction.activate(new GLib.Variant('(ssu)',
+ [matches[0], '#' + room, time]));
+ else
+ this._createAccount(matchedId, server, port,
+ function(a) {
+ if (a)
+ joinAction.activate(new GLib.Variant('(ssu)',
+ [a.get_object_path(),
+ '#' + room, time]));
+ });
+ }));
+ },
+
+ _parseURI: function(uri) {
+ let server, port, room;
+ let success = false;
+ try {
+ [,, server, port, room] = uri.match(IRC_SCHEMA_REGEX);
+ success = true;
+ } catch(e) {
+ let label = _("Failed to open link");
+ let n = new AppNotifications.MessageNotification(label,
+ 'dialog-error-symbolic');
+ this.notificationQueue.addNotification(n);
+ }
+
+ return [success, server, port, room];
+ },
+
+ _createAccount: function(id, server, port, callback) {
+ let params, name;
+
+ if (id) {
+ params = this._networksManager.getNetworkDetails(id);
+ name = this._networksManager.getNetworkName(id);
+ } else {
+ params = {
+ 'account': new GLib.Variant('s', GLib.get_user_name()),
+ 'server': new GLib.Variant('s', server),
+ 'port': new GLib.Variant('u', port ? port : 6667),
+ 'use-ssl': new GLib.Variant('b', (port == 6697)),
+ };
+ name = server;
+ }
+
+ let req = new Tp.AccountRequest({ account_manager: Tp.AccountManager.dup(),
+ connection_manager: 'idle',
+ protocol: 'irc',
+ display_name: name });
+ req.set_enabled(true);
+
+ if (id)
+ req.set_service(id);
+
+ for (let prop in params)
+ req.set_parameter(prop, params[prop]);
+
+ req.create_account_async(Lang.bind(this,
+ function(r, res) {
+ let account = req.create_account_finish(res);
+ callback(account);
+ }));
+ },
+
+ _updateUserListAction: function() {
+ let room = this.active_window.active_room;
+ let action = this.lookup_action('user-list');
+ action.enabled = room && room.type == Tp.HandleType.ROOM && room.channel;
+ },
+
+ _userListCreateHook: function(action) {
+ action.connect('notify::enabled', function() {
+ if (!action.enabled)
+ action.change_state(GLib.Variant.new('b', false));
+ });
+ action.enabled = false;
+ },
+
+ _onShowJoinDialog: function() {
+ this.active_window.showJoinRoomDialog();
+ },
+
+ _maybePresent: function(time) {
+ let [present, ] = Tp.user_action_time_should_present(time);
+
+ if (!this.active_window || present)
+ this.activate();
+ },
+
+ _onJoinRoom: function(action, parameter) {
+ let [accountPath, channelName, time] = parameter.deep_unpack();
+ this._maybePresent(time);
+ },
+
+ _onMessageUser: function(action, parameter) {
+ let [accountPath, contactName, message, time] = parameter.deep_unpack();
+ this._maybePresent(time);
+ },
+
+ _ensureRetryData: function(account) {
+ let data = this._retryData.get(account.object_path);
+ if (data)
+ return data;
+
+ let params = Connections.getAccountParams(account);
+ let server = params['server'];
+ let accountName = params['account'];
+ let port = params['port'];
+ debug('Failed to connect to %s with username %s'.format(server, accountName));
+
+ let accountServers = [];
+ if (this._networksManager.getAccountIsPredefined(account))
+ accountServers = this._networksManager.getNetworkServers(account.service);
+
+ data = {
+ retry: 0,
+ originalAccountName: accountName,
+ alternateServers: accountServers.filter(s => s.address != server ||
+ s.port != port)
+ };
+ this._retryData.set(account.object_path, data);
+ return data;
+ },
+
+ _restoreAccountName: function(account) {
+ let data = this._retryData.get(account.object_path);
+ if (!data || !data.retry || !data.originalAccountName)
+ return;
+
+ let params = { account: new GLib.Variant('s', data.originalAccountName) };
+ let asv = new GLib.Variant('a{sv}', params);
+ account.update_parameters_vardict_async(asv, [], null);
+ delete data.originalAccountName;
+ },
+
+ _retryWithParams: function(account, params) {
+ account.update_parameters_vardict_async(params, [], () => {
+ let presence = Tp.ConnectionPresenceType.AVAILABLE;
+ let msg = account.requested_status_message;
+ account.request_presence_async(presence, 'available', msg, null);
+ });
+ },
+
+ _retryNickRequest: function(account) {
+ let retryData = this._ensureRetryData(account);
+
+ if (retryData.retry++ >= MAX_RETRIES)
+ return false;
+
+ let oldParams = account.dup_parameters_vardict().deep_unpack();
+ let nick = oldParams['account'].deep_unpack();
+
+ debug('Retrying with nickname %s'.format(nick + '_'));
+ let params = { account: new GLib.Variant('s', nick + '_') };
+ this._retryWithParams(account, new GLib.Variant('a{sv}', params));
+ return true;
+ },
+
+ _retryServerRequest: function(account) {
+ let retryData = this._ensureRetryData(account);
+
+ let server = retryData.alternateServers.shift();
+ if (!server)
+ return false;
+
+ debug('Retrying with %s:%d'.format(server.address, server.port));
+ let params = { server: new GLib.Variant('s', server.address),
+ port: new GLib.Variant('u', server.port),
+ 'use-ssl': new GLib.Variant('b', server.ssl) };
+ this._retryWithParams(account, new GLib.Variant('a{sv}', params));
+ return true;
+ },
+
+ _onAccountStatusChanged: function(mon, account) {
+ let status = account.connection_status;
+
+ if (status == Tp.ConnectionStatus.CONNECTING)
+ return;
+
+ if (status == Tp.ConnectionStatus.DISCONNECTED) {
+ let reason = account.connection_status_reason;
+
+ if (reason == Tp.ConnectionStatusReason.NAME_IN_USE)
+ if (this._retryNickRequest(account))
+ return;
+
+ if (reason == Tp.ConnectionStatusReason.NETWORK_ERROR ||
+ reason == Tp.ConnectionStatusReason.NONE_SPECIFIED)
+ if (this._retryServerRequest(account))
+ return;
+
+ if (reason != Tp.ConnectionStatusReason.REQUESTED) {
+ let strReasons = Object.keys(Tp.ConnectionStatusReason);
+ debug('Account %s disconnected with reason %s'.format(
+ account.display_name, strReasons[reason]));
+ }
+ }
+
+ this._restoreAccountName(account);
+ },
+
+ _onLeaveCurrentRoom: function() {
+ let room = this.active_window.active_room;
+ if (!room)
+ return;
+ let action = this.lookup_action('leave-room');
+ action.activate(GLib.Variant.new('(ss)', [room.id, '']));
+ },
+
+ _onConnectAccount: function(action, parameter) {
+ let accountPath = parameter.deep_unpack();
+ let account = this._accountsMonitor.lookupAccount(accountPath);
+ if (account)
+ this._restoreAccountName(account);
+ this._retryData.delete(accountPath);
+ },
+
+ _onToggleAction: function(action) {
+ let state = action.get_state();
+ action.change_state(GLib.Variant.new('b', !state.get_boolean()));
+ },
+
+ _onRemoveConnection: function(action, parameter){
+ let accountPath = parameter.deep_unpack();
+ let account = this._accountsMonitor.lookupAccount(accountPath);
+ account.set_enabled_async(false, Lang.bind(this,
+ function() {
+ let label = _("%s removed.").format(account.display_name);
+ let n = new AppNotifications.UndoNotification(label);
+ this.notificationQueue.addNotification(n);
+
+ n.connect('closed', function() {
+ account.remove_async(function(a, res) {
+ a.remove_finish(res); // TODO: Check for errors
+ });
+ });
+ n.connect('undo', function() {
+ account.set_enabled_async(true, function(a, res) {
+ a.set_enabled_finish(res); // TODO: Check for errors
+ });
+ });
+ }));
+ },
+
+ _onEditConnection: function(action, parameter) {
+ let accountPath = parameter.deep_unpack();
+ let account = this._accountsMonitor.lookupAccount(accountPath);
+ let dialog = new Connections.ConnectionProperties(account);
+ dialog.transient_for = this.active_window;
+ dialog.connect('response', Lang.bind(this,
+ function(w, response) {
+ w.destroy();
+ }));
+ dialog.show();
+ },
+
+ _onStartClient: function() {
+ if (this._telepathyClient)
+ return;
+
+ let params = {
+ name: 'Polari',
+ account_manager: this._accountsMonitor.accountManager,
+ uniquify_name: false
+ };
+ this._telepathyClient = new TelepathyClient.TelepathyClient(params);
+ },
+
+ _onShowHelp: function() {
+ Utils.openURL('help:org.gnome.Polari', Gtk.get_current_event_time());
+ },
+
+ _onShowAbout: function() {
+ if (this._aboutDialog) {
+ this._aboutDialog.present();
+ return;
+ }
+ let aboutParams = {
+ authors: [
+ 'Florian Müllner <fmuellner gnome org>',
+ 'William Jon McCann <william jon mccann gmail com>',
+ 'Carlos Soriano <carlos soriano89 gmail com>',
+ 'Giovanni Campagna <gcampagna src gnome org>',
+ 'Carlos Garnacho <carlosg gnome org>',
+ 'Jonas Danielsson <jonas danielsson threetimestwo org>',
+ 'Bastian Ilsø <bastianilso gnome org>',
+ 'Kunaal Jain <kunaalus gmail com>',
+ 'Cody Welsh <codyw protonmail com>',
+ 'Isabella Ribeiro <belinhacbr gmail com>',
+ 'Jonas Danielsson <jonas threetimestwo org>',
+ 'Rares Visalom <rares visalom gmail com>',
+ 'Danny Mølgaard <moelgaard dmp gmail com>'
+ ],
+ artists: [
+ 'Sam Hewitt',
+ 'Jakub Steiner <jimmac gmail com>'
+ ],
+ translator_credits: _("translator-credits"),
+ comments: _("An Internet Relay Chat Client for GNOME"),
+ copyright: 'Copyright © 2013-2015 The Polari authors',
+ license_type: Gtk.License.GPL_2_0,
+ logo_icon_name: 'org.gnome.Polari',
+ version: pkg.version,
+ website_label: _("Learn more about Polari"),
+ website: 'https://wiki.gnome.org/Apps/Polari',
+
+ transient_for: this.active_window,
+ modal: true
+ };
+
+ this._aboutDialog = new Gtk.AboutDialog(aboutParams);
+ this._aboutDialog.show();
+ this._aboutDialog.connect('response', Lang.bind(this, function() {
+ this._aboutDialog.destroy();
+ this._aboutDialog = null;
+ }));
+ },
+
+ _onQuit: function() {
+ this.get_windows().reverse().forEach(w => { w.destroy(); });
+ }
+});
diff --git a/src/application.js b/src/application.js
index 934fd0f..c509a5f 100644
--- a/src/application.js
+++ b/src/application.js
@@ -288,23 +288,18 @@ var Application = new Lang.Class({
this.emit('prepare-shutdown');
});
- if (true /*first time startup*/) {
+ if (/*firstTimeStartup*/true) {
let setupDialog = new InitSetup.InitSetup({ application: this });
setupDialog.show_all();
- }
-/* let window = new MainWindow.MainWindow({ application: this });
- window.connect('destroy', () => {
- if (this._settings.get_boolean('run-in-background'))
- return;
- this.emit('prepare-shutdown');
- });
-
- window.connect('notify::active-room',
- () => { this.emit('room-focus-changed'); });
- window.connect('notify::is-active',
- () => { this.emit('room-focus-changed'); });
- window.show_all();*/
+ setupDialog.connect('destroy', () => {
+ window.connect('notify::active-room',
+ () => { this.emit('room-focus-changed'); });
+ window.connect('notify::is-active',
+ () => { this.emit('room-focus-changed'); });
+ window.show_all();
+ });
+ }
}
this.active_window.present();
},
diff --git a/src/initSetup.js b/src/initSetup.js
index 20d8f59..51a510e 100644
--- a/src/initSetup.js
+++ b/src/initSetup.js
@@ -8,6 +8,7 @@ const Tp = imports.gi.TelepathyGLib;
const Lang = imports.lang;
const NetworksManager = imports.networksManager;
+const Utils = imports.utils;
const CONFIGURE_TIMEOUT = 100; /* ms */
@@ -16,9 +17,6 @@ const SetupPage = {
ROOM: 1
};
-
-// SETUP WINDOW CONFIG
-
const InitSetup = new Lang.Class({
Name: 'InitSetup',
Extends: Gtk.Window,
@@ -30,13 +28,17 @@ const InitSetup = new Lang.Class({
'nextButton',
'doneButton',
'contentStack',
- 'connectionPageList' ],
+ 'connectionPageList',
+ 'serverRoomList',
+ 'nameEntry',
+ 'spinner' ],
_init: function(params) {
this.parent(params);
- // Allow css styling
+ this._currentAccount = null;
+
this._addApplicationStyle();
this._setupConnectionPage();
@@ -70,21 +72,26 @@ const InitSetup = new Lang.Class({
this.destroy();
}));
- this._connectionPageList.connect('row-selected', Lang.bind(this,
- function() {
+ this._connectionPageList.connect('account-created', Lang.bind(this,
+ function(w, account) {
this._setPage(SetupPage.ROOM);
+ this._currentAccount = account;
+ this._serverRoomList.setAccount(account);
}));
},
_setPage: function(page) {
let isConnection = page == SetupPage.CONNECTION;
+ if (!isConnection)
+ this._nameEntry.grab_focus();
+
this._contentStack.visible_child_name = isConnection ? 'connectionPage'
- : 'roomPage';
+ : 'roomPage';
this._leftHeaderStack.visible_child_name = isConnection ? 'cancelButton'
- : 'backButton';
+ : 'backButton';
this._rightHeaderStack.visible_child_name = isConnection ? 'nextButton'
- : 'doneButton';
+ : 'doneButton';
},
_setupRoomPage: function() {
@@ -92,15 +99,66 @@ const InitSetup = new Lang.Class({
function() {
this._setPage(SetupPage.CONNECTION);
}));
+
+ this._doneButton.connect('clicked', Lang.bind(this,
+ function() {
+ this._joinRoom();
+ this.destroy();
+ }));
+
+ this._doneButton.sensitive = false;
+
+ this._nameEntry.connect('changed',
+ Lang.bind(this, this._updateCanJoin));
+ this._serverRoomList.connect('notify::can-join',
+ Lang.bind(this, this._updateCanJoin));
+ this._serverRoomList.bind_property('loading', this._spinner, 'active',
+ GObject.BindingFlags.SYNC_CREATE);
+ },
+
+ get _page() {
+ if (this._contentStack.visible_child_name == 'roomPage')
+ return SetupPage.ROOM;
+ else
+ return SetupPage.MAIN;
+ },
+
+ _updateCanJoin: function() {
+ let sensitive = false;
+
+ if (this._page == SetupPage.ROOM)
+ sensitive = this._serverRoomList.can_join;
+
+ this._doneButton.sensitive = sensitive;
+ },
+
+ _joinRoom: function() {
+ this.hide();
+
+ let toJoinRooms = this._serverRoomList.selectedRooms;
+ if (this._nameEntry.get_text_length() > 0)
+ toJoinRooms.push(this._nameEntry.get_text());
+
+ let account = this._currentAccount;
+ toJoinRooms.forEach(function(room) {
+ if (room[0] != '#')
+ room = '#' + room;
+
+ let app = Gio.Application.get_default();
+ let action = app.lookup_action('join-room');
+ action.activate(GLib.Variant.new('(ssu)',
+ [ account.get_object_path(),
+ room,
+ Utils.getTpEventTime() ]));
+ });
}
});
-// CONNECTION LIST SETUP
const InitSetupConnectionsList = new Lang.Class({
Name: 'InitSetupConnectionsList',
Extends: Gtk.Frame,
- Signals: { 'row-selected' : {} },
+ Signals: { 'account-created': { param_types: [Tp.Account.$gtype] } },
_init: function(params) {
this.parent(params);
@@ -126,20 +184,33 @@ const InitSetupConnectionsList = new Lang.Class({
},
_networksChanged: function() {
-
- let networkList = this._networksManager.networks;
- for (let n of networkList) {
- if (this._networksManager.getNetworkIsFavorite(n.id)) {
- this._rows.set(n.id,
- new InitSetupConnectionRow({ id: n.id }));
- this._list.add(this._rows.get(n.id));
- }
+ for (let network of this._networksManager.favoriteNetworks) {
+ this._rows.set(network.id,
+ new InitSetupConnectionRow({ id: network.id }));
+ this._list.add(this._rows.get(network.id));
}
},
- _onRowActivated: function() {
- this.emit('row-selected');
- },
+ _onRowActivated: function(list, row) {
+ let name = this._networksManager.getNetworkName(row.id);
+ let req = new Tp.AccountRequest({ account_manager: Tp.AccountManager.dup(),
+ connection_manager: 'idle',
+ protocol: 'irc',
+ display_name: name });
+ req.set_service(row.id);
+ req.set_enabled(true);
+
+ let details = this._networksManager.getNetworkDetails(row.id);
+
+ for (let prop in details)
+ req.set_parameter(prop, details[prop]);
+
+ req.create_account_async(Lang.bind(this,
+ function(r, res) {
+ let account = req.create_account_finish(res);
+ this.emit('account-created', account);
+ }));
+ }
});
const InitSetupConnectionRow = new Lang.Class({
@@ -164,4 +235,8 @@ const InitSetupConnectionRow = new Lang.Class({
this.show_all();
},
+ get id() {
+ return this._id;
+ }
+
});
diff --git a/src/networksManager.js b/src/networksManager.js
index f69c8cc..5a0d3c5 100644
--- a/src/networksManager.js
+++ b/src/networksManager.js
@@ -70,6 +70,15 @@ var NetworksManager = new Lang.Class({
return this._networks;
},
+ get favoriteNetworks() {
+ let favNetworks = [ ];
+ for (let network of this._networks) {
+ if (this.getNetworkIsFavorite(network.id))
+ favNetworks.push(network);
+ }
+ return favNetworks;
+ },
+
getAccountIsPredefined: function(account) {
return account && this._networksById.get(account.service) != null;
},
diff --git a/src/serverRoomManager.js b/src/serverRoomManager.js
index e15c95d..1a89510 100644
--- a/src/serverRoomManager.js
+++ b/src/serverRoomManager.js
@@ -77,6 +77,7 @@ var _ServerRoomManager = new Lang.Class({
roomList.connect('got-room', Lang.bind(this, this._onGotRoom));
roomList.connect('notify::listing',
Lang.bind(this, this._onListingChanged));
+
this._roomLists.set(account, { list: roomList, rooms: [] });
},
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]