[polari/wip/fmuellner/room-list: 18/23] serverRoomManager: Add ServerRoomList widget



commit 84f96b2bfb93665bf6982febcba0d440f38f11ac
Author: Isabella Ribeiro <belinhacbr gmail com>
Date:   Wed Mar 23 21:54:00 2016 -0400

    serverRoomManager: Add ServerRoomList widget
    
    Now that we have a room list cache, we want to present the lists in
    the UI, so add a list widget that'll allow users to browse and select
    existing rooms in the join dialog.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=763200

 src/serverRoomManager.js |  158 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 158 insertions(+), 0 deletions(-)
---
diff --git a/src/serverRoomManager.js b/src/serverRoomManager.js
index 6817f98..edcc767 100644
--- a/src/serverRoomManager.js
+++ b/src/serverRoomManager.js
@@ -1,4 +1,6 @@
 const GLib = imports.gi.GLib;
+const GObject = imports.gi.GObject;
+const Gtk = imports.gi.Gtk;
 const Tp = imports.gi.TelepathyGLib;
 
 const AccountsMonitor = imports.accountsMonitor;
@@ -90,3 +92,159 @@ const _ServerRoomManager = new Lang.Class({
     }
 });
 Signals.addSignalMethods(_ServerRoomManager.prototype);
+
+const ServerRoomList = new Lang.Class({
+    Name: 'ServerRoomList',
+    Extends: Gtk.ScrolledWindow,
+    Properties: { 'can-join': GObject.ParamSpec.boolean('can-join',
+                                                        'can-join',
+                                                        'can-join',
+                                                        GObject.ParamFlags.READABLE,
+                                                        false),
+                  'loading': GObject.ParamSpec.boolean('loading',
+                                                       'loading',
+                                                       'loading',
+                                                       GObject.ParamFlags.READABLE,
+                                                       false)
+    },
+
+    _init: function(params) {
+        this._account = null;
+
+        this.parent(params);
+
+        this.connect('destroy', () => {
+            this.setAccount(null);
+        });
+
+        this._list = new Gtk.ListBox({ visible: true });
+        this._list.set_header_func(Lang.bind(this, this._updateHeader));
+        this._list.connect('row-activated',
+                               Lang.bind(this, this._onRowActivated));
+        this.add(this._list);
+
+        this._manager = getDefault();
+        this._manager.connect('loading-changed',
+                              Lang.bind(this, this._onLoadingChanged));
+    },
+
+    get can_join() {
+        return this._list.get_children().some(r => r.checked);
+    },
+
+    get loading() {
+        return this._account && this._manager.isLoading(this._account);
+    },
+
+    _onRowActivated: function(list, row) {
+        row.activate();
+    },
+
+    get selectedRooms() {
+        let selectedRows = this._list.get_children().filter(r => r.checked);
+        return selectedRows.map(r => r.info.get_name());
+    },
+
+    setAccount: function(account) {
+        if (this._account == account)
+            return;
+
+        this._account = account;
+        this._onLoadingChanged(this._manager, account);
+    },
+
+    _updateHeader: function(row, before) {
+        if (!before)
+            row.set_header(null);
+        else if (!row.get_header())
+            row.set_header(new Gtk.Separator());
+    },
+
+    _onLoadingChanged: function(mgr, account) {
+        if (account != this._account)
+            return;
+
+        this.notify('loading');
+
+        if (this.loading)
+            return;
+
+        this._list.foreach(function(w) { w.destroy(); });
+
+        if (!account)
+            return;
+
+        let roomInfos = this._manager.getRoomInfos(account);
+        roomInfos.sort((info1, info2) => {
+            let count1 = info1.get_members_count(null);
+            let count2 = info2.get_members_count(null);
+            if (count1 != count2)
+                return count2 - count1;
+            return info1.get_name().localeCompare(info2.get_name());
+        });
+        roomInfos.forEach(roomInfo => {
+            let row = new ServerRoomRow({ info: roomInfo });
+            row.connect('notify::checked', () => { this.notify('can-join'); });
+            this._list.add(row);
+        });
+    }
+});
+
+const ServerRoomRow = new Lang.Class({
+    Name: 'ServerRoomRow',
+    Extends: Gtk.ListBoxRow,
+    Properties: { 'checked': GObject.ParamSpec.boolean('checked',
+                                                       'checked',
+                                                       'checked',
+                                                       GObject.ParamFlags.READABLE,
+                                                       false),
+    },
+
+    _init: function(params) {
+        if (!params || !params.info)
+            throw new Error('No info in parameters');
+
+        this._info = params.info;
+        delete params.info;
+
+        this.parent(params);
+
+        let name = this._info.get_name();
+        if (name[0] == '#')
+           name = name.substr(1, name.length);
+
+        let box = new Gtk.Box({ spacing: 12, margin: 12 });
+        this.add(box);
+
+        this._checkbox = new Gtk.CheckButton();
+        this._checkbox.connect('toggled', Lang.bind(this,
+            function() {
+                this.notify('checked');
+            }));
+
+        box.add(this._checkbox);
+
+        box.add(new Gtk.Label({ label: name,
+                                hexpand: true,
+                                halign: Gtk.Align.START }));
+
+        let count = this._info.get_members_count(null);
+        let label = new Gtk.Label({ label: "%d".format(count) });
+        label.get_style_context().add_class('dim-label');
+        box.add(label);
+
+        this.show_all();
+    },
+
+    get info() {
+        return this._info;
+    },
+
+    get checked() {
+        return this._checkbox.active;
+    },
+
+    vfunc_activate: function() {
+        this._checkbox.activate();
+    }
+});


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