Everything except Gang is Muified

This commit is contained in:
Olivier Gagnon 2021-10-01 13:36:59 -04:00
parent 4e8bb96f3f
commit 3187bb990d
10 changed files with 146 additions and 194 deletions

@ -53,7 +53,13 @@ export function CoinFlip(props: IProps): React.ReactElement {
} }
const correct: boolean = guess === letter; const correct: boolean = guess === letter;
setResult(<span className={correct ? "text" : "failure"}>{letter}</span>); setResult(
<Box display="flex">
<Typography sx={{ lineHeight: "1em", whiteSpace: "pre" }} color={correct ? "primary" : "error"}>
{letter}
</Typography>
</Box>,
);
setStatus(correct ? " win!" : "lose!"); setStatus(correct ? " win!" : "lose!");
setPlayLock(true); setPlayLock(true);
@ -68,15 +74,7 @@ export function CoinFlip(props: IProps): React.ReactElement {
return ( return (
<> <>
<Typography sx={{ lineHeight: "1em", whiteSpace: "pre" }}>{`+———————+`}</Typography> <Typography>Result:</Typography> {result}
<Typography sx={{ lineHeight: "1em", whiteSpace: "pre" }}>{`| | | |`}</Typography>
<Typography sx={{ lineHeight: "1em", whiteSpace: "pre" }}>
{`| | `}
{result}
{` | |`}
</Typography>
<Typography sx={{ lineHeight: "1em", whiteSpace: "pre" }}>{`| | | |`}</Typography>
<Typography sx={{ lineHeight: "1em", whiteSpace: "pre" }}>{`+———————+`}</Typography>
<Box display="flex" alignItems="center"> <Box display="flex" alignItems="center">
<TextField <TextField
type="number" type="number"
@ -95,7 +93,6 @@ export function CoinFlip(props: IProps): React.ReactElement {
}} }}
/> />
</Box> </Box>
<Typography variant="h3">{status}</Typography> <Typography variant="h3">{status}</Typography>
</> </>
); );

@ -1,20 +0,0 @@
import React from "react";
interface IProps {
current: boolean;
text: string;
onClick: () => void;
}
export function HeaderTab(props: IProps): React.ReactElement {
let className = "cmpy-mgmt-header-tab";
if (props.current) {
className += " current";
}
return (
<button className={className} onClick={props.onClick}>
{props.text}
</button>
);
}

@ -1,14 +1,30 @@
import * as React from "react"; import * as React from "react";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { ICorporation } from "../ICorporation"; import { ICorporation } from "../ICorporation";
import { Theme } from "@mui/material/styles";
import makeStyles from "@mui/styles/makeStyles";
import createStyles from "@mui/styles/createStyles";
const useStyles = makeStyles((theme: Theme) =>
createStyles({
unbuyable: {
color: theme.palette.action.disabled,
},
money: {
color: theme.colors.money,
},
}),
);
interface IProps { interface IProps {
money: number; money: number;
corp: ICorporation; corp: ICorporation;
} }
export function MoneyCost(props: IProps): JSX.Element {
if (!props.corp.funds.gt(props.money))
return <span className={"unbuyable samefont"}>{numeralWrapper.formatMoney(props.money)}</span>;
return <span className={"money-gold samefont"}>{numeralWrapper.formatMoney(props.money)}</span>; export function MoneyCost(props: IProps): React.ReactElement {
const classes = useStyles();
if (!props.corp.funds.gt(props.money))
return <span className={classes.unbuyable}>{numeralWrapper.formatMoney(props.money)}</span>;
return <span className={classes.money}>{numeralWrapper.formatMoney(props.money)}</span>;
} }

@ -0,0 +1,64 @@
/**
* React Component for the popup used to create a new gang.
*/
import React from "react";
import { Modal } from "../../ui/React/Modal";
import { use } from "../../ui/Context";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
interface IProps {
open: boolean;
onClose: () => void;
facName: string;
}
export function CreateGangModal(props: IProps): React.ReactElement {
const player = use.Player();
const router = use.Router();
const combatGangText =
"This is a COMBAT gang. Members in this gang will have different tasks than HACKING gangs. " +
"Compared to hacking gangs, progression with combat gangs can be more difficult as territory management " +
"is more important. However, well-managed combat gangs can progress faster than hacking ones.";
const hackingGangText =
"This is a HACKING gang. Members in this gang will have different tasks than COMBAT gangs. " +
"Compared to combat gangs, progression with hacking gangs is more straightforward as territory warfare " +
"is not as important.";
function isHacking(): boolean {
return ["NiteSec", "The Black Hand"].includes(props.facName);
}
function createGang(): void {
player.startGang(props.facName, isHacking());
props.onClose();
router.toGang();
}
function onKeyUp(event: React.KeyboardEvent): void {
if (event.keyCode === 13) createGang();
}
return (
<Modal open={props.open} onClose={props.onClose}>
<Typography>
Would you like to create a new Gang with {props.facName}?
<br />
<br />
Note that this will prevent you from creating a Gang with any other Faction until this BitNode is destroyed. It
also resets your reputation with this faction.
<br />
<br />
{isHacking() ? hackingGangText : combatGangText}
<br />
<br />
Other than hacking vs combat, there are NO differences between the Factions you can create a Gang with, and each
of these Factions have all Augmentations available.
</Typography>
<Button onClick={createGang} onKeyUp={onKeyUp} autoFocus>
Create Gang
</Button>
</Modal>
);
}

@ -1,69 +0,0 @@
/**
* React Component for the popup used to create a new gang.
*/
import React from "react";
import { removePopup } from "../../ui/React/createPopup";
import { StdButton } from "../../ui/React/StdButton";
import { IRouter } from "../../ui/Router";
import { IPlayer } from "../../PersonObjects/IPlayer";
interface ICreateGangPopupProps {
popupId: string;
facName: string;
player: IPlayer;
router: IRouter;
}
export function CreateGangPopup(props: ICreateGangPopupProps): React.ReactElement {
const player = props.player;
const router = props.router;
const combatGangText =
"This is a COMBAT gang. Members in this gang will have different tasks than HACKING gangs. " +
"Compared to hacking gangs, progression with combat gangs can be more difficult as territory management " +
"is more important. However, well-managed combat gangs can progress faster than hacking ones.";
const hackingGangText =
"This is a HACKING gang. Members in this gang will have different tasks than COMBAT gangs. " +
"Compared to combat gangs, progression with hacking gangs is more straightforward as territory warfare " +
"is not as important.";
function isHacking(): boolean {
return ["NiteSec", "The Black Hand"].includes(props.facName);
}
function createGang(): void {
player.startGang(props.facName, isHacking());
removePopup(props.popupId);
router.toGang();
}
function onKeyUp(event: React.KeyboardEvent): void {
if (event.keyCode === 13) createGang();
}
return (
<>
Would you like to create a new Gang with {props.facName}?
<br />
<br />
Note that this will prevent you from creating a Gang with any other Faction until this BitNode is destroyed. It
also resets your reputation with this faction.
<br />
<br />
{isHacking() ? hackingGangText : combatGangText}
<br />
<br />
Other than hacking vs combat, there are NO differences between the Factions you can create a Gang with, and each
of these Factions have all Augmentations available.
<div className="popup-box-input-div">
<StdButton
onClick={createGang}
onKeyUp={onKeyUp}
text="Create Gang"
style={{ float: "right" }}
autoFocus={true}
/>
</div>
</>
);
}

@ -18,7 +18,7 @@ import { SourceFileFlags } from "../../SourceFile/SourceFileFlags";
import { createPopup } from "../../ui/React/createPopup"; import { createPopup } from "../../ui/React/createPopup";
import { use } from "../../ui/Context"; import { use } from "../../ui/Context";
import { CreateGangPopup } from "./CreateGangPopup"; import { CreateGangModal } from "./CreateGangModal";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button"; import Button from "@mui/material/Button";
@ -75,22 +75,17 @@ function MainPage({ faction, rerender, onAugmentations }: IMainProps): React.Rea
const player = use.Player(); const player = use.Player();
const router = use.Router(); const router = use.Router();
const [sleevesOpen, setSleevesOpen] = useState(false); const [sleevesOpen, setSleevesOpen] = useState(false);
const [gangOpen, setGangOpen] = useState(false);
const p = player; const p = player;
const factionInfo = faction.getInfo(); const factionInfo = faction.getInfo();
function manageGang(faction: Faction): void { function manageGang(): void {
// If player already has a gang, just go to the gang UI // If player already has a gang, just go to the gang UI
if (player.inGang()) { if (player.inGang()) {
return router.toGang(); return router.toGang();
} }
const popupId = "create-gang-popup"; setGangOpen(true);
createPopup(popupId, CreateGangPopup, {
popupId: popupId,
facName: faction.name,
player: player,
router: router,
});
} }
function startFieldWork(faction: Faction): void { function startFieldWork(faction: Faction): void {
@ -137,7 +132,12 @@ function MainPage({ faction, rerender, onAugmentations }: IMainProps): React.Rea
{faction.name} {faction.name}
</Typography> </Typography>
<Info faction={faction} factionInfo={factionInfo} /> <Info faction={faction} factionInfo={factionInfo} />
{canAccessGang && <Option buttonText={"Manage Gang"} infoText={gangInfo} onClick={() => manageGang(faction)} />} {canAccessGang && (
<>
<Option buttonText={"Manage Gang"} infoText={gangInfo} onClick={manageGang} />
<CreateGangModal facName={faction.name} open={gangOpen} onClose={() => setGangOpen(false)} />
</>
)}
{!isPlayersGang && factionInfo.offerHackingMission && ( {!isPlayersGang && factionInfo.offerHackingMission && (
<Option <Option
buttonText={"Hacking Mission"} buttonText={"Hacking Mission"}

@ -1,9 +1,10 @@
import React from "react"; import React, { useState, useEffect } from "react";
export function BlinkingCursor(): React.ReactElement { export function BlinkingCursor(): React.ReactElement {
return ( const [on, setOn] = useState(true);
<span style={{ fontSize: "1em" }} className={"blinking-cursor"}> useEffect(() => {
| const i = setInterval(() => setOn((old) => !old), 1000);
</span> return () => clearInterval(i);
); });
return <>{on ? "|" : ""}</>;
} }

@ -1,5 +1,6 @@
import React, { useState } from "react"; import React, { useState } from "react";
import Grid from "@mui/material/Grid"; import Grid from "@mui/material/Grid";
import Typography from "@mui/material/Typography";
import { IMinigameProps } from "./IMinigameProps"; import { IMinigameProps } from "./IMinigameProps";
import { KeyHandler } from "./KeyHandler"; import { KeyHandler } from "./KeyHandler";
import { GameTimer } from "./GameTimer"; import { GameTimer } from "./GameTimer";
@ -93,9 +94,9 @@ export function WireCuttingGame(props: IMinigameProps): React.ReactElement {
<Grid container spacing={3}> <Grid container spacing={3}>
<GameTimer millis={timer} onExpire={props.onFailure} /> <GameTimer millis={timer} onExpire={props.onFailure} />
<Grid item xs={12}> <Grid item xs={12}>
<h1 className={"noselect"}>Cut the wires with the following properties! (keyboard 1 to 9)</h1> <Typography variant="h4">Cut the wires with the following properties! (keyboard 1 to 9)</Typography>
{questions.map((question, i) => ( {questions.map((question, i) => (
<h3 key={i}>{question.toString()}</h3> <Typography key={i}>{question.toString()}</Typography>
))} ))}
<pre> <pre>
{new Array(wires.length).fill(0).map((_, i) => ( {new Array(wires.length).fill(0).map((_, i) => (

@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react";
import { KEY } from "../../utils/helpers/keyCodes"; import { KEY } from "../../utils/helpers/keyCodes";
import { CodingContract, CodingContractType, CodingContractTypes } from "../../CodingContracts"; import { CodingContract, CodingContractType, CodingContractTypes } from "../../CodingContracts";
import { ClickableTag, CopyableText } from "./CopyableText"; import { CopyableText } from "./CopyableText";
import { Modal } from "./Modal"; import { Modal } from "./Modal";
import { EventEmitter } from "../../utils/EventEmitter"; import { EventEmitter } from "../../utils/EventEmitter";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
@ -55,9 +55,7 @@ export function CodingContractModal(): React.ReactElement {
description.push(<span key={i} dangerouslySetInnerHTML={{ __html: value + "<br />" }}></span>); description.push(<span key={i} dangerouslySetInnerHTML={{ __html: value + "<br />" }}></span>);
return ( return (
<Modal open={props !== null} onClose={close}> <Modal open={props !== null} onClose={close}>
<Typography variant="h4"> <CopyableText variant="h4" value={props.c.type} />
<CopyableText value={props.c.type} />
</Typography>
<Typography> <Typography>
You are attempting to solve a Coding Contract. You have {props.c.getMaxNumTries() - props.c.tries} tries 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. remaining, after which the contract will self-destruct.

@ -1,83 +1,47 @@
import * as React from "react"; import React, { useState } from "react";
import Typography from "@mui/material/Typography";
export enum ClickableTag { import Tooltip from "@mui/material/Tooltip";
Tag_span,
Tag_h1,
}
type IProps = { type IProps = {
value: string; value: string;
tag: ClickableTag; variant?:
| "button"
| "caption"
| "h1"
| "h2"
| "h3"
| "h4"
| "h5"
| "h6"
| "subtitle1"
| "subtitle2"
| "body1"
| "body2"
| "overline"
| "inherit"
| undefined;
}; };
type IState = { export function CopyableText(props: IProps): React.ReactElement {
tooltipVisible: boolean; const [open, setOpen] = useState(false);
};
export class CopyableText extends React.Component<IProps, IState> { function copy(): void {
public static defaultProps = {
//Default span to prevent destroying current clickables
tag: ClickableTag.Tag_span,
};
constructor(props: IProps) {
super(props);
this.copy = this.copy.bind(this);
this.tooltipClasses = this.tooltipClasses.bind(this);
this.textClasses = this.textClasses.bind(this);
this.state = {
tooltipVisible: false,
};
}
copy(): void {
const copyText = document.createElement("textarea"); const copyText = document.createElement("textarea");
copyText.value = this.props.value; copyText.value = props.value;
document.body.appendChild(copyText); document.body.appendChild(copyText);
copyText.select(); copyText.select();
copyText.setSelectionRange(0, 1e10); copyText.setSelectionRange(0, 1e10);
document.execCommand("copy"); document.execCommand("copy");
document.body.removeChild(copyText); document.body.removeChild(copyText);
this.setState({ tooltipVisible: true }); setOpen(true);
setTimeout(() => this.setState({ tooltipVisible: false }), 1000); setTimeout(() => setOpen(false), 1000);
} }
tooltipClasses(): string {
let classes = "copy_tooltip_text";
if (this.state.tooltipVisible) {
classes += " copy_tooltip_text_visible";
}
return classes;
}
textClasses(): string {
let classes = "copy_tooltip noselect text";
if (this.state.tooltipVisible) {
classes += " copy_tooltip_copied";
}
return classes;
}
render(): React.ReactNode {
switch (this.props.tag) {
case ClickableTag.Tag_h1:
return ( return (
<h1 className={this.textClasses()} onClick={this.copy}> <Tooltip open={open} title={<Typography>Copied!</Typography>}>
{this.props.value} <Typography variant={props.variant} onClick={copy}>
<span className={this.tooltipClasses()}>Copied!</span> {props.value}
</h1> </Typography>
</Tooltip>
); );
case ClickableTag.Tag_span:
return (
<span className={this.textClasses()} onClick={this.copy}>
<b>{this.props.value}</b>
<span className={this.tooltipClasses()}>Copied!</span>
</span>
);
}
}
} }