@mblinkov/whats-missing 20.0.11 → 20.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/whats-missing.cjs.js +3 -40
- package/dist/whats-missing.es.js +247 -295
- package/package.json +1 -1
- package/src/Game.tsx +217 -264
package/src/Game.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useState, useEffect, useMemo } from "react";
|
|
1
|
+
import { useState, useEffect, useMemo, useRef } from "react";
|
|
2
2
|
import { themes } from "./themes";
|
|
3
3
|
import { styles } from "./Game.styles";
|
|
4
4
|
import type { Theme } from "./themes";
|
|
@@ -11,57 +11,20 @@ type RoundResult = {
|
|
|
11
11
|
result: "correct" | "almost" | "wrong";
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
-
// ✅
|
|
14
|
+
// ✅ Минимальный reset — без вмешательства в body
|
|
15
15
|
const globalReset = () => {
|
|
16
16
|
const style = document.createElement("style");
|
|
17
17
|
style.textContent = `
|
|
18
|
-
html, body {
|
|
19
|
-
margin: 0;
|
|
20
|
-
padding: 0;
|
|
21
|
-
width: 100%;
|
|
22
|
-
height: 100%;
|
|
23
|
-
overflow-x: hidden;
|
|
24
|
-
overflow-y: hidden;
|
|
25
|
-
background: linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%);
|
|
26
|
-
background-repeat: no-repeat;
|
|
27
|
-
background-attachment: fixed;
|
|
28
|
-
background-size: cover;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
#whats-missing-root {
|
|
32
|
-
all: unset;
|
|
33
|
-
display: flex;
|
|
34
|
-
flex-direction: column;
|
|
35
|
-
justify-content: center;
|
|
36
|
-
align-items: center;
|
|
37
|
-
position: fixed;
|
|
38
|
-
inset: 0;
|
|
39
|
-
width: 100vw;
|
|
40
|
-
height: 100vh;
|
|
41
|
-
margin: 0;
|
|
42
|
-
padding: 0;
|
|
43
|
-
color: #1f2937;
|
|
44
|
-
text-align: center;
|
|
45
|
-
background: linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%);
|
|
46
|
-
background-size: cover;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
18
|
#whats-missing-root, #whats-missing-root * {
|
|
50
19
|
box-sizing: border-box;
|
|
51
20
|
font-family: "Geist", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
|
|
52
21
|
}
|
|
53
|
-
|
|
54
22
|
#whats-missing-root img {
|
|
55
23
|
max-width: 100%;
|
|
56
24
|
height: auto;
|
|
57
25
|
display: block;
|
|
58
26
|
user-select: none;
|
|
59
27
|
}
|
|
60
|
-
|
|
61
|
-
@keyframes spin {
|
|
62
|
-
from { transform: rotate(0deg); }
|
|
63
|
-
to { transform: rotate(360deg); }
|
|
64
|
-
}
|
|
65
28
|
`;
|
|
66
29
|
document.head.appendChild(style);
|
|
67
30
|
};
|
|
@@ -82,8 +45,13 @@ const levenshtein = (a: string, b: string) => {
|
|
|
82
45
|
};
|
|
83
46
|
|
|
84
47
|
export default function Game() {
|
|
48
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
49
|
+
|
|
85
50
|
useEffect(() => {
|
|
86
51
|
globalReset();
|
|
52
|
+
return () => {
|
|
53
|
+
document.body.style.overflow = "";
|
|
54
|
+
};
|
|
87
55
|
}, []);
|
|
88
56
|
|
|
89
57
|
const [theme, setTheme] = useState<Theme | null>(null);
|
|
@@ -159,17 +127,15 @@ export default function Game() {
|
|
|
159
127
|
useEffect(() => {
|
|
160
128
|
if (!started || finished || answered) return;
|
|
161
129
|
if (phase === "ready") {
|
|
162
|
-
if (readyTime <= 0)
|
|
163
|
-
|
|
164
|
-
} else {
|
|
130
|
+
if (readyTime <= 0) setPhase("memorize");
|
|
131
|
+
else {
|
|
165
132
|
const t = setTimeout(() => setReadyTime((r) => r - 1), 1000);
|
|
166
133
|
return () => clearTimeout(t);
|
|
167
134
|
}
|
|
168
135
|
}
|
|
169
136
|
if (phase === "memorize") {
|
|
170
|
-
if (memorizeTime <= 0)
|
|
171
|
-
|
|
172
|
-
} else {
|
|
137
|
+
if (memorizeTime <= 0) setPhase("guess");
|
|
138
|
+
else {
|
|
173
139
|
const t = setTimeout(() => setMemorizeTime((m) => m - 1), 1000);
|
|
174
140
|
return () => clearTimeout(t);
|
|
175
141
|
}
|
|
@@ -188,19 +154,7 @@ export default function Game() {
|
|
|
188
154
|
const t = setTimeout(() => setTimeLeft((s) => s - 1), 1000);
|
|
189
155
|
return () => clearTimeout(t);
|
|
190
156
|
}
|
|
191
|
-
}, [
|
|
192
|
-
phase,
|
|
193
|
-
readyTime,
|
|
194
|
-
memorizeTime,
|
|
195
|
-
timeLeft,
|
|
196
|
-
started,
|
|
197
|
-
finished,
|
|
198
|
-
answered,
|
|
199
|
-
files,
|
|
200
|
-
hiddenIndex,
|
|
201
|
-
currentRound,
|
|
202
|
-
inputValue,
|
|
203
|
-
]);
|
|
157
|
+
}, [phase, readyTime, memorizeTime, timeLeft, started, finished, answered, files, hiddenIndex, currentRound, inputValue]);
|
|
204
158
|
|
|
205
159
|
const checkAnswer = () => {
|
|
206
160
|
if (hiddenIndex === null || animating) return;
|
|
@@ -219,10 +173,7 @@ export default function Game() {
|
|
|
219
173
|
setResult("wrong");
|
|
220
174
|
roundResult = "wrong";
|
|
221
175
|
}
|
|
222
|
-
setResultsTable((prev) => [
|
|
223
|
-
...prev,
|
|
224
|
-
{ round: currentRound, answer: userAnswer, correct, result: roundResult },
|
|
225
|
-
]);
|
|
176
|
+
setResultsTable((prev) => [...prev, { round: currentRound, answer: userAnswer, correct, result: roundResult }]);
|
|
226
177
|
setAnimating(true);
|
|
227
178
|
setTimeout(() => {
|
|
228
179
|
setAnimating(false);
|
|
@@ -231,9 +182,7 @@ export default function Game() {
|
|
|
231
182
|
};
|
|
232
183
|
|
|
233
184
|
const nextRound = () =>
|
|
234
|
-
currentRound < rounds
|
|
235
|
-
? (setCurrentRound((r) => r + 1), startRound())
|
|
236
|
-
: setFinished(true);
|
|
185
|
+
currentRound < rounds ? (setCurrentRound((r) => r + 1), startRound()) : setFinished(true);
|
|
237
186
|
|
|
238
187
|
const exitGame = () => {
|
|
239
188
|
setStarted(false);
|
|
@@ -245,224 +194,228 @@ export default function Game() {
|
|
|
245
194
|
() => (
|
|
246
195
|
<div style={styles.gmLogoFixed}>
|
|
247
196
|
<picture>
|
|
248
|
-
<source
|
|
249
|
-
|
|
250
|
-
type="image/svg+xml"
|
|
251
|
-
/>
|
|
252
|
-
<img
|
|
253
|
-
src={window.origin + "/cloud/speakid/games/whatsmissing/logo.png"}
|
|
254
|
-
alt="SPEAKID Logo"
|
|
255
|
-
style={styles.gmLogoImg}
|
|
256
|
-
loading="lazy"
|
|
257
|
-
/>
|
|
197
|
+
<source srcSet={window.origin + "/cloud/speakid/games/whatsmissing/logo.svg"} type="image/svg+xml" />
|
|
198
|
+
<img src={window.origin + "/cloud/speakid/games/whatsmissing/logo.png"} alt="SPEAKID Logo" style={styles.gmLogoImg} loading="lazy" />
|
|
258
199
|
</picture>
|
|
259
200
|
</div>
|
|
260
201
|
),
|
|
261
202
|
[]
|
|
262
203
|
);
|
|
263
204
|
|
|
205
|
+
// ✅ Новый контейнер для защиты от zoom
|
|
264
206
|
return (
|
|
265
|
-
<div
|
|
266
|
-
{
|
|
207
|
+
<div
|
|
208
|
+
ref={containerRef}
|
|
209
|
+
style={{
|
|
210
|
+
display: "flex",
|
|
211
|
+
justifyContent: "center",
|
|
212
|
+
alignItems: "center",
|
|
213
|
+
width: "100%",
|
|
214
|
+
height: "100%",
|
|
215
|
+
overflow: "hidden",
|
|
216
|
+
}}
|
|
217
|
+
>
|
|
218
|
+
<div
|
|
219
|
+
style={{
|
|
220
|
+
width: window.innerWidth > window.innerHeight ? "90vh" : "90vw",
|
|
221
|
+
height: window.innerWidth > window.innerHeight ? "90vh" : "90vw",
|
|
222
|
+
display: "flex",
|
|
223
|
+
justifyContent: "center",
|
|
224
|
+
alignItems: "center",
|
|
225
|
+
flexDirection: "column",
|
|
226
|
+
borderRadius: "20px",
|
|
227
|
+
background: "linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",
|
|
228
|
+
}}
|
|
229
|
+
>
|
|
230
|
+
<div id="whats-missing-root">
|
|
231
|
+
{!isMobile && MemoizedLogo}
|
|
267
232
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
233
|
+
{!theme && !started && (
|
|
234
|
+
<div style={styles.gmCenterScreen}>
|
|
235
|
+
<h1 style={styles.gmHeadline1}>WHAT'S MISSING?</h1>
|
|
236
|
+
<p style={styles.gmBodyM}>Select a theme:</p>
|
|
237
|
+
<div style={{ display: "flex", gap: 16 }}>
|
|
238
|
+
{["animals", "food", "toys"].map((t) => (
|
|
239
|
+
<button key={t} style={styles.gmButton} onClick={() => setTheme(t as Theme)}>
|
|
240
|
+
{t === "animals" ? "🐶 Animals" : t === "food" ? "🍎 Food" : "🧸 Toys"}
|
|
241
|
+
</button>
|
|
242
|
+
))}
|
|
243
|
+
</div>
|
|
244
|
+
<div style={{ marginTop: 24 }}>
|
|
245
|
+
<p style={styles.gmBodyS}>Choose number of rounds:</p>
|
|
246
|
+
<div style={{ display: "flex", gap: 12, marginTop: 8 }}>
|
|
247
|
+
{[3, 4, 5].map((n) => (
|
|
248
|
+
<button
|
|
249
|
+
key={n}
|
|
250
|
+
style={{
|
|
251
|
+
...styles.gmButton,
|
|
252
|
+
...(rounds === n ? styles.gmButtonActive : {}),
|
|
253
|
+
}}
|
|
254
|
+
onClick={() => setRounds(n)}
|
|
255
|
+
>
|
|
256
|
+
{n}
|
|
257
|
+
</button>
|
|
258
|
+
))}
|
|
259
|
+
</div>
|
|
260
|
+
</div>
|
|
294
261
|
</div>
|
|
295
|
-
|
|
296
|
-
</div>
|
|
297
|
-
)}
|
|
298
|
-
|
|
299
|
-
{theme && !started && (
|
|
300
|
-
<div style={styles.gmCenterScreen}>
|
|
301
|
-
<h1 style={styles.gmHeadline1}>Theme selected: {theme}</h1>
|
|
302
|
-
<p style={styles.gmBodyM}>Rounds: {rounds}</p>
|
|
303
|
-
<button style={styles.gmButton} onClick={startGame}>
|
|
304
|
-
▶ Start game
|
|
305
|
-
</button>
|
|
306
|
-
</div>
|
|
307
|
-
)}
|
|
262
|
+
)}
|
|
308
263
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
<table style={styles.gmTable}>
|
|
319
|
-
<thead>
|
|
320
|
-
<tr>
|
|
321
|
-
<th>Round</th>
|
|
322
|
-
<th>Your Answer</th>
|
|
323
|
-
<th>Correct</th>
|
|
324
|
-
<th>Result</th>
|
|
325
|
-
</tr>
|
|
326
|
-
</thead>
|
|
327
|
-
<tbody>
|
|
328
|
-
{resultsTable.map((r, i) => (
|
|
329
|
-
<tr key={i}>
|
|
330
|
-
<td style={styles.gmTableCell}>{r.round}</td>
|
|
331
|
-
<td style={styles.gmTableCell}>{r.answer || "—"}</td>
|
|
332
|
-
<td style={styles.gmTableCell}>{r.correct}</td>
|
|
333
|
-
<td style={styles.gmTableCell}>
|
|
334
|
-
{r.result === "correct"
|
|
335
|
-
? "✔ Correct"
|
|
336
|
-
: r.result === "almost"
|
|
337
|
-
? "◐ Almost (0.5)"
|
|
338
|
-
: "✘ Wrong"}
|
|
339
|
-
</td>
|
|
340
|
-
</tr>
|
|
341
|
-
))}
|
|
342
|
-
</tbody>
|
|
343
|
-
</table>
|
|
344
|
-
<div style={{ display: "flex", gap: 12, marginTop: 24 }}>
|
|
345
|
-
<button style={styles.gmButton} onClick={startGame}>
|
|
346
|
-
🔁 Play again
|
|
347
|
-
</button>
|
|
348
|
-
<button style={styles.gmButton} onClick={exitGame}>
|
|
349
|
-
⬅️ Choose theme
|
|
350
|
-
</button>
|
|
351
|
-
</div>
|
|
352
|
-
</div>
|
|
353
|
-
)}
|
|
264
|
+
{theme && !started && (
|
|
265
|
+
<div style={styles.gmCenterScreen}>
|
|
266
|
+
<h1 style={styles.gmHeadline1}>Theme selected: {theme}</h1>
|
|
267
|
+
<p style={styles.gmBodyM}>Rounds: {rounds}</p>
|
|
268
|
+
<button style={styles.gmButton} onClick={startGame}>
|
|
269
|
+
▶ Start game
|
|
270
|
+
</button>
|
|
271
|
+
</div>
|
|
272
|
+
)}
|
|
354
273
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
alignItems: "center",
|
|
364
|
-
}}
|
|
365
|
-
>
|
|
366
|
-
{phase === "ready" && (
|
|
367
|
-
<>
|
|
368
|
-
<h1 style={{ ...styles.gmHeadline1, color: "#ec4c44" }}>GET READY</h1>
|
|
369
|
-
<div style={styles.gmHourglass}>⏳</div>
|
|
370
|
-
</>
|
|
371
|
-
)}
|
|
372
|
-
{phase === "memorize" && (
|
|
373
|
-
<p style={{ ...styles.gmBodyM, color: "#10b981" }}>
|
|
374
|
-
MEMORIZE ({memorizeTime})
|
|
274
|
+
{finished && (
|
|
275
|
+
<div style={styles.gmCenterScreen}>
|
|
276
|
+
<h1 style={styles.gmHeadline1}>Results</h1>
|
|
277
|
+
<h2 style={styles.gmHeadline3}>
|
|
278
|
+
Your score: {score} / {rounds}
|
|
279
|
+
</h2>
|
|
280
|
+
<p style={{ ...styles.gmBodyM, color: "#10b981", marginTop: 12 }}>
|
|
281
|
+
Yahoo! You did it! 🍬✨
|
|
375
282
|
</p>
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
283
|
+
<table style={styles.gmTable}>
|
|
284
|
+
<thead>
|
|
285
|
+
<tr>
|
|
286
|
+
<th>Round</th>
|
|
287
|
+
<th>Your Answer</th>
|
|
288
|
+
<th>Correct</th>
|
|
289
|
+
<th>Result</th>
|
|
290
|
+
</tr>
|
|
291
|
+
</thead>
|
|
292
|
+
<tbody>
|
|
293
|
+
{resultsTable.map((r, i) => (
|
|
294
|
+
<tr key={i}>
|
|
295
|
+
<td style={styles.gmTableCell}>{r.round}</td>
|
|
296
|
+
<td style={styles.gmTableCell}>{r.answer || "—"}</td>
|
|
297
|
+
<td style={styles.gmTableCell}>{r.correct}</td>
|
|
298
|
+
<td style={styles.gmTableCell}>
|
|
299
|
+
{r.result === "correct"
|
|
300
|
+
? "✔ Correct"
|
|
301
|
+
: r.result === "almost"
|
|
302
|
+
? "◐ Almost (0.5)"
|
|
303
|
+
: "✘ Wrong"}
|
|
304
|
+
</td>
|
|
305
|
+
</tr>
|
|
306
|
+
))}
|
|
307
|
+
</tbody>
|
|
308
|
+
</table>
|
|
309
|
+
<div style={{ display: "flex", gap: 12, marginTop: 24 }}>
|
|
310
|
+
<button style={styles.gmButton} onClick={startGame}>
|
|
311
|
+
🔁 Play again
|
|
312
|
+
</button>
|
|
313
|
+
<button style={styles.gmButton} onClick={exitGame}>
|
|
314
|
+
⬅️ Choose theme
|
|
315
|
+
</button>
|
|
316
|
+
</div>
|
|
317
|
+
</div>
|
|
318
|
+
)}
|
|
381
319
|
|
|
382
|
-
{
|
|
383
|
-
<div
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
<
|
|
424
|
-
|
|
425
|
-
alt={file.name}
|
|
320
|
+
{started && !finished && (
|
|
321
|
+
<div style={styles.gmGameLayout}>
|
|
322
|
+
<div
|
|
323
|
+
style={{
|
|
324
|
+
minHeight: 160,
|
|
325
|
+
display: "flex",
|
|
326
|
+
flexDirection: "column",
|
|
327
|
+
justifyContent: "center",
|
|
328
|
+
alignItems: "center",
|
|
329
|
+
}}
|
|
330
|
+
>
|
|
331
|
+
{phase === "ready" && (
|
|
332
|
+
<>
|
|
333
|
+
<h1 style={{ ...styles.gmHeadline1, color: "#ec4c44" }}>GET READY</h1>
|
|
334
|
+
<div style={styles.gmHourglass}>⏳</div>
|
|
335
|
+
</>
|
|
336
|
+
)}
|
|
337
|
+
{phase === "memorize" && (
|
|
338
|
+
<p style={{ ...styles.gmBodyM, color: "#10b981" }}>
|
|
339
|
+
MEMORIZE ({memorizeTime})
|
|
340
|
+
</p>
|
|
341
|
+
)}
|
|
342
|
+
{phase === "guess" && !answered && (
|
|
343
|
+
<p style={styles.gmBodyM}>⏳ Time left: {timeLeft}s</p>
|
|
344
|
+
)}
|
|
345
|
+
</div>
|
|
346
|
+
|
|
347
|
+
{phase !== "ready" && (
|
|
348
|
+
<div
|
|
349
|
+
style={{
|
|
350
|
+
...styles.gmGrid,
|
|
351
|
+
gridTemplateColumns: isMobile ? "repeat(2, 1fr)" : "repeat(3, 210px)",
|
|
352
|
+
gridAutoRows: isMobile ? "150px" : "210px",
|
|
353
|
+
gap: isMobile ? "12px" : "20px",
|
|
354
|
+
justifyItems: "center",
|
|
355
|
+
}}
|
|
356
|
+
>
|
|
357
|
+
{files.map((file, i) => {
|
|
358
|
+
const isHidden =
|
|
359
|
+
hiddenIndex === i && phase === "guess" && !answered;
|
|
360
|
+
return (
|
|
361
|
+
<div
|
|
362
|
+
key={i}
|
|
426
363
|
style={{
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
364
|
+
...styles.gmCard,
|
|
365
|
+
...(result === "correct" && hiddenIndex === i
|
|
366
|
+
? styles.gmCorrect
|
|
367
|
+
: {}),
|
|
368
|
+
...(result === "wrong" && hiddenIndex === i
|
|
369
|
+
? styles.gmWrong
|
|
370
|
+
: {}),
|
|
430
371
|
}}
|
|
431
|
-
|
|
432
|
-
|
|
372
|
+
>
|
|
373
|
+
{!isHidden && (
|
|
374
|
+
<img
|
|
375
|
+
src={file.src}
|
|
376
|
+
alt={file.name}
|
|
377
|
+
style={{
|
|
378
|
+
width: "100%",
|
|
379
|
+
height: "100%",
|
|
380
|
+
objectFit: "cover",
|
|
381
|
+
}}
|
|
382
|
+
/>
|
|
383
|
+
)}
|
|
384
|
+
</div>
|
|
385
|
+
);
|
|
386
|
+
})}
|
|
387
|
+
</div>
|
|
388
|
+
)}
|
|
389
|
+
|
|
390
|
+
<div style={{ marginTop: 16, height: 80 }}>
|
|
391
|
+
{phase === "guess" && !answered && (
|
|
392
|
+
<div>
|
|
393
|
+
<input
|
|
394
|
+
type="text"
|
|
395
|
+
placeholder="Type the missing word"
|
|
396
|
+
value={inputValue}
|
|
397
|
+
onChange={(e) => setInputValue(e.target.value)}
|
|
398
|
+
style={styles.gmInput}
|
|
399
|
+
/>
|
|
400
|
+
<button
|
|
401
|
+
style={{ ...styles.gmButton, marginLeft: 8 }}
|
|
402
|
+
onClick={checkAnswer}
|
|
403
|
+
disabled={animating}
|
|
404
|
+
>
|
|
405
|
+
{animating ? "..." : "Check"}
|
|
406
|
+
</button>
|
|
433
407
|
</div>
|
|
434
|
-
)
|
|
435
|
-
|
|
408
|
+
)}
|
|
409
|
+
{answered && (
|
|
410
|
+
<button style={styles.gmButton} onClick={nextRound}>
|
|
411
|
+
Next round
|
|
412
|
+
</button>
|
|
413
|
+
)}
|
|
414
|
+
</div>
|
|
436
415
|
</div>
|
|
437
416
|
)}
|
|
438
|
-
|
|
439
|
-
<div style={{ marginTop: 16, height: 80 }}>
|
|
440
|
-
{phase === "guess" && !answered && (
|
|
441
|
-
<div>
|
|
442
|
-
<input
|
|
443
|
-
type="text"
|
|
444
|
-
placeholder="Type the missing word"
|
|
445
|
-
value={inputValue}
|
|
446
|
-
onChange={(e) => setInputValue(e.target.value)}
|
|
447
|
-
style={styles.gmInput}
|
|
448
|
-
/>
|
|
449
|
-
<button
|
|
450
|
-
style={{ ...styles.gmButton, marginLeft: 8 }}
|
|
451
|
-
onClick={checkAnswer}
|
|
452
|
-
disabled={animating}
|
|
453
|
-
>
|
|
454
|
-
{animating ? "..." : "Check"}
|
|
455
|
-
</button>
|
|
456
|
-
</div>
|
|
457
|
-
)}
|
|
458
|
-
{answered && (
|
|
459
|
-
<button style={styles.gmButton} onClick={nextRound}>
|
|
460
|
-
Next round
|
|
461
|
-
</button>
|
|
462
|
-
)}
|
|
463
|
-
</div>
|
|
464
417
|
</div>
|
|
465
|
-
|
|
418
|
+
</div>
|
|
466
419
|
</div>
|
|
467
420
|
);
|
|
468
421
|
}
|