mirror of
https://github.com/outline/outline.git
synced 2026-06-13 11:25:03 +03:00
feat: Emoji reaction shorthand (#12650)
* Add "+:emoji:" reaction shorthand to comment form Typing a comment that consists solely of a leading "+" followed by a single emoji now adds that emoji as a reaction to the comment above, instead of posting a new reply — mirroring the Slack shorthand. https://claude.ai/code/session_01RSiUiEFLBaRF6YBfPNPiX6 * Move parseReactionShorthand into editor/lib/emoji https://claude.ai/code/session_01RSiUiEFLBaRF6YBfPNPiX6 * Open emoji menu when colon is preceded by a plus The suggestion menu's trigger boundary excluded "+", so typing "+:" never opened the emoji menu — preventing the "+:emoji:" reaction shorthand from being typed. Add a configurable `precededBy` option to the Suggestion extension and set it to "+" for the emoji menu. https://claude.ai/code/session_01RSiUiEFLBaRF6YBfPNPiX6 * Always allow "+" before suggestion trigger Simplify by adding "+" to the trigger boundary for all suggestion menus rather than making it a per-menu option. This lets the "+:emoji:" reaction shorthand open the emoji menu. https://claude.ai/code/session_01RSiUiEFLBaRF6YBfPNPiX6 --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -46,7 +46,7 @@ export default class Suggestion<
|
||||
: `(?:${triggers.map(escapeRegExp).join("|")})`;
|
||||
|
||||
this.openRegex = new RegExp(
|
||||
`(?:^|\\s|\\(|[\\p{Script=Han}\\p{Script=Hiragana}\\p{Script=Katakana}\\p{Script=Hangul}])${triggerPattern}(${`[\\p{L}/\\p{M}\\d${
|
||||
`(?:^|\\s|\\(|\\+|[\\p{Script=Han}\\p{Script=Hiragana}\\p{Script=Katakana}\\p{Script=Hangul}])${triggerPattern}(${`[\\p{L}/\\p{M}\\d${
|
||||
this.options.allowSpaces ? "\\s{1}" : ""
|
||||
}\\.\\-–_]+`})${this.options.requireSearchTerm ? "" : "?"}$`,
|
||||
"u"
|
||||
|
||||
@@ -8,6 +8,7 @@ import * as React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { toast } from "sonner";
|
||||
import { useTheme } from "styled-components";
|
||||
import { parseReactionShorthand } from "@shared/editor/lib/emoji";
|
||||
import type { ProsemirrorData } from "@shared/types";
|
||||
import { getEventFiles } from "@shared/utils/files";
|
||||
import { AttachmentValidation, CommentValidation } from "@shared/validations";
|
||||
@@ -157,6 +158,30 @@ function CommentForm({
|
||||
return;
|
||||
}
|
||||
|
||||
// "+:emoji:" shorthand: react to the comment above instead of replying.
|
||||
if (thread && !thread.isNew) {
|
||||
const emoji = parseReactionShorthand(draft);
|
||||
if (emoji) {
|
||||
const target = comments
|
||||
.inThread(thread.id)
|
||||
.filter((comment) => !comment.isNew)
|
||||
.pop();
|
||||
|
||||
if (target) {
|
||||
onSaveDraft(undefined);
|
||||
setForceRender((s) => ++s);
|
||||
void target.addReaction({ emoji, user });
|
||||
onSubmit?.();
|
||||
|
||||
// re-focus the comment editor
|
||||
setTimeout(() => {
|
||||
editorRef.current?.focusAtStart();
|
||||
}, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const commentDraft = draft;
|
||||
onSaveDraft(undefined);
|
||||
setForceRender((s) => ++s);
|
||||
|
||||
Reference in New Issue
Block a user