Private
Public Access
Add custom emoji support (#18)
Site-wide, any user can upload -- usable both as reactions and inline in message text via :shortcode:, alongside the existing built-in Unicode picker. A :shortcode: reference is stored/sent as literal text (same as the built-in shortcode convention) and resolved to an image at render time, so it degrades to plain text if the emoji is later deleted. Backend: new custom_emoji table (shortcode unique, sized to fit MessageReaction.emoji's existing column alongside its colons), upload/ list/delete endpoints (delete restricted to uploader or site admin). Frontend: a CustomEmojiProvider context feeds a new "Custom" category in the emoji picker (inline upload + hover-to-remove), extends the composer's shortcode autocomplete, and a shared EmojiGlyph resolver renders custom emoji wherever a value can appear -- message text, reaction pills, and the picker itself. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b26643527d
commit
2e84ca42b7
23 files changed
+1056
-28
No files matched your search
@@ -69,6 +69,26 @@
|
||||
padding: 4px 4px 2px;
|
||||
}
|
||||
|
||||
.emoji-picker-category-label-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.emoji-picker-add-custom {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: var(--ds-accent);
|
||||
font-size: 0.7rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
padding: 2px 4px;
|
||||
}
|
||||
|
||||
.emoji-picker-add-custom:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.emoji-picker-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(9, 1fr);
|
||||
@@ -89,6 +109,32 @@
|
||||
background: var(--ds-surface-2);
|
||||
}
|
||||
|
||||
.emoji-picker-item-custom {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.emoji-picker-item-remove {
|
||||
position: absolute;
|
||||
top: -2px;
|
||||
right: -2px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 50%;
|
||||
background: var(--ds-danger);
|
||||
color: white;
|
||||
font-size: 0.65rem;
|
||||
line-height: 1;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.emoji-picker-item-custom:hover .emoji-picker-item-remove {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* The picker is positioned absolutely relative to its trigger button, which
|
||||
can sit close enough to a narrow viewport's edge that the full 320px
|
||||
width runs off-screen (e.g. the composer's emoji trigger, near the left
|
||||
|
||||
Reference in new issue
Block a user