🚀 Auto-deploy: melhoria no snap e medição AR em 31/05/2026 23:46:46

This commit is contained in:
2026-05-31 23:46:46 +00:00
parent 126bc6f80d
commit a2ac72cfe7
2 changed files with 99 additions and 7 deletions
+81 -6
View File
@@ -1,6 +1,6 @@
import { useNavigate, useSearchParams } from "react-router-dom";
import { supabase } from "@/integrations/supabase/client";
import { ArrowLeft, Glasses, Box, Ruler, FileText, Upload, Loader2, Users } from "lucide-react";
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 { ModelViewerCanvas } from "@/components/three/ModelViewer";
@@ -21,6 +21,7 @@ import { Separator } from "@/components/ui/separator";
import { getSupportedExtension, convertToGLB, ACCEPTED_EXTENSIONS } from "@/lib/convertToGLB";
import { validateModelFile } from "@/lib/validateModelFile";
import { convertIFCtoGLB } from "@/lib/convertIFC";
import { mainCameraRef, mainControlsRef } from "@/components/three/viewCubeBus";
const Viewer = () => {
const navigate = useNavigate();
@@ -39,6 +40,44 @@ const Viewer = () => {
const fileInputRef = useRef<HTMLInputElement>(null);
const [converting, setConverting] = useState(false);
const [isFullscreen, setIsFullscreen] = useState(false);
const [sidebarOpen, setSidebarOpen] = useState(true);
useEffect(() => {
const handleFullscreenChange = () => {
setIsFullscreen(!!document.fullscreenElement);
};
document.addEventListener("fullscreenchange", handleFullscreenChange);
return () => {
document.removeEventListener("fullscreenchange", handleFullscreenChange);
};
}, []);
const handleRecenter = useCallback(() => {
const camera = mainCameraRef.current;
const controls = mainControlsRef.current;
if (camera) {
camera.position.set(2, 2, 2);
camera.up.set(0, 1, 0);
camera.lookAt(0, 0, 0);
}
if (controls) {
// @ts-ignore
controls.target.set(0, 0, 0);
// @ts-ignore
controls.update();
}
toast.success("Visualização centralizada");
}, []);
const exitFullscreen = useCallback(() => {
if (document.fullscreenElement) {
document.exitFullscreen().catch((err) => {
console.error("Erro ao sair de tela cheia:", err);
});
}
}, []);
const [searchParams] = useSearchParams();
const roomId = searchParams.get("room");
const channelRef = useRef<ReturnType<typeof supabase.channel> | null>(null);
@@ -325,15 +364,51 @@ const Viewer = () => {
<div className="flex flex-1 overflow-hidden">
{/* 3D Canvas with floating controls */}
<div className="relative flex-1">
<div className="relative flex-1" id="canvas-container">
<ModelViewerCanvas />
<ViewCube />
<ViewerControls />
<SectionCutPanel />
{isFullscreen ? (
<div className="absolute top-4 left-4 z-50 flex gap-2">
<Button
variant="outline"
className="gap-2 bg-background/80 border-primary/40 hover:bg-primary/20 text-foreground font-mono shadow-md backdrop-blur-sm h-9"
onClick={handleRecenter}
>
<Target className="h-4 w-4 text-primary animate-pulse" />
Centralizar
</Button>
<Button
variant="outline"
className="gap-2 bg-background/80 border-destructive/40 hover:bg-destructive/20 text-foreground font-mono shadow-md backdrop-blur-sm h-9"
onClick={exitFullscreen}
>
<ArrowLeft className="h-4 w-4 text-destructive" />
Retornar (ESC)
</Button>
</div>
) : (
<>
{/* Botão de Toggle do Sidebar */}
<Button
variant="outline"
size="icon"
onClick={() => setSidebarOpen(!sidebarOpen)}
className={`absolute z-30 h-8 w-8 rounded-md bg-background/80 border-primary/30 text-primary shadow-md hover:bg-primary/10 transition-all duration-300 ${
sidebarOpen ? "right-[332px]" : "right-4"
} top-[205px]`}
title={sidebarOpen ? "Recolher menu" : "Expandir menu"}
>
<Menu className="h-4 w-4" />
</Button>
<ViewCube />
<ViewerControls />
<SectionCutPanel />
</>
)}
</div>
{/* Side panel */}
<aside className="w-80 shrink-0 border-l bg-card">
<aside className={`transition-all duration-300 border-l bg-card flex flex-col ${sidebarOpen ? 'w-80 opacity-100' : 'w-0 opacity-0 pointer-events-none border-l-0 overflow-hidden'}`}>
<ScrollArea className="h-full">
<div className="p-4 space-y-5">
<div>