From 35c32e2871137584105389675a1d87081a77111b Mon Sep 17 00:00:00 2001 From: catloversg <152669316+catloversg@users.noreply.github.com> Date: Fri, 10 May 2024 15:55:50 +0700 Subject: [PATCH] BUGFIX: Fix unresolved promise in ns.prompt API (#1257) --- markdown/bitburner.ns.prompt.md | 4 +++- src/ScriptEditor/NetscriptDefinitions.d.ts | 7 +++++- src/ui/React/PromptManager.tsx | 26 ++++++++++++++++------ 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/markdown/bitburner.ns.prompt.md b/markdown/bitburner.ns.prompt.md index fb4bf4d05..38cbd1033 100644 --- a/markdown/bitburner.ns.prompt.md +++ b/markdown/bitburner.ns.prompt.md @@ -32,7 +32,9 @@ True if the player clicks “Yes”; false if the player clicks “No”; or the RAM cost: 0 GB -Prompts the player with a dialog box. Here is an explanation of the various options. +Prompts the player with a dialog box and returns a promise. If the player cancels this dialog box (press X button or click outside the dialog box), the promise is resolved with a default value (empty string or "false"). If this API is called again while the old dialog box still exists, the old dialog box will be replaced with a new one, and the old promise will be resolved with the default value. + +Here is an explanation of the various options. - `options.type` is not provided to the function. If `options.type` is left out and only a string is passed to the function, then the default behavior is to create a boolean dialog box. diff --git a/src/ScriptEditor/NetscriptDefinitions.d.ts b/src/ScriptEditor/NetscriptDefinitions.d.ts index 3d4934411..33346ce78 100644 --- a/src/ScriptEditor/NetscriptDefinitions.d.ts +++ b/src/ScriptEditor/NetscriptDefinitions.d.ts @@ -7158,7 +7158,12 @@ export interface NS { * @remarks * RAM cost: 0 GB * - * Prompts the player with a dialog box. Here is an explanation of the various options. + * Prompts the player with a dialog box and returns a promise. If the player cancels this dialog box (press X button + * or click outside the dialog box), the promise is resolved with a default value (empty string or "false"). If this + * API is called again while the old dialog box still exists, the old dialog box will be replaced with a new one, and + * the old promise will be resolved with the default value. + * + * Here is an explanation of the various options. * * - `options.type` is not provided to the function. If `options.type` is left out and * only a string is passed to the function, then the default behavior is to create a diff --git a/src/ui/React/PromptManager.tsx b/src/ui/React/PromptManager.tsx index 5288450cc..cf4264415 100644 --- a/src/ui/React/PromptManager.tsx +++ b/src/ui/React/PromptManager.tsx @@ -18,19 +18,31 @@ interface Prompt { export function PromptManager({ hidden }: { hidden: boolean }): React.ReactElement { const [prompt, setPrompt] = useState(null); + + const resolveCurrentPromptWithDefaultValue = (currentPrompt: Prompt) => { + if (["text", "select"].includes(currentPrompt.options?.type ?? "")) { + currentPrompt.resolve(""); + } else { + currentPrompt.resolve(false); + } + }; + useEffect(() => { - return PromptEvent.subscribe((p: Prompt) => { - setPrompt(p); + return PromptEvent.subscribe((newPrompt: Prompt) => { + setPrompt((currentPrompt) => { + if (currentPrompt) { + resolveCurrentPromptWithDefaultValue(currentPrompt); + } + return newPrompt; + }); }); }, []); function close(): void { - if (prompt === null) return; - if (["text", "select"].includes(prompt.options?.type ?? "")) { - prompt.resolve(""); - } else { - prompt.resolve(false); + if (prompt === null) { + return; } + resolveCurrentPromptWithDefaultValue(prompt); setPrompt(null); }