-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSpatialstrates.jsx
More file actions
96 lines (80 loc) · 3.66 KB
/
Spatialstrates.jsx
File metadata and controls
96 lines (80 loc) · 3.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import React from 'react';
const { useMemo, useEffect, useRef } = React;
import { Varv, useProperty } from '#VarvReact';
import { DynamicComponents, useDynamicModules } from '#Spatialstrates .dynamic-components';
import { GlobalEventProvider } from '#Spatialstrates .global-events';
import { SceneView } from '#Spatialstrates .scene-view';
import { CanvasView } from '#Spatialstrates .canvas-view';
function SpaceView() {
const [currentView] = useProperty('currentView');
const [currentSpace, setCurrentSpace] = useProperty('locationHash');
const [, setXRPlatform] = useProperty('xrPlatform');
// Detect XR platform type
const initXRPlatformTimeout = useRef(null);
useEffect(() => {
if (initXRPlatformTimeout.current) {
clearTimeout(initXRPlatformTimeout.current);
initXRPlatformTimeout.current = null;
}
if (typeof setXRPlatform === 'function') {
initXRPlatformTimeout.current = setTimeout(async () => {
const supportsImmersiveAR = navigator.xr && await navigator.xr.isSessionSupported('immersive-ar');
const supportsImmersiveVR = navigator.xr && await navigator.xr.isSessionSupported('immersive-vr');
const isAndroid = navigator.userAgent.includes('Android')
const isOculusBrowser = navigator.userAgent.includes('OculusBrowser');
const supportsModelElement = typeof window.HTMLModelElement !== 'undefined';
if (supportsModelElement && supportsImmersiveVR) {
setXRPlatform('Vision Pro');
} else if (isOculusBrowser && supportsImmersiveVR) {
setXRPlatform('Quest');
} else if (isAndroid && supportsImmersiveAR) {
setXRPlatform('Android Mobile');
} else {
setXRPlatform('None');
}
initXRPlatformTimeout.current = null;
}, 1000);
}
}, [setXRPlatform]);
// Initialize the current space if it is not set
const initSpaceTimeout = useRef(null);
useEffect(() => {
if (initSpaceTimeout.current) {
clearTimeout(initSpaceTimeout.current);
initSpaceTimeout.current = null;
}
if (!currentSpace) {
initSpaceTimeout.current = setTimeout(async () => {
const spaceUUIDs = await VarvEngine.getAllUUIDsFromType('Space');
if (spaceUUIDs.length > 0) {
setCurrentSpace(spaceUUIDs[0]);
} else {
setCurrentSpace(await VarvEngine.getConceptFromType('Space').create(null, { name: 'New Space' }));
}
initSpaceTimeout.current = null;
}, 1000);
}
}, [currentSpace, setCurrentSpace]);
// Load shape utils and movables here to cache them between switching views
const shapeUtils = useDynamicModules('.dynamic-shape-component');
const movableSceneComponents = useDynamicModules('.dynamic-movable-scene-component');
const view = useMemo(() => {
switch (currentView) {
case '3D':
return <SceneView movableSceneComponents={movableSceneComponents} />;
case '2D':
return <CanvasView shapeUtils={shapeUtils} />;
default:
return null;
}
}, [currentView, shapeUtils, movableSceneComponents]);
return currentSpace ? view : null;
}
export function App() {
return <GlobalEventProvider>
<Varv concept="SpaceManager">
<DynamicComponents selector=".dynamic-gui-component" />
<SpaceView />
</Varv>
</GlobalEventProvider>;
}