mirror of
https://github.com/glitch-soc/mastodon.git
synced 2025-12-15 16:59:41 +00:00
[Glitch] Emoji Rendering Efficiency
Port 6bca52453a to glitch-soc
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
@@ -1,81 +1,31 @@
|
||||
import type { HTMLAttributes } from 'react';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import type { ComponentPropsWithoutRef, ElementType } from 'react';
|
||||
|
||||
import type { List as ImmutableList } from 'immutable';
|
||||
import { isList } from 'immutable';
|
||||
import { useEmojify } from './hooks';
|
||||
import type { CustomEmojiMapArg } from './types';
|
||||
|
||||
import type { ApiCustomEmojiJSON } from '@/flavours/glitch/api_types/custom_emoji';
|
||||
import type { CustomEmoji } from '@/flavours/glitch/models/custom_emoji';
|
||||
import { isModernEmojiEnabled } from '@/flavours/glitch/utils/environment';
|
||||
|
||||
import { useEmojiAppState } from './hooks';
|
||||
import { emojifyElement } from './render';
|
||||
import type { ExtraCustomEmojiMap } from './types';
|
||||
|
||||
type EmojiHTMLProps = Omit<
|
||||
HTMLAttributes<HTMLDivElement>,
|
||||
type EmojiHTMLProps<Element extends ElementType = 'div'> = Omit<
|
||||
ComponentPropsWithoutRef<Element>,
|
||||
'dangerouslySetInnerHTML'
|
||||
> & {
|
||||
htmlString: string;
|
||||
extraEmojis?: ExtraCustomEmojiMap | ImmutableList<CustomEmoji>;
|
||||
extraEmojis?: CustomEmojiMapArg;
|
||||
as?: Element;
|
||||
};
|
||||
|
||||
export const EmojiHTML: React.FC<EmojiHTMLProps> = ({
|
||||
htmlString,
|
||||
export const EmojiHTML = <Element extends ElementType>({
|
||||
extraEmojis,
|
||||
htmlString,
|
||||
as: asElement, // Rename for syntax highlighting
|
||||
...props
|
||||
}) => {
|
||||
if (isModernEmojiEnabled()) {
|
||||
return (
|
||||
<ModernEmojiHTML
|
||||
htmlString={htmlString}
|
||||
extraEmojis={extraEmojis}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return <div dangerouslySetInnerHTML={{ __html: htmlString }} {...props} />;
|
||||
};
|
||||
}: EmojiHTMLProps<Element>) => {
|
||||
const Wrapper = asElement ?? 'div';
|
||||
const emojifiedHtml = useEmojify(htmlString, extraEmojis);
|
||||
|
||||
const ModernEmojiHTML: React.FC<EmojiHTMLProps> = ({
|
||||
extraEmojis: rawEmojis,
|
||||
htmlString: text,
|
||||
...props
|
||||
}) => {
|
||||
const appState = useEmojiAppState();
|
||||
const [innerHTML, setInnerHTML] = useState('');
|
||||
|
||||
const extraEmojis: ExtraCustomEmojiMap = useMemo(() => {
|
||||
if (!rawEmojis) {
|
||||
return {};
|
||||
}
|
||||
if (isList(rawEmojis)) {
|
||||
return (
|
||||
rawEmojis.toJS() as ApiCustomEmojiJSON[]
|
||||
).reduce<ExtraCustomEmojiMap>(
|
||||
(acc, emoji) => ({ ...acc, [emoji.shortcode]: emoji }),
|
||||
{},
|
||||
);
|
||||
}
|
||||
return rawEmojis;
|
||||
}, [rawEmojis]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!text) {
|
||||
return;
|
||||
}
|
||||
const cb = async () => {
|
||||
const div = document.createElement('div');
|
||||
div.innerHTML = text;
|
||||
const ele = await emojifyElement(div, appState, extraEmojis);
|
||||
setInnerHTML(ele.innerHTML);
|
||||
};
|
||||
void cb();
|
||||
}, [text, appState, extraEmojis]);
|
||||
|
||||
if (!innerHTML) {
|
||||
if (emojifiedHtml === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <div {...props} dangerouslySetInnerHTML={{ __html: innerHTML }} />;
|
||||
return (
|
||||
<Wrapper {...props} dangerouslySetInnerHTML={{ __html: emojifiedHtml }} />
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user