import { h, render, Fragment } from 'preact'; import { useState, useEffect, useMemo } from 'preact/hooks'; import { Game } from './Game'; import { gameName, urlParam } from "./util"; import "./App.css"; import { About } from './About'; import { useLocalStorage } from './localstorage'; import { PuzzleType, PuzzleTypeDisplay } from './PuzzleType'; import * as PUZZLES from './puzzles.json'; const EPOCH = new Date(2022, 1, 27); type PickPuzzleTypeProps = { puzzleType: PuzzleType, setPuzzleType: (p: PuzzleType) => void, }; function PickPuzzleType(props: PickPuzzleTypeProps) { const { puzzleType, setPuzzleType } = props; const PUZZLE_TYPES: PuzzleType[] = [2, 3, 4]; return (
{PUZZLE_TYPES.map((type) => (
setPuzzleType(type)}>
))}
); } 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] = useLocalStorage("dark", prefersDark); const [colorBlind, setColorBlind] = useLocalStorage("colorblind", false); const [keyboard, setKeyboard] = useLocalStorage( "keyboard", "qwertyuiop-asdfghjkl-BzxcvbnmE" ); const [enterLeft, setEnterLeft] = useLocalStorage("enter-left", false); const day = useMemo(() => { let date = new Date(); date.setHours(date.getHours() - 6); // treat 6 AM as the start of the day date.setHours(0); // now set it to midnight of the day return Math.round((date.getTime() - EPOCH.getTime()) / (24 * 60 * 60 * 1000)); }, []); const [puzzleType, setPuzzleType] = useLocalStorage<2 | 3 | 4>("puzzleType", 4); const puzzle = useMemo(() => PUZZLES[puzzleType][day], [puzzleType]); 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 (
{page === "game" && ( )}

{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)} />
)} {puzzle ? (
); } render(, document.body);