import { Link, useParams, useSearchParams } from "react-router-dom"; import { MutableRefObject, useEffect, useRef, useState } from "react"; import { css } from "@emotion/css"; import { useWebsocket } from "./hooks/useWebsocket"; import { Pico8Player } from "@athingperday/react-pico-player"; type PicoPlayerHandle = NonNullable< Parameters["0"]["consoleRef"] > extends MutableRefObject ? NonNullable : never; type Game = { carts: Parameters["0"]["carts"]; }; const getPatch = (before: number[], after: number[]) => { const diff: Record = {}; for (const i in after) { if (after[i] !== before[i]) { diff[i] = after[i]; } } return diff; }; const applyPatch = (before: number[], patch: Record) => { for (const i in patch) { before[i] = patch[i]; } }; export const GamePage = () => { const { author, slug } = useParams(); // const [text, setText] = useState(""); const [prevGpio, setPrevGpio] = useState(null); const [searchParams, setSearchParams] = useSearchParams(); const room = searchParams.get("room"); const picoRef = useRef(null); const socket = useWebsocket({ url: `/api/ws/room?room=${room}`, onMessage({ message }) { // console.log("message", message); const msg = message as any; if (msg.getGpio) { if (picoRef.current) { const handle = picoRef.current; if (handle) { socket.sendMessage({ gpio: handle.gpio }); } } } if (msg.gpio) { if (picoRef.current) { const handle = picoRef.current; if (handle) { // console.log("updating pico gpio"); handle.gpio.length = 0; handle.gpio.push(...msg.gpio); setPrevGpio([...handle.gpio]); } } } if (msg.gpioPatch) { if (picoRef.current) { const handle = picoRef.current; if (handle) { // console.log("updating pico gpio"); applyPatch(handle.gpio, msg.gpioPatch); setPrevGpio([...handle.gpio]); } } } }, }); const [game, setGame] = useState(null); useEffect(() => { const fetchInfo = async () => { let url = `/api/game?author=${author}&name=${slug ?? ""}`; const information = await fetch(url); const json = await information.json(); console.log(json); setGame(json); }; fetchInfo(); }, [setGame, slug]); useEffect(() => { const interval = setInterval(() => { const handle = picoRef.current; if (!handle) { return; } if (JSON.stringify(handle.gpio) !== JSON.stringify(prevGpio)) { if (prevGpio) { setPrevGpio([...handle.gpio]); socket.sendMessage({ gpioPatch: getPatch(prevGpio, handle.gpio), }); } else { socket.sendMessage({ getGpio: true }); setPrevGpio([...handle.gpio]); } } }, 1000 / 60); return () => { clearInterval(interval); }; }); if (!game) { return
LOADING...
; } if (!game.carts) { return
NOT FOUND
; } return (

{slug}

by {author}

{game.carts.map((cart) => "src" in cart ? ( ) : null, )}
{/*
setText(x.target.value)} />
*/} {/*

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.

*/}
); };