[polari/wip/raresv/nick-popover: 9/10] userTracker: Add notify-user actions



commit a581bbfc3b70fa3f6d1c41253b9438e186aa3a41
Author: raresv <rares visalom gmail com>
Date:   Tue Aug 2 22:00:42 2016 +0300

    userTracker: Add notify-user actions
    
    It is not uncommon that users need to chat with a particular person
    who is not connected at the time. As we are already tracking the
    online status of nicks, we can support this case by showing a
    notification when a particular user comes online. For that purpose,
    add a getNotifyActionName() method that returns the name of a stateful
    action that controls whether this feature is enabled for a particular
    basenick.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=760853

 src/userTracker.js |   73 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 71 insertions(+), 2 deletions(-)
---
diff --git a/src/userTracker.js b/src/userTracker.js
index 5d8faef..4343cf2 100644
--- a/src/userTracker.js
+++ b/src/userTracker.js
@@ -206,9 +206,15 @@ const UserTracker = new Lang.Class({
             this._runHandlers(room, member, status);
 
         let map = this._baseNickContacts;
-        if (this._pushMember(map, baseNick, member) == 1)
+        if (this._pushMember(map, baseNick, member) == 1) {
             this.emit("status-changed::" + baseNick, baseNick, status);
 
+            if (this._shouldNotifyNick(member.alias))
+                this._notifyNickAvailable(member, room);
+
+            this._setNotifyActionEnabled(member.alias, false);
+        }
+
         this.emit("contacts-changed::" + baseNick, member.alias);
     },
 
@@ -233,8 +239,12 @@ const UserTracker = new Lang.Class({
         let map = this._baseNickContacts;
         let [found, nContacts] = this._popMember(map, baseNick, member);
         if (found) {
-            if (nContacts == 0)
+            if (nContacts == 0) {
                 this.emit("status-changed::" + baseNick, member.alias, status);
+                this._setNotifyActionEnabled(member.alias, true);
+
+                this._app.withdraw_notification(this._getNotifyActionNameInternal(member.alias));
+            }
             this.emit("contacts-changed::" + baseNick, member.alias);
         }
     },
@@ -284,5 +294,64 @@ const UserTracker = new Lang.Class({
         if (!this._roomData.has(room))
             return;
         this._getRoomHandlers(room).delete(handlerID);
+    },
+
+    _notifyNickAvailable: function (member, room) {
+        let notification = new Gio.Notification();
+        notification.set_title(_("User is online"));
+        notification.set_body(_("User %s is now online.").format(member.alias));
+
+        let param = GLib.Variant.new('(ssu)',
+                                     [ this._account.get_object_path(),
+                                       room.channel_name,
+                                       Utils.getTpEventTime() ]);
+        notification.set_default_action_and_target('app.join-room', param);
+
+        this._app.send_notification(this._getNotifyActionNameInternal(member.alias), notification);
+
+        let baseNick = Polari.util_get_basenick(member.alias);
+    },
+
+    _shouldNotifyNick: function(nickName) {
+        let actionName = this._getNotifyActionNameInternal(nickName);
+        let state = this._app.get_action_state(actionName);
+        return state ? state.get_boolean()
+                     : false;
+    },
+
+    _setNotifyActionEnabled: function(nickName, enabled) {
+        let name = this._getNotifyActionNameInternal(nickName);
+        let action = this._app.lookup_action(name);
+        if (action)
+            action.enabled = enabled;
+    },
+
+    _getNotifyActionNameInternal: function(nickName) {
+        return 'notify-user-' +
+               this._account.get_path_suffix() + '-' +
+               Polari.util_get_basenick(nickName);
+    },
+
+    getNotifyActionName: function(nickName) {
+        let name = this._getNotifyActionNameInternal(nickName);
+
+        if (!this._app.lookup_action(name)) {
+            let status = this.getNickStatus(nickName);
+            let enabled = status == Tp.ConnectionPresenceType.OFFLINE;
+
+            let state = new GLib.Variant('b', false);
+            let action = new Gio.SimpleAction({ name: name,
+                                                enabled: enabled,
+                                                state: state });
+
+            action.connect('notify::enabled', () => {
+                if (!action.enabled)
+                    action.change_state(GLib.Variant.new('b', false));
+            });
+
+            this._app.add_action(action);
+        }
+
+        return 'app.' + name;
     }
 });


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