Skip to content

Fix @mention styling inside bold/italic + 3 audit loose ends (#55 follow-up) - #57

Merged
Aztec03hub merged 1 commit into
mainfrom
fix/mention-emphasis-and-audit-loose-ends
Jun 26, 2026
Merged

Fix @mention styling inside bold/italic + 3 audit loose ends (#55 follow-up)#57
Aztec03hub merged 1 commit into
mainfrom
fix/mention-emphasis-and-audit-loose-ends

Conversation

@Aztec03hub

Copy link
Copy Markdown
Owner

Primary bug — @mentions inside bold/italic lose mention styling

In the message feed, an @mention in plain text rendered as a gold mention pill, but an @mention inside **bold** / *italic* / ~~strike~~ rendered with the emphasis styling but without the mention color/pill.

Root cause: MessageBubble.parseBody emitted bold/italic/strike tokens (from parseRich) whose inner value was raw text that was never run through the mention/link splitter. Only top-level text tokens got the parseMentions + URL pass, so any @name wrapped in emphasis was rendered as plain emphasized text.

Fix:

  • Extracted the mention + link classification (self/other/broadcast/legacy + URL split + coalesce) into a shared splitTextToSegments helper inside parseBody.
  • Emphasis tokens now carry children: splitTextToSegments(value), rendered inside the <strong>/<em>/strike wrapper via a recursive renderSeg snippet — so a nested mention/link inherits the emphasis styling and gets its own chip/link styling.
  • Code spans (inline-code / block-code) are emitted as their own tokens and pushed literally, so an @name inside backtick code stays literal and is never linkified (XSS-safe; no new {@html} path; DOMPurify untouched).
  • hasSelfMention now recurses into emphasis children so a self-mention inside emphasis still paints the bubble border accent.

Secondary — 3 audit loose ends

  1. ChannelModal isPrivate wired end-to-end. App.sveltestore.createChannel(id, topic, isPrivate). The backend create API (comms_conversation_create) takes no visibility argument, so createChannel sets the local row + retained meta broadcast to private and persists it through the admin path (setVisibilitycomms_conversation_update), mirroring ChannelAdminPanel. #handleMeta now reads visibility back from the meta broadcast (was hardcoded public). No longer a silently-inert toggle.
  2. Compare-version dropdown outside-click close. Added a <svelte:window onmousedown> guard in ArtifactDetailHeader.svelte for the Compare dropdown (its open state is local to the header), mirroring ArtifactPanel's primary-dropdown pattern.
  3. safeStorage DRY. The two byte-identical copies (mqtt-store.svelte.js + resizable-panel.svelte.js) are folded into a shared web/src/lib/safe-storage.js; both now import it.

Tests

  • message-bubble-mention-emphasis.spec.js (new): bold **@alice**, italic *@bob*, strike ~~@carol~~, plain @carol all render a .mention chip; @dave inside backtick code does not; mixed bold+plain.
  • mqtt-store-admin-actions.spec.js (+3): private create sets local private + fires comms_conversation_update visibility; public create does not; private create while disconnected queues the admin action.
  • artifact-compare-dropdown-outside-click.spec.js (new): outside mousedown closes, inside mousedown keeps open.
  • channel-modal-wires.spec.js: updated the create assertion to the 3-arg signature ('phoenix', '', false).

Counts: 1314 → 1325 tests, 97 → 99 files, 0 skips. Full suite green (run 2×, no flakiness, no stderr noise). pnpm build green. e2e source-level invariants: 55 passed.

…low-up)

PRIMARY: @mentions inside inline emphasis lost their mention styling.
MessageBubble.parseBody emitted bold/italic/strike tokens whose inner
`value` was raw text never run through the mention/link splitter, so an
@mention in **bold** or *italic* rendered with emphasis styling but no
mention pill/color. Extract the mention+link classification into a shared
`splitTextToSegments` helper, run it over emphasis inner values, and
render the resulting children INSIDE the emphasis wrapper via a recursive
`renderSeg` snippet — mentions/links now inherit emphasis styling AND get
their own chip/link styling. Code spans stay literal (never linkified).
`hasSelfMention` now recurses into emphasis children for the border accent.

SECONDARY (audit follow-ups):
- ChannelModal isPrivate wired end-to-end: App -> store.createChannel(id,
  topic, isPrivate). The create API takes no visibility arg, so createChannel
  sets the local row + retained meta to private AND persists via the admin
  path (setVisibility -> comms_conversation_update), mirroring
  ChannelAdminPanel. #handleMeta now reads visibility from the broadcast.
- ArtifactDetailHeader Compare dropdown closes on outside mousedown via a
  <svelte:window> guard, mirroring ArtifactPanel's primary-dropdown pattern.
- safeStorage DRY: extracted the byte-identical copies from mqtt-store and
  resizable-panel into a shared web/src/lib/safe-storage.js.

Tests: +11 (bold/italic/strike/plain mention chips + code-not-linkified;
createChannel private/public/queued; compare-dropdown outside-click).
1314 -> 1325 tests, all green; build green.
@Aztec03hub
Aztec03hub merged commit b5a9e9c into main Jun 26, 2026
8 checks passed
@Aztec03hub
Aztec03hub deleted the fix/mention-emphasis-and-audit-loose-ends branch June 26, 2026 20:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant