Context: the parts bin showed flat coloured glyphs for each piece,
unlike the vanilla builder which previews the real LDraw geometry.
Approach: add a single shared offscreen WebGLRenderer in ldraw.js
(renderPartThumbnail) that reuses the cached LDraw template via
buildPartObject, renders the piece once into a 96x96 canvas from a
3/4 view with soft lighting, and exports a PNG data URL cached per
part key. No live mini-scene, one render per type.
Changes:
- ldraw.js: shared offscreen renderer/scene/camera built lazily,
per-type data-URL cache, throwaway-object disposal, and a
disposeThumbnailRenderer teardown. Degrades to null on failure.
- PartsBar: fetch thumbnails on mount, show <img> when ready, keep
the glyph as fallback, dispose the renderer on unmount.
- styles.css: .PartThumb sizing inside the part card.
Impact: each piece now shows a real 3D preview; names and the active
border are preserved; no WebGL leak on unmount; graceful fallback
when WebGL is unavailable.
Translate the remaining English "Color" label in the edit panel's
colour picker to "Couleur", matching the already-French controls
("Tourner", "Créer"/"Modifier").
Restore working undo/redo after the liveblocks removal left
room.history as a no-op.
- Add a client-local past/future stack in the store. recordHistory()
snapshots bricks before each user mutation (place / delete / colour);
undo/redo rewrite bricks, so the result fans out to peers through the
normal storage sync. History is capped to avoid unbounded growth.
- Wire the BottomBar undo/redo buttons and Ctrl+Z / Ctrl+R shortcuts.
- Import DEFAULT_PART and friends from the leaf util modules instead of
the ../utils barrel: the barrel also pulls in hooks.js, which imports
the store back, and that cycle let the store body run before ldraw.js
finished initialising, throwing "Cannot access 'DEFAULT_PART' before
initialization" in the built bundle.
Add the real LDraw LEGO parts (LeoCAD-style) as the posable objects.
- Vendor the curated 15-part LDraw closure under public/ldraw so it is
served at /blocs-pro/ldraw/ after build (CC BY 4.0, credits kept).
- src/utils/ldraw.js loads each part via three's LDrawLoader, caches the
geometry per type, applies the LDU->world scale and Y flip to match the
existing grid, and tints surfaces with the active colour.
- A LeoCAD-style PartsBar (colour row + category tabs + part grid) picks
the active part; Create mode places it at the grid cell and stores a
JSON-only brick { uID, type, color, position/dimensions, rotation } so
the piece syncs to peers like any other brick.
- Brick.jsx renders the cached LDraw clone for typed bricks and keeps the
parametric box as a fallback. Edit-mode tooling (select / move / colour
/ delete) walks up to the brick group so it works on multi-mesh pieces;
selection is shown with an emissive tint instead of the stud wireframe.
Replace the English Name + Room ID form with two big, no-keyboard
buttons aimed at a 6-year-old:
- "Construire tout seul" joins a unique solo room (solo-<random>).
- "Construire a plusieurs" joins a fixed shared room ("lisael") so two
kids who tap it land together without typing anything.
- An auto name ("Constructeur NNN") keeps self.name non-empty for the
people list.
- A small "Salle perso" link reveals an optional room field for adults.
Also francise the visible chrome: Creer / Modifier modes, the rotate
toggle, the empty-room people label, and the help dialog (which no
longer auto-opens so the builder is playable immediately).
Remove @liveblocks/client and @liveblocks/zustand; add ws and a
server npm script. Update README (fork attribution preserved, WS
backend usage), .env.example (VITE_RT_URL), and pin the /blocs-pro/
base in vite.config.
roomSync() replicates the @liveblocks/zustand surface
(state.liveblocks.{enterRoom,leaveRoom,status,others,room}) over the
self-hosted relay. Storage fan-out is debounced and guarded against
remote echo; presence maps the self key; room exposes broadcastEvent,
subscribe and no-op history stubs. Falls back to a degraded solo mode
if the socket never opens so the Loader never blocks. Dev-only store
hook on window for debugging (stripped in production).