mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-07 19:22:14 +09:00
fix(app): retry emoji picker images that fail to load (#3151)
This commit is contained in:
@@ -11,6 +11,7 @@ import type {FlatEmoji} from '@app/features/emoji/types/EmojiTypes';
|
||||
import {checkEmojiAvailability} from '@app/features/expressions/utils/ExpressionPermissionUtils';
|
||||
import {getEmojiDisplayDataWithSkinTone} from '@app/features/expressions/utils/SkinToneUtils';
|
||||
import UnicodeEmojis, {EMOJI_SPRITES} from '@app/features/expressions/utils/UnicodeEmojis';
|
||||
import {loadImage} from '@app/features/messaging/utils/ImageCacheUtils';
|
||||
import {getEmojiRenderUrl} from '@app/features/messaging/utils/markdown/EmojiDetector';
|
||||
import {EmojiContextMenuItems} from '@app/features/ui/action_menu/items/EmojiContextMenuItems';
|
||||
import * as ContextMenuCommands from '@app/features/ui/commands/ContextMenuCommands';
|
||||
@@ -25,9 +26,34 @@ type PickerEmojiImageProps = React.ImgHTMLAttributes<HTMLImageElement> & {
|
||||
alt: string;
|
||||
};
|
||||
|
||||
const PICKER_IMAGE_RETRY_LIMIT = 3;
|
||||
|
||||
const PickerEmojiImage = ({src, alt, ...props}: PickerEmojiImageProps) => {
|
||||
const imageRef = useRef<HTMLImageElement | null>(null);
|
||||
const hasLoadedRef = useRef(false);
|
||||
const retriesRef = useRef(0);
|
||||
const cancelRetryRef = useRef<(() => void) | null>(null);
|
||||
useEffect(() => {
|
||||
retriesRef.current = 0;
|
||||
return () => {
|
||||
cancelRetryRef.current?.();
|
||||
cancelRetryRef.current = null;
|
||||
};
|
||||
}, [src]);
|
||||
const handleError = () => {
|
||||
if (retriesRef.current >= PICKER_IMAGE_RETRY_LIMIT) {
|
||||
return;
|
||||
}
|
||||
retriesRef.current += 1;
|
||||
cancelRetryRef.current?.();
|
||||
cancelRetryRef.current = loadImage(src, () => {
|
||||
cancelRetryRef.current = null;
|
||||
const image = imageRef.current;
|
||||
if (image != null && image.getAttribute('src') === src) {
|
||||
image.src = src;
|
||||
}
|
||||
});
|
||||
};
|
||||
const handleLoad = (event: React.SyntheticEvent<HTMLImageElement>) => {
|
||||
const view = event.currentTarget?.ownerDocument?.defaultView ?? window;
|
||||
view.requestAnimationFrame(() => {
|
||||
@@ -47,6 +73,7 @@ const PickerEmojiImage = ({src, alt, ...props}: PickerEmojiImageProps) => {
|
||||
alt={alt}
|
||||
className={hasLoadedRef.current ? styles.emojiImage : clsx(styles.emojiImage, styles.emojiImageLoading)}
|
||||
onLoad={hasLoadedRef.current ? undefined : handleLoad}
|
||||
onError={hasLoadedRef.current ? undefined : handleError}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user