feat(chat): preload and cache the custom emoji. Closes #3117
This commit is contained in:
parent
8a4039217f
commit
02811ef37e
@ -72,6 +72,7 @@ export const ChatTextField: FC<ChatTextFieldProps> = ({ defaultText, enabled, fo
|
|||||||
const websocketService = useRecoilValue<WebsocketService>(websocketServiceAtom);
|
const websocketService = useRecoilValue<WebsocketService>(websocketServiceAtom);
|
||||||
const text = useRef(defaultText || '');
|
const text = useRef(defaultText || '');
|
||||||
const [savedCursorLocation, setSavedCursorLocation] = useState(0);
|
const [savedCursorLocation, setSavedCursorLocation] = useState(0);
|
||||||
|
const [customEmoji, setCustomEmoji] = useState([]);
|
||||||
|
|
||||||
// This is a bit of a hack to force the component to re-render when the text changes.
|
// This is a bit of a hack to force the component to re-render when the text changes.
|
||||||
// By default when updating a ref the component doesn't re-render.
|
// By default when updating a ref the component doesn't re-render.
|
||||||
@ -211,6 +212,28 @@ export const ChatTextField: FC<ChatTextFieldProps> = ({ defaultText, enabled, fo
|
|||||||
document.getElementById('chat-input-content-editable').focus();
|
document.getElementById('chat-input-content-editable').focus();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const getCustomEmoji = async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`/api/emoji`);
|
||||||
|
const emoji = await response.json();
|
||||||
|
setCustomEmoji(emoji);
|
||||||
|
|
||||||
|
emoji.forEach(e => {
|
||||||
|
const preImg = document.createElement('link');
|
||||||
|
preImg.href = e.url;
|
||||||
|
preImg.rel = 'preload';
|
||||||
|
preImg.as = 'image';
|
||||||
|
document.head.appendChild(preImg);
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error('cannot fetch custom emoji', e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getCustomEmoji();
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id="chat-input" className={styles.root}>
|
<div id="chat-input" className={styles.root}>
|
||||||
<div
|
<div
|
||||||
@ -221,7 +244,11 @@ export const ChatTextField: FC<ChatTextFieldProps> = ({ defaultText, enabled, fo
|
|||||||
>
|
>
|
||||||
<Popover
|
<Popover
|
||||||
content={
|
content={
|
||||||
<EmojiPicker onEmojiSelect={onEmojiSelect} onCustomEmojiSelect={onCustomEmojiSelect} />
|
<EmojiPicker
|
||||||
|
customEmoji={customEmoji}
|
||||||
|
onEmojiSelect={onEmojiSelect}
|
||||||
|
onCustomEmojiSelect={onCustomEmojiSelect}
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
trigger="click"
|
trigger="click"
|
||||||
placement="topRight"
|
placement="topRight"
|
||||||
|
@ -1,31 +1,19 @@
|
|||||||
import React, { FC, useEffect, useRef, useState } from 'react';
|
import React, { FC, useEffect, useRef } from 'react';
|
||||||
import { createPicker } from 'picmo';
|
import { createPicker } from 'picmo';
|
||||||
|
|
||||||
const CUSTOM_EMOJI_URL = '/api/emoji';
|
|
||||||
export type EmojiPickerProps = {
|
export type EmojiPickerProps = {
|
||||||
onEmojiSelect: (emoji: string) => void;
|
onEmojiSelect: (emoji: string) => void;
|
||||||
onCustomEmojiSelect: (name: string, url: string) => void;
|
onCustomEmojiSelect: (name: string, url: string) => void;
|
||||||
|
customEmoji: any[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const EmojiPicker: FC<EmojiPickerProps> = ({ onEmojiSelect, onCustomEmojiSelect }) => {
|
export const EmojiPicker: FC<EmojiPickerProps> = ({
|
||||||
const [customEmoji, setCustomEmoji] = useState([]);
|
onEmojiSelect,
|
||||||
|
onCustomEmojiSelect,
|
||||||
|
customEmoji,
|
||||||
|
}) => {
|
||||||
const ref = useRef();
|
const ref = useRef();
|
||||||
|
|
||||||
const getCustomEmoji = async () => {
|
|
||||||
try {
|
|
||||||
const response = await fetch(CUSTOM_EMOJI_URL);
|
|
||||||
const emoji = await response.json();
|
|
||||||
setCustomEmoji(emoji);
|
|
||||||
} catch (e) {
|
|
||||||
console.error('cannot fetch custom emoji', e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Fetch the custom emoji on component mount.
|
|
||||||
useEffect(() => {
|
|
||||||
getCustomEmoji();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// Recreate the emoji picker when the custom emoji changes.
|
// Recreate the emoji picker when the custom emoji changes.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const e = customEmoji.map(emoji => ({
|
const e = customEmoji.map(emoji => ({
|
||||||
@ -48,7 +36,7 @@ export const EmojiPicker: FC<EmojiPickerProps> = ({ onEmojiSelect, onCustomEmoji
|
|||||||
onEmojiSelect(event.emoji);
|
onEmojiSelect(event.emoji);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, [customEmoji]);
|
}, []);
|
||||||
|
|
||||||
return <div ref={ref} />;
|
return <div ref={ref} />;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user