import { h, render, Fragment } from 'preact'; import { useState, useEffect } from 'preact/hooks'; import { Game } from './Game'; import { gameName, urlParam } from "./util"; import "./App.css"; import { About } from './About'; function useSetting( key: string, initial: T ): [T, (value: T | ((t: T) => T)) => void] { const [current, setCurrent] = useState(() => { try { const item = window.localStorage.getItem(key); return item ? JSON.parse(item) : initial; } catch (e) { return initial; } }); const setSetting = (value: T | ((t: T) => T)) => { try { const v = value instanceof Function ? value(current) : value; setCurrent(v); window.localStorage.setItem(key, JSON.stringify(v)); } catch (e) { } }; return [current, setSetting]; } export function App() { type Page = "game" | "about" | "settings"; const [page, setPage] = useState("game"); const prefersDark = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches; const [dark, setDark] = useSetting("dark", prefersDark); const [colorBlind, setColorBlind] = useSetting("colorblind", false); const [keyboard, setKeyboard] = useSetting( "keyboard", "qwertyuiop-asdfghjkl-BzxcvbnmE" ); const [enterLeft, setEnterLeft] = useSetting("enter-left", false); useEffect(() => { document.body.className = dark ? "dark" : ""; setTimeout(() => { // Avoid transition on page load document.body.style.transition = "0.3s background-color ease-out"; }, 1); }, [dark]); const link = (emoji: string, label: string, page: Page) => ( ); return (

{gameName}

{page !== "game" ? ( link("❌", "Close", "game") ) : ( <> {link("❓", "About", "about")} {link("⚙️", "Settings", "settings")} )}
{page === "about" && } {page === "settings" && (
setDark((x: boolean) => !x)} />
setColorBlind((x: boolean) => !x)} />
setEnterLeft((x: boolean) => !x)} />
)}
); } render(, document.body);