feat(expressions): custom emojis and stickers per space
Emojis and stickers get separate tables on purpose: an emoji sits inside a sentence and a sticker is the whole message, so their sizes, limits and render paths differ. Emoji names are unique per space and restricted to letters, digits and underscore — :name: has to resolve to one image, and a space or colon inside the name would make the reference impossible to delimit. Sticker names are labels picked from a grid, so they accept anything. Rendering reuses the existing markdown pipeline by rewriting :name: into image syntax, which needs no plugin. Code spans and fences are left alone: text someone wrapped in backticks was meant to be shown literally, and turning it into an image would destroy what they wrote. Messages carry stickerId with ON DELETE set null — removing a sticker from the space must not delete the history of everyone who used it. The server refuses a sticker from another space, which would otherwise leak images between unrelated servers. Expressions load once per space and stay in memory: the message renderer consults the map for every :name: it finds, and a request per lookup would turn each message into a cascade. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { useExpressionStore } from '../../stores/expressionStore';
|
||||
import { useParams, useNavigate } from 'react-router-dom';
|
||||
import { SpaceSidebar } from './SpaceSidebar';
|
||||
import { ChannelSidebar } from './ChannelSidebar';
|
||||
@@ -217,6 +218,15 @@ export function AppLayout() {
|
||||
const setCurrentSpace = useSpaceStore((s) => s.setCurrentSpace);
|
||||
const loadSpaceDetail = useSpaceStore((s) => s.loadSpaceDetail);
|
||||
useSpotifyActivity();
|
||||
|
||||
// Emojis e figurinhas do espaço atual, carregados uma vez por espaço: o
|
||||
// render de mensagem consulta o mapa a cada `:nome:`, e buscar por mensagem
|
||||
// viraria uma cascata de requisições.
|
||||
const expressionSpaceId = useSpaceStore((s) => s.currentSpaceId);
|
||||
const loadExpressions = useExpressionStore((s) => s.load);
|
||||
useEffect(() => {
|
||||
if (expressionSpaceId) void loadExpressions(expressionSpaceId);
|
||||
}, [expressionSpaceId, loadExpressions]);
|
||||
const setCurrentChannel = useChatStore((s) => s.setCurrentChannel);
|
||||
const loadMessages = useChatStore((s) => s.loadMessages);
|
||||
const setIsMobile = useUIStore((s) => s.setIsMobile);
|
||||
|
||||
Reference in New Issue
Block a user