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.
Files changed (84) hide show
  1. package/CHANGELOG +39 -0
  2. package/LICENSE +1 -1
  3. package/media/assets/janus-avatar-animations.glb +0 -0
  4. package/media/assets/janus-avatar-base.glb +0 -0
  5. package/media/assets/webui/apps/avatar/avatar.css +6 -2
  6. package/media/assets/webui/apps/avatar/avatar.js +99 -11
  7. package/media/assets/webui/apps/buttons/buttons.html +2 -2
  8. package/media/assets/webui/apps/buttons/buttons.js +3 -3
  9. package/media/assets/webui/apps/comms/comms.js +7 -4
  10. package/media/assets/webui/apps/comms/voip.js +133 -57
  11. package/media/assets/webui/apps/editor/codemirror/addon/hint/javascript-hint.js +162 -0
  12. package/media/assets/webui/apps/editor/codemirror/addon/hint/show-hint.css +36 -0
  13. package/media/assets/webui/apps/editor/codemirror/addon/hint/show-hint.js +529 -0
  14. package/media/assets/webui/apps/editor/codemirror/addon/hint/xml-hint.js +140 -0
  15. package/media/assets/webui/apps/editor/codemirror/keymap/vim.js +5734 -0
  16. package/media/assets/webui/apps/editor/codemirror/lib/codemirror.css +350 -0
  17. package/media/assets/webui/apps/editor/codemirror/lib/codemirror.js +9800 -0
  18. package/media/assets/webui/apps/editor/codemirror/lib/jmldark.css +33 -0
  19. package/media/assets/webui/apps/editor/codemirror/mode/css/css.js +864 -0
  20. package/media/assets/webui/apps/editor/codemirror/mode/htmlmixed/htmlmixed.js +153 -0
  21. package/media/assets/webui/apps/editor/codemirror/mode/javascript/javascript.js +942 -0
  22. package/media/assets/webui/apps/editor/codemirror/mode/xml/xml.js +413 -0
  23. package/media/assets/webui/apps/editor/editor.css +3 -0
  24. package/media/assets/webui/apps/editor/editor.js +409 -9
  25. package/media/assets/webui/apps/editor/editor.json +6 -3
  26. package/media/assets/webui/apps/inventory/inventory.html +7 -4
  27. package/media/assets/webui/apps/inventory/inventory.js +2 -2
  28. package/media/assets/webui/apps/locomotion/teleporter.js +10 -9
  29. package/media/assets/webui/apps/navigation/navigation.js +12 -12
  30. package/media/assets/webui/apps/settings/settings.html +1 -1
  31. package/media/assets/webui/apps/vfs/browserfs/browserfs.js +8 -0
  32. package/media/assets/webui/apps/vfs/vfs.css +52 -0
  33. package/media/assets/webui/apps/vfs/vfs.js +452 -0
  34. package/media/assets/webui/apps/vfs/vfs.json +10 -0
  35. package/media/assets/webui/apps/virtualgamepad/virtualgamepad.js +9 -7
  36. package/media/assets/webui/apps/xrmenu/xrmenu.js +13 -4
  37. package/media/assets/webui/default.json +2 -1
  38. package/media/assets/webui/none.json +1 -0
  39. package/media/assets/webui/themes/default.css +29 -2
  40. package/media/assets.json +2 -1
  41. package/media/index.html +1 -1
  42. package/media/lib/draco/README.md +32 -0
  43. package/media/lib/draco/draco_decoder.js +52 -0
  44. package/media/lib/draco/draco_decoder.wasm +0 -0
  45. package/media/lib/draco/draco_encoder.js +33 -0
  46. package/media/lib/draco/draco_wasm_wrapper.js +104 -0
  47. package/media/lib/draco/gltf/draco_decoder.js +48 -0
  48. package/media/lib/draco/gltf/draco_decoder.wasm +0 -0
  49. package/media/lib/draco/gltf/draco_encoder.js +33 -0
  50. package/media/lib/draco/gltf/draco_wasm_wrapper.js +104 -0
  51. package/media/lib/physx/physx.release.js +21 -0
  52. package/media/lib/physx/physx.release.wasm +0 -0
  53. package/media/manifest.json +5 -5
  54. package/media/service-worker.js +7 -0
  55. package/package.json +2 -9
  56. package/scripts/client.js +67 -46
  57. package/scripts/config.js +2 -0
  58. package/scripts/elements/linesegments.js +10 -3
  59. package/scripts/external/JanusFireboxParser.js +1 -0
  60. package/scripts/image.js +7 -1
  61. package/scripts/janusbase.js +104 -43
  62. package/scripts/janusghost.js +314 -16
  63. package/scripts/januslight.js +11 -2
  64. package/scripts/janusparagraph.js +8 -6
  65. package/scripts/janusparticle.js +26 -16
  66. package/scripts/janusplayer.js +126 -37
  67. package/scripts/janusweb.js +26 -2
  68. package/scripts/janusxrplayer.js +5 -3
  69. package/scripts/multiplayermanager.js +6 -4
  70. package/scripts/object.js +246 -88
  71. package/scripts/portal.js +23 -14
  72. package/scripts/remoteplayer.js +1 -25
  73. package/scripts/room.js +199 -77
  74. package/scripts/sound.js +8 -6
  75. package/scripts/text.js +13 -5
  76. package/scripts/translators/janusvfs.js +20 -0
  77. package/scripts/video.js +1 -1
  78. package/scripts/websurface.js +17 -3
  79. package/utils/build.sh +3 -0
  80. package/utils/init.sh +2 -2
  81. package/scripts/chat.js +0 -80
  82. package/scripts/ui.js +0 -265
  83. package/scripts/urlbar.js +0 -93
  84. package/templates/janusweb.tpl +0 -3
@@ -0,0 +1,52 @@
1
+ janus-ui-vfs-browser ui-flexpanel>ui-treeview {
2
+ flex: 0;
3
+ border-right: 1px solid #333;
4
+ margin-right: 1em;
5
+ padding-right: 1em;
6
+ }
7
+ janus-ui-vfs-browser-directorylist {
8
+ display: grid;
9
+ grid-template-columns: repeat(auto-fit, 90px);
10
+ width: 40em;
11
+ height: 15em;
12
+ overflow: auto;
13
+ outline: 0;
14
+ }
15
+ janus-ui-vfs-browser-directorylist.dragactive {
16
+ border: 2px solid lime;
17
+ border-radius: 10px;
18
+ background: rgba(0,255,0,.2);
19
+ margin: -2px;
20
+ }
21
+ janus-ui-vfs-browser-file.dragactive {
22
+ border: 2px solid lime;
23
+ background: rgba(0,255,0,.2);
24
+ }
25
+ janus-ui-vfs-browser-file {
26
+ width: 80px;
27
+ height: 80px;
28
+ border: 1px solid black;
29
+ border-radius: 10px;
30
+ margin: 5px;
31
+ display: flex;
32
+ text-align: center;
33
+ align-items: flex-end;
34
+ justify-content: center;
35
+ cursor: pointer;
36
+ background: rgba(0,0,0,.2);
37
+ }
38
+ janus-ui-vfs-browser-file[selected] {
39
+ background: rgba(255,255,255,.2);
40
+ }
41
+ janus-ui-vfs-browser-file:hover {
42
+ background: rgba(0,255,0,.2);
43
+ }
44
+ janus-ui-vfs-browser-file[selected]:hover {
45
+ background: rgba(255,255,255,.4);
46
+ }
47
+ janus-ui-vfs-browser-file ui-label {
48
+ width: 100%;
49
+ overflow: hidden;
50
+ text-overflow: ellipsis;
51
+ pointer-events: none;
52
+ }
@@ -0,0 +1,452 @@
1
+ elation.extend('engine.assetloader.agent.janus-vfs', new function() {
2
+ this.initBrowserFS = function() {
3
+ return new Promise((accept, reject) => {
4
+ BrowserFS.configure({
5
+ fs: "MountableFileSystem",
6
+ options: {
7
+ //'/': { fs: "LocalStorage" },
8
+ //'/blurp': { fs: "IndexedDB", options: { storeName: 'janusVFS' } },
9
+ '/': { fs: "IndexedDB", options: { storeName: 'janusVFS' } },
10
+ //'/mnt/usb0': { fs: "LocalStorage" }
11
+ }
12
+ }, (e) => {
13
+ if (e) {
14
+ } else {
15
+ var fs = BrowserFS.BFSRequire('fs');
16
+ this.fs = fs;
17
+ accept(this.fs);
18
+ }
19
+ });
20
+ });
21
+ }
22
+
23
+ this.getFS = async function() {
24
+ if (!this.fs) {
25
+ await this.initBrowserFS();
26
+ }
27
+ return this.fs;
28
+ }
29
+
30
+ this.fetch = async function(url) {
31
+ let fs = await this.getFS();
32
+
33
+ let pathparts = url.split('://');
34
+ return new Promise((resolve, reject) => {
35
+ let filepath = pathparts[1];
36
+ fs.readFile(filepath, ( e, file) => {
37
+ if (file) {
38
+ resolve({
39
+ target: {
40
+ responseURL: url,
41
+ data: file.buffer,
42
+ response: file.buffer,
43
+ getResponseHeader(header) {
44
+ if (header.toLowerCase() == 'content-type') {
45
+ // FIXME - We should implement mime type detection at a lower level, and avoid the need to access the XHR object in calling code
46
+ return 'application/octet-stream';
47
+ }
48
+ }
49
+ },
50
+ });
51
+ } else {
52
+ reject();
53
+ }
54
+ });
55
+ });
56
+ }
57
+ });
58
+
59
+ elation.elements.define('janus.ui.vfs.browser', class extends elation.elements.base {
60
+ init() {
61
+ super.init();
62
+ this.defineAttributes({
63
+ cwd: { type: 'string', default: '/' },
64
+ chroot: { type: 'string', default: '' },
65
+ });
66
+ }
67
+ create() {
68
+ super.create();
69
+
70
+ /*
71
+ this.win = elation.elements.create('ui-window', {
72
+ append: document.body,
73
+ center: true,
74
+ windowtitle: '/',
75
+ });
76
+ */
77
+ this.content = elation.elements.create('ui-rowlayout', {
78
+ append: this,
79
+ });
80
+ this.controls = elation.elements.create('ui-content', {
81
+ append: this.content,
82
+ });
83
+ this.updirbutton = elation.elements.create('ui-button', {
84
+ append: this.controls,
85
+ label: '⬅',
86
+ onclick: ev => this.handleUpDirectoryClick(ev),
87
+ });
88
+ this.deletebutton = elation.elements.create('ui-button', {
89
+ append: this.controls,
90
+ label: '🗑️',
91
+ onclick: ev => this.handleDeleteClick(ev),
92
+ });
93
+ this.addbuttonlist = elation.elements.create('ui-list', {
94
+ selectable: true,
95
+ items: ['Upload', 'Directory', 'HTML', 'JS'],
96
+ onselectionchange: ev => this.handleAddButtonSelect(ev),
97
+ });
98
+ this.addbutton = elation.elements.create('ui-popupbutton', {
99
+ append: this.controls,
100
+ label: '➕',
101
+ popupcontent: this.addbuttonlist,
102
+ });
103
+ this.mainpanel = elation.elements.create('ui-flexpanel', {
104
+ append: this.content,
105
+ });
106
+
107
+ this.dirtree = elation.elements.create('ui-treeview', {
108
+ append: this.mainpanel,
109
+ attrs: {
110
+ name: 'path',
111
+ label: 'name',
112
+ },
113
+ });
114
+ elation.events.add(this.dirtree, 'ui_treeview_select', ev => this.handleDirectoryTreeSelect(ev));
115
+
116
+ this.dirlist = elation.elements.create('janus-ui-vfs-browser-directorylist', {
117
+ append: this.mainpanel,
118
+ itemcomponent: 'janus-ui-vfs-browser-file',
119
+ selectable: true,
120
+ multiselect: true,
121
+ draggable: true,
122
+ });
123
+ elation.events.add(this.dirlist, 'directorychange', ev => this.handleDirectoryChange(ev));
124
+ elation.events.add(this.dirlist, 'selectionchange', ev => this.handleFilesSelectionChange(ev));
125
+
126
+ elation.events.add(this.dirlist, 'dragstart', ev => this.handleDragStart(ev));
127
+ elation.events.add(this.dirlist, 'dragover', ev => this.handleDragOver(ev));
128
+ elation.events.add(this.dirlist, 'dragenter', ev => this.handleDragEnter(ev));
129
+ elation.events.add(this.dirlist, 'dragleave', ev => this.handleDragLeave(ev));
130
+ elation.events.add(this.dirlist, 'drop', ev => this.handleDrop(ev));
131
+
132
+ elation.events.add(this.dirlist, 'keypress', ev => this.handleFilesKeypress(ev));
133
+
134
+ //this.win.setcontent(this);
135
+ this.updateDirectories();
136
+ this.updateFiles();
137
+ }
138
+ async updateFiles() {
139
+ let fs = await elation.engine.assetloader.agent['janus-vfs'].getFS();
140
+
141
+ fs.readdir(this.chroot + this.cwd, (e, contents) => {
142
+ let entries = {};
143
+ let promises = [];
144
+ for (let i = 0; i < contents.length; i++) {
145
+ promises.push(new Promise(accept => {
146
+ fs.stat(this.chroot + this.cwd + contents[i], (e, stats) => {
147
+ entries[contents[i]] = {
148
+ name: contents[i],
149
+ path: this.cwd,
150
+ stats: stats,
151
+ };
152
+ accept(stats);
153
+ });
154
+ }));
155
+ }
156
+ Promise.all(promises).then(() => {
157
+ this.dirlist.clear();
158
+ this.dirlist.setItems(entries);
159
+ });
160
+ });
161
+ this.updirbutton.disabled = (this.cwd == '/');
162
+ this.deletebutton.disabled = (this.dirlist.selection.length == 0);
163
+ //this.win.settitle(this.cwd);
164
+ }
165
+ async updateDirectories() {
166
+ let dirtree = {
167
+ '/': {
168
+ name: '/',
169
+ path: '/',
170
+ items: await this.getDirectoryTree(),
171
+ }
172
+ };
173
+ this.dirtree.setItems(dirtree);
174
+ let selected = this.dirtree.find(this.cwd);
175
+ if (selected) {
176
+ selected.select();
177
+ }
178
+
179
+ console.log('my full dirtree', dirtree, this.dirtree, selected);
180
+ }
181
+ async getDirectoryTree(dir='/', entries) {
182
+ if (!entries) entries = {};
183
+ let fs = await elation.engine.assetloader.agent['janus-vfs'].getFS();
184
+ return new Promise(async (resolve, reject) => {
185
+ fs.readdir(this.chroot + dir, async (e, contents) => {
186
+ let promises = [];
187
+ for (let i = 0; i < contents.length; i++) {
188
+ promises.push(new Promise(accept => {
189
+ let stats = fs.stat(this.chroot + dir + contents[i], async (e, stats) => {
190
+ if (stats.isDirectory()) {
191
+ entries[contents[i]] = {
192
+ name: contents[i],
193
+ path: dir + contents[i] + '/',
194
+ stats: stats,
195
+ };
196
+ let children = await this.getDirectoryTree(dir + contents[i] + '/');
197
+ entries[contents[i]].items = (Object.keys(children).length > 0 ? children : false);
198
+ }
199
+ accept();
200
+ });
201
+ }));
202
+ }
203
+ await Promise.all(promises);
204
+ resolve(entries);
205
+ });
206
+ });
207
+ }
208
+ chdir(dir) {
209
+ this.cwd = dir + (dir.lastIndexOf('/') != dir.length - 1 ? '/' : '');
210
+ this.dirlist.selectall(false);
211
+
212
+ let selected = this.dirtree.find(this.cwd);
213
+ if (selected && selected !== this.dirtree.selected) {
214
+ selected.select();
215
+ } else {
216
+ this.updateFiles();
217
+ }
218
+ }
219
+ updir() {
220
+ let pathparts = this.cwd.split('/');
221
+ pathparts.pop();
222
+ pathparts.pop();
223
+ let newpath = (pathparts.length > 0 ? pathparts.join('/') + '/' : '/');
224
+ //newpath = newpath.replaceAll('//', '/');
225
+ this.chdir(newpath);
226
+ }
227
+ async mkdir(dir) {
228
+ let fs = await elation.engine.assetloader.agent['janus-vfs'].getFS();
229
+ let fulldir = this.chroot + (dir[0] == '/' ? dir : this.cwd + dir);
230
+ await fs.mkdir(fulldir);
231
+ this.updateDirectories();
232
+ this.updateFiles();
233
+ }
234
+ async rm(files) {
235
+ let fs = await elation.engine.assetloader.agent['janus-vfs'].getFS();
236
+ if (!elation.utils.isArray(files)) files = [files];
237
+ console.log('delete files', files);
238
+ let promises = [];
239
+ files.forEach(file => {
240
+ promises.push(new Promise((resolve, reject) => {
241
+ fs.unlink(this.chroot + this.cwd + file, e => {
242
+ if (!e) {
243
+ resolve();
244
+ } else {
245
+ reject();
246
+ }
247
+ });
248
+ }));
249
+ });
250
+ await Promise.all(promises);
251
+ this.updateFiles();
252
+ }
253
+ async rmdir(dirs) {
254
+ let fs = await elation.engine.assetloader.agent['janus-vfs'].getFS();
255
+ if (!elation.utils.isArray(dirs)) dirs = [dirs];
256
+ console.log('delete dirs', dirs);
257
+ let promises = [];
258
+ dirs.forEach(dir => {
259
+ promises.push(new Promise((resolve, reject) => {
260
+ fs.rmdir(this.chroot + this.cwd + dir, e => {
261
+ if (!e) {
262
+ resolve();
263
+ } else {
264
+ reject();
265
+ }
266
+ });
267
+ }));
268
+ });
269
+ await Promise.all(promises);
270
+ this.updateDirectories();
271
+ this.updateFiles();
272
+ }
273
+ showUploadPrompt() {
274
+ let input = document.createElement('input');
275
+ input.type = 'file';
276
+ input.multiple = true;
277
+ input.style.width = 0;
278
+ input.style.height = 0;
279
+ input.style.overflow = 'hidden';
280
+ input.addEventListener('change', ev => this.handleFileUpload(ev));
281
+ this.appendChild(input);
282
+ input.click();
283
+ }
284
+ handleDirectoryTreeSelect(ev) {
285
+ let newpath = ev.data.item.path;
286
+ this.chdir(newpath);
287
+ }
288
+ handleDirectoryChange(ev) {
289
+ let newdir = ev.target;
290
+ let newpath = newdir.path + newdir.name;
291
+ this.chdir(newpath);
292
+ }
293
+ handleUpDirectoryClick(ev) {
294
+ if (!ev.target.disabled) {
295
+ this.updir();
296
+ }
297
+ }
298
+ handleDeleteClick(ev) {
299
+ if (this.dirlist.selection.length > 0) {
300
+ console.log('delete', this.dirlist.selection);
301
+ let files = this.dirlist.selection.filter(n => !n.stats.isDirectory()).map(n => n.name),
302
+ dirs = this.dirlist.selection.filter(n => n.stats.isDirectory()).map(n => n.name);
303
+ if (files.length > 0) this.rm(files);
304
+ if (dirs.length > 0) this.rmdir(dirs);
305
+ this.dirlist.selectall(false);
306
+ }
307
+ }
308
+ handleAddButtonSelect(ev) {
309
+ let selected = this.addbuttonlist.selection[0];
310
+ if (selected) {
311
+ this.addbuttonlist.selectall(false);
312
+ this.addbutton.hidePopup();
313
+
314
+ switch(selected.value) {
315
+ case 'Upload':
316
+ this.showUploadPrompt();
317
+ break;
318
+ case 'Directory':
319
+ let dirname = prompt('Directory name?'); // FIXME - make this an HTML pop-up prompt
320
+ if (dirname !== null) {
321
+ this.mkdir(dirname);
322
+ }
323
+ }
324
+ }
325
+ }
326
+ handleFilesSelectionChange(ev) {
327
+ this.deletebutton.disabled = (this.dirlist.selection.length == 0);
328
+ }
329
+ handleFilesKeypress(ev) {
330
+ if (ev.keyCode == 127) {
331
+ this.handleDeleteClick(ev);
332
+ }
333
+ }
334
+ async handleFileUpload(ev) {
335
+ let files = ev.target.files;
336
+ console.log('upload some files', ev, files);
337
+ if (files && files.length > 0) {
338
+ let filenames = await this.saveFiles(files);
339
+ console.log('finished writing files', filenames);
340
+ }
341
+ }
342
+ handleDragStart(ev) {
343
+ let urilist = '';
344
+ this.dirlist.selection.forEach(f => {
345
+ urilist += 'janus-vfs://' + this.chroot + this.cwd + f.name + '\r\n';
346
+ });
347
+ ev.dataTransfer.setData('text/uri-list', urilist);
348
+ console.log('drag it!', urilist, ev, this.dirlist.selection);
349
+ }
350
+ handleDragOver(ev) {
351
+ ev.dataTransfer.dropEffect = "copy"
352
+ ev.preventDefault();
353
+ }
354
+ handleDragEnter(ev) {
355
+ let dragtarget = this.getDragTarget(ev);
356
+ if (dragtarget && !dragtarget.hasclass('dragactive')) {
357
+ dragtarget.addclass('dragactive');
358
+ }
359
+ }
360
+ handleDragLeave(ev) {
361
+ //let dragtarget = this.getDragTarget(ev);
362
+ let dragtarget = ev.target;
363
+ if (dragtarget && elation.html.hasclass(dragtarget, 'dragactive')) elation.html.removeclass(dragtarget, 'dragactive');
364
+ if (this.dirlist.hasclass('dragactive') && !this.dirlist.contains(dragtarget)) this.dirlist.removeclass('dragactive');
365
+ }
366
+ async handleDrop(ev) {
367
+ ev.preventDefault();
368
+ let dragtarget = this.getDragTarget(ev);
369
+ if (dragtarget) dragtarget.removeclass('dragactive');
370
+ let files = ev.dataTransfer.files;
371
+ let subdir = (dragtarget instanceof elation.elements.janus.ui.vfs.browser.file && dragtarget.stats.isDirectory() ? dragtarget.name : '');
372
+ console.log('upload some files', ev, files);
373
+ if (files && files.length > 0) {
374
+ let filenames = await this.saveFiles(files, subdir);
375
+ console.log('finished writing files', filenames);
376
+ }
377
+ }
378
+ getDragTarget(ev) {
379
+ let dragtarget = ev.target;
380
+
381
+ while (dragtarget !== this.dirlist && !(dragtarget instanceof elation.elements.janus.ui.vfs.browser.file && dragtarget.stats.isDirectory())) {
382
+ dragtarget = dragtarget.parentNode;
383
+ }
384
+ console.log('my dragtarget!', dragtarget);
385
+ return dragtarget;
386
+ }
387
+ async saveFiles(files, subdir) {
388
+ let fs = await elation.engine.assetloader.agent['janus-vfs'].getFS();
389
+
390
+ let Buffer = BrowserFS.BFSRequire('buffer').Buffer;
391
+ let promises = [];
392
+ for (let i = 0; i < files.length; i++) {
393
+ let file = files[i];
394
+ let fname = this.chroot + this.cwd + (subdir ? subdir + '/' : '') + file.name;
395
+ console.log('Got file!', file.name, file.size, fname);
396
+ promises.push(new Promise((accept, reject) => {
397
+ let reader = new FileReader();
398
+ reader.onload = function() {
399
+ let buffer = Buffer.from(this.result);
400
+ fs.writeFile(fname, buffer, (e, f) => {
401
+ accept(fname);
402
+ });
403
+ }
404
+ reader.readAsArrayBuffer(file);
405
+ }));
406
+ }
407
+ Promise.all(promises).then((filenames) => {
408
+ this.updateFiles();
409
+ return filenames;
410
+ });
411
+ }
412
+ });
413
+ elation.elements.define('janus.ui.vfs.browser.directorytree', class extends elation.elements.ui.treeview {
414
+ create() {
415
+ super.create();
416
+ }
417
+ });
418
+ elation.elements.define('janus.ui.vfs.browser.directorylist', class extends elation.elements.ui.list {
419
+ create() {
420
+ super.create();
421
+ }
422
+ });
423
+ elation.elements.define('janus.ui.vfs.browser.directory', class extends elation.elements.ui.item {
424
+ create() {
425
+ }
426
+ });
427
+ elation.elements.define('janus.ui.vfs.browser.file', class extends elation.elements.ui.item {
428
+ create() {
429
+ super.create();
430
+
431
+ this.name = this.value.name;
432
+ this.path = this.value.path;
433
+ this.stats = this.value.stats;
434
+
435
+ this.title = this.name;
436
+
437
+ elation.elements.create('ui-label', {
438
+ append: this,
439
+ label: this.name + (this.stats.isDirectory() ? '/' : ''),
440
+ });
441
+
442
+ this.addEventListener('dblclick', ev => this.handleDblClick(ev));
443
+ }
444
+ handleDblClick(ev) {
445
+ if (this.stats.isDirectory()) {
446
+ this.dispatchEvent({type: 'directorychange', bubbles: true});
447
+ } else {
448
+ console.log('do something with this thing!', this);
449
+ }
450
+ ev.preventDefault();
451
+ }
452
+ });
@@ -0,0 +1,10 @@
1
+ {
2
+ "templates": {
3
+ },
4
+ "scripts": ["./vfs.js", "./browserfs/browserfs.js"],
5
+ "css": ["./vfs.css"],
6
+ "components": [
7
+ "janus-ui-vfs-browser"
8
+ ]
9
+ }
10
+
@@ -97,13 +97,15 @@ this.debug.style.zIndex = '1000';
97
97
  }
98
98
 
99
99
  let janus = elation.component.fetch(this.queryParentSelector('[data-elation-component="janusweb.client"]'))
100
- janus.engine.systems.controls.addVirtualGamepad(this);
101
- this.hide();
102
- janus.engine.systems.render.renderer.domElement.addEventListener('touchstart', (ev) => {
103
- this.show();
104
- this.reset();
105
- if (!player.enabled) player.enable();
106
- });
100
+ if (janus) {
101
+ janus.engine.systems.controls.addVirtualGamepad(this);
102
+ this.hide();
103
+ janus.engine.systems.render.renderer.domElement.addEventListener('touchstart', (ev) => {
104
+ this.show();
105
+ this.reset();
106
+ if (!player.enabled) player.enable();
107
+ });
108
+ }
107
109
  }
108
110
  reset() {
109
111
  for (let i = 0; i < this.axes.length; i++) {
@@ -14,6 +14,10 @@ janus.registerElement('xrmenu', {
14
14
  });
15
15
  */
16
16
 
17
+ this.worldpos = V();
18
+ this.worlddir = V();
19
+ this.playervec = V();
20
+
17
21
  let xrmenu = janus.ui.apps.default.apps.xrmenu;
18
22
  let asseturl = xrmenu.resolveFullURL('./xrmenu-assets.json');
19
23
  fetch(asseturl).then(res => res.json()).then(assetlist => {
@@ -66,10 +70,11 @@ janus.registerElement('xrmenu', {
66
70
  button.pos.x = (-width / 2) + (this.buttonwidth * this.buttonmargin * (i + .5)) ;
67
71
  }
68
72
  },
73
+ /*
69
74
  update() {
70
- let worldpos = this.localToWorld(V());
71
- let worlddir = this.localToWorld(V(0, 0, 1)).sub(worldpos).normalize();
72
- let playervec = player.head.localToWorld(V()).sub(worldpos).normalize();
75
+ let worldpos = this.localToWorld(this.worldpos.set(0,0,0));
76
+ let worlddir = this.localToWorld(this.worlddir.set(0,0,1)).sub(worldpos).normalize();
77
+ let playervec = player.head.localToWorld(this.playervec.set(0,0,0)).sub(worldpos).normalize();
73
78
  let dot = playervec.dot(worlddir);
74
79
  let opacity = Math.max(0, dot);
75
80
  for (let k in this.buttons) {
@@ -79,6 +84,7 @@ janus.registerElement('xrmenu', {
79
84
  }
80
85
  //this.backing.opacity = opacity;
81
86
  },
87
+ */
82
88
  });
83
89
  janus.registerElement('xrmenu-button', {
84
90
  onactivate: null,
@@ -122,6 +128,8 @@ janus.registerElement('xrmenu-popup', {
122
128
  element: null,
123
129
  width: 512,
124
130
  height: 512,
131
+ depth_test: true,
132
+ renderorder: 0,
125
133
 
126
134
  create() {
127
135
 
@@ -160,7 +168,6 @@ container.style.opacity = 0;
160
168
  this.elementcontainer = container;
161
169
 
162
170
  setTimeout(() => {
163
- console.log('my element', element);
164
171
  let canvas = element.toCanvas(this.width, this.height, 1);
165
172
  /*
166
173
  document.body.appendChild(canvas);
@@ -186,6 +193,8 @@ canvas.style.border = '1px solid red';
186
193
  lighting: false,
187
194
  //image_id: 'xrmenu-element-canvas',
188
195
  scale: V(1, this.height / this.width, 1),
196
+ depth_test: this.depth_test,
197
+ renderorder: this.renderorder,
189
198
  });
190
199
  this.element = element;
191
200
  this.plane.addEventListener('mousemove', ev => this.handleMouse(ev));
@@ -10,7 +10,8 @@
10
10
  "locomotion": "./apps/locomotion/locomotion.json",
11
11
  "virtualgamepad": "./apps/virtualgamepad/virtualgamepad.json",
12
12
  "buttons": "./apps/buttons/buttons.json",
13
- "xrmenu": "./apps/xrmenu/xrmenu.json"
13
+ "xrmenu": "./apps/xrmenu/xrmenu.json",
14
+ "vfs": "./apps/vfs/vfs.json"
14
15
  },
15
16
  "includes": [
16
17
  ],
@@ -0,0 +1 @@
1
+ {}