Repository navigation
v0.4.0
Copy link and inline editing for comments and replies, collision-free ids, a
confirmation before every delete, and a round of thread and inbox chrome work.
npm install helldots@0.4.0Upgrading from 0.3.0: locale keys
Only affects hosts that pass a custom strings object. Everyone else can
skip this section — the bundled en and es locales are complete.
The entries below each describe the keys their own change touched, but the
work landed across several releases' worth of changesets, so here is the whole
delta in one place. Six keys are gone and thirty-one are new; a strings
object built for 0.3.0 will render empty labels for anything it does not
supply.
Removed — safe to delete:
inboxEmpty, filterUnresolved, filterResolved, filterStatusAll,
removeTag, tagsPlaceholder
Added — copy the values from src/locales/en.js:
- Empty state and filters:
inboxEmptyTitle,inboxEmptyHintTemplate,
inboxEmptyAction,inboxNoMatches,filterTitle,filterClear - Threads and replies:
replyCountOne,replyCountTemplate,replyOptions,
deleteReply - Delete confirmation:
confirmDelete,confirmCancel,
confirmDeleteCommentTitle,confirmDeleteCommentMessage,
confirmDeleteThreadMessage,confirmDeleteReplyTitle,
confirmDeleteReplyMessage - Copy link and editing:
copyLink,linkCopied,editComment,editReply,
editorAriaLabel,editSave,editCancel,editedMark,editedAtPrefix,
confirmDiscardTitle,confirmDiscardMessage,confirmDiscard,
confirmKeepEditing,commentNotFound
Minor Changes
-
bdfff0a: Stop inbox cards stating the same thing twice, and give the hover preview a
sense of the thread behind it.- The hover tooltip now says how many replies a thread has, when it has any.
Threads with no replies are unchanged. - The status picker carries its label like type and priority already did, so
the current status is readable without hovering — which touch never allows. - Those labels are no longer capped at 72px, so "In progress" and
"Improvement" show in full. The strip wraps to a second line in the one
combination that no longer fits a narrow card. - Inbox cards no longer repeat type and priority as badges when the action
strip above already states them. Tags and the resolution time still show —
nothing else displays those. - The action strip sits directly under the author now, the same place the
thread popover puts it, instead of in a card footer.
- The hover tooltip now says how many replies a thread has, when it has any.
-
66f12bd: Ask before deleting anything.
Deleting a comment or a reply was a single click on a menu item, and there is
no trash and no undo to recover from it. Both now open a confirmation modal
first, from every place they can be reached: the inbox cards, the inbox
detail and the thread popover.- The warning names what goes: deleting a comment that has replies says the
replies go with it. - Cancel takes focus, so the destructive button is never one stray Enter
away. Escape and a click on the backdrop both cancel, and neither reaches
the panel behind the dialog. - Seven new locale keys (
confirmDelete,confirmCancel,
confirmDeleteCommentTitle,confirmDeleteCommentMessage,
confirmDeleteThreadMessage,confirmDeleteReplyTitle,
confirmDeleteReplyMessage). Hosts passing a customstringsobject need
to add them.
- The warning names what goes: deleting a comment that has replies says the
-
eb1365d: Add "Copy link" and "Edit" to the ⋯ menu, for comments and for replies.
Copy link copies
<page>?helldotsComment=<id>. Opening it anywhere the
comments are available opens the inbox on that comment's thread. There is no
redirect hop: the page a comment lives on is recorded on the comment, so the
link points straight at its destination.- The parameter stays in the URL, so the link can be reloaded or re-copied.
- The id is remembered and retried after every
loadComments(), so a link
works for hosts that fetch their comments from their own back end. - A link to a comment this page cannot show opens the inbox with a notice
rather than doing nothing. - Under
persistence: "localStorage"a link only works in the same browser —
there is no server to share through.
Edit replaces the body with an inline editor, in the thread popover and
in the inbox. The draft is held as panel state, so it survives everything
that re-renders the panel — changing a comment's status, priority or type, or
deleting a reply, no longer discards what you were typing. Cancel, Escape,
opening another editor, closing the panel and navigating between comments all
ask before dropping unsaved text; a click on the page leaves the panel open
instead of asking. Edited items carry a text "edited" mark with the exact
time on hover.New API:
editComment(id, text),editReply(commentId, replyId, text),
commentLink(id), thelinkParamoption, and theonCommentEdited/
onReplyEditedcallbacks.SerializedCommentandCommentReplygained an
optionaleditedAt.Fourteen new locale keys (
copyLink,linkCopied,editComment,
editReply,editorAriaLabel,editSave,editCancel,editedMark,
editedAtPrefix,confirmDiscardTitle,confirmDiscardMessage,
confirmDiscard,confirmKeepEditing,commentNotFound). Hosts passing a
customstringsobject need to add them. -
6b3efb2: Rework the inbox's empty state. Instead of a single line of grey text it now
shows the marker's outline, the comment shortcut spelled the way the user's
platform spells it (⌥ on Apple, Alt elsewhere — the same string the toolbar
tooltip shows), and a button that turns comment mode on.An inbox whose filters happen to match nothing is treated as a different
state: it names that cause and offers Clear, rather than teaching a shortcut
to someone who already has comments.Turning comment mode on now closes the inbox, so the panel stops covering the
page the user is being asked to click on. This applies to the keyboard
shortcut and the new button; turning the mode off leaves an open inbox alone.The
inboxEmptystring is replaced byinboxEmptyTitle,
inboxEmptyHintTemplate,inboxEmptyActionandinboxNoMatches. Only
consumers passing a customstringsobject are affected. -
9105193: Give comments and replies collision-free ids.
Ids were
Date.now(), so anything created inside the same millisecond shared
one. That is not a cosmetic problem:mergeForStoragededuplicates by id and
every lookup returns the first match, so a collision silently overwrites a
comment instead of failing. A programmatic import, or two people commenting
from different machines into a shared back end, is enough to trigger it.New ids are 21-character nanoid strings — URL-safe, so they can travel in a
link, and generated fromcrypto.getRandomValues, which works outside secure
contexts.CommentIdisstring | number. Comments already stored with numeric ids
keep resolving, anddeleteComment(123)still typechecks. Hosts that read
comment.idinto a variable typednumberneed to widen it.- nanoid is bundled into both artifacts rather than added as a runtime
dependency, so the package still installs on Node 18 and gains no new
dependencies. It costs ~130 B gzip.
-
e2d90cf: Overlay UI pass: card density, chip filters, richer tooltip and mobile fixes
- The per-comment action strip moved out of the header and onto its own row —
a footer on inbox cards (shared with the reply link) and a row under the
header in the thread popover. The author no longer wraps onto two lines in
the inbox or truncates mid-name in the popover. - The inbox filter is now a chip panel: page, status, type and priority are
all visible at once, with a clear button. Status, type and priority chips
toggle off to clear their group. - The status filter takes the real lifecycle values (
open,in_progress,
resolved) instead ofunresolved/resolved, soin_progressis
filterable. A comment with no stored status still matchesopen. - The hover tooltip now summarises status, type, priority, tags and
resolution time as badges instead of showing only the author and the text. - The marker whose thread is open is visibly marked as active, and clicking
it again closes the thread — it works as a toggle. Clicking a different
marker still switches threads. - The automatic context capture is reachable from the thread popover as a
collapsed disclosure, not only from the inbox detail. - The comment box's classification row lines up with the textarea, and its
type/priority controls are outlined. - The tags input was removed from the comment box. The
tagsfield,
setCommentTags()and the rendering of existing tags are unchanged. - The comment box, tooltip and thread popover are now
min(400px, calc(100vw - 24px))wide and clamp to the viewport, fixing the
horizontal overflow when creating or opening a comment on a phone. - The thread popover follows its marker while the page scrolls instead of
staying fixed on screen, and hides while the marker is off-screen — coming
back, with any half-typed reply intact, as soon as the marker returns. - The thread popover no longer grows past the viewport. Its body, context
block and replies scroll inside it while the header, the action strip and
the reply box stay pinned, so a long thread or an expanded context block is
actually reachable.
- The per-comment action strip moved out of the header and onto its own row —
-
453b71b: Make long threads usable: a scrollbar that matches the panel, a popover that
grows the right way, and a way to remove a single reply.- Scrollbars in the thread popover, the hover preview and both inbox panes
are now dark. They were rendering as the light platform default, because
Chromium ignores::-webkit-scrollbar-*rules on any element that also
setsscrollbar-width. - A thread popover that no longer fits below its marker anchors to the bottom
of the viewport, so new replies extend it upward instead of pushing the
reply box off screen. It goes back to sitting beside the marker as soon as
it fits again. - Sending a reply scrolls the thread to it, rather than leaving it below the
fold. - Each reply carries the same ⋯ menu as its comment, with a "Delete reply"
option. Available in the thread popover and in the inbox detail view. - New
deleteReply(commentId, replyId)method and matchingonReplyDeleted
callback, so hosts that persist comments themselves can mirror the change.
- Scrollbars in the thread popover, the hover preview and both inbox panes
Patch Changes
-
6e42c32: Stop comment anchors from capturing HellDots' own
comment-cursorclass.
That class is on<body>only while comment mode is active — exactly when
anchors are created — so a comment anchored on<body>was stored as
body.comment-cursorand its selector stopped matching as soon as the mode
ended, forcing every reload through the fuzzy fingerprint rescue path.
Anchors now store a plainbody. Existing comments are unaffected: they keep
resolving through the rescue path as they already did. -
f0d62b1: Fix the comment-mode cursor reverting to the default arrow near the edges of
the page. The image was 48x48, and Chromium drops custom cursors larger than
32x32 device-independent pixels once they can intersect native browser UI.
The canvas is now 32x32 with the artwork unchanged at 28px, so the cursor
looks identical and keeps its shape all the way to the edge. The blue drop
shadow is gone — it needed more margin than the smaller canvas allows; the
white outline that carries contrast is unchanged. -
6e42c32: Mark the on-page marker as active while its comment's detail is open in the
inbox, matching what already happens when the thread is opened from the
marker itself. Going back to the list, navigating to another comment, or
closing the inbox moves or clears the state. Comments with no marker on the
page — resolved, orphaned or hidden — are unaffected. -
6e42c32: Fix opening a comment from the inbox scrolling to an unrelated part of the
page. The scroll targeted the comment's anchor container, which falls back to
<body>whenever the commented element has nosection/container ancestor —
centring<body>lands halfway down the document. It now scrolls to the
marker's own position, derived from the anchor so it is correct even when the
marker's rendered coordinates have not been refreshed yet. -
6504703: Fix two overlay dismissal bugs
- Opening a screenshot in the lightbox no longer tears down the surface
behind it. The lightbox is mounted as a sibling of the inbox and the thread
popover, so their "the click landed outside me, close" rule used to read
every click on it — its own close button included — as a click away, and
closed the panel underneath. - The status, type and priority pickers (and the ⋯ menu, and the inbox
filter) now follow a single-open rule: opening one closes the others,
instead of leaving three menus stacked on top of each other in the thread
popover. Any click outside the open menu closes it too, and the toggles
reportaria-expanded.
- Opening a screenshot in the lightbox no longer tears down the surface