Reorganize a bit, fix missing-first-message bug
https://bugzilla.gnome.org/show_bug.cgi?id=599193
This commit is contained in:
parent
f883e32f26
commit
56d2691c31
@ -1,6 +1,11 @@
|
|||||||
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
const DBus = imports.dbus;
|
const DBus = imports.dbus;
|
||||||
|
const Lang = imports.lang;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
|
const AVATAR_SIZE = 24;
|
||||||
|
|
||||||
const TELEPATHY = "org.freedesktop.Telepathy.";
|
const TELEPATHY = "org.freedesktop.Telepathy.";
|
||||||
const CONN = TELEPATHY + "Connection";
|
const CONN = TELEPATHY + "Connection";
|
||||||
const CHANNEL = TELEPATHY + "Channel";
|
const CHANNEL = TELEPATHY + "Channel";
|
||||||
@ -24,7 +29,10 @@ const ClientObserverIface = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const ConnectionIface = {
|
const ConnectionIface = {
|
||||||
name: CONN
|
name: CONN,
|
||||||
|
signals: [
|
||||||
|
{ name: 'StatusChanged', inSignature: 'u' }
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
const ConnectionAvatarsIface = {
|
const ConnectionAvatarsIface = {
|
||||||
@ -71,6 +79,12 @@ DBus.proxifyPrototype(Channel.prototype, ChannelIface);
|
|||||||
|
|
||||||
const ChannelTextIface = {
|
const ChannelTextIface = {
|
||||||
name: CHANNELTEXT,
|
name: CHANNELTEXT,
|
||||||
|
methods: [
|
||||||
|
{ name: 'ListPendingMessages',
|
||||||
|
inSignature: 'b',
|
||||||
|
outSignature: 'a(uuuuus)'
|
||||||
|
}
|
||||||
|
],
|
||||||
signals: [
|
signals: [
|
||||||
{ name: 'Received', inSignature: 'uuuuus' }
|
{ name: 'Received', inSignature: 'uuuuus' }
|
||||||
]
|
]
|
||||||
@ -107,6 +121,8 @@ Messaging.prototype = {
|
|||||||
DBus.session.acquire_name(name, DBus.SINGLE_INSTANCE,
|
DBus.session.acquire_name(name, DBus.SINGLE_INSTANCE,
|
||||||
function(name){log("Acquired name " + name);},
|
function(name){log("Acquired name " + name);},
|
||||||
function(name){log("Lost name " + name);});
|
function(name){log("Lost name " + name);});
|
||||||
|
|
||||||
|
this._conns = {};
|
||||||
},
|
},
|
||||||
|
|
||||||
get Interfaces() {
|
get Interfaces() {
|
||||||
@ -122,47 +138,97 @@ Messaging.prototype = {
|
|||||||
ObserveChannels: function(account, conn_path, channels,
|
ObserveChannels: function(account, conn_path, channels,
|
||||||
dispatch_operation, requests_satisfied,
|
dispatch_operation, requests_satisfied,
|
||||||
observer_info) {
|
observer_info) {
|
||||||
log('observing ' + conn_path);
|
let conn = this._conns[conn_path];
|
||||||
let conn = new Connection(conn_path);
|
if (!conn) {
|
||||||
let conn_name = conn_path.substr(1).replace('/','.','g');
|
conn = new Connection(conn_path);
|
||||||
|
conn.connect('StatusChanged', Lang.bind(this, this._connectionStatusChanged));
|
||||||
|
}
|
||||||
|
|
||||||
for (var i = 0; i < channels.length; i++) {
|
let conn_name = nameify(conn_path);
|
||||||
let path = channels[i][0];
|
for (let i = 0; i < channels.length; i++) {
|
||||||
let props = channels[i][1];
|
new Source(conn, conn_name, channels[i][0], channels[i][1]);
|
||||||
|
|
||||||
let targethandle = props[CHANNEL + '.TargetHandle'];
|
|
||||||
let targetid = props[CHANNEL + '.TargetID'];
|
|
||||||
|
|
||||||
// conn.RequestAvatarRemote(targethandle,
|
|
||||||
// function(result, excp) {
|
|
||||||
// log("called for " + targetid);
|
|
||||||
// let avatar;
|
|
||||||
// if (result) {
|
|
||||||
// let bytes = result[0];
|
|
||||||
// avatar = Shell.TextureCache.get_default().load_from_data(bytes, bytes.length, -1, TRAY_HEIGHT);
|
|
||||||
// } else {
|
|
||||||
// // fallback avatar
|
|
||||||
// avatar = Shell.TextureCache.get_default().load_icon_name("stock_person", TRAY_HEIGHT);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
let channel = new Channel(conn_name, path);
|
|
||||||
let id = channel.connect('Closed',
|
|
||||||
function(emitter) {
|
|
||||||
log('closed');
|
|
||||||
channel.disconnect(id);
|
|
||||||
});
|
|
||||||
|
|
||||||
let text = new ChannelText(conn_name, path);
|
|
||||||
text.connect('Received',
|
|
||||||
function(chan, id, timestamp, sender, type, flags, text) {
|
|
||||||
log('Received: id ' + id + ', time ' + timestamp + ', sender ' + sender + ', type ' + type + ', flags ' + flags + ': ' + text);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return [true];
|
return [true];
|
||||||
|
},
|
||||||
|
|
||||||
|
_connectionStatusChanged: function(connection, status) {
|
||||||
|
if (status == Connection_Status.Disconnected) {
|
||||||
|
delete this._conns[connection.getPath()];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
DBus.conformExport(Messaging.prototype, ClientIface);
|
DBus.conformExport(Messaging.prototype, ClientIface);
|
||||||
DBus.conformExport(Messaging.prototype, ClientObserverIface);
|
DBus.conformExport(Messaging.prototype, ClientObserverIface);
|
||||||
|
|
||||||
|
function Source(conn, conn_name, channel_path, channel_props) {
|
||||||
|
this._init(conn, conn_name, channel_path, channel_props);
|
||||||
|
}
|
||||||
|
|
||||||
|
Source.prototype = {
|
||||||
|
_init: function(conn, conn_name, channel_path, channel_props) {
|
||||||
|
this._targetId = channel_props[CHANNEL + '.TargetID'];
|
||||||
|
|
||||||
|
log('channel for ' + this._targetId);
|
||||||
|
|
||||||
|
this._pendingMessages = null;
|
||||||
|
|
||||||
|
// FIXME: RequestAvatar is deprecated in favor of
|
||||||
|
// RequestAvatars; but RequestAvatars provides no explicit
|
||||||
|
// indication of "no avatar available", so there's no way we
|
||||||
|
// can reliably wait for it to finish before displaying a
|
||||||
|
// message. So we use RequestAvatar() instead.
|
||||||
|
let targethandle = channel_props[CHANNEL + '.TargetHandle'];
|
||||||
|
conn.RequestAvatarRemote(targethandle, Lang.bind(this, this._gotAvatar));
|
||||||
|
|
||||||
|
this._channel = new Channel(conn_name, channel_path);
|
||||||
|
this._closedId = this._channel.connect('Closed', Lang.bind(this, this._channelClosed));
|
||||||
|
|
||||||
|
this._channelText = new ChannelText(conn_name, channel_path);
|
||||||
|
this._receivedId = this._channelText.connect('Received', Lang.bind(this, this._receivedMessage));
|
||||||
|
|
||||||
|
this._channelText.ListPendingMessagesRemote(false,
|
||||||
|
Lang.bind(this, function(msgs, excp) {
|
||||||
|
if (msgs) {
|
||||||
|
log('got pending messages for ' + this._targetId);
|
||||||
|
this._pendingMessages = msgs;
|
||||||
|
this._processPendingMessages();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
_gotAvatar: function(result, excp) {
|
||||||
|
if (result) {
|
||||||
|
let bytes = result[0];
|
||||||
|
this._avatar = Shell.TextureCache.get_default().load_from_data(bytes, bytes.length, AVATAR_SIZE, AVATAR_SIZE);
|
||||||
|
log('got avatar for ' + this._targetId);
|
||||||
|
} else {
|
||||||
|
// fallback avatar (FIXME)
|
||||||
|
this._avatar = Shell.TextureCache.get_default().load_icon_name("stock_person", AVATAR_SIZE);
|
||||||
|
log('using default avatar for ' + this._targetId);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._processPendingMessages();
|
||||||
|
},
|
||||||
|
|
||||||
|
_processPendingMessages: function() {
|
||||||
|
if (!this._avatar || !this._pendingMessages)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (let i = 0; i < this._pendingMessages.length; i++)
|
||||||
|
this._receivedMessage.apply(this, [this._channel].concat(this._pendingMessages[i]));
|
||||||
|
this._pendingMessages = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
_channelClosed: function() {
|
||||||
|
log('closed');
|
||||||
|
this._channel.disconnect(this._closedId);
|
||||||
|
this._channelText.disconnect(this._receivedId);
|
||||||
|
},
|
||||||
|
|
||||||
|
_receivedMessage: function(channel, id, timestamp, sender,
|
||||||
|
type, flags, text) {
|
||||||
|
log('Received: id ' + id + ', time ' + timestamp + ', sender ' + sender + ', type ' + type + ', flags ' + flags + ': ' + text);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user