| Index: remoting/webapp/me2mom/host_list.js
|
| diff --git a/remoting/webapp/me2mom/host_list.js b/remoting/webapp/me2mom/host_list.js
|
| index d84d73edf7d8119dc0348e45707d700abea0e109..8fd59c0cf9a1f66d12e7c437174382b67bda7633 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;
|
| +remoting.hostList = null;
|
|
|