2022-03-17 21:44:44 +01:00
|
|
|
import React, { useState, useEffect } from "react";
|
2021-10-02 04:53:23 +02:00
|
|
|
import { EventEmitter } from "../../utils/EventEmitter";
|
2022-03-06 05:05:55 +01:00
|
|
|
import { Modal } from "./Modal";
|
2021-10-02 04:53:23 +02:00
|
|
|
import Typography from "@mui/material/Typography";
|
|
|
|
import Button from "@mui/material/Button";
|
2022-01-30 15:06:18 +01:00
|
|
|
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
2022-03-17 21:44:44 +01:00
|
|
|
import TextField from "@mui/material/TextField";
|
|
|
|
import MenuItem from "@mui/material/MenuItem";
|
2022-03-18 11:15:51 +01:00
|
|
|
import { KEY } from "../../utils/helpers/keyCodes";
|
2021-10-02 04:53:23 +02:00
|
|
|
|
|
|
|
export const PromptEvent = new EventEmitter<[Prompt]>();
|
|
|
|
|
|
|
|
interface Prompt {
|
|
|
|
txt: string;
|
2022-03-17 21:44:44 +01:00
|
|
|
options?: { type?: string; choices?: string[] };
|
2022-01-30 15:06:18 +01:00
|
|
|
resolve: (result: boolean | string) => void;
|
2021-10-02 04:53:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export function PromptManager(): React.ReactElement {
|
|
|
|
const [prompt, setPrompt] = useState<Prompt | null>(null);
|
2022-03-17 21:44:44 +01:00
|
|
|
useEffect(() => {
|
|
|
|
return PromptEvent.subscribe((p: Prompt) => {
|
|
|
|
setPrompt(p);
|
|
|
|
});
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
if (prompt === null) {
|
|
|
|
return <></>;
|
|
|
|
}
|
2022-01-30 15:21:46 +01:00
|
|
|
|
2021-10-02 04:53:23 +02:00
|
|
|
function close(): void {
|
|
|
|
if (prompt === null) return;
|
2022-03-17 21:44:44 +01:00
|
|
|
if (["text", "select"].includes(prompt?.options?.type ?? "")) {
|
|
|
|
prompt.resolve("");
|
|
|
|
} else {
|
|
|
|
prompt.resolve(false);
|
|
|
|
}
|
2021-10-02 04:53:23 +02:00
|
|
|
setPrompt(null);
|
|
|
|
}
|
|
|
|
|
2022-03-17 21:44:44 +01:00
|
|
|
const types: { [key: string]: any } = {
|
|
|
|
text: PromptMenuText,
|
|
|
|
select: PromptMenuSelect,
|
|
|
|
};
|
2022-01-30 15:06:18 +01:00
|
|
|
|
2022-03-17 21:44:44 +01:00
|
|
|
let PromptContent = PromptMenuBoolean;
|
2022-03-17 23:17:19 +01:00
|
|
|
if (prompt?.options?.type && ["text", "select"].includes(prompt?.options?.type))
|
|
|
|
PromptContent = types[prompt?.options?.type];
|
2022-03-17 21:44:44 +01:00
|
|
|
const resolve = (value: boolean | string): void => {
|
|
|
|
prompt.resolve(value);
|
|
|
|
setPrompt(null);
|
|
|
|
};
|
2021-10-02 04:53:23 +02:00
|
|
|
|
|
|
|
return (
|
2022-03-17 21:44:44 +01:00
|
|
|
<Modal open={true} onClose={close}>
|
2022-03-18 22:13:21 +01:00
|
|
|
<pre>
|
|
|
|
<Typography>{prompt.txt}</Typography>
|
|
|
|
</pre>
|
2022-03-17 21:44:44 +01:00
|
|
|
<PromptContent prompt={prompt} resolve={resolve} />
|
|
|
|
</Modal>
|
2021-10-02 04:53:23 +02:00
|
|
|
);
|
|
|
|
}
|
2022-01-30 15:06:18 +01:00
|
|
|
|
2022-03-17 21:44:44 +01:00
|
|
|
interface IContentProps {
|
|
|
|
prompt: Prompt;
|
|
|
|
resolve: (value: boolean | string) => void;
|
|
|
|
}
|
|
|
|
|
|
|
|
function PromptMenuBoolean({ resolve }: IContentProps): React.ReactElement {
|
|
|
|
const yes = (): void => resolve(true);
|
|
|
|
const no = (): void => resolve(false);
|
2022-01-30 15:06:18 +01:00
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
2022-03-17 21:44:44 +01:00
|
|
|
<div style={{ display: "flex", justifyContent: "center", alignItems: "center", paddingTop: "10px" }}>
|
|
|
|
<Button style={{ marginRight: "auto" }} onClick={yes}>
|
|
|
|
Yes
|
|
|
|
</Button>
|
2022-01-30 15:06:18 +01:00
|
|
|
<Button onClick={no}>No</Button>
|
|
|
|
</div>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-03-17 21:44:44 +01:00
|
|
|
function PromptMenuText({ resolve }: IContentProps): React.ReactElement {
|
|
|
|
const [value, setValue] = useState("");
|
2022-01-30 15:06:18 +01:00
|
|
|
|
2022-03-17 21:44:44 +01:00
|
|
|
const submit = (): void => resolve(value);
|
2022-01-30 15:06:18 +01:00
|
|
|
|
|
|
|
const onInput = (event: React.ChangeEvent<HTMLInputElement>): void => {
|
|
|
|
setValue(event.target.value);
|
2022-03-17 21:44:44 +01:00
|
|
|
};
|
2022-01-30 15:06:18 +01:00
|
|
|
|
|
|
|
const onKeyDown = (event: React.KeyboardEvent<HTMLInputElement>): void => {
|
|
|
|
event.stopPropagation();
|
|
|
|
|
2022-03-18 11:15:51 +01:00
|
|
|
if (event.key === KEY.ENTER) {
|
2022-01-30 15:06:18 +01:00
|
|
|
event.preventDefault();
|
|
|
|
submit();
|
|
|
|
}
|
2022-03-17 21:44:44 +01:00
|
|
|
};
|
2022-01-30 15:06:18 +01:00
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
2022-03-17 21:44:44 +01:00
|
|
|
<div style={{ display: "flex", alignItems: "center", paddingTop: "10px" }}>
|
2022-01-30 15:06:18 +01:00
|
|
|
<TextField
|
|
|
|
autoFocus
|
|
|
|
value={value}
|
|
|
|
onInput={onInput}
|
|
|
|
onKeyDown={onKeyDown}
|
2022-03-17 21:44:44 +01:00
|
|
|
style={{ flex: "1 0 auto" }}
|
2022-01-30 15:06:18 +01:00
|
|
|
InputProps={{
|
2022-03-17 21:44:44 +01:00
|
|
|
endAdornment: <Button onClick={submit}>Confirm</Button>,
|
2022-01-30 15:06:18 +01:00
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-03-17 21:44:44 +01:00
|
|
|
function PromptMenuSelect({ prompt, resolve }: IContentProps): React.ReactElement {
|
|
|
|
const [value, setValue] = useState("");
|
2022-01-30 15:06:18 +01:00
|
|
|
|
2022-03-17 21:44:44 +01:00
|
|
|
const submit = (): void => resolve(value);
|
2022-01-30 15:06:18 +01:00
|
|
|
|
|
|
|
const onChange = (event: SelectChangeEvent<string>): void => {
|
|
|
|
setValue(event.target.value);
|
2022-03-17 21:44:44 +01:00
|
|
|
};
|
2022-01-30 15:06:18 +01:00
|
|
|
|
2022-03-17 21:44:44 +01:00
|
|
|
const getItems = (choices: string[]): React.ReactElement[] => {
|
2022-01-30 15:06:18 +01:00
|
|
|
const content = [];
|
2022-03-17 21:44:44 +01:00
|
|
|
for (const i of choices) {
|
2022-01-30 15:06:18 +01:00
|
|
|
// @ts-ignore
|
2022-03-17 21:44:44 +01:00
|
|
|
content.push(
|
|
|
|
<MenuItem key={i} value={i}>
|
|
|
|
{i}
|
|
|
|
</MenuItem>,
|
|
|
|
);
|
2022-01-30 15:06:18 +01:00
|
|
|
}
|
|
|
|
return content;
|
2022-03-17 21:44:44 +01:00
|
|
|
};
|
2022-01-30 15:06:18 +01:00
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
2022-03-17 21:44:44 +01:00
|
|
|
<div style={{ display: "flex", alignItems: "center", paddingTop: "10px" }}>
|
|
|
|
<Select onChange={onChange} value={value} style={{ flex: "1 0 auto" }}>
|
2022-01-31 19:15:13 +01:00
|
|
|
{getItems(prompt?.options?.choices || [])}
|
2022-01-30 15:06:18 +01:00
|
|
|
</Select>
|
2022-03-17 21:44:44 +01:00
|
|
|
<Button onClick={submit} disabled={value === ""}>
|
|
|
|
Confirm
|
|
|
|
</Button>
|
2022-01-30 15:06:18 +01:00
|
|
|
</div>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
}
|