mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 05:25:40 +09:00
perf(app): render member list rows in scroll chunks (#1895)
This commit is contained in:
1 parent
b81bfc80fd
commit
c54d7bcc88
5 files changed
+146
-228
No files matched your search
@@ -1,13 +1,13 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import sharedStyles from '@app/features/app/components/shared/custom_status_display/CustomStatusDisplay.module.css';
|
||||
import {buildCustomEmojiURL} from '@app/features/expressions/utils/CustomEmojiImageUrl';
|
||||
import {getEmojiURL as getUnicodeEmojiURL} from '@app/features/expressions/utils/EmojiUtils';
|
||||
import {usePresenceCustomStatus} from '@app/features/presence/hooks/usePresenceCustomStatus';
|
||||
import {useTextOverflow} from '@app/features/ui/hooks/useTextOverflow';
|
||||
import {Tooltip} from '@app/features/ui/tooltip/Tooltip';
|
||||
import type {CustomStatus} from '@app/features/user/state/CustomStatus';
|
||||
import {getCustomStatusText, isCustomStatusExpired, normalizeCustomStatus} from '@app/features/user/state/CustomStatus';
|
||||
import * as AvatarUtils from '@app/features/user/utils/AvatarUtils';
|
||||
import clsx from 'clsx';
|
||||
import {type ReactNode, useEffect, useMemo, useRef, useState} from 'react';
|
||||
|
||||
@@ -16,7 +16,6 @@ interface CompactMemberCustomStatusProps {
|
||||
customStatus?: CustomStatus | null;
|
||||
userId?: string;
|
||||
showText?: boolean;
|
||||
deferMediaLoad?: boolean;
|
||||
}
|
||||
|
||||
function sanitizeText(text: string): string {
|
||||
@@ -45,33 +44,14 @@ export function hasVisibleCompactMemberCustomStatus(status: CustomStatus | null
|
||||
return sanitizeText(normalized.text ?? '').length > 0;
|
||||
}
|
||||
|
||||
const loadedStatusMediaUrls = new Set<string>();
|
||||
|
||||
function markStatusMediaLoaded(url: string): void {
|
||||
loadedStatusMediaUrls.add(url);
|
||||
}
|
||||
|
||||
function renderEmoji(status: CustomStatus, deferMediaLoad: boolean): ReactNode {
|
||||
function renderEmoji(status: CustomStatus): ReactNode {
|
||||
if (status.emojiId) {
|
||||
const emojiUrl = AvatarUtils.getEmojiURL({id: status.emojiId, animated: false});
|
||||
if (deferMediaLoad && !loadedStatusMediaUrls.has(emojiUrl)) {
|
||||
return (
|
||||
<span
|
||||
className={sharedStyles.statusEmojiWrapper}
|
||||
aria-hidden={true}
|
||||
data-flx="channel.compact-member-custom-status.emoji-placeholder"
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<img
|
||||
src={emojiUrl}
|
||||
src={buildCustomEmojiURL({id: status.emojiId, animated: false})}
|
||||
alt={status.emojiName ?? undefined}
|
||||
draggable={false}
|
||||
className={sharedStyles.statusEmoji}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
onLoad={() => markStatusMediaLoaded(emojiUrl)}
|
||||
data-flx="channel.compact-member-custom-status.emoji"
|
||||
/>
|
||||
);
|
||||
@@ -83,24 +63,12 @@ function renderEmoji(status: CustomStatus, deferMediaLoad: boolean): ReactNode {
|
||||
if (!twemojiUrl) {
|
||||
return null;
|
||||
}
|
||||
if (deferMediaLoad && !loadedStatusMediaUrls.has(twemojiUrl)) {
|
||||
return (
|
||||
<span
|
||||
className={sharedStyles.statusEmojiWrapper}
|
||||
aria-hidden={true}
|
||||
data-flx="channel.compact-member-custom-status.unicode-emoji-placeholder"
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<img
|
||||
src={twemojiUrl}
|
||||
alt={status.emojiName}
|
||||
draggable={false}
|
||||
className={sharedStyles.statusEmoji}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
onLoad={() => markStatusMediaLoaded(twemojiUrl)}
|
||||
data-flx="channel.compact-member-custom-status.unicode-emoji"
|
||||
/>
|
||||
);
|
||||
@@ -111,7 +79,6 @@ export function CompactMemberCustomStatus({
|
||||
customStatus,
|
||||
userId,
|
||||
showText = true,
|
||||
deferMediaLoad = false,
|
||||
}: CompactMemberCustomStatusProps) {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const shouldFetchFromPresence = customStatus === undefined && userId !== undefined;
|
||||
@@ -143,7 +110,7 @@ export function CompactMemberCustomStatus({
|
||||
return null;
|
||||
}
|
||||
const text = normalized.text ? sanitizeText(normalized.text) : null;
|
||||
const emoji = renderEmoji(normalized, deferMediaLoad);
|
||||
const emoji = renderEmoji(normalized);
|
||||
if (!emoji && (!showText || !text)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user