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 |