- collab.blocks sync had no guard against empty arrays
- when project loads, collab syncs empty blocks from server
- this overwrites createDefaultBlocks() with empty array
- added if (collab.blocks.length > 0) guard, same as layers
- Root cause: App.tsx collab sync effect called setLayers(collab.layers)
even when collab.layers was empty, wiping out initialLayers
- Effect: RenderEngine.render() iterates layers to draw elements;
with 0 layers, no elements render (appear to disappear)
- Fix: guard against empty collab.layers
Fixes: drawing tools work on desktop and mobile, objects persist after release
- RightSidebar: added onCollapse prop and close button in header
- LeftSidebar: wired existing onCollapse prop in App.tsx
- CSS: show .leftbar-toggle and .rightbar-close on mobile
- Both buttons call setMobile{Left,Right}Open(false) to close overlays
- LeftSidebar/RightSidebar: added className prop for 'open' class
- Topbar: wired hamburger onClick + added mobile-drawer-toggle button for right panel
- App.tsx: added SettingsModal import/state/render, passed className props to sidebars
- styles.css: mobile sidebars now fixed slide-in overlays (translateX) instead of display:none
- ui.types.ts: added className to RightSidebarProps, onOpenLeftDrawer/onOpenRightDrawer to TopbarProps
- Tested at 390px viewport: both sidebars slide in correctly, transform verified via DOM
Root cause: layers.id is TEXT PRIMARY KEY (global unique across all drawings).
Hardcoded IDs layer-0..layer-4 collided when multiple projects tried to create
the same layer IDs. Second project got UNIQUE constraint failed on POST /layers.
Without layers, elements had dangling layer_id refs causing FOREIGN KEY errors.
Fix: makeInitialLayers() generates unique IDs: layer-{timestamp}-{index}.
activeLayerId initialized from first layer, not hardcoded.
activeLayerName uses activeLayerId variable, not hardcoded layer-0.
On project load with existing layers, activeLayerId set from first DB layer.
Three fixes:
1. interaction/index.ts: Add layerId to created element in confirmDraw()
2. CanvasArea.tsx: Sync layers to LayerManager via layerManagerRef
3. App.tsx: Fallback to activeLayerId in handleElementCreated if layerId missing
Root cause: LayerManager.activeLayerId was empty because layers were never
synced from React state to the interaction layer LayerManager. New elements
got layer_id="" which failed SQLite FOREIGN KEY constraint.
Also includes Yjs sync race condition fix from previous commit.
- CanvasArea: add useEffect to refresh InteractionEngine callbacks when props change
- App.tsx: handleElementCreated/Deleted/Modified now use functional setElements updates
- Root cause: CanvasArea init useEffect had empty deps, capturing stale callbacks at mount
- handleElementCreated used [...elements, el] with stale elements=[] closure
- Each new element replaced all previous ones instead of appending
- All 343 tests pass, tsc clean