From 37d49069e5b75ea168d3b539e22a7b2e15d0a3a1 Mon Sep 17 00:00:00 2001 From: monoid Date: Sat, 6 Apr 2024 08:19:56 +0900 Subject: [PATCH] some refactor --- packages/client/src/App.tsx | 4 +- .../src/components/gallery/GalleryCard.tsx | 46 +++---------------- .../src/components/gallery/LazyImage.tsx | 37 +++++++++++++++ packages/client/src/page/contentInfoPage.tsx | 20 ++++++++ packages/client/src/page/profilesPage.tsx | 4 +- packages/server/src/route/comic.ts | 14 ++++-- packages/server/src/util/zipwrap.ts | 3 -- 7 files changed, 78 insertions(+), 50 deletions(-) create mode 100644 packages/client/src/components/gallery/LazyImage.tsx create mode 100644 packages/client/src/page/contentInfoPage.tsx diff --git a/packages/client/src/App.tsx b/packages/client/src/App.tsx index 539f446..cc0398a 100644 --- a/packages/client/src/App.tsx +++ b/packages/client/src/App.tsx @@ -21,6 +21,7 @@ import Layout from "./components/layout/layout"; import NotFoundPage from "./page/404"; import LoginPage from "./page/loginPage"; import ProfilePage from "./page/profilesPage"; +import ContentInfoPage from "./page/contentInfoPage"; const App = () => { return ( @@ -31,7 +32,8 @@ const App = () => { - {/* }> + + {/* }> }> }> diff --git a/packages/client/src/components/gallery/GalleryCard.tsx b/packages/client/src/components/gallery/GalleryCard.tsx index 30f6bcc..4e0aaac 100644 --- a/packages/client/src/components/gallery/GalleryCard.tsx +++ b/packages/client/src/components/gallery/GalleryCard.tsx @@ -2,6 +2,8 @@ import type { Document } from "dbtype/api"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import TagBadge from "@/components/gallery/TagBadge"; import { useEffect, useRef, useState } from "react"; +import { Link, useLocation } from "wouter"; +import { LazyImage } from "./LazyImage"; function clipTagsWhenOverflow(tags: string[], limit: number) { let l = 0; @@ -15,48 +17,12 @@ function clipTagsWhenOverflow(tags: string[], limit: number) { return tags; } -function LazyImage({ src, alt, className }: { src: string; alt: string; className?: string; }) { - const ref = useRef(null); - const [loaded, setLoaded] = useState(false); - - useEffect(() => { - if (ref.current) { - let toggle = false; - const observer = new IntersectionObserver((entries) => { - if (entries.some(x => x.isIntersecting)) { - setLoaded(true); - toggle = !toggle; - ref.current?.animate([{ opacity: 0 }, { opacity: 1 }], { duration: 500, easing: "ease-in-out" }); - observer.disconnect(); - } - else { - if (toggle) { - console.log("fade out"); - ref.current?.animate([{ opacity: 1 }, { opacity: 0 }], { duration: 500, easing: "ease-in-out" }); - } - } - }); - observer.observe(ref.current); - return () => { - observer.disconnect(); - }; - } - }, []); - - return {alt}; -} - export function GalleryCard({ doc: x }: { doc: Document; }) { const ref = useRef(null); const [clipCharCount, setClipCharCount] = useState(200); + const [location] = useLocation(); const artists = x.tags.filter(x => x.startsWith("artist:")).map(x => x.replace("artist:", "")); const groups = x.tags.filter(x => x.startsWith("group:")).map(x => x.replace("group:", "")); @@ -84,11 +50,13 @@ export function GalleryCard({ + />
- {x.title} + + {x.title} + {artists.join(", ")} {groups.length > 0 && "|"} {groups.join(", ")} diff --git a/packages/client/src/components/gallery/LazyImage.tsx b/packages/client/src/components/gallery/LazyImage.tsx new file mode 100644 index 0000000..6520da7 --- /dev/null +++ b/packages/client/src/components/gallery/LazyImage.tsx @@ -0,0 +1,37 @@ +import { useEffect, useRef, useState } from "react"; + +export function LazyImage({ src, alt, className }: { src: string; alt: string; className?: string; }) { + const ref = useRef(null); + const [loaded, setLoaded] = useState(false); + + useEffect(() => { + if (ref.current) { + let toggle = false; + const observer = new IntersectionObserver((entries) => { + if (entries.some(x => x.isIntersecting)) { + setLoaded(true); + toggle = !toggle; + ref.current?.animate([{ opacity: 0 }, { opacity: 1 }], { duration: 500, easing: "ease-in-out" }); + observer.disconnect(); + } + else { + if (toggle) { + console.log("fade out"); + ref.current?.animate([{ opacity: 1 }, { opacity: 0 }], { duration: 500, easing: "ease-in-out" }); + } + } + }); + observer.observe(ref.current); + return () => { + observer.disconnect(); + }; + } + }, []); + + return {alt}; +} diff --git a/packages/client/src/page/contentInfoPage.tsx b/packages/client/src/page/contentInfoPage.tsx new file mode 100644 index 0000000..abd4f91 --- /dev/null +++ b/packages/client/src/page/contentInfoPage.tsx @@ -0,0 +1,20 @@ +export interface ContentInfoPageProps { + params: { + id: string; + }; +} + + + +export function ContentInfoPage({params}: ContentInfoPageProps) { + + return ( +
+

ContentInfoPage

+ {params.id} +

Find me in packages/client/src/page/contentInfoPage.tsx

+
+ ); +} + +export default ContentInfoPage; \ No newline at end of file diff --git a/packages/client/src/page/profilesPage.tsx b/packages/client/src/page/profilesPage.tsx index d19f7b4..852bd42 100644 --- a/packages/client/src/page/profilesPage.tsx +++ b/packages/client/src/page/profilesPage.tsx @@ -1,4 +1,4 @@ -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { useLogin } from "@/state/user"; import { Redirect } from "wouter"; @@ -9,7 +9,7 @@ export function ProfilePage() { return ; } return ( -
+
Profile diff --git a/packages/server/src/route/comic.ts b/packages/server/src/route/comic.ts index 2dd34ea..7991e4c 100644 --- a/packages/server/src/route/comic.ts +++ b/packages/server/src/route/comic.ts @@ -1,11 +1,11 @@ -import { type Context, DefaultContext, DefaultState, Next } from "koa"; +import type { Context } from "koa"; import Router from "koa-router"; import { createReadableStreamFromZip, entriesByNaturalOrder, readZip } from "../util/zipwrap"; import type { ContentContext } from "./context"; import { since_last_modified } from "./util"; import type { ZipReader } from "@zip.js/zip.js"; import type { FileHandle } from "node:fs/promises"; -import { Readable, Writable } from "node:stream"; +import { Readable } from "node:stream"; /** * zip stream cache. @@ -91,11 +91,15 @@ async function renderZipImage(ctx: Context, path: string, page: number) { }, close() { nodeReadableStream.push(null); - releaseZip(path); - // setTimeout(() => { - // }, 500); }, })); + nodeReadableStream.on("error", (err) => { + console.error(err); + releaseZip(path); + }); + nodeReadableStream.on("close", () => { + releaseZip(path); + }); ctx.body = nodeReadableStream; ctx.response.length = entry.uncompressedSize; diff --git a/packages/server/src/util/zipwrap.ts b/packages/server/src/util/zipwrap.ts index 8699d84..187655f 100644 --- a/packages/server/src/util/zipwrap.ts +++ b/packages/server/src/util/zipwrap.ts @@ -4,15 +4,12 @@ import { ZipReader, Reader, type Entry } from "@zip.js/zip.js"; class FileReader extends Reader { private fd: FileHandle; - private offset: number; constructor(fd: FileHandle) { super(fd); this.fd = fd; - this.offset = 0; } async init(): Promise { - this.offset = 0; this.size = (await this.fd.stat()).size; } close(): void {