feat(composer): emoji :shortcode: autocomplete (LC-296) #326

Merged
longjacksonle merged 1 commit from feat/lc-296-emoji-autocomplete into main 2026-06-14 22:04:18 +02:00

Summary

Emoji :shortcode: autocomplete in the composer: type :tada to pick an emoji inline. Third autocomplete alongside @mention and /slash, built on the same combobox pattern.

Changes

  • server/Cargo.toml: add emojis = "0.6" (embeds the Unicode emoji set with shortcodes + names; no runtime fetch).
  • server/src/routes/emoji_complete.rs (new): GET /rooms/{id}/emoji-complete?q=, auth + is_room_accessible gated. Custom emoji matches (room enclave, prefix-first) before Unicode matches, capped at 8. A bare : returns custom emojis only.
  • server/src/views/emoji_complete.rs + server/templates/partials/emoji_popover.html (new): the listbox fragment. Custom rows carry data-insert=":shortcode:" and an <img> preview; Unicode rows carry data-insert="<glyph>" + name.
  • server/src/routes/mod.rs, server/src/views/mod.rs: register module + route.
  • server/templates/room/composer.html: #lc-emoji-popover slot + the : autocomplete IIFE (mirror of the mention block: 200ms debounce, ARIA combobox keyboard nav, form-swap teardown). Both Enter-to-send guards now also defer to the emoji popover. The : trigger only fires after start-of-line or whitespace, so URLs / times never open it.

Custom emojis insert a :shortcode: token (rendered to an <img> by the existing markdown pipeline); Unicode emojis insert the literal glyph (plain text, no renderer change).

Testing

  • just check, just fmt, just test, just test-saas all pass.
  • New server/tests/routes_emoji_complete.rs: Unicode shortcode-prefix match returns the glyph; a seeded custom emoji is offered with its :shortcode: insert token + img preview; a bare : lists custom only (no Unicode dump); non-member is 403.

Not operator-visible (the new crate dependency is internal; no env/config/contract change).

## Summary Emoji `:shortcode:` autocomplete in the composer: type `:tada` to pick an emoji inline. Third autocomplete alongside @mention and /slash, built on the same combobox pattern. ## Changes - `server/Cargo.toml`: add `emojis = "0.6"` (embeds the Unicode emoji set with shortcodes + names; no runtime fetch). - `server/src/routes/emoji_complete.rs` (new): `GET /rooms/{id}/emoji-complete?q=`, auth + `is_room_accessible` gated. Custom emoji matches (room enclave, prefix-first) before Unicode matches, capped at 8. A bare `:` returns custom emojis only. - `server/src/views/emoji_complete.rs` + `server/templates/partials/emoji_popover.html` (new): the listbox fragment. Custom rows carry `data-insert=":shortcode:"` and an `<img>` preview; Unicode rows carry `data-insert="<glyph>"` + name. - `server/src/routes/mod.rs`, `server/src/views/mod.rs`: register module + route. - `server/templates/room/composer.html`: `#lc-emoji-popover` slot + the `:` autocomplete IIFE (mirror of the mention block: 200ms debounce, ARIA combobox keyboard nav, form-swap teardown). Both Enter-to-send guards now also defer to the emoji popover. The `:` trigger only fires after start-of-line or whitespace, so URLs / times never open it. Custom emojis insert a `:shortcode:` token (rendered to an `<img>` by the existing markdown pipeline); Unicode emojis insert the literal glyph (plain text, no renderer change). ## Testing - `just check`, `just fmt`, `just test`, `just test-saas` all pass. - New `server/tests/routes_emoji_complete.rs`: Unicode shortcode-prefix match returns the glyph; a seeded custom emoji is offered with its `:shortcode:` insert token + img preview; a bare `:` lists custom only (no Unicode dump); non-member is 403. Not operator-visible (the new crate dependency is internal; no env/config/contract change).
feat(composer): emoji :shortcode: autocomplete (LC-296)
All checks were successful
check-secrets / Nosey parker (push) Successful in 4s
check-secrets / TruffleHog (push) Successful in 4s
check-secrets / Kingfisher (push) Successful in 6s
check-secrets / Nosey parker (pull_request) Successful in 3s
check-secrets / TruffleHog (pull_request) Successful in 5s
check-secrets / Kingfisher (pull_request) Successful in 7s
Create release / Create release from merged PR (pull_request) Has been skipped
Check / clippy + fmt + tests (pull_request) Successful in 3m44s
efbd24e33e
Typing `:` plus a prefix in the composer now opens an inline picker of matching emojis, the third autocomplete alongside @mention and /slash and built on the same combobox pattern.

A new GET /rooms/{id}/emoji-complete endpoint (auth + room-access gated, mirroring /users/mentions) returns a listbox fragment: the room enclave's custom emojis whose shortcode matches first, then Unicode emojis from the `emojis` crate. A bare `:` surfaces just the room's custom set so the list is never the full Unicode dump. Choosing a row inserts a `:shortcode:` token for a custom emoji (the markdown pipeline already renders it to an <img>) or the literal glyph for a Unicode emoji (plain text, no renderer change). The composer's `:` block mirrors the mention popover: 200ms debounce, ARIA combobox keyboard nav, form-swap teardown, and the two Enter-to-send guards now also defer to the emoji popover.

The `:` trigger only fires after start-of-line or whitespace, so URLs (http://) and times (10:30) never open it.

#LC-296
#LC-297

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
longjacksonle deleted branch feat/lc-296-emoji-autocomplete 2026-06-14 22:04:18 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/lets-chat!326
No description provided.