blob: f412ba5bce6686fc8a19e1b95a9387dfad7ac3f9 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
import type { Quiz } from "../quiz";
import { execPHP } from "../exec_php";
import React, { useState, useEffect } from "react";
import { useDebounce } from "use-debounce";
type Props = {
quiz: Quiz;
};
function FuncExpectedAnswer({ quiz }: Props) {
const [argument, setArgument] = useState<string>("123");
const [debouncedArgument] = useDebounce(argument, 1000);
const [result, setResult] = useState<string>("");
const [loading, setLoading] = useState<boolean>(true);
const handleArgumentChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setArgument(e.target.value);
};
useEffect(() => {
if (debouncedArgument === "") {
setResult("<empty>");
return;
}
setLoading(true);
setResult("");
const code = `
function f($x) {
return ${quiz.func}($x);
}
try {
var_dump(f(${debouncedArgument}));
} catch (\\Throwable $e) {
echo $e->getMessage(), PHP_EOL;
}
`;
execPHP(code).then((result) => {
const output = result.stdout + result.stderr;
setResult(output.replaceAll(quiz.func, "<answer is masked>"));
setLoading(false);
});
}, [debouncedArgument, quiz.func]);
return (
<div>
<code>
{`f(`}
<input type="text" value={argument} onChange={handleArgumentChange} />
{`)`}
</code>
は <code>{loading ? "running..." : result}</code> を返す。
</div>
);
}
export default FuncExpectedAnswer;
|