telepathyClient: improve Empathy interaction

Activate empathy when clicking on a chat icon by asking the
ChannelDispatcher to open the conversation in the default handler.

Also, remove the Approver and Handler for now, since until
telepathy-logger is stable, this means Empathy won't see (and log)
those conversations. This means that empathy's blinky status icon is
back; we'll have to do something else about that.

https://bugzilla.gnome.org/show_bug.cgi?id=611610
This commit is contained in:
Dan Winship 2010-04-08 10:55:22 -04:00
parent b1486f54c8
commit 2bd64b6cab
2 changed files with 71 additions and 54 deletions

View File

@ -276,3 +276,31 @@ const AccountIface = {
] ]
}; };
let Account = makeProxyClass(AccountIface); let Account = makeProxyClass(AccountIface);
const CHANNEL_DISPATCHER_NAME = TELEPATHY + '.ChannelDispatcher';
const ChannelDispatcherIface = {
name: CHANNEL_DISPATCHER_NAME,
methods: [
{ name: 'EnsureChannel',
inSignature: 'oa{sv}xs',
outSignature: 'o' }
]
};
let ChannelDispatcher = makeProxyClass(ChannelDispatcherIface);
const CHANNEL_REQUEST_NAME = TELEPATHY + '.ChannelRequest';
const ChannelRequestIface = {
name: CHANNEL_REQUEST_NAME,
methods: [
{ name: 'Proceed',
inSignature: '',
outSignature: '' }
],
signals: [
{ name: 'Failed',
signature: 'ss' },
{ name: 'Succeeded',
signature: '' }
]
};
let ChannelRequest = makeProxyClass(ChannelRequestIface);

View File

@ -12,6 +12,7 @@ const MessageTray = imports.ui.messageTray;
const Telepathy = imports.misc.telepathy; const Telepathy = imports.misc.telepathy;
let avatarManager; let avatarManager;
let channelDispatcher;
// See Notification.appendMessage // See Notification.appendMessage
const SCROLLBACK_RECENT_TIME = 15 * 60; // 15 minutes const SCROLLBACK_RECENT_TIME = 15 * 60; // 15 minutes
@ -19,11 +20,9 @@ const SCROLLBACK_RECENT_LENGTH = 20;
const SCROLLBACK_IDLE_LENGTH = 5; const SCROLLBACK_IDLE_LENGTH = 5;
// This is GNOME Shell's implementation of the Telepathy "Client" // This is GNOME Shell's implementation of the Telepathy "Client"
// interface. Specifically, the shell is a Telepathy "Approver", which // interface. Specifically, the shell is a Telepathy "Observer", which
// lets us control the routing of incoming messages, a "Handler", // lets us see messages even if they belong to another app (eg,
// which lets us receive and respond to messages, and an "Observer", // Empathy).
// which lets us see messages even if they belong to another app (eg,
// a conversation started from within Empathy).
function Client() { function Client() {
this._init(); this._init();
@ -41,6 +40,10 @@ Client.prototype = {
avatarManager = new AvatarManager(); avatarManager = new AvatarManager();
channelDispatcher = new Telepathy.ChannelDispatcher(DBus.session,
Telepathy.CHANNEL_DISPATCHER_NAME,
Telepathy.nameToPath(Telepathy.CHANNEL_DISPATCHER_NAME));
// Acquire existing connections. (Needed to make things work // Acquire existing connections. (Needed to make things work
// through a restart.) // through a restart.)
let accountManager = new Telepathy.AccountManager(DBus.session, let accountManager = new Telepathy.AccountManager(DBus.session,
@ -69,19 +72,17 @@ Client.prototype = {
function(channels, err) { function(channels, err) {
if (!channels) if (!channels)
return; return;
this._addChannels(connPath, channels); this._addChannels(account.getPath(), connPath, channels);
})); }));
})); }));
} }
}, },
get Interfaces() { get Interfaces() {
return [ Telepathy.CLIENT_APPROVER_NAME, return [ Telepathy.CLIENT_OBSERVER_NAME ];
Telepathy.CLIENT_HANDLER_NAME,
Telepathy.CLIENT_OBSERVER_NAME ];
}, },
get ApproverChannelFilter() { get ObserverChannelFilter() {
return [ return [
// We only care about single-user text-based chats // We only care about single-user text-based chats
{ 'org.freedesktop.Telepathy.Channel.ChannelType': Telepathy.CHANNEL_TEXT_NAME, { 'org.freedesktop.Telepathy.Channel.ChannelType': Telepathy.CHANNEL_TEXT_NAME,
@ -98,46 +99,13 @@ Client.prototype = {
]; ];
}, },
AddDispatchOperation: function(channels, dispatchOperationPath, properties) { ObserveChannels: function(accountPath, connPath, channels,
let sender = DBus.getCurrentMessageContext().sender;
let op = new Telepathy.ChannelDispatchOperation(DBus.session, sender,
dispatchOperationPath);
op.ClaimRemote();
},
get HandlerChannelFilter() {
// See ApproverChannelFilter
return [
{ 'org.freedesktop.Telepathy.Channel.ChannelType': Telepathy.CHANNEL_TEXT_NAME,
'org.freedesktop.Telepathy.Channel.TargetHandleType': Telepathy.HandleType.CONTACT },
{ 'org.freedesktop.Telepathy.Channel.ChannelType': Telepathy.CHANNEL_TEXT_NAME,
'org.freedesktop.Telepathy.Channel.TargetHandleType': Telepathy.HandleType.NONE }
];
},
HandleChannels: function(account, connPath, channels,
requestsSatisfied, userActionTime,
handlerInfo) {
this._addChannels(connPath, channels);
},
get ObserverChannelFilter() {
// See ApproverChannelFilter
return [
{ 'org.freedesktop.Telepathy.Channel.ChannelType': Telepathy.CHANNEL_TEXT_NAME,
'org.freedesktop.Telepathy.Channel.TargetHandleType': Telepathy.HandleType.CONTACT },
{ 'org.freedesktop.Telepathy.Channel.ChannelType': Telepathy.CHANNEL_TEXT_NAME,
'org.freedesktop.Telepathy.Channel.TargetHandleType': Telepathy.HandleType.NONE }
];
},
ObserveChannels: function(account, connPath, channels,
dispatchOperation, requestsSatisfied, dispatchOperation, requestsSatisfied,
observerInfo) { observerInfo) {
this._addChannels(connPath, channels); this._addChannels(accountPath, connPath, channels);
}, },
_addChannels: function(connPath, channelDetailsList) { _addChannels: function(accountPath, connPath, channelDetailsList) {
for (let i = 0; i < channelDetailsList.length; i++) { for (let i = 0; i < channelDetailsList.length; i++) {
let [channelPath, props] = channelDetailsList[i]; let [channelPath, props] = channelDetailsList[i];
if (this._channels[channelPath]) if (this._channels[channelPath])
@ -159,7 +127,7 @@ Client.prototype = {
let targetHandle = props[Telepathy.CHANNEL_NAME + '.TargetHandle']; let targetHandle = props[Telepathy.CHANNEL_NAME + '.TargetHandle'];
let targetId = props[Telepathy.CHANNEL_NAME + '.TargetID']; let targetId = props[Telepathy.CHANNEL_NAME + '.TargetID'];
let source = new Source(connPath, channelPath, let source = new Source(accountPath, connPath, channelPath,
targetHandle, targetHandleType, targetId); targetHandle, targetHandleType, targetId);
this._channels[channelPath] = source; this._channels[channelPath] = source;
source.connect('destroy', Lang.bind(this, source.connect('destroy', Lang.bind(this,
@ -170,8 +138,6 @@ Client.prototype = {
} }
}; };
DBus.conformExport(Client.prototype, Telepathy.ClientIface); DBus.conformExport(Client.prototype, Telepathy.ClientIface);
DBus.conformExport(Client.prototype, Telepathy.ClientApproverIface);
DBus.conformExport(Client.prototype, Telepathy.ClientHandlerIface);
DBus.conformExport(Client.prototype, Telepathy.ClientObserverIface); DBus.conformExport(Client.prototype, Telepathy.ClientObserverIface);
@ -350,22 +316,25 @@ AvatarManager.prototype = {
}; };
function Source(connPath, channelPath, targetHandle, targetHandleType, targetId) { function Source(accountPath, connPath, channelPath, targetHandle, targetHandleType, targetId) {
this._init(connPath, channelPath, targetHandle, targetHandleType, targetId); this._init(accountPath, connPath, channelPath, targetHandle, targetHandleType, targetId);
} }
Source.prototype = { Source.prototype = {
__proto__: MessageTray.Source.prototype, __proto__: MessageTray.Source.prototype,
_init: function(connPath, channelPath, targetHandle, targetHandleType, targetId) { _init: function(accountPath, connPath, channelPath, targetHandle, targetHandleType, targetId) {
MessageTray.Source.prototype._init.call(this, targetId); MessageTray.Source.prototype._init.call(this, targetId);
this._accountPath = accountPath;
let connName = Telepathy.pathToName(connPath); let connName = Telepathy.pathToName(connPath);
this._conn = new Telepathy.Connection(DBus.session, connName, connPath); this._conn = new Telepathy.Connection(DBus.session, connName, connPath);
this._channel = new Telepathy.Channel(DBus.session, connName, channelPath); this._channel = new Telepathy.Channel(DBus.session, connName, channelPath);
this._closedId = this._channel.connect('Closed', Lang.bind(this, this._channelClosed)); this._closedId = this._channel.connect('Closed', Lang.bind(this, this._channelClosed));
this._targetHandle = targetHandle; this._targetHandle = targetHandle;
this._targetHandleType = targetHandleType;
this._targetId = targetId; this._targetId = targetId;
this.name = this._targetId; this.name = this._targetId;
@ -388,6 +357,28 @@ Source.prototype = {
return avatarManager.createAvatar(this._conn, this._targetHandle, size); return avatarManager.createAvatar(this._conn, this._targetHandle, size);
}, },
clicked: function() {
channelDispatcher.EnsureChannelRemote(this._accountPath,
{ 'org.freedesktop.Telepathy.Channel.ChannelType': Telepathy.CHANNEL_TEXT_NAME,
'org.freedesktop.Telepathy.Channel.TargetHandle': this._targetHandle,
'org.freedesktop.Telepathy.Channel.TargetHandleType': this._targetHandleType },
global.get_current_time(),
'',
Lang.bind(this, this._gotChannelRequest));
MessageTray.Source.prototype.clicked.call(this);
},
_gotChannelRequest: function (chanReqPath, ex) {
if (ex) {
log ('EnsureChannelRemote failed? ' + ex);
return;
}
let chanReq = new Telepathy.ChannelRequest(DBus.session, Telepathy.CHANNEL_DISPATCHER_NAME, chanReqPath);
chanReq.ProceedRemote();
},
_gotPendingMessages: function(msgs, err) { _gotPendingMessages: function(msgs, err) {
if (!msgs) if (!msgs)
return; return;
@ -411,8 +402,6 @@ Source.prototype = {
this._notification = new Notification(this._targetId, this); this._notification = new Notification(this._targetId, this);
this._notification.appendMessage(text); this._notification.appendMessage(text);
this.notify(this._notification); this.notify(this._notification);
this._channelText.AcknowledgePendingMessagesRemote([id]);
}, },
respond: function(text) { respond: function(text) {