Whiteboard: comment-reply / drag-transform edge cases #190
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
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_whiteboard#190
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?
Three related bugs in
static/web/js/whiteboard/comments.jsA. Reply edge cases
deleteComment(line 203) callshidePopover()unconditionally on success. When the user clicks the smalldeletelink next to a reply inside the parents popover, the parents popover gets closed even though the parent itself wasnt deleted. Expected: refresh the popover so the reply row disappears, keep the parent popover open.board_id,user_id,text,x,y. It dropsparent_id,rotation,scale, andresolved(the resolved flag is partially handled in a second RPC). So undoing the deletion of a reply silently re-creates it as a NEW top-level comment with its own marker on the canvas.B. Drag history omits rotation/scale (audit #25)
oldX/oldYin the snapshot, so Ctrl+Z restores x/y but not rotation/scale.onTransformEnd(line 652) bakes rotation/scale into the entry + firescomment.updatebut pushes NOTHING onto the history stack. Transform-only changes are entirely outside undo.C. Reply coords are stored from parent at create time then never resynced (audit #29)
replyToComment(line 142) inherits the parents x/y at create time (line 152-155). These values are stored on the server and returned bycomment.list, but the reply has no marker (addCommentMarkerat line 243 skips replies). When the parent later moves, the reply rows hold stale parent coords forever.openrpc.jsoncomment.create) marks x/y as optional, so we can simply omit them for replies.Approach
deleteComment, if the deleted comment had aparent_idAND the popover is currently showing that parent, callshowCommentPopover(parent_id)to refresh instead ofhidePopover(). Only top-level deletions hide the popover (the parent is now gone — nothing to show).parent_id,rotation,scale. The recreate path (_createCommentFromData) already supports passing these via the params object;comment.createschema accepts them as optional. Same for the resolved flag (already partially handled).replyToComment, drop theparams.x = parent.data.xlines. Dont send x/y for replies. The reply is never rendered as a marker so the values are unused, and omitting them keeps the server data sane when the parent moves._updateCommentTransform(id, x, y, rotation, scale)helper. Make the drag-end snapshot capture rotation/scale alongside x/y; push an undo that calls the transform helper with the old quad and a redo with the new quad. MakeonTransformEnddo the same: capture before-state at transformstart, push history at transformend.Acceptance
deletenext to a reply in the parents popover → reply disappears from the popover, popover stays open. Ctrl+Z restores the reply as a reply (not a top-level), and the popover re-shows it.Implementation Spec for Issue #190
File to Modify
static/web/js/whiteboard/comments.jsPlan
Step 1: Add
_updateCommentTransformhelperInsert next to the existing
_updateCommentXY(~line 74). Accepts the full transform quad and updates both server + local state + marker:Step 2: Reply create — omit x/y
In
replyToComment(line 142-167), DROP the block:comment.createaccepts x/y as optional. Replies have no marker, so the values are never used; omitting them prevents the server from holding stale coordinates after the parent moves.Step 3: Reply delete UX + complete snapshot
Rewrite
deleteComment(line 203-235):_createCommentFromDataalready callsaddCommentMarker, which skips marker creation for replies (no visual change for the popover-only path), so undo restoring a reply is correct: the popover refresh on the next render will show it again if the parent is open.Step 4: Drag-end → store rotation/scale too
Replace the
dragstart/dragendblock (line 320-347):Step 5: Transform-end pushes history
Replace
onTransformEnd(line 652-686). Capture before-state intransformstart(the transformer fires this on the selected node), bake the new transform intransformend, then push history. SinceonTransformEndis called fromtools.json the transformer'stransformend, add a pairedonTransformStartthat captures the before state per-comment-id.Actually simpler: bake state on the group via
_transformBeforeand read it inonTransformEnd:Export
onTransformStartin the IIFE return so tools.js can wire it ontotransformer.on("transformstart").Acceptance Criteria
deletenext to a reply in the parent's popover → reply disappears, parent popover stays open with remaining replies. Ctrl+Z restores the reply (it reappears in the popover; the parent popover refreshes).comment.createpayload in DevTools network tab.Notes
_updateCommentTransformis idempotent (same RPC shape as_updateCommentXYwith extra fields). Other clients see onecomment.updatedper gesture.showCommentPopoverrebuilds the DOM, so re-focus is best-effort and out of scope here.Test Results + Final Summary
Changes
static/web/js/whiteboard/comments.js:_updateCommentTransform(id, x, y, rotation, scale)helper (mirrors_updateCommentXYbut for the full quad).replyToCommentdrops the parent x/y inheritance — replies no longer send unused x/y to the server.deleteComment:parent_id,rotation,scale(in addition to existing fields). Undo restores reply-ness AND transform.dragstartand pushes a_updateCommentTransformundo so rotation/scale are preserved across drag history.onTransformStart(group)stashes the before-quad on the Konva group; rewrittenonTransformEndreads it and pushes a quad-restore undo step. ExportedonTransformStartin the IIFE return.static/web/js/whiteboard/tools.js:transformer.on('transformstart')routes comment markers throughWhiteboardComments.onTransformStartinstead of the genericWhiteboardHistory.snapshotBefore(which can't serialize a comment marker throughWhiteboardObjects).Behaviour after fix
comment.createparams in the network tab after rebuild.Gates
node -c comments.js / tools.js— JS syntax OKcargo fmt --check— passcargo clippy --workspace --all-targets -- -D warnings— passManual verification still required
Rebuild + restart
hero_whiteboard_admin, hard-reload. Open a board with comments:comment.createdoes NOT includex/y.