Anna Sun
squash for release
2485dd8
import * as THREE from 'three';
import {Button} from '@mui/material';
import {useCallback, useEffect, useState} from 'react';
import {BufferedSpeechPlayer} from '../createBufferedSpeechPlayer';
type Props = {
bufferedSpeechPlayer: BufferedSpeechPlayer;
renderer: THREE.WebGLRenderer | null;
onARVisible?: () => void;
onARHidden?: () => void;
};
export default function ARButton({
bufferedSpeechPlayer,
renderer,
onARVisible,
onARHidden,
}: Props) {
const [session, setSession] = useState<XRSession | null>(null);
const [supported, setSupported] = useState<boolean>(true);
useEffect(() => {
if (!navigator.xr) {
setSupported(false);
return;
}
navigator.xr.isSessionSupported('immersive-ar').then((supported) => {
setSupported(supported);
});
}, []);
const resetBuffers = useCallback(
(event: XRSessionEvent) => {
const session = event.target;
if (!(session instanceof XRSession)) {
return;
}
switch (session.visibilityState) {
case 'visible':
console.log('Restarting speech player, device is visible');
bufferedSpeechPlayer.stop();
bufferedSpeechPlayer.start();
onARVisible?.();
break;
case 'hidden':
console.log('Stopping speech player, device is hidden');
bufferedSpeechPlayer.stop();
bufferedSpeechPlayer.start();
onARHidden?.();
break;
}
},
[bufferedSpeechPlayer],
);
async function onSessionStarted(session: XRSession) {
setSession(session);
session.onvisibilitychange = resetBuffers;
session.onend = onSessionEnded;
await renderer.xr.setSession(session);
}
function onSessionEnded() {
setSession(null);
}
const onClick = () => {
if (session === null) {
navigator.xr!.requestSession('immersive-ar').then(onSessionStarted);
} else {
session.end();
}
};
return (
<Button
variant="contained"
onClick={onClick}
disabled={!supported || renderer == null}
sx={{mt: 1}}>
{supported
? renderer != null
? 'Enter AR'
: 'Initializing AR...'
: 'AR Not Supported'}
</Button>
);
}