diff --git a/js/ui/main.js b/js/ui/main.js index 502511e66..ca349c552 100644 --- a/js/ui/main.js +++ b/js/ui/main.js @@ -16,7 +16,6 @@ const Chrome = imports.ui.chrome; const Environment = imports.ui.environment; const ExtensionSystem = imports.ui.extensionSystem; const MessageTray = imports.ui.messageTray; -const Messaging = imports.ui.messaging; const Overview = imports.ui.overview; const Panel = imports.ui.panel; const PlaceDisplay = imports.ui.placeDisplay; @@ -38,7 +37,6 @@ let overview = null; let runDialog = null; let lookingGlass = null; let wm = null; -let messaging = null; let notificationDaemon = null; let notificationPopup = null; let messageTray = null; @@ -120,7 +118,6 @@ function start() { panel = new Panel.Panel(); sidebar = new Sidebar.Sidebar(); wm = new WindowManager.WindowManager(); - messaging = new Messaging.Messaging(); notificationDaemon = new NotificationDaemon.NotificationDaemon(); notificationPopup = new MessageTray.Notification(); messageTray = new MessageTray.MessageTray(); diff --git a/js/ui/messaging.js b/js/ui/messaging.js deleted file mode 100644 index 8cfc335a1..000000000 --- a/js/ui/messaging.js +++ /dev/null @@ -1,435 +0,0 @@ -/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */ - -const DBus = imports.dbus; -const Lang = imports.lang; -const Shell = imports.gi.Shell; -const St = imports.gi.St; - -const Main = imports.ui.main; -const MessageTray = imports.ui.messageTray; - -const TELEPATHY = "org.freedesktop.Telepathy."; -const CONN = TELEPATHY + "Connection"; -const CHANNEL = TELEPATHY + "Channel"; -const CHANNELTEXT = CHANNEL + ".Type.Text"; -const ACCOUNTMANAGER = TELEPATHY + 'AccountManager'; - -const ClientIface = { - name: TELEPATHY + "Client", - properties: [{ name: "Interfaces", - signature: "as", - access: "read" }] -}; - -const ClientObserverIface = { - name: TELEPATHY + "Client.Observer", - methods: [{ name: "ObserveChannels", - inSignature: "ooa(oa{sv})oaoa{sv}", - outSignature: "" }], - properties: [{ name: "ObserverChannelFilter", - signature: "aa{sv}", - access: "read" }] -}; - -const ConnectionIface = { - name: CONN, - methods: [ - // This is deprecated, but the alternative requires building - // another interface object... - { name: "ListChannels", - inSignature: "", - outSignature: "a(osuu)" - } - ], - signals: [ - { name: 'StatusChanged', inSignature: 'u' } - ] -}; - -function Connection(path) { - this._init(path); -}; - -Connection.prototype = { - _init: function(path) { - DBus.session.proxifyObject(this, nameify(path), path); - } -}; - -DBus.proxifyPrototype(Connection.prototype, ConnectionIface); - -const ConnectionAvatarsIface = { - name: CONN + '.Interface.Avatars', - methods: [ - { name: 'GetKnownAvatarTokens', - inSignature: 'au', - outSignature: 'a{us}' - }, - { name: 'RequestAvatars', - inSignature: 'au', - outSignature: '' - } - ], - signals: [ - { name: 'AvatarRetrieved', - inSignature: 'usays' - }, - { name: 'AvatarUpdated', - inSignature: 'us' - } - ] -}; - -function ConnectionAvatars(path) { - this._init(path); -}; - -ConnectionAvatars.prototype = { - _init: function(path) { - DBus.session.proxifyObject(this, nameify(path), path); - - this.connect('AvatarUpdated', Lang.bind(this, this._avatarUpdated)); - this.connect('AvatarRetrieved', Lang.bind(this, this._avatarRetrieved)); - - // _avatarData[handle] describes the icon for @handle: either - // the string 'default', meaning to use the default avatar, or - // an array of bytes containing, eg, PNG data. - this._avatarData = {}; - - // _icons[handle] is an array of the icon actors currently - // being displayed for @handle. These will be updated - // automatically if @handle's avatar changes. - this._icons = {}; - }, - - _avatarUpdated: function(iface, handle, token) { - if (!this._avatarData[handle]) { - // This would only happen if we get an AvatarUpdated - // signal for an avatar while there's already a - // RequestAvatars() call pending, so we don't need to do - // anything. - return; - } - - if (token == '') { - // Invoke the next async callback in the chain, telling - // it to use the default image. - this._avatarRetrieved(this, handle, token, 'default', null); - } else { - // In this case, @token is some sort of UUID. Telepathy - // expects us to cache avatar images to disk and use the - // tokens to figure out when we already have the right - // images cached. But we don't do that, we just - // ignore @token and request the image unconditionally. - this.RequestAvatarsRemote([handle]); - } - }, - - _createIcon: function(iconData, size) { - let textureCache = Shell.TextureCache.get_default(); - if (iconData == 'default') - return textureCache.load_icon_name('stock_person', size); - else - return textureCache.load_from_data(iconData, iconData.length, size); - }, - - _avatarRetrieved: function(iface, handle, token, avatarData, mimeType) { - this._avatarData[handle] = avatarData; - if (!this._icons[handle]) - return; - - for (let i = 0; i < this._icons[handle].length; i++) { - let iconBox = this._icons[handle][i]; - let size = iconBox.child.height; - iconBox.child = this._createIcon(avatarData, size); - } - }, - - createAvatar: function(handle, size) { - let iconBox = new St.Bin({ style_class: 'avatar-box' }); - - if (!this._icons[handle]) - this._icons[handle] = []; - this._icons[handle].push(iconBox); - - iconBox.connect('destroy', Lang.bind(this, - function() { - let i = this._icons[handle].indexOf(iconBox); - if (i != -1) - this._icons[handle].splice(i, 1); - })); - - let avatarData = this._avatarData[handle]; - if (avatarData) { - iconBox.child = this._createIcon(avatarData, size); - return iconBox; - } - - // Fill in the default icon and then asynchronously load - // the real avatar. - iconBox.child = this._createIcon('default', size); - this.GetKnownAvatarTokensRemote([handle], Lang.bind(this, - function (tokens, excp) { - if (tokens && tokens[handle]) - this.RequestAvatarsRemote([handle]); - else - this._avatarData[handle] = 'default'; - })); - - return iconBox; - } -}; - -DBus.proxifyPrototype(ConnectionAvatars.prototype, ConnectionAvatarsIface); - -const ChannelIface = { - name: CHANNEL, - properties: [ - { name: "TargetHandle", - signature: "u", - access: "read" }, - { name: "TargetID", - signature: "s", - access: "read" } - ], - signals: [ - { name: 'Closed', inSignature: '' } - ] -}; - -function Channel(name, path) { - this._init(name, path); -}; - -Channel.prototype = { - _init: function(name, path) { - DBus.session.proxifyObject(this, name, path); - } -}; - -DBus.proxifyPrototype(Channel.prototype, ChannelIface); - -const ChannelTextIface = { - name: CHANNELTEXT, - methods: [ - { name: 'ListPendingMessages', - inSignature: 'b', - outSignature: 'a(uuuuus)' - } - ], - signals: [ - { name: 'Received', inSignature: 'uuuuus' } - ] -}; - -function ChannelText(name, path) { - this._init(name, path); -}; - -ChannelText.prototype = { - _init: function(name, path) { - DBus.session.proxifyObject(this, name, path); - } -}; - -DBus.proxifyPrototype(ChannelText.prototype, ChannelTextIface); - -const AccountManagerIface = { - name: ACCOUNTMANAGER, - - properties: [{ name: "ValidAccounts", - signature: "ao", - access: "read" }] -}; - -function AccountManager() { - this._init(); -} - -AccountManager.prototype = { - _init: function() { - DBus.session.proxifyObject(this, - ACCOUNTMANAGER, - pathify(ACCOUNTMANAGER)); - } -}; - -DBus.proxifyPrototype(AccountManager.prototype, AccountManagerIface); - -const AccountIface = { - name: 'org.freedesktop.Telepathy.Account', - - properties: [{ name: "Connection", - signature: "o", - access: "read" }] -}; - -function Account(name, path) { - this._init(name, path); -} - -Account.prototype = { - _init: function(name, path) { - DBus.session.proxifyObject(this, name, path); - } -}; - -DBus.proxifyPrototype(Account.prototype, AccountIface); - -let nameify = function(path) { - return path.substr(1).replace('/', '.', 'g'); -}; - -let pathify = function(name) { - return '/' + name.replace('.', '/', 'g'); -}; - -function Messaging() { - this._init(); -}; - -Messaging.prototype = { - _init : function() { - let name = TELEPATHY + "Client.GnomeShell"; - DBus.session.exportObject(pathify(name), this); - DBus.session.acquire_name(name, DBus.SINGLE_INSTANCE, - function(name){log("Acquired name " + name);}, - function(name){log("Lost name " + name);}); - - this._conns = {}; - this._channels = {}; - - // Acquire existing connections. (This wouldn't really be - // needed if gnome-shell was only being started at the start - // of a session, but it's very useful for making things - // continue to work after restarting the shell.) - let accountManager = new AccountManager(); - accountManager.GetRemote('ValidAccounts', Lang.bind(this, this._gotValidAccounts)); - }, - - _gotValidAccounts: function(accounts, excp) { - if (!accounts) - return; - - for (let i = 0; i < accounts.length; i++) { - let account = new Account(ACCOUNTMANAGER, accounts[i]); - account.GetRemote('Connection', Lang.bind(this, - function (conn_path, excp) { - if (!conn_path || conn_path == '/') - return; - - let conn = new Connection(conn_path); - conn.ListChannelsRemote(Lang.bind(this, - function(channels, excp) { - if (!channels) { - log('no channels on ' + conn.getPath() + ': ' + excp); - return; - } - for (let i = 0; i < channels.length; i++) { - let [path, channel_type, handle_type, handle] = channels[i]; - if (channel_type != CHANNELTEXT) - continue; - if (this._channels[path]) - continue; - - let connName = nameify(conn.getPath()); - let channel = new Channel(connName, path); - channel.GetAllRemote(Lang.bind(this, - function(props, excp) { - this._addChannel(conn, path, - props['TargetHandle'], - props['TargetID']); - })); - } - })); - })); - } - }, - - get Interfaces() { - return [TELEPATHY + "Client.Observer"]; - }, - - get ObserverChannelFilter() { - return [ - { 'org.freedesktop.Telepathy.Channel.ChannelType': CHANNELTEXT } - ]; - }, - - ObserveChannels: function(account, conn_path, channels, - dispatch_operation, requests_satisfied, - observer_info) { - let conn = new Connection(conn_path); - let conn_name = nameify(conn_path); - for (let i = 0; i < channels.length; i++) { - let channelPath = channels[i][0]; - let props = channels[i][1]; - let targetHandle = props[CHANNEL + '.TargetHandle']; - let targetId = props[CHANNEL + '.TargetID']; - this._addChannel(conn, channelPath, targetHandle, targetId); - } - - return [true]; - }, - - _addChannel: function(conn, channelPath, targetHandle, targetId) { - this._channels[channelPath] = new Source(conn, channelPath, targetHandle, targetId); - } -}; - -DBus.conformExport(Messaging.prototype, ClientIface); -DBus.conformExport(Messaging.prototype, ClientObserverIface); - -function Source(conn, channelPath, channel_props, targetId) { - this._init(conn, channelPath, channel_props, targetId); -} - -Source.prototype = { - __proto__: MessageTray.Source.prototype, - - _init: function(conn, channelPath, targetHandle, targetId) { - MessageTray.Source.prototype._init.call(this, targetId); - - let connName = nameify(conn.getPath()); - this._channel = new Channel(connName, channelPath); - this._closedId = this._channel.connect('Closed', Lang.bind(this, this._channelClosed)); - - this._targetHandle = targetHandle; - this._targetId = targetId; - log('channel for ' + this._targetId + ' channelPath ' + channelPath); - - this._avatars = new ConnectionAvatars(conn.getPath()); - - this._channelText = new ChannelText(connName, channelPath); - this._receivedId = this._channelText.connect('Received', Lang.bind(this, this._receivedMessage)); - - this._channelText.ListPendingMessagesRemote(false, Lang.bind(this, this._gotPendingMessages)); - }, - - createIcon: function(size) { - return this._avatars.createAvatar(this._targetHandle, size); - }, - - _gotPendingMessages: function(msgs, excp) { - if (!msgs) - return; - - for (let i = 0; i < msgs.length; i++) - this._receivedMessage.apply(this, [this._channel].concat(msgs[i])); - }, - - _channelClosed: function() { - log('Channel closed ' + this._targetId); - this._channel.disconnect(this._closedId); - this._channelText.disconnect(this._receivedId); - this.destroy(); - }, - - _receivedMessage: function(channel, id, timestamp, sender, - type, flags, text) { - log('Received: id ' + id + ', time ' + timestamp + ', sender ' + sender + ', type ' + type + ', flags ' + flags + ': ' + text); - if (!Main.messageTray.contains(this)) - Main.messageTray.add(this); - this.notify(text); - } -};