[gnome-shell] telepathyClient: Add messages from TelepathyLogger



commit 5a269db9d5d7b2a65f138cccfc6b449ba27f6d86
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Mon Mar 7 17:10:53 2011 -0500

    telepathyClient: Add messages from TelepathyLogger
    
    This allows users to see chat history from other contacts with
    the inline message tray replies.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=643377

 js/ui/telepathyClient.js |  137 ++++++++++++++++++++++++++++++++++++----------
 1 files changed, 108 insertions(+), 29 deletions(-)
---
diff --git a/js/ui/telepathyClient.js b/js/ui/telepathyClient.js
index de504b4..e7a8240 100644
--- a/js/ui/telepathyClient.js
+++ b/js/ui/telepathyClient.js
@@ -7,6 +7,7 @@ const Mainloop = imports.mainloop;
 const Shell = imports.gi.Shell;
 const Signals = imports.signals;
 const St = imports.gi.St;
+const Tpl = imports.gi.TelepathyLogger;
 const Tp = imports.gi.TelepathyGLib;
 const Gettext = imports.gettext.domain('gnome-shell');
 const _ = Gettext.gettext;
@@ -22,6 +23,9 @@ const SCROLLBACK_RECENT_TIME = 15 * 60; // 15 minutes
 const SCROLLBACK_RECENT_LENGTH = 20;
 const SCROLLBACK_IDLE_LENGTH = 5;
 
+// See Source._displayPendingMessages
+const SCROLLBACK_HISTORY_LINES = 10;
+
 const NotificationDirection = {
     SENT: 'chat-sent',
     RECEIVED: 'chat-received'
@@ -36,6 +40,31 @@ let contactFeatures = [Tp.ContactFeature.ALIAS,
 // lets us see messages even if they belong to another app (eg,
 // Empathy).
 
+function makeMessageFromTpMessage(tpMessage, direction) {
+    let [text, flags] = tpMessage.to_text();
+    return {
+        messageType: tpMessage.get_message_type(),
+        text: text,
+        sender: tpMessage.sender.alias,
+        timestamp: tpMessage.get_received_timestamp(),
+        direction: direction
+    };
+}
+
+
+function makeMessageFromTplEvent(event) {
+    let sent = event.get_sender().get_entity_type() == Tpl.EntityType.SELF;
+    let direction = sent ? NotificationDirection.SENT : NotificationDirection.RECEIVED;
+
+    return {
+        messageType: event.get_message_type(),
+        text: event.get_message(),
+        sender: event.get_sender().get_alias(),
+        timestamp: event.get_timestamp(),
+        direction: direction
+    };
+}
+
 function Client() {
     this._init();
 };
@@ -160,7 +189,7 @@ Source.prototype = {
         Main.messageTray.add(this);
         this.pushNotification(this._notification);
 
-        this._displayPendingMessages();
+        this._getLogMessages();
     },
 
     _updateAlias: function() {
@@ -203,13 +232,50 @@ Source.prototype = {
         req.ensure_channel_async('', null, null);
     },
 
-    _displayPendingMessages: function() {
-        let msgs = this._channel.get_pending_messages();
+    _getLogMessages: function() {
+        let logManager = Tpl.LogManager.dup_singleton();
+        let entity = Tpl.Entity.new_from_tp_contact(this._contact, Tpl.EntityType.CONTACT);
+        Shell.get_contact_events(logManager,
+                                 this._account, entity,
+                                 SCROLLBACK_HISTORY_LINES,
+                                 Lang.bind(this, this._displayPendingMessages));
+    },
+
+    _displayPendingMessages: function(logManager, result) {
+        let [success, events] = logManager.get_filtered_events_finish(result);
 
-        for (let i = 0; i < msgs.length; i++) {
-            let msg = msgs[i];
-            this._messageReceived(this._channel, msg);
+        let logMessages = events.map(makeMessageFromTplEvent);
+        for (let i = 0; i < logMessages.length; i++) {
+            this._notification.appendMessage(logMessages[i], true);
         }
+
+        let pendingMessages = this._channel.get_pending_messages();
+        let hasPendingMessage = false;
+        for (let i = 0; i < pendingMessages.length; i++) {
+            let message = makeMessageFromTpMessage(pendingMessages[i], NotificationDirection.RECEIVED);
+
+            // Skip any pending messages that are in the logs.
+            let inLog = false;
+            for (let j = 0; j < logMessages.length; j++) {
+                let logMessage = logMessages[j];
+                if (logMessage.timestamp == message.timestamp && logMessage.text == message.body) {
+                    inLog = true;
+                }
+            }
+
+            if (inLog)
+                continue;
+
+            this._notification.appendMessage(message, true);
+            hasPendingMessage = true;
+        }
+
+        // Only show the timestamp if we have at least one message.
+        if (hasPendingMessage || logMessages.length > 0)
+            this._notification.appendTimestamp();
+
+        if (hasPendingMessage)
+            this.notify();
     },
 
     _channelClosed: function() {
@@ -225,14 +291,16 @@ Source.prototype = {
     },
 
     _messageReceived: function(channel, message) {
-        this._notification.appendMessage(message, NotificationDirection.RECEIVED);
+        message = makeMessageFromTpMessage(message, NotificationDirection.RECEIVED);
+        this._notification.appendMessage(message);
         this.notify();
     },
 
     // This is called for both messages we send from
     // our client and other clients as well.
     _messageSent: function(channel, message, flags, token) {
-        this._notification.appendMessage(message, NotificationDirection.SENT);
+        message = makeMessageFromTpMessage(message, NotificationDirection.SENT);
+        this._notification.appendMessage(message);
     },
 
     notify: function() {
@@ -320,25 +388,34 @@ Notification.prototype = {
         this._timestampTimeoutId = 0;
     },
 
-    appendMessage: function(message, direction) {
-        let type = message.get_message_type();
-        let [text, flags] = message.to_text();
-        let timestamp = message.get_received_timestamp();
-
-        let messageBody = GLib.markup_escape_text(text, -1);
-        let styles = [direction];
-
-        if (type == Tp.ChannelTextMessageType.ACTION) {
-            let senderAlias = GLib.markup_escape_text(message.sender.alias, -1);
+    /**
+     * appendMessage:
+     * @message: An object with the properties:
+     *   text: the body of the message,
+     *   messageType: a #Tp.ChannelTextMessageType,
+     *   sender: the name of the sender,
+     *   timestamp: the time the message was sent
+     *   direction: a #NotificationDirection
+     * 
+     * @noTimestamp: Whether to add a timestamp. If %true, no timestamp
+     *   will be added, regardless of the difference since the
+     *   last timestamp
+     */
+    appendMessage: function(message, noTimestamp) {
+        let messageBody = GLib.markup_escape_text(message.text, -1);
+        let styles = [message.direction];
+
+        if (message.messageType == Tp.ChannelTextMessageType.ACTION) {
+            let senderAlias = GLib.markup_escape_text(message.sender, -1);
             messageBody = '<i>%s</i> %s'.format(senderAlias, messageBody);
             styles.push('chat-action');
         }
 
         this.update(this.source.title, messageBody, { customContent: true, bannerMarkup: true });
-        this._append(messageBody, styles, timestamp);
+        this._append(messageBody, styles, message.timestamp, noTimestamp);
     },
 
-    _append: function(text, styles, timestamp) {
+    _append: function(text, styles, timestamp, noTimestamp) {
         let currentTime = (Date.now() / 1000);
         if (!timestamp)
             timestamp = currentTime;
@@ -356,14 +433,16 @@ Notification.prototype = {
 
         this._history.unshift({ actor: body, time: timestamp, realMessage: true });
 
-        if (timestamp < currentTime - SCROLLBACK_IMMEDIATE_TIME)
-            this._appendTimestamp();
-        else
-            // Schedule a new timestamp in SCROLLBACK_IMMEDIATE_TIME
-            // from the timestamp of the message.
-            this._timestampTimeoutId = Mainloop.timeout_add_seconds(
-                SCROLLBACK_IMMEDIATE_TIME - (currentTime - timestamp),
-                Lang.bind(this, this._appendTimestamp));
+        if (!noTimestamp) {
+            if (timestamp < currentTime - SCROLLBACK_IMMEDIATE_TIME)
+                this.appendTimestamp();
+            else
+                // Schedule a new timestamp in SCROLLBACK_IMMEDIATE_TIME
+                // from the timestamp of the message.
+                this._timestampTimeoutId = Mainloop.timeout_add_seconds(
+                    SCROLLBACK_IMMEDIATE_TIME - (currentTime - timestamp),
+                    Lang.bind(this, this.appendTimestamp));
+        }
 
         if (this._history.length > 1) {
             // Keep the scrollback from growing too long. If the most
@@ -384,7 +463,7 @@ Notification.prototype = {
         }
     },
 
-    _appendTimestamp: function() {
+    appendTimestamp: function() {
         let lastMessageTime = this._history[0].time;
         let lastMessageDate = new Date(lastMessageTime * 1000);
 



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