bitburner-src/src/ui/React/CodingContractModal.tsx

91 lines
2.7 KiB
TypeScript
Raw Normal View History

2021-10-01 19:08:37 +02:00
import React, { useState, useEffect } from "react";
2021-09-25 20:42:57 +02:00
import { KEY } from "../../utils/helpers/keyCodes";
2021-10-15 00:45:50 +02:00
import { CodingContract, CodingContractTypes } from "../../CodingContracts";
2021-10-01 19:36:59 +02:00
import { CopyableText } from "./CopyableText";
2021-10-01 19:08:37 +02:00
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";
2021-10-01 19:08:37 +02:00
interface IProps {
2021-09-05 01:09:30 +02:00
c: CodingContract;
onClose: () => void;
onAttempt: (answer: string) => void;
2021-10-01 19:08:37 +02:00
}
export const CodingContractEvent = new EventEmitter<[IProps]>();
2021-10-01 19:08:37 +02:00
export function CodingContractModal(): React.ReactElement {
const [props, setProps] = useState<IProps | null>(null);
2021-09-05 01:09:30 +02:00
const [answer, setAnswer] = useState("");
2021-10-01 19:08:37 +02:00
useEffect(() => {
CodingContractEvent.subscribe((props) => setProps(props));
});
if (props === null) return <></>;
2021-09-05 01:09:30 +02:00
function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
setAnswer(event.target.value);
}
2021-09-05 01:09:30 +02:00
function onKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {
2021-10-01 19:08:37 +02:00
if (props === null) return;
2021-09-05 01:09:30 +02:00
// 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;
2021-05-29 20:48:56 +02:00
2021-09-05 01:09:30 +02:00
if (event.keyCode === KEY.ENTER && value !== "") {
event.preventDefault();
props.onAttempt(answer);
setAnswer("");
2021-11-27 00:59:25 +01:00
close();
}
2021-09-05 01:09:30 +02:00
}
2021-10-01 19:08:37 +02:00
function close(): void {
if (props === null) return;
props.onClose();
setProps(null);
}
2021-10-15 00:45:50 +02:00
const contractType = CodingContractTypes[props.c.type];
2021-09-05 01:09:30 +02:00
const description = [];
2021-09-09 05:47:34 +02:00
for (const [i, value] of contractType.desc(props.c.data).split("\n").entries())
description.push(<span key={i} dangerouslySetInnerHTML={{ __html: value + "<br />" }}></span>);
2021-09-05 01:09:30 +02:00
return (
2021-10-01 19:08:37 +02:00
<Modal open={props !== null} onClose={close}>
2021-10-01 19:36:59 +02:00
<CopyableText variant="h4" value={props.c.type} />
2021-10-01 19:08:37 +02:00
<Typography>
2021-09-09 05:47:34 +02:00
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.
2021-10-01 19:08:37 +02:00
</Typography>
2021-09-05 01:09:30 +02:00
<br />
2021-10-01 19:08:37 +02:00
<Typography>{description}</Typography>
2021-09-05 01:09:30 +02:00
<br />
2021-10-01 19:08:37 +02:00
<TextField
autoFocus
2021-09-05 01:09:30 +02:00
placeholder="Enter Solution here"
value={answer}
onChange={onChange}
onKeyDown={onKeyDown}
2021-10-01 19:08:37 +02:00
InputProps={{
endAdornment: (
<Button
onClick={() => {
props.onAttempt(answer);
setAnswer("");
2021-10-01 19:08:37 +02:00
close();
}}
>
Solve
</Button>
),
}}
2021-09-05 01:09:30 +02:00
/>
2021-10-01 19:08:37 +02:00
</Modal>
2021-09-05 01:09:30 +02:00
);
}