monal-rebuild/tsconfig.json
pijukka 66a374ef1e feat(chat): emoji reactions (XEP-0444)
Give, withdraw, receive and group reactions by emoji, in 1:1 chats and in
rooms, surviving a reload out of the server's archive.

Addressing is the question quoted replies already answered, so `replyId()`
owns it for both: the origin id in 1:1, the room-issued stanza id in a
room. The set is full state, never a delta. Reactions live in their own
store keyed by the reacted-to message's stable id, because one can arrive
before the message it points at; an older copy never replaces a newer one.
`parseMessage` discards bodiless stanzas, so the receive path parses them
separately, and a reaction never touches a conversation's unread count or
preview: it is not a message. `mod_mam` has no reactions branch, so the
`<store/>` hint is what makes them survive at all.

Reactions go out in cleartext even in an encrypted chat, and the picker
says so where the reaction is given. The client has no XEP-0420 envelope,
so nothing can ride inside the ciphertext; this is a named exception and
the fail-closed rule stays in force for everything carrying content.
Decided by the operator, REACTIONS-PLAN.md §4.

Monal 6.4.21 has no XEP-0444 and drops a bodiless message before it can
become a bubble or a notification, so this is 0ff chat to 0ff chat for now
and costs the phone nothing. Read from its source, §5.

Checks: zero svelte-check errors, 93 tests, production build, and
ux-reactions-runner.cjs 11/11 with zero page errors under both Chromium
and WebKit against the built preview and the real server — including the
account's own MAM archive and the room's. Evidence and the two
own-reaction bugs the room checks found: UX-REACTIONS-RESULTS.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-08 19:58:03 +02:00

18 lines
612 B
JSON

{
"extends": "@tsconfig/svelte/tsconfig.json",
"compilerOptions": {
"target": "ES2020",
// ES2022.Intl adds Intl.Segmenter, which counts the graphemes a single
// emoji reaction may consist of (src/xmpp/reactions.ts). The rest is
// what target ES2020 implies on its own.
"lib": ["ES2020", "ES2022.Intl", "DOM", "DOM.Iterable"],
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"noEmit": true,
"allowImportingTsExtensions": true,
"skipLibCheck": true,
"types": ["svelte", "vite/client"]
},
"include": ["src/**/*.ts", "src/**/*.svelte"]
}