[gnome-shell/message-tray: 3/5] Reorganize a bit, fix missing-first-message bug
- From: Dan Winship <danw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-shell/message-tray: 3/5] Reorganize a bit, fix missing-first-message bug
- Date: Tue, 3 Nov 2009 15:48:51 +0000 (UTC)
commit 56d2691c314d6a7e05a8eb59a87b2054672bdf6f
Author: Dan Winship <danw gnome org>
Date: Wed Oct 28 15:30:26 2009 -0400
Reorganize a bit, fix missing-first-message bug
https://bugzilla.gnome.org/show_bug.cgi?id=599193
js/ui/messaging.js | 140 ++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 103 insertions(+), 37 deletions(-)
---
diff --git a/js/ui/messaging.js b/js/ui/messaging.js
index 190d6e6..9c4be52 100644
--- a/js/ui/messaging.js
+++ b/js/ui/messaging.js
@@ -1,6 +1,11 @@
+/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
+
const DBus = imports.dbus;
+const Lang = imports.lang;
const Shell = imports.gi.Shell;
+const AVATAR_SIZE = 24;
+
const TELEPATHY = "org.freedesktop.Telepathy.";
const CONN = TELEPATHY + "Connection";
const CHANNEL = TELEPATHY + "Channel";
@@ -24,7 +29,10 @@ const ClientObserverIface = {
};
const ConnectionIface = {
- name: CONN
+ name: CONN,
+ signals: [
+ { name: 'StatusChanged', inSignature: 'u' }
+ ]
};
const ConnectionAvatarsIface = {
@@ -71,6 +79,12 @@ DBus.proxifyPrototype(Channel.prototype, ChannelIface);
const ChannelTextIface = {
name: CHANNELTEXT,
+ methods: [
+ { name: 'ListPendingMessages',
+ inSignature: 'b',
+ outSignature: 'a(uuuuus)'
+ }
+ ],
signals: [
{ name: 'Received', inSignature: 'uuuuus' }
]
@@ -107,6 +121,8 @@ Messaging.prototype = {
DBus.session.acquire_name(name, DBus.SINGLE_INSTANCE,
function(name){log("Acquired name " + name);},
function(name){log("Lost name " + name);});
+
+ this._conns = {};
},
get Interfaces() {
@@ -122,47 +138,97 @@ Messaging.prototype = {
ObserveChannels: function(account, conn_path, channels,
dispatch_operation, requests_satisfied,
observer_info) {
- log('observing ' + conn_path);
- let conn = new Connection(conn_path);
- let conn_name = conn_path.substr(1).replace('/','.','g');
-
- for (var i = 0; i < channels.length; i++) {
- let path = channels[i][0];
- let props = 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);
- });
+ let conn = this._conns[conn_path];
+ if (!conn) {
+ conn = new Connection(conn_path);
+ conn.connect('StatusChanged', Lang.bind(this, this._connectionStatusChanged));
+ }
+
+ let conn_name = nameify(conn_path);
+ for (let i = 0; i < channels.length; i++) {
+ new Source(conn, conn_name, channels[i][0], channels[i][1]);
}
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, 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);
+ }
+};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]