@webex/plugin-device-manager 2.59.2 → 2.59.3-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +6 -6
- package/README.md +80 -80
- package/babel.config.js +3 -3
- package/dist/collection.js.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.js.map +1 -1
- package/dist/device-manager.js +104 -104
- package/dist/device-manager.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/jest.config.js +3 -3
- package/package.json +20 -19
- package/process +1 -1
- package/sample/app.js +453 -453
- package/sample/index.html +121 -121
- package/src/collection.js +32 -32
- package/src/config.js +1 -1
- package/src/constants.js +3 -3
- package/src/device-manager.js +643 -643
- package/src/index.js +18 -18
- package/test/unit/spec/index.js +11 -11
- package/webex.js +42 -42
package/sample/app.js
CHANGED
|
@@ -1,453 +1,453 @@
|
|
|
1
|
-
/* eslint-env browser */
|
|
2
|
-
|
|
3
|
-
/* global Webex */
|
|
4
|
-
|
|
5
|
-
/* eslint-disable camelcase */
|
|
6
|
-
/* eslint-disable max-nested-callbacks */
|
|
7
|
-
/* eslint-disable no-alert */
|
|
8
|
-
/* eslint-disable no-console */
|
|
9
|
-
/* eslint-disable require-jsdoc */
|
|
10
|
-
|
|
11
|
-
// Declare some globals that we'll need throughout
|
|
12
|
-
let webex;
|
|
13
|
-
// First, let's wire our form fields up to localStorage so we don't have to
|
|
14
|
-
// retype things everytime we reload the page.
|
|
15
|
-
|
|
16
|
-
[
|
|
17
|
-
'access-token',
|
|
18
|
-
// 'invitee'
|
|
19
|
-
].forEach((id) => {
|
|
20
|
-
const el = document.getElementById(id);
|
|
21
|
-
|
|
22
|
-
el.value = localStorage.getItem(id);
|
|
23
|
-
el.addEventListener('change', (event) => {
|
|
24
|
-
localStorage.setItem(id, event.target.value);
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
function notify(message) {
|
|
29
|
-
document.getElementById('notifications').innerHTML = message;
|
|
30
|
-
setTimeout(() => {
|
|
31
|
-
document.getElementById('notifications').innerHTML = '';
|
|
32
|
-
}, 5000);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function populateDeviceDropdown(devices) {
|
|
36
|
-
const deviceListDropdown = document.getElementById('device-list-dropdown');
|
|
37
|
-
|
|
38
|
-
deviceListDropdown.length = 0;
|
|
39
|
-
|
|
40
|
-
const defaultOption = document.createElement('option');
|
|
41
|
-
|
|
42
|
-
defaultOption.text = 'Choose a Device';
|
|
43
|
-
deviceListDropdown.add(defaultOption);
|
|
44
|
-
deviceListDropdown.selectedIndex = 0;
|
|
45
|
-
|
|
46
|
-
let option;
|
|
47
|
-
|
|
48
|
-
devices.forEach((device) => {
|
|
49
|
-
option = document.createElement('option');
|
|
50
|
-
option.text = device.deviceInfo.description || device.deviceInfo.name;
|
|
51
|
-
option.value = device.id;
|
|
52
|
-
deviceListDropdown.add(option);
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function toggleDisplay(elementId, status) {
|
|
57
|
-
const element = document.getElementById(elementId);
|
|
58
|
-
|
|
59
|
-
if (status) {
|
|
60
|
-
element.style.display = 'block';
|
|
61
|
-
} else {
|
|
62
|
-
element.style.display = 'none';
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function populateDeviceAudioState(audioState) {
|
|
67
|
-
document.getElementById('getAudioStateContentsDiv').innerHTML = `<div>
|
|
68
|
-
<ul>
|
|
69
|
-
<li>Muted: ${audioState.microphones.muted}</li>
|
|
70
|
-
<li>volume current level: ${audioState.volume.level}</li>
|
|
71
|
-
<li>volume max level: ${audioState.volume.max}</li>
|
|
72
|
-
<li>volume min level: ${audioState.volume.min}</li>
|
|
73
|
-
<li>volume step level: ${audioState.volume.step}</li>
|
|
74
|
-
</ul>
|
|
75
|
-
<div id='hideAudioStateBtnDiv' style=muted"display:none;">
|
|
76
|
-
<button id="hideAudioState" title="hideAudioState" type="button">hideAudioState</button>
|
|
77
|
-
</div>
|
|
78
|
-
</div>`;
|
|
79
|
-
toggleDisplay('getAudioStateContentsDiv', true);
|
|
80
|
-
toggleDisplay('hideAudioStateBtnDiv', true);
|
|
81
|
-
// hideAudioState of the paired device
|
|
82
|
-
document.getElementById('hideAudioState').addEventListener('click', () => {
|
|
83
|
-
toggleDisplay('getAudioStateContentsDiv', false);
|
|
84
|
-
toggleDisplay('hideAudioStateBtnDiv', false);
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function populateDeviceSearchResults(response) {
|
|
89
|
-
let devices = '';
|
|
90
|
-
|
|
91
|
-
response.forEach((device) => {
|
|
92
|
-
devices += `
|
|
93
|
-
<li style='list-style-type: none'>
|
|
94
|
-
<input type='radio' name='deviceRadio' onclick='requestPinChallenge("${device.id}")'/>
|
|
95
|
-
<label>${device.description || device.name}</label>
|
|
96
|
-
</li>`;
|
|
97
|
-
});
|
|
98
|
-
document.getElementById('getDeviceSearchResultsDiv').innerHTML = `<div>
|
|
99
|
-
<ul>
|
|
100
|
-
${devices}
|
|
101
|
-
</ul>
|
|
102
|
-
<div id='hideDeviceSearchResultsBtnDiv' style=muted"display:none;">
|
|
103
|
-
<button id="hideDeviceSearchResults" title="hideDeviceSearchResults" type="button">hideDeviceSearchResults</button>
|
|
104
|
-
</div>
|
|
105
|
-
</div>`;
|
|
106
|
-
toggleDisplay('getDeviceSearchResultsDiv', true);
|
|
107
|
-
toggleDisplay('hideDeviceSearchResults', true);
|
|
108
|
-
// hideAudioState of the paired device
|
|
109
|
-
document.getElementById('hideDeviceSearchResults').addEventListener('click', () => {
|
|
110
|
-
toggleDisplay('getDeviceSearchResultsDiv', false);
|
|
111
|
-
toggleDisplay('hideDeviceSearchResults', false);
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function connect() {
|
|
116
|
-
if (!webex) {
|
|
117
|
-
webex = Webex.init({
|
|
118
|
-
config: {
|
|
119
|
-
// Any other sdk config we need
|
|
120
|
-
},
|
|
121
|
-
credentials: {
|
|
122
|
-
access_token: document.getElementById('access-token').value,
|
|
123
|
-
},
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (!webex.internal.device.registered) {
|
|
128
|
-
webex.internal.device
|
|
129
|
-
.register()
|
|
130
|
-
.then(() => {
|
|
131
|
-
// This is just a little helper for our selenium tests and doesn't
|
|
132
|
-
// really matter for the example
|
|
133
|
-
document.body.classList.add('listening');
|
|
134
|
-
document.getElementById('connection-status').innerHTML = 'connected';
|
|
135
|
-
|
|
136
|
-
// return this.webex.internal.device.register()
|
|
137
|
-
return webex.internal.mercury.connect();
|
|
138
|
-
})
|
|
139
|
-
// This is a terrible way to handle errors, but anything more specific is
|
|
140
|
-
// going to depend a lot on your app
|
|
141
|
-
.catch((err) => {
|
|
142
|
-
console.error(err);
|
|
143
|
-
// we'll rethrow here since we didn't really *handle* the error, we just
|
|
144
|
-
// reported it
|
|
145
|
-
throw err;
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
function requestPinChallenge(deviceId) {
|
|
151
|
-
return webex.devicemanager.requestPin({id: deviceId}).then(() => {
|
|
152
|
-
toggleDisplay('enterPinDiv', true);
|
|
153
|
-
toggleDisplay('requestPairingBtnDiv', true);
|
|
154
|
-
notify('Enter the PIN');
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
document.getElementById('deviceControls').refresh.addEventListener('click', () => {
|
|
159
|
-
if (webex.devicemanager) {
|
|
160
|
-
notify('Listing devices...');
|
|
161
|
-
|
|
162
|
-
return webex.devicemanager.refresh().then((devices) => {
|
|
163
|
-
populateDeviceDropdown(devices);
|
|
164
|
-
notify('');
|
|
165
|
-
toggleDisplay('requestPinDiv', true);
|
|
166
|
-
toggleDisplay('removeBtnDiv', true);
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
return false;
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
// when PIN is requested
|
|
174
|
-
document.getElementById('requestPin').addEventListener('click', () => {
|
|
175
|
-
if (webex.devicemanager) {
|
|
176
|
-
notify('Requesting Pin...');
|
|
177
|
-
const dropdown = document.getElementById('device-list-dropdown');
|
|
178
|
-
const deviceId = dropdown.options[dropdown.selectedIndex].value;
|
|
179
|
-
|
|
180
|
-
if (deviceId && deviceId !== 'Choose a Device') {
|
|
181
|
-
return requestPinChallenge(deviceId);
|
|
182
|
-
}
|
|
183
|
-
notify('Select a device first');
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
return false;
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
// when device pairing is requested
|
|
190
|
-
document.getElementById('requestPairing').addEventListener('click', () => {
|
|
191
|
-
if (webex.devicemanager) {
|
|
192
|
-
notify('Pairing...');
|
|
193
|
-
const pin = document.getElementById('pin').value;
|
|
194
|
-
|
|
195
|
-
return webex.devicemanager
|
|
196
|
-
.pair({pin})
|
|
197
|
-
.then(() => {
|
|
198
|
-
notify('Paired');
|
|
199
|
-
toggleDisplay('requestUnPairingBtnDiv', true);
|
|
200
|
-
toggleDisplay('getAudioStateBtnDiv', true);
|
|
201
|
-
toggleDisplay('volumeUpBtnDiv', true);
|
|
202
|
-
toggleDisplay('volumeDownBtnDiv', true);
|
|
203
|
-
toggleDisplay('muteBtnDiv', true);
|
|
204
|
-
toggleDisplay('enterConvoIdDiv', true);
|
|
205
|
-
toggleDisplay('bindSpaceBtnDiv', true);
|
|
206
|
-
})
|
|
207
|
-
.then(() => webex.devicemanager.refresh())
|
|
208
|
-
.then((devices) => {
|
|
209
|
-
populateDeviceDropdown(devices);
|
|
210
|
-
notify('');
|
|
211
|
-
toggleDisplay('requestPinDiv', true);
|
|
212
|
-
toggleDisplay('removeBtnDiv', true);
|
|
213
|
-
})
|
|
214
|
-
.catch(() => {
|
|
215
|
-
notify('Incorrect PIN');
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
return false;
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
// when device unpairing is requested
|
|
223
|
-
document.getElementById('requestUnPairing').addEventListener('click', () => {
|
|
224
|
-
if (webex.devicemanager) {
|
|
225
|
-
notify('UnPairing...');
|
|
226
|
-
|
|
227
|
-
return webex.devicemanager.unpair().then(() => {
|
|
228
|
-
notify('UnPaired');
|
|
229
|
-
toggleDisplay('requestUnPairingBtnDiv', false);
|
|
230
|
-
toggleDisplay('requestPairingBtnDiv', false);
|
|
231
|
-
toggleDisplay('enterPinDiv', false);
|
|
232
|
-
toggleDisplay('getAudioStateBtnDiv', false);
|
|
233
|
-
toggleDisplay('hideAudioStateBtnDiv', false);
|
|
234
|
-
toggleDisplay('getAudioStateContentsDiv', false);
|
|
235
|
-
toggleDisplay('volumeUpBtnDiv', false);
|
|
236
|
-
toggleDisplay('volumeDownBtnDiv', false);
|
|
237
|
-
toggleDisplay('muteBtnDiv', false);
|
|
238
|
-
toggleDisplay('unmuteBtnDiv', false);
|
|
239
|
-
toggleDisplay('enterConvoIdDiv', false);
|
|
240
|
-
toggleDisplay('bindSpaceBtnDiv', false);
|
|
241
|
-
toggleDisplay('unbindSpaceBtnDiv', false);
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
return false;
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
// getAudioState of the paired device
|
|
249
|
-
document.getElementById('getAudioState').addEventListener('click', () => {
|
|
250
|
-
if (webex.devicemanager) {
|
|
251
|
-
notify('GettingAudioState...');
|
|
252
|
-
|
|
253
|
-
return webex.devicemanager.getAudioState().then((res) => {
|
|
254
|
-
populateDeviceAudioState(res);
|
|
255
|
-
notify('Audio State fetched');
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
return false;
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
// increase volume of paired device
|
|
263
|
-
document.getElementById('volumeUp').addEventListener('click', () => {
|
|
264
|
-
if (webex.devicemanager) {
|
|
265
|
-
notify('Increasing Volume...');
|
|
266
|
-
|
|
267
|
-
return webex.devicemanager
|
|
268
|
-
.increaseVolume()
|
|
269
|
-
.then(() => webex.devicemanager.getAudioState())
|
|
270
|
-
.then((res) => {
|
|
271
|
-
populateDeviceAudioState(res);
|
|
272
|
-
notify('Volume Increased');
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
return false;
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
// increase volume of paired device
|
|
280
|
-
document.getElementById('volumeDown').addEventListener('click', () => {
|
|
281
|
-
if (webex.devicemanager) {
|
|
282
|
-
notify('Decreasing Volume...');
|
|
283
|
-
|
|
284
|
-
return webex.devicemanager
|
|
285
|
-
.decreaseVolume()
|
|
286
|
-
.then(() => webex.devicemanager.getAudioState())
|
|
287
|
-
.then((res) => {
|
|
288
|
-
populateDeviceAudioState(res);
|
|
289
|
-
notify('Volume Decreased');
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
return false;
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
// mute paired device
|
|
297
|
-
document.getElementById('mute').addEventListener('click', () => {
|
|
298
|
-
if (webex.devicemanager) {
|
|
299
|
-
notify('Muting...');
|
|
300
|
-
|
|
301
|
-
return webex.devicemanager
|
|
302
|
-
.mute()
|
|
303
|
-
.then(() => webex.devicemanager.getAudioState())
|
|
304
|
-
.then((res) => {
|
|
305
|
-
populateDeviceAudioState(res);
|
|
306
|
-
notify('Muted');
|
|
307
|
-
toggleDisplay('muteBtnDiv', false);
|
|
308
|
-
toggleDisplay('unmuteBtnDiv', true);
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
return false;
|
|
313
|
-
});
|
|
314
|
-
|
|
315
|
-
// unmute paired device
|
|
316
|
-
document.getElementById('unmute').addEventListener('click', () => {
|
|
317
|
-
if (webex.devicemanager) {
|
|
318
|
-
notify('UnMuting');
|
|
319
|
-
|
|
320
|
-
return webex.devicemanager
|
|
321
|
-
.unmute()
|
|
322
|
-
.then(() => webex.devicemanager.getAudioState())
|
|
323
|
-
.then((res) => {
|
|
324
|
-
populateDeviceAudioState(res);
|
|
325
|
-
notify('Unmuted');
|
|
326
|
-
toggleDisplay('muteBtnDiv', true);
|
|
327
|
-
toggleDisplay('unmuteBtnDiv', false);
|
|
328
|
-
});
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
return false;
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
// when bindSpace is requested
|
|
335
|
-
document.getElementById('bindSpace').addEventListener('click', () => {
|
|
336
|
-
if (webex.devicemanager) {
|
|
337
|
-
notify('Binding space...');
|
|
338
|
-
const convoId = document.getElementById('convoId').value;
|
|
339
|
-
|
|
340
|
-
let url;
|
|
341
|
-
|
|
342
|
-
return webex.internal.services
|
|
343
|
-
.waitForCatalog('postauth')
|
|
344
|
-
.then(() => {
|
|
345
|
-
url = `${webex.internal.services.get('conversation')}/conversations/${convoId}`;
|
|
346
|
-
|
|
347
|
-
return webex.internal.conversation.get(
|
|
348
|
-
{url},
|
|
349
|
-
{
|
|
350
|
-
url,
|
|
351
|
-
includeUxTimers: true,
|
|
352
|
-
ackFilter: 'noack',
|
|
353
|
-
includeParticipants: false,
|
|
354
|
-
lastViewableActivityOnly: true,
|
|
355
|
-
participantsLimit: 0,
|
|
356
|
-
}
|
|
357
|
-
);
|
|
358
|
-
})
|
|
359
|
-
.then((conversation) =>
|
|
360
|
-
webex.devicemanager.bindSpace({
|
|
361
|
-
url,
|
|
362
|
-
kmsResourceObjectUrl: conversation.kmsResourceObjectUrl,
|
|
363
|
-
})
|
|
364
|
-
)
|
|
365
|
-
.then(() => {
|
|
366
|
-
notify('Space is bound');
|
|
367
|
-
toggleDisplay('bindSpaceBtnDiv', false);
|
|
368
|
-
toggleDisplay('unbindSpaceBtnDiv', true);
|
|
369
|
-
})
|
|
370
|
-
.catch(() => {
|
|
371
|
-
notify('Space could not be bound');
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
return false;
|
|
376
|
-
});
|
|
377
|
-
|
|
378
|
-
// when unbindSpace is requested
|
|
379
|
-
document.getElementById('unbindSpace').addEventListener('click', () => {
|
|
380
|
-
if (webex.devicemanager) {
|
|
381
|
-
notify('UnBinding space...');
|
|
382
|
-
|
|
383
|
-
return webex.devicemanager
|
|
384
|
-
.unbindSpace()
|
|
385
|
-
.then(() => {
|
|
386
|
-
notify('Space is unbound');
|
|
387
|
-
toggleDisplay('bindSpaceBtnDiv', true);
|
|
388
|
-
toggleDisplay('unbindSpaceBtnDiv', false);
|
|
389
|
-
})
|
|
390
|
-
.catch(() => {
|
|
391
|
-
notify('Space could not be bound');
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
return false;
|
|
396
|
-
});
|
|
397
|
-
|
|
398
|
-
document.getElementById('remove').addEventListener('click', () => {
|
|
399
|
-
if (webex.devicemanager) {
|
|
400
|
-
notify('Removing selected device...');
|
|
401
|
-
const dropdown = document.getElementById('device-list-dropdown');
|
|
402
|
-
const deviceId = dropdown.options[dropdown.selectedIndex].value;
|
|
403
|
-
|
|
404
|
-
if (deviceId && deviceId !== 'Choose a Device') {
|
|
405
|
-
return webex.devicemanager
|
|
406
|
-
.remove(deviceId)
|
|
407
|
-
.then(() => {
|
|
408
|
-
notify('Device removed');
|
|
409
|
-
|
|
410
|
-
return webex.devicemanager.refresh();
|
|
411
|
-
})
|
|
412
|
-
.then((devices) => {
|
|
413
|
-
populateDeviceDropdown(devices);
|
|
414
|
-
toggleDisplay('requestPinDiv', true);
|
|
415
|
-
toggleDisplay('removeBtnDiv', true);
|
|
416
|
-
})
|
|
417
|
-
.catch(() => {
|
|
418
|
-
notify('Failed to remove the device');
|
|
419
|
-
});
|
|
420
|
-
}
|
|
421
|
-
notify('Select a device first');
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
return false;
|
|
425
|
-
});
|
|
426
|
-
|
|
427
|
-
document.getElementById('search').addEventListener('click', () => {
|
|
428
|
-
if (webex.devicemanager) {
|
|
429
|
-
const searchQuery = document.getElementById('searchQuery').value;
|
|
430
|
-
|
|
431
|
-
if (searchQuery && searchQuery.length >= 3) {
|
|
432
|
-
return webex.devicemanager
|
|
433
|
-
.search({
|
|
434
|
-
searchQuery,
|
|
435
|
-
})
|
|
436
|
-
.then((res) => {
|
|
437
|
-
populateDeviceSearchResults(res);
|
|
438
|
-
})
|
|
439
|
-
.catch((error) => {
|
|
440
|
-
console.error(error);
|
|
441
|
-
});
|
|
442
|
-
}
|
|
443
|
-
console.info('Requires atleast 3 chars to search');
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
return false;
|
|
447
|
-
});
|
|
448
|
-
|
|
449
|
-
document.getElementById('credentials').addEventListener('submit', (event) => {
|
|
450
|
-
// let's make sure we don't reload the page when we submit the form
|
|
451
|
-
event.preventDefault();
|
|
452
|
-
connect();
|
|
453
|
-
});
|
|
1
|
+
/* eslint-env browser */
|
|
2
|
+
|
|
3
|
+
/* global Webex */
|
|
4
|
+
|
|
5
|
+
/* eslint-disable camelcase */
|
|
6
|
+
/* eslint-disable max-nested-callbacks */
|
|
7
|
+
/* eslint-disable no-alert */
|
|
8
|
+
/* eslint-disable no-console */
|
|
9
|
+
/* eslint-disable require-jsdoc */
|
|
10
|
+
|
|
11
|
+
// Declare some globals that we'll need throughout
|
|
12
|
+
let webex;
|
|
13
|
+
// First, let's wire our form fields up to localStorage so we don't have to
|
|
14
|
+
// retype things everytime we reload the page.
|
|
15
|
+
|
|
16
|
+
[
|
|
17
|
+
'access-token',
|
|
18
|
+
// 'invitee'
|
|
19
|
+
].forEach((id) => {
|
|
20
|
+
const el = document.getElementById(id);
|
|
21
|
+
|
|
22
|
+
el.value = localStorage.getItem(id);
|
|
23
|
+
el.addEventListener('change', (event) => {
|
|
24
|
+
localStorage.setItem(id, event.target.value);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
function notify(message) {
|
|
29
|
+
document.getElementById('notifications').innerHTML = message;
|
|
30
|
+
setTimeout(() => {
|
|
31
|
+
document.getElementById('notifications').innerHTML = '';
|
|
32
|
+
}, 5000);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function populateDeviceDropdown(devices) {
|
|
36
|
+
const deviceListDropdown = document.getElementById('device-list-dropdown');
|
|
37
|
+
|
|
38
|
+
deviceListDropdown.length = 0;
|
|
39
|
+
|
|
40
|
+
const defaultOption = document.createElement('option');
|
|
41
|
+
|
|
42
|
+
defaultOption.text = 'Choose a Device';
|
|
43
|
+
deviceListDropdown.add(defaultOption);
|
|
44
|
+
deviceListDropdown.selectedIndex = 0;
|
|
45
|
+
|
|
46
|
+
let option;
|
|
47
|
+
|
|
48
|
+
devices.forEach((device) => {
|
|
49
|
+
option = document.createElement('option');
|
|
50
|
+
option.text = device.deviceInfo.description || device.deviceInfo.name;
|
|
51
|
+
option.value = device.id;
|
|
52
|
+
deviceListDropdown.add(option);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function toggleDisplay(elementId, status) {
|
|
57
|
+
const element = document.getElementById(elementId);
|
|
58
|
+
|
|
59
|
+
if (status) {
|
|
60
|
+
element.style.display = 'block';
|
|
61
|
+
} else {
|
|
62
|
+
element.style.display = 'none';
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function populateDeviceAudioState(audioState) {
|
|
67
|
+
document.getElementById('getAudioStateContentsDiv').innerHTML = `<div>
|
|
68
|
+
<ul>
|
|
69
|
+
<li>Muted: ${audioState.microphones.muted}</li>
|
|
70
|
+
<li>volume current level: ${audioState.volume.level}</li>
|
|
71
|
+
<li>volume max level: ${audioState.volume.max}</li>
|
|
72
|
+
<li>volume min level: ${audioState.volume.min}</li>
|
|
73
|
+
<li>volume step level: ${audioState.volume.step}</li>
|
|
74
|
+
</ul>
|
|
75
|
+
<div id='hideAudioStateBtnDiv' style=muted"display:none;">
|
|
76
|
+
<button id="hideAudioState" title="hideAudioState" type="button">hideAudioState</button>
|
|
77
|
+
</div>
|
|
78
|
+
</div>`;
|
|
79
|
+
toggleDisplay('getAudioStateContentsDiv', true);
|
|
80
|
+
toggleDisplay('hideAudioStateBtnDiv', true);
|
|
81
|
+
// hideAudioState of the paired device
|
|
82
|
+
document.getElementById('hideAudioState').addEventListener('click', () => {
|
|
83
|
+
toggleDisplay('getAudioStateContentsDiv', false);
|
|
84
|
+
toggleDisplay('hideAudioStateBtnDiv', false);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function populateDeviceSearchResults(response) {
|
|
89
|
+
let devices = '';
|
|
90
|
+
|
|
91
|
+
response.forEach((device) => {
|
|
92
|
+
devices += `
|
|
93
|
+
<li style='list-style-type: none'>
|
|
94
|
+
<input type='radio' name='deviceRadio' onclick='requestPinChallenge("${device.id}")'/>
|
|
95
|
+
<label>${device.description || device.name}</label>
|
|
96
|
+
</li>`;
|
|
97
|
+
});
|
|
98
|
+
document.getElementById('getDeviceSearchResultsDiv').innerHTML = `<div>
|
|
99
|
+
<ul>
|
|
100
|
+
${devices}
|
|
101
|
+
</ul>
|
|
102
|
+
<div id='hideDeviceSearchResultsBtnDiv' style=muted"display:none;">
|
|
103
|
+
<button id="hideDeviceSearchResults" title="hideDeviceSearchResults" type="button">hideDeviceSearchResults</button>
|
|
104
|
+
</div>
|
|
105
|
+
</div>`;
|
|
106
|
+
toggleDisplay('getDeviceSearchResultsDiv', true);
|
|
107
|
+
toggleDisplay('hideDeviceSearchResults', true);
|
|
108
|
+
// hideAudioState of the paired device
|
|
109
|
+
document.getElementById('hideDeviceSearchResults').addEventListener('click', () => {
|
|
110
|
+
toggleDisplay('getDeviceSearchResultsDiv', false);
|
|
111
|
+
toggleDisplay('hideDeviceSearchResults', false);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function connect() {
|
|
116
|
+
if (!webex) {
|
|
117
|
+
webex = Webex.init({
|
|
118
|
+
config: {
|
|
119
|
+
// Any other sdk config we need
|
|
120
|
+
},
|
|
121
|
+
credentials: {
|
|
122
|
+
access_token: document.getElementById('access-token').value,
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (!webex.internal.device.registered) {
|
|
128
|
+
webex.internal.device
|
|
129
|
+
.register()
|
|
130
|
+
.then(() => {
|
|
131
|
+
// This is just a little helper for our selenium tests and doesn't
|
|
132
|
+
// really matter for the example
|
|
133
|
+
document.body.classList.add('listening');
|
|
134
|
+
document.getElementById('connection-status').innerHTML = 'connected';
|
|
135
|
+
|
|
136
|
+
// return this.webex.internal.device.register()
|
|
137
|
+
return webex.internal.mercury.connect();
|
|
138
|
+
})
|
|
139
|
+
// This is a terrible way to handle errors, but anything more specific is
|
|
140
|
+
// going to depend a lot on your app
|
|
141
|
+
.catch((err) => {
|
|
142
|
+
console.error(err);
|
|
143
|
+
// we'll rethrow here since we didn't really *handle* the error, we just
|
|
144
|
+
// reported it
|
|
145
|
+
throw err;
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function requestPinChallenge(deviceId) {
|
|
151
|
+
return webex.devicemanager.requestPin({id: deviceId}).then(() => {
|
|
152
|
+
toggleDisplay('enterPinDiv', true);
|
|
153
|
+
toggleDisplay('requestPairingBtnDiv', true);
|
|
154
|
+
notify('Enter the PIN');
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
document.getElementById('deviceControls').refresh.addEventListener('click', () => {
|
|
159
|
+
if (webex.devicemanager) {
|
|
160
|
+
notify('Listing devices...');
|
|
161
|
+
|
|
162
|
+
return webex.devicemanager.refresh().then((devices) => {
|
|
163
|
+
populateDeviceDropdown(devices);
|
|
164
|
+
notify('');
|
|
165
|
+
toggleDisplay('requestPinDiv', true);
|
|
166
|
+
toggleDisplay('removeBtnDiv', true);
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return false;
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// when PIN is requested
|
|
174
|
+
document.getElementById('requestPin').addEventListener('click', () => {
|
|
175
|
+
if (webex.devicemanager) {
|
|
176
|
+
notify('Requesting Pin...');
|
|
177
|
+
const dropdown = document.getElementById('device-list-dropdown');
|
|
178
|
+
const deviceId = dropdown.options[dropdown.selectedIndex].value;
|
|
179
|
+
|
|
180
|
+
if (deviceId && deviceId !== 'Choose a Device') {
|
|
181
|
+
return requestPinChallenge(deviceId);
|
|
182
|
+
}
|
|
183
|
+
notify('Select a device first');
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return false;
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// when device pairing is requested
|
|
190
|
+
document.getElementById('requestPairing').addEventListener('click', () => {
|
|
191
|
+
if (webex.devicemanager) {
|
|
192
|
+
notify('Pairing...');
|
|
193
|
+
const pin = document.getElementById('pin').value;
|
|
194
|
+
|
|
195
|
+
return webex.devicemanager
|
|
196
|
+
.pair({pin})
|
|
197
|
+
.then(() => {
|
|
198
|
+
notify('Paired');
|
|
199
|
+
toggleDisplay('requestUnPairingBtnDiv', true);
|
|
200
|
+
toggleDisplay('getAudioStateBtnDiv', true);
|
|
201
|
+
toggleDisplay('volumeUpBtnDiv', true);
|
|
202
|
+
toggleDisplay('volumeDownBtnDiv', true);
|
|
203
|
+
toggleDisplay('muteBtnDiv', true);
|
|
204
|
+
toggleDisplay('enterConvoIdDiv', true);
|
|
205
|
+
toggleDisplay('bindSpaceBtnDiv', true);
|
|
206
|
+
})
|
|
207
|
+
.then(() => webex.devicemanager.refresh())
|
|
208
|
+
.then((devices) => {
|
|
209
|
+
populateDeviceDropdown(devices);
|
|
210
|
+
notify('');
|
|
211
|
+
toggleDisplay('requestPinDiv', true);
|
|
212
|
+
toggleDisplay('removeBtnDiv', true);
|
|
213
|
+
})
|
|
214
|
+
.catch(() => {
|
|
215
|
+
notify('Incorrect PIN');
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return false;
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
// when device unpairing is requested
|
|
223
|
+
document.getElementById('requestUnPairing').addEventListener('click', () => {
|
|
224
|
+
if (webex.devicemanager) {
|
|
225
|
+
notify('UnPairing...');
|
|
226
|
+
|
|
227
|
+
return webex.devicemanager.unpair().then(() => {
|
|
228
|
+
notify('UnPaired');
|
|
229
|
+
toggleDisplay('requestUnPairingBtnDiv', false);
|
|
230
|
+
toggleDisplay('requestPairingBtnDiv', false);
|
|
231
|
+
toggleDisplay('enterPinDiv', false);
|
|
232
|
+
toggleDisplay('getAudioStateBtnDiv', false);
|
|
233
|
+
toggleDisplay('hideAudioStateBtnDiv', false);
|
|
234
|
+
toggleDisplay('getAudioStateContentsDiv', false);
|
|
235
|
+
toggleDisplay('volumeUpBtnDiv', false);
|
|
236
|
+
toggleDisplay('volumeDownBtnDiv', false);
|
|
237
|
+
toggleDisplay('muteBtnDiv', false);
|
|
238
|
+
toggleDisplay('unmuteBtnDiv', false);
|
|
239
|
+
toggleDisplay('enterConvoIdDiv', false);
|
|
240
|
+
toggleDisplay('bindSpaceBtnDiv', false);
|
|
241
|
+
toggleDisplay('unbindSpaceBtnDiv', false);
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return false;
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
// getAudioState of the paired device
|
|
249
|
+
document.getElementById('getAudioState').addEventListener('click', () => {
|
|
250
|
+
if (webex.devicemanager) {
|
|
251
|
+
notify('GettingAudioState...');
|
|
252
|
+
|
|
253
|
+
return webex.devicemanager.getAudioState().then((res) => {
|
|
254
|
+
populateDeviceAudioState(res);
|
|
255
|
+
notify('Audio State fetched');
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return false;
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
// increase volume of paired device
|
|
263
|
+
document.getElementById('volumeUp').addEventListener('click', () => {
|
|
264
|
+
if (webex.devicemanager) {
|
|
265
|
+
notify('Increasing Volume...');
|
|
266
|
+
|
|
267
|
+
return webex.devicemanager
|
|
268
|
+
.increaseVolume()
|
|
269
|
+
.then(() => webex.devicemanager.getAudioState())
|
|
270
|
+
.then((res) => {
|
|
271
|
+
populateDeviceAudioState(res);
|
|
272
|
+
notify('Volume Increased');
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return false;
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
// increase volume of paired device
|
|
280
|
+
document.getElementById('volumeDown').addEventListener('click', () => {
|
|
281
|
+
if (webex.devicemanager) {
|
|
282
|
+
notify('Decreasing Volume...');
|
|
283
|
+
|
|
284
|
+
return webex.devicemanager
|
|
285
|
+
.decreaseVolume()
|
|
286
|
+
.then(() => webex.devicemanager.getAudioState())
|
|
287
|
+
.then((res) => {
|
|
288
|
+
populateDeviceAudioState(res);
|
|
289
|
+
notify('Volume Decreased');
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return false;
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
// mute paired device
|
|
297
|
+
document.getElementById('mute').addEventListener('click', () => {
|
|
298
|
+
if (webex.devicemanager) {
|
|
299
|
+
notify('Muting...');
|
|
300
|
+
|
|
301
|
+
return webex.devicemanager
|
|
302
|
+
.mute()
|
|
303
|
+
.then(() => webex.devicemanager.getAudioState())
|
|
304
|
+
.then((res) => {
|
|
305
|
+
populateDeviceAudioState(res);
|
|
306
|
+
notify('Muted');
|
|
307
|
+
toggleDisplay('muteBtnDiv', false);
|
|
308
|
+
toggleDisplay('unmuteBtnDiv', true);
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return false;
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
// unmute paired device
|
|
316
|
+
document.getElementById('unmute').addEventListener('click', () => {
|
|
317
|
+
if (webex.devicemanager) {
|
|
318
|
+
notify('UnMuting');
|
|
319
|
+
|
|
320
|
+
return webex.devicemanager
|
|
321
|
+
.unmute()
|
|
322
|
+
.then(() => webex.devicemanager.getAudioState())
|
|
323
|
+
.then((res) => {
|
|
324
|
+
populateDeviceAudioState(res);
|
|
325
|
+
notify('Unmuted');
|
|
326
|
+
toggleDisplay('muteBtnDiv', true);
|
|
327
|
+
toggleDisplay('unmuteBtnDiv', false);
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
return false;
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
// when bindSpace is requested
|
|
335
|
+
document.getElementById('bindSpace').addEventListener('click', () => {
|
|
336
|
+
if (webex.devicemanager) {
|
|
337
|
+
notify('Binding space...');
|
|
338
|
+
const convoId = document.getElementById('convoId').value;
|
|
339
|
+
|
|
340
|
+
let url;
|
|
341
|
+
|
|
342
|
+
return webex.internal.services
|
|
343
|
+
.waitForCatalog('postauth')
|
|
344
|
+
.then(() => {
|
|
345
|
+
url = `${webex.internal.services.get('conversation')}/conversations/${convoId}`;
|
|
346
|
+
|
|
347
|
+
return webex.internal.conversation.get(
|
|
348
|
+
{url},
|
|
349
|
+
{
|
|
350
|
+
url,
|
|
351
|
+
includeUxTimers: true,
|
|
352
|
+
ackFilter: 'noack',
|
|
353
|
+
includeParticipants: false,
|
|
354
|
+
lastViewableActivityOnly: true,
|
|
355
|
+
participantsLimit: 0,
|
|
356
|
+
}
|
|
357
|
+
);
|
|
358
|
+
})
|
|
359
|
+
.then((conversation) =>
|
|
360
|
+
webex.devicemanager.bindSpace({
|
|
361
|
+
url,
|
|
362
|
+
kmsResourceObjectUrl: conversation.kmsResourceObjectUrl,
|
|
363
|
+
})
|
|
364
|
+
)
|
|
365
|
+
.then(() => {
|
|
366
|
+
notify('Space is bound');
|
|
367
|
+
toggleDisplay('bindSpaceBtnDiv', false);
|
|
368
|
+
toggleDisplay('unbindSpaceBtnDiv', true);
|
|
369
|
+
})
|
|
370
|
+
.catch(() => {
|
|
371
|
+
notify('Space could not be bound');
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
return false;
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
// when unbindSpace is requested
|
|
379
|
+
document.getElementById('unbindSpace').addEventListener('click', () => {
|
|
380
|
+
if (webex.devicemanager) {
|
|
381
|
+
notify('UnBinding space...');
|
|
382
|
+
|
|
383
|
+
return webex.devicemanager
|
|
384
|
+
.unbindSpace()
|
|
385
|
+
.then(() => {
|
|
386
|
+
notify('Space is unbound');
|
|
387
|
+
toggleDisplay('bindSpaceBtnDiv', true);
|
|
388
|
+
toggleDisplay('unbindSpaceBtnDiv', false);
|
|
389
|
+
})
|
|
390
|
+
.catch(() => {
|
|
391
|
+
notify('Space could not be bound');
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
return false;
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
document.getElementById('remove').addEventListener('click', () => {
|
|
399
|
+
if (webex.devicemanager) {
|
|
400
|
+
notify('Removing selected device...');
|
|
401
|
+
const dropdown = document.getElementById('device-list-dropdown');
|
|
402
|
+
const deviceId = dropdown.options[dropdown.selectedIndex].value;
|
|
403
|
+
|
|
404
|
+
if (deviceId && deviceId !== 'Choose a Device') {
|
|
405
|
+
return webex.devicemanager
|
|
406
|
+
.remove(deviceId)
|
|
407
|
+
.then(() => {
|
|
408
|
+
notify('Device removed');
|
|
409
|
+
|
|
410
|
+
return webex.devicemanager.refresh();
|
|
411
|
+
})
|
|
412
|
+
.then((devices) => {
|
|
413
|
+
populateDeviceDropdown(devices);
|
|
414
|
+
toggleDisplay('requestPinDiv', true);
|
|
415
|
+
toggleDisplay('removeBtnDiv', true);
|
|
416
|
+
})
|
|
417
|
+
.catch(() => {
|
|
418
|
+
notify('Failed to remove the device');
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
notify('Select a device first');
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
return false;
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
document.getElementById('search').addEventListener('click', () => {
|
|
428
|
+
if (webex.devicemanager) {
|
|
429
|
+
const searchQuery = document.getElementById('searchQuery').value;
|
|
430
|
+
|
|
431
|
+
if (searchQuery && searchQuery.length >= 3) {
|
|
432
|
+
return webex.devicemanager
|
|
433
|
+
.search({
|
|
434
|
+
searchQuery,
|
|
435
|
+
})
|
|
436
|
+
.then((res) => {
|
|
437
|
+
populateDeviceSearchResults(res);
|
|
438
|
+
})
|
|
439
|
+
.catch((error) => {
|
|
440
|
+
console.error(error);
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
console.info('Requires atleast 3 chars to search');
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
return false;
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
document.getElementById('credentials').addEventListener('submit', (event) => {
|
|
450
|
+
// let's make sure we don't reload the page when we submit the form
|
|
451
|
+
event.preventDefault();
|
|
452
|
+
connect();
|
|
453
|
+
});
|