fix(app): resolve custom emoji before gating the edit length (#1999)

This commit is contained in:
Hampus authored and GitHub committed 2026-08-25 12:56:39 +02:00
1 parent 44ecd928f0
commit 9f5a5b16d3
2 files changed
+11 -16

No files matched your search

@@ -23,6 +23,7 @@ import MessageEdit from '@app/features/messaging/state/MessageEdit';
import {applyMarkdownSegments} from '@app/features/messaging/utils/MarkdownToSegmentUtils'; import {applyMarkdownSegments} from '@app/features/messaging/utils/MarkdownToSegmentUtils';
import type {MentionSegment} from '@app/features/messaging/utils/TextareaSegmentManager'; import type {MentionSegment} from '@app/features/messaging/utils/TextareaSegmentManager';
import {TextareaSegmentManager} from '@app/features/messaging/utils/TextareaSegmentManager'; import {TextareaSegmentManager} from '@app/features/messaging/utils/TextareaSegmentManager';
import {resolveTypedEmojiShortcodes} from '@app/features/messaging/utils/TypedEmojiShortcodeUtils';
import {ComponentBus} from '@app/features/platform/utils/ComponentBus'; import {ComponentBus} from '@app/features/platform/utils/ComponentBus';
import * as PopoutCommands from '@app/features/ui/commands/PopoutCommands'; import * as PopoutCommands from '@app/features/ui/commands/PopoutCommands';
import FocusRing from '@app/features/ui/focus_ring/FocusRing'; import FocusRing from '@app/features/ui/focus_ring/FocusRing';
@@ -35,9 +36,7 @@ import {SmileyIcon} from '@phosphor-icons/react';
import {clsx} from 'clsx'; import {clsx} from 'clsx';
import {observer} from 'mobx-react-lite'; import {observer} from 'mobx-react-lite';
import type React from 'react'; import type React from 'react';
import {useCallback, useEffect, useRef, useState} from 'react'; import {useCallback, useEffect, useMemo, useRef, useState} from 'react';
const EDITING_ALLOWED_TRIGGERS = ['emoji', 'mention', 'channel'] as const;
interface EditingFocusRequest { interface EditingFocusRequest {
requestedChannelId: string | null; requestedChannelId: string | null;
@@ -101,6 +100,10 @@ export const EditingMessageInput = observer(
return {display, segments: segments.getSegmentsCopy(), wire}; return {display, segments: segments.getSegmentsCopy(), wire};
}); });
const [actualContent, setActualContent] = useState(initial.wire); const [actualContent, setActualContent] = useState(initial.wire);
const resolvedContent = useMemo(
() => resolveTypedEmojiShortcodes({content: actualContent, channel, i18n}),
[actualContent, channel, i18n],
);
const composerRef = useRef<LexicalRichInputHandle | null>(null); const composerRef = useRef<LexicalRichInputHandle | null>(null);
const containerRef = useRef<HTMLDivElement>(null); const containerRef = useRef<HTMLDivElement>(null);
const editableRef = useRef<HTMLElement | null>(null); const editableRef = useRef<HTMLElement | null>(null);
@@ -144,11 +147,11 @@ export const EditingMessageInput = observer(
} }
}, []); }, []);
const handleSubmit = useCallback(() => { const handleSubmit = useCallback(() => {
if (editingDisabled || actualContent.length > maxMessageLength) { if (editingDisabled || resolvedContent.length > maxMessageLength) {
return; return;
} }
onSubmit(actualContent); onSubmit(resolvedContent);
}, [actualContent, editingDisabled, maxMessageLength, onSubmit]); }, [editingDisabled, maxMessageLength, onSubmit, resolvedContent]);
const handleKeyDown = useCallback( const handleKeyDown = useCallback(
(event: React.KeyboardEvent<HTMLElement>) => { (event: React.KeyboardEvent<HTMLElement>) => {
if (event.defaultPrevented) { if (event.defaultPrevented) {
@@ -264,7 +267,7 @@ export const EditingMessageInput = observer(
if (mobileLayout.enabled) { if (mobileLayout.enabled) {
handleExpressionPickerButtonClick = () => setExpressionPickerOpen(true); handleExpressionPickerButtonClick = () => setExpressionPickerOpen(true);
} }
let displayContentLength = actualContent.length; let displayContentLength = resolvedContent.length;
if (editingDisabled) { if (editingDisabled) {
displayContentLength = 0; displayContentLength = 0;
} }
@@ -287,7 +290,6 @@ export const EditingMessageInput = observer(
placeholder={placeholderText} placeholder={placeholderText}
disabled={editingDisabled} disabled={editingDisabled}
channel={channel} channel={channel}
allowedTriggers={[...EDITING_ALLOWED_TRIGGERS]}
markdown={true} markdown={true}
singleLine={!mobileLayout.enabled} singleLine={!mobileLayout.enabled}
size="chat" size="chat"
@@ -33,7 +33,6 @@ import {
import {retryFailedMessage} from '@app/features/messaging/utils/MessageRetryUtils'; import {retryFailedMessage} from '@app/features/messaging/utils/MessageRetryUtils';
import {NodeType} from '@app/features/messaging/utils/markdown/parser/Enums'; import {NodeType} from '@app/features/messaging/utils/markdown/parser/Enums';
import {SpoilerSyncProvider} from '@app/features/messaging/utils/SpoilerUtils'; import {SpoilerSyncProvider} from '@app/features/messaging/utils/SpoilerUtils';
import {resolveTypedEmojiShortcodes} from '@app/features/messaging/utils/TypedEmojiShortcodeUtils';
import {compactMarkdownProps} from '@app/features/theme/layout/MessageLayoutAttributes'; import {compactMarkdownProps} from '@app/features/theme/layout/MessageLayoutAttributes';
import markupStyles from '@app/features/theme/styles/Markup.module.css'; import markupStyles from '@app/features/theme/styles/Markup.module.css';
import styles from '@app/features/theme/styles/Message.module.css'; import styles from '@app/features/theme/styles/Message.module.css';
@@ -194,11 +193,7 @@ export const UserMessage = observer(() => {
if (message.messageSnapshots) { if (message.messageSnapshots) {
return; return;
} }
const content = resolveTypedEmojiShortcodes({ const content = (actualContent ?? '').trim();
content: (actualContent ?? '').trim(),
channel,
i18n,
});
if (!content) { if (!content) {
if (canSubmitEmptyMessageEdit(message)) { if (canSubmitEmptyMessageEdit(message)) {
if (message.content.length === 0) { if (message.content.length === 0) {
@@ -232,10 +227,8 @@ export const UserMessage = observer(() => {
}); });
}, },
[ [
channel,
channel.id, channel.id,
handleDelete, handleDelete,
i18n,
message, message,
message.id, message.id,
message.messageSnapshots, message.messageSnapshots,