Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @fileoverview | 6 * @fileoverview |
| 7 * Functions related to the 'home screen' for Chromoting. | 7 * Functions related to the 'home screen' for Chromoting. |
| 8 */ | 8 */ |
| 9 | 9 |
| 10 'use strict'; | 10 'use strict'; |
| 11 | 11 |
| 12 /** @suppress {duplicate} */ | 12 /** @suppress {duplicate} */ |
| 13 var remoting = remoting || {}; | 13 var remoting = remoting || {}; |
| 14 | 14 |
| 15 /** | |
| 16 * Cache of the latest host list and status information. | |
| 17 * | |
| 18 * @type {Array.<{hostName: string, hostId: string, status: string, | |
| 19 * jabberId: string, publicKey: string}>} | |
| 20 * | |
| 21 */ | |
| 22 remoting.hostList = new Array(); | |
| 23 | |
| 24 (function() { | 15 (function() { |
| 25 | 16 |
| 26 /** | 17 /** |
| 27 * Query the Remoting Directory for the user's list of hosts. | 18 * Query the Remoting Directory for the user's list of hosts. |
| 28 * | 19 * |
| 29 * @return {void} Nothing. | 20 * @return {void} Nothing. |
| 30 */ | 21 */ |
| 31 remoting.refreshHostList = function() { | 22 remoting.refreshHostList = function() { |
| 32 // Fetch a new Access Token for the user, if necessary. | 23 // Fetch a new Access Token for the user, if necessary. |
| 33 if (remoting.oauth2.needsNewAccessToken()) { | 24 if (remoting.oauth2.needsNewAccessToken()) { |
| 34 remoting.oauth2.refreshAccessToken(function(xhr) { | 25 remoting.oauth2.refreshAccessToken(function(xhr) { |
| 35 if (remoting.oauth2.needsNewAccessToken()) { | 26 if (remoting.oauth2.needsNewAccessToken()) { |
| 36 // Failed to get access token | 27 // Failed to get access token |
| 37 console.error('refreshHostList: OAuth2 token fetch failed'); | 28 console.error('refreshHostList: OAuth2 token fetch failed'); |
| 38 showHostListError_(remoting.Error.AUTHENTICATION_FAILED); | 29 remoting.hostList.showError(remoting.Error.AUTHENTICATION_FAILED); |
| 39 return; | 30 return; |
| 40 } | 31 } |
| 41 remoting.refreshHostList(); | 32 remoting.refreshHostList(); |
| 42 }); | 33 }); |
| 43 return; | 34 return; |
| 44 } | 35 } |
| 45 | 36 |
| 46 var headers = { | 37 var headers = { |
| 47 'Authorization': 'OAuth ' + remoting.oauth2.getAccessToken() | 38 'Authorization': 'OAuth ' + remoting.oauth2.getAccessToken() |
| 48 }; | 39 }; |
| 49 | 40 |
| 50 var xhr = remoting.xhr.get( | 41 var xhr = remoting.xhr.get( |
| 51 'https://www.googleapis.com/chromoting/v1/@me/hosts', | 42 'https://www.googleapis.com/chromoting/v1/@me/hosts', |
| 52 parseHostListResponse_, | 43 parseHostListResponse_, |
| 53 '', | 44 '', |
| 54 headers); | 45 headers); |
| 55 } | 46 } |
| 56 | 47 |
| 57 /** | 48 /** |
| 58 * Handle the results of the host list request. A success response will | 49 * Handle the results of the host list request. A success response will |
| 59 * include a JSON-encoded list of host descriptions, which we display if we're | 50 * include a JSON-encoded list of host descriptions, which we display if we're |
| 60 * able to successfully parse it. | 51 * able to successfully parse it. |
| 61 * | 52 * |
| 62 * @param {XMLHttpRequest} xhr The XHR object for the host list request. | 53 * @param {XMLHttpRequest} xhr The XHR object for the host list request. |
| 63 * @return {void} Nothing. | 54 * @return {void} Nothing. |
| 64 */ | 55 */ |
| 65 function parseHostListResponse_(xhr) { | 56 function parseHostListResponse_(xhr) { |
|
Wez
2011/11/16 21:41:23
Would it make sense to move the XHR dispatch and p
Jamie
2011/11/16 22:09:09
You could make a case either way. I think I'd pref
| |
| 66 // Ignore host list responses if we're not on the Home screen. This mainly | 57 // Ignore host list responses if we're not on the Home screen. This mainly |
| 67 // ensures that errors don't cause an unexpected mode switch. | 58 // ensures that errors don't cause an unexpected mode switch. |
| 68 if (remoting.currentMode != remoting.AppMode.HOME) { | 59 if (remoting.currentMode != remoting.AppMode.HOME) { |
| 69 return; | 60 return; |
| 70 } | 61 } |
| 71 | 62 |
| 72 if (xhr.readyState != 4) { | 63 if (xhr.readyState != 4) { |
| 73 return; | 64 return; |
| 74 } | 65 } |
| 75 | 66 |
| 76 try { | 67 try { |
| 77 if (xhr.status == 200) { | 68 if (xhr.status == 200) { |
| 78 var parsed_response = | 69 var parsed_response = |
| 79 /** @type {{data: {items: Array}}} */ JSON.parse(xhr.responseText); | 70 /** @type {{data: {items: Array}}} */ JSON.parse(xhr.responseText); |
| 80 if (parsed_response.data && parsed_response.data.items) { | 71 if (parsed_response.data && parsed_response.data.items) { |
| 81 replaceHostList_(parsed_response.data.items); | 72 remoting.hostList.update(parsed_response.data.items); |
| 82 } | 73 } |
| 83 } else { | 74 } else { |
| 84 // Some other error. Log for now, pretty-print in future. | 75 // Some other error. Log for now, pretty-print in future. |
| 85 console.error('Bad status on host list query: ', xhr); | 76 console.error('Bad status on host list query: ', xhr); |
| 86 var errorResponse = | 77 var errorResponse = |
| 87 /** @type {{error: {code: *, message: *}}} */ | 78 /** @type {{error: {code: *, message: *}}} */ |
| 88 JSON.parse(xhr.responseText); | 79 JSON.parse(xhr.responseText); |
| 89 if (errorResponse.error && | 80 if (errorResponse.error && |
| 90 errorResponse.error.code && | 81 errorResponse.error.code && |
| 91 errorResponse.error.message) { | 82 errorResponse.error.message) { |
| 92 remoting.debug.log('Error code ' + errorResponse.error.code); | 83 remoting.debug.log('Error code ' + errorResponse.error.code); |
| 93 remoting.debug.log('Error message ' + errorResponse.error.message); | 84 remoting.debug.log('Error message ' + errorResponse.error.message); |
| 94 } else { | 85 } else { |
| 95 remoting.debug.log('Error response: ' + xhr.responseText); | 86 remoting.debug.log('Error response: ' + xhr.responseText); |
| 96 } | 87 } |
| 97 | 88 |
| 98 // For most errors in the 4xx range, tell the user to re-authorize us. | 89 // For most errors in the 4xx range, tell the user to re-authorize us. |
| 99 if (xhr.status == 403) { | 90 if (xhr.status == 403) { |
| 100 // The user's account is not enabled for Me2Me, so fail silently. | 91 // The user's account is not enabled for Me2Me, so fail silently. |
| 101 } else if (xhr.status >= 400 && xhr.status <= 499) { | 92 } else if (xhr.status >= 400 && xhr.status <= 499) { |
| 102 showHostListError_(remoting.Error.GENERIC); | 93 remoting.hostList.showError(remoting.Error.GENERIC); |
| 103 } | 94 } |
| 104 } | 95 } |
| 105 } catch (er) { | 96 } catch (er) { |
| 106 console.error('Error processing response: ', xhr); | 97 console.error('Error processing response: ', xhr); |
| 107 } | 98 } |
| 108 } | 99 } |
| 109 | 100 |
| 110 /** | |
| 111 * Refresh the host list display with up to date host details. | |
| 112 * | |
| 113 * @param {Array.<{hostName: string, hostId: string, status: string, | |
| 114 * jabberId: string, publicKey: string}>} hostList | |
| 115 * The new list of registered hosts. | |
| 116 * @return {void} Nothing. | |
| 117 */ | |
| 118 function replaceHostList_(hostList) { | |
| 119 var hostListDiv = document.getElementById('host-list-div'); | |
| 120 var hostListTable = document.getElementById('host-list'); | |
| 121 | |
| 122 remoting.hostList = hostList; | |
| 123 | |
| 124 // Clear the table before adding the host info. | |
| 125 hostListTable.innerHTML = ''; | |
| 126 showHostListError_(null); | |
| 127 | |
| 128 for (var i = 0; i < hostList.length; ++i) { | |
| 129 var host = hostList[i]; | |
| 130 if (!host.hostName || !host.hostId || !host.status || !host.jabberId || | |
| 131 !host.publicKey) | |
| 132 continue; | |
| 133 var hostEntry = document.createElement('tr'); | |
| 134 addClass(hostEntry, 'host-list-row'); | |
| 135 | |
| 136 var hostIcon = document.createElement('td'); | |
| 137 var hostIconImage = document.createElement('img'); | |
| 138 hostIconImage.src = 'icon_host.png'; | |
| 139 hostIcon.className = 'host-list-row-start'; | |
| 140 hostIcon.appendChild(hostIconImage); | |
| 141 hostEntry.appendChild(hostIcon); | |
| 142 | |
| 143 var hostName = document.createElement('td'); | |
| 144 hostName.setAttribute('class', 'mode-select-label'); | |
| 145 hostName.appendChild(document.createTextNode(host.hostName)); | |
| 146 hostEntry.appendChild(hostName); | |
| 147 | |
| 148 var hostStatus = document.createElement('td'); | |
| 149 if (host.status == 'ONLINE') { | |
| 150 var connectButton = document.createElement('button'); | |
| 151 connectButton.setAttribute('class', 'mode-select-button'); | |
| 152 connectButton.setAttribute('type', 'button'); | |
| 153 connectButton.setAttribute('onclick', | |
| 154 'remoting.connectHost("'+host.hostId+'")'); | |
| 155 connectButton.innerHTML = | |
| 156 chrome.i18n.getMessage(/*i18n-content*/'CONNECT_BUTTON'); | |
| 157 hostStatus.appendChild(connectButton); | |
| 158 } else { | |
| 159 addClass(hostEntry, 'host-offline'); | |
| 160 hostStatus.innerHTML = chrome.i18n.getMessage(/*i18n-content*/'OFFLINE'); | |
| 161 } | |
| 162 hostStatus.className = 'host-list-row-end'; | |
| 163 hostEntry.appendChild(hostStatus); | |
| 164 | |
| 165 hostListTable.appendChild(hostEntry); | |
| 166 } | |
| 167 | |
| 168 showHostList_(hostList.length != 0); | |
| 169 } | |
| 170 | |
| 171 /** | |
| 172 * Show or hide the host list. | |
| 173 * @param {boolean} show True to show the list or false to hide it. | |
| 174 * @return {void} | |
| 175 */ | |
| 176 function showHostList_(show) { | |
| 177 var hostListDiv = document.getElementById('host-list-div'); | |
| 178 hostListDiv.hidden = (!show); | |
| 179 if (show) { | |
| 180 hostListDiv.style.height = hostListDiv.scrollHeight + 'px'; | |
| 181 removeClass(hostListDiv, 'collapsed'); | |
| 182 } else { | |
| 183 addClass(hostListDiv, 'collapsed'); | |
| 184 } | |
| 185 } | |
| 186 | |
| 187 /** | |
| 188 * Show an error message in the host list portion of the UI. | |
| 189 * | |
| 190 * @param {remoting.Error?} errorTag The error to display, or NULL to clear any | |
| 191 * previous error. | |
| 192 * @return {void} Nothing. | |
| 193 */ | |
| 194 function showHostListError_(errorTag) { | |
| 195 var hostListTable = document.getElementById('host-list'); | |
| 196 hostListTable.innerHTML = ''; | |
| 197 var errorDiv = document.getElementById('host-list-error'); | |
| 198 if (errorTag) { | |
| 199 l10n.localizeElementFromTag(errorDiv, /** @type {string} */ (errorTag)); | |
| 200 showHostList_(true); | |
| 201 } else { | |
| 202 errorDiv.innerText = ''; | |
| 203 } | |
| 204 } | |
| 205 | |
| 206 }()); | 101 }()); |
| OLD | NEW |