mirror of
https://github.com/captbaritone/webamp.git
synced 2026-01-23 02:15:01 +00:00
Start wiring up Webamp in scroller museum UI
This commit is contained in:
parent
52f12327fa
commit
4b784b6eaf
4 changed files with 221 additions and 6 deletions
|
|
@ -1,20 +1,20 @@
|
|||
"use client";
|
||||
|
||||
// @ts-expect-error - unstable_ViewTransition is not yet in @types/react
|
||||
import { useEffect, unstable_ViewTransition as ViewTransition } from "react";
|
||||
import { unstable_ViewTransition as ViewTransition } from "react";
|
||||
import { ClientSkin } from "./SkinScroller";
|
||||
import SkinActionIcons from "./SkinActionIcons";
|
||||
import WebampComponent from "./Webamp";
|
||||
|
||||
type Props = {
|
||||
skin: ClientSkin;
|
||||
index: number;
|
||||
sessionId: string;
|
||||
focused: boolean;
|
||||
};
|
||||
|
||||
export default function SkinPage({ skin, index, sessionId }: Props) {
|
||||
useEffect(() => {
|
||||
console.log("Mount SkinPage");
|
||||
}, []);
|
||||
export default function SkinPage({ skin, index, sessionId, focused }: Props) {
|
||||
const showWebamp = focused && false; // Disable for now
|
||||
return (
|
||||
<div
|
||||
key={skin.md5}
|
||||
|
|
@ -41,11 +41,19 @@ export default function SkinPage({ skin, index, sessionId }: Props) {
|
|||
src={skin.screenshotUrl}
|
||||
alt={skin.fileName}
|
||||
style={{
|
||||
position: "relative",
|
||||
width: "100%",
|
||||
aspectRatio: "275 / 348",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
/>
|
||||
{showWebamp && (
|
||||
<WebampComponent
|
||||
skinUrl={skin.skinUrl}
|
||||
closeModal={() => {}}
|
||||
loaded={() => {}}
|
||||
/>
|
||||
)}
|
||||
</ViewTransition>
|
||||
|
||||
<SkinActionIcons skin={skin} sessionId={sessionId} />
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { MOBILE_MAX_WIDTH } from "../../../legacy-client/src/constants";
|
|||
|
||||
export type ClientSkin = {
|
||||
screenshotUrl: string;
|
||||
skinUrl: string;
|
||||
fileName: string;
|
||||
md5: string;
|
||||
readmeStart: string;
|
||||
|
|
@ -190,6 +191,7 @@ export default function SkinScroller({
|
|||
key={skin.md5}
|
||||
skin={skin}
|
||||
index={i}
|
||||
focused={i === visibleSkinIndex}
|
||||
sessionId={sessionId}
|
||||
/>
|
||||
);
|
||||
|
|
|
|||
204
packages/skin-database/app/(modern)/scroll/Webamp.tsx
Normal file
204
packages/skin-database/app/(modern)/scroll/Webamp.tsx
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
import React, { useEffect, useRef } from "react";
|
||||
import {
|
||||
SCREENSHOT_HEIGHT,
|
||||
SCREENSHOT_WIDTH,
|
||||
} from "../../../legacy-client/src/constants";
|
||||
|
||||
type Props = {
|
||||
skinUrl: string;
|
||||
closeModal: () => void;
|
||||
loaded: () => void;
|
||||
};
|
||||
|
||||
export default function WebampComponent({
|
||||
skinUrl,
|
||||
closeModal,
|
||||
loaded,
|
||||
}: Props) {
|
||||
const ref = useRef<HTMLDivElement | null>(null);
|
||||
const outerRef = useRef<HTMLDivElement | null>(null);
|
||||
// @ts-ignore
|
||||
const webampRef = useRef<typeof import("webamp") | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
let disposed = false;
|
||||
let cleanup = () => {};
|
||||
|
||||
async function loadWebamp() {
|
||||
// @ts-ignore
|
||||
const { default: Webamp } = await import("webamp");
|
||||
|
||||
if (disposed) return;
|
||||
|
||||
const webamp = new Webamp({
|
||||
initialSkin: { url: skinUrl },
|
||||
initialTracks,
|
||||
hotkeys: true,
|
||||
zIndex: 1001,
|
||||
});
|
||||
|
||||
webampRef.current = webamp;
|
||||
cleanup = () => webamp.dispose();
|
||||
|
||||
webamp.onClose(closeModal);
|
||||
await webamp.renderWhenReady(ref.current);
|
||||
const { width } = outerRef.current!.getBoundingClientRect();
|
||||
const zoom = width / SCREENSHOT_WIDTH;
|
||||
console.log("Setting zoom:", zoom);
|
||||
document
|
||||
.getElementById("webamp")
|
||||
?.style.setProperty("zoom", String(zoom));
|
||||
|
||||
if (!disposed) loaded();
|
||||
}
|
||||
|
||||
loadWebamp();
|
||||
|
||||
return () => {
|
||||
disposed = true;
|
||||
cleanup();
|
||||
};
|
||||
}, [skinUrl, closeModal, loaded]);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={outerRef}
|
||||
style={{
|
||||
top: 0,
|
||||
position: "absolute",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="webamp-container"
|
||||
style={{
|
||||
width: SCREENSHOT_WIDTH,
|
||||
height: SCREENSHOT_HEIGHT,
|
||||
}}
|
||||
ref={ref}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const album = "netBloc Vol. 24: tiuqottigeloot";
|
||||
|
||||
const initialTracks = [
|
||||
{
|
||||
metaData: {
|
||||
artist: "DJ Mike Llama",
|
||||
title: "Llama Whippin' Intro",
|
||||
},
|
||||
url: "/llama.mp3",
|
||||
duration: 5.322286,
|
||||
},
|
||||
{
|
||||
url: "https://raw.githubusercontent.com/captbaritone/webamp-music/4b556fbf/Diablo_Swing_Orchestra_-_01_-_Heroines.mp3",
|
||||
duration: 322.612245,
|
||||
metaData: {
|
||||
title: "Heroines",
|
||||
artist: "Diablo Swing Orchestra",
|
||||
album,
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "https://raw.githubusercontent.com/captbaritone/webamp-music/4b556fbf/Eclectek_-_02_-_We_Are_Going_To_Eclecfunk_Your_Ass.mp3",
|
||||
duration: 190.093061,
|
||||
metaData: {
|
||||
title: "We Are Going To Eclecfunk Your Ass",
|
||||
artist: "Eclectek",
|
||||
album,
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "https://raw.githubusercontent.com/captbaritone/webamp-music/4b556fbf/Auto-Pilot_-_03_-_Seventeen.mp3",
|
||||
duration: 214.622041,
|
||||
metaData: {
|
||||
title: "Seventeen",
|
||||
artist: "Auto-Pilot",
|
||||
album,
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "https://raw.githubusercontent.com/captbaritone/webamp-music/4b556fbf/Muha_-_04_-_Microphone.mp3",
|
||||
duration: 181.838367,
|
||||
metaData: {
|
||||
title: "Microphone",
|
||||
artist: "Muha",
|
||||
album,
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "https://raw.githubusercontent.com/captbaritone/webamp-music/4b556fbf/Just_Plain_Ant_-_05_-_Stumble.mp3",
|
||||
duration: 86.047347,
|
||||
metaData: {
|
||||
title: "Stumble",
|
||||
artist: "Just Plain Ant",
|
||||
album,
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "https://raw.githubusercontent.com/captbaritone/webamp-music/4b556fbf/Sleaze_-_06_-_God_Damn.mp3",
|
||||
duration: 226.795102,
|
||||
metaData: {
|
||||
title: "God Damn",
|
||||
artist: "Sleaze",
|
||||
album,
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "https://raw.githubusercontent.com/captbaritone/webamp-music/4b556fbf/Juanitos_-_07_-_Hola_Hola_Bossa_Nova.mp3",
|
||||
duration: 207.072653,
|
||||
metaData: {
|
||||
title: "Hola Hola Bossa Nova",
|
||||
artist: "Juanitos",
|
||||
album,
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "https://raw.githubusercontent.com/captbaritone/webamp-music/4b556fbf/Entertainment_for_the_Braindead_-_08_-_Resolutions_Chris_Summer_Remix.mp3",
|
||||
duration: 314.331429,
|
||||
metaData: {
|
||||
title: "Resolutions (Chris Summer Remix)",
|
||||
artist: "Entertainment for the Braindead",
|
||||
album,
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "https://raw.githubusercontent.com/captbaritone/webamp-music/4b556fbf/Nobara_Hayakawa_-_09_-_Trail.mp3",
|
||||
duration: 204.042449,
|
||||
metaData: {
|
||||
title: "Trail",
|
||||
artist: "Nobara Hayakawa",
|
||||
album,
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "https://raw.githubusercontent.com/captbaritone/webamp-music/4b556fbf/Paper_Navy_-_10_-_Tongue_Tied.mp3",
|
||||
duration: 201.116735,
|
||||
metaData: {
|
||||
title: "Tongue Tied",
|
||||
artist: "Paper Navy",
|
||||
album,
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "https://raw.githubusercontent.com/captbaritone/webamp-music/4b556fbf/60_Tigres_-_11_-_Garage.mp3",
|
||||
duration: 245.394286,
|
||||
metaData: {
|
||||
title: "Garage",
|
||||
artist: "60 Tigres",
|
||||
album,
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "https://raw.githubusercontent.com/captbaritone/webamp-music/4b556fbf/CM_aka_Creative_-_12_-_The_Cycle_Featuring_Mista_Mista.mp3",
|
||||
duration: 221.44,
|
||||
metaData: {
|
||||
title: "The Cycle (Featuring Mista Mista)",
|
||||
artist: "CM aka Creative",
|
||||
album,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
|
@ -24,7 +24,7 @@ export async function getSkinForSession(
|
|||
ctx: UserContext,
|
||||
sessionId: string,
|
||||
md5: string
|
||||
) {
|
||||
): Promise<ClientSkin> {
|
||||
const model = await SkinModel.fromMd5Assert(ctx, md5);
|
||||
const readmeText = await model.getReadme();
|
||||
const fileName = await model.getFileName();
|
||||
|
|
@ -35,6 +35,7 @@ export async function getSkinForSession(
|
|||
|
||||
return {
|
||||
screenshotUrl: model.getScreenshotUrl(),
|
||||
skinUrl: model.getSkinUrl(),
|
||||
md5,
|
||||
// TODO: Normalize to .wsz
|
||||
fileName: fileName,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue