janusweb 1.5.30 → 1.5.34
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/CHANGELOG +39 -0
- package/LICENSE +1 -1
- package/media/assets/janus-avatar-animations.glb +0 -0
- package/media/assets/janus-avatar-base.glb +0 -0
- package/media/assets/webui/apps/avatar/avatar.css +6 -2
- package/media/assets/webui/apps/avatar/avatar.js +99 -11
- package/media/assets/webui/apps/buttons/buttons.html +2 -2
- package/media/assets/webui/apps/buttons/buttons.js +3 -3
- package/media/assets/webui/apps/comms/comms.js +7 -4
- package/media/assets/webui/apps/comms/voip.js +133 -57
- package/media/assets/webui/apps/editor/codemirror/addon/hint/javascript-hint.js +162 -0
- package/media/assets/webui/apps/editor/codemirror/addon/hint/show-hint.css +36 -0
- package/media/assets/webui/apps/editor/codemirror/addon/hint/show-hint.js +529 -0
- package/media/assets/webui/apps/editor/codemirror/addon/hint/xml-hint.js +140 -0
- package/media/assets/webui/apps/editor/codemirror/keymap/vim.js +5734 -0
- package/media/assets/webui/apps/editor/codemirror/lib/codemirror.css +350 -0
- package/media/assets/webui/apps/editor/codemirror/lib/codemirror.js +9800 -0
- package/media/assets/webui/apps/editor/codemirror/lib/jmldark.css +33 -0
- package/media/assets/webui/apps/editor/codemirror/mode/css/css.js +864 -0
- package/media/assets/webui/apps/editor/codemirror/mode/htmlmixed/htmlmixed.js +153 -0
- package/media/assets/webui/apps/editor/codemirror/mode/javascript/javascript.js +942 -0
- package/media/assets/webui/apps/editor/codemirror/mode/xml/xml.js +413 -0
- package/media/assets/webui/apps/editor/editor.css +3 -0
- package/media/assets/webui/apps/editor/editor.js +409 -9
- package/media/assets/webui/apps/editor/editor.json +6 -3
- package/media/assets/webui/apps/inventory/inventory.html +7 -4
- package/media/assets/webui/apps/inventory/inventory.js +2 -2
- package/media/assets/webui/apps/locomotion/teleporter.js +10 -9
- package/media/assets/webui/apps/navigation/navigation.js +12 -12
- package/media/assets/webui/apps/settings/settings.html +1 -1
- package/media/assets/webui/apps/vfs/browserfs/browserfs.js +8 -0
- package/media/assets/webui/apps/vfs/vfs.css +52 -0
- package/media/assets/webui/apps/vfs/vfs.js +452 -0
- package/media/assets/webui/apps/vfs/vfs.json +10 -0
- package/media/assets/webui/apps/virtualgamepad/virtualgamepad.js +9 -7
- package/media/assets/webui/apps/xrmenu/xrmenu.js +13 -4
- package/media/assets/webui/default.json +2 -1
- package/media/assets/webui/none.json +1 -0
- package/media/assets/webui/themes/default.css +29 -2
- package/media/assets.json +2 -1
- package/media/index.html +1 -1
- package/media/lib/draco/README.md +32 -0
- package/media/lib/draco/draco_decoder.js +52 -0
- package/media/lib/draco/draco_decoder.wasm +0 -0
- package/media/lib/draco/draco_encoder.js +33 -0
- package/media/lib/draco/draco_wasm_wrapper.js +104 -0
- package/media/lib/draco/gltf/draco_decoder.js +48 -0
- package/media/lib/draco/gltf/draco_decoder.wasm +0 -0
- package/media/lib/draco/gltf/draco_encoder.js +33 -0
- package/media/lib/draco/gltf/draco_wasm_wrapper.js +104 -0
- package/media/lib/physx/physx.release.js +21 -0
- package/media/lib/physx/physx.release.wasm +0 -0
- package/media/manifest.json +5 -5
- package/media/service-worker.js +7 -0
- package/package.json +2 -9
- package/scripts/client.js +67 -46
- package/scripts/config.js +2 -0
- package/scripts/elements/linesegments.js +10 -3
- package/scripts/external/JanusFireboxParser.js +1 -0
- package/scripts/image.js +7 -1
- package/scripts/janusbase.js +104 -43
- package/scripts/janusghost.js +314 -16
- package/scripts/januslight.js +11 -2
- package/scripts/janusparagraph.js +8 -6
- package/scripts/janusparticle.js +26 -16
- package/scripts/janusplayer.js +126 -37
- package/scripts/janusweb.js +26 -2
- package/scripts/janusxrplayer.js +5 -3
- package/scripts/multiplayermanager.js +6 -4
- package/scripts/object.js +246 -88
- package/scripts/portal.js +23 -14
- package/scripts/remoteplayer.js +1 -25
- package/scripts/room.js +199 -77
- package/scripts/sound.js +8 -6
- package/scripts/text.js +13 -5
- package/scripts/translators/janusvfs.js +20 -0
- package/scripts/video.js +1 -1
- package/scripts/websurface.js +17 -3
- package/utils/build.sh +3 -0
- package/utils/init.sh +2 -2
- package/scripts/chat.js +0 -80
- package/scripts/ui.js +0 -265
- package/scripts/urlbar.js +0 -93
- package/templates/janusweb.tpl +0 -3
|
@@ -202,21 +202,19 @@ elation.elements.define('janus-voip-client-hifi', class extends elation.elements
|
|
|
202
202
|
let localuser = this.parentNode.localuser;
|
|
203
203
|
this.remoteusers[localuser.userid] = localuser;
|
|
204
204
|
|
|
205
|
-
console.log('create hifi client', this);
|
|
206
205
|
elation.file.get('js', 'https://hifi-spatial-audio-api.s3.amazonaws.com/releases/latest/HighFidelityAudio-latest.js', (ev) => {
|
|
207
206
|
this.connect();
|
|
208
|
-
console.log('FIRE HIFI INIT');
|
|
209
207
|
elation.events.fire({type: 'init', element: this});
|
|
210
208
|
});
|
|
211
209
|
this.roomid = room.voipid || '2bfa2bd1-9338-46c3-b740-e339303a1225';
|
|
212
210
|
}
|
|
213
211
|
async connect() {
|
|
214
212
|
let currentPosition = new HighFidelityAudio.Point3D({ "x": 0, "y": 0, "z": 0 });
|
|
215
|
-
let currentOrientation = new HighFidelityAudio.
|
|
213
|
+
let currentOrientation = new HighFidelityAudio.Quaternion({ x: 0, y: 0, z: 0, w: 1});
|
|
216
214
|
|
|
217
215
|
let initialHiFiAudioAPIData = new HighFidelityAudio.HiFiAudioAPIData({
|
|
218
216
|
position: currentPosition,
|
|
219
|
-
|
|
217
|
+
orientation: currentOrientation,
|
|
220
218
|
providedUserID: player.getNetworkUsername(),
|
|
221
219
|
});
|
|
222
220
|
let hifiCommunicator = new HighFidelityAudio.HiFiCommunicator({ initialHiFiAudioAPIData });
|
|
@@ -236,7 +234,6 @@ console.log('voip picker select?', ev);
|
|
|
236
234
|
});
|
|
237
235
|
*/
|
|
238
236
|
|
|
239
|
-
console.log('new hifi client has existing input stream?', this.inputstream);
|
|
240
237
|
if (this.inputstream) {
|
|
241
238
|
hifiCommunicator.setInputAudioMediaStream(this.inputstream);
|
|
242
239
|
}
|
|
@@ -262,12 +259,12 @@ console.log('new hifi client has existing input stream?', this.inputstream);
|
|
|
262
259
|
}
|
|
263
260
|
});
|
|
264
261
|
|
|
265
|
-
elation.events.add(janus.engine, 'engine_frame', ev => this.handleFrameUpdate(ev))
|
|
262
|
+
elation.events.add(janus.engine, 'engine_frame', ev => this.handleFrameUpdate(ev));
|
|
266
263
|
|
|
267
264
|
let newUserDataSubscription = new HighFidelityAudio.UserDataSubscription({
|
|
268
265
|
components: [
|
|
269
266
|
HighFidelityAudio.AvailableUserDataSubscriptionComponents.Position,
|
|
270
|
-
HighFidelityAudio.AvailableUserDataSubscriptionComponents.
|
|
267
|
+
HighFidelityAudio.AvailableUserDataSubscriptionComponents.Orientation,
|
|
271
268
|
HighFidelityAudio.AvailableUserDataSubscriptionComponents.VolumeDecibels
|
|
272
269
|
],
|
|
273
270
|
callback: audioDataArray => this.handleUserDataSubscription(audioDataArray)
|
|
@@ -278,7 +275,7 @@ console.log('new hifi client has existing input stream?', this.inputstream);
|
|
|
278
275
|
/*
|
|
279
276
|
this.userData = {
|
|
280
277
|
position: currentPosition,
|
|
281
|
-
|
|
278
|
+
orientation: currentOrientation,
|
|
282
279
|
providedUserID: player.getNetworkUsername(),
|
|
283
280
|
};
|
|
284
281
|
*/
|
|
@@ -313,10 +310,10 @@ console.log('new hifi client has existing input stream?', this.inputstream);
|
|
|
313
310
|
this.userData.position.y = pos.y * scale;
|
|
314
311
|
this.userData.position.z = pos.z * scale;
|
|
315
312
|
|
|
316
|
-
this.userData.
|
|
317
|
-
this.userData.
|
|
318
|
-
this.userData.
|
|
319
|
-
this.userData.
|
|
313
|
+
this.userData.orientation.x = orientation.x;
|
|
314
|
+
this.userData.orientation.y = orientation.y;
|
|
315
|
+
this.userData.orientation.z = orientation.z;
|
|
316
|
+
this.userData.orientation.w = orientation.w;
|
|
320
317
|
|
|
321
318
|
if (this.hifiCommunicator._currentHiFiAudioAPIData) {
|
|
322
319
|
this.hifiCommunicator.updateUserDataAndTransmit(this.userData);
|
|
@@ -371,7 +368,7 @@ elation.elements.define('janus-voip-localuser', class extends elation.elements.b
|
|
|
371
368
|
this.defineAttribute('userid', { type: 'string', });
|
|
372
369
|
this.defineAttribute('muted', { type: 'boolean', default: true, });
|
|
373
370
|
this.defineAttribute('speaking', { type: 'boolean', default: false });
|
|
374
|
-
|
|
371
|
+
this.defineAttribute('threshold', { type: 'float', default: .2 });
|
|
375
372
|
}
|
|
376
373
|
create() {
|
|
377
374
|
this.userid = player.getNetworkUsername();
|
|
@@ -433,6 +430,30 @@ elation.elements.define('janus-voip-localuser', class extends elation.elements.b
|
|
|
433
430
|
*/
|
|
434
431
|
this.stream = data;
|
|
435
432
|
|
|
433
|
+
let listener = player.engine.systems.sound.getRealListener();
|
|
434
|
+
let context = listener.context;
|
|
435
|
+
let analyser = context.createAnalyser();
|
|
436
|
+
let source = context.createMediaStreamSource(this.stream);
|
|
437
|
+
source.connect(analyser);
|
|
438
|
+
|
|
439
|
+
analyser.fftSize = 32;
|
|
440
|
+
this.analyser = analyser;
|
|
441
|
+
this.audiobuffer = new Uint8Array(analyser.frequencyBinCount);
|
|
442
|
+
|
|
443
|
+
if (this.updateVolumeInterval) {
|
|
444
|
+
clearInterval(this.updateVolumeInterval);
|
|
445
|
+
this.updateVolumeInterval = false;
|
|
446
|
+
}
|
|
447
|
+
this.updateVolumeInterval = setInterval(() => {
|
|
448
|
+
analyser.getByteFrequencyData(this.audiobuffer);
|
|
449
|
+
let sum = 0;
|
|
450
|
+
for (let i = 0; i < this.audiobuffer.length; i++) {
|
|
451
|
+
sum += this.audiobuffer[i];
|
|
452
|
+
}
|
|
453
|
+
let avg = sum / this.audiobuffer.length;
|
|
454
|
+
this.updateVolume(avg / 100);
|
|
455
|
+
}, 20);
|
|
456
|
+
|
|
436
457
|
/*
|
|
437
458
|
player.createObject('object', {
|
|
438
459
|
id: 'cone',
|
|
@@ -462,15 +483,24 @@ elation.elements.define('janus-voip-localuser', class extends elation.elements.b
|
|
|
462
483
|
this.averagevolume = (percent * .6 + this.averagevolume * .4)
|
|
463
484
|
if (isNaN(this.averagevolume)) this.averagevolume = 0;
|
|
464
485
|
//this.style.opacity = percent;
|
|
465
|
-
if (this.averagevolume > .
|
|
486
|
+
if (this.averagevolume > this.threshold) {
|
|
466
487
|
this.speaking = true;
|
|
488
|
+
player.defaultanimation = 'speak';
|
|
467
489
|
if (this.colorreset) {
|
|
468
490
|
clearTimeout(this.colorreset);
|
|
469
491
|
}
|
|
470
492
|
this.colorreset = setTimeout(() => {
|
|
471
493
|
this.speaking = false;
|
|
472
494
|
this.colorreset = false;
|
|
495
|
+
player.defaultanimation = 'idle';
|
|
473
496
|
}, 200);
|
|
497
|
+
if (player.ghost) {
|
|
498
|
+
player.ghost.setSpeakingVolume(this.averagevolume);
|
|
499
|
+
}
|
|
500
|
+
} else {
|
|
501
|
+
if (player.ghost) {
|
|
502
|
+
player.ghost.setSpeakingVolume(0);
|
|
503
|
+
}
|
|
474
504
|
}
|
|
475
505
|
}
|
|
476
506
|
|
|
@@ -481,9 +511,9 @@ elation.elements.define('janus-voip-remoteuser', class extends elation.elements.
|
|
|
481
511
|
'muted': { type: 'boolean', default: false },
|
|
482
512
|
'hasaudio': { type: 'boolean', default: false },
|
|
483
513
|
'hasvideo': { type: 'boolean', default: false },
|
|
484
|
-
'hasvideo': { type: 'boolean', default: false },
|
|
485
514
|
'averagevolume': { type: 'float', default: 0 },
|
|
486
515
|
'speaking': { type: 'boolean', default: false },
|
|
516
|
+
'threshold': { type: 'float', default: .2 },
|
|
487
517
|
});
|
|
488
518
|
this.lastposition = V();
|
|
489
519
|
setTimeout(() => this.setAttribute('active', true), 100);
|
|
@@ -525,6 +555,30 @@ elation.elements.define('janus-voip-remoteuser', class extends elation.elements.
|
|
|
525
555
|
this.audio = audio;
|
|
526
556
|
this.appendChild(audio);
|
|
527
557
|
this.hasaudio = true;
|
|
558
|
+
|
|
559
|
+
let listener = player.engine.systems.sound.getRealListener();
|
|
560
|
+
let context = listener.context;
|
|
561
|
+
let analyser = context.createAnalyser();
|
|
562
|
+
let source = context.createMediaStreamSource(audio.srcObject);
|
|
563
|
+
source.connect(analyser);
|
|
564
|
+
|
|
565
|
+
analyser.fftSize = 32;
|
|
566
|
+
this.analyser = analyser;
|
|
567
|
+
this.audiobuffer = new Uint8Array(analyser.frequencyBinCount);
|
|
568
|
+
|
|
569
|
+
if (this.updateVolumeInterval) {
|
|
570
|
+
clearInterval(this.updateVolumeInterval);
|
|
571
|
+
this.updateVolumeInterval = false;
|
|
572
|
+
}
|
|
573
|
+
this.updateVolumeInterval = setInterval(() => {
|
|
574
|
+
analyser.getByteFrequencyData(this.audiobuffer);
|
|
575
|
+
let sum = 0;
|
|
576
|
+
for (let i = 0; i < this.audiobuffer.length; i++) {
|
|
577
|
+
sum += this.audiobuffer[i];
|
|
578
|
+
}
|
|
579
|
+
let avg = sum / this.audiobuffer.length;
|
|
580
|
+
this.updateVolume(avg / 100);
|
|
581
|
+
}, 20);
|
|
528
582
|
}
|
|
529
583
|
|
|
530
584
|
let remoteuser = janus.network.remoteplayers[this.id];
|
|
@@ -603,7 +657,9 @@ elation.elements.define('janus-voip-remoteuser', class extends elation.elements.
|
|
|
603
657
|
|
|
604
658
|
elation.events.add(this.remoteuser, 'update', ev => {
|
|
605
659
|
// Store user's last known position so we know where they were once they leave
|
|
606
|
-
|
|
660
|
+
if (this.lastposition) {
|
|
661
|
+
this.remoteuser.localToWorld(this.lastposition.set(0,0,0));
|
|
662
|
+
}
|
|
607
663
|
});
|
|
608
664
|
}
|
|
609
665
|
|
|
@@ -658,7 +714,7 @@ elation.elements.define('janus-voip-remoteuser', class extends elation.elements.
|
|
|
658
714
|
if (isNaN(this.averagevolume)) this.averagevolume = 0;
|
|
659
715
|
//this.style.opacity = percent;
|
|
660
716
|
//console.log('update volume', percent, this);
|
|
661
|
-
if (this.averagevolume > .
|
|
717
|
+
if (this.averagevolume > this.threshold) {
|
|
662
718
|
this.speaking = true;
|
|
663
719
|
if (this.colorreset) {
|
|
664
720
|
clearTimeout(this.colorreset);
|
|
@@ -669,10 +725,9 @@ elation.elements.define('janus-voip-remoteuser', class extends elation.elements.
|
|
|
669
725
|
}, 200);
|
|
670
726
|
}
|
|
671
727
|
|
|
672
|
-
let scale = 1 + this.averagevolume / 2.5;
|
|
673
728
|
if (this.label3d) {
|
|
674
729
|
this.label3d.setAudioVolume(this.averagevolume);
|
|
675
|
-
this.
|
|
730
|
+
this.remoteuser.setSpeakingVolume(this.averagevolume);
|
|
676
731
|
}
|
|
677
732
|
}
|
|
678
733
|
});
|
|
@@ -685,6 +740,9 @@ elation.elements.define('janus-voip-picker', class extends elation.elements.base
|
|
|
685
740
|
<!-- li><ui-togglebutton name="video" disabled="1">With my webcam</ui-togglebutton></li -->
|
|
686
741
|
</ul>
|
|
687
742
|
`, this);
|
|
743
|
+
this.defineAttributes({
|
|
744
|
+
'showvideo': { type: 'boolean', default: true },
|
|
745
|
+
});
|
|
688
746
|
|
|
689
747
|
elation.events.add(this.elements.none, 'click', (ev) => this.handleSelectNone());
|
|
690
748
|
elation.events.add(this.elements.audio, 'click', (ev) => this.handleSelectAudio(ev));
|
|
@@ -694,7 +752,7 @@ elation.elements.define('janus-voip-picker', class extends elation.elements.base
|
|
|
694
752
|
if (this.voipconfig) {
|
|
695
753
|
// FIXME - starting the audio without explicitly asking the user within this session is bad, but we want to resume across refreshes
|
|
696
754
|
// We should use a session cookie-based timeout in addition to the localStorage settings
|
|
697
|
-
|
|
755
|
+
this.handleSelectAudio({detail: 1});
|
|
698
756
|
}
|
|
699
757
|
console.log('voip picker loaded config', this.voipconfig);
|
|
700
758
|
}
|
|
@@ -715,7 +773,7 @@ elation.elements.define('janus-voip-picker', class extends elation.elements.base
|
|
|
715
773
|
console.log('selected audio', ev.detail, this.voipconfig);
|
|
716
774
|
//janus.engine.systems.sound.enableSound();
|
|
717
775
|
if (!this.subpicker) {
|
|
718
|
-
this.subpicker = elation.elements.create('janus-voip-picker-audio', { config: (this.voipconfig ? JSON.stringify(this.voipconfig) : false) });
|
|
776
|
+
this.subpicker = elation.elements.create('janus-voip-picker-audio', { config: (this.voipconfig ? JSON.stringify(this.voipconfig) : false), showvideo: this.showvideo });
|
|
719
777
|
elation.events.add(this.subpicker, 'select', ev => {
|
|
720
778
|
console.log('SELECTED', ev.detail);
|
|
721
779
|
document.dispatchEvent(new CustomEvent('voip-picker-select', { detail: ev.detail }));
|
|
@@ -739,8 +797,9 @@ elation.elements.define('janus-voip-picker-audio', class extends elation.element
|
|
|
739
797
|
create() {
|
|
740
798
|
this.defineAttributes({
|
|
741
799
|
'config': { type: 'object', default: false },
|
|
800
|
+
'showvideo': { type: 'boolean', default: true },
|
|
742
801
|
});
|
|
743
|
-
|
|
802
|
+
let tplstr = `
|
|
744
803
|
<div class="permissions" name="permissions">
|
|
745
804
|
<ui-spinner></ui-spinner>
|
|
746
805
|
Waiting for permission to be granted
|
|
@@ -752,20 +811,27 @@ elation.elements.define('janus-voip-picker-audio', class extends elation.element
|
|
|
752
811
|
<janus-voip-picker-mictest name="mictest" width="75" height="25"></janus-voip-picker-mictest>
|
|
753
812
|
</li>
|
|
754
813
|
<!-- li><ui-select name="outputDevice" label="Output"></ui-select></li -->
|
|
755
|
-
<li><ui-toggle name="echoCancellation" label="Echo Cancellation"></ui-toggle></li>
|
|
756
|
-
<li><ui-toggle name="noiseSuppression" label="Noise Reduction"></ui-toggle></li>
|
|
757
|
-
</ul>
|
|
758
|
-
<h3>Video</h3>
|
|
759
|
-
<ul>
|
|
760
|
-
<li><ui-toggle name="webcamEnabled" label="Webcam"></ui-toggle></li>
|
|
761
|
-
<li>
|
|
762
|
-
<ui-select name="videoDevice" label="Webcam" hidden="1"></ui-select>
|
|
763
|
-
<janus-voip-picker-videotest name="videotest" width="150" height="150"></janus-voip-picker-videotest>
|
|
764
|
-
</li>
|
|
814
|
+
<li><ui-toggle name="echoCancellation" label="Echo Cancellation" checked></ui-toggle></li>
|
|
815
|
+
<li><ui-toggle name="noiseSuppression" label="Noise Reduction" checked></ui-toggle></li>
|
|
765
816
|
</ul>
|
|
817
|
+
`;
|
|
818
|
+
|
|
819
|
+
if (this.showvideo && this.showvideo != 'false') {
|
|
820
|
+
tplstr += `<h3>Video</h3>
|
|
821
|
+
<ul>
|
|
822
|
+
<li><ui-toggle name="webcamEnabled" label="Webcam"></ui-toggle></li>
|
|
823
|
+
<li>
|
|
824
|
+
<ui-select name="videoDevice" label="Webcam" hidden="1"></ui-select>
|
|
825
|
+
<janus-voip-picker-videotest name="videotest" width="150" height="150"></janus-voip-picker-videotest>
|
|
826
|
+
</li>
|
|
827
|
+
</ul>
|
|
828
|
+
`;
|
|
829
|
+
}
|
|
830
|
+
tplstr += `
|
|
766
831
|
<ui-label name="error" hidden></ui-label>
|
|
767
832
|
<ui-button name="submit">Continue</ui-button>
|
|
768
|
-
|
|
833
|
+
`;
|
|
834
|
+
this.elements = elation.elements.fromString(tplstr, this);
|
|
769
835
|
|
|
770
836
|
if (this.config) {
|
|
771
837
|
console.log('I have a config!', this.config);
|
|
@@ -776,7 +842,9 @@ elation.elements.define('janus-voip-picker-audio', class extends elation.element
|
|
|
776
842
|
//this.getUserMedia();
|
|
777
843
|
|
|
778
844
|
this.elements.inputDevice.addEventListener('change', (ev) => this.getUserMedia());
|
|
779
|
-
this.elements.videoDevice
|
|
845
|
+
if (this.elements.videoDevice) {
|
|
846
|
+
this.elements.videoDevice.addEventListener('change', (ev) => this.getUserMedia());
|
|
847
|
+
}
|
|
780
848
|
//this.elements.outputDevice.addEventListener('change', (ev) => this.getUserMedia());
|
|
781
849
|
elation.events.add(this.elements.echoCancellation, 'toggle', (ev) => this.getUserMedia());
|
|
782
850
|
elation.events.add(this.elements.noiseSuppression, 'toggle', (ev) => this.getUserMedia());
|
|
@@ -808,11 +876,13 @@ elation.elements.define('janus-voip-picker-audio', class extends elation.element
|
|
|
808
876
|
|
|
809
877
|
// FIXME - I'm not really using these UI elements properly here, I shouldn't be mucking with the HTML elements directly
|
|
810
878
|
inputs.select.innerHTML = '';
|
|
811
|
-
cameras.select.innerHTML = '';
|
|
812
|
-
//outputs.select.innerHTML = '';
|
|
813
|
-
|
|
814
879
|
let hasWebcamPermission = true;
|
|
815
|
-
|
|
880
|
+
if (cameras) {
|
|
881
|
+
cameras.select.innerHTML = '';
|
|
882
|
+
//outputs.select.innerHTML = '';
|
|
883
|
+
|
|
884
|
+
this.webcamDisabledElement = elation.elements.create('option', {innerHTML: 'Disabled', value: 'none', append: cameras.select});
|
|
885
|
+
}
|
|
816
886
|
devices.forEach(d => {
|
|
817
887
|
if (d.kind == 'audioinput') {
|
|
818
888
|
elation.elements.create('option', {innerHTML: d.label, value: d.deviceId, append: inputs.select});
|
|
@@ -826,16 +896,18 @@ elation.elements.define('janus-voip-picker-audio', class extends elation.element
|
|
|
826
896
|
elation.elements.create('option', {innerHTML: d.label, value: d.deviceId, append: outputs.select});
|
|
827
897
|
}
|
|
828
898
|
});
|
|
829
|
-
if (
|
|
830
|
-
this.elements.
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
899
|
+
if (this.elements.videoDevice) {
|
|
900
|
+
if (hasWebcamPermission && this.elements.videoDevice.hidden ) {
|
|
901
|
+
this.elements.webcamEnabled.hide();
|
|
902
|
+
this.elements.videoDevice.show();
|
|
903
|
+
let option = this.elements.videoDevice.select.childNodes[0];
|
|
904
|
+
option.selected = true;
|
|
905
|
+
this.elements.videoDevice.select.value = option.value;
|
|
906
|
+
} else {
|
|
907
|
+
console.log('NO WEBCAM PERMISSION');
|
|
908
|
+
this.elements.webcamEnabled.show();
|
|
909
|
+
this.elements.videoDevice.hide();
|
|
910
|
+
}
|
|
839
911
|
}
|
|
840
912
|
this.elements.permissions.style.display = 'none';
|
|
841
913
|
|
|
@@ -845,7 +917,7 @@ elation.elements.define('janus-voip-picker-audio', class extends elation.element
|
|
|
845
917
|
//this.elements.inputDevice.select.value = this.voipconfig.inputDevice;
|
|
846
918
|
this.elements.inputDevice.setSelected(voipconfig.inputDevice);
|
|
847
919
|
}
|
|
848
|
-
if (voipconfig.videoDevice) {
|
|
920
|
+
if (voipconfig.videoDevice && this.elements.videoDevice) {
|
|
849
921
|
this.elements.videoDevice.setSelected(voipconfig.videoDevice);
|
|
850
922
|
}
|
|
851
923
|
//this.dispatchEvent(new CustomEvent('select', {detail: this.stream}));
|
|
@@ -867,7 +939,7 @@ elation.elements.define('janus-voip-picker-audio', class extends elation.element
|
|
|
867
939
|
console.log('input!', this.elements.inputDevice.value);
|
|
868
940
|
constraints.audio.deviceId = { exact: this.elements.inputDevice.value };
|
|
869
941
|
}
|
|
870
|
-
if (this.elements.videoDevice.value && this.elements.videoDevice.value != 'none') {
|
|
942
|
+
if (this.elements.videoDevice && this.elements.videoDevice.value && this.elements.videoDevice.value != 'none') {
|
|
871
943
|
console.log('video!', this.elements.videoDevice.value);
|
|
872
944
|
constraints.video = {
|
|
873
945
|
deviceId: { exact: this.elements.videoDevice.value },
|
|
@@ -891,7 +963,9 @@ elation.elements.define('janus-voip-picker-audio', class extends elation.element
|
|
|
891
963
|
.then(stream => {
|
|
892
964
|
this.elements.submit.disabled = false;
|
|
893
965
|
this.elements.mictest.setStream(stream);
|
|
894
|
-
this.elements.videotest
|
|
966
|
+
if (this.elements.videotest) {
|
|
967
|
+
this.elements.videotest.setStream(stream);
|
|
968
|
+
}
|
|
895
969
|
if (this.stream) {
|
|
896
970
|
let tracks = this.stream.getTracks();
|
|
897
971
|
tracks.forEach(t => {
|
|
@@ -928,10 +1002,12 @@ elation.elements.define('janus-voip-picker-audio', class extends elation.element
|
|
|
928
1002
|
];
|
|
929
1003
|
keys.forEach(k => {
|
|
930
1004
|
let el = this.elements[k];
|
|
931
|
-
if (
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
1005
|
+
if (this.elements[k]) {
|
|
1006
|
+
if (el instanceof elation.elements.ui.toggle) {
|
|
1007
|
+
settings[k] = this.elements[k].checked;
|
|
1008
|
+
} else {
|
|
1009
|
+
settings[k] = this.elements[k].value;
|
|
1010
|
+
}
|
|
935
1011
|
}
|
|
936
1012
|
});
|
|
937
1013
|
return settings;
|
|
@@ -954,8 +1030,8 @@ elation.elements.define('janus-voip-picker-audio', class extends elation.element
|
|
|
954
1030
|
if ('inputDevice' in settings) this.elements['inputDevice'].setSelected(settings['inputDevice']);
|
|
955
1031
|
if ('echoCancellation' in settings) this.elements['echoCancellation'].checked = settings['echoCancellation'];
|
|
956
1032
|
if ('noiseSuppression' in settings) this.elements['noiseSuppression'].checked = settings['noiseSuppression'];
|
|
957
|
-
if ('webcamEnabled' in settings) this.elements['webcamEnabled'].checked = settings['webcamEnabled'];
|
|
958
|
-
if ('videoDevice' in settings) this.elements['videoDevice'].setSelected(settings['videoDevice']);
|
|
1033
|
+
if ('webcamEnabled' in settings && this.elements['webcamEnabled']) this.elements['webcamEnabled'].checked = settings['webcamEnabled'];
|
|
1034
|
+
if ('videoDevice' in settings && this.elements['videoDevice']) this.elements['videoDevice'].setSelected(settings['videoDevice']);
|
|
959
1035
|
|
|
960
1036
|
this.currentsettings = settings;
|
|
961
1037
|
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
|
2
|
+
// Distributed under an MIT license: https://codemirror.net/LICENSE
|
|
3
|
+
|
|
4
|
+
(function(mod) {
|
|
5
|
+
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
|
6
|
+
mod(require("../../lib/codemirror"));
|
|
7
|
+
else if (typeof define == "function" && define.amd) // AMD
|
|
8
|
+
define(["../../lib/codemirror"], mod);
|
|
9
|
+
else // Plain browser env
|
|
10
|
+
mod(CodeMirror);
|
|
11
|
+
})(function(CodeMirror) {
|
|
12
|
+
var Pos = CodeMirror.Pos;
|
|
13
|
+
|
|
14
|
+
function forEach(arr, f) {
|
|
15
|
+
for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function arrayContains(arr, item) {
|
|
19
|
+
if (!Array.prototype.indexOf) {
|
|
20
|
+
var i = arr.length;
|
|
21
|
+
while (i--) {
|
|
22
|
+
if (arr[i] === item) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
return arr.indexOf(item) != -1;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function scriptHint(editor, keywords, getToken, options) {
|
|
32
|
+
// Find the token at the cursor
|
|
33
|
+
var cur = editor.getCursor(), token = getToken(editor, cur);
|
|
34
|
+
if (/\b(?:string|comment)\b/.test(token.type)) return;
|
|
35
|
+
var innerMode = CodeMirror.innerMode(editor.getMode(), token.state);
|
|
36
|
+
if (innerMode.mode.helperType === "json") return;
|
|
37
|
+
token.state = innerMode.state;
|
|
38
|
+
|
|
39
|
+
// If it's not a 'word-style' token, ignore the token.
|
|
40
|
+
if (!/^[\w$_]*$/.test(token.string)) {
|
|
41
|
+
token = {start: cur.ch, end: cur.ch, string: "", state: token.state,
|
|
42
|
+
type: token.string == "." ? "property" : null};
|
|
43
|
+
} else if (token.end > cur.ch) {
|
|
44
|
+
token.end = cur.ch;
|
|
45
|
+
token.string = token.string.slice(0, cur.ch - token.start);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
var tprop = token;
|
|
49
|
+
// If it is a property, find out what it is a property of.
|
|
50
|
+
while (tprop.type == "property") {
|
|
51
|
+
tprop = getToken(editor, Pos(cur.line, tprop.start));
|
|
52
|
+
if (tprop.string != ".") return;
|
|
53
|
+
tprop = getToken(editor, Pos(cur.line, tprop.start));
|
|
54
|
+
if (!context) var context = [];
|
|
55
|
+
context.push(tprop);
|
|
56
|
+
}
|
|
57
|
+
return {list: getCompletions(token, context, keywords, options),
|
|
58
|
+
from: Pos(cur.line, token.start),
|
|
59
|
+
to: Pos(cur.line, token.end)};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function javascriptHint(editor, options) {
|
|
63
|
+
return scriptHint(editor, javascriptKeywords,
|
|
64
|
+
function (e, cur) {return e.getTokenAt(cur);},
|
|
65
|
+
options);
|
|
66
|
+
};
|
|
67
|
+
CodeMirror.registerHelper("hint", "javascript", javascriptHint);
|
|
68
|
+
|
|
69
|
+
function getCoffeeScriptToken(editor, cur) {
|
|
70
|
+
// This getToken, it is for coffeescript, imitates the behavior of
|
|
71
|
+
// getTokenAt method in javascript.js, that is, returning "property"
|
|
72
|
+
// type and treat "." as independent token.
|
|
73
|
+
var token = editor.getTokenAt(cur);
|
|
74
|
+
if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') {
|
|
75
|
+
token.end = token.start;
|
|
76
|
+
token.string = '.';
|
|
77
|
+
token.type = "property";
|
|
78
|
+
}
|
|
79
|
+
else if (/^\.[\w$_]*$/.test(token.string)) {
|
|
80
|
+
token.type = "property";
|
|
81
|
+
token.start++;
|
|
82
|
+
token.string = token.string.replace(/\./, '');
|
|
83
|
+
}
|
|
84
|
+
return token;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function coffeescriptHint(editor, options) {
|
|
88
|
+
return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options);
|
|
89
|
+
}
|
|
90
|
+
CodeMirror.registerHelper("hint", "coffeescript", coffeescriptHint);
|
|
91
|
+
|
|
92
|
+
var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " +
|
|
93
|
+
"toUpperCase toLowerCase split concat match replace search").split(" ");
|
|
94
|
+
var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " +
|
|
95
|
+
"lastIndexOf every some filter forEach map reduce reduceRight ").split(" ");
|
|
96
|
+
var funcProps = "prototype apply call bind".split(" ");
|
|
97
|
+
var javascriptKeywords = ("break case catch class const continue debugger default delete do else export extends false finally for function " +
|
|
98
|
+
"if in import instanceof new null return super switch this throw true try typeof var void while with yield").split(" ");
|
|
99
|
+
var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " +
|
|
100
|
+
"if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" ");
|
|
101
|
+
|
|
102
|
+
function forAllProps(obj, callback) {
|
|
103
|
+
if (!Object.getOwnPropertyNames || !Object.getPrototypeOf) {
|
|
104
|
+
for (var name in obj) callback(name)
|
|
105
|
+
} else {
|
|
106
|
+
for (var o = obj; o; o = Object.getPrototypeOf(o))
|
|
107
|
+
Object.getOwnPropertyNames(o).forEach(callback)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function getCompletions(token, context, keywords, options) {
|
|
112
|
+
var found = [], start = token.string, global = options && options.globalScope || window;
|
|
113
|
+
function maybeAdd(str) {
|
|
114
|
+
if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str);
|
|
115
|
+
}
|
|
116
|
+
function gatherCompletions(obj) {
|
|
117
|
+
if (typeof obj == "string") forEach(stringProps, maybeAdd);
|
|
118
|
+
else if (obj instanceof Array) forEach(arrayProps, maybeAdd);
|
|
119
|
+
else if (obj instanceof Function) forEach(funcProps, maybeAdd);
|
|
120
|
+
forAllProps(obj, maybeAdd)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (context && context.length) {
|
|
124
|
+
// If this is a property, see if it belongs to some object we can
|
|
125
|
+
// find in the current environment.
|
|
126
|
+
var obj = context.pop(), base;
|
|
127
|
+
if (obj.type && obj.type.indexOf("variable") === 0) {
|
|
128
|
+
if (options && options.additionalContext)
|
|
129
|
+
base = options.additionalContext[obj.string];
|
|
130
|
+
if (!options || options.useGlobalScope !== false)
|
|
131
|
+
base = base || global[obj.string];
|
|
132
|
+
} else if (obj.type == "string") {
|
|
133
|
+
base = "";
|
|
134
|
+
} else if (obj.type == "atom") {
|
|
135
|
+
base = 1;
|
|
136
|
+
} else if (obj.type == "function") {
|
|
137
|
+
if (global.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') &&
|
|
138
|
+
(typeof global.jQuery == 'function'))
|
|
139
|
+
base = global.jQuery();
|
|
140
|
+
else if (global._ != null && (obj.string == '_') && (typeof global._ == 'function'))
|
|
141
|
+
base = global._();
|
|
142
|
+
}
|
|
143
|
+
while (base != null && context.length)
|
|
144
|
+
base = base[context.pop().string];
|
|
145
|
+
if (base != null) gatherCompletions(base);
|
|
146
|
+
} else {
|
|
147
|
+
// If not, just look in the global object, any local scope, and optional additional-context
|
|
148
|
+
// (reading into JS mode internals to get at the local and global variables)
|
|
149
|
+
for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name);
|
|
150
|
+
for (var c = token.state.context; c; c = c.prev)
|
|
151
|
+
for (var v = c.vars; v; v = v.next) maybeAdd(v.name)
|
|
152
|
+
for (var v = token.state.globalVars; v; v = v.next) maybeAdd(v.name);
|
|
153
|
+
if (options && options.additionalContext != null)
|
|
154
|
+
for (var key in options.additionalContext)
|
|
155
|
+
maybeAdd(key);
|
|
156
|
+
if (!options || options.useGlobalScope !== false)
|
|
157
|
+
gatherCompletions(global);
|
|
158
|
+
forEach(keywords, maybeAdd);
|
|
159
|
+
}
|
|
160
|
+
return found;
|
|
161
|
+
}
|
|
162
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
.CodeMirror-hints {
|
|
2
|
+
position: absolute;
|
|
3
|
+
z-index: 10;
|
|
4
|
+
overflow: hidden;
|
|
5
|
+
list-style: none;
|
|
6
|
+
|
|
7
|
+
margin: 0;
|
|
8
|
+
padding: 2px;
|
|
9
|
+
|
|
10
|
+
-webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
|
|
11
|
+
-moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
|
|
12
|
+
box-shadow: 2px 3px 5px rgba(0,0,0,.2);
|
|
13
|
+
border-radius: 3px;
|
|
14
|
+
border: 1px solid silver;
|
|
15
|
+
|
|
16
|
+
background: white;
|
|
17
|
+
font-size: 90%;
|
|
18
|
+
font-family: monospace;
|
|
19
|
+
|
|
20
|
+
max-height: 20em;
|
|
21
|
+
overflow-y: auto;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.CodeMirror-hint {
|
|
25
|
+
margin: 0;
|
|
26
|
+
padding: 0 4px;
|
|
27
|
+
border-radius: 2px;
|
|
28
|
+
white-space: pre;
|
|
29
|
+
color: black;
|
|
30
|
+
cursor: pointer;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
li.CodeMirror-hint-active {
|
|
34
|
+
background: #08f;
|
|
35
|
+
color: white;
|
|
36
|
+
}
|