[polari/wip/bastianilso/status-hiding: 2/2] chatView: Compress status messages on idle channels



commit 02af093cee149824dde9f53bdd3688f8b10f4bf1
Author: Bastian Ilsø <bastianilso src gnome org>
Date:   Wed Jun 24 15:28:34 2015 +0200

    chatView: Compress status messages on idle channels
    
    if channel is idle (no activity in 30 minutes), then
    emit compressed status messages. Clicking on the compressed
    status message will uncompress it (useful, should the user
    be waiting for someone specific to chat with).
    
    https://bugzilla.gnome.org/show_bug.cgi?id=711542

 src/chatView.js |  113 ++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 96 insertions(+), 17 deletions(-)
---
diff --git a/src/chatView.js b/src/chatView.js
index a075e99..e97315e 100644
--- a/src/chatView.js
+++ b/src/chatView.js
@@ -103,6 +103,12 @@ const ChatView = new Lang.Class({
         this._needsIndicator = true;
         this._pending = {};
         this._pendingLogs = [];
+        this._statusCount = [
+            { name: 'left',
+              count: 0 },
+            { name: 'joined',
+              count: 0 },
+            ];
 
         let isRoom = room.type == Tp.HandleType.ROOM;
         let target = new Tpl.Entity({ type: isRoom ? Tpl.EntityType.ROOM
@@ -601,7 +607,7 @@ const ChatView = new Lang.Class({
             { name: 'message-received',
               handler: Lang.bind(this, this._onMessageReceived) },
             { name: 'message-sent',
-              handler: Lang.bind(this, this._insertTpMessage) },
+              handler: Lang.bind(this, this._onMessageSent) },
             { name: 'pending-message-removed',
               handler: Lang.bind(this, this._pendingMessageRemoved) }
         ];
@@ -638,49 +644,82 @@ const ChatView = new Lang.Class({
     },
 
     _onMemberDisconnected: function(room, member, message) {
+        let time = GLib.DateTime.new_now_utc().to_unix();
+        let text = _("%s has disconnected").format(member.alias);
+        if (message)
+            text += ' (%s)'.format(message);
         if (this._shouldStatus(member.alias)) {
-            let text = _("%s has disconnected").format(member.alias);
-            if (message)
-                text += ' (%s)'.format(message);
             this._insertStatus(text);
+        } else if (time - this._state.lastTimestamp > ACTIVITY_DURATION) {
+            this._insertStatusCompressed(text, 'left');
+            let buffer = this._view.get_buffer();
+            let iter = buffer.get_end_iter();
+            buffer.create_mark('idle-status', iter, true);
         }
         this._setNickStatus(member.alias, Tp.ConnectionPresenceType.OFFLINE);
     },
 
     _onMemberKicked: function(room, member, actor) {
+        let time = GLib.DateTime.new_now_utc().to_unix();
+        let message =
+            actor ? _("%s has been kicked by %s").format(member.alias,
+                                                         actor.alias)
+                  : _("%s has been kicked").format(member.alias);
         if (this._shouldStatus(member.alias)) {
-            let message =
-                actor ? _("%s has been kicked by %s").format(member.alias,
-                                                             actor.alias)
-                      : _("%s has been kicked").format(member.alias);
             this._insertStatus(message);
+        } else if (time - this._state.lastTimestamp > ACTIVITY_DURATION) {
+            this._insertStatusCompressed(text, 'left');
+            let buffer = this._view.get_buffer();
+            let iter = buffer.get_end_iter();
+            buffer.create_mark('idle-status', iter, true);
         }
         this._setNickStatus(member.alias, Tp.ConnectionPresenceType.OFFLINE);
     },
 
     _onMemberBanned: function(room, member, actor) {
+        let time = GLib.DateTime.new_now_utc().to_unix();
+        let message =
+            actor ? _("%s has been banned by %s").format(member.alias,
+                                                         actor.alias)
+                  : _("%s has been banned").format(member.alias)
         if (this._shouldStatus(member.alias)) {
-            let message =
-                actor ? _("%s has been banned by %s").format(member.alias,
-                                                             actor.alias)
-                      : _("%s has been banned").format(member.alias)
             this._insertStatus(message);
+        } else if (time - this._state.lastTimestamp > ACTIVITY_DURATION) {
+            this._insertStatusCompressed(text, 'left');
+            let buffer = this._view.get_buffer();
+            let iter = buffer.get_end_iter();
+            buffer.create_mark('idle-status', iter, true);
         }
         this._setNickStatus(member.alias, Tp.ConnectionPresenceType.OFFLINE);
     },
 
     _onMemberJoined: function(room, member) {
-        if (this._shouldStatus(member.alias))
-            this._insertStatus(_("%s joined").format(member.alias));
+        let time = GLib.DateTime.new_now_utc().to_unix();
+        let text = _("%s joined").format(member.alias);
+        if (this._shouldStatus(member.alias)) {
+            this._insertStatus(text);
+        } else if (time - this._state.lastTimestamp > ACTIVITY_DURATION) {
+            this._insertStatusCompressed(text, 'joined');
+            let buffer = this._view.get_buffer();
+            let iter = buffer.get_end_iter();
+            buffer.create_mark('idle-status', iter, true);
+        }
         this._setNickStatus(member.alias, Tp.ConnectionPresenceType.AVAILABLE);
     },
 
     _onMemberLeft: function(room, member, message) {
+        let time = GLib.DateTime.new_now_utc().to_unix();
+        let text = _("%s left").format(member.alias);
+        if (message)
+            text += ' (%s)'.format(message);
+
         if (this._shouldStatus(member.alias)) {
-            let text = _("%s left").format(member.alias);
-            if (message)
-                text += ' (%s)'.format(message);
             this._insertStatus(text);
+        } else if (time - this._state.lastTimestamp > ACTIVITY_DURATION) {
+            this._insertStatusCompressed(text, 'left');
+            let buffer = this._view.get_buffer();
+            let iter = buffer.get_end_iter();
+            buffer.create_mark('idle-status', iter, true);
         }
         this._setNickStatus(member.alias, Tp.ConnectionPresenceType.OFFLINE);
     },
@@ -693,6 +732,21 @@ const ChatView = new Lang.Class({
         if (!nickTag)
            return;
         nickTag._active = GLib.DateTime.new_now_utc().to_unix();
+
+        let mark = this._view.buffer.get_mark('idle-status');
+        if (mark) {
+            this._view.buffer.delete_mark(mark);
+            log('we have activity, so mark is deleted');
+        }
+    },
+
+    _onMessageSent: function(room, tpMessage) {
+        this._insertTpMessage(room, tpMessage);
+
+        let mark = this._view.buffer.get_mark('idle-status');
+        if (mark) {
+            this._view.buffer.delete_mark(mark);
+        }
     },
 
     _shouldStatus: function(nick) {
@@ -705,6 +759,31 @@ const ChatView = new Lang.Class({
         return time - nickTag._active < ACTIVITY_DURATION;
     },
 
+    _insertStatusCompressed: function(statusText, status) {
+        let compressedText = '';
+        let buffer = this._view.buffer;
+        let mark = buffer.get_mark('idle-status');
+
+        this._statusCount.forEach(function(statusEntry) {
+            if (statusEntry.name == status)
+                statusEntry.count++;
+            if (statusEntry.count) {
+                compressedText = compressedText + ', ' + statusEntry.count +
+                                 ' users ' + statusEntry.name;
+            }
+        });
+
+        if (mark) {
+            let endIter = buffer.get_iter_at_mark(mark);
+            let startIter = buffer.get_iter_at_line(endIter.get_line());
+            buffer.delete(startIter, endIter);
+            this._insertStatus(compressedText);
+        } else {
+        this._insertStatus(statusText);
+        }
+
+    },
+
     _insertStatus: function(text) {
         let time = GLib.DateTime.new_now_utc().to_unix();
         if (time - this._joinTime < IGNORE_STATUS_TIME)


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