kopia lustrzana https://gitlab.com/soapbox-pub/soapbox
StatusContent: replace custom emojis on render
rodzic
afac59dc3d
commit
f335249104
|
@ -1,10 +1,11 @@
|
||||||
import chevronRightIcon from '@tabler/icons/outline/chevron-right.svg';
|
import chevronRightIcon from '@tabler/icons/outline/chevron-right.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import graphemesplit from 'graphemesplit';
|
import graphemesplit from 'graphemesplit';
|
||||||
import parse, { Element, type HTMLReactParserOptions, domToReact, type DOMNode } from 'html-react-parser';
|
import parse, { Element, type HTMLReactParserOptions, domToReact, type DOMNode, Text as DOMText } from 'html-react-parser';
|
||||||
import { useState, useRef, useLayoutEffect, useMemo, memo } from 'react';
|
import { useState, useRef, useLayoutEffect, useMemo, memo } from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
import { useCustomEmojis } from 'soapbox/api/hooks/useCustomEmojis.ts';
|
||||||
import Icon from 'soapbox/components/icon.tsx';
|
import Icon from 'soapbox/components/icon.tsx';
|
||||||
|
|
||||||
import { getTextDirection } from '../utils/rtl.ts';
|
import { getTextDirection } from '../utils/rtl.ts';
|
||||||
|
@ -51,11 +52,12 @@ const StatusContent: React.FC<IStatusContent> = ({
|
||||||
const [collapsed, setCollapsed] = useState(false);
|
const [collapsed, setCollapsed] = useState(false);
|
||||||
|
|
||||||
const node = useRef<HTMLDivElement>(null);
|
const node = useRef<HTMLDivElement>(null);
|
||||||
|
const { customEmojis } = useCustomEmojis();
|
||||||
|
|
||||||
const isOnlyEmoji = useMemo(() => {
|
const isOnlyEmoji = useMemo(() => {
|
||||||
const textContent = new DOMParser().parseFromString(status.contentHtml, 'text/html').body.firstChild?.textContent;
|
const textContent = new DOMParser().parseFromString(status.content, 'text/html').body.firstChild?.textContent ?? '';
|
||||||
return Boolean(textContent && /^\p{Extended_Pictographic}+$/u.test(textContent) && (graphemesplit(textContent).length <= BIG_EMOJI_LIMIT));
|
return Boolean(/^\p{Extended_Pictographic}+$/u.test(textContent) && (graphemesplit(textContent).length <= BIG_EMOJI_LIMIT));
|
||||||
}, [status.contentHtml]);
|
}, [status.content]);
|
||||||
|
|
||||||
const maybeSetCollapsed = (): void => {
|
const maybeSetCollapsed = (): void => {
|
||||||
if (!node.current) return;
|
if (!node.current) return;
|
||||||
|
@ -72,8 +74,8 @@ const StatusContent: React.FC<IStatusContent> = ({
|
||||||
});
|
});
|
||||||
|
|
||||||
const parsedHtml = useMemo((): string => {
|
const parsedHtml = useMemo((): string => {
|
||||||
return translatable && status.translation ? status.translation.get('content')! : status.contentHtml;
|
return translatable && status.translation ? status.translation.get('content')! : status.content;
|
||||||
}, [status.contentHtml, status.translation]);
|
}, [status.content, status.translation]);
|
||||||
|
|
||||||
if (status.content.length === 0) {
|
if (status.content.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -89,6 +91,22 @@ const StatusContent: React.FC<IStatusContent> = ({
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (domNode instanceof DOMText) {
|
||||||
|
const parts = domNode.data.split(' ').map((part) => {
|
||||||
|
const match = part.match(/^:(\w+):$/);
|
||||||
|
if (!match) return part;
|
||||||
|
|
||||||
|
const [, shortcode] = match;
|
||||||
|
const customEmoji = customEmojis.find((e) => e.shortcode === shortcode);
|
||||||
|
|
||||||
|
if (!customEmoji) return part;
|
||||||
|
|
||||||
|
return <img key={part} src={customEmoji.url} alt={part} className='inline-block h-[1em]' />;
|
||||||
|
});
|
||||||
|
|
||||||
|
return <>{parts}</>;
|
||||||
|
}
|
||||||
|
|
||||||
if (domNode instanceof Element && domNode.name === 'a') {
|
if (domNode instanceof Element && domNode.name === 'a') {
|
||||||
const classes = domNode.attribs.class?.split(' ');
|
const classes = domNode.attribs.class?.split(' ');
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue