diff --git a/configure.ac b/configure.ac index 77ae4d8c0..5ca8049c1 100644 --- a/configure.ac +++ b/configure.ac @@ -73,7 +73,7 @@ GIO_MIN_VERSION=2.29.10 LIBECAL_MIN_VERSION=2.32.0 LIBEDATASERVER_MIN_VERSION=1.2.0 LIBEDATASERVERUI_MIN_VERSION=2.91.6 -TELEPATHY_GLIB_MIN_VERSION=0.15.3 +TELEPATHY_GLIB_MIN_VERSION=0.15.5 TELEPATHY_LOGGER_MIN_VERSION=0.2.4 POLKIT_MIN_VERSION=0.100 STARTUP_NOTIFICATION_MIN_VERSION=0.11 diff --git a/js/ui/notificationDaemon.js b/js/ui/notificationDaemon.js index 05dcd2a56..86bd4a27b 100644 --- a/js/ui/notificationDaemon.js +++ b/js/ui/notificationDaemon.js @@ -195,6 +195,7 @@ NotificationDaemon.prototype = { if (appName == 'Empathy' && (hints['category'] == 'im.received' || hints['category'] == 'x-empathy.im.room-invitation' || hints['category'] == 'x-empathy.call.incoming' || + hints['category'] == 'x-empathy.call.incoming"' || hints['category'] == 'presence.online' || hints['category'] == 'presence.offline')) { // Ignore replacesId since we already sent back a diff --git a/js/ui/telepathyClient.js b/js/ui/telepathyClient.js index b0d1218fe..4e2a95c21 100644 --- a/js/ui/telepathyClient.js +++ b/js/ui/telepathyClient.js @@ -1,6 +1,7 @@ /* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */ const DBus = imports.dbus; +const Gio = imports.gi.Gio; const GLib = imports.gi.GLib; const Lang = imports.lang; const Mainloop = imports.mainloop; @@ -244,6 +245,8 @@ Client.prototype = { else if (chanType == Tp.IFACE_CHANNEL_TYPE_STREAMED_MEDIA || chanType == 'org.freedesktop.Telepathy.Channel.Type.Call.DRAFT') this._approveCall(account, conn, channel, dispatchOp, context); + else if (chanType == Tp.IFACE_CHANNEL_TYPE_FILE_TRANSFER) + this._approveFileTransfer(account, conn, channel, dispatchOp, context); }, _approveTextChannel: function(account, conn, channel, dispatchOp, context) { @@ -299,6 +302,32 @@ Client.prototype = { context.accept(); }, + _approveFileTransfer: function(account, conn, channel, dispatchOp, context) { + let [targetHandle, targetHandleType] = channel.get_handle(); + + Shell.get_tp_contacts(conn, [targetHandle], + contactFeatures, + Lang.bind(this, this._createFileTransferSource, channel, context, dispatchOp)); + }, + + _createFileTransferSource: function(connection, contacts, failed, channel, context, dispatchOp) { + if (contacts.length < 1) { + Shell.decline_dispatch_op(context, 'Failed to get file sender'); + return; + } + + // Use the icon of the file being transferred + let gicon = Gio.content_type_get_icon(channel.get_mime_type()); + + // We got the TpContact + let source = new ApproverSource(dispatchOp, _("File Transfer"), gicon); + Main.messageTray.add(source); + + let notif = new FileTransferNotification(source, dispatchOp, channel, contacts[0]); + source.notify(notif); + context.accept(); + }, + _delegatedChannelsCb: function(client, channels) { // Nothing to do as we don't make a distinction between observed and // handled channels. @@ -973,3 +1002,46 @@ AudioVideoNotification.prototype = { })); } }; + +// File Transfer +function FileTransferNotification(source, dispatchOp, channel, contact) { + this._init(source, dispatchOp, channel, contact); +} + +FileTransferNotification.prototype = { + __proto__: MessageTray.Notification.prototype, + + _init: function(source, dispatchOp, channel, contact) { + MessageTray.Notification.prototype._init.call(this, + source, + /* To translators: The first parameter is + * the contact's alias and the second one is the + * file name. The string will be something + * like: "Alice is sending you test.ogg" + */ + _("%s is sending you %s").format(contact.get_alias(), + channel.get_filename()), + null, + { customContent: true }); + this.setResident(true); + + this.addButton('decline', _("Decline")); + this.addButton('accept', _("Accept")); + + this.connect('action-invoked', Lang.bind(this, function(self, action) { + switch (action) { + case 'decline': + dispatchOp.leave_channels_async(Tp.ChannelGroupChangeReason.NONE, + '', function(src, result) { + src.leave_channels_finish(result)}); + break; + case 'accept': + dispatchOp.handle_with_time_async('', global.get_current_time(), + function(src, result) { + src.handle_with_time_finish(result)}); + break; + } + this.destroy(); + })); + } +}; diff --git a/src/shell-tp-client.c b/src/shell-tp-client.c index bce0cbba7..48233e2ac 100644 --- a/src/shell-tp-client.c +++ b/src/shell-tp-client.c @@ -127,6 +127,14 @@ shell_tp_client_init (ShellTpClient *self) TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT, NULL)); + /* Approve file transfers. We let Empathy handle the transfer itself. */ + tp_base_client_take_approver_filter (TP_BASE_CLIENT (self), + tp_asv_new ( + TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, + TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, + TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT, + NULL)); + /* Handler */ tp_base_client_add_handler_filter (TP_BASE_CLIENT (self), filter);