mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 21:45:31 +09:00
fix(app): use +:shortcode: for reactions, no space before emoji (#3001)
This commit is contained in:
1 parent
5b280898c5
commit
f6df3169ca
6 files changed
+68
-39
No files matched your search
@@ -465,7 +465,7 @@ export const useTextareaSubmit = ({
|
||||
const replaceCommand = ReplaceCommandUtils.parseReplaceCommand(actualContent);
|
||||
const reactionShorthand =
|
||||
editingMessage === null && uploadAttachmentsLength === 0 && !hasPendingSticker
|
||||
? parseReactionShorthand(resolvedContent)
|
||||
? parseReactionShorthand(actualContent, Channels.getChannel(channelId) ?? null, guildId, i18n)
|
||||
: null;
|
||||
const reactionTargetId = reactionShorthand === null ? null : getReactionShorthandTargetId(channelId);
|
||||
if (reactionShorthand !== null && reactionTargetId !== null) {
|
||||
|
||||
@@ -1,34 +1,54 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import type {Channel} from '@app/features/channel/models/Channel';
|
||||
import type {FlatEmoji} from '@app/features/emoji/types/EmojiTypes';
|
||||
import {getSkinTonedSurrogate} from '@app/features/expressions/utils/SkinToneUtils';
|
||||
import UnicodeEmojis from '@app/features/expressions/utils/UnicodeEmojis';
|
||||
import MessageReply from '@app/features/messaging/state/MessageReply';
|
||||
import Messages from '@app/features/messaging/state/MessagingMessages';
|
||||
import {type ReactionEmoji, toReactionEmoji} from '@app/features/messaging/utils/MessageReactionUtils';
|
||||
import type {ReactionEmoji} from '@app/features/messaging/utils/MessageReactionUtils';
|
||||
import {resolveTypedEmojiToken} from '@app/features/messaging/utils/TypedEmojiShortcodeUtils';
|
||||
import type {I18n} from '@lingui/core';
|
||||
|
||||
const REACTION_SHORTHAND_PATTERN = /^\+(\S+)$/u;
|
||||
const CUSTOM_EMOJI_MARKDOWN_PATTERN = /^<(a)?:([a-zA-Z0-9_+-]{2,}):(\d+)>$/;
|
||||
const SHORTCODE_PATTERN = /^:([^\s:]+):$/;
|
||||
const REACTION_SHORTHAND_PATTERN = /^\s*\+:([^\s:]+(?:::skin-tone-[1-5])?):\s*$/u;
|
||||
const REACTION_SHORTHAND_PREFIX_PATTERN = /^\s*\+$/;
|
||||
|
||||
export function parseReactionShorthand(content: string): ReactionEmoji | null {
|
||||
const match = REACTION_SHORTHAND_PATTERN.exec(content.trim());
|
||||
export function isReactionShorthandText(text: string): boolean {
|
||||
return REACTION_SHORTHAND_PATTERN.test(text);
|
||||
}
|
||||
|
||||
export function isReactionShorthandPrefix(textBefore: string, textAfter: string): boolean {
|
||||
return REACTION_SHORTHAND_PREFIX_PATTERN.test(textBefore) && textAfter.trim() === '';
|
||||
}
|
||||
|
||||
export function getReactionShortcodeName(emoji: FlatEmoji): string {
|
||||
if (emoji.id) {
|
||||
return emoji.name;
|
||||
}
|
||||
const name = UnicodeEmojis.nameForSurrogate(getSkinTonedSurrogate(emoji), false);
|
||||
return name === '' ? emoji.name : name;
|
||||
}
|
||||
|
||||
export function parseReactionShorthand(
|
||||
content: string,
|
||||
channel: Channel | null,
|
||||
guildId: string | null,
|
||||
i18n: I18n,
|
||||
): ReactionEmoji | null {
|
||||
const match = REACTION_SHORTHAND_PATTERN.exec(content);
|
||||
if (match === null) {
|
||||
return null;
|
||||
}
|
||||
const token = match[1];
|
||||
const customMatch = CUSTOM_EMOJI_MARKDOWN_PATTERN.exec(token);
|
||||
if (customMatch !== null) {
|
||||
return {id: customMatch[3], name: customMatch[2], animated: customMatch[1] === 'a'};
|
||||
const shortcodeName = match[1];
|
||||
const unicodeEmoji = UnicodeEmojis.findEmojiByShortcodeName(shortcodeName);
|
||||
if (unicodeEmoji !== null) {
|
||||
return {name: unicodeEmoji.surrogates};
|
||||
}
|
||||
const shortcodeMatch = SHORTCODE_PATTERN.exec(token);
|
||||
if (shortcodeMatch !== null) {
|
||||
const emoji = UnicodeEmojis.findEmojiByShortcodeName(shortcodeMatch[1]);
|
||||
return emoji === null ? null : toReactionEmoji(emoji);
|
||||
}
|
||||
const name = UnicodeEmojis.nameForSurrogate(token, false);
|
||||
if (name === '') {
|
||||
const resolved = resolveTypedEmojiToken(shortcodeName, channel, guildId, i18n);
|
||||
if (resolved === null || resolved.kind !== 'custom') {
|
||||
return null;
|
||||
}
|
||||
return {name: UnicodeEmojis.surrogateForName(name, token)};
|
||||
return {id: resolved.emojiId, name: shortcodeName.replace(/~\d+$/, ''), animated: resolved.animated};
|
||||
}
|
||||
|
||||
export function getReactionShorthandTargetId(channelId: string): string | null {
|
||||
|
||||
Reference in new issue
Block a user