diff options
Diffstat (limited to 'remoting/webapp/me2mom/host_list.js')
-rw-r--r-- | remoting/webapp/me2mom/host_list.js | 242 |
1 files changed, 172 insertions, 70 deletions
diff --git a/remoting/webapp/me2mom/host_list.js b/remoting/webapp/me2mom/host_list.js index d84d73e..8fd59c0 100644 --- a/remoting/webapp/me2mom/host_list.js +++ b/remoting/webapp/me2mom/host_list.js @@ -13,87 +13,128 @@ var remoting = remoting || {}; /** + * Create a host list consisting of the specified HTML elements, which should + * have a common parent that contains only host-list UI as it will be hidden + * if the host-list is empty. * @constructor + * @param {Element} table The HTML <table> to contain host-list. + * @param {Element} errorDiv The HTML <div> to display error messages. */ -remoting.Host = function() { - /** @type {string} */ - this.hostName = ''; - /** @type {string} */ - this.hostId = ''; - /** @type {string} */ - this.status = ''; - /** @type {string} */ - this.jabberId = ''; - /** @type {string} */ - this.publicKey = ''; -} +remoting.HostList = function(table, errorDiv) { + /** + * @type {Element} + * @private + */ + this.table_ = table; + /** + * @type {Element} + * @private + */ + this.errorDiv_ = errorDiv; + /** + * @type {Array.<remoting.HostTableEntry>} + * @private + */ + this.hostTableEntries_ = null; +}; +/** + * Search the host list for a host with the specified id. + * @param {string} hostId The unique id of the host. + * @return {remoting.HostTableEntry?} The host table entry, if any. + */ +remoting.HostList.prototype.getHostForId = function(hostId) { + for (var i = 0; i < this.hostTableEntries_.length; ++i) { + if (this.hostTableEntries_[i].host.hostId == hostId) { + return this.hostTableEntries_[i]; + } + } + return null; +}; /** - * @constructor - * @param {Element} table The HTML <table> to contain host-list. - * @param {Element} errorDiv The HTML <div> to display error messages. + * Query the Remoting Directory for the user's list of hosts. + * + * @return {void} Nothing. */ -remoting.HostList = function(table, errorDiv) { - this.table = table; - this.errorDiv = errorDiv; - /** @type {Array.<remoting.Host>} */ - this.hosts = null; +remoting.HostList.prototype.refresh = function() { + /** @type {remoting.HostList} */ + var that = this; + /** @param {XMLHttpRequest} xhr */ + var parseHostListResponse = function(xhr) { + that.parseHostListResponse_(xhr); + } + /** @param {string} token */ + var getHosts = function(token) { + var headers = { 'Authorization': 'OAuth ' + token }; + remoting.xhr.get( + 'https://www.googleapis.com/chromoting/v1/@me/hosts', + parseHostListResponse, '', headers); + }; + remoting.oauth2.callWithToken(getHosts); +} + +/** + * Handle the results of the host list request. A success response will + * include a JSON-encoded list of host descriptions, which we display if we're + * able to successfully parse it. + * + * @param {XMLHttpRequest} xhr The XHR object for the host list request. + * @return {void} Nothing. + */ +remoting.HostList.prototype.parseHostListResponse_ = function(xhr) { + try { + if (xhr.status == 200) { + var parsed_response = + /** @type {{data: {items: Array}}} */ JSON.parse(xhr.responseText); + if (parsed_response.data && parsed_response.data.items) { + this.setHosts_(parsed_response.data.items); + } + } else { + // Some other error. + console.error('Bad status on host list query: ', xhr); + // For most errors in the 4xx range, tell the user to re-authorize us. + if (xhr.status == 403) { + // The user's account is not enabled for Me2Me, so fail silently. + } else if (xhr.status >= 400 && xhr.status <= 499) { + this.showError_(remoting.Error.GENERIC); + } + } + } catch (er) { + console.error('Error processing response: ', xhr, er); + } } /** * Refresh the host list with up-to-date details. * @param {Array.<remoting.Host>} hosts The new host list. * @return {void} Nothing. + * @private */ -remoting.HostList.prototype.update = function(hosts) { - this.table.innerHTML = ''; - this.showError(null); - this.hosts = hosts; +remoting.HostList.prototype.setHosts_ = function(hosts) { + this.table_.innerHTML = ''; + this.showError_(null); + this.hostTableEntries_ = []; + /** @type {remoting.HostList} */ + var that = this; for (var i = 0; i < hosts.length; ++i) { + /** @type {remoting.Host} */ var host = hosts[i]; - if (!host.hostName || !host.hostId || !host.status || !host.jabberId || - !host.publicKey) - continue; - - var hostEntry = document.createElement('tr'); - addClass(hostEntry, 'host-list-row'); - - var hostIcon = document.createElement('td'); - var hostIconImage = document.createElement('img'); - hostIconImage.src = 'icon_host.png'; - hostIcon.className = 'host-list-row-start'; - hostIcon.appendChild(hostIconImage); - hostEntry.appendChild(hostIcon); - - var hostName = document.createElement('td'); - hostName.setAttribute('class', 'mode-select-label'); - hostName.appendChild(document.createTextNode(host.hostName)); - hostEntry.appendChild(hostName); - - var hostStatus = document.createElement('td'); - if (host.status == 'ONLINE') { - var connectButton = document.createElement('button'); - connectButton.setAttribute('class', 'mode-select-button'); - connectButton.setAttribute('type', 'button'); - connectButton.setAttribute('onclick', - 'remoting.connectHost("'+host.hostId+'")'); - connectButton.innerHTML = - chrome.i18n.getMessage(/*i18n-content*/'CONNECT_BUTTON'); - hostStatus.appendChild(connectButton); - } else { - addClass(hostEntry, 'host-offline'); - hostStatus.innerHTML = chrome.i18n.getMessage(/*i18n-content*/'OFFLINE'); + // Validate the entry to make sure it has all the fields we expect. + if (host.hostName && host.hostId && host.status && host.jabberId && + host.publicKey) { + var onRename = function() { that.renameHost_(host.hostId); } + var onDelete = function() { that.deleteHost_(host.hostId); } + var hostTableEntry = new remoting.HostTableEntry(); + hostTableEntry.init(host, onRename, onDelete); + this.hostTableEntries_[i] = hostTableEntry; + this.table_.appendChild(hostTableEntry.tableRow); } - hostStatus.className = 'host-list-row-end'; - hostEntry.appendChild(hostStatus); - - this.table.appendChild(hostEntry); } - this.showOrHide_(this.hosts.length != 0); -} + this.showOrHide_(this.hostTableEntries_.length != 0); +}; /** * Display a localized error message. @@ -101,16 +142,16 @@ remoting.HostList.prototype.update = function(hosts) { * previous error. * @return {void} Nothing. */ -remoting.HostList.prototype.showError = function(errorTag) { - this.table.innerHTML = ''; +remoting.HostList.prototype.showError_ = function(errorTag) { + this.table_.innerHTML = ''; if (errorTag) { - l10n.localizeElementFromTag(this.errorDiv, + l10n.localizeElementFromTag(this.errorDiv_, /** @type {string} */ (errorTag)); this.showOrHide_(true); } else { - this.errorDiv.innerText = ''; + this.errorDiv_.innerText = ''; } -} +}; /** * Show or hide the host-list UI. @@ -119,7 +160,7 @@ remoting.HostList.prototype.showError = function(errorTag) { * @private */ remoting.HostList.prototype.showOrHide_ = function(show) { - var parent = /** @type {Element} */ (this.table.parentNode); + var parent = /** @type {Element} */ (this.table_.parentNode); parent.hidden = !show; if (show) { parent.style.height = parent.scrollHeight + 'px'; @@ -127,7 +168,68 @@ remoting.HostList.prototype.showOrHide_ = function(show) { } else { addClass(parent, remoting.HostList.COLLAPSED_); } -} +}; + +/** + * Remove a host from the list, and deregister it. + * @param {string} hostId The id of the host to be removed. + * @return {void} Nothing. + * @private + */ +remoting.HostList.prototype.deleteHost_ = function(hostId) { + /** @type {remoting.HostTableEntry} */ + var hostTableEntry = this.getHostForId(hostId); + if (!hostTableEntry) { + console.error('No host registered for id ' + hostId); + return; + } + + this.table_.removeChild(hostTableEntry.tableRow); + var index = this.hostTableEntries_.indexOf(hostTableEntry); + if (index != -1) { // Since we've just found it, index must be >= 0 + this.hostTableEntries_.splice(index, 1); + } + + /** @param {string} token */ + var deleteHost = function(token) { + var headers = { 'Authorization': 'OAuth ' + token }; + remoting.xhr.remove( + 'https://www.googleapis.com/chromoting/v1/@me/hosts/' + hostId, + function() {}, '', headers); + } + remoting.oauth2.callWithToken(deleteHost); + + this.showOrHide_(this.hostTableEntries_.length != 0); +}; + +/** + * Prepare a host for renaming by replacing its name with an edit box. + * @param {string} hostId The id of the host to be renamed. + * @return {void} Nothing. + * @private + */ +remoting.HostList.prototype.renameHost_ = function(hostId) { + /** @type {remoting.HostTableEntry} */ + var hostTableEntry = this.getHostForId(hostId); + if (!hostTableEntry) { + console.error('No host registered for id ' + hostId); + return; + } + /** @param {string} token */ + var renameHost = function(token) { + var headers = { + 'Authorization': 'OAuth ' + token, + 'Content-type' : 'application/json; charset=UTF-8' + }; + var newHostDetails = { data: hostTableEntry.host }; + remoting.xhr.put( + 'https://www.googleapis.com/chromoting/v1/@me/hosts/' + hostId, + function(xhr) {}, + JSON.stringify(newHostDetails), + headers); + } + remoting.oauth2.callWithToken(renameHost); +}; /** * Class name for the host list when it is collapsed. @@ -136,4 +238,4 @@ remoting.HostList.prototype.showOrHide_ = function(show) { remoting.HostList.COLLAPSED_ = 'collapsed'; /** @type {remoting.HostList} */ -remoting.hostList = null;
\ No newline at end of file +remoting.hostList = null; |