janusweb 1.5.51 → 1.5.52

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.
@@ -1,4 +1,11 @@
1
+
2
+ let sfus = {};
3
+
1
4
  elation.elements.define('janus-voip-client', class extends elation.elements.base {
5
+ init() {
6
+ super.init();
7
+ this.defineAttribute('spatialized', { type: 'boolean', default: false, set: this.updateSpatialization });
8
+ }
2
9
  create() {
3
10
  this.localuser = document.createElement('janus-voip-localuser');
4
11
  this.appendChild(this.localuser);
@@ -10,7 +17,6 @@ elation.elements.define('janus-voip-client', class extends elation.elements.base
10
17
  let datapath = elation.config.get('janusweb.datapath', '/media/janusweb'),
11
18
  assetpath = datapath + 'assets/webui/apps/comms/';
12
19
 
13
-
14
20
  janus.assetpack.loadJSON([
15
21
  { "assettype":"sound", "name":"voip_ui_enter", "src":"assets/webui/apps/comms/sounds/ui_casual_pops_confirm.wav" },
16
22
  { "assettype":"sound", "name":"voip_ui_mic", "src":"assets/webui/apps/comms/sounds/ui_casual_pops_back.wav" },
@@ -20,7 +26,7 @@ elation.elements.define('janus-voip-client', class extends elation.elements.base
20
26
  elation.events.add(janus._target, 'room_change', (ev) => {
21
27
  if (!room.loaded) {
22
28
  room.addEventListener('room_load_processed', async () => {
23
- console.log('changed room', room.voipid, ev);
29
+ console.log('[voip-client] changed room', room.voipid, ev);
24
30
  this.setRoom(room);
25
31
  });
26
32
  } else {
@@ -44,14 +50,16 @@ elation.elements.define('janus-voip-client', class extends elation.elements.base
44
50
  let roomid = newroom.voipid || newroom.id;
45
51
 
46
52
  if (this.currentroom) { // && this.rooms[roomid] !== this.currentroom) {
53
+ console.log('[voip-client] setRoom called, disconnect from existing room', this.currentroom);
47
54
  if (this.currentroom.disconnect) {
48
- this.currentroom.disconnect();
55
+ //this.currentroom.disconnect();
56
+ this.currentroom.leave();
49
57
  }
50
58
  this.removeChild(this.currentroom);
51
59
  }
52
60
 
53
61
  if (newroom.private) {
54
- console.log('Room is private, don\'t connect to VOIP server');
62
+ console.log('[voip-client] Room is private, don\'t connect to VOIP server');
55
63
  this.currentroom = false;
56
64
  return;
57
65
  }
@@ -62,6 +70,7 @@ elation.elements.define('janus-voip-client', class extends elation.elements.base
62
70
  append: this,
63
71
  roomid: roomid,
64
72
  });
73
+ console.log('[voip-client] create new voip-client', voiptype, roomid, this.rooms[roomid]);
65
74
 
66
75
  if (this.inputstream) {
67
76
  this.rooms[roomid].setInputStream(this.inputstream);
@@ -72,6 +81,7 @@ elation.elements.define('janus-voip-client', class extends elation.elements.base
72
81
  elation.events.fire({type: 'init', element: this});
73
82
  });
74
83
  } else {
84
+ console.log('[voip-client] voip client for room already exists', roomid, this.rooms[roomid]);
75
85
  this.appendChild(this.rooms[roomid]);
76
86
  this.rooms[roomid].connect();
77
87
  }
@@ -85,7 +95,6 @@ elation.elements.define('janus-voip-client', class extends elation.elements.base
85
95
  this.localuser.setData(null);
86
96
  }
87
97
  handleUserChat(ev) {
88
- console.log('got a chat', ev.data);
89
98
  let msg = ev.data.message;
90
99
  let m = msg.data.match(/📞 (.*$)/);
91
100
  if (m) {
@@ -99,55 +108,103 @@ elation.elements.define('janus-voip-client', class extends elation.elements.base
99
108
  }
100
109
  }
101
110
  }
111
+ updateSpatialization() {
112
+ if (this.spatialized) {
113
+ requestAnimationFrame(() => this.spatialize());
114
+ } else {
115
+ remoteusers.forEach(user => {
116
+ if (user.spatialized) user.spatialized = false;
117
+ });
118
+ }
119
+ }
120
+ spatialize() {
121
+ let remoteusers = this.querySelectorAll('janus-voip-remoteuser');
122
+ remoteusers.forEach(user => {
123
+ if (!user.spatialized) user.spatialized = true;
124
+ user.spatialize();
125
+ });
126
+ if (this.spatialized) {
127
+ requestAnimationFrame(() => this.spatialize());
128
+ }
129
+ }
102
130
  });
103
131
  elation.elements.define('janus-voip-client-janus', class extends elation.elements.base {
132
+ init() {
133
+ super.init();
134
+ this.defineAttribute('roomid', { type: 'string' });
135
+ }
104
136
  create() {
105
137
  this.connect();
106
138
  }
107
139
  connect() {
108
140
  if (typeof NAF != 'undefined' && !('janus' in NAF.adapters.adapters)) {
109
- console.log('NAF adapter not found, load it');
141
+ console.log('[voip-client-janus] NAF adapter not found, load it');
110
142
  elation.file.get('js', janus.ui.apps.default.apps.comms.resolveFullURL('./external/naf-janus-adapter.js'), (ev) => {
143
+ console.log('[voip-client-janus] NAF adapter loaded, continue');
111
144
  this.connect();
112
145
  });
113
146
  return;
114
147
  }
115
- let sfu = new JanusNAF(player.getNetworkUsername()); //'testclient-' + Math.floor(Math.random() * 1e6));
116
- this.sfu = sfu;
117
148
 
118
149
  let voipserver = room.voipserver || 'voip.janusxr.org';
119
150
 
120
- sfu.connect('wss://' + voipserver + '/', 'default', room.url, true);
151
+ let roomid = this.roomid || room.voipid || room.url;
152
+ let sfu = sfus[voipserver];
153
+ if (!sfu) {
154
+ sfu = new JanusNAF(player.getNetworkUsername()); //'testclient-' + Math.floor(Math.random() * 1e6));
155
+ sfu.connect('wss://' + voipserver + '/', 'default', roomid, true);
156
+ sfus[voipserver] = sfu;
157
+ } else {
158
+ sfu.setRoom(roomid);
159
+ }
160
+ this.sfu = sfu;
161
+
121
162
 
122
163
  this.localuser = this.parentNode.localuser;
123
164
  //this.localuser = document.createElement('janus-voip-localuser');
124
165
  //this.appendChild(this.localuser);
125
166
 
126
- let remoteusers = {};
127
- sfu.addEventListener('voip-media-change', (ev) => {
128
- console.log('got some media', ev.detail);
129
- this.localuser.setData(ev.detail.stream);
130
- });
131
- sfu.addEventListener('voip-user-connect', (ev) => {
132
- console.log('new client', ev);
133
- let el = document.createElement('janus-voip-remoteuser');
134
- el.setUserData(ev.detail);
135
- this.appendChild(el);
136
- remoteusers[ev.detail.id] = el;
137
- });
138
- sfu.addEventListener('voip-user-disconnect', (ev) => {
139
- let userid = ev.detail.id,
140
- user = remoteusers[userid];
141
- if (user) {
142
- user.destroy();
143
- setTimeout(() => { if (user.parentNode === this) this.removeChild(user); }, 250);
144
- }
145
- });
146
- document.addEventListener('voip-picker-select', ev => {
147
- let localStream = ev.detail;
148
- sfu.adapter.setLocalMediaStream(localStream);
149
- sfu.dispatchEvent(new CustomEvent('voip-media-change', {detail: { stream: localStream }}));
150
- });
167
+ if (!this.remoteusers) {
168
+ this.remoteusers = {};
169
+ }
170
+ let remoteusers = this.remoteusers;
171
+ if (!this.sfueventsregistered) {
172
+ sfu.addEventListener('voip-media-change', (ev) => {
173
+ console.log('[voip-client-janus] got some media', ev.detail);
174
+ this.localuser.setData(ev.detail.stream);
175
+ });
176
+ sfu.addEventListener('voip-user-connect', (ev) => {
177
+ console.log('[voip-client-janus] user connected', ev);
178
+ if (!this.remoteusers[ev.detail.id]) {
179
+ let el = document.createElement('janus-voip-remoteuser');
180
+ el.setUserData(ev.detail);
181
+ this.appendChild(el);
182
+ this.remoteusers[ev.detail.id] = el;
183
+ } else {
184
+ let el = this.remoteusers[ev.detail.id];
185
+ el.setUserData(ev.detail);
186
+ this.appendChild(el);
187
+ }
188
+ });
189
+ sfu.addEventListener('voip-user-disconnect', (ev) => {
190
+ console.log('[voip-client-janus] user disconnected', ev);
191
+ let userid = ev.detail.id,
192
+ user = remoteusers[userid];
193
+ if (user) {
194
+ user.destroy();
195
+ setTimeout(() => { if (user.parentNode === this) this.removeChild(user); }, 250);
196
+ }
197
+ });
198
+ document.addEventListener('voip-picker-select', ev => {
199
+ let localStream = ev.detail;
200
+ if (localStream) {
201
+ sfu.adapter.setLocalMediaStream(localStream);
202
+ }
203
+ sfu.dispatchEvent(new CustomEvent('voip-media-change', {detail: { stream: localStream }}));
204
+ });
205
+ elation.events.add(player._target, 'username_change', (ev) => this.handleUsernameChange(ev));
206
+ this.sfueventsregistered = true;
207
+ }
151
208
  if (this.inputstream) {
152
209
  sfu.adapter.setLocalMediaStream(this.inputstream);
153
210
  }
@@ -186,7 +243,6 @@ console.log('leave room and remove all occupants', this.room);
186
243
  });
187
244
  */
188
245
  // FIXME - player proxy should expose .addEventListener()
189
- elation.events.add(player._target, 'username_change', (ev) => this.handleUsernameChange(ev));
190
246
  elation.events.fire({type: 'init', element: this});
191
247
  }
192
248
  disconnect() {
@@ -194,12 +250,17 @@ console.log('leave room and remove all occupants', this.room);
194
250
  this.sfu.adapter.disconnect();
195
251
  }
196
252
  }
253
+ leave() {
254
+ if (this.sfu && this.sfu.adapter && this.sfu.adapter.publisher) {
255
+ this.sfu.adapter.sendLeave(this.sfu.adapter.publisher.handle);
256
+ }
257
+ }
197
258
  initRoom(room) {
198
259
  let sfu = this.sfu;
199
260
  if (!room.private) {
200
- sfu.adapter.setRoom(room.url)
201
- console.log('room is now', sfu.adapter.room);
202
- sfu.adapter.reconnect();
261
+ let roomid = room.voipid || room.url;
262
+ sfu.setRoom(roomid)
263
+ console.log('[voip-client-janus] room is now', sfu.adapter.room);
203
264
  /*
204
265
  let handle = sfu.adapter.publisher.handle;
205
266
  sfu.adapter.sendJoin(handle, {
@@ -208,7 +269,7 @@ console.log('leave room and remove all occupants', this.room);
208
269
  });
209
270
  */
210
271
  } else {
211
- console.log('new room is private, disconnect');
272
+ console.log('[voip-client-janus] new room is private, disconnect');
212
273
  setTimeout(() => {
213
274
  sfu.adapter.disconnect();
214
275
  }, 0);
@@ -220,7 +281,9 @@ console.log('leave room and remove all occupants', this.room);
220
281
  setInputStream(stream) {
221
282
  if (this.sfu) {
222
283
  this.inputstream = stream;
223
- this.sfu.adapter.setLocalMediaStream(stream);
284
+ if (stream) {
285
+ this.sfu.adapter.setLocalMediaStream(stream);
286
+ }
224
287
  } else {
225
288
  this.connect();
226
289
  }
@@ -445,7 +508,7 @@ elation.elements.define('janus-voip-localuser', class extends elation.elements.b
445
508
  video.srcObject = data;
446
509
  this.appendChild(video);
447
510
  video.muted = true;
448
- video.play().then(() => console.log('playing', video)).catch(e => console.log('Failed to start video', e, video));
511
+ video.play().then(() => console.log('[voip-localuser] playing', video)).catch(e => console.log('[voip-localuser] Failed to start video', e, video));
449
512
  this.video = video;
450
513
  }
451
514
 
@@ -544,53 +607,85 @@ elation.elements.define('janus-voip-remoteuser', class extends elation.elements.
544
607
  create() {
545
608
  this.defineAttributes({
546
609
  'muted': { type: 'boolean', default: false },
610
+ 'active': { type: 'boolean', default: false },
547
611
  'hasaudio': { type: 'boolean', default: false },
548
612
  'hasvideo': { type: 'boolean', default: false },
549
613
  'averagevolume': { type: 'float', default: 0 },
550
614
  'speaking': { type: 'boolean', default: false },
551
615
  'threshold': { type: 'float', default: .2 },
616
+ 'spatialized': { type: 'bool', default: false },
552
617
  });
553
618
  this.lastposition = V();
554
- setTimeout(() => this.setAttribute('active', true), 100);
555
619
  }
556
620
  setUserData(data) {
621
+ if (!this.created) {
622
+ setTimeout(() => this.setUserData(data), 10);
623
+ return;
624
+ }
557
625
  this.id = data.id;
558
- console.log('got a remote voip user', data);
626
+ console.log('[voip-remoteuser] got a remote voip user', data);
627
+ this.active = true;
559
628
 
560
629
  if (!this.label) {
561
630
  let label = document.createElement('h2');
562
- label.innerText = this.id;
563
631
  this.appendChild(label);
564
632
  this.label = label;
565
633
  }
634
+ this.label.innerText = this.id;
566
635
 
567
636
  if (data.media.video) {
568
637
  let track = data.media.video.getVideoTracks()[0];
569
- data.media.video.addEventListener('addtrack', (ev) => console.log('a track was added', ev));
570
- data.media.video.addEventListener('removetrack', (ev) => console.log('a track was added', ev));
571
- let video = document.createElement('video');
638
+ data.media.video.addEventListener('addtrack', (ev) => console.log('[voip-remoteuser] a track was added', ev));
639
+ data.media.video.addEventListener('removetrack', (ev) => console.log('[voip-remoteuser] a track was removed', ev));
640
+ let video = this.video;
641
+ if (!video) {
642
+ video = document.createElement('video');
643
+ video.addEventListener('resize', (ev) => { console.log('[voip-remoteuser] video resized', video.videoWidth, video.videoHeight, video, this); this.updateVideo(); });
644
+ }
572
645
  video.muted = true;
573
646
  video.srcObject = data.media.video;
574
647
  this.appendChild(video);
575
- console.log('remote user call play', video);
648
+ console.log('[voip-remoteuser] remote user call play', video);
576
649
  video.play()
577
- .then(() => { console.log('remote user video playing', video, this); })
578
- .catch(e => { console.log('failed to play remote video', video, e, this); });
650
+ .then(() => {
651
+ console.log('[voip-remoteuser] remote user video playing', video, this);
652
+ this.updateVideo();
653
+
654
+ let frametimer = false;
655
+ let detectStoppedVideo = (frame) => {
656
+ video.requestVideoFrameCallback(detectStoppedVideo);
657
+ if (frametimer) clearTimeout(frametimer);
658
+ frametimer = setTimeout(() => {
659
+ // FIXME - when video stops, we still display the last frame indefinitely. The below code clears the video frame,
660
+ // but prevents video from resuming if the remote player reenables their camera
661
+ //video.srcObject = new MediaStream(video.srcObject.getAudioTracks());
662
+ this.hasvideo = false;
663
+ }, 2000);
664
+ if (frame && !this.hasvideo) {
665
+ this.hasvideo = true;
666
+ }
667
+ };
668
+ detectStoppedVideo(false);
669
+ })
670
+ .catch(e => { console.log('[voip-remoteuser] failed to play remote video', video, e, this); });
579
671
  this.video = video;
580
- video.addEventListener('resize', (ev) => { console.log('video resized', video, this); this.updateVideo(); });
581
- this.updateVideo();
582
- this.hasvideo = true;
672
+ //this.hasvideo = true;
583
673
  } else {
584
- this.hasvideo = false;
674
+ //this.hasvideo = false;
585
675
  }
586
676
 
587
677
  // audio
588
678
  if (data.media.audio) {
589
- let audio = document.createElement('audio');
679
+ let audio = this.audio || document.createElement('audio');
590
680
  audio.srcObject = data.media.audio;
591
681
  this.audio = audio;
592
682
  this.appendChild(audio);
593
- this.hasaudio = true;
683
+
684
+ audio.play()
685
+ .then(() => {
686
+ console.log('[voip-remoteuser] remote user audio playing', audio, this);
687
+ this.hasaudio = true;
688
+ });
594
689
 
595
690
  let listener = player.engine.systems.sound.getRealListener();
596
691
  let context = listener.context;
@@ -620,7 +715,7 @@ console.log('got a remote voip user', data);
620
715
  let remoteuser = janus.network.remoteplayers[this.id];
621
716
 
622
717
  if (!this.controlpanel) {
623
- this.controlpanel = elation.elements.create('ui-panel', { bottom: 1, append: this });
718
+ this.controlpanel = elation.elements.create('ui-panel', { bottom: true, append: this });
624
719
  this.mutebutton = elation.elements.create('ui-button', { label: 'Mute', name: "mutebutton", append: this.controlpanel });
625
720
  this.volume = elation.elements.create('ui-slider', { name: "volume", min: 0, max: 200, value: this.video.volume * 100, append: this.controlpanel, snap: 1 });
626
721
 
@@ -699,10 +794,10 @@ console.log('got a remote voip user', data);
699
794
  });
700
795
  }
701
796
 
702
- console.log('got remote media', data, remoteuser);
797
+ console.log('[voip-remoteuser] got remote media', data, remoteuser);
703
798
  }
704
799
  destroy() {
705
- console.log('stop media', this.id);
800
+ console.log('[voip-remoteuser] stop media', this.id);
706
801
  if (this.video) {
707
802
  //this.video.pause();
708
803
  }
@@ -711,7 +806,7 @@ console.log('got a remote voip user', data);
711
806
  let tracks = this.audio.srcObject.getTracks();
712
807
  //tracks.forEach(track => { console.log('stop track', track); track.stop(); });
713
808
  }
714
- this.removeAttribute('active');
809
+ this.active = false;
715
810
  if (this.parentNode) {
716
811
  this.parentNode.removeChild(this);
717
812
  }
@@ -720,18 +815,20 @@ console.log('got a remote voip user', data);
720
815
  let video = this.video;
721
816
  if (video) {
722
817
  let hasclass = elation.html.hasclass(video, 'active');
723
- if (video.videoWidth > 0 && video.videoHeight > 0 && !hasclass) {
818
+ if (video.videoWidth > 2 && video.videoHeight > 2 && !hasclass) {
724
819
  this.hasvideo = true;
725
820
  elation.html.addclass(video, 'active');
726
- } else if (hasclass && (video.videoWidth == 0 || video.videoHeight == 0)) {
821
+ } else if (hasclass && (video.videoWidth <= 2 || video.videoHeight <= 2)) {
727
822
  this.hasvideo = false;
728
823
  elation.html.removeclass(video, 'active');
729
824
  }
825
+ } else {
826
+ this.hasvideo = false;
730
827
  }
731
828
  }
732
829
  toggleMute() {
733
830
  this.muted = !this.muted;
734
- console.log('mute?', this.muted, this);
831
+ console.log('[voip-remoteuser] mute?', this.muted, this);
735
832
  let remoteuser = janus.network.remoteplayers[this.id];
736
833
  if (this.muted) {
737
834
  this.mutebutton.addclass('muted');
@@ -759,14 +856,31 @@ console.log('mute?', this.muted, this);
759
856
  this.colorreset = setTimeout(() => {
760
857
  this.speaking = false;
761
858
  this.colorreset = false;
859
+ this.video.style.removeProperty('box-shadow');
762
860
  }, 200);
861
+ let shadowsize = 2 + (3 * this.averagevolume);
862
+ this.video.style.boxShadow = '0 0 2px ' + shadowsize + 'px rgba(0,255,0,.8)';
863
+ } else {
864
+ this.video.style.removeProperty('box-shadow');
763
865
  }
866
+ this.hasaudio = this.averagevolume > 0;
764
867
 
765
868
  if (this.label3d) {
766
869
  this.label3d.setAudioVolume(this.averagevolume);
767
870
  this.remoteuser.setSpeakingVolume(this.averagevolume);
768
871
  }
769
872
  }
873
+ spatialize() {
874
+ if (!this.relativepos) this.relativepos = V();
875
+ let remoteuser = janus.network.remoteplayers[this.id];
876
+ if (remoteuser) {
877
+ let relativepos = player.worldToLocal(remoteuser.localToWorld(this.relativepos.set(0, 0, 0)));
878
+ let angle = Math.PI - Math.atan2(relativepos.x, relativepos.z),
879
+ len = .4 * window.innerHeight;
880
+ this.style.top = ( window.innerHeight / 2 - len * Math.cos(angle) - (this.offsetHeight / 2)) + 'px';
881
+ this.style.left = (len * Math.sin(angle) + window.innerWidth / 2 - (this.offsetWidth / 2)) + 'px';
882
+ }
883
+ }
770
884
  });
771
885
  elation.elements.define('janus-voip-picker', class extends elation.elements.base {
772
886
  create() {
@@ -791,10 +905,10 @@ elation.elements.define('janus-voip-picker', class extends elation.elements.base
791
905
  // We should use a session cookie-based timeout in addition to the localStorage settings
792
906
  this.handleSelectAudio({detail: 1});
793
907
  }
794
- console.log('voip picker loaded config', this.voipconfig);
908
+ console.log('[voip-picker] voip picker loaded config', this.voipconfig);
795
909
  }
796
910
  handleSelectNone() {
797
- console.log('selected none');
911
+ console.log('[voip-picker] selected none');
798
912
  //janus.engine.systems.sound.enableSound();
799
913
  if (this.subpicker && this.subpicker.parentNode) {
800
914
  this.subpicker.parentNode.removeChild(this.subpicker);
@@ -802,21 +916,23 @@ elation.elements.define('janus-voip-picker', class extends elation.elements.base
802
916
  this.dispatchEvent(new CustomEvent('select', { detail: false }));
803
917
  document.dispatchEvent(new CustomEvent('voip-picker-select', { detail: false }));
804
918
  player.setSetting('voip', false);
805
- this.subpicker.stopUserMedia();
919
+ if (this.subpicker) {
920
+ this.subpicker.stopUserMedia();
921
+ }
806
922
  if (!this.elements.none.active) this.elements.none.activate();
807
923
  this.elements.audio.deactivate();
808
924
  }
809
925
  handleSelectAudio(ev) {
810
- console.log('selected audio', ev.detail, this.voipconfig);
926
+ console.log('[voip-picker] selected audio', ev.detail, this.voipconfig);
811
927
  //janus.engine.systems.sound.enableSound();
812
928
  if (!this.subpicker) {
813
929
  this.subpicker = elation.elements.create('janus-voip-picker-audio', { config: (this.voipconfig ? JSON.stringify(this.voipconfig) : false), showvideo: this.showvideo });
814
930
  elation.events.add(this.subpicker, 'select', ev => {
815
- console.log('SELECTED', ev.detail);
931
+ console.log('[voip-picker] SELECTED', ev.detail);
816
932
  document.dispatchEvent(new CustomEvent('voip-picker-select', { detail: ev.detail }));
817
933
  this.dispatchEvent(new CustomEvent('select', { detail: ev.detail }));
818
934
  let voipsettings = this.subpicker.getSettings();
819
- console.log('update voip settings', voipsettings);
935
+ console.log('[voip-picker] update voip settings', voipsettings);
820
936
  player.setSetting('voip', voipsettings);
821
937
  });
822
938
  }
@@ -826,7 +942,7 @@ console.log('SELECTED', ev.detail);
826
942
  this.elements.none.deactivate();
827
943
  }
828
944
  handleSelectVideo() {
829
- console.log('selected video');
945
+ console.log('[voip-picker] selected video');
830
946
  this.dispatchEvent(new CustomEvent('select', { detail: 'video' }));
831
947
  }
832
948
  });
@@ -871,7 +987,7 @@ elation.elements.define('janus-voip-picker-audio', class extends elation.element
871
987
  this.elements = elation.elements.fromString(tplstr, this);
872
988
 
873
989
  if (this.config) {
874
- console.log('I have a config!', this.config);
990
+ console.log('[voip-picker-audio] I have a config!', this.config);
875
991
  this.setSettings(JSON.parse(this.config));
876
992
  }
877
993
 
@@ -894,7 +1010,7 @@ elation.elements.define('janus-voip-picker-audio', class extends elation.element
894
1010
  this.updateButton();
895
1011
  });
896
1012
  elation.events.add(this.elements.webcamEnabled, 'toggle', (ev) => {
897
- console.log('toggled', ev.data, ev);
1013
+ console.log('[voip-picker-audio] toggled', ev.data, ev);
898
1014
  if (ev.data) {
899
1015
  this.getUserMedia({video: true});
900
1016
  }
@@ -946,7 +1062,7 @@ elation.elements.define('janus-voip-picker-audio', class extends elation.element
946
1062
  this.elements.webcamEnabled.hide();
947
1063
  this.elements.videoDevice.show();
948
1064
  } else {
949
- console.log('NO WEBCAM PERMISSION');
1065
+ console.log('[voip-picker-audio] NO WEBCAM PERMISSION');
950
1066
  this.elements.webcamEnabled.show();
951
1067
  this.elements.videoDevice.hide();
952
1068
  }
@@ -978,11 +1094,11 @@ elation.elements.define('janus-voip-picker-audio', class extends elation.element
978
1094
  constraints.audio.autoGainControl = { ideal: false };
979
1095
 
980
1096
  if (this.elements.inputDevice.value && this.elements.inputDevice.value != 'default') {
981
- console.log('input!', this.elements.inputDevice.value);
1097
+ console.log('[voip-picker-audio] input!', this.elements.inputDevice.value);
982
1098
  constraints.audio.deviceId = { ideal: this.elements.inputDevice.value };
983
1099
  }
984
1100
  if (this.elements.videoDevice && this.elements.videoDevice.value && this.elements.videoDevice.value != 'none') {
985
- console.log('video!', this.elements.videoDevice.value);
1101
+ console.log('[voip-picker-audio] video!', this.elements.videoDevice.value);
986
1102
  constraints.video = {
987
1103
  deviceId: { ideal: this.elements.videoDevice.value },
988
1104
  height: 256,
@@ -1023,7 +1139,7 @@ elation.elements.define('janus-voip-picker-audio', class extends elation.element
1023
1139
  this.elements.error.hide();
1024
1140
  this.updateButton();
1025
1141
  }).catch(err => {
1026
- console.log('OH NO!', err);
1142
+ console.log('[voip-picker-audio] OH NO!', err);
1027
1143
  this.elements.error.innerHTML = err;
1028
1144
  this.elements.error.show();
1029
1145
  });
@@ -1212,7 +1328,7 @@ elation.elements.define('janus-voip-picker-videotest', class extends elation.ele
1212
1328
  }
1213
1329
  video.srcObject = stream;
1214
1330
  video.muted = true;
1215
- video.play().then(() => console.log('playing', video));
1331
+ video.play().then(() => console.log('[voip-picker-videotest] playing', video));
1216
1332
  } else if (video && video.parentNode) {
1217
1333
  video.parentNode.removeChild(video);
1218
1334
  }
@@ -164,3 +164,8 @@ janus-ui-editor-property-vector3.selected[constraint="none"] ui-input input {
164
164
  janus-ui-editor-source .CodeMirror {
165
165
  max-width: 80em;
166
166
  }
167
+ janus-ui-editor-source ui-button[name="refresh"] {
168
+ position: absolute;
169
+ top: 0;
170
+ right: 0;
171
+ }
@@ -656,6 +656,7 @@ console.log('set translation snap', ev.data, ev);
656
656
  }
657
657
  editObjectUpdate() {
658
658
  var obj = this.roomedit.object;
659
+ if (!obj) return;
659
660
  var bbox = this.roomedit.objectBoundingBox;
660
661
 
661
662
  var point = this.roomedit.objectPosition || this.roomedit.object.position;
@@ -1627,6 +1628,11 @@ elation.elements.define('janus.ui.editor.source', class extends elation.elements
1627
1628
  //let roomtab = elation.elements.create('ui-tab', { append: this.tabs, label: 'Room Markup' });
1628
1629
  let roomedit = elation.elements.create('janus-ui-editor-source-file', { append: this.tabs, label: 'Room Markup', source: room.getRoomSource(), hints: this.jmlhints });
1629
1630
 
1631
+ let refreshbutton = elation.elements.create('ui-button', { append: this, label: '↻', title: "Refresh room source", name: "refresh" });
1632
+ refreshbutton.addEventListener('click', ev => {
1633
+ roomedit.source = room.getRoomSource();
1634
+ });
1635
+
1630
1636
  if (room.roomassets.script) {
1631
1637
  for (let k in room.roomassets.script) {
1632
1638
  let scriptasset = room.roomassets.script[k];
@@ -1880,7 +1886,7 @@ elation.elements.define('janus.ui.editor.source.file', class extends elation.ele
1880
1886
  init() {
1881
1887
  super.init();
1882
1888
  this.defineAttributes({
1883
- source: { type: 'string' },
1889
+ source: { type: 'string', set: this.updateSource },
1884
1890
  filename: { type: 'string', default: 'New File' },
1885
1891
  mode: { type: 'string', default: 'xml' },
1886
1892
  hints: { type: 'object' },
@@ -1984,6 +1990,11 @@ console.log('editor hints', this.hints);
1984
1990
  this.updatetimer = false;
1985
1991
  }, 500);
1986
1992
  }
1993
+ updateSource() {
1994
+ if (this.source != this.codemirror.getValue()) {
1995
+ this.codemirror.setValue(this.source);
1996
+ }
1997
+ }
1987
1998
  });
1988
1999
 
1989
2000
  class ColorTransform extends THREE.Object3D {
@@ -18,7 +18,7 @@ janus.registerElement('locomotion_teleporter', {
18
18
  shadow: false,
19
19
  shadow_cast: false,
20
20
  shadow_receive: false,
21
- renderorder: 51,
21
+ renderorder: 501,
22
22
  depth_test: false,
23
23
  depth_write: false,
24
24
  });
@@ -29,9 +29,10 @@ janus.registerElement('locomotion_teleporter', {
29
29
  collidable: false,
30
30
  pickable: false,
31
31
  shadow: false,
32
+ opacity: .1,
32
33
  shadow_cast: false,
33
34
  shadow_receive: false,
34
- renderorder: 50,
35
+ renderorder: 500,
35
36
  });
36
37
  this.pointer = this.marker.createObject('Object', {
37
38
  id: 'pyramid',
@@ -44,7 +45,7 @@ janus.registerElement('locomotion_teleporter', {
44
45
  shadow: false,
45
46
  shadow_cast: false,
46
47
  shadow_receive: false,
47
- renderorder: 52,
48
+ renderorder: 502,
48
49
  });
49
50
  /*
50
51
  this.light = this.createObject('Light', {
@@ -147,7 +147,7 @@ elation.elements.define('janus.username.picker', class extends elation.elements.
147
147
  create() {
148
148
  this.elements = elation.elements.fromString(`
149
149
  <form name="usernameform">
150
- <ui-input label="${this.label}" name="clientid"></ui-input>
150
+ <ui-input type="text" label="${this.label}" name="clientid"></ui-input>
151
151
  <input type="submit" name="submit" value="${this.confirm ? this.confirmlabel : this.buttonlabel}">
152
152
  </form>
153
153
  `, this);