[polari] joinDialog: Move handling of join dialog into its own class



commit c9b1f363ec3176826107943f1a96f729cb8bdbe5
Author: Florian Müllner <florian muellner gmail com>
Date:   Mon Jul 22 18:58:13 2013 +0200

    joinDialog: Move handling of join dialog into its own class

 data/resources/join-room-dialog.ui |    1 -
 src/Makefile.am                    |    1 +
 src/joinDialog.js                  |  132 ++++++++++++++++++++++++++++++++++++
 src/mainWindow.js                  |   44 ++----------
 src/telepathyClient.js             |   45 ------------
 5 files changed, 141 insertions(+), 82 deletions(-)
---
diff --git a/data/resources/join-room-dialog.ui b/data/resources/join-room-dialog.ui
index 46356fd..f4c4b4c 100644
--- a/data/resources/join-room-dialog.ui
+++ b/data/resources/join-room-dialog.ui
@@ -199,7 +199,6 @@
       </object>
     </child>
     <action-widgets>
-      <action-widget response="-5">join_button</action-widget>
       <action-widget response="-6">cancel_button</action-widget>
     </action-widgets>
   </object>
diff --git a/src/Makefile.am b/src/Makefile.am
index ca275d2..ff8e0a3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -33,6 +33,7 @@ dist_js_DATA = \
        chatView.js \
        connections.js \
        ircParser.js \
+       joinDialog.js \
        main.js \
        mainWindow.js \
        roomList.js \
diff --git a/src/joinDialog.js b/src/joinDialog.js
new file mode 100644
index 0000000..e32baa7
--- /dev/null
+++ b/src/joinDialog.js
@@ -0,0 +1,132 @@
+const Gdk = imports.gi.Gdk;
+const GLib = imports.gi.GLib;
+const Gtk = imports.gi.Gtk;
+const Tp = imports.gi.TelepathyGLib;
+
+const Lang = imports.lang;
+
+const MAX_RETRIES = 3;
+
+const TP_ERROR_PREFIX = 'org.freedesktop.Telepathy.Error.'
+const TP_ERROR_ALREADY_CONNECTED = TP_ERROR_PREFIX + 'AlreadyConnected';
+
+const JoinDialog = new Lang.Class({
+    Name: 'JoinDialog',
+
+    _init: function() {
+        this._accountManager = Tp.AccountManager.dup();
+        this._accountManager.prepare_async(null,
+                                           Lang.bind(this, this._onPrepared));
+        this._accounts = {};
+
+        let builder = new Gtk.Builder();
+        builder.add_from_resource('/org/gnome/polari/join-room-dialog.ui');
+
+        this.widget = builder.get_object('join_room_dialog');
+
+        this._connectionCombo = builder.get_object('connection_combo');
+        this._connectionCombo.sensitive = false;
+
+        this._joinButton = builder.get_object('join_button');
+        this._joinButton.connect('clicked',
+                                 Lang.bind(this, this._onJoinClicked));
+        this._joinButton.sensitive = false;
+
+        this._nameEntry = builder.get_object('name_entry');
+        this._nameEntry.connect('changed',
+                                Lang.bind(this, this._updateCanConfirm));
+    },
+
+    _onPrepared: function() {
+        this._accountManager.dup_valid_accounts().forEach(Lang.bind(this,
+            function(a) {
+                if (!a.enabled || a.protocol_name != 'irc')
+                    return;
+                this._accounts[a.display_name] = a;
+            }));
+        let names = Object.keys(this._accounts).sort(
+            function(a, b) {
+                // TODO: figure out combo box sorting
+                return (a < b) ? -1 : ((a > b) ? 1 : 0);
+            });
+        for (let i = 0; i < names.length; i++)
+            this._connectionCombo.append_text(names[i]);
+        this._connectionCombo.set_active(0);
+        this._connectionCombo.sensitive = names.length > 1;
+        this._updateCanConfirm();
+    },
+
+    _onJoinClicked: function() {
+        this.widget.hide();
+
+        let selected = this._connectionCombo.get_active_text();
+        let account = this._accounts[selected];
+
+        let room = this._nameEntry.get_text();
+        if (room[0] != '#')
+            room = '#' + room;
+
+        this._requestData = { account: account, target: room };
+        this._originalNick = account.nickname;
+        this._retry = 0;
+
+        this._ensureChannel();
+    },
+
+    _updateAccountName: function(account, name, callback) {
+        let sv = { account: GLib.Variant.new('s', name) };
+        let asv = GLib.Variant.new('a{sv}', sv);
+        account.update_parameters_vardict_async(asv, [], callback);
+    },
+
+    _ensureChannel: function() {
+        let account = this._requestData.account;
+
+        let req = Tp.AccountChannelRequest.new_text(account, Gdk.CURRENT_TIME);
+        req.set_target_id(Tp.HandleType.ROOM, this._requestData.target);
+        req.set_delegate_to_preferred_handler(true);
+        let preferredHandler = Tp.CLIENT_BUS_NAME_BASE + 'Polari';
+        req.ensure_channel_async(preferredHandler, null,
+                                 Lang.bind(this, this._onEnsureChannel));
+    },
+
+    _onEnsureChannel: function(req, res) {
+        let account = req.account;
+
+        try {
+            req.ensure_channel_finish(res);
+        } catch (e if e.matches(Tp.Error, Tp.Error.DISCONNECTED)) {
+            let [error,] = account.dup_detailed_error_vardict();
+            if (error != TP_ERROR_ALREADY_CONNECTED)
+                throw(e);
+
+            if (++this._retry >= MAX_RETRIES) {
+                log('Exceeded maximum number of retries, giving up');
+                return;
+            }
+
+            // Try again with a different nick
+            let params = account.dup_parameters_vardict().deep_unpack();
+            let oldNick = params['account'].deep_unpack();
+            let nick = oldNick + '_';
+            this._updateAccountName(account, nick, Lang.bind(this,
+                function() {
+                    this._ensureChannel();
+                }));
+            return;
+        } catch (e) {
+            logError(e, 'Failed to ensure channel');
+        }
+
+        if (this._retry > 0)
+            this._updateAccountName(account, this._originalNick, null);
+
+        this.widget.response(Gtk.ResponseType.OK);
+    },
+
+    _updateCanConfirm: function() {
+            let sensitive = this._connectionCombo.get_active() > -1  &&
+                            this._nameEntry.get_text_length() > 0;
+            this._joinButton.sensitive = sensitive;
+    }
+});
diff --git a/src/mainWindow.js b/src/mainWindow.js
index ddf9489..dc8d836 100644
--- a/src/mainWindow.js
+++ b/src/mainWindow.js
@@ -5,6 +5,7 @@ const AppNotifications = imports.appNotifications;
 const ChatroomManager = imports.chatroomManager;
 const ChatView = imports.chatView;
 const IrcParser = imports.ircParser;
+const JoinDialog = imports.joinDialog;
 const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 const RoomList = imports.roomList;
@@ -181,42 +182,13 @@ const MainWindow = new Lang.Class({
     },
 
     showJoinRoomDialog: function() {
-        let builder = new Gtk.Builder();
-        builder.add_from_resource('/org/gnome/polari/join-room-dialog.ui');
-
-        let dialog = builder.get_object('join_room_dialog');
-        dialog.set_transient_for(this.window);
-
-        let connectionCombo = builder.get_object('connection_combo');
-
-        let accounts = this._tpClient.getAccounts();
-        let names = accounts.map(function(a) { return a.display_name; });
-        for (let i = 0; i < names.length; i++)
-            connectionCombo.append_text(names[i]);
-        connectionCombo.set_active(0);
-        connectionCombo.sensitive = accounts.length > 1;
-
-        let joinButton = builder.get_object('join_button');
-        joinButton.sensitive = false;
-
-        let nameEntry = builder.get_object('name_entry');
-        nameEntry.connect('changed', function() {
-            joinButton.sensitive = accounts.length > 0 &&
-                                   nameEntry.get_text_length() > 0;
-        });
-        dialog.show();
-        dialog.connect('response', Lang.bind(this, function(dialog, response) {
-            if (response == Gtk.ResponseType.OK) {
-                let account = accounts[connectionCombo.get_active()];
-
-                let room = nameEntry.get_text();
-                if (room[0] != '#')
-                    room = '#' + room;
-
-                this._tpClient.joinRoom(account, room);
-            }
-            dialog.destroy();
-        }));
+        let dialog = new JoinDialog.JoinDialog();
+        dialog.widget.transient_for = this.window;
+        dialog.widget.show();
+        dialog.widget.connect('response',
+            function(widget) {
+                widget.destroy();
+            });
     },
 
     _updateTitlebar: function() {
diff --git a/src/telepathyClient.js b/src/telepathyClient.js
index 231c14b..204eea3 100644
--- a/src/telepathyClient.js
+++ b/src/telepathyClient.js
@@ -7,9 +7,6 @@ const ChatroomManager = imports.chatroomManager;
 const Lang = imports.lang;
 const Signals = imports.signals;
 
-const TP_ERROR_PREFIX = 'org.freedesktop.Telepathy.Error.'
-const TP_ERROR_ALREADY_CONNECTED = TP_ERROR_PREFIX + 'AlreadyConnected';
-
 const TelepathyClient = new Lang.Class({
     Name: 'TelepathyClient',
 
@@ -79,48 +76,6 @@ const TelepathyClient = new Lang.Class({
             }));
     },
 
-    _updateAccountName: function(account, name, callback) {
-        let params = GLib.Variant.new('a{sv}', { account: GLib.Variant.new('s', name) });
-        account.update_parameters_vardict_async(params, [], callback);
-    },
-
-    joinRoom: function(account, name) {
-        let channelRequest = Tp.AccountChannelRequest.new_text(account,
-                                                               Gdk.CURRENT_TIME);
-        channelRequest.set_target_id(Tp.HandleType.ROOM, name);
-        channelRequest.set_delegate_to_preferred_handler(true);
-        let preferredHandler = Tp.CLIENT_BUS_NAME_BASE + 'Polari';
-        channelRequest.ensure_channel_async(preferredHandler, null,
-            Lang.bind(this, function(req, res) {
-                try {
-                    req.ensure_channel_finish(res);
-
-                    if (account._originalNick)
-                        this._updateAccountName(account, account._originalNick,
-                            function() {
-                                delete account._originalNick;
-                            });
-                } catch (e if e.matches(Tp.Error, Tp.Error.DISCONNECTED)) {
-                    let [error,] = account.dup_detailed_error_vardict();
-                    if (error != TP_ERROR_ALREADY_CONNECTED)
-                        throw(e);
-
-                    // Try again with a different nick
-                    if (!account._originalNick)
-                        account._originalNick = account.nickname;
-                    let params = account.dup_parameters_vardict().deep_unpack();
-                    let oldNick = params['account'].deep_unpack();
-                    let nick = oldNick + '_';
-                    this._updateAccountName(account, nick, Lang.bind(this,
-                        function() {
-                            this.joinRoom(account, name);
-                        }));
-                } catch (e) {
-                    logError(e, "Failed to create channel");
-                }
-            }));
-    },
-
     _observeChannels: function(observer, account, conn, channels, op, requests, context) {
         if (conn.protocol_name != 'irc') {
             let message = 'Not implementing non-IRC protocols';


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]