[polari/wip/raresv/nick-popover: 27/32] userPopover: Add user popover



commit 58033bd6df5d6eb3480981854fb41f646f320c8c
Author: raresv <rares visalom gmail com>
Date:   Sat Aug 20 19:38:48 2016 +0300

    userPopover: Add user popover
    
    We add the UserPopover because we want to add a more
    convenient way of accessing the information of the
    UserList without actually locating the user inside
    a potentially long list. Moreover, the UserPopover
    will be able to provide details when the user is
    offline as well.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=760853

 data/org.gnome.Polari.data.gresource.xml |    1 +
 data/resources/user-popover.ui           |   39 +++++++++++
 src/userList.js                          |  103 ++++++++++++++++++++++++++++++
 3 files changed, 143 insertions(+), 0 deletions(-)
---
diff --git a/data/org.gnome.Polari.data.gresource.xml b/data/org.gnome.Polari.data.gresource.xml
index 65ee61b..1c4d3fc 100644
--- a/data/org.gnome.Polari.data.gresource.xml
+++ b/data/org.gnome.Polari.data.gresource.xml
@@ -13,5 +13,6 @@
     <file alias="ui/room-list-header.ui" preprocess="xml-stripblanks">resources/room-list-header.ui</file>
     <file alias="ui/room-list-row.ui" preprocess="xml-stripblanks">resources/room-list-row.ui</file>
     <file alias="ui/user-details.ui" preprocess="xml-stripblanks">resources/user-details.ui</file>
+    <file alias="ui/user-popover.ui" preprocess="xml-stripblanks">resources/user-popover.ui</file>
   </gresource>
 </gresources>
diff --git a/data/resources/user-popover.ui b/data/resources/user-popover.ui
new file mode 100644
index 0000000..adc2d76
--- /dev/null
+++ b/data/resources/user-popover.ui
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="Gjs_UserPopover" parent="GtkPopover">
+    <property name="hexpand">False</property>
+    <property name="width-request">280</property>
+    <child>
+      <object class="GtkBox">
+        <property name="orientation">vertical</property>
+        <property name="visible">True</property>
+        <child>
+          <object class="GtkLabel" id="nickLabel">
+            <property name="halign">start</property>
+            <property name="margin-top">0</property>
+            <property name="ellipsize">end</property>
+            <property name="max-width-chars">17</property>
+            <property name="visible">True</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkLabel" id="statusLabel">
+            <property name="halign">start</property>
+            <property name="margin-bottom">0</property>
+            <property name="use-markup">True</property>
+            <property name="visible">True</property>
+          </object>
+        </child>
+        <child>
+          <object class="Gjs_UserDetails" id="userDetails">
+            <property name="visible">True</property>
+            <!-- trigger details update on visibility changes -->
+            <property name="expanded" bind-source="Gjs_UserPopover"
+                      bind-property="visible"
+                      bind-flags="sync-create"/>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/src/userList.js b/src/userList.js
index af5ee00..fd89873 100644
--- a/src/userList.js
+++ b/src/userList.js
@@ -5,6 +5,7 @@ const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
 const Pango = imports.gi.Pango;
 const Tp = imports.gi.TelepathyGLib;
+const Polari = imports.gi.Polari;
 
 const Lang = imports.lang;
 const Mainloop = imports.mainloop;
@@ -301,6 +302,108 @@ const UserDetails = new Lang.Class({
     }
 });
 
+const UserPopover = new Lang.Class({
+    Name: 'UserPopover',
+    Extends: Gtk.Popover,
+    Template: 'resource:///org/gnome/Polari/ui/user-popover.ui',
+    InternalChildren: ['nickLabel',
+                       'statusLabel',
+                       'userDetails'],
+
+    _init: function(params) {
+        this._room = params.room;
+        delete params.room;
+
+        this._userTracker = params.userTracker;
+        delete params.userTracker;
+
+        this.parent(params);
+
+        this._statusLabel.set_state_flags(Gtk.StateFlags.LINK, false);
+
+        this._app = Gio.Application.get_default();
+
+        this._roomStatusChangedId = 0;
+        this._globalStatusChangedId = 0;
+        this._contactsChangedId = 0;
+
+        this.connect('destroy', () => {
+            this.nickname = null;
+        });
+
+        this.show();
+    },
+
+    set nickname(nickname) {
+        if (this._nickname == nickname)
+            return;
+
+        if (nickname == null)
+            return;
+
+        this._nickname = nickname;
+        this._nickLabel.label = this._nickname;
+        this._userDetails.nickname = nickname;
+
+        this._setBasenick(Polari.util_get_basenick(nickname));
+    },
+
+    _setBasenick: function(basenick) {
+        if (this._basenick == basenick)
+            return;
+
+        this._basenick = basenick;
+
+        if (this._roomStatusChangedId > 0)
+            this._userTracker.unwatchRoomStatus(this._room, this._roomStatusChangedId);
+        this._roomStatusChangedId =
+            this._userTracker.watchRoomStatus(this._room, this._basenick,
+                                        Lang.bind(this, this._onNickStatusChanged));
+
+        if (this._globalStatusChangedId > 0)
+            this._userTracker.disconnect(this._globalStatusChangedId);
+        this._globalStatusChangedId = this._userTracker.connect("status-changed::" + basenick, 
Lang.bind(this, this._updateStatusLabel));
+
+        if (this._contactsChangedId > 0)
+            this._userTracker.disconnect(this._contactsChangedId);
+        this._contactsChangedId = this._userTracker.connect("contacts-changed::" + basenick, () => {
+            this._userDetails.user = this._userTracker.lookupContact(this._nickname);
+        });
+
+        this._updateStatusLabel();
+        this._updateDetailsContact();
+    },
+
+    get nickname() {
+        return this._nickname;
+    },
+
+    _updateStatusLabel: function() {
+        let status = this._userTracker.getNickStatus(this._nickname);
+        let roomStatus = this._userTracker.getNickRoomStatus(this._nickname,
+                                                             this._room);
+
+        let label;
+        if (status != roomStatus)
+            label = _("Available in another room.");
+        else if (status == Tp.ConnectionPresenceType.AVAILABLE)
+            label = _("Online");
+        else
+            label = _("Offline");
+        this._statusLabel.label = label;
+
+        this._statusLabel.sensitive = (status == Tp.ConnectionPresenceType.AVAILABLE);
+    },
+
+    _updateDetailsContact: function() {
+        this._userDetails.user = this._userTracker.lookupContact(this._nickname);
+     },
+
+    _onNickStatusChanged: function(baseNick, status) {
+        this._updateStatusLabel();
+    }
+});
+
 const UserListRow = new Lang.Class({
     Name: 'UserListRow',
     Extends: Gtk.ListBoxRow,


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