Skip to content

Commit 2c74eac

Browse files
committed
Merge branch 'room-ui-redesign' into redesign/remaining-l10-tasks
2 parents 09e85d2 + dca9d1a commit 2c74eac

File tree

8 files changed

+148
-63
lines changed

8 files changed

+148
-63
lines changed

src/components/set-max-resolution.js

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/hub.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@
7878
personal-space-bubble="debug: false;"
7979
rotate-selected-object
8080
environment-map
81-
set-max-resolution
8281
light="defaultLightsEnabled: false"
8382
>
8483
<a-assets>

src/hub.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ import "./components/inspect-button";
115115
import "./components/inspect-pivot-child-selector";
116116
import "./components/inspect-pivot-offset-from-camera";
117117
import "./components/optional-alternative-to-not-hide";
118-
import "./components/set-max-resolution";
119118
import "./components/avatar-audio-source";
120119
import "./components/avatar-inspect-collider";
121120

src/react-components/layout/RoomLayout.js

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
import React, { useRef, useEffect } from "react";
1+
import React from "react";
22
import PropTypes from "prop-types";
33
import classNames from "classnames";
44
import styles from "./RoomLayout.scss";
5-
// ResizeObserver not currently supported in Firefox Android
6-
import ResizeObserver from "resize-observer-polyfill";
75
import { Toolbar } from "./Toolbar";
86

97
export function RoomLayout({
@@ -19,31 +17,9 @@ export function RoomLayout({
1917
viewport,
2018
objectFocused,
2119
streaming,
22-
onResizeViewport,
20+
viewportRef,
2321
...rest
2422
}) {
25-
const viewportRef = useRef();
26-
27-
useEffect(
28-
() => {
29-
let observer = null;
30-
31-
if (onResizeViewport) {
32-
observer = new ResizeObserver(entries => {
33-
onResizeViewport(entries[0].contentRect);
34-
});
35-
observer.observe(viewportRef.current);
36-
}
37-
38-
return () => {
39-
if (observer) {
40-
observer.disconnect();
41-
}
42-
};
43-
},
44-
[onResizeViewport]
45-
);
46-
4723
return (
4824
<div className={classNames(styles.roomLayout, { [styles.objectFocused]: objectFocused }, className)} {...rest}>
4925
{sidebar && <div className={classNames(styles.sidebar, sidebarClassName)}>{sidebar}</div>}
@@ -79,5 +55,5 @@ RoomLayout.propTypes = {
7955
viewport: PropTypes.node,
8056
objectFocused: PropTypes.bool,
8157
streaming: PropTypes.bool,
82-
onResizeViewport: PropTypes.func
58+
viewportRef: PropTypes.any
8359
};

src/react-components/layout/RoomLayout.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,5 +93,5 @@
9393
}
9494

9595
:local(.streaming) {
96-
border: 3px solid theme.$red;
96+
box-shadow: inset 0 0 0 3px theme.$red;
9797
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React, { useRef } from "react";
2+
import PropTypes from "prop-types";
3+
import { RoomLayout } from "../layout/RoomLayout";
4+
import { useResizeViewport } from "./useResizeViewport";
5+
6+
export function RoomLayoutContainer({ store, scene, ...rest }) {
7+
const viewportRef = useRef();
8+
9+
useResizeViewport(viewportRef, store, scene);
10+
11+
return <RoomLayout viewportRef={viewportRef} {...rest} />;
12+
}
13+
14+
RoomLayoutContainer.propTypes = {
15+
store: PropTypes.object.isRequired,
16+
scene: PropTypes.object.isRequired
17+
};
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import { useState, useEffect } from "react";
2+
// ResizeObserver not currently supported in Firefox Android
3+
import ResizeObserver from "resize-observer-polyfill";
4+
5+
const DEFAULT_MAX_RESOLUTION = 1920;
6+
7+
// Modified from AFrame
8+
function getRenderResolution(canvasRect, maxResolution, isVR) {
9+
const pixelRatio = window.devicePixelRatio;
10+
11+
if (!maxResolution || isVR || (maxResolution.width === -1 && maxResolution.height === -1)) {
12+
return canvasRect;
13+
}
14+
15+
if (canvasRect.width * pixelRatio < maxResolution.width && canvasRect.height * pixelRatio < maxResolution.height) {
16+
return canvasRect;
17+
}
18+
19+
const aspectRatio = canvasRect.width / canvasRect.height;
20+
21+
if (canvasRect.width * pixelRatio > maxResolution.width && maxResolution.width !== -1) {
22+
return {
23+
width: Math.round(maxResolution.width / pixelRatio),
24+
height: Math.round(maxResolution.width / aspectRatio / pixelRatio)
25+
};
26+
}
27+
28+
if (canvasRect.height * pixelRatio > maxResolution.height && maxResolution.height !== -1) {
29+
return {
30+
width: Math.round(maxResolution.height / pixelRatio),
31+
height: Math.round((maxResolution.height * aspectRatio) / pixelRatio)
32+
};
33+
}
34+
35+
return canvasRect;
36+
}
37+
38+
export function useResizeViewport(viewportRef, store, scene) {
39+
const [maxResolution, setMaxResolution] = useState({
40+
width: DEFAULT_MAX_RESOLUTION,
41+
height: DEFAULT_MAX_RESOLUTION
42+
});
43+
44+
useEffect(
45+
() => {
46+
const oldResizeFunc = scene.resize;
47+
48+
// HACK: Override native AFRAME resize handler for our own.
49+
scene.resize = () => {};
50+
51+
return () => {
52+
scene.resize = oldResizeFunc;
53+
};
54+
},
55+
[scene]
56+
);
57+
58+
useEffect(
59+
() => {
60+
function onStoreChanged() {
61+
const { maxResolutionWidth, maxResolutionHeight } = store.state.preferences;
62+
63+
setMaxResolution({
64+
width: maxResolutionWidth === undefined ? DEFAULT_MAX_RESOLUTION : maxResolutionWidth,
65+
height: maxResolutionHeight === undefined ? DEFAULT_MAX_RESOLUTION : maxResolutionHeight
66+
});
67+
}
68+
69+
onStoreChanged();
70+
71+
store.addEventListener("statechanged", onStoreChanged);
72+
73+
return () => {
74+
store.removeEventListener("statechanged", onStoreChanged);
75+
};
76+
},
77+
[store]
78+
);
79+
80+
useEffect(
81+
() => {
82+
const observer = new ResizeObserver(entries => {
83+
const isPresenting = scene.renderer.vr.isPresenting();
84+
const isVRPresenting = scene.renderer.vr.enabled && isPresenting;
85+
86+
// Do not update renderer, if a camera or a canvas have not been injected.
87+
// In VR mode, three handles canvas resize based on the dimensions returned by
88+
// the getEyeParameters function of the WebVR API. These dimensions are independent of
89+
// the window size, therefore should not be overwritten with the window's width and
90+
// height, // except when in fullscreen mode.
91+
if (!scene.camera || !scene.canvas || (scene.is("vr-mode") && (scene.isMobile || isVRPresenting))) {
92+
return;
93+
}
94+
95+
const canvasRect = entries[0].contentRect;
96+
97+
const resolution = getRenderResolution(canvasRect, maxResolution, isVRPresenting);
98+
99+
const canvas = scene.canvas;
100+
canvas.style.width = canvasRect.width + "px";
101+
canvas.style.height = canvasRect.height + "px";
102+
103+
scene.renderer.setSize(resolution.width, resolution.height, false);
104+
105+
scene.camera.aspect = resolution.width / resolution.height;
106+
scene.camera.updateProjectionMatrix();
107+
108+
// Resizing the canvas clears it, so render immediately after resize to prevent flicker.
109+
scene.renderer.render(scene.object3D, scene.camera);
110+
});
111+
112+
observer.observe(viewportRef.current);
113+
114+
return () => {
115+
observer.disconnect();
116+
};
117+
},
118+
[viewportRef, scene, maxResolution]
119+
);
120+
}

src/react-components/ui-root.js

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import qsTruthy from "../utils/qs_truthy";
3939
import { LoadingScreenContainer } from "./room/LoadingScreenContainer";
4040

4141
import "./styles/global.scss";
42-
import { RoomLayout } from "./layout/RoomLayout";
42+
import { RoomLayoutContainer } from "./room/RoomLayoutContainer";
4343
import roomLayoutStyles from "./layout/RoomLayout.scss";
4444
import { useAccessibleOutlineStyle } from "./input/useAccessibleOutlineStyle";
4545
import { ToolbarButton } from "./input/ToolbarButton";
@@ -273,19 +273,6 @@ class UIRoot extends Component {
273273
}
274274
}
275275

276-
onResizeViewport = ({ width, height }) => {
277-
const sceneEl = this.props.scene;
278-
279-
sceneEl.renderer.setSize(width, height);
280-
281-
if (sceneEl.camera) {
282-
sceneEl.camera.aspect = width / height;
283-
sceneEl.camera.updateProjectionMatrix();
284-
// Resizing the canvas clears it, so render immediately after resize to prevent flicker.
285-
sceneEl.renderer.render(sceneEl.object3D, sceneEl.camera);
286-
}
287-
};
288-
289276
onConcurrentLoad = () => {
290277
if (qsTruthy("allow_multi") || this.props.store.state.preferences["allowMultipleHubsInstances"]) return;
291278
this.startAutoExitTimer(AutoExitReason.concurrentSession);
@@ -1107,8 +1094,9 @@ class UIRoot extends Component {
11071094
if (this.props.hide || this.state.hide) {
11081095
return (
11091096
<div className={classNames(rootStyles)}>
1110-
<RoomLayout
1111-
onResizeViewport={this.onResizeViewport}
1097+
<RoomLayoutContainer
1098+
scene={this.props.scene}
1099+
store={this.props.store}
11121100
viewport={!this.state.hideUITip && <FullscreenTip onDismiss={() => this.setState({ hideUITip: true })} />}
11131101
/>
11141102
</div>
@@ -1483,10 +1471,11 @@ class UIRoot extends Component {
14831471
scene={this.props.scene}
14841472
/>
14851473
)}
1486-
<RoomLayout
1474+
<RoomLayoutContainer
1475+
scene={this.props.scene}
1476+
store={this.props.store}
14871477
objectFocused={!!this.props.selectedObject}
14881478
streaming={streaming}
1489-
onResizeViewport={this.onResizeViewport}
14901479
viewport={
14911480
<>
14921481
{!this.state.dialog && renderEntryFlow ? entryDialog : undefined}

0 commit comments

Comments
 (0)