diff --git a/css/_reset.scss b/css/_reset.scss
index 3f6a10dee..145f51196 100644
--- a/css/_reset.scss
+++ b/css/_reset.scss
@@ -11,5 +11,5 @@
margin: 0;
padding: 0;
box-sizing: border-box;
- vertical-align: top;
+ vertical-align: middle;
}
diff --git a/css/popupboxes.scss b/css/popupboxes.scss
index e2394d77a..c308a520e 100644
--- a/css/popupboxes.scss
+++ b/css/popupboxes.scss
@@ -27,6 +27,10 @@
color: var(--my-font-color);
}
+.popup-box-input-div {
+ margin: 2px;
+}
+
.popup-box-button,
.popup-box-button-inactive {
color: #aaa;
@@ -189,11 +193,6 @@
background-color: #000;
}
-/* Generic Yes No Box */
-#yes-no-text-input-box-input {
- color: #fff;
-}
-
/* Game Options */
#game-options-container {
transition: opacity 400ms ease-in;
diff --git a/src/Locations/LocationsHelpers.tsx b/src/Locations/LocationsHelpers.tsx
index 7f620dbf2..06fc1ed55 100644
--- a/src/Locations/LocationsHelpers.tsx
+++ b/src/Locations/LocationsHelpers.tsx
@@ -9,11 +9,9 @@ import { CityName } from "./data/CityNames";
import { IPlayer } from "../PersonObjects/IPlayer";
import { AddToAllServers, createUniqueRandomIp } from "../Server/AllServers";
import { safetlyCreateUniqueServer } from "../Server/ServerHelpers";
-import { getPurchaseServerCost, purchaseServer } from "../Server/ServerPurchases";
import { SpecialServerIps } from "../Server/SpecialServerIps";
import { Settings } from "../Settings/Settings";
-import { numeralWrapper } from "../ui/numeralFormat";
import { Money } from "../ui/React/Money";
import { dialogBoxCreate } from "../../utils/DialogBox";
@@ -22,10 +20,6 @@ import {
yesNoBoxGetNoButton,
yesNoBoxClose,
yesNoBoxCreate,
- yesNoTxtInpBoxGetYesButton,
- yesNoTxtInpBoxGetNoButton,
- yesNoTxtInpBoxClose,
- yesNoTxtInpBoxCreate,
} from "../../utils/YesNoBox";
import { createElement } from "../../utils/uiHelpers/createElement";
@@ -78,45 +72,6 @@ export function createTravelPopup(destination: CityName, travelFn: TravelFunctio
);
}
-/**
- * Create a pop-up box that lets the player purchase a server.
- * @param {number} ram - Amount of RAM (GB) on server
- * @param {IPlayer} p - Player object
- */
-export function createPurchaseServerPopup(ram: number, p: IPlayer): void {
- const cost = getPurchaseServerCost(ram);
- if (cost === Infinity) {
- dialogBoxCreate("Something went wrong when trying to purchase this server. Please contact developer.");
- return;
- }
-
- const yesBtn = yesNoTxtInpBoxGetYesButton();
- const noBtn = yesNoTxtInpBoxGetNoButton();
- if (yesBtn == null || noBtn == null) {
- return;
- }
- yesBtn.innerHTML = "Purchase Server";
- noBtn.innerHTML = "Cancel";
- yesBtn.addEventListener("click", function () {
- purchaseServer(ram, p);
- yesNoTxtInpBoxClose();
- });
- noBtn.addEventListener("click", function () {
- yesNoTxtInpBoxClose();
- });
-
- yesNoTxtInpBoxCreate(
- <>
- Would you like to purchase a new server with {numeralWrapper.formatRAM(ram)} of RAM for{" "}
- ?
-
-
- Please enter the server hostname below:
-
- >,
- );
-}
-
/**
* Create a popup that lets the player start a Corporation
* @param {IPlayer} p - Player object
diff --git a/src/Locations/ui/PurchaseServerPopup.tsx b/src/Locations/ui/PurchaseServerPopup.tsx
new file mode 100644
index 000000000..3e34d83a4
--- /dev/null
+++ b/src/Locations/ui/PurchaseServerPopup.tsx
@@ -0,0 +1,69 @@
+/**
+ * React Component for the popup used to purchase a new server.
+ */
+ import React, { useState } from "react";
+ import { removePopup } from "../../ui/React/createPopup";
+ import { purchaseServer } from "../../Server/ServerPurchases";
+ import { numeralWrapper } from "../../ui/numeralFormat";
+ import { Money } from "../../ui/React/Money";
+ import { IPlayer } from "../../PersonObjects/IPlayer";
+ import { StdButton } from "../../ui/React/StdButton";
+
+ interface IPurchaseServerPopupProps {
+ ram: number;
+ cost: number;
+ p: IPlayer;
+ popupId: string;
+ rerender: () => void;
+ }
+
+ export function PurchaseServerPopup(props: IPurchaseServerPopupProps): React.ReactElement {
+ const [hostname, setHostname] = useState("");
+
+ function tryToPurchaseServer(): void {
+ purchaseServer(hostname, props.ram, props.cost, props.p);
+
+ removePopup(props.popupId);
+ }
+
+ function cancel(): void {
+ removePopup(props.popupId);
+ }
+
+ function onKeyUp(event: React.KeyboardEvent): void {
+ if (event.keyCode === 13) tryToPurchaseServer();
+ if (event.keyCode === 27) cancel();
+ }
+
+ function onChange(event: React.ChangeEvent): void {
+ setHostname(event.target.value);
+ props.rerender();
+ }
+
+ return (
+ <>
+ Would you like to purchase a new server with {numeralWrapper.formatRAM(props.ram)} of RAM for{" "}
+ ?
+
+
+ Please enter the server hostname below:
+
+
+
+
+
+ >
+ );
+ }
+
\ No newline at end of file
diff --git a/src/Locations/ui/TechVendorLocation.tsx b/src/Locations/ui/TechVendorLocation.tsx
index e077fc9fa..a18ae4852 100644
--- a/src/Locations/ui/TechVendorLocation.tsx
+++ b/src/Locations/ui/TechVendorLocation.tsx
@@ -6,7 +6,6 @@
import React, { useState } from "react";
import { Location } from "../Location";
-import { createPurchaseServerPopup } from "../LocationsHelpers";
import { RamButton } from "./RamButton";
import { TorButton } from "./TorButton";
import { CoresButton } from "./CoresButton";
@@ -14,8 +13,12 @@ import { CoresButton } from "./CoresButton";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { getPurchaseServerCost } from "../../Server/ServerPurchases";
+
import { StdButton } from "../../ui/React/StdButton";
import { Money } from "../../ui/React/Money";
+import { createPopup } from "../../ui/React/createPopup";
+import { PurchaseServerPopup } from "./PurchaseServerPopup";
+
type IProps = {
loc: Location;
@@ -23,10 +26,24 @@ type IProps = {
};
export function TechVendorLocation(props: IProps): React.ReactElement {
+
+
const setRerender = useState(false)[1];
function rerender(): void {
setRerender((old) => !old);
}
+
+ function openPurchaseServer(ram: number, cost: number, p: IPlayer): void {
+ const popupId = "purchase-server-popup";
+ createPopup(popupId, PurchaseServerPopup, {
+ ram: ram,
+ cost: cost,
+ p: p,
+ popupId: popupId,
+ rerender: rerender
+ });
+ }
+
const btnStyle = { display: "block" };
const purchaseServerButtons: React.ReactNode[] = [];
@@ -35,7 +52,7 @@ export function TechVendorLocation(props: IProps): React.ReactElement {
purchaseServerButtons.push(
createPurchaseServerPopup(i, props.p)}
+ onClick={() => openPurchaseServer(i, cost, props.p)}
style={btnStyle}
text={
<>
diff --git a/src/Server/ServerPurchases.ts b/src/Server/ServerPurchases.ts
index 5df63d598..70604fb3b 100644
--- a/src/Server/ServerPurchases.ts
+++ b/src/Server/ServerPurchases.ts
@@ -10,7 +10,6 @@ import { CONSTANTS } from "../Constants";
import { IPlayer } from "../PersonObjects/IPlayer";
import { dialogBoxCreate } from "../../utils/DialogBox";
-import { yesNoTxtInpBoxGetInput } from "../../utils/YesNoBox";
import { isPowerOfTwo } from "../../utils/helpers/isPowerOfTwo";
// Returns the cost of purchasing a server with the given RAM
@@ -44,9 +43,7 @@ export function getPurchaseServerMaxRam(): number {
}
// Manually purchase a server (NOT through Netscript)
-export function purchaseServer(ram: number, p: IPlayer): void {
- const cost = getPurchaseServerCost(ram);
-
+export function purchaseServer(hostname: string, ram: number, cost: number, p: IPlayer): void {
//Check if player has enough money
if (!p.canAfford(cost)) {
dialogBoxCreate("You don't have enough money to purchase this server!", false);
@@ -65,7 +62,6 @@ export function purchaseServer(ram: number, p: IPlayer): void {
return;
}
- const hostname = yesNoTxtInpBoxGetInput();
if (hostname == "") {
dialogBoxCreate("You must enter a hostname for your new server!");
return;