diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index b58b603f..00000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Editor-based HTTP Client requests
-/httpRequests/
diff --git a/.idea/electron-vite-turbo.iml b/.idea/electron-vite-turbo.iml
deleted file mode 100644
index 24643cc3..00000000
--- a/.idea/electron-vite-turbo.iml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index aeadf309..00000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 35eb1ddf..00000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/README.md b/README.md
index 11dc123e..6f421b88 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
| undefined;
const app = express();
@@ -21,14 +22,23 @@ const asyncMiddleware =
};
/**
- * 启动静态文件服务器,自动获取获取可用端口 并返回
+ *
* @param path
- * @param port
* @returns
*/
-export const startStaticServer = async (path: string, port?: number) => {
+export const startStaticServer = async () => {
+ const caller = router.createCaller({});
+ const config = await caller.config.get();
+ const library = await caller.library.get();
+
+ const port = config?.staticServerPort;
+
+ if (!port) throw new Error("staticServerPort is not defined");
+
+ if (!library) return;
if (server) return;
- const _port = port ?? (await getPort({ port: portNumbers(9100, 9300) }));
+
+ const path = join(library.path, "images");
app.use((_req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
@@ -49,17 +59,44 @@ export const startStaticServer = async (path: string, port?: number) => {
"/blur",
asyncMiddleware((req, res) => {
void (async () => {
- const file = readFileSync(join(path, req.path));
- const { base64 } = await getPlaiceholder(file);
- const img = Buffer.from(
- base64.replace(/^data:image\/(png|jpeg|jpg);base64,/, ""),
- "base64",
+ const parts = req.path.split("/");
+ const imageDbPath = join(
+ path,
+ parts[parts.length - 2] ?? "",
+ "metadata.json",
);
+ const image = await caller.image.findUnique({
+ path: imageDbPath,
+ });
+
res.writeHead(200, {
"Content-Type": "image/png",
});
- res.end(img);
+ if (image?.blurDataURL) {
+ const img = Buffer.from(
+ image.blurDataURL.replace(
+ /^data:image\/(png|jpeg|jpg);base64,/,
+ "",
+ ),
+ "base64",
+ );
+ res.end(img);
+ } else {
+ const file = readFileSync(join(path, req.path));
+ const { base64 } = await getPlaiceholder(file);
+ const img = Buffer.from(
+ base64.replace(/^data:image\/(png|jpeg|jpg);base64,/, ""),
+ "base64",
+ );
+
+ void caller.image.update({
+ path: imageDbPath,
+ blurDataURL: `data:image/png;base64,${img.toString("base64")}`,
+ });
+
+ res.end(img);
+ }
})();
}),
);
@@ -69,11 +106,9 @@ export const startStaticServer = async (path: string, port?: number) => {
res.end("Not Found");
});
- server = app.listen(_port, () => {
- console.log(`static server is listening on http://localhost:${_port}`);
+ server = app.listen(port, () => {
+ console.log(`static server is listening on http://localhost:${port}`);
});
-
- return port;
};
export const stopStaticServer = () => {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index acae9886..4217672e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -326,12 +326,12 @@ importers:
packages/static-server:
dependencies:
+ '@rao-pics/api':
+ specifier: workspace:^
+ version: link:../api
express:
specifier: ^4.18.2
version: 4.18.2
- get-port:
- specifier: ^7.0.0
- version: 7.0.0
plaiceholder:
specifier: ^3.0.0
version: 3.0.0(sharp@0.32.5)
@@ -360,9 +360,6 @@ importers:
eslint:
specifier: ^8.47.0
version: 8.47.0
- ts-node:
- specifier: ^10.9.1
- version: 10.9.1(@types/node@18.17.6)(typescript@5.1.6)
typescript:
specifier: ^5.1.6
version: 5.1.6
@@ -846,13 +843,6 @@ packages:
resolution: {integrity: sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==}
dev: false
- /@cspotcode/source-map-support@0.8.1:
- resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
- engines: {node: '>=12'}
- dependencies:
- '@jridgewell/trace-mapping': 0.3.9
- dev: true
-
/@csstools/selector-specificity@3.0.0(postcss-selector-parser@6.0.13):
resolution: {integrity: sha512-hBI9tfBtuPIi885ZsZ32IMEU/5nlZH/KOVYJCOh7gyMxaVLGmLedYqFN6Ui1LXkI8JlC8IsuC0rF0btcRZKd5g==}
engines: {node: ^14 || ^16 || >=18}
@@ -1316,13 +1306,6 @@ packages:
'@jridgewell/resolve-uri': 3.1.0
'@jridgewell/sourcemap-codec': 1.4.14
- /@jridgewell/trace-mapping@0.3.9:
- resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
- dependencies:
- '@jridgewell/resolve-uri': 3.1.0
- '@jridgewell/sourcemap-codec': 1.4.15
- dev: true
-
/@malept/cross-spawn-promise@1.1.1:
resolution: {integrity: sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==}
engines: {node: '>= 10'}
@@ -1800,22 +1783,6 @@ packages:
resolution: {integrity: sha512-r3VeA319/braYMBIzj+XLgLKQ9lJSVglvPvP9HUv4kr5w6Y5grQMxMcExhTiZWltE9bnSJHKtBBzHafOo7KC8A==}
dev: false
- /@tsconfig/node10@1.0.9:
- resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==}
- dev: true
-
- /@tsconfig/node12@1.0.11:
- resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==}
- dev: true
-
- /@tsconfig/node14@1.0.3:
- resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==}
- dev: true
-
- /@tsconfig/node16@1.0.4:
- resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
- dev: true
-
/@types/acorn@4.0.6:
resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==}
dependencies:
@@ -2481,10 +2448,6 @@ packages:
resolution: {integrity: sha512-Wk7TEzl1KqvTGs/uyhmHO/3XLd3t1UeU4IstvPXVzGPM522cTjqjNZ99esCkcL52sjqjo8e8CTBcWhkxvGzoAw==}
dev: false
- /arg@4.1.3:
- resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
- dev: true
-
/arg@5.0.2:
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
@@ -3221,10 +3184,6 @@ packages:
dev: true
optional: true
- /create-require@1.1.1:
- resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
- dev: true
-
/cross-env@7.0.3:
resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==}
engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'}
@@ -3783,11 +3742,6 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dev: true
- /diff@4.0.2:
- resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
- engines: {node: '>=0.3.1'}
- dev: true
-
/diff@5.1.0:
resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==}
engines: {node: '>=0.3.1'}
@@ -6088,10 +6042,6 @@ packages:
semver: 7.5.4
dev: true
- /make-error@1.3.6:
- resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
- dev: true
-
/make-fetch-happen@11.1.1:
resolution: {integrity: sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
@@ -9062,37 +9012,6 @@ packages:
/ts-interface-checker@0.1.13:
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
- /ts-node@10.9.1(@types/node@18.17.6)(typescript@5.1.6):
- resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
- hasBin: true
- peerDependencies:
- '@swc/core': '>=1.2.50'
- '@swc/wasm': '>=1.2.50'
- '@types/node': '*'
- typescript: '>=2.7'
- peerDependenciesMeta:
- '@swc/core':
- optional: true
- '@swc/wasm':
- optional: true
- dependencies:
- '@cspotcode/source-map-support': 0.8.1
- '@tsconfig/node10': 1.0.9
- '@tsconfig/node12': 1.0.11
- '@tsconfig/node14': 1.0.3
- '@tsconfig/node16': 1.0.4
- '@types/node': 18.17.6
- acorn: 8.10.0
- acorn-walk: 8.2.0
- arg: 4.1.3
- create-require: 1.1.1
- diff: 4.0.2
- make-error: 1.3.6
- typescript: 5.1.6
- v8-compile-cache-lib: 3.0.1
- yn: 3.1.1
- dev: true
-
/tsconfig-paths@3.14.2:
resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==}
dependencies:
@@ -9484,10 +9403,6 @@ packages:
sade: 1.8.1
dev: false
- /v8-compile-cache-lib@3.0.1:
- resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
- dev: true
-
/v8-to-istanbul@9.1.0:
resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==}
engines: {node: '>=10.12.0'}
@@ -9849,11 +9764,6 @@ packages:
buffer-crc32: 0.2.13
fd-slicer: 1.1.0
- /yn@3.1.1:
- resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
- engines: {node: '>=6'}
- dev: true
-
/yocto-queue@0.1.0:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
diff --git a/themes/tiga-basic/src/pages/index.tsx b/themes/tiga-basic/src/pages/index.tsx
index 3208eb9c..4d49bd50 100644
--- a/themes/tiga-basic/src/pages/index.tsx
+++ b/themes/tiga-basic/src/pages/index.tsx
@@ -54,7 +54,6 @@ function Home() {
gallery: "#" + id,
children: "a.photo-swipe-lightbox-a",
pswpModule: () => import("photoswipe"),
- showHideAnimationType: "none",
});
lightbox.init();
@@ -62,11 +61,11 @@ function Home() {
lightbox?.destroy();
lightbox = null;
};
- }, []);
+ }, [config]);
return (
{pages?.map((page) => {
@@ -78,9 +77,15 @@ function Home() {
return {
id: image.id,
src,
- blurDataURL,
+ blurDataURL: image.blurDataURL ?? blurDataURL,
width: image.width,
height: image.height,
+ srcset: [
+ 16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200,
+ 1920, 2048, 3840,
+ ]
+ .map((size) => `/_next/image?url=${src}?w=${size}&q=75 ${size}w`)
+ .join(", "),
};
});
@@ -98,29 +103,13 @@ function Home() {
layout="rows"
photos={photos}
breakpoints={[640, 768, 1024, 1280, 1536]}
- spacing={(containerWidth) => {
- if (containerWidth < 640) return 4;
- if (containerWidth < 768) return 8;
- if (containerWidth < 1024) return 12;
- if (containerWidth < 1280) return 16;
- if (containerWidth < 1536) return 20;
- return 20;
- }}
- columns={(containerWidth) => {
- if (containerWidth < 640) return 1;
- if (containerWidth < 768) return 2;
- if (containerWidth < 1024) return 3;
- if (containerWidth < 1280) return 4;
- if (containerWidth < 1536) return 5;
- return Math.floor(containerWidth / 240);
- }}
+ spacing={16}
targetRowHeight={(containerWidth) => {
- if (containerWidth < 640) return containerWidth / 2;
- if (containerWidth < 768) return containerWidth / 3;
- if (containerWidth < 1024) return containerWidth / 4;
- if (containerWidth < 1280) return containerWidth / 5;
- if (containerWidth < 1536) return containerWidth / 6;
- return containerWidth / 6;
+ if (containerWidth < 640) return containerWidth / 1;
+ if (containerWidth < 768) return containerWidth / 1;
+ if (containerWidth < 1024) return containerWidth / 3;
+ if (containerWidth < 1280) return containerWidth / 4;
+ return containerWidth / 5;
}}
renderPhoto={NextJsImage}
onClick={({ index }) => setIndex(index)}
@@ -148,8 +137,9 @@ function NextJsImage({
href={photo.src}
data-pswp-width={photo.width}
data-pswp-height={photo.height}
+ data-src-set={photo.srcSet}
key={`photo-swipe-lightbox-${photo.id}`}
- className="photo-swipe-lightbox-a select-none"
+ className="photo-swipe-lightbox-a select-none overflow-hidden rounded-md border shadow"
style={{ ...wrapperStyle, position: "relative" }}
target="_blank"
rel="noreferrer"