{
+ // We want the URL and title to update as you scroll, but
+ // we can't trigger a NextJS navigation since that would remount the
+ // component. So, here we replicate the metadata behavior of the route.
+ const skinMd5 = skins[visibleSkinIndex].md5;
+ const newUrl = `/scroll/skin/${skinMd5}`;
+ window.document.title = `${skins[visibleSkinIndex].fileName} - Winamp Skin Museum`;
+ window.history.replaceState(
+ { ...window.history.state, as: newUrl, url: newUrl },
+ "",
+ newUrl
+ );
+
logUserEvent(sessionId, {
type: "skin_view_start",
- skinMd5: skins[visibleSkinIndex].md5,
+ skinMd5,
});
const startTime = Date.now();
return () => {
diff --git a/packages/skin-database/app/(modern)/scroll/grid/getMuseumPageSkins.ts b/packages/skin-database/app/(modern)/scroll/getMuseumPageSkins.ts
similarity index 86%
rename from packages/skin-database/app/(modern)/scroll/grid/getMuseumPageSkins.ts
rename to packages/skin-database/app/(modern)/scroll/getMuseumPageSkins.ts
index 4be6b404..a614cdc6 100644
--- a/packages/skin-database/app/(modern)/scroll/grid/getMuseumPageSkins.ts
+++ b/packages/skin-database/app/(modern)/scroll/getMuseumPageSkins.ts
@@ -1,6 +1,6 @@
"use server";
-import { getMuseumPage, getScreenshotUrl } from "../../../../data/skins";
+import { getMuseumPage, getScreenshotUrl } from "../../../data/skins";
export type GridSkin = {
md5: string;
diff --git a/packages/skin-database/app/(modern)/scroll/grid/layout.tsx b/packages/skin-database/app/(modern)/scroll/grid/layout.tsx
deleted file mode 100644
index da627208..00000000
--- a/packages/skin-database/app/(modern)/scroll/grid/layout.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import { ReactNode } from "react";
-
-type LayoutProps = {
- children: ReactNode;
-};
-
-export default function Layout({ children }: LayoutProps) {
- return
{children}
;
-}
diff --git a/packages/skin-database/app/(modern)/scroll/grid/page.tsx b/packages/skin-database/app/(modern)/scroll/grid/page.tsx
deleted file mode 100644
index 4a2a3dd2..00000000
--- a/packages/skin-database/app/(modern)/scroll/grid/page.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import React from "react";
-import Grid from "./Grid";
-import { getMuseumPageSkins } from "./getMuseumPageSkins";
-import * as Skins from "../../../../data/skins";
-
-export default async function SkinTable() {
- const [initialSkins, skinCount] = await Promise.all([
- getMuseumPageSkins(0, 50),
- Skins.getClassicSkinCount(),
- ]);
-
- return
;
-}
diff --git a/packages/skin-database/app/(modern)/scroll/page.tsx b/packages/skin-database/app/(modern)/scroll/page.tsx
index 620c69a5..88c9e09c 100644
--- a/packages/skin-database/app/(modern)/scroll/page.tsx
+++ b/packages/skin-database/app/(modern)/scroll/page.tsx
@@ -1,24 +1,13 @@
-import SessionModel from "../../../data/SessionModel";
-import { getClientSkins } from "./getClientSkins";
-import SkinScroller from "./SkinScroller";
+import React from "react";
+import Grid from "./Grid";
+import { getMuseumPageSkins } from "./getMuseumPageSkins";
+import * as Skins from "../../..//data/skins";
-// Ensure each page load gets a new session
-export const dynamic = "force-dynamic";
-
-/**
- * A tik-tok style scroll page where we display one skin at a time in full screen
- */
-export default async function ScrollPage() {
- // Create the session in the database
- const sessionId = await SessionModel.create();
-
- const initialSkins = await getClientSkins(sessionId);
-
- return (
-
- );
+export default async function SkinTable() {
+ const [initialSkins, skinCount] = await Promise.all([
+ getMuseumPageSkins(0, 50),
+ Skins.getClassicSkinCount(),
+ ]);
+ console.log("SERVER RENDER generic");
+ return
;
}
diff --git a/packages/skin-database/app/(modern)/scroll/skin/[md5]/page.tsx b/packages/skin-database/app/(modern)/scroll/skin/[md5]/page.tsx
index 89b8ac16..2cae8731 100644
--- a/packages/skin-database/app/(modern)/scroll/skin/[md5]/page.tsx
+++ b/packages/skin-database/app/(modern)/scroll/skin/[md5]/page.tsx
@@ -1,7 +1,14 @@
+import { Metadata } from "next";
import SessionModel from "../../../../../data/SessionModel";
import UserContext from "../../../../../data/UserContext";
import { getClientSkins, getSkinForSession } from "../../getClientSkins";
import SkinScroller from "../../SkinScroller";
+import { generateSkinPageMetadata } from "../../../../(legacy)/skin/[hash]/skinMetadata";
+
+export async function generateMetadata({ params }): Promise
{
+ const { md5 } = await params;
+ return generateSkinPageMetadata(md5);
+}
// Ensure each page load gets a new session
export const dynamic = "force-dynamic";
diff --git a/packages/skin-database/app/(modern)/scroll/skin/page.tsx b/packages/skin-database/app/(modern)/scroll/skin/page.tsx
new file mode 100644
index 00000000..c752b03a
--- /dev/null
+++ b/packages/skin-database/app/(modern)/scroll/skin/page.tsx
@@ -0,0 +1,25 @@
+import SessionModel from "../../../../data/SessionModel";
+import { getClientSkins } from "../getClientSkins";
+import SkinScroller from "../SkinScroller";
+
+// Ensure each page load gets a new session
+export const dynamic = "force-dynamic";
+
+/**
+ * A tik-tok style scroll page where we display one skin at a time in full screen
+ */
+export default async function ScrollPage() {
+ // Create the session in the database
+ const sessionId = await SessionModel.create();
+
+ const initialSkins = await getClientSkins(sessionId);
+ console.log("SERVER RENDER generic");
+
+ return (
+
+ );
+}
diff --git a/packages/skin-database/app/bulk-download/page.tsx b/packages/skin-database/app/bulk-download/page.tsx
index e8b8b81e..06c11a1c 100644
--- a/packages/skin-database/app/bulk-download/page.tsx
+++ b/packages/skin-database/app/bulk-download/page.tsx
@@ -99,7 +99,7 @@ export default function BulkDownloadPage() {
completedSkins: prev.completedSkins + 1,
}));
return;
- } catch (error) {
+ } catch (_) {
// File doesn't exist, continue with download
}
@@ -277,6 +277,7 @@ export default function BulkDownloadPage() {
}
for (const skin of skins) {
+ // eslint-disable-next-line max-depth
if (abortController.current.signal.aborted) break;
await waitForAvailableSlot(
@@ -284,6 +285,7 @@ export default function BulkDownloadPage() {
abortController.current.signal
);
+ // eslint-disable-next-line max-depth
if (abortController.current.signal.aborted) break;
const downloadPromise = downloadSkin(