[polari/wip/raresv/userTrackerAndPopoversRebase: 22/24] userPopover: notifyButton is now a toggleButton, use watchUser() in order to track status changes fo



commit 07d454c184da62e4b18e2d4eeb5cac0ccb9f1597
Author: raresv <rares visalom gmail com>
Date:   Fri Aug 5 16:58:40 2016 +0300

    userPopover: notifyButton is now a toggleButton, use watchUser() in order to track status changes for the 
given basenick, replace getBestMatchingContact with getBestMatchingContactInRoom, use the notification logic 
that was moved from the chatroomManager to the userTracker.
    
    userPopover: add the 'offline in another room' status and it is updated whenever the global status 
changes. Both callbacks are connected in the setter for the nickname property (this might be a bit odd, maybe 
find another place to put those).
    userPopover: update notifyButton according to the global status of a user plus some cleaning up.
    
    userPopover: bind the active property of the notifyButton to the isUserWatched property of the 
userDetails in order to show the notifyLabel whenever the notifyButton is pressed. Disconnect 
contactsChangedSignal. Replace getBestMatchingContactInRoom with lookupContact.
    
    userPopover: update the active property of the notifyButton based on the new 
notification-emitted::basenick signal that the userTracker emits. Add _onNotificationEmitted method (will be 
removed in the future). We do this so that the popover can unset the toggled notifyButton.
    
    userPopover: moved the UserPopover widgets into user-popover.ui
    
    userPopover: bind the sensitive and visible properties of the notifyButton. Bind the active property of 
the notifyButton to the notifications-enabled property of the userDetails. Remove _onNotifyButtonClicked and 
_updateNotifyButton since the whole logic will be replaced with GActions.
    
    userPopover: bind the notifyButton sensitivity to its visible property. Then disconnect signals when not 
needed anymore. Remove _onNotificationEmitted handler for the notification-emitted userTracker signal that 
was removed.
    
    userPopover: nickLabel has ellipsize and max-width-chars set.
    
    userPopover: use <small> markup for the status label and make it translatable. (will be replaced with 
string formats)
    
    userPopover: Only use IDs for widgets we access
    
    userPopover: replace watchUser() with watchRoomStatus().
    
    userPopover: check if signal id is greater than 0, just checking its existance is not enough for 
consistency.
    
    userPopover: add signal ids and disconnect them upon changing the nickname.
    
    userPopover: global status change signal detail is now the basenick, not the nickname.
    
    userPopover: replace nickName with baseNick.
    
    userPopover: Comment on the popover code as well
    
    userPopover: minor ui adjustment and only use referenced children.
    
    userPopover: vertically center the notifyButton.
    
    userPopover: all widgets in the UserPopover ui are marked as visible in order to reveal them by calling 
UserPopover.show(). userPopover: the _setBasenick() method is added in order to keep track of the basenick 
and disconnect connected events upon changing the basenick, but before connecting new ones. userPopover: 
refactor _updateContents() to _updateStatusLabel(), this fixes the 'available in another room' status that 
would appear when it shouldn't.
    
    userPopover: moved the bindings of the notifyButton
    to the template file.
    
    userPopover: bind the expanded property of the UserDetails class
    to its visible property, and do that in the ui file. The reason
    for this binding is that we want the UserDetails to update
    itself every time the popover is opened. If the expanded property
    is always true, then the UserDetails will never get updated.
    
    userPopover: set a fixed height of the UserPopover using the
    height-request property and set the label of the fullnameLabel
    to empty whenever it needs to be hidden. We cannod use its
    visible property, as the space taken by it would be squashed
    in that case
    
    userPopover: removed the old css class that used to set the height of the popover status label.
    userPopover: use the <small> markup for the status label.

 data/org.gnome.Polari.data.gresource.xml |    1 +
 data/resources/application.css           |    4 -
 data/resources/user-popover.ui           |   77 ++++++++++++++++
 src/chatView.js                          |    2 -
 src/userList.js                          |  144 ++++++++++++++----------------
 5 files changed, 144 insertions(+), 84 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/application.css b/data/resources/application.css
index 8968630..7a11efd 100644
--- a/data/resources/application.css
+++ b/data/resources/application.css
@@ -142,7 +142,3 @@
 
 /* the following adds a border on top of the inputbar when users scroll up */
 .polari-chat-view > undershoot.bottom { border-bottom: 1px solid @borders; }
-
-.nick-popover-status {
-    font-size: 10px;
-}
diff --git a/data/resources/user-popover.ui b/data/resources/user-popover.ui
new file mode 100644
index 0000000..63e91e4
--- /dev/null
+++ b/data/resources/user-popover.ui
@@ -0,0 +1,77 @@
+<?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>
+    <property name="height-request">220</property>
+    <child>
+      <object class="GtkBox">
+        <property name="orientation">vertical</property>
+        <property name="visible">True</property>
+        <child>
+          <object class="GtkBox">
+            <property name="orientation">horizontal</property>
+            <property name="visible">True</property>
+            <property name="halign">fill</property>
+            <property name="margin">9</property>
+            <child>
+              <object class="GtkBox">
+                <property name="orientation">vertical</property>
+                <property name="visible">True</property>
+                <property name="halign">fill</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>
+              </object>
+            </child>
+            <child>
+              <object class="GtkToggleButton" id="notifyButton">
+                <property name="hexpand">True</property>
+                <property name="halign">end</property>
+                <property name="valign">center</property>
+                <property name="visible">True</property>
+                <property name="visible" bind-source="notifyButton"
+                          bind-property="sensitive"
+                          bind-flags="sync-create"/>
+                <child>
+                  <object class="GtkImage">
+                    <property name="icon-name">alarm-symbolic</property>
+                    <property name="visible">True</property>
+                    <property name="halign">center</property>
+                    <property name="visible">True</property>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="Gjs_UserDetails" id="userDetails">
+            <property name="visible">True</property>
+            <property name="notifications-enabled" bind-source="notifyButton"
+                      bind-property="active"
+                      bind-flags="sync-create"/>
+            <property name="expanded" bind-source="Gjs_UserPopover"
+                      bind-property="visible"
+                      bind-flags="sync-create"/>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/src/chatView.js b/src/chatView.js
index 4e7bddd..06ffc1c 100644
--- a/src/chatView.js
+++ b/src/chatView.js
@@ -1226,8 +1226,6 @@ const ChatView = new Lang.Class({
     },
 
     _onStatusChangedCallback: function(nick, status) {
-        log("Nick " + nick + " has local status " + status);
-
         let nickTagName = this._getNickTagName(nick);
         let nickTag = this._lookupTag(nickTagName);
 
diff --git a/src/userList.js b/src/userList.js
index e8cd245..5f96329 100644
--- a/src/userList.js
+++ b/src/userList.js
@@ -288,6 +288,7 @@ const UserDetails = new Lang.Class({
         this._lastHeader.show();
 
         this._userIcon.visible = false;
+        this._fullnameLabel.label = "";
 
         this._revealDetails();
     },
@@ -331,6 +332,11 @@ 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',
+                       'notifyButton',
+                       'userDetails'],
 
     _init: function(params) {
         this._room = params.room;
@@ -341,109 +347,91 @@ const UserPopover = new Lang.Class({
 
         this.parent(params);
 
-        this._chatroomManager = ChatroomManager.getDefault();
+        this._statusLabel.set_state_flags(Gtk.StateFlags.LINK, false);
 
-        this._nickLabel = new Gtk.Label({ halign: Gtk.Align.START, margin_top: 0 });
-        this._statusLabel = new Gtk.Label({ halign: Gtk.Align.START, margin_bottom: 0 });
+        this._app = Gio.Application.get_default();
 
-        this._headervbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL, halign: Gtk.Align.FILL });
-        this._headervbox.add(this._nickLabel);
-        this._headervbox.add(this._statusLabel);
+        this._roomStatusChangedId = 0;
+        this._globalStatusChangedId = 0;
+        this._contactsChangedId = 0;
 
-        this._hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, halign: Gtk.Align.FILL, margin: 
9 });
-        this._hbox.add(this._headervbox);
-
-        this._notifyButton = new Gtk.Button({ image: new Gtk.Image({ icon_name: 'alarm-symbolic' }), halign: 
Gtk.Align.END, hexpand: true });
-        this._notifyButton.connect('clicked',
-                                    Lang.bind(this, this._onNotifyButtonClicked));
-        this._hbox.add(this._notifyButton);
+        this.connect('destroy', () => {
+            this.nickname = null;
+        });
 
+        this.show();
+    },
 
-        this._userDetails = new UserDetails();
-        this.bind_property('visible', this._userDetails, 'expanded', 0);
+    set nickname(nickname) {
+        if (this._nickname == nickname)
+            return;
 
-        let context = this._statusLabel.get_style_context();
-        context.add_class('nick-popover-status');
+        if (nickname == null)
+            return;
 
-        this._vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL });
-        this._vbox.add(this._hbox);
-        this._vbox.add(this._userDetails);
+        this._nickname = nickname;
+        this._nickLabel.label = this._nickname;
+        this._userDetails.nickname = nickname;
 
-        this.add(this._vbox);
+        let actionName = this._userTracker.getNotifyActionName(this._nickname);
+        this._notifyButton.action_name = actionName;
 
-        this._vbox.show_all();
+        this._setBasenick(Polari.util_get_basenick(nickname));
     },
 
-    set nickname(nickname) {
-        this._nickname = 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));
 
-        let baseNick = Polari.util_get_basenick(nickname);
+        if (this._globalStatusChangedId > 0)
+            this._userTracker.disconnect(this._globalStatusChangedId);
+        this._globalStatusChangedId = this._userTracker.connect("status-changed::" + basenick, 
Lang.bind(this, this._updateStatusLabel));
 
-        this._userTracker.connect("status-changed::" + baseNick, Lang.bind(this, this._onNickStatusChanged));
+        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._updateContents();
+        this._updateStatusLabel();
+        this._updateDetailsContact();
     },
 
     get nickname() {
         return this._nickname;
     },
 
-    _updateContents: function() {
-        let bestMatchingContact = this._userTracker.getBestMatchingContact(this._nickname);
+    _updateStatusLabel: function() {
+        let status = this._userTracker.getNickStatus(this._nickname);
+        let roomStatus = this._userTracker.getNickRoomStatus(this._nickname,
+                                                             this._room);
 
-        this._nickLabel.set_label(this._nickname);
-        this._statusLabel.set_label(bestMatchingContact ? "Online" : "Offline");
-
-        if (bestMatchingContact) {
-            this._userDetails.user = bestMatchingContact;
-
-            let context = this._statusLabel.get_style_context();
-            context.set_state(Gtk.StateFlags.LINK);
-            context.save();
-
-            this._statusLabel.sensitive = true;
-        }
-        else {
-            this._userDetails.clearPrevUserAndDetails();
-
-            this._statusLabel.sensitive = false;
-        }
-
-        this._updateNotifyButton();
+        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._userDetails.nickname = this._nickname;
+        this._statusLabel.sensitive = (status == Tp.ConnectionPresenceType.AVAILABLE);
     },
 
-    _onNotifyButtonClicked: function() {
-        if (!this._chatroomManager.isUserWatched(this._nickname, this._room.account.get_display_name())) {
-            this._chatroomManager.addToWatchlist(this._nickname, this._room.account.get_display_name());
-            this._updateNotifyButton();
-        }
-    },
+    _updateDetailsContact: function() {
+        this._userDetails.user = this._userTracker.lookupContact(this._nickname);
+     },
 
-    _updateNotifyButton: function() {
-        if (!this._chatroomManager.isUserWatched(this._nickname, this._room.account.get_display_name()))
-            if (this._user) {
-                this._notifyButton.visible = false;
-                this._notifyButton.sensitive = true;
-            }
-            else {
-                this._notifyButton.visible = true;
-                this._notifyButton.sensitive = true;
-            }
-        else
-            if (this._user) {
-                this._notifyButton.visible = false;
-                this._notifyButton.sensitive = true;
-            }
-            else {
-                this._notifyButton.visibile = true;
-                this._notifyButton.sensitive = false;
-            }
-    },
-
-    _onNickStatusChanged: function(tracker, nickName, status) {
-        this.user = this._userTracker.getBestMatchingContact(this._nickname);
+    _onNickStatusChanged: function(baseNick, status) {
+        this._updateStatusLabel();
     }
 });
 


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