mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 13:05:32 +09:00
perf(app): fetch text attachment previews only when they scroll near (#1865)
This commit is contained in:
1 parent
39e2c89d5c
commit
d2d199e136
2 files changed
+13
-3
No files matched your search
@@ -48,9 +48,10 @@ interface AttachmentFileProps {
|
|||||||
attachment: MessageAttachment;
|
attachment: MessageAttachment;
|
||||||
isPreview?: boolean;
|
isPreview?: boolean;
|
||||||
message?: Message;
|
message?: Message;
|
||||||
|
spoilerHidden?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AttachmentFile = observer(({attachment, message, isPreview}: AttachmentFileProps) => {
|
export const AttachmentFile = observer(({attachment, message, isPreview, spoilerHidden}: AttachmentFileProps) => {
|
||||||
const {i18n} = useLingui();
|
const {i18n} = useLingui();
|
||||||
const {enabled: isMobile} = MobileLayout;
|
const {enabled: isMobile} = MobileLayout;
|
||||||
const isExpired = Boolean(attachment.expired);
|
const isExpired = Boolean(attachment.expired);
|
||||||
@@ -247,6 +248,7 @@ export const AttachmentFile = observer(({attachment, message, isPreview}: Attach
|
|||||||
{showTextPreview ? (
|
{showTextPreview ? (
|
||||||
<TextualAttachmentPreview
|
<TextualAttachmentPreview
|
||||||
attachment={attachment}
|
attachment={attachment}
|
||||||
|
spoilerHidden={spoilerHidden}
|
||||||
data-flx="channel.embeds.attachments.attachment-file.textual-attachment-preview"
|
data-flx="channel.embeds.attachments.attachment-file.textual-attachment-preview"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
+10
-2
@@ -26,6 +26,7 @@ import {
|
|||||||
} from '@app/features/channel/components/embeds/attachments/TextualAttachmentPreviewUtils';
|
} from '@app/features/channel/components/embeds/attachments/TextualAttachmentPreviewUtils';
|
||||||
import {TextualPreviewContextMenu} from '@app/features/channel/components/embeds/attachments/TextualPreviewContextMenu';
|
import {TextualPreviewContextMenu} from '@app/features/channel/components/embeds/attachments/TextualPreviewContextMenu';
|
||||||
import {useArboriumHighlightedHtml} from '@app/features/code_highlighting/utils/ArboriumHighlighting';
|
import {useArboriumHighlightedHtml} from '@app/features/code_highlighting/utils/ArboriumHighlighting';
|
||||||
|
import {useNearViewport} from '@app/features/messaging/hooks/useNearViewport';
|
||||||
import TextualPreview from '@app/features/messaging/state/TextualPreview';
|
import TextualPreview from '@app/features/messaging/state/TextualPreview';
|
||||||
import {
|
import {
|
||||||
shouldPreviewAttachment,
|
shouldPreviewAttachment,
|
||||||
@@ -93,9 +94,12 @@ async function readPreviewText(response: Response): Promise<string> {
|
|||||||
|
|
||||||
export const TextualAttachmentPreview = observer(function TextualAttachmentPreview({
|
export const TextualAttachmentPreview = observer(function TextualAttachmentPreview({
|
||||||
attachment,
|
attachment,
|
||||||
}: TextualAttachmentPreviewProps) {
|
spoilerHidden = false,
|
||||||
|
}: TextualAttachmentPreviewProps & {spoilerHidden?: boolean}) {
|
||||||
const {i18n} = useLingui();
|
const {i18n} = useLingui();
|
||||||
const shouldShowPreview = shouldPreviewAttachment(attachment);
|
const shouldShowPreview = shouldPreviewAttachment(attachment);
|
||||||
|
const {ref: visibilityRef, isNearViewport} = useNearViewport<HTMLDivElement>({rememberKey: attachment.url});
|
||||||
|
const shouldFetchPreview = shouldShowPreview && isNearViewport && !spoilerHidden;
|
||||||
const isCsvPreview = useMemo(
|
const isCsvPreview = useMemo(
|
||||||
() => isCsvAttachment(attachment),
|
() => isCsvAttachment(attachment),
|
||||||
[attachment.content_type, attachment.filename, attachment.title],
|
[attachment.content_type, attachment.filename, attachment.title],
|
||||||
@@ -123,6 +127,9 @@ export const TextualAttachmentPreview = observer(function TextualAttachmentPrevi
|
|||||||
setIsFullscreenOpen(false);
|
setIsFullscreenOpen(false);
|
||||||
}, [attachment.id]);
|
}, [attachment.id]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!shouldFetchPreview) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!attachment.url) {
|
if (!attachment.url) {
|
||||||
setStatus('error');
|
setStatus('error');
|
||||||
setPreviewError({type: 'network'});
|
setPreviewError({type: 'network'});
|
||||||
@@ -164,7 +171,7 @@ export const TextualAttachmentPreview = observer(function TextualAttachmentPrevi
|
|||||||
setPreviewError({type: 'network', message: error?.message ?? 'Failed to load preview'});
|
setPreviewError({type: 'network', message: error?.message ?? 'Failed to load preview'});
|
||||||
});
|
});
|
||||||
return () => controller.abort();
|
return () => controller.abort();
|
||||||
}, [attachment.id, attachment.size, attachment.url]);
|
}, [attachment.id, attachment.size, attachment.url, shouldFetchPreview]);
|
||||||
const lineCount = useMemo(() => getLineCount(textContent), [textContent]);
|
const lineCount = useMemo(() => getLineCount(textContent), [textContent]);
|
||||||
const csvRows = useMemo(() => (isCsvPreview ? parseCsvRows(textContent) : null), [isCsvPreview, textContent]);
|
const csvRows = useMemo(() => (isCsvPreview ? parseCsvRows(textContent) : null), [isCsvPreview, textContent]);
|
||||||
const csvRowCount = csvRows?.length ?? 0;
|
const csvRowCount = csvRows?.length ?? 0;
|
||||||
@@ -282,6 +289,7 @@ export const TextualAttachmentPreview = observer(function TextualAttachmentPrevi
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
|
ref={visibilityRef}
|
||||||
className={styles.textualPreview}
|
className={styles.textualPreview}
|
||||||
data-flx="channel.embeds.attachments.textual-attachment-preview.textual-preview"
|
data-flx="channel.embeds.attachments.textual-attachment-preview.textual-preview"
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in new issue
Block a user