[polari/wip/raresv/nick-popover: 14/16] userTracker: Add notify actions



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

    userTracker: Add notify actions
    
    In order to be able to show a notification whenever a
    watched user comes online, we will use a GAction, as it
    makes the whole process a lot cleaner. Each basenick
    has an associated GAction, thus making the notifications
    basenick-specific (just like all the status tracking that
    is done) on that account (network). Whether or not the
    action is enabled is decided by the basenick's status.
    Whether or not a notification should be emitted is decided
    by the state of the GAction.

 src/userTracker.js |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 70 insertions(+), 2 deletions(-)
---
diff --git a/src/userTracker.js b/src/userTracker.js
index a9d0db2..dc52905 100644
--- a/src/userTracker.js
+++ b/src/userTracker.js
@@ -76,6 +76,7 @@ const UserTracker = new Lang.Class({
         this._baseNickContacts = new Map();
         this._roomData = new Map();
         this._handlerCounter = 0;
+        this._app = Gio.Application.get_default();
 
         this._chatroomManager = ChatroomManager.getDefault();
         this._chatroomManager.connect('room-added', Lang.bind(this, this._onRoomAdded));
@@ -196,9 +197,15 @@ const UserTracker = new Lang.Class({
         let status = Tp.ConnectionPresenceType.AVAILABLE;
 
         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);
+        }
+
         let roomMap = this._getRoomContacts(room);
         if (this._pushMember(roomMap, baseNick, member) == 1)
             this._runHandlers(room, member, status);
@@ -222,8 +229,10 @@ 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.emit("contacts-changed::" + baseNick, member.alias);
         }
 
@@ -281,5 +290,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]