store link previews in lrucache to prevent layout shift

This commit is contained in:
Martti Malmi 2024-01-10 14:51:46 +02:00
parent 90b15ee668
commit 52adf6fb1f
3 changed files with 17 additions and 1 deletions

View File

@ -40,6 +40,7 @@
"react-textarea-autosize": "^8.4.0",
"recharts": "^2.8.0",
"three": "^0.157.0",
"typescript-lru-cache": "^2.0.0",
"use-long-press": "^3.2.0",
"use-sync-external-store": "^1.2.0",
"uuid": "^9.0.0",

View File

@ -1,6 +1,7 @@
import "./LinkPreview.css";
import { CSSProperties, useEffect, useState } from "react";
import { LRUCache } from 'typescript-lru-cache';
import { MediaElement } from "@/Components/Embed/MediaElement";
import Spinner from "@/Components/Icons/Spinner";
@ -16,18 +17,24 @@ async function fetchUrlPreviewInfo(url: string) {
}
}
const cache = new LRUCache<string, LinkPreviewData>({
maxSize: 100,
});
const LinkPreview = ({ url }: { url: string }) => {
const [preview, setPreview] = useState<LinkPreviewData | null>();
const [preview, setPreview] = useState<LinkPreviewData | null>(cache.get(url));
const { proxy } = useImgProxy();
useEffect(() => {
(async () => {
if (preview) return;
const data = await fetchUrlPreviewInfo(url);
if (data) {
const type = data.og_tags?.find(a => a[0].toLowerCase() === "og:type");
const canPreviewType = type?.[1].startsWith("image") || type?.[1].startsWith("video") || false;
if (canPreviewType || data.image) {
setPreview(data);
cache.set(url, data);
return;
}
}

View File

@ -2994,6 +2994,7 @@ __metadata:
three: ^0.157.0
tinybench: ^2.5.1
typescript: ^5.2.2
typescript-lru-cache: ^2.0.0
use-long-press: ^3.2.0
use-sync-external-store: ^1.2.0
uuid: ^9.0.0
@ -11290,6 +11291,13 @@ __metadata:
languageName: node
linkType: hard
"typescript-lru-cache@npm:^2.0.0":
version: 2.0.0
resolution: "typescript-lru-cache@npm:2.0.0"
checksum: 50948bb62cfe928f0baf4dcc09634cc2456520c0abf2ad726483039371eb523ee6b9c4f45210704f3c1fb30dc6ae5e5ffb27127a34d626848db9d80bcb3057d1
languageName: node
linkType: hard
"typescript@npm:5, typescript@npm:^5.2.2":
version: 5.2.2
resolution: "typescript@npm:5.2.2"