Tapple
This commit is contained in:
parent
1ecc040e12
commit
890cada87e
|
|
@ -18,7 +18,7 @@ while (!await isGame(game)) {
|
||||||
choices: (await getGames()).map(value => ({ value })),
|
choices: (await getGames()).map(value => ({ value })),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
console.log(`Building ${game}...`);
|
||||||
const html = await buildHTML(game, { production: true });
|
const html = await buildHTML(game, { production: true });
|
||||||
|
|
||||||
if (!html) {
|
if (!html) {
|
||||||
|
|
@ -28,6 +28,7 @@ const filePath = path.resolve(outDir, `${game}.html`);
|
||||||
await Bun.write(filePath, html);
|
await Bun.write(filePath, html);
|
||||||
|
|
||||||
if (publish) {
|
if (publish) {
|
||||||
|
console.log(`Publishing ${game}...`);
|
||||||
const result = await $`scp "${filePath}" "${publish}${game}.html"`;
|
const result = await $`scp "${filePath}" "${publish}${game}.html"`;
|
||||||
if (result.exitCode === 0) {
|
if (result.exitCode === 0) {
|
||||||
console.log(`Build successful: ${process.env.PUBLISH_URL}${game}.html`);
|
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