mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-29 19:13:49 +01:00
dialogBoxCreate now uses the same logic as other popups, now all popup can be dismissed with escape.
This commit is contained in:
parent
5c92360310
commit
d6b349b6ff
@ -7,7 +7,7 @@ import { Player } from "../Player";
|
|||||||
import { redPillFlag } from "../RedPill";
|
import { redPillFlag } from "../RedPill";
|
||||||
import { GetServerByHostname } from "../Server/ServerHelpers";
|
import { GetServerByHostname } from "../Server/ServerHelpers";
|
||||||
import { Settings } from "../Settings/Settings";
|
import { Settings } from "../Settings/Settings";
|
||||||
import { dialogBoxCreate, dialogBoxOpened} from "../../utils/DialogBox";
|
import { dialogBoxCreate} from "../../utils/DialogBox";
|
||||||
import { Reviver } from "../../utils/JSONReviver";
|
import { Reviver } from "../../utils/JSONReviver";
|
||||||
|
|
||||||
//Sends message to player, including a pop up
|
//Sends message to player, including a pop up
|
||||||
@ -59,12 +59,10 @@ function checkForMessagesToSend() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (redpill && redpillOwned && Player.sourceFiles.length === 0 && !redPillFlag && !inMission) {
|
if (redpill && redpillOwned && Player.sourceFiles.length === 0 && !redPillFlag && !inMission) {
|
||||||
if (!dialogBoxOpened) {
|
|
||||||
sendMessage(redpill, true);
|
sendMessage(redpill, true);
|
||||||
}
|
|
||||||
} else if (redpill && redpillOwned) {
|
} else if (redpill && redpillOwned) {
|
||||||
//If player has already destroyed a BitNode, message is not forced
|
//If player has already destroyed a BitNode, message is not forced
|
||||||
if (!redPillFlag && !inMission && !dialogBoxOpened) {
|
if (!redPillFlag && !inMission) {
|
||||||
sendMessage(redpill);
|
sendMessage(redpill);
|
||||||
}
|
}
|
||||||
} else if (jumper0 && !jumper0.recvd && Player.hacking_skill >= 25) {
|
} else if (jumper0 && !jumper0.recvd && Player.hacking_skill >= 25) {
|
||||||
|
@ -3,15 +3,27 @@
|
|||||||
*
|
*
|
||||||
* Takes in a prop for rendering the content inside the popup
|
* Takes in a prop for rendering the content inside the popup
|
||||||
*/
|
*/
|
||||||
import * as React from "react";
|
import React, { useEffect } from "react";
|
||||||
|
|
||||||
interface IProps<T> {
|
interface IProps<T> {
|
||||||
content: (props: T) => React.ReactElement;
|
content: (props: T) => React.ReactElement;
|
||||||
id: string;
|
id: string;
|
||||||
props: T;
|
props: T;
|
||||||
|
removePopup: (id: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Popup<T>(props: IProps<T>): React.ReactElement {
|
export function Popup<T>(props: IProps<T>): React.ReactElement {
|
||||||
|
function keyDown(event: KeyboardEvent): void {
|
||||||
|
if(event.key === 'Escape') props.removePopup(props.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
document.addEventListener('keydown', keyDown);
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('keydown', keyDown);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={"popup-box-content"} id={`${props.id}-content`}>
|
<div className={"popup-box-content"} id={`${props.id}-content`}>
|
||||||
{React.createElement(props.content, props.props)}
|
{React.createElement(props.content, props.props)}
|
||||||
|
@ -16,6 +16,7 @@ import { removeElementById } from "../../../utils/uiHelpers/removeElementById";
|
|||||||
|
|
||||||
let gameContainer: HTMLElement;
|
let gameContainer: HTMLElement;
|
||||||
|
|
||||||
|
(function() {
|
||||||
function getGameContainer(): void {
|
function getGameContainer(): void {
|
||||||
const container = document.getElementById("entire-game-container");
|
const container = document.getElementById("entire-game-container");
|
||||||
if (container == null) {
|
if (container == null) {
|
||||||
@ -27,9 +28,15 @@ function getGameContainer(): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", getGameContainer);
|
document.addEventListener("DOMContentLoaded", getGameContainer);
|
||||||
|
})();
|
||||||
|
|
||||||
|
// This variable is used to avoid setting the semi-transparent background
|
||||||
|
// several times on top of one another. Sometimes there's several popup at once.
|
||||||
|
let deepestPopupId: string = "";
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||||
export function createPopup<T>(id: string, rootComponent: (props: T) => React.ReactElement, props: T): HTMLElement | null {
|
export function createPopup<T>(id: string, rootComponent: (props: T) => React.ReactElement, props: T): HTMLElement | null {
|
||||||
|
|
||||||
let container = document.getElementById(id);
|
let container = document.getElementById(id);
|
||||||
if (container == null) {
|
if (container == null) {
|
||||||
function onClick(this: HTMLElement, event: MouseEvent): any {
|
function onClick(this: HTMLElement, event: MouseEvent): any {
|
||||||
@ -39,19 +46,20 @@ export function createPopup<T>(id: string, rootComponent: (props: T) => React.Re
|
|||||||
if(clickedId !== id) return;
|
if(clickedId !== id) return;
|
||||||
removePopup(id);
|
removePopup(id);
|
||||||
}
|
}
|
||||||
|
const backgroundColor = deepestPopupId === "" ? 'rgba(0,0,0,0.5)' : 'rgba(0,0,0,0)';
|
||||||
container = createElement("div", {
|
container = createElement("div", {
|
||||||
class: "popup-box-container",
|
class: "popup-box-container",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
id: id,
|
id: id,
|
||||||
backgroundColor: 'rgba(0,0,0,0.5)',
|
backgroundColor: backgroundColor,
|
||||||
clickListener: onClick,
|
clickListener: onClick,
|
||||||
});
|
});
|
||||||
|
|
||||||
gameContainer.appendChild(container);
|
gameContainer.appendChild(container);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReactDOM.render(<Popup content={rootComponent} id={id} props={props} />, container);
|
if(deepestPopupId === "") deepestPopupId = id;
|
||||||
|
ReactDOM.render(<Popup content={rootComponent} id={id} props={props} removePopup={removePopup} />, container);
|
||||||
|
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
@ -67,4 +75,5 @@ export function removePopup(id: string): void {
|
|||||||
|
|
||||||
removeElementById(id);
|
removeElementById(id);
|
||||||
removeElementById(`${id}-close`);
|
removeElementById(`${id}-close`);
|
||||||
|
if(id === deepestPopupId) deepestPopupId = "";
|
||||||
}
|
}
|
||||||
|
2
utils/DialogBox.d.ts
vendored
2
utils/DialogBox.d.ts
vendored
@ -1,2 +0,0 @@
|
|||||||
export function dialogBoxCreate(txt: string | JSX.Element, preformatted?: boolean): void;
|
|
||||||
export let dialogBoxOpened: boolean;
|
|
@ -1,76 +0,0 @@
|
|||||||
import { KEY } from "./helpers/keyCodes";
|
|
||||||
import { DialogBox } from "./ui/DialogBox";
|
|
||||||
import React from "react";
|
|
||||||
import ReactDOM from "react-dom";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create and display a pop-up dialog box.
|
|
||||||
* This dialog box does not allow for any interaction and should close when clicking
|
|
||||||
* outside of it
|
|
||||||
*/
|
|
||||||
let dialogBoxes = [];
|
|
||||||
|
|
||||||
// Close dialog box when clicking outside
|
|
||||||
$(document).click(function(event) {
|
|
||||||
if (dialogBoxOpened && dialogBoxes.length >= 1) {
|
|
||||||
if (!$(event.target).closest(dialogBoxes[0]).length){
|
|
||||||
closeTopmostDialogBox();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function closeTopmostDialogBox() {
|
|
||||||
if (!dialogBoxOpened || dialogBoxes.length === 0) return;
|
|
||||||
dialogBoxes[0].remove();
|
|
||||||
dialogBoxes.shift();
|
|
||||||
if (dialogBoxes.length == 0) {
|
|
||||||
dialogBoxOpened = false;
|
|
||||||
} else {
|
|
||||||
dialogBoxes[0].style.visibility = "visible";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dialog box close buttons
|
|
||||||
$(document).on('click', '.dialog-box-close-button', function() {
|
|
||||||
closeTopmostDialogBox();
|
|
||||||
});
|
|
||||||
|
|
||||||
document.addEventListener("keydown", function (event) {
|
|
||||||
if (event.keyCode == KEY.ESC && dialogBoxOpened) {
|
|
||||||
closeTopmostDialogBox();
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let dialogBoxOpened = false;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function dialogBoxCreate(txt, preformatted=false) {
|
|
||||||
const container = document.createElement("div");
|
|
||||||
container.setAttribute("class", "dialog-box-container");
|
|
||||||
|
|
||||||
let elem = txt;
|
|
||||||
if (typeof txt === 'string') {
|
|
||||||
if (preformatted) {
|
|
||||||
// For text files as they are often computed data that
|
|
||||||
// shouldn't be wrapped and should retain tabstops.
|
|
||||||
elem = <pre dangerouslySetInnerHTML={{ __html: txt }} />
|
|
||||||
} else {
|
|
||||||
elem = <p dangerouslySetInnerHTML={{ __html: txt.replace(/(?:\r\n|\r|\n)/g, '<br />') }} />
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReactDOM.render(DialogBox(elem), container);
|
|
||||||
document.body.appendChild(container);
|
|
||||||
if (dialogBoxes.length >= 1) {
|
|
||||||
container.style.visibility = "hidden";
|
|
||||||
}
|
|
||||||
dialogBoxes.push(container);
|
|
||||||
|
|
||||||
setTimeout(function() {
|
|
||||||
dialogBoxOpened = true;
|
|
||||||
}, 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
export {dialogBoxCreate, dialogBoxOpened};
|
|
38
utils/DialogBox.tsx
Normal file
38
utils/DialogBox.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { KEY } from "./helpers/keyCodes";
|
||||||
|
import { DialogBox } from "./ui/DialogBox";
|
||||||
|
import { createPopup } from "../src/ui/React/createPopup";
|
||||||
|
import { getRandomInt } from "./helpers/getRandomInt";
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import ReactDOM from "react-dom";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
content: JSX.Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function MessagePopup(props: IProps): React.ReactElement {
|
||||||
|
return (<>{props.content}</>);
|
||||||
|
}
|
||||||
|
|
||||||
|
function dialogBoxCreate(txt: string | JSX.Element, preformatted: boolean = false): void {
|
||||||
|
const popupId = `popup-`+(Array.from(Array(16))).map(() => `${getRandomInt(0, 9)}`).join('');
|
||||||
|
if (typeof txt === 'string') {
|
||||||
|
if (preformatted) {
|
||||||
|
// For text files as they are often computed data that
|
||||||
|
// shouldn't be wrapped and should retain tabstops.
|
||||||
|
createPopup(popupId, MessagePopup, {
|
||||||
|
content: (<pre dangerouslySetInnerHTML={{ __html: txt }} />)
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
createPopup(popupId, MessagePopup, {
|
||||||
|
content: (<p dangerouslySetInnerHTML={{ __html: txt.replace(/(?:\r\n|\r|\n)/g, '<br />') }} />)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
createPopup(popupId, MessagePopup, {
|
||||||
|
content: txt
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {dialogBoxCreate};
|
Loading…
Reference in New Issue
Block a user