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 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
d0e0fe7e1e
commit
31c09bacdd
@@ -28,6 +28,10 @@ export default function ViewerPage() {
|
|||||||
const [canShowGuides, setCanShowGuides] = useState(true)
|
const [canShowGuides, setCanShowGuides] = useState(true)
|
||||||
const setScene = useScene((state) => state.setScene)
|
const setScene = useScene((state) => state.setScene)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
useViewer.getState().setProjectId(projectId)
|
||||||
|
}, [projectId])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const loadContent = async () => {
|
const loadContent = async () => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -71,6 +71,14 @@ export default function Editor({ projectId }: EditorProps) {
|
|||||||
const isSceneLoading = useProjectStore((state) => state.isSceneLoading)
|
const isSceneLoading = useProjectStore((state) => state.isSceneLoading)
|
||||||
const isLoading = isProjectLoading || isSceneLoading
|
const isLoading = isProjectLoading || isSceneLoading
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (projectId) {
|
||||||
|
useViewer.getState().setProjectId(projectId)
|
||||||
|
} else {
|
||||||
|
useViewer.getState().setProjectId(null)
|
||||||
|
}
|
||||||
|
}, [projectId])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.body.classList.add('dark')
|
document.body.classList.add('dark')
|
||||||
return () => {
|
return () => {
|
||||||
|
|||||||
@@ -5,15 +5,17 @@ import { DoubleSide, type Group, type Texture, TextureLoader } from 'three'
|
|||||||
import { float, texture } from 'three/tsl'
|
import { float, texture } from 'three/tsl'
|
||||||
import { MeshBasicNodeMaterial } from 'three/webgpu'
|
import { MeshBasicNodeMaterial } from 'three/webgpu'
|
||||||
import { useAssetUrl } from '../../../hooks/use-asset-url'
|
import { useAssetUrl } from '../../../hooks/use-asset-url'
|
||||||
|
import useViewer from '../../../store/use-viewer'
|
||||||
|
|
||||||
export const GuideRenderer = ({ node }: { node: GuideNode }) => {
|
export const GuideRenderer = ({ node }: { node: GuideNode }) => {
|
||||||
|
const showGuides = useViewer((s) => s.showGuides)
|
||||||
const ref = useRef<Group>(null!)
|
const ref = useRef<Group>(null!)
|
||||||
useRegistry(node.id, 'guide', ref)
|
useRegistry(node.id, 'guide', ref)
|
||||||
|
|
||||||
const resolvedUrl = useAssetUrl(node.url)
|
const resolvedUrl = useAssetUrl(node.url)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<group ref={ref} position={node.position} rotation={[0, node.rotation[1], 0]}>
|
<group ref={ref} visible={showGuides} position={node.position} rotation={[0, node.rotation[1], 0]}>
|
||||||
{resolvedUrl && (
|
{resolvedUrl && (
|
||||||
<Suspense>
|
<Suspense>
|
||||||
<GuidePlane url={resolvedUrl} scale={node.scale} opacity={node.opacity} />
|
<GuidePlane url={resolvedUrl} scale={node.scale} opacity={node.opacity} />
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ import { Suspense, useMemo, useRef } from 'react'
|
|||||||
import type { Group, Material, Mesh } from 'three'
|
import type { Group, Material, Mesh } from 'three'
|
||||||
import { useAssetUrl } from '../../../hooks/use-asset-url'
|
import { useAssetUrl } from '../../../hooks/use-asset-url'
|
||||||
import { useGLTFKTX2 } from '../../../hooks/use-gltf-ktx2'
|
import { useGLTFKTX2 } from '../../../hooks/use-gltf-ktx2'
|
||||||
|
import useViewer from '../../../store/use-viewer'
|
||||||
|
|
||||||
export const ScanRenderer = ({ node }: { node: ScanNode }) => {
|
export const ScanRenderer = ({ node }: { node: ScanNode }) => {
|
||||||
|
const showScans = useViewer((s) => s.showScans)
|
||||||
const ref = useRef<Group>(null!)
|
const ref = useRef<Group>(null!)
|
||||||
useRegistry(node.id, 'scan', ref)
|
useRegistry(node.id, 'scan', ref)
|
||||||
|
|
||||||
@@ -13,6 +15,7 @@ export const ScanRenderer = ({ node }: { node: ScanNode }) => {
|
|||||||
return (
|
return (
|
||||||
<group
|
<group
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
visible={showScans}
|
||||||
position={node.position}
|
position={node.position}
|
||||||
rotation={node.rotation}
|
rotation={node.rotation}
|
||||||
scale={[node.scale, node.scale, node.scale]}
|
scale={[node.scale, node.scale, node.scale]}
|
||||||
|
|||||||
@@ -47,6 +47,10 @@ type ViewerState = {
|
|||||||
showGuides: boolean
|
showGuides: boolean
|
||||||
setShowGuides: (show: boolean) => void
|
setShowGuides: (show: boolean) => void
|
||||||
|
|
||||||
|
projectId: string | null
|
||||||
|
setProjectId: (id: string | null) => void
|
||||||
|
projectPreferences: Record<string, { showScans?: boolean, showGuides?: boolean }>
|
||||||
|
|
||||||
// Smart selection update
|
// Smart selection update
|
||||||
setSelection: (updates: Partial<SelectionPath>) => void
|
setSelection: (updates: Partial<SelectionPath>) => void
|
||||||
resetSelection: () => void
|
resetSelection: () => void
|
||||||
@@ -80,10 +84,43 @@ const useViewer = create<ViewerState>()(
|
|||||||
setWallMode: (mode) => set({ wallMode: mode }),
|
setWallMode: (mode) => set({ wallMode: mode }),
|
||||||
|
|
||||||
showScans: true,
|
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,
|
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) =>
|
setSelection: (updates) =>
|
||||||
set((state) => {
|
set((state) => {
|
||||||
@@ -130,8 +167,7 @@ const useViewer = create<ViewerState>()(
|
|||||||
cameraMode: state.cameraMode,
|
cameraMode: state.cameraMode,
|
||||||
levelMode: state.levelMode,
|
levelMode: state.levelMode,
|
||||||
wallMode: state.wallMode,
|
wallMode: state.wallMode,
|
||||||
showScans: state.showScans,
|
projectPreferences: state.projectPreferences,
|
||||||
showGuides: state.showGuides,
|
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user