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
This commit is contained in:
parent
525da01a62
commit
5a269db9d5
@ -7,6 +7,7 @@ const Mainloop = imports.mainloop;
|
|||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
const Tpl = imports.gi.TelepathyLogger;
|
||||||
const Tp = imports.gi.TelepathyGLib;
|
const Tp = imports.gi.TelepathyGLib;
|
||||||
const Gettext = imports.gettext.domain('gnome-shell');
|
const Gettext = imports.gettext.domain('gnome-shell');
|
||||||
const _ = Gettext.gettext;
|
const _ = Gettext.gettext;
|
||||||
@ -22,6 +23,9 @@ const SCROLLBACK_RECENT_TIME = 15 * 60; // 15 minutes
|
|||||||
const SCROLLBACK_RECENT_LENGTH = 20;
|
const SCROLLBACK_RECENT_LENGTH = 20;
|
||||||
const SCROLLBACK_IDLE_LENGTH = 5;
|
const SCROLLBACK_IDLE_LENGTH = 5;
|
||||||
|
|
||||||
|
// See Source._displayPendingMessages
|
||||||
|
const SCROLLBACK_HISTORY_LINES = 10;
|
||||||
|
|
||||||
const NotificationDirection = {
|
const NotificationDirection = {
|
||||||
SENT: 'chat-sent',
|
SENT: 'chat-sent',
|
||||||
RECEIVED: 'chat-received'
|
RECEIVED: 'chat-received'
|
||||||
@ -36,6 +40,31 @@ let contactFeatures = [Tp.ContactFeature.ALIAS,
|
|||||||
// lets us see messages even if they belong to another app (eg,
|
// lets us see messages even if they belong to another app (eg,
|
||||||
// Empathy).
|
// 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() {
|
function Client() {
|
||||||
this._init();
|
this._init();
|
||||||
};
|
};
|
||||||
@ -160,7 +189,7 @@ Source.prototype = {
|
|||||||
Main.messageTray.add(this);
|
Main.messageTray.add(this);
|
||||||
this.pushNotification(this._notification);
|
this.pushNotification(this._notification);
|
||||||
|
|
||||||
this._displayPendingMessages();
|
this._getLogMessages();
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateAlias: function() {
|
_updateAlias: function() {
|
||||||
@ -203,13 +232,50 @@ Source.prototype = {
|
|||||||
req.ensure_channel_async('', null, null);
|
req.ensure_channel_async('', null, null);
|
||||||
},
|
},
|
||||||
|
|
||||||
_displayPendingMessages: function() {
|
_getLogMessages: function() {
|
||||||
let msgs = this._channel.get_pending_messages();
|
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));
|
||||||
|
},
|
||||||
|
|
||||||
for (let i = 0; i < msgs.length; i++) {
|
_displayPendingMessages: function(logManager, result) {
|
||||||
let msg = msgs[i];
|
let [success, events] = logManager.get_filtered_events_finish(result);
|
||||||
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() {
|
_channelClosed: function() {
|
||||||
@ -225,14 +291,16 @@ Source.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_messageReceived: function(channel, message) {
|
_messageReceived: function(channel, message) {
|
||||||
this._notification.appendMessage(message, NotificationDirection.RECEIVED);
|
message = makeMessageFromTpMessage(message, NotificationDirection.RECEIVED);
|
||||||
|
this._notification.appendMessage(message);
|
||||||
this.notify();
|
this.notify();
|
||||||
},
|
},
|
||||||
|
|
||||||
// This is called for both messages we send from
|
// This is called for both messages we send from
|
||||||
// our client and other clients as well.
|
// our client and other clients as well.
|
||||||
_messageSent: function(channel, message, flags, token) {
|
_messageSent: function(channel, message, flags, token) {
|
||||||
this._notification.appendMessage(message, NotificationDirection.SENT);
|
message = makeMessageFromTpMessage(message, NotificationDirection.SENT);
|
||||||
|
this._notification.appendMessage(message);
|
||||||
},
|
},
|
||||||
|
|
||||||
notify: function() {
|
notify: function() {
|
||||||
@ -320,25 +388,34 @@ Notification.prototype = {
|
|||||||
this._timestampTimeoutId = 0;
|
this._timestampTimeoutId = 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
appendMessage: function(message, direction) {
|
/**
|
||||||
let type = message.get_message_type();
|
* appendMessage:
|
||||||
let [text, flags] = message.to_text();
|
* @message: An object with the properties:
|
||||||
let timestamp = message.get_received_timestamp();
|
* 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];
|
||||||
|
|
||||||
let messageBody = GLib.markup_escape_text(text, -1);
|
if (message.messageType == Tp.ChannelTextMessageType.ACTION) {
|
||||||
let styles = [direction];
|
let senderAlias = GLib.markup_escape_text(message.sender, -1);
|
||||||
|
|
||||||
if (type == Tp.ChannelTextMessageType.ACTION) {
|
|
||||||
let senderAlias = GLib.markup_escape_text(message.sender.alias, -1);
|
|
||||||
messageBody = '<i>%s</i> %s'.format(senderAlias, messageBody);
|
messageBody = '<i>%s</i> %s'.format(senderAlias, messageBody);
|
||||||
styles.push('chat-action');
|
styles.push('chat-action');
|
||||||
}
|
}
|
||||||
|
|
||||||
this.update(this.source.title, messageBody, { customContent: true, bannerMarkup: true });
|
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);
|
let currentTime = (Date.now() / 1000);
|
||||||
if (!timestamp)
|
if (!timestamp)
|
||||||
timestamp = currentTime;
|
timestamp = currentTime;
|
||||||
@ -356,14 +433,16 @@ Notification.prototype = {
|
|||||||
|
|
||||||
this._history.unshift({ actor: body, time: timestamp, realMessage: true });
|
this._history.unshift({ actor: body, time: timestamp, realMessage: true });
|
||||||
|
|
||||||
|
if (!noTimestamp) {
|
||||||
if (timestamp < currentTime - SCROLLBACK_IMMEDIATE_TIME)
|
if (timestamp < currentTime - SCROLLBACK_IMMEDIATE_TIME)
|
||||||
this._appendTimestamp();
|
this.appendTimestamp();
|
||||||
else
|
else
|
||||||
// Schedule a new timestamp in SCROLLBACK_IMMEDIATE_TIME
|
// Schedule a new timestamp in SCROLLBACK_IMMEDIATE_TIME
|
||||||
// from the timestamp of the message.
|
// from the timestamp of the message.
|
||||||
this._timestampTimeoutId = Mainloop.timeout_add_seconds(
|
this._timestampTimeoutId = Mainloop.timeout_add_seconds(
|
||||||
SCROLLBACK_IMMEDIATE_TIME - (currentTime - timestamp),
|
SCROLLBACK_IMMEDIATE_TIME - (currentTime - timestamp),
|
||||||
Lang.bind(this, this._appendTimestamp));
|
Lang.bind(this, this.appendTimestamp));
|
||||||
|
}
|
||||||
|
|
||||||
if (this._history.length > 1) {
|
if (this._history.length > 1) {
|
||||||
// Keep the scrollback from growing too long. If the most
|
// 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 lastMessageTime = this._history[0].time;
|
||||||
let lastMessageDate = new Date(lastMessageTime * 1000);
|
let lastMessageDate = new Date(lastMessageTime * 1000);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user