Skip to content

[2.x] feat(realtime): ambient typing dots on the index sidebar tag list - #4756

Merged
imorland merged 2 commits into
2.xfrom
im/realtime-tag-list-typing
Jun 17, 2026
Merged

[2.x] feat(realtime): ambient typing dots on the index sidebar tag list#4756
imorland merged 2 commits into
2.xfrom
im/realtime-tag-list-typing

Conversation

@imorland

@imorland imorland commented Jun 17, 2026

Copy link
Copy Markdown
Member

Extends the discussion-list ambient typing indicator (#4731) to the index sidebar tag list: a tag lights up with a presence-only dot while someone is typing in a discussion carrying it — including someone composing a new discussion in it.

Builds on #4755 (merged), which added the linkItems extension seam to TagLinkButton.

Backend (IndexTypingPresence)

  • The index-typing broadcast now carries the tag IDs a typing discussion belongs to, scoped per channel so a restricted tag is never disclosed to an audience that can't see it: the public channel carries a guest-visible discussion's tags; each restricted-tag channel carries only its own tag.
  • touchTags() — new-discussion compose typing. There's no discussion id yet, so the client sends its selected tag IDs on its own private-user={id} channel. The user id is taken from the (already-authorised) channel name — never the payload — and every claimed tag is re-authorised against that actor before broadcasting, so a client can't light up (and thus disclose activity in) a restricted tag it can't see.
  • While typing continues, the rising edge is re-broadcast every REFRESH_MS so the dot doesn't self-clear mid-typing (the frontend TTL would otherwise lapse between coalesced bursts). Falling edge on TTL expiry, as before.

Frontend

  • IndexTagTypingState — tag-keyed presence, keyed per source (discussion id, or a per-user compose key) so concurrent typers in one tag don't clear each other's dot.
  • TagLinkButton renders the dot via its linkItems ItemList (the [2.x] refactor(tags): convert TagLinkButton to TSX with an extensible linkItems list #4755 seam).
  • The restricted-tag channel subscriptions now come from a server-computed forum attribute (index-typing-tags) listing the restricted tags the actor can see, replacing the per-visible-tag subscribe loop — this drops the websocket-auth requests on page load from one-per-tag to one-per-visible-restricted-tag.

Reuses the existing index-typing channels, subscriptions and dot styling. No new admin settings — the existing public / restricted index-typing toggles gate it.

Testing

  • yarn check-typings, yarn build (realtime): clean.
  • PHP: unit 34, integration 34 — including new coverage for per-channel tag scoping, the compose-typing leak guard (a claimed-but-hidden restricted tag produces zero broadcasts), the index-typing-tags forum attribute per actor, and the rising-edge refresh/coalesce timing.
  • Manually verified on a running 2.x install: dots appear/clear for replies and new-discussion composing, on both public and (visible) restricted tags, with no leak to users who can't see a tag.

imorland and others added 2 commits June 18, 2026 00:11
Extend the discussion-list ambient typing indicator to the tag list: a tag
lights up while someone is typing in a discussion carrying it, or composing
a new discussion in it.

Backend (IndexTypingPresence):
- The index-typing broadcast now carries the tag IDs a typing discussion
  belongs to, scoped per channel so a restricted tag is never disclosed to an
  audience that can't see it (public channel → guest-visible tags; each
  restricted-tag channel → only its own tag).
- touchTags(): new-discussion compose typing. There's no discussion id yet, so
  the client sends the selected tag IDs on its own private-user channel; the
  user id comes from the (authorised) channel name and every claimed tag is
  re-authorised against that actor before broadcasting — a client can't light
  up a restricted tag it can't see.
- While typing continues, the rising edge is re-broadcast every REFRESH_MS so
  the dot doesn't self-clear mid-typing (the frontend TTL would otherwise
  expire between coalesced bursts). Falling edge on TTL expiry as before.

Frontend:
- IndexTagTypingState: tag-keyed presence, keyed per source (discussion id or
  per-user compose key) so concurrent typers in one tag don't clear each
  other's dot.
- TagLinkButton renders the dot via its linkItems ItemList (the seam added in
  the prior tags refactor).
- The restricted-tag channel subscriptions now come from a server-computed
  forum attribute (index-typing-tags) listing the restricted tags the actor
  can see, replacing the per-visible-tag subscribe loop — one auth round-trip
  per visible restricted tag instead of one per tag.

Reuses the existing index-typing channels, subscriptions and dot styling; no
new admin settings (the existing public/restricted toggles gate it).
@imorland imorland changed the title feat(realtime): ambient typing dots on the index sidebar tag list [2.x] feat(realtime): ambient typing dots on the index sidebar tag list Jun 17, 2026
@imorland imorland added this to the 2.0.0-rc.4 milestone Jun 17, 2026
@imorland
imorland marked this pull request as ready for review June 17, 2026 23:23
@imorland
imorland requested a review from a team as a code owner June 17, 2026 23:23
@imorland
imorland merged commit 63f302e into 2.x Jun 17, 2026
25 checks passed
@imorland
imorland deleted the im/realtime-tag-list-typing branch June 17, 2026 23:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants