feat(composer): #channel-link autocomplete and clickable links (LC-323) #338
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/lc-323-channel-link-autocomplete"
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
#channel-link autocomplete: type#in the composer to autocomplete a room in the current enclave you can access; the chosen#nametoken renders as a clickable link to that room (/room/{id}), styled like a mention chip. A direct parallel to the existing@-mention and:emoji:autocomplete. Implements LC-323 / LC-324.How
GET /rooms/{id}/channel-complete?q=(access-gated like emoji-complete) returns a#lc-channel-popoverlistbox of accessible same-enclave rooms, prefix-ranked, capped at 8; rows carrydata-insert="#name". A composer JS block mirrors the emoji trigger (#-anchored regex,htmx.ajax, cursor insert).routes::channel_refs_for_room=enclave_for_room+list_rooms_in_enclave(already access-scoped: public, or private-and-member; admin sees all) filtered to the linkable charset. Empty for DMs / non-enclave rooms.MessageViewgains achannels: Vec<ChannelRef>(computed once per page/DM render, cloned per message; fetched per-render in the WS single-message paths).body_htmlcalls a newmarkdown::render_with_channels, which threads the channel set throughrender_inner/render_with_spoilers/math::render_math_in_textintorender_body. There the boundary-anchored@scan is generalized to(^|\s)([@#])([A-Za-z0-9_-]{1,64}); the#branch emits a/room/{id}link when the lowercased token resolves, else falls through to the literal-text pass.linkify_body/emojify_and_escapeare untouched, and#inside markdown link labels is deliberately not resolved (no nested anchors).markdown::renderdelegates with an empty channel set, so wiki / description / scheduled / edit-history render exactly as before. The channel set is folded intomarkdown_cache_key, so a cached body never serves a stale link across enclaves.Scope / assumptions
[A-Za-z0-9_-]{1,64}, matched case-insensitively. Rooms with spaces / other characters are not#-linkable in v1, so the autocomplete only offers names that match (a user is never offered a#namethat won't render).#tokenrenders as plain text (no leak about rooms the viewer can't see).Testing
just check(clippy standalone + saas, fmt) clean.just testandjust test-saasgreen. Newviews::roomunit tests cover#name-> link, case-insensitive match with canonical-name display, unknown token literal, empty-channel-set literal, and mid-word non-match. Newroutes_channel_complete.rscovers prefix match, empty-query listing, the non-linkable-name filter, the access-gated 403, and the non-enclave-room empty case.Operator impact
None. No new env var, config, or contract change; no
[operator-action]marker.🤖 Generated with Claude Code
Type # in the composer to autocomplete a room in the current enclave that you can access; the chosen #name token renders as a clickable link to that room. A direct parallel to the existing @-mention and :emoji: autocomplete. The render integration folds into the single author-render pipeline: a new `markdown::render_with_channels` threads a channel set through render_inner / render_with_spoilers / math into `render_body`, whose boundary-anchored @ scan is generalized to `(^|\s)([@#])([A-Za-z0-9_-]{1,64})`. The # branch resolves the token (lowercased) against the message's same-enclave room map and emits a /room/{id} link; unresolved or inaccessible tokens stay literal text. The 3-arg `markdown::render` is unchanged (delegates with an empty channel set) so wiki / description / scheduled / edit-history are untouched, and the channel set keys the markdown cache so a body never serves a stale link across enclaves. `#name` is intra-enclave (names are unique per enclave); DMs and non-enclave rooms resolve nothing. A channel token is the linkable charset `[A-Za-z0-9_-]{1,64}`, so the autocomplete only offers rooms whose names fully match it (insertion and render stay consistent). Resolution and autocomplete both honor `list_rooms_in_enclave` access scoping. en/es parity. #LC-323 #LC-324 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>