From 31c09bacdd5caa3ec0e0222e9b11940c0a09f77b Mon Sep 17 00:00:00 2001 From: Aymeric Rabot Date: Fri, 27 Feb 2026 01:38:10 -0500 Subject: [PATCH] Fix scan/guide visibility with per-project preferences - Store showScans/showGuides preferences per project so toggling persists when switching between projects - Apply showGuides/showScans directly on guide and scan renderer groups - Set projectId in both editor and viewer pages on mount Co-Authored-By: Claude Opus 4.6 --- apps/editor/app/viewer/[id]/page.tsx | 4 ++ apps/editor/components/editor/index.tsx | 8 ++++ .../renderers/guide/guide-renderer.tsx | 4 +- .../renderers/scan/scan-renderer.tsx | 3 ++ packages/viewer/src/store/use-viewer.ts | 44 +++++++++++++++++-- 5 files changed, 58 insertions(+), 5 deletions(-) diff --git a/apps/editor/app/viewer/[id]/page.tsx b/apps/editor/app/viewer/[id]/page.tsx index a21f97d3..8d06101b 100644 --- a/apps/editor/app/viewer/[id]/page.tsx +++ b/apps/editor/app/viewer/[id]/page.tsx @@ -28,6 +28,10 @@ export default function ViewerPage() { const [canShowGuides, setCanShowGuides] = useState(true) const setScene = useScene((state) => state.setScene) + useEffect(() => { + useViewer.getState().setProjectId(projectId) + }, [projectId]) + useEffect(() => { const loadContent = async () => { try { diff --git a/apps/editor/components/editor/index.tsx b/apps/editor/components/editor/index.tsx index 56627adc..161d4ddb 100644 --- a/apps/editor/components/editor/index.tsx +++ b/apps/editor/components/editor/index.tsx @@ -71,6 +71,14 @@ export default function Editor({ projectId }: EditorProps) { const isSceneLoading = useProjectStore((state) => state.isSceneLoading) const isLoading = isProjectLoading || isSceneLoading + useEffect(() => { + if (projectId) { + useViewer.getState().setProjectId(projectId) + } else { + useViewer.getState().setProjectId(null) + } + }, [projectId]) + useEffect(() => { document.body.classList.add('dark') return () => { diff --git a/packages/viewer/src/components/renderers/guide/guide-renderer.tsx b/packages/viewer/src/components/renderers/guide/guide-renderer.tsx index 10a50c49..ced9b464 100644 --- a/packages/viewer/src/components/renderers/guide/guide-renderer.tsx +++ b/packages/viewer/src/components/renderers/guide/guide-renderer.tsx @@ -5,15 +5,17 @@ import { DoubleSide, type Group, type Texture, TextureLoader } from 'three' import { float, texture } from 'three/tsl' import { MeshBasicNodeMaterial } from 'three/webgpu' import { useAssetUrl } from '../../../hooks/use-asset-url' +import useViewer from '../../../store/use-viewer' export const GuideRenderer = ({ node }: { node: GuideNode }) => { + const showGuides = useViewer((s) => s.showGuides) const ref = useRef(null!) useRegistry(node.id, 'guide', ref) const resolvedUrl = useAssetUrl(node.url) return ( - + {resolvedUrl && ( diff --git a/packages/viewer/src/components/renderers/scan/scan-renderer.tsx b/packages/viewer/src/components/renderers/scan/scan-renderer.tsx index d186c9b4..e631c173 100644 --- a/packages/viewer/src/components/renderers/scan/scan-renderer.tsx +++ b/packages/viewer/src/components/renderers/scan/scan-renderer.tsx @@ -3,8 +3,10 @@ import { Suspense, useMemo, useRef } from 'react' import type { Group, Material, Mesh } from 'three' import { useAssetUrl } from '../../../hooks/use-asset-url' import { useGLTFKTX2 } from '../../../hooks/use-gltf-ktx2' +import useViewer from '../../../store/use-viewer' export const ScanRenderer = ({ node }: { node: ScanNode }) => { + const showScans = useViewer((s) => s.showScans) const ref = useRef(null!) useRegistry(node.id, 'scan', ref) @@ -13,6 +15,7 @@ export const ScanRenderer = ({ node }: { node: ScanNode }) => { return ( void + projectId: string | null + setProjectId: (id: string | null) => void + projectPreferences: Record + // Smart selection update setSelection: (updates: Partial) => void resetSelection: () => void @@ -80,10 +84,43 @@ const useViewer = create()( setWallMode: (mode) => set({ wallMode: mode }), showScans: true, - setShowScans: (show) => set({ showScans: show }), + setShowScans: (show) => + set((state) => { + const projectPreferences = { ...(state.projectPreferences || {}) }; + if (state.projectId) { + projectPreferences[state.projectId] = { + ...(projectPreferences[state.projectId] || {}), + showScans: show, + }; + } + return { showScans: show, projectPreferences }; + }), showGuides: true, - setShowGuides: (show) => set({ showGuides: show }), + setShowGuides: (show) => + set((state) => { + const projectPreferences = { ...(state.projectPreferences || {}) }; + if (state.projectId) { + projectPreferences[state.projectId] = { + ...(projectPreferences[state.projectId] || {}), + showGuides: show, + }; + } + return { showGuides: show, projectPreferences }; + }), + + projectId: null, + setProjectId: (id) => + set((state) => { + if (!id) return { projectId: id }; + const prefs = state.projectPreferences?.[id] || {}; + return { + projectId: id, + showScans: prefs.showScans ?? true, + showGuides: prefs.showGuides ?? true, + }; + }), + projectPreferences: {}, setSelection: (updates) => set((state) => { @@ -130,8 +167,7 @@ const useViewer = create()( cameraMode: state.cameraMode, levelMode: state.levelMode, wallMode: state.wallMode, - showScans: state.showScans, - showGuides: state.showGuides, + projectPreferences: state.projectPreferences, }), }, ),