Tapple
This commit is contained in:
parent
1ecc040e12
commit
890cada87e
|
|
@ -18,7 +18,7 @@ while (!await isGame(game)) {
|
|||
choices: (await getGames()).map(value => ({ value })),
|
||||
});
|
||||
}
|
||||
|
||||
console.log(`Building ${game}...`);
|
||||
const html = await buildHTML(game, { production: true });
|
||||
|
||||
if (!html) {
|
||||
|
|
@ -28,6 +28,7 @@ const filePath = path.resolve(outDir, `${game}.html`);
|
|||
await Bun.write(filePath, html);
|
||||
|
||||
if (publish) {
|
||||
console.log(`Publishing ${game}...`);
|
||||
const result = await $`scp "${filePath}" "${publish}${game}.html"`;
|
||||
if (result.exitCode === 0) {
|
||||
console.log(`Build successful: ${process.env.PUBLISH_URL}${game}.html`);
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -0,0 +1,40 @@
|
|||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
width: 100dvw;
|
||||
height: 100dvh;
|
||||
font-size: 24px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
main {
|
||||
width: 100dvw;
|
||||
height: 100dvh;
|
||||
padding: 1rem;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
gap: 0.5rem;
|
||||
|
||||
button {
|
||||
font-size: 10vmin;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
&[disabled] {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
body > button {
|
||||
width: 100dvw;
|
||||
height: 100dvh;
|
||||
font-size: 80vmin;
|
||||
}
|
||||
Binary file not shown.
|
|
@ -0,0 +1,52 @@
|
|||
import { useEffect, useState } from "preact/hooks";
|
||||
import tick from '../assets/tick.ogg';
|
||||
import beep from '../assets/beep.ogg';
|
||||
|
||||
const LETTERS = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЭЮЯ'.split('');
|
||||
|
||||
export const App = () => {
|
||||
const [init, setInit] = useState(false);
|
||||
const [usedLetters, setUsedLetters] = useState<string[]>([]);
|
||||
const [isOver, setOver] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
let timeout = 0;
|
||||
|
||||
if (usedLetters.length) {
|
||||
tick.pause();
|
||||
tick.currentTime = 0;
|
||||
tick.loop = true;
|
||||
tick.play();
|
||||
|
||||
timeout = window.setTimeout(() => {
|
||||
tick.pause();
|
||||
beep.play();
|
||||
setOver(true);
|
||||
window.clearTimeout(timeout);
|
||||
}, 10_000);
|
||||
}
|
||||
|
||||
return () => {
|
||||
window.clearTimeout(timeout);
|
||||
};
|
||||
}, [usedLetters]);
|
||||
|
||||
if (!init) {
|
||||
return <button onClick={() => setInit(true)}>▶</button>;
|
||||
}
|
||||
|
||||
return <>
|
||||
<main>
|
||||
{LETTERS.map(l => (
|
||||
<button
|
||||
key={l}
|
||||
disabled={isOver || usedLetters.includes(l)}
|
||||
onMouseDown={() => setUsedLetters(b => [...b, l])}
|
||||
onTouchStart={() => setUsedLetters(b => [...b, l])}
|
||||
>
|
||||
{l}
|
||||
</button>
|
||||
))}
|
||||
</main>
|
||||
</>;
|
||||
};
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
import { render } from "preact";
|
||||
import { App } from "./components/App";
|
||||
|
||||
import './assets/style.css';
|
||||
|
||||
export default function main() {
|
||||
render(
|
||||
<App />,
|
||||
document.body
|
||||
);
|
||||
}
|
||||
Loading…
Reference in New Issue