2023-08-14 11:32:26 +02:00

70 lines
2.5 KiB
TypeScript

import { useEffect } from '../../../../lib/teact/teact';
import type { ApiSticker } from '../../../../api/types';
import type { Signal } from '../../../../util/signals';
import { getActions } from '../../../../global';
import { EMOJI_IMG_REGEX } from '../../../../config';
import { IS_EMOJI_SUPPORTED } from '../../../../util/windowEnvironment';
import parseEmojiOnlyString from '../../../../util/parseEmojiOnlyString';
import twemojiRegex from '../../../../lib/twemojiRegex';
import { prepareForRegExp } from '../helpers/prepareForRegExp';
import useDerivedState from '../../../../hooks/useDerivedState';
import useFlag from '../../../../hooks/useFlag';
import useDerivedSignal from '../../../../hooks/useDerivedSignal';
const MAX_LENGTH = 8;
const STARTS_ENDS_ON_EMOJI_IMG_REGEX = new RegExp(`^${EMOJI_IMG_REGEX.source}$`, 'g');
export default function useStickerTooltip(
isEnabled: boolean,
getHtml: Signal<string>,
stickers?: ApiSticker[],
) {
const { loadStickersForEmoji, clearStickersForEmoji } = getActions();
const [isManuallyClosed, markManuallyClosed, unmarkManuallyClosed] = useFlag(false);
const getSingleEmoji = useDerivedSignal(() => {
const html = getHtml();
if (!isEnabled || !html || (IS_EMOJI_SUPPORTED && html.length > MAX_LENGTH)) return undefined;
const hasEmoji = html.match(IS_EMOJI_SUPPORTED ? twemojiRegex : EMOJI_IMG_REGEX);
if (!hasEmoji) return undefined;
const cleanHtml = prepareForRegExp(html);
const isSingleEmoji = cleanHtml && (
(IS_EMOJI_SUPPORTED && parseEmojiOnlyString(cleanHtml) === 1)
|| (!IS_EMOJI_SUPPORTED && Boolean(html.match(STARTS_ENDS_ON_EMOJI_IMG_REGEX)))
);
return isSingleEmoji
? (IS_EMOJI_SUPPORTED ? cleanHtml : cleanHtml.match(/alt="(.+)"/)?.[1]!)
: undefined;
}, [getHtml, isEnabled]);
const isActive = useDerivedState(() => Boolean(getSingleEmoji()), [getSingleEmoji]);
const hasStickers = Boolean(stickers?.length);
useEffect(() => {
if (!isEnabled || !isActive) return;
const singleEmoji = getSingleEmoji();
if (singleEmoji) {
if (!hasStickers) {
loadStickersForEmoji({ emoji: singleEmoji });
}
} else {
clearStickersForEmoji();
}
}, [isEnabled, isActive, getSingleEmoji, hasStickers, loadStickersForEmoji, clearStickersForEmoji]);
useEffect(unmarkManuallyClosed, [unmarkManuallyClosed, getHtml]);
return {
isStickerTooltipOpen: Boolean(isActive && hasStickers && !isManuallyClosed),
closeStickerTooltip: markManuallyClosed,
};
}