diff --git a/src/components/common/CoverImage.astro b/src/components/common/CoverImage.astro
index 2f41fa61b4..403bfe8a32 100644
--- a/src/components/common/CoverImage.astro
+++ b/src/components/common/CoverImage.astro
@@ -1,8 +1,8 @@
---
-import { Picture } from "astro:assets";
+import { getImage, Picture } from "astro:assets";
import * as path from "node:path";
import type { ImageMetadata } from "astro";
-import { coverImageConfig } from "@/config";
+import { coverImageConfig, siteConfig } from "@/config";
import type { ImageFormat, ResponsiveImageLayout } from "@/types/config";
import {
getFallbackFormat,
@@ -136,6 +136,26 @@ const remoteReferrerPolicy =
!isLocal && shouldAddNoReferrer(isPublic ? url(src) : src)
? "no-referrer"
: undefined;
+
+// Generate tiny image for local or public images if available
+let tinyImgUrl = "";
+if (siteConfig.post.generateTinyThumbnails) {
+ if (isLocal && img) {
+ try {
+ const tinyImg = await getImage({ src: img, width: 32, quality: 30 });
+ tinyImgUrl = tinyImg.src;
+ } catch (e) {
+ console.error("Failed to generate tiny thumbnail:", e);
+ }
+ } else if (isPublic && src) {
+ try {
+ const tinyImg = await getImage({ src: src, width: 32, quality: 30 });
+ tinyImgUrl = tinyImg.src;
+ } catch (e) {
+ console.error("Failed to generate tiny thumbnail for public image:", e);
+ }
+ }
+}
---
0 ? JSON.stringify(apiUrls) : undefined}
>
-
+
{showLoading && (
diff --git a/src/components/common/ImageWrapper.astro b/src/components/common/ImageWrapper.astro
index ed0d6054b0..0f211dd3aa 100644
--- a/src/components/common/ImageWrapper.astro
+++ b/src/components/common/ImageWrapper.astro
@@ -1,5 +1,5 @@
---
-import { Image, Picture } from "astro:assets";
+import { getImage, Image, Picture } from "astro:assets";
import * as path from "node:path";
import type { ImageMetadata } from "astro";
import type { ImageFormat, ResponsiveImageLayout } from "@/types/config";
@@ -11,6 +11,7 @@ import {
} from "@/utils/image-utils";
import { getLqipProps } from "@/utils/lqip-utils";
import { url } from "@/utils/url-utils";
+import { siteConfig } from "@/config";
interface Props {
id?: string;
@@ -103,9 +104,34 @@ const lqipProps = isLocal
: isPublic
? getLqipProps(src, basePath, true)
: getLqipProps(src);
+
+// Generate tiny image for local or public images if available
+let tinyImgUrl = "";
+if (siteConfig.post.generateTinyThumbnails) {
+ if (isLocal && img) {
+ try {
+ const tinyImg = await getImage({ src: img, width: 32, quality: 30 });
+ tinyImgUrl = tinyImg.src;
+ } catch (e) {
+ console.error("Failed to generate tiny thumbnail:", e);
+ }
+ } else if (isPublic && src) {
+ try {
+ const tinyImg = await getImage({ src: src, width: 32, quality: 30 });
+ tinyImgUrl = tinyImg.src;
+ } catch (e) {
+ console.error("Failed to generate tiny thumbnail for public image:", e);
+ }
+ }
+}
---
-
+
{isLocal && img && usePicture && (
{
{/if}
+
+
{#if allowLayoutSwitch}
diff --git a/src/components/pages/gallery/AlbumCard.astro b/src/components/pages/gallery/AlbumCard.astro
index d8591e265d..bcdb7cbb58 100644
--- a/src/components/pages/gallery/AlbumCard.astro
+++ b/src/components/pages/gallery/AlbumCard.astro
@@ -1,8 +1,10 @@
---
+import { getImage } from "astro:assets";
import I18nKey from "@/i18n/i18nKey";
import { i18n } from "@/i18n/translation";
import { getLqipProps } from "@/utils/lqip-utils";
import { url } from "@/utils/url-utils";
+import { siteConfig } from "@/config";
interface Props {
id: string;
@@ -30,6 +32,16 @@ const {
// LQIP 渐变占位
const lqipProps = cover ? getLqipProps(cover, undefined, true) : { style: "" };
+
+let tinyImgUrl = "";
+if (siteConfig.post.generateTinyThumbnails && cover) {
+ try {
+ const tinyImg = await getImage({ src: cover, width: 32, quality: 30 });
+ tinyImgUrl = tinyImg.src;
+ } catch (e) {
+ console.error("Failed to generate tiny thumbnail:", e);
+ }
+}
---
{cover ? (
<>
-
+
@@ -20,7 +32,12 @@ const lqipProps = getLqipProps(src, undefined, true);
data-type="image"
class="block rounded-xl overflow-hidden relative group cursor-pointer"
>
-
+
{
@@ -1659,6 +1667,7 @@ function disableAnimation() {
updateSidebarComponentsVisibility();
initWallpaperMode();
initThemeListener();
+ initProgressiveLoading();
initIconLoader();
});
} else {
@@ -1666,6 +1675,7 @@ function disableAnimation() {
updateSidebarComponentsVisibility();
initWallpaperMode();
initThemeListener();
+ initProgressiveLoading();
initIconLoader();
}
diff --git a/src/pages/gallery/[album].astro b/src/pages/gallery/[album].astro
index 4d7fcdc990..009da1a079 100644
--- a/src/pages/gallery/[album].astro
+++ b/src/pages/gallery/[album].astro
@@ -1,4 +1,5 @@
---
+import { getImage } from "astro:assets";
import { Icon } from "astro-icon/components";
import EncryptedContent from "@/components/features/EncryptedContent.astro";
import PhotoCard from "@/components/pages/gallery/PhotoCard.astro";
@@ -36,6 +37,16 @@ const columnWidth = galleryConfig.columnWidth || 240;
const coverLqipProps = cover
? getLqipProps(cover, undefined, true)
: { style: "" };
+
+let tinyImgUrl = "";
+if (siteConfig.post.generateTinyThumbnails && cover) {
+ try {
+ const tinyImg = await getImage({ src: cover, width: 32, quality: 30 });
+ tinyImgUrl = tinyImg.src;
+ } catch (e) {
+ console.error("Failed to generate tiny thumbnail:", e);
+ }
+}
---
@@ -43,7 +54,12 @@ const coverLqipProps = cover
{cover ? (
-
+

= {};
+if (siteConfig.post.generateTinyThumbnails) {
+ for (const method of enabledMethods) {
+ if (method.qrCode) {
+ try {
+ const tinyImg = await getImage({
+ src: method.qrCode,
+ width: 32,
+ quality: 30,
+ });
+ tinyQrs[method.qrCode] = tinyImg.src;
+ } catch (e) {
+ console.error(
+ `Failed to generate tiny QR thumbnail for ${method.name}:`,
+ e,
+ );
+ }
+ }
+ }
+}
---
@@ -88,7 +111,12 @@ function getQrLqipProps(qrCode: string) {
{method.qrCode && (
-
+
})