feat(expressions): pickers and upload for emojis and stickers

Completes the feature: the tables existed but nothing could be put in them.

Space settings gain an Emojis & Stickers panel behind MANAGE_SPACE, with a
512KB ceiling — both are fetched on every message that uses them, so weight
matters more than fidelity. The suggested name is pre-normalised so the common
case needs no typing, and a name collision reports itself distinctly from an
upload failure: the corrective action is different.

Custom emojis join the emoji picker as their own category. They have no native
character, so selecting one inserts :name: — the same text the renderer
resolves back to an image, which also means copying a message yields something
that still reads.

Stickers get a picker tab that only appears inside a space, since that is where
they exist, and send immediately on click: a sticker is the whole message, so
parking it in the composer to await Enter would make no sense.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-01 18:25:10 -03:00
co-authored by Claude Opus 5
parent 7d003021d1
commit 7f08384372
10 changed files with 392 additions and 12 deletions
+20
View File
@@ -55,6 +55,26 @@ export const ptBR: Partial<Dictionary> = {
'accountMenu.copyId': 'Copiar ID do usuário',
'accountMenu.copied': 'Copiado',
// Emojis e figurinhas
'expressions.title': 'Emojis e figurinhas',
'expressions.emojis': 'Emojis',
'expressions.stickers': 'Figurinhas',
'expressions.addEmoji': 'Adicionar emoji',
'expressions.addSticker': 'Adicionar figurinha',
'expressions.emptyEmojis': 'Nenhum emoji próprio ainda.',
'expressions.emptyStickers': 'Nenhuma figurinha ainda.',
'expressions.namePrompt': 'Nome',
'expressions.nameHintEmoji': 'Letras, números e sublinhado. Usado como :nome: nas mensagens.',
'expressions.confirm': 'Adicionar',
'expressions.cancel': 'Cancelar',
'expressions.remove': 'Remover',
'expressions.tooLarge': 'A imagem precisa ter menos de 512 KB.',
'expressions.uploadFailed': 'Não foi possível adicionar essa imagem. Tente outra.',
'expressions.nameTaken': 'Esse nome já está em uso neste servidor.',
'expressions.uploading': 'Enviando…',
'expressions.pickerTitle': 'Figurinhas',
'expressions.pickerEmpty': 'Este servidor ainda não tem figurinhas.',
// Busca
'search.placeholder': 'Buscar mensagens…',
'search.filters': 'Filtros',