mirror of
https://github.com/captbaritone/webamp.git
synced 2026-01-23 02:15:01 +00:00
Improve scroll UI
This commit is contained in:
parent
e062a51a88
commit
8d4ff41f42
13 changed files with 73 additions and 58 deletions
|
|
@ -1,5 +1,6 @@
|
|||
import App from "../App";
|
||||
|
||||
export default function Layout() {
|
||||
console.log("Render legacy layout");
|
||||
return <App />;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,18 +135,16 @@ export default function BottomMenuBar() {
|
|||
}}
|
||||
>
|
||||
<MenuButton
|
||||
href="/scroll/grid"
|
||||
href="/scroll"
|
||||
icon={<Grid3x3 size={24} />}
|
||||
label="Grid"
|
||||
isActive={pathname === "/scroll/grid"}
|
||||
isActive={pathname === "/scroll"}
|
||||
/>
|
||||
<MenuButton
|
||||
href="/scroll"
|
||||
href="/scroll/skin"
|
||||
icon={<Smartphone size={24} />}
|
||||
label="Feed"
|
||||
isActive={
|
||||
pathname === "/scroll" || pathname.startsWith("/scroll/skin")
|
||||
}
|
||||
isActive={pathname.startsWith("/scroll/skin")}
|
||||
/>
|
||||
|
||||
<MenuButton
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ import React, {
|
|||
|
||||
import Link from "next/link";
|
||||
import { FixedSizeGrid as Grid } from "react-window";
|
||||
import { useWindowSize } from "../../../../legacy-client/src/hooks";
|
||||
import { useWindowSize } from "../../../legacy-client/src/hooks";
|
||||
import {
|
||||
SCREENSHOT_WIDTH,
|
||||
SKIN_RATIO,
|
||||
} from "../../../../legacy-client/src/constants";
|
||||
} from "../../../legacy-client/src/constants";
|
||||
import { getMuseumPageSkins, GridSkin } from "./getMuseumPageSkins";
|
||||
|
||||
type CellData = {
|
||||
|
|
@ -10,11 +10,11 @@ import {
|
|||
} from "react";
|
||||
import { FixedSizeGrid as Grid } from "react-window";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { ClientSkin } from "../SkinScroller";
|
||||
import { ClientSkin } from "./SkinScroller";
|
||||
import {
|
||||
SCREENSHOT_WIDTH,
|
||||
SKIN_RATIO,
|
||||
} from "../../../../legacy-client/src/constants";
|
||||
} from "../../../legacy-client/src/constants";
|
||||
|
||||
type Props = {
|
||||
initialSkins: ClientSkin[];
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
"use client";
|
||||
|
||||
// @ts-expect-error - unstable_ViewTransition is not yet in @types/react
|
||||
import { unstable_ViewTransition as ViewTransition } from "react";
|
||||
import { useEffect, unstable_ViewTransition as ViewTransition } from "react";
|
||||
import { ClientSkin } from "./SkinScroller";
|
||||
import SkinActionIcons from "./SkinActionIcons";
|
||||
|
||||
|
|
@ -12,6 +12,9 @@ type Props = {
|
|||
};
|
||||
|
||||
export default function SkinPage({ skin, index, sessionId }: Props) {
|
||||
useEffect(() => {
|
||||
console.log("Mount SkinPage");
|
||||
}, []);
|
||||
return (
|
||||
<div
|
||||
key={skin.md5}
|
||||
|
|
|
|||
|
|
@ -109,9 +109,21 @@ export default function SkinScroller({
|
|||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
// 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 () => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use server";
|
||||
|
||||
import { getMuseumPage, getScreenshotUrl } from "../../../../data/skins";
|
||||
import { getMuseumPage, getScreenshotUrl } from "../../../data/skins";
|
||||
|
||||
export type GridSkin = {
|
||||
md5: string;
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
import { ReactNode } from "react";
|
||||
|
||||
type LayoutProps = {
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
export default function Layout({ children }: LayoutProps) {
|
||||
return <div style={{}}>{children}</div>;
|
||||
}
|
||||
|
|
@ -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 <Grid initialSkins={initialSkins} initialTotal={skinCount} />;
|
||||
}
|
||||
|
|
@ -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 (
|
||||
<SkinScroller
|
||||
initialSkins={initialSkins}
|
||||
getSkins={getClientSkins}
|
||||
sessionId={sessionId}
|
||||
/>
|
||||
);
|
||||
export default async function SkinTable() {
|
||||
const [initialSkins, skinCount] = await Promise.all([
|
||||
getMuseumPageSkins(0, 50),
|
||||
Skins.getClassicSkinCount(),
|
||||
]);
|
||||
console.log("SERVER RENDER generic");
|
||||
return <Grid initialSkins={initialSkins} initialTotal={skinCount} />;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Metadata> {
|
||||
const { md5 } = await params;
|
||||
return generateSkinPageMetadata(md5);
|
||||
}
|
||||
|
||||
// Ensure each page load gets a new session
|
||||
export const dynamic = "force-dynamic";
|
||||
|
|
|
|||
25
packages/skin-database/app/(modern)/scroll/skin/page.tsx
Normal file
25
packages/skin-database/app/(modern)/scroll/skin/page.tsx
Normal file
|
|
@ -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 (
|
||||
<SkinScroller
|
||||
initialSkins={initialSkins}
|
||||
getSkins={getClientSkins}
|
||||
sessionId={sessionId}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
@ -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(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue