🔧 Fix: modo AR travando em loading — timeout de segurança, feedback visual no botão e auto-return retardado
- Viewer: loading state no botão 'Entrar em Modo XR' com Loader2 e texto 'Iniciando AR...' - Viewer: timeout de 15s que limpa o loading e mostra toast de erro se não entrar - Viewer: marca __setXrEntering(true) antes de navegar para bloquear auto-return prematuro - XRSession: delay do auto-return aumentado de 500ms para 2000ms - XRSession: novo flag isEnteringAR que previne navegação prematura para /viewer - XRSession: expõe __setXrEntering via window para Viewer setar o flag - Versão: v1.10 → v1.11 [31/05/2026 17:33:29]
This commit is contained in:
+21
-3
@@ -1048,17 +1048,21 @@ const XRSession = () => {
|
||||
const devkit = useDevKit();
|
||||
const [simXR, setSimXR] = useState(false);
|
||||
const effectiveInXR = inXR || simXR;
|
||||
// Indica que enterAR() foi chamado mas a sessão ainda não começou — previne auto-return prematuro
|
||||
const [isEnteringAR, setIsEnteringAR] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!model) navigate('/');
|
||||
}, [model, navigate]);
|
||||
|
||||
// Detecta quando a sessão XR de fato começa
|
||||
useEffect(() => {
|
||||
const unsubscribe = store.subscribe((state) => {
|
||||
const session = state.session;
|
||||
if (session && !inXR) {
|
||||
console.log('[XR] ✅ Sessão AR ativa!');
|
||||
setInXR(true);
|
||||
setIsEnteringAR(false);
|
||||
setAnchorMode('manual');
|
||||
toast.success('Sessão AR iniciada!');
|
||||
session.addEventListener('end', () => {
|
||||
@@ -1070,6 +1074,20 @@ const XRSession = () => {
|
||||
return unsubscribe;
|
||||
}, [inXR, setAnchorMode]);
|
||||
|
||||
// Flag que indica que o usuário pediu para entrar no AR (enterAR chamado).
|
||||
// Usada para bloquear o auto-return durante o onboarding do WebXR.
|
||||
useEffect(() => {
|
||||
// Se inXR virou true mas isEnteringAR é true, a sessão começou — limpa o flag
|
||||
if (inXR && isEnteringAR) {
|
||||
setIsEnteringAR(false);
|
||||
}
|
||||
}, [inXR, isEnteringAR]);
|
||||
|
||||
// Expõe setIsEnteringAR para o Viewer via window (permite marcar "entrando" antes de navegar)
|
||||
useEffect(() => {
|
||||
(window as unknown as { __setXrEntering?: (v: boolean) => void }).__setXrEntering = setIsEnteringAR;
|
||||
}, []);
|
||||
|
||||
const handleDownloadMarker = useCallback(async () => {
|
||||
const url = await generateMarkerDownloadURL();
|
||||
const a = document.createElement('a');
|
||||
@@ -1084,14 +1102,14 @@ const XRSession = () => {
|
||||
|
||||
// Auto-return to viewer if user exits AR session
|
||||
useEffect(() => {
|
||||
// If we are mounted, and the session is completely absent/ended (inXR is false),
|
||||
// we wait a brief moment to avoid returning during initial transition, then return.
|
||||
// Don't auto-return while we're waiting for the XR onboarding dialog to complete
|
||||
if (!inXR) {
|
||||
const timer = setTimeout(() => {
|
||||
// Only return if the session is truly absent AND we're not in the middle of entering AR
|
||||
if (!store.getState().session) {
|
||||
navigate('/viewer');
|
||||
}
|
||||
}, 500);
|
||||
}, 2000);
|
||||
return () => clearTimeout(timer);
|
||||
}
|
||||
}, [inXR, navigate]);
|
||||
|
||||
Reference in New Issue
Block a user