Shape stroke width is not persisted across reload #67
Labels
No labels
prio_critical
prio_low
type_bug
type_contact
type_issue
type_lead
type_question
type_story
type_task
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_whiteboard#67
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Changing a shape's
Stroke Widthvia the Properties panel updates therendering immediately, but the increased stroke width is lost after
reloading the board.
Steps to reproduce
Stroke Width.Expected
The shape renders after reload with the same stroke width that was set
before the reload.
Actual
After reload the stroke is rendered to maybe a default value.
Implementation Spec for Issue #67
Objective
Make the shape's
Stroke Width,Strokecolor, andFillcolor edits from the Properties panel survive a page reload. Today these edits re-render the shape immediately but are never sent to the server, so on reload the shape renders with the pre-edit style.Requirements
Stroke Widthon a selected shape persists via the existing debouncedobject.updateRPC; reload restores the new value.Strokecolor andFillcolor — same root cause, same panel, same pattern.style.strokeWidth,style.stroke,style.fillare already in the wire format and correctly round-trip through the create/update/list/partial_update paths on the server and throughapplySyncUpdate/createObjectFromDataon the client. The only missing link is the UI forgetting to enqueue the update.Files to Modify
crates/hero_whiteboard_ui/static/web/js/whiteboard/properties.js— addWhiteboardSync.onUpdate(currentNode)to the three shape style handlers.No other files need changes.
Implementation Plan
Step 1 — Persist shape
Stroke WidthFiles:
properties.jsprop-stroke-widthinput handler inattachEventListeners(around lines 783–795).bg.strokeWidth(parseInt(strokeWidthInput.value))andbatchDraw(), addWhiteboardSync.onUpdate(currentNode);— mirroring the pattern already used forprop-draw-width(freehand, lines 606–619) and the document color handlers (lines 642–667).Dependencies: none.
Step 2 — Persist shape
StrokecolorFiles:
properties.jsprop-stroke-inputhandler (around lines 757–767).bg.stroke(strokeInput.value)andbatchDraw(), addWhiteboardSync.onUpdate(currentNode);.Dependencies: none.
Step 3 — Persist shape
FillcolorFiles:
properties.jsprop-fill-inputhandler (around lines 770–780).bg.fill(fillInput.value)andbatchDraw(), addWhiteboardSync.onUpdate(currentNode);.Dependencies: none.
Acceptance Criteria
object.updateRPC (a single update ~500 ms after the last input, with the newstyle.*values).object.updatedWebSocket broadcast continues to re-render the shape correctly (already handled byapplySyncUpdate; behavior unchanged, just now actually triggered).Notes
Root cause. The three shape style inputs (
prop-stroke-input,prop-fill-input,prop-stroke-width) inproperties.jsmutate the Konva node and redraw the layer but never enqueue a sync update.WhiteboardSync.onUpdate(node)is what adds the node topendingUpdates, triggers the debounce timer, and ultimately callsserializeForServer(node)— which already readsbg.strokeWidth()/bg.stroke()/bg.fill(). Without the call, the server never hears the edit, soobject.liston reload returns the original style.Why shape-specific. Every other object-type handler that mutates visual state (freehand stroke/width, document bg/border, kanban/mindmap/calendar/group) already calls
WhiteboardSync.onUpdate. The shape block is the one that forgot — likely because the bg mutation is an inline Konva call rather than going through a dedicated helper.Related round-trip gaps discovered during exploration, OUT OF SCOPE for this PR (surface in a follow-up issue):
prop-frame-title): rename is lost on reload.prop-mm-root-text) and root color (prop-mm-root-color): edits lost on reload.These are the same trivial one-line fix but belong in a separately reviewable PR since the issue title is specifically about stroke width. Will mention in the PR description.
No schema migration.
styleis already an opaque JSON blob server-side;strokeWidthis already sent and read back by the existing code. Fix is purely client-side in one file.Test Results
JavaScript-only change in
properties.js; Rust workspace validated for regressions.cargo check --workspacecargo clippy --workspace -- -D warningscargo fmt --checkManual verification is required: create a shape, change Stroke Width / Stroke / Fill via the Properties panel, reload, confirm the new values are rendered back.
Implementation Summary
Shape style edits (Stroke Width, Stroke color, Fill color) from the Properties panel now persist across reload.
Files changed
crates/hero_whiteboard_ui/static/web/js/whiteboard/properties.js(+3 / -0)Root cause
The three shape style inputs (
prop-stroke-input,prop-fill-input,prop-stroke-width) mutated the Konva node and redrew the layer but never calledWhiteboardSync.onUpdate(currentNode). That call is what adds the node topendingUpdates, triggers the debounce timer, and ultimately sends theobject.updateRPC. Without it the server never heard the edit, so on reloadobject.listreturned the original style.Fix
Added
WhiteboardSync.onUpdate(currentNode);inside each of the threeif (bg) { ... }blocks, right afterbatchDraw(), mirroring the pattern already used for every other object-type style handler in the same file.Preserved
applySyncUpdate; this fix merely ensures it is actually triggered).style.strokeWidth,style.stroke,style.fillwere already in the wire format and already round-tripped through the reload path.Out of scope
Two related persistence gaps were discovered during exploration and are NOT fixed here (to keep the PR narrowly reviewable against this issue):
prop-frame-title): rename lost on reload.prop-mm-root-text,prop-mm-root-color): edits lost on reload.These deserve a separate issue and PR.
Test results
cargo check --workspace: passcargo clippy --workspace -- -D warnings: passcargo fmt --check: passManual QA required: set Stroke Width / Stroke / Fill on a shape, reload, confirm the new values are rendered back.
Pull request opened: #70
This PR implements the changes discussed in this issue.