import { useEffect, useState } from "react"; import { getEmojiAssetUrlSync, loadEmojiAssetUrl, normalizeEmoji } from "@/client/lib/emoji"; interface EmojiIconProps { emoji: string; size?: number; } export function EmojiIcon({ emoji, size = 20 }: EmojiIconProps) { const cachedAssetUrl = getEmojiAssetUrlSync(emoji); const [assetState, setAssetState] = useState(() => ({ emoji, assetUrl: cachedAssetUrl, failed: false, })); const currentAsset = assetState.emoji === emoji ? assetState : { emoji, assetUrl: cachedAssetUrl, failed: false }; const style = { width: size, height: size }; useEffect(() => { if (currentAsset.assetUrl !== null) return; let cancelled = false; loadEmojiAssetUrl(emoji).then((url) => { if (!cancelled) setAssetState({ emoji, assetUrl: url, failed: false }); }); return () => { cancelled = true; }; }, [currentAsset.assetUrl, emoji]); if (currentAsset.assetUrl && !currentAsset.failed) { return ( setAssetState({ emoji, assetUrl: currentAsset.assetUrl, failed: true })} className="inline-block shrink-0 select-none align-text-bottom" style={style} /> ); } return ( {normalizeEmoji(emoji)} ); }