From f1339901e69a427b02ba1143c8aa7764db93c47b Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Fri, 7 Nov 2025 19:12:08 -0800 Subject: [PATCH] Stub out permalink page --- .../app/(modern)/scroll/getClientSkins.ts | 47 +++++++++++++++++++ .../app/(modern)/scroll/layout.tsx | 1 + .../app/(modern)/scroll/page.tsx | 40 +--------------- .../app/(modern)/scroll/skin/[md5]/page.tsx | 23 +++++++++ 4 files changed, 73 insertions(+), 38 deletions(-) create mode 100644 packages/skin-database/app/(modern)/scroll/getClientSkins.ts create mode 100644 packages/skin-database/app/(modern)/scroll/skin/[md5]/page.tsx diff --git a/packages/skin-database/app/(modern)/scroll/getClientSkins.ts b/packages/skin-database/app/(modern)/scroll/getClientSkins.ts new file mode 100644 index 00000000..e39a1540 --- /dev/null +++ b/packages/skin-database/app/(modern)/scroll/getClientSkins.ts @@ -0,0 +1,47 @@ +import UserContext from "../../../data/UserContext"; +import SessionModel from "../../../data/SessionModel"; +import { ClientSkin } from "./SkinScroller"; +import { getScrollPage } from "../../../data/skins"; +import SkinModel from "../../../data/SkinModel"; + +// Ensure each page load gets a new session +export const dynamic = "force-dynamic"; + +export async function getClientSkins(sessionId: string): Promise { + "use server"; + const ctx = new UserContext(); + + const page = await getScrollPage(sessionId); + + return await Promise.all( + page.map(async (item) => { + return getSkinForSession(ctx, sessionId, item.md5); + }) + ); +} + +export async function getSkinForSession( + ctx: UserContext, + sessionId: string, + md5: string +) { + const model = await SkinModel.fromMd5Assert(ctx, md5); + const readmeText = await model.getReadme(); + const fileName = await model.getFileName(); + const tweet = await model.getTweet(); + const likeCount = tweet ? tweet.getLikes() : 0; + + SessionModel.addSkin(sessionId, md5); + + return { + screenshotUrl: model.getScreenshotUrl(), + md5, + // TODO: Normalize to .wsz + fileName: fileName, + readmeStart: readmeText ? readmeText.slice(0, 200) : "", + downloadUrl: model.getSkinUrl(), + shareUrl: `https://skins.webamp.org/scroll/skin/${md5}`, + nsfw: await model.getIsNsfw(), + likeCount: likeCount, + }; +} diff --git a/packages/skin-database/app/(modern)/scroll/layout.tsx b/packages/skin-database/app/(modern)/scroll/layout.tsx index 75abcf9a..c2aaedf3 100644 --- a/packages/skin-database/app/(modern)/scroll/layout.tsx +++ b/packages/skin-database/app/(modern)/scroll/layout.tsx @@ -2,6 +2,7 @@ import { ReactNode } from "react"; import BottomMenuBar from "./BottomMenuBar"; +import "./scroll.css"; type LayoutProps = { children: ReactNode; diff --git a/packages/skin-database/app/(modern)/scroll/page.tsx b/packages/skin-database/app/(modern)/scroll/page.tsx index 25576a49..620c69a5 100644 --- a/packages/skin-database/app/(modern)/scroll/page.tsx +++ b/packages/skin-database/app/(modern)/scroll/page.tsx @@ -1,46 +1,10 @@ -import UserContext from "../../../data/UserContext"; import SessionModel from "../../../data/SessionModel"; -import "./scroll.css"; -import SkinScroller, { ClientSkin } from "./SkinScroller"; -import { getScrollPage } from "../../../data/skins"; -import SkinModel from "../../../data/SkinModel"; +import { getClientSkins } from "./getClientSkins"; +import SkinScroller from "./SkinScroller"; // Ensure each page load gets a new session export const dynamic = "force-dynamic"; -async function getClientSkins(sessionId: string): Promise { - "use server"; - const ctx = new UserContext(); - - const page = await getScrollPage(sessionId); - - const skins = await Promise.all( - page.map(async (item) => { - const model = await SkinModel.fromMd5Assert(ctx, item.md5); - const readmeText = await model.getReadme(); - const fileName = await model.getFileName(); - const tweet = await model.getTweet(); - const likeCount = tweet ? tweet.getLikes() : 0; - - return { - screenshotUrl: model.getScreenshotUrl(), - md5: item.md5, - // TODO: Normalize to .wsz - fileName: fileName, - readmeStart: readmeText ? readmeText.slice(0, 200) : "", - downloadUrl: model.getSkinUrl(), - shareUrl: `https://skins.webamp.org/skin/${item.md5}`, - nsfw: await model.getIsNsfw(), - likeCount: likeCount, - }; - }) - ); - for (const skin of skins) { - SessionModel.addSkin(sessionId, skin.md5); - } - return skins; -} - /** * A tik-tok style scroll page where we display one skin at a time in full screen */ diff --git a/packages/skin-database/app/(modern)/scroll/skin/[md5]/page.tsx b/packages/skin-database/app/(modern)/scroll/skin/[md5]/page.tsx new file mode 100644 index 00000000..f04e6092 --- /dev/null +++ b/packages/skin-database/app/(modern)/scroll/skin/[md5]/page.tsx @@ -0,0 +1,23 @@ +import SessionModel from "../../../../../data/SessionModel"; +import UserContext from "../../../../../data/UserContext"; +import { getClientSkins, getSkinForSession } from "../../getClientSkins"; +import SkinScroller from "../../SkinScroller"; + +export default async function Skin({ params }) { + const { md5 } = await params; + + // Create the session in the database + const sessionId = await SessionModel.create(); + + const ctx = new UserContext(); + const linked = await getSkinForSession(ctx, sessionId, md5); + const initialSkins = await getClientSkins(sessionId); + + return ( + + ); +}