import React, { useState, useEffect } from 'react' import Link from 'next/link' import Head from 'next/head' function disposables() { let disposables: Function[] = [] let api = { requestAnimationFrame(...args: Parameters) { let raf = requestAnimationFrame(...args) api.add(() => cancelAnimationFrame(raf)) }, nextFrame(...args: Parameters) { api.requestAnimationFrame(() => { api.requestAnimationFrame(...args) }) }, setTimeout(...args: Parameters) { let timer = setTimeout(...args) api.add(() => clearTimeout(timer)) }, add(cb: () => void) { disposables.push(cb) }, dispose() { for (let dispose of disposables.splice(0)) { dispose() } }, } return api } export function useDisposables() { // Using useState instead of useRef so that we can use the initializer function. let [d] = useState(disposables) useEffect(() => () => d.dispose(), [d]) return d } function NextLink(props: React.ComponentProps<'a'>) { let { href, children, ...rest } = props return ( {children} ) } enum KeyDisplayMac { ArrowUp = '↑', ArrowDown = '↓', ArrowLeft = '←', ArrowRight = '→', Home = '↖', End = '↘', Alt = '⌥', CapsLock = '⇪', Meta = '⌘', Shift = '⇧', Control = '⌃', Backspace = '⌫', Delete = '⌦', Enter = '↵', Escape = '⎋', Tab = '↹', PageUp = '⇞', PageDown = '⇟', ' ' = '␣', } enum KeyDisplayWindows { ArrowUp = '↑', ArrowDown = '↓', ArrowLeft = '←', ArrowRight = '→', Meta = 'Win', Control = 'Ctrl', Backspace = '⌫', Delete = 'Del', Escape = 'Esc', PageUp = 'PgUp', PageDown = 'PgDn', ' ' = '␣', } function tap(value: T, cb: (value: T) => void) { cb(value) return value } function useKeyDisplay() { let [mounted, setMounted] = useState(false) useEffect(() => { setMounted(true) }, []) if (!mounted) return {} let isMac = navigator.userAgent.indexOf('Mac OS X') !== -1 return isMac ? KeyDisplayMac : KeyDisplayWindows } function KeyCaster() { let [keys, setKeys] = useState([]) let d = useDisposables() let KeyDisplay = useKeyDisplay() useEffect(() => { function handler(event: KeyboardEvent) { setKeys((current) => [ event.shiftKey && event.key !== 'Shift' ? KeyDisplay[`Shift${event.key}`] ?? event.key : KeyDisplay[event.key] ?? event.key, ...current, ]) d.setTimeout(() => setKeys((current) => tap(current.slice(), (clone) => clone.pop())), 2000) } window.addEventListener('keydown', handler, true) return () => window.removeEventListener('keydown', handler, true) }, [d, KeyDisplay]) if (keys.length <= 0) return null return (
{keys.slice().reverse().join(' ')}
) } function MyApp({ Component, pageProps }) { return ( <>
) } function Logo({ className }) { return ( ) } export default MyApp