Spoiler: Fixes for emojis (#2132)

This commit is contained in:
Alexander Zinchuk 2022-11-13 17:06:17 +04:00
parent dfe7b80a6b
commit 99767907a7
2 changed files with 25 additions and 5 deletions

View File

@ -42,6 +42,11 @@ function MessageText({
const { text, entities } = message.content.text || {};
const withSharedCanvas = useMemo(() => {
const hasSpoilers = entities?.some((e) => e.type === ApiMessageEntityTypes.Spoiler);
if (hasSpoilers) {
return false;
}
const customEmojisCount = entities?.filter((e) => e.type === ApiMessageEntityTypes.CustomEmoji).length || 0;
return customEmojisCount >= MIN_CUSTOM_EMOJIS_FOR_SHARED_CANVAS;
}, [entities]) || 0;

View File

@ -22,6 +22,7 @@ const MAX_HIDE_TIMEOUT = 60000; // 1m
const actionsByMessageId: Map<number, {
reveal: VoidFunction;
conceal: VoidFunction;
contentLength: number;
}[]> = new Map();
const buildClassName = createClassNameBuilder('Spoiler');
@ -35,14 +36,26 @@ const Spoiler: FC<OwnProps> = ({
const [isRevealed, reveal, conceal] = useFlag();
const getContentLength = useCallback(() => {
if (!contentRef.current) {
return 0;
}
const textLength = contentRef.current.textContent?.length || 0;
const emojiCount = contentRef.current.querySelectorAll('.emoji').length;
// Optimization: ignore alt, assume that viewing emoji takes same time as viewing 4 characters
return textLength + emojiCount * 4;
}, []);
const handleClick = useCallback((e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
e.preventDefault();
e.stopPropagation();
actionsByMessageId.get(messageId!)?.forEach((actions) => actions.reveal());
const contentLength = contentRef.current!.innerText.length;
const readingMs = Math.round(contentLength / READING_SYMBOLS_PER_SECOND) * 1000;
const totalContentLength = actionsByMessageId.get(messageId!)
?.reduce((acc, actions) => acc + actions.contentLength, 0) || 0;
const readingMs = Math.round(totalContentLength / READING_SYMBOLS_PER_SECOND) * 1000;
const timeoutMs = Math.max(MIN_HIDE_TIMEOUT, Math.min(readingMs, MAX_HIDE_TIMEOUT));
setTimeout(() => {
@ -56,16 +69,18 @@ const Spoiler: FC<OwnProps> = ({
return undefined;
}
const contentLength = getContentLength();
if (actionsByMessageId.has(messageId)) {
actionsByMessageId.get(messageId)!.push({ reveal, conceal });
actionsByMessageId.get(messageId)!.push({ reveal, conceal, contentLength });
} else {
actionsByMessageId.set(messageId, [{ reveal, conceal }]);
actionsByMessageId.set(messageId, [{ reveal, conceal, contentLength }]);
}
return () => {
actionsByMessageId.delete(messageId);
};
}, [conceal, handleClick, isRevealed, messageId, reveal]);
}, [conceal, getContentLength, handleClick, isRevealed, messageId, reveal]);
return (
<span