Files
picobook/src/client/GamePage.tsx
T

124 lines
3.2 KiB
TypeScript
Raw Normal View History

2024-04-03 20:29:27 -07:00
import { Link, useParams, useSearchParams } from "react-router-dom"
2024-04-03 22:53:11 -07:00
import { Pico8Console, Pico8ConsoleImperatives } from "./pico8-client/Pico8Console";
import { useEffect, useRef, useState } from "react";
2024-03-31 19:40:06 -07:00
import { DbRelease } from "../server/dbal/dbal";
import { css } from "@emotion/css";
2024-04-03 20:29:27 -07:00
import { useWebsocket } from "./hooks/useWebsocket";
2024-03-31 19:40:06 -07:00
type Info = {
release: DbRelease | null;
versions: string[];
}
export const GamePage = () => {
2024-04-02 19:04:34 -07:00
const {author, slug} = useParams();
2024-04-03 20:29:27 -07:00
const [searchParams, setSearchParams] = useSearchParams();
const room = searchParams.get('room');
2024-04-03 22:53:11 -07:00
const picoRef = useRef<Pico8ConsoleImperatives>(null);
2024-04-03 20:29:27 -07:00
const socket = useWebsocket({
url: `/api/ws/room?room=${room}`,
// url: "wss://echo.websocket.org",
onMessage({message}) {
2024-04-03 22:53:11 -07:00
const msg = message as any;
if (msg.type === "gpio") {
if (picoRef.current) {
const handle = picoRef.current.getPicoConsoleHandle();
if (handle) {
console.log("updating pico gpio");
(handle.gpio as any).dontSend = true;
handle.gpio.length = 0;
handle.gpio.push(...msg.gpio);
(handle.gpio as any).dontSend = false;
}
}
}
2024-04-03 20:29:27 -07:00
console.log('message', message);
}
})
2024-04-02 19:04:34 -07:00
// const version = searchParams.get('v');
const [v, setVersion] = useState<string | null>(null);
2024-03-31 19:40:06 -07:00
const [info, setInfo] = useState<Info | null>(null);
2024-03-31 21:25:54 -07:00
2024-04-02 19:04:34 -07:00
const version = v ?? info?.release?.version ?? info?.versions[0];
2024-03-31 19:40:06 -07:00
useEffect(() => {
const fetchInfo = async () => {
let url = `/api/release?author=${author}&slug=${slug}`;
if (version) {
2024-04-02 19:04:34 -07:00
url += `&version=${version}`;
2024-03-31 19:40:06 -07:00
}
const information = await fetch(url);
const json = await information.json();
setInfo(json);
}
fetchInfo();
}, [setInfo, author, slug, version]);
if (!info) {
return (
2024-04-02 19:04:34 -07:00
<div>
2024-03-31 19:40:06 -07:00
LOADING...
</div>
)
}
if (!info.release) {
return (
2024-04-02 19:04:34 -07:00
<div>
2024-03-31 19:40:06 -07:00
NOT FOUND
</div>
)
}
return (
<div className={css`
2024-04-02 19:04:34 -07:00
margin: auto;
width: max-content;
max-inline-size: 66ch;
padding: 1.5em;
display: flex;
flex-direction: column;
gap: 1em;
2024-03-31 19:40:06 -07:00
`}>
2024-04-02 19:04:34 -07:00
<div>
<h1>{info.release.manifest.title ?? slug!.split("-").map(word => word[0].toUpperCase()+word.slice(1)).join(" ")}</h1>
<h2>by <Link to={`/u/${info.release.author}`}>{info.release.author}</Link></h2>
</div>
2024-03-31 19:48:23 -07:00
<div className={css`
2024-04-02 19:04:34 -07:00
width: 512px;
max-width: 100%;
2024-03-31 19:48:23 -07:00
margin: auto;
`}>
2024-04-02 19:04:34 -07:00
<div className={css`
border: 2px solid transparent;
&:focus-within {
border: 2px solid limegreen;
}
`}>
2024-04-03 22:53:11 -07:00
<Pico8Console ref={picoRef} carts={info.release.carts} onGpioChange={(gpio: number[]) => {
console.log("sending gpio");
socket.sendMessage({
type: "gpio",
gpio,
});
}} />
2024-04-01 00:22:52 -07:00
</div>
2024-03-31 19:48:23 -07:00
<div className={css`
2024-04-02 19:04:34 -07:00
display: flex;
justify-content: end;
2024-03-31 19:48:23 -07:00
`}>
2024-04-02 19:04:34 -07:00
Version: <select defaultValue={info.release.version} onChange={(ev) => setVersion(ev.target.value)}>
{
[...info.versions].reverse().map(v => (
<option key={v} value={v}>{v}</option>
))
2024-03-31 19:48:23 -07:00
}
2024-04-02 19:04:34 -07:00
</select>
2024-03-31 21:25:54 -07:00
</div>
2024-03-31 19:48:23 -07:00
</div>
2024-04-02 19:04:34 -07:00
{/* <div>
<p>This is a paragraph about this game. It is a cool game. And a cool website to play it on. It automagically connects from GitHub.</p>
</div> */}
2024-03-31 19:40:06 -07:00
</div>
)
}