make react component
This commit is contained in:
		
							
								
								
									
										33
									
								
								TODO.md
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								TODO.md
									
									
									
									
									
								
							@@ -1,15 +1,20 @@
 | 
				
			|||||||
TODO
 | 
					# TODO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- [ ] User Auth
 | 
					## MVP
 | 
				
			||||||
- [x] Component Pack
 | 
					- [ ] Update GH Workflow to be by push
 | 
				
			||||||
- [x] Typescript Pack
 | 
					- [ ] Add version prop to picobook.json
 | 
				
			||||||
	- [ ] Can this be used in a way where it doesn't need to be imported everywhere (lib?)
 | 
					- [ ] "Compile" carts in server and save them to db
 | 
				
			||||||
- [ ] Consider making more parts into Packs
 | 
					- [ ] Load cart by URL in React
 | 
				
			||||||
	- [ ] tsconfig with extends
 | 
					
 | 
				
			||||||
	- [ ] server with wrapper around fastify
 | 
					## Later
 | 
				
			||||||
	- [ ] scripts from package.json
 | 
					- [ ] Update pico console handle
 | 
				
			||||||
- [ ] Streamline spinning up a server
 | 
					- [ ] Add readme prop to picobook.json (figure out best name) and display it in React
 | 
				
			||||||
- [ ] Should public be top level?
 | 
					- [ ] Multiplayer support
 | 
				
			||||||
- [ ] Clean up .env variable names
 | 
					- [ ] More console support (touch detected, gamepad count, etc.)
 | 
				
			||||||
- [ ] use Temporal (polyfill)?
 | 
					- [ ] User accounts to manage published games, and user accounts for players to save progress
 | 
				
			||||||
- [ ] Do I want to add testing infrastructure?
 | 
					- [ ] GPIO Support (maybe gpio prop in picobook.json can have values like "ignore" | "v1")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## GPIO ideas
 | 
				
			||||||
 | 
					- RGB background color
 | 
				
			||||||
 | 
					- Awards
 | 
				
			||||||
 | 
					- Extra buttons?
 | 
				
			||||||
@@ -1,34 +1,16 @@
 | 
				
			|||||||
import { css } from "@emotion/css";
 | 
					import { css } from "@emotion/css";
 | 
				
			||||||
import { Center, Cover, Stack } from "@firebox/components";
 | 
					import { Center, Cover, Stack } from "@firebox/components";
 | 
				
			||||||
 | 
					import { Pico8Console } from "./pico8-client/Pico8Console";
 | 
				
			||||||
 | 
					import testcarts from "./testcarts";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const App = (props: { name: string }) => {
 | 
					const App = (props: {}) => {
 | 
				
			||||||
	const {name} = props;
 | 
					 | 
				
			||||||
	return (
 | 
						return (
 | 
				
			||||||
		<Stack>
 | 
							<div className={css`
 | 
				
			||||||
			<div className={css`background-color: floralwhite;`}>
 | 
								min-height: 100vh;
 | 
				
			||||||
				<Cover gap pad>
 | 
							`}>
 | 
				
			||||||
					<Center>
 | 
								<Pico8Console carts={testcarts.carts} />
 | 
				
			||||||
						<Stack gap={-1}>
 | 
							</div>
 | 
				
			||||||
							<h1>Hello, {name}!</h1>
 | 
					 | 
				
			||||||
							<p>Welcome to a website with a certain design philosophy. Tell me how it's working out! I want to see this text wrap a few times. Hopefully this sentence will help.</p>
 | 
					 | 
				
			||||||
						</Stack>
 | 
					 | 
				
			||||||
					</Center>
 | 
					 | 
				
			||||||
					<Cover.Footer>A page by Dylan Pizzo</Cover.Footer>
 | 
					 | 
				
			||||||
				</Cover>
 | 
					 | 
				
			||||||
			</div>
 | 
					 | 
				
			||||||
			<div className={css`background-color: aliceblue;`}>
 | 
					 | 
				
			||||||
				<Cover gap pad>
 | 
					 | 
				
			||||||
					<Center>
 | 
					 | 
				
			||||||
						<Stack gap={-1}>
 | 
					 | 
				
			||||||
							<h1>Hello, {name}!</h1>
 | 
					 | 
				
			||||||
							<p>Welcome to a website with a certain design philosophy. Tell me how it's working out! I want to see this text wrap a few times. Hopefully this sentence will help.</p>
 | 
					 | 
				
			||||||
						</Stack>
 | 
					 | 
				
			||||||
					</Center>
 | 
					 | 
				
			||||||
					<Cover.Footer>A page by Dylan Pizzo</Cover.Footer>
 | 
					 | 
				
			||||||
				</Cover>
 | 
					 | 
				
			||||||
			</div>
 | 
					 | 
				
			||||||
		</Stack>
 | 
					 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const app = <App name="World" />;
 | 
					export const app = <App />;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,8 @@
 | 
				
			|||||||
// import { createRoot } from "react-dom/client";
 | 
					import { createRoot } from "react-dom/client";
 | 
				
			||||||
// import { app } from "./app.js";
 | 
					import { app } from "./app.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// const domNode = document.getElementById("root")!;
 | 
					const domNode = document.getElementById("root")!;
 | 
				
			||||||
// const root = createRoot(domNode);
 | 
					const root = createRoot(domNode);
 | 
				
			||||||
// root.render(app);
 | 
					root.render(app);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export * from "./pico8-client/index";
 | 
					// export * from "./pico8-client/index";
 | 
				
			||||||
							
								
								
									
										44
									
								
								src/client/pico8-client/Pico8Console.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/client/pico8-client/Pico8Console.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					import { css } from "@emotion/css";
 | 
				
			||||||
 | 
					import { PicoCart, PicoPlayerHandle, makePicoConsole } from "./renderCart";
 | 
				
			||||||
 | 
					import { ForwardedRef, forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from "react";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Pico8ConsoleImperatives = {
 | 
				
			||||||
 | 
						getPicoConsoleHandle(): PicoPlayerHandle | null;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const Pico8Console = forwardRef((props: { carts: PicoCart[] }, forwardedRef: ForwardedRef<Pico8ConsoleImperatives>) => {
 | 
				
			||||||
 | 
						const {carts} = props;
 | 
				
			||||||
 | 
						const ref = useRef<HTMLDivElement>(null);
 | 
				
			||||||
 | 
						const [handle, setHandle] = useState<PicoPlayerHandle | null>(null);
 | 
				
			||||||
 | 
						const attachConsole = useCallback(async () => {
 | 
				
			||||||
 | 
							const picoConsole = await makePicoConsole({
 | 
				
			||||||
 | 
								carts,
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
							if (ref.current) {
 | 
				
			||||||
 | 
								ref.current.appendChild(picoConsole.canvas);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							setHandle(picoConsole);
 | 
				
			||||||
 | 
						}, [carts]);
 | 
				
			||||||
 | 
						useImperativeHandle(forwardedRef, () => ({
 | 
				
			||||||
 | 
							getPicoConsoleHandle() {
 | 
				
			||||||
 | 
								return handle;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}), [handle]);
 | 
				
			||||||
 | 
						useEffect(() => {
 | 
				
			||||||
 | 
							attachConsole();
 | 
				
			||||||
 | 
						}, [attachConsole]);
 | 
				
			||||||
 | 
						return (
 | 
				
			||||||
 | 
							<div ref={ref} className={css`
 | 
				
			||||||
 | 
								width: 100%;
 | 
				
			||||||
 | 
								height: 100%;
 | 
				
			||||||
 | 
								display: flex;
 | 
				
			||||||
 | 
								align-items: center;
 | 
				
			||||||
 | 
								justify-content: center;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								& > canvas {
 | 
				
			||||||
 | 
									width: 100%;
 | 
				
			||||||
 | 
									height: 100%;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							`}></div>
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
@@ -1,9 +1,9 @@
 | 
				
			|||||||
// @ts-ignore
 | 
					// @ts-ignore
 | 
				
			||||||
import "./build/veryRawRenderCart.js";
 | 
					import "./build/veryRawRenderCart.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type PicoBool = 0 | 1;
 | 
					export type PicoBool = 0 | 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type RenderCart = (Module: {canvas: HTMLCanvasElement}, cartNames: string[], cartDatas: number[][], audioContext: AudioContext) => {
 | 
					export type RenderCart = (Module: {canvas: HTMLCanvasElement}, cartNames: string[], cartDatas: number[][], audioContext: AudioContext) => {
 | 
				
			||||||
	p8_touch_detected?: PicoBool;
 | 
						p8_touch_detected?: PicoBool;
 | 
				
			||||||
	p8_dropped_cart?: string;
 | 
						p8_dropped_cart?: string;
 | 
				
			||||||
	p8_dropped_cart_name?: string;
 | 
						p8_dropped_cart_name?: string;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,8 @@
 | 
				
			|||||||
import { assertNever } from "@firebox/tsutil";
 | 
					import { assertNever } from "@firebox/tsutil";
 | 
				
			||||||
import { pngToRom } from "./pngToRom";
 | 
					import { pngToRom } from "./pngToRom";
 | 
				
			||||||
import { renderCart as rawRenderCart } from "./rawRenderCart";
 | 
					import { RenderCart, renderCart as rawRenderCart } from "./rawRenderCart";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type PicoCart = {
 | 
					export type PicoCart = {
 | 
				
			||||||
	name: string;
 | 
						name: string;
 | 
				
			||||||
	src: string;
 | 
						src: string;
 | 
				
			||||||
} | {
 | 
					} | {
 | 
				
			||||||
@@ -20,7 +20,9 @@ type PlayerButtons = {
 | 
				
			|||||||
	menu: boolean;
 | 
						menu: boolean;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type PicoPlayerHandle = {
 | 
					export type PicoPlayerHandle = {
 | 
				
			||||||
 | 
						raw: ReturnType<RenderCart>;
 | 
				
			||||||
 | 
						rawModule: unknown;
 | 
				
			||||||
	// external things
 | 
						// external things
 | 
				
			||||||
	readonly canvas: HTMLCanvasElement;
 | 
						readonly canvas: HTMLCanvasElement;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -35,16 +37,16 @@ type PicoPlayerHandle = {
 | 
				
			|||||||
	setGamepadCount: (count: number) => void;
 | 
						setGamepadCount: (count: number) => void;
 | 
				
			||||||
	readonly gpio: number[]; // read + write (should be 256-tuple)
 | 
						readonly gpio: number[]; // read + write (should be 256-tuple)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// state (all communicated out)
 | 
						// state
 | 
				
			||||||
	readonly state: {
 | 
						readonly state: {
 | 
				
			||||||
		readonly frameNumber: number;
 | 
							frameNumber: number;
 | 
				
			||||||
		readonly isPaused: boolean;
 | 
							isPaused: boolean;
 | 
				
			||||||
		readonly hasFocus: boolean;
 | 
							hasFocus: boolean;
 | 
				
			||||||
		readonly requestPointerLock: boolean;
 | 
							requestPointerLock: boolean;
 | 
				
			||||||
		readonly requirePageNavigateConfirmation: boolean;
 | 
							requirePageNavigateConfirmation: boolean;
 | 
				
			||||||
		readonly showDpad: boolean;
 | 
							showDpad: boolean;
 | 
				
			||||||
		readonly shutdownRequested: boolean;
 | 
							shutdownRequested: boolean;
 | 
				
			||||||
		readonly soundVolume: number;
 | 
							soundVolume: number;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// misc?
 | 
						// misc?
 | 
				
			||||||
@@ -109,6 +111,8 @@ export const makePicoConsole = async (props: {
 | 
				
			|||||||
	];
 | 
						];
 | 
				
			||||||
	handle.pico8_gamepads = {count: 0};
 | 
						handle.pico8_gamepads = {count: 0};
 | 
				
			||||||
	return {
 | 
						return {
 | 
				
			||||||
 | 
							raw: handle,
 | 
				
			||||||
 | 
							rawModule: Module,
 | 
				
			||||||
		canvas,
 | 
							canvas,
 | 
				
			||||||
		state: {
 | 
							state: {
 | 
				
			||||||
			frameNumber: handle.pico8_state.frame_number!,
 | 
								frameNumber: handle.pico8_state.frame_number!,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										21
									
								
								src/client/testcarts.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/client/testcarts.ts
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -3,11 +3,6 @@
 | 
				
			|||||||
<meta name="viewport" content="width=device-width, user-scalable=no">
 | 
					<meta name="viewport" content="width=device-width, user-scalable=no">
 | 
				
			||||||
<script type="text/javascript">
 | 
					<script type="text/javascript">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	console.log(Object.keys(window));
 | 
					 | 
				
			||||||
	setTimeout(() => {
 | 
					 | 
				
			||||||
		console.log(Object.keys(window));
 | 
					 | 
				
			||||||
	}, 1000);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Default shell for PICO-8 0.2.2 (includes @weeble's gamepad mod 1.0)
 | 
						// Default shell for PICO-8 0.2.2 (includes @weeble's gamepad mod 1.0)
 | 
				
			||||||
	// This file is available under a CC0 license https://creativecommons.org/share-your-work/public-domain/cc0/
 | 
						// This file is available under a CC0 license https://creativecommons.org/share-your-work/public-domain/cc0/
 | 
				
			||||||
	// (note: "this file" does not include any cartridge or cartridge artwork injected into a derivative html file when using the PICO-8 html exporter)
 | 
						// (note: "this file" does not include any cartridge or cartridge artwork injected into a derivative html file when using the PICO-8 html exporter)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user