[polari/wip/raresv/nick-popover: 10/16] userPopover: Add user popover



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

    userPopover: Add user popover
    
    Right now, the UserPopover contains the nickname, the
    status (online/offline) and the UserDetails class.
    The UserPopover knows which user it is linked to by
    keeping a _nickname variable. The basenick is derived
    from the _nickname, the basenick being used to track the
    changes that the UserTracker signals about that specific
    basenick, thus correctly updating the status. The popover
    tracks the local and global status and also the changes
    that occur with the contacts associated to a basenick.

 data/org.gnome.Polari.data.gresource.xml |    1 +
 data/resources/user-popover.ui           |   40 ++++++++++++
 src/userList.js                          |  103 ++++++++++++++++++++++++++++++
 3 files changed, 144 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..9e9c164
--- /dev/null
+++ b/data/resources/user-popover.ui
@@ -0,0 +1,40 @@
+<?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="label" translatable="yes"></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 e335698..cfcb337 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 ChatroomManager = imports.chatroomManager;
 const Lang = imports.lang;
@@ -298,6 +299,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]