fix: don't highlight against a malformed address, gate the listener

Per a "needs a closer look" review pass:
- articles/index.tsx now passes an empty string, not a malformed
  "kind:pubkey:" address, when an article has no d tag. HighlightLayer
  treats a falsy address as "highlighting isn't available here."
- The selectionchange listener is only registered when both user and
  address are present (in the effect's deps), instead of always
  running selection tracking regardless of whether a highlight could
  ever be published.
- handleHighlight and the floating button both guard on address too,
  not just selection, so stale selection state from before a prop
  change went missing can't still trigger a publish.
- docs/apps.md corrected: the saved text comes from Selection.toString()
  (window.getSelection()), not Range.toString().

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BYiUtZMQeA5RHggQw73wto
This commit is contained in:
2026-09-06 18:27:13 +02:00
parent 3d77b0516c
commit 7c9eec8c82
3 changed files with 15 additions and 6 deletions

View File

@@ -105,8 +105,8 @@ export default function ExampleApp({ setTitle }: AppProps) {
`HighlightLayer` (`src/apps/articles/HighlightLayer.tsx`) tracks `window.getSelection()`
against the rendered article, not the raw markdown — the highlighted text saved to a kind
9802 event is whatever `Range.toString()` returns, i.e. the plain-text content the reader
actually saw, not markdown syntax.
9802 event is whatever that `Selection`'s `.toString()` returns, i.e. the plain-text content
the reader actually saw, not markdown syntax.
### Follow lists are a whole-list replacement