Refine inline review composer: gutter + buttons, click-anywhere-on-line composer below the line, unlimited simultaneous composers #560
Labels
No labels
actions
bug
cli
duplicate
enhancement
fork
forum
git storage
help wanted
insights
invalid
issues
moderation
oidc
ownership transfer
packages
pr/merge protection rules
projects
pull requests
question
releases
sponsorships
tags
webhooks
wiki
wontfix
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
crueber/walhub#560
Loading…
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?
What's requested
Refine the PR inline review composer interaction (built for #546, extended by #555) on the conversation page's diff so commenting feels like per-line affordance rather than a single staged draft:
Current state (static read of the current tree)
web/src/pages/Pull.jsx,DiffFile:<button ... class="ml-2 hidden shrink-0 px-1 text-emerald-600 group-hover:inline hover:text-emerald-700 focus-visible:inline pointer-coarse:inline ...">in the row<div class="group flex font-mono text-xs ...">). It is hover/keyboard/coarse-pointer conditional, not a permanent gutter element.const [getDraft, setDraft] = createSignal(null)—stageLineoverwritessetDraft({ anchor }), so opening a second comment discards/aborts the first, and only one composer exists at a time.<Show when={getDraft()}>block after the hunks<For>), not below the line being commented on — the reviewer has to scroll to see what they're writing about on long files.Everything else stays as landed:
stageLine→buildAnchor(lib/review-anchor.js) → sharedCommentComposer→props.onStageinto the finish-review modal; Shift+click range extension;#502anonymous-viewer gate; drifted-thread placement.Architecture notes
getDraftsignal per file to a keyed collection (e.g. a signal holding a Map/array of drafts keyed by hunk+row or anchor start), so multiple composers coexist. Row rendering inserts the composer inline in the row<For>immediately below the matching row, instead of one<Show>at file end.stageLine's anchor-building logic intact —buildAnchorinputs must stay byte-identical (anchorContextShapinned vectors /DriftHashtwin ininternal/review/model.goare unaffected; this is presentation only). Shift+click range extension should keep working with the gutter buttons.DiffTablegutter conventions (line-number gutter cells,gutterLinkaccessibility labels) so the two diff surfaces read consistently.#502gate stays: no triggers, no composers, no row-click handler for anonymous viewers (props.canComment !== falseguards all three entry points).focus-visibleaffordances and ensure tapping a row doesn't require precise hover.Acceptance criteria
#502gate holds: anonymous viewers get no gutter buttons, no row-click behavior, no composersbuildAnchorinputs andanchorContextShapinned vector tests stay byte-identical (presentation-only change)Fixed by #562 (merged): gutter '+' triggers per line (always visible), click-anywhere-on-row opens composer below the line, keyed multi-draft Map for unlimited simultaneous composers with independent submit. Verified: 1322 unit tests green (smoke excluded, pre-existing live-server failure only), vite+esbuild green, go vet clean, independent review APPROVE (all 9 acceptance criteria hold, presentation-only).