feat: filter empty projects from public gallery (#125)

* feat(community): filter empty projects from public gallery

Add is_empty column to projects table so the public gallery only shows
projects with actual content. Scene graph emptiness is computed on save
and on creation, and a backfill migration marks existing non-empty
projects. Also cleans up import ordering, fixes README migration path,
and removes stale feedback table migration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Use ESNext modules and bundler resolution

Update packages/db tsconfig to emit ESNext modules and use 'bundler' moduleResolution. This enables modern ESM output and bundler-style resolution for the db package (keeps outDir and rootDir unchanged).

* feat(editor): add dark mode theme and grid visibility toggle

Add theme state to viewer store with light/dark modes, dark-aware
lighting and background colors, grid show/hide toggle in settings,
and theme toggle buttons in the sidebar.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Add ground occluder, animated lighting & UI tweaks

Introduce a ground occluder and smoother animated lighting while adjusting editor UI and icons. Viewer: add GroundOccluder (uses polygon-clipping to union slab/zone polygons) and AnimatedBackground, integrate both into the Canvas; improve Lights to interpolate intensities/colors/ambient for smooth theme transitions. Editor: refactor sidebar header to support inline project title editing and move the theme toggle; replace some lucide icons with image assets and add a settings icon (apps/editor/public/icons/settings.png). Also add polygon-clipping to the viewer package dependencies.

* Update dark mode background color and clean up imports

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Aymeric Rabot
2026-02-27 23:49:48 -05:00
committed by GitHub
co-authored by Claude Opus 4.6
parent 5077011c26
commit 98c1d5247e
25 changed files with 2775 additions and 91 deletions
+25 -1
View File
@@ -35,6 +35,9 @@ type ViewerState = {
cameraMode: 'perspective' | 'orthographic'
setCameraMode: (mode: 'perspective' | 'orthographic') => void
theme: 'light' | 'dark'
setTheme: (theme: 'light' | 'dark') => void
levelMode: 'stacked' | 'exploded' | 'solo' | 'manual'
setLevelMode: (mode: 'stacked' | 'exploded' | 'solo' | 'manual') => void
@@ -47,9 +50,12 @@ type ViewerState = {
showGuides: boolean
setShowGuides: (show: boolean) => void
showGrid: boolean
setShowGrid: (show: boolean) => void
projectId: string | null
setProjectId: (id: string | null) => void
projectPreferences: Record<string, { showScans?: boolean, showGuides?: boolean }>
projectPreferences: Record<string, { showScans?: boolean, showGuides?: boolean, showGrid?: boolean }>
// Smart selection update
setSelection: (updates: Partial<SelectionPath>) => void
@@ -77,6 +83,9 @@ const useViewer = create<ViewerState>()(
cameraMode: "perspective",
setCameraMode: (mode) => set({ cameraMode: mode }),
theme: "light",
setTheme: (theme) => set({ theme }),
levelMode: "stacked",
setLevelMode: (mode) => set({ levelMode: mode }),
@@ -109,6 +118,19 @@ const useViewer = create<ViewerState>()(
return { showGuides: show, projectPreferences };
}),
showGrid: true,
setShowGrid: (show) =>
set((state) => {
const projectPreferences = { ...(state.projectPreferences || {}) };
if (state.projectId) {
projectPreferences[state.projectId] = {
...(projectPreferences[state.projectId] || {}),
showGrid: show,
};
}
return { showGrid: show, projectPreferences };
}),
projectId: null,
setProjectId: (id) =>
set((state) => {
@@ -118,6 +140,7 @@ const useViewer = create<ViewerState>()(
projectId: id,
showScans: prefs.showScans ?? true,
showGuides: prefs.showGuides ?? true,
showGrid: prefs.showGrid ?? true,
};
}),
projectPreferences: {},
@@ -165,6 +188,7 @@ const useViewer = create<ViewerState>()(
name: 'viewer-preferences',
partialize: (state) => ({
cameraMode: state.cameraMode,
theme: state.theme,
levelMode: state.levelMode,
wallMode: state.wallMode,
projectPreferences: state.projectPreferences,