bitburner-src/src/ui/React/CodingContractModal.tsx
2022-03-18 10:43:56 +01:00

91 lines
2.7 KiB
TypeScript

import React, { useState, useEffect } from "react";
import { KEY } from "../../utils/helpers/keyCodes";
import { CodingContract, CodingContractTypes } from "../../CodingContracts";
import { CopyableText } from "./CopyableText";
import { Modal } from "./Modal";
import { EventEmitter } from "../../utils/EventEmitter";
import Typography from "@mui/material/Typography";
import TextField from "@mui/material/TextField";
import Button from "@mui/material/Button";
interface IProps {
c: CodingContract;
onClose: () => void;
onAttempt: (answer: string) => void;
}
export const CodingContractEvent = new EventEmitter<[IProps]>();
export function CodingContractModal(): React.ReactElement {
const [props, setProps] = useState<IProps | null>(null);
const [answer, setAnswer] = useState("");
useEffect(() => {
CodingContractEvent.subscribe((props) => setProps(props));
});
if (props === null) return <></>;
function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
setAnswer(event.target.value);
}
function onKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {
if (props === null) return;
// React just won't cooperate on this one.
// "React.KeyboardEvent<HTMLInputElement>" seems like the right type but
// whatever ...
const value = (event.target as any).value;
if (event.key === KEY.ENTER && value !== "") {
event.preventDefault();
props.onAttempt(answer);
setAnswer("");
close();
}
}
function close(): void {
if (props === null) return;
props.onClose();
setProps(null);
}
const contractType = CodingContractTypes[props.c.type];
const description = [];
for (const [i, value] of contractType.desc(props.c.data).split("\n").entries())
description.push(<span key={i} dangerouslySetInnerHTML={{ __html: value + "<br />" }}></span>);
return (
<Modal open={props !== null} onClose={close}>
<CopyableText variant="h4" value={props.c.type} />
<Typography>
You are attempting to solve a Coding Contract. You have {props.c.getMaxNumTries() - props.c.tries} tries
remaining, after which the contract will self-destruct.
</Typography>
<br />
<Typography>{description}</Typography>
<br />
<TextField
autoFocus
placeholder="Enter Solution here"
value={answer}
onChange={onChange}
onKeyDown={onKeyDown}
InputProps={{
endAdornment: (
<Button
onClick={() => {
props.onAttempt(answer);
setAnswer("");
close();
}}
>
Solve
</Button>
),
}}
/>
</Modal>
);
}