mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-08 03:32:27 +09:00
fix(app): load expression grid images only when they scroll into view (#1922)
This commit is contained in:
@@ -3,10 +3,11 @@
|
||||
import i18nGlobal from '@app/app/I18n';
|
||||
import {GenericErrorModal} from '@app/features/app/components/alerts/GenericErrorModal';
|
||||
import {ConfirmModal} from '@app/features/app/components/dialogs/ConfirmModal';
|
||||
import {useShouldAnimate} from '@app/features/app/hooks/useShouldAnimate';
|
||||
import styles from '@app/features/emoji/components/emojis/EmojiListItem.module.css';
|
||||
import {useStickerAnimation} from '@app/features/emoji/hooks/useStickerAnimation';
|
||||
import * as GuildEmojiCommands from '@app/features/expressions/commands/GuildEmojiCommands';
|
||||
import Guilds from '@app/features/guild/state/Guilds';
|
||||
import {getEmojiRenderUrl} from '@app/features/messaging/utils/markdown/EmojiDetector';
|
||||
import {Logger} from '@app/features/platform/utils/AppLogger';
|
||||
import {failureCode} from '@app/features/platform/utils/ResponseInspection';
|
||||
import {EmojiContextMenuItems} from '@app/features/ui/action_menu/items/EmojiContextMenuItems';
|
||||
@@ -419,8 +420,15 @@ export const EmojiListItem: React.FC<{
|
||||
)),
|
||||
);
|
||||
};
|
||||
const {shouldAnimate} = useStickerAnimation();
|
||||
const emojiUrl = AvatarUtils.getEmojiURL({id: emoji.id, animated: shouldAnimate});
|
||||
const shouldAnimate = useShouldAnimate({kind: 'emoji', isAnimated: emoji.animated});
|
||||
const emojiUrl =
|
||||
getEmojiRenderUrl({
|
||||
id: emoji.id,
|
||||
surrogateUrl: null,
|
||||
isAnimatable: emoji.animated,
|
||||
animated: shouldAnimate,
|
||||
jumbo: false,
|
||||
}) ?? '';
|
||||
const emojiForMenu = {
|
||||
id: emoji.id,
|
||||
guildId,
|
||||
@@ -457,7 +465,6 @@ export const EmojiListItem: React.FC<{
|
||||
src={emojiUrl}
|
||||
alt={emoji.name}
|
||||
className={styles.gridEmojiImage}
|
||||
loading="lazy"
|
||||
data-flx="emoji.emojis.emoji-list-item.grid-emoji-image"
|
||||
/>
|
||||
{emoji.user && avatarUrl && (
|
||||
@@ -466,7 +473,6 @@ export const EmojiListItem: React.FC<{
|
||||
src={avatarUrl}
|
||||
alt=""
|
||||
className={styles.gridAvatar}
|
||||
loading="lazy"
|
||||
data-flx="emoji.emojis.emoji-list-item.grid-avatar"
|
||||
/>
|
||||
</Tooltip>
|
||||
@@ -543,7 +549,6 @@ export const EmojiListItem: React.FC<{
|
||||
src={emojiUrl}
|
||||
alt={emoji.name}
|
||||
className={styles.listEmojiImage}
|
||||
loading="lazy"
|
||||
data-flx="emoji.emojis.emoji-list-item.list-emoji-image"
|
||||
/>
|
||||
</div>
|
||||
@@ -570,13 +575,7 @@ export const EmojiListItem: React.FC<{
|
||||
<div className={styles.listUploader} data-flx="emoji.emojis.emoji-list-item.list-uploader">
|
||||
{emoji.user && avatarUrl ? (
|
||||
<>
|
||||
<img
|
||||
src={avatarUrl}
|
||||
alt=""
|
||||
className={styles.avatar}
|
||||
loading="lazy"
|
||||
data-flx="emoji.emojis.emoji-list-item.avatar"
|
||||
/>
|
||||
<img src={avatarUrl} alt="" className={styles.avatar} data-flx="emoji.emojis.emoji-list-item.avatar" />
|
||||
<span className={styles.username} data-flx="emoji.emojis.emoji-list-item.username">
|
||||
{NicknameUtils.getDisplayName(emoji.user)}
|
||||
</span>
|
||||
|
||||
@@ -6,6 +6,7 @@ import {useStickerAnimation} from '@app/features/emoji/hooks/useStickerAnimation
|
||||
import * as GuildStickerCommands from '@app/features/expressions/commands/GuildStickerCommands';
|
||||
import {EditGuildStickerModal} from '@app/features/expressions/components/modals/EditGuildStickerModal';
|
||||
import Guilds from '@app/features/guild/state/Guilds';
|
||||
import {useNearViewport} from '@app/features/messaging/hooks/useNearViewport';
|
||||
import {StickerContextMenuItems} from '@app/features/ui/action_menu/items/StickerContextMenuItems';
|
||||
import {Checkbox} from '@app/features/ui/checkbox/Checkbox';
|
||||
import * as ContextMenuCommands from '@app/features/ui/commands/ContextMenuCommands';
|
||||
@@ -66,7 +67,10 @@ export const StickerGridItem = observer(function StickerGridItem({
|
||||
onUpdate,
|
||||
}: StickerGridItemProps) {
|
||||
const {i18n} = useLingui();
|
||||
const {shouldAnimate} = useStickerAnimation();
|
||||
const {shouldAnimate, interactionHandlers} = useStickerAnimation({isAnimated: sticker.animated});
|
||||
const {ref: tileRef, isNearViewport} = useNearViewport<HTMLDivElement>({
|
||||
rememberKey: `guild-sticker-tile:${sticker.id}`,
|
||||
});
|
||||
const stickerName = sticker.name;
|
||||
const guild = Guilds.getGuild(guildId);
|
||||
const canExpressionPurge = guild?.features.has(GuildFeatures.EXPRESSION_PURGE_ALLOWED) ?? false;
|
||||
@@ -109,6 +113,7 @@ export const StickerGridItem = observer(function StickerGridItem({
|
||||
const stickerUrl = AvatarUtils.getStickerURL({
|
||||
id: sticker.id,
|
||||
animated: shouldAnimate,
|
||||
isAnimatable: sticker.animated,
|
||||
size: 320,
|
||||
});
|
||||
const avatarUrl = sticker.user ? AvatarUtils.getUserAvatarURL(sticker.user, false) : null;
|
||||
@@ -136,19 +141,25 @@ export const StickerGridItem = observer(function StickerGridItem({
|
||||
};
|
||||
return (
|
||||
<div
|
||||
ref={tileRef}
|
||||
role="group"
|
||||
className={styles.container}
|
||||
onContextMenu={handleContextMenu}
|
||||
onMouseEnter={interactionHandlers.onMouseEnter}
|
||||
onMouseLeave={interactionHandlers.onMouseLeave}
|
||||
onFocus={interactionHandlers.onFocus}
|
||||
onBlur={interactionHandlers.onBlur}
|
||||
data-flx="emoji.stickers.sticker-grid-item.container.context-menu"
|
||||
>
|
||||
<div className={styles.stickerWrapper} data-flx="emoji.stickers.sticker-grid-item.sticker-wrapper">
|
||||
<img
|
||||
src={stickerUrl}
|
||||
alt={stickerName}
|
||||
className={styles.stickerImage}
|
||||
loading="lazy"
|
||||
data-flx="emoji.stickers.sticker-grid-item.sticker-image"
|
||||
/>
|
||||
{isNearViewport && (
|
||||
<img
|
||||
src={stickerUrl}
|
||||
alt={stickerName}
|
||||
className={styles.stickerImage}
|
||||
data-flx="emoji.stickers.sticker-grid-item.sticker-image"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className={styles.content} data-flx="emoji.stickers.sticker-grid-item.content">
|
||||
<div className={styles.header} data-flx="emoji.stickers.sticker-grid-item.header">
|
||||
@@ -158,13 +169,19 @@ export const StickerGridItem = observer(function StickerGridItem({
|
||||
</div>
|
||||
{sticker.user && avatarUrl && (
|
||||
<div className={styles.authorInfo} data-flx="emoji.stickers.sticker-grid-item.author-info">
|
||||
<img
|
||||
src={avatarUrl}
|
||||
alt=""
|
||||
className={styles.authorAvatar}
|
||||
loading="lazy"
|
||||
data-flx="emoji.stickers.sticker-grid-item.author-avatar"
|
||||
/>
|
||||
{isNearViewport ? (
|
||||
<img
|
||||
src={avatarUrl}
|
||||
alt=""
|
||||
className={styles.authorAvatar}
|
||||
data-flx="emoji.stickers.sticker-grid-item.author-avatar"
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
className={styles.authorAvatar}
|
||||
data-flx="emoji.stickers.sticker-grid-item.author-avatar-placeholder"
|
||||
/>
|
||||
)}
|
||||
<span className={styles.authorName} data-flx="emoji.stickers.sticker-grid-item.author-name">
|
||||
{NicknameUtils.getDisplayName(sticker.user)}
|
||||
</span>
|
||||
|
||||
Reference in New Issue
Block a user