diff --git a/src/pages/Viewer.tsx b/src/pages/Viewer.tsx index 92ab215..2638e61 100644 --- a/src/pages/Viewer.tsx +++ b/src/pages/Viewer.tsx @@ -3,6 +3,7 @@ import { supabase } from "@/integrations/supabase/client"; import { ArrowLeft, Glasses, Box, Ruler, FileText, Upload, Loader2, Users, Menu, Target } from "lucide-react"; import { Button } from "@/components/ui/button"; import { useModelStore } from "@/stores/useModelStore"; +import { xrStore } from "@/stores/useXRStore"; import { ModelViewerCanvas } from "@/components/three/ModelViewer"; import { ViewerControls } from "@/components/ViewerControls"; import { InspectionChecklist } from "@/components/InspectionChecklist"; @@ -274,12 +275,16 @@ const Viewer = () => { }, 15000); try { - const { xrStore } = await import('@/stores/useXRStore'); // Marca que está entrando no AR antes de navegar — bloqueia auto-return prematuro (window as unknown as { __setXrEntering?: (v: boolean) => void }).__setXrEntering?.(true); - await xrStore.enterAR(); + + // Chamada síncrona de enterAR para preservar o User Gesture exigido pelo WebXR + const enterPromise = xrStore.enterAR(); + clearTimeout(timeoutId); navigate("/xr"); + + await enterPromise; } catch (e) { clearTimeout(timeoutId); setEnteringXR(false); diff --git a/src/stores/useModelStore.ts b/src/stores/useModelStore.ts index c37a4cb..56ad8dd 100644 --- a/src/stores/useModelStore.ts +++ b/src/stores/useModelStore.ts @@ -812,3 +812,12 @@ export const useModelStore = create((set, get) => ({ set({ ifcMaterialColors: enabled }); }, })); + +// Autodetecção global de suporte a WebXR +if (typeof navigator !== 'undefined' && navigator.xr) { + navigator.xr.isSessionSupported('immersive-ar') + .then((supported) => useModelStore.getState().setXrSupported(supported)) + .catch(() => useModelStore.getState().setXrSupported(false)); +} else { + useModelStore.getState().setXrSupported(false); +}