Active Scripts

This commit is contained in:
Olivier Gagnon 2021-09-18 00:16:02 -04:00
parent 907314e76b
commit 1996deaf0a
17 changed files with 289 additions and 189 deletions

@ -32,7 +32,7 @@
.loaderoverlay { .loaderoverlay {
$spinnerBoxSize: 200px; $spinnerBoxSize: 200px;
$themeColor: #6f3; $themeColor: #0c0;
position: absolute; position: absolute;
width: 100%; width: 100%;

@ -4,7 +4,7 @@
@import "reset"; @import "reset";
:root { :root {
--my-font-color: #6f3; --my-font-color: #0c0;
--my-background-color: #000; --my-background-color: #000;
--my-highlight-color: #fff; --my-highlight-color: #fff;
--my-prompt-color: #f92672; --my-prompt-color: #f92672;

@ -340,15 +340,13 @@ export class Blackjack extends Game<Props, State> {
{/* Buttons */} {/* Buttons */}
{!gameInProgress ? ( {!gameInProgress ? (
<div> <div>
<MuiButton color="primary" onClick={this.startOnClick} disabled={wagerInvalid || !this.canStartGame()}> <MuiButton onClick={this.startOnClick} disabled={wagerInvalid || !this.canStartGame()}>
Start Start
</MuiButton> </MuiButton>
</div> </div>
) : ( ) : (
<div> <div>
<MuiButton color="primary" onClick={this.playerHit}> <MuiButton onClick={this.playerHit}>Hit</MuiButton>
Hit
</MuiButton>
<MuiButton color="secondary" onClick={this.playerStay}> <MuiButton color="secondary" onClick={this.playerStay}>
Stay Stay
</MuiButton> </MuiButton>

@ -37,12 +37,12 @@ export function Adjuster(props: IProps): React.ReactElement {
startAdornment: ( startAdornment: (
<> <>
<Tooltip title="Add a lot"> <Tooltip title="Add a lot">
<IconButton color="primary" onClick={tons} size="large"> <IconButton onClick={tons} size="large">
<DoubleArrowIcon style={{ transform: "rotate(-90deg)" }} /> <DoubleArrowIcon style={{ transform: "rotate(-90deg)" }} />
</IconButton> </IconButton>
</Tooltip> </Tooltip>
<Tooltip title="Add"> <Tooltip title="Add">
<IconButton color="primary" onClick={() => add(typeof value !== "string" ? value : 0)} size="large"> <IconButton onClick={() => add(typeof value !== "string" ? value : 0)} size="large">
<AddIcon /> <AddIcon />
</IconButton> </IconButton>
</Tooltip> </Tooltip>
@ -51,16 +51,12 @@ export function Adjuster(props: IProps): React.ReactElement {
endAdornment: ( endAdornment: (
<> <>
<Tooltip title="Remove"> <Tooltip title="Remove">
<IconButton <IconButton onClick={() => subtract(typeof value !== "string" ? value : 0)} size="large">
color="primary"
onClick={() => subtract(typeof value !== "string" ? value : 0)}
size="large"
>
<RemoveIcon /> <RemoveIcon />
</IconButton> </IconButton>
</Tooltip> </Tooltip>
<Tooltip title="Reset"> <Tooltip title="Reset">
<IconButton color="primary" onClick={reset} size="large"> <IconButton onClick={reset} size="large">
<ClearIcon /> <ClearIcon />
</IconButton> </IconButton>
</Tooltip> </Tooltip>

@ -53,23 +53,21 @@ export function Augmentations(props: IProps): React.ReactElement {
</td> </td>
<td> <td>
<Select <Select
id="dev-augs-dropdown"
className="dropdown"
onChange={setAugmentationDropdown} onChange={setAugmentationDropdown}
value={augmentation} value={augmentation}
startAdornment={ startAdornment={
<> <>
<IconButton color="primary" onClick={queueAllAugs} size="large"> <IconButton onClick={queueAllAugs} size="large">
<ReplyAllIcon /> <ReplyAllIcon />
</IconButton> </IconButton>
<IconButton color="primary" onClick={queueAug} size="large"> <IconButton onClick={queueAug} size="large">
<ReplyIcon /> <ReplyIcon />
</IconButton> </IconButton>
</> </>
} }
endAdornment={ endAdornment={
<> <>
<IconButton color="primary" onClick={clearAugs} size="large"> <IconButton onClick={clearAugs} size="large">
<ClearIcon /> <ClearIcon />
</IconButton> </IconButton>
</> </>

@ -119,10 +119,10 @@ export function Factions(props: IProps): React.ReactElement {
value={faction} value={faction}
startAdornment={ startAdornment={
<> <>
<IconButton color="primary" onClick={receiveAllInvites} size="large"> <IconButton onClick={receiveAllInvites} size="large">
<ReplyAllIcon /> <ReplyAllIcon />
</IconButton> </IconButton>
<IconButton color="primary" onClick={receiveInvite} size="large"> <IconButton onClick={receiveInvite} size="large">
<ReplyIcon /> <ReplyIcon />
</IconButton> </IconButton>
</> </>

@ -207,10 +207,10 @@ function setTheme() {
/^#[0-9a-f]{3}(?:[0-9a-f]{3})?$/i.test(FconfSettings.THEME_BACKGROUND_COLOR) && /^#[0-9a-f]{3}(?:[0-9a-f]{3})?$/i.test(FconfSettings.THEME_BACKGROUND_COLOR) &&
/^#[0-9a-f]{3}(?:[0-9a-f]{3})?$/i.test(FconfSettings.THEME_PROMPT_COLOR) /^#[0-9a-f]{3}(?:[0-9a-f]{3})?$/i.test(FconfSettings.THEME_PROMPT_COLOR)
) { ) {
document.body.style.setProperty("--my-highlight-color", FconfSettings.THEME_HIGHLIGHT_COLOR); // document.body.style.setProperty("--my-highlight-color", FconfSettings.THEME_HIGHLIGHT_COLOR);
document.body.style.setProperty("--my-font-color", FconfSettings.THEME_FONT_COLOR); // document.body.style.setProperty("--my-font-color", FconfSettings.THEME_FONT_COLOR);
document.body.style.setProperty("--my-background-color", FconfSettings.THEME_BACKGROUND_COLOR); // document.body.style.setProperty("--my-background-color", FconfSettings.THEME_BACKGROUND_COLOR);
document.body.style.setProperty("--my-prompt-color", FconfSettings.THEME_PROMPT_COLOR); // document.body.style.setProperty("--my-prompt-color", FconfSettings.THEME_PROMPT_COLOR);
} }
} }

@ -586,7 +586,7 @@ export function createAndAddWorkerScript(runningScriptObj, server, parent) {
* Updates the online running time stat of all running scripts * Updates the online running time stat of all running scripts
*/ */
export function updateOnlineScriptTimes(numCycles = 1) { export function updateOnlineScriptTimes(numCycles = 1) {
var time = (numCycles * Engine._idleSpeed) / 1000; //seconds var time = (numCycles * CONSTANTS._idleSpeed) / 1000; //seconds
for (const ws of workerScripts.values()) { for (const ws of workerScripts.values()) {
ws.scriptRef.onlineRunningTime += time; ws.scriptRef.onlineRunningTime += time;
} }

@ -333,18 +333,18 @@ export function SidebarRoot(props: IProps): React.ReactElement {
<Drawer open={open} anchor="left" variant="permanent"> <Drawer open={open} anchor="left" variant="permanent">
<ListItem classes={{ root: classes.listitem }} button onClick={toggleDrawer}> <ListItem classes={{ root: classes.listitem }} button onClick={toggleDrawer}>
<ListItemIcon> <ListItemIcon>
{!open ? <ChevronRightIcon color={"primary"} /> : <ChevronLeftIcon color={"primary"} />} {!open ? <ChevronRightIcon color="primary" /> : <ChevronLeftIcon color="primary" />}
</ListItemIcon> </ListItemIcon>
<ListItemText primary={<Typography color="primary">Bitburner v{CONSTANTS.Version}</Typography>} /> <ListItemText primary={<Typography>Bitburner v{CONSTANTS.Version}</Typography>} />
</ListItem> </ListItem>
<Divider /> <Divider />
<List> <List>
<ListItem classes={{ root: classes.listitem }} button onClick={() => setHackingOpen((old) => !old)}> <ListItem classes={{ root: classes.listitem }} button onClick={() => setHackingOpen((old) => !old)}>
<ListItemIcon> <ListItemIcon>
<ComputerIcon color={"primary"} /> <ComputerIcon color="primary" />
</ListItemIcon> </ListItemIcon>
<ListItemText primary={<Typography color="primary">Hacking</Typography>} /> <ListItemText primary={<Typography>Hacking</Typography>} />
{hackingOpen ? <ExpandLessIcon color={"primary"} /> : <ExpandMoreIcon color={"primary"} />} {hackingOpen ? <ExpandLessIcon /> : <ExpandMoreIcon />}
</ListItem> </ListItem>
<Collapse in={hackingOpen} timeout="auto" unmountOnExit> <Collapse in={hackingOpen} timeout="auto" unmountOnExit>
<List> <List>
@ -435,10 +435,10 @@ export function SidebarRoot(props: IProps): React.ReactElement {
<Divider /> <Divider />
<ListItem classes={{ root: classes.listitem }} button onClick={() => setCharacterOpen((old) => !old)}> <ListItem classes={{ root: classes.listitem }} button onClick={() => setCharacterOpen((old) => !old)}>
<ListItemIcon> <ListItemIcon>
<AccountBoxIcon color={"primary"} /> <AccountBoxIcon color="primary" />
</ListItemIcon> </ListItemIcon>
<ListItemText primary={<Typography color="primary">Character</Typography>} /> <ListItemText primary={<Typography>Character</Typography>} />
{characterOpen ? <ExpandLessIcon color={"primary"} /> : <ExpandMoreIcon color={"primary"} />} {characterOpen ? <ExpandLessIcon /> : <ExpandMoreIcon />}
</ListItem> </ListItem>
<Collapse in={characterOpen} timeout="auto" unmountOnExit> <Collapse in={characterOpen} timeout="auto" unmountOnExit>
<ListItem <ListItem
@ -545,10 +545,10 @@ export function SidebarRoot(props: IProps): React.ReactElement {
<Divider /> <Divider />
<ListItem classes={{ root: classes.listitem }} button onClick={() => setWorldOpen((old) => !old)}> <ListItem classes={{ root: classes.listitem }} button onClick={() => setWorldOpen((old) => !old)}>
<ListItemIcon> <ListItemIcon>
<PublicIcon color={"primary"} /> <PublicIcon color="primary" />
</ListItemIcon> </ListItemIcon>
<ListItemText primary={<Typography color="primary">World</Typography>} /> <ListItemText primary={<Typography>World</Typography>} />
{worldOpen ? <ExpandLessIcon color={"primary"} /> : <ExpandMoreIcon color={"primary"} />} {worldOpen ? <ExpandLessIcon /> : <ExpandMoreIcon />}
</ListItem> </ListItem>
<Collapse in={worldOpen} timeout="auto" unmountOnExit> <Collapse in={worldOpen} timeout="auto" unmountOnExit>
<ListItem <ListItem
@ -678,10 +678,10 @@ export function SidebarRoot(props: IProps): React.ReactElement {
<Divider /> <Divider />
<ListItem classes={{ root: classes.listitem }} button onClick={() => setHelpOpen((old) => !old)}> <ListItem classes={{ root: classes.listitem }} button onClick={() => setHelpOpen((old) => !old)}>
<ListItemIcon> <ListItemIcon>
<LiveHelpIcon color={"primary"} /> <LiveHelpIcon color="primary" />
</ListItemIcon> </ListItemIcon>
<ListItemText primary={<Typography color="primary">Help</Typography>} /> <ListItemText primary={<Typography>Help</Typography>} />
{helpOpen ? <ExpandLessIcon color={"primary"} /> : <ExpandMoreIcon color={"primary"} />} {helpOpen ? <ExpandLessIcon /> : <ExpandMoreIcon />}
</ListItem> </ListItem>
<Collapse in={helpOpen} timeout="auto" unmountOnExit> <Collapse in={helpOpen} timeout="auto" unmountOnExit>
<ListItem <ListItem

@ -10,6 +10,7 @@ import { ServerAccordions } from "./ServerAccordions";
import { WorkerScript } from "../../Netscript/WorkerScript"; import { WorkerScript } from "../../Netscript/WorkerScript";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import TextField from "@mui/material/TextField";
type IProps = { type IProps = {
workerScripts: Map<number, WorkerScript>; workerScripts: Map<number, WorkerScript>;

@ -5,10 +5,14 @@
import * as React from "react"; import * as React from "react";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import Accordion from "@mui/material/Accordion";
import AccordionSummary from "@mui/material/AccordionSummary"; import ListItemButton from "@mui/material/ListItemButton";
import AccordionDetails from "@mui/material/AccordionDetails"; import ListItemText from "@mui/material/ListItemText";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import Paper from "@mui/material/Paper";
import Collapse from "@mui/material/Collapse";
import ExpandMore from "@mui/icons-material/ExpandMore";
import ExpandLess from "@mui/icons-material/ExpandLess";
import { ServerAccordionContent } from "./ServerAccordionContent"; import { ServerAccordionContent } from "./ServerAccordionContent";
import { BaseServer } from "../../Server/BaseServer"; import { BaseServer } from "../../Server/BaseServer";
@ -22,6 +26,7 @@ type IProps = {
}; };
export function ServerAccordion(props: IProps): React.ReactElement { export function ServerAccordion(props: IProps): React.ReactElement {
const [open, setOpen] = React.useState(false);
const server = props.server; const server = props.server;
// Accordion's header text // Accordion's header text
@ -38,15 +43,14 @@ export function ServerAccordion(props: IProps): React.ReactElement {
const headerTxt = `${paddedName} ${createProgressBarText(barOptions)}`; const headerTxt = `${paddedName} ${createProgressBarText(barOptions)}`;
return ( return (
<Accordion TransitionProps={{ unmountOnExit: true }}> <>
<AccordionSummary expandIcon={<ExpandMoreIcon />}> <ListItemButton onClick={() => setOpen((old) => !old)} component={Paper}>
<Typography style={{ whiteSpace: "pre-wrap" }} color="primary"> <ListItemText primary={<Typography style={{ whiteSpace: "pre-wrap" }}>{headerTxt}</Typography>} />
{headerTxt} {open ? <ExpandLess color="primary" /> : <ExpandMore color="primary" />}
</Typography> </ListItemButton>
</AccordionSummary> <Collapse in={open} timeout={0} unmountOnExit>
<AccordionDetails>
<ServerAccordionContent workerScripts={props.workerScripts} /> <ServerAccordionContent workerScripts={props.workerScripts} />
</AccordionDetails> </Collapse>
</Accordion> </>
); );
} }

@ -2,6 +2,10 @@ import React, { useState } from "react";
import { WorkerScript } from "../../Netscript/WorkerScript"; import { WorkerScript } from "../../Netscript/WorkerScript";
import { WorkerScriptAccordion } from "./WorkerScriptAccordion"; import { WorkerScriptAccordion } from "./WorkerScriptAccordion";
import { AccordionButton } from "../React/AccordionButton"; import { AccordionButton } from "../React/AccordionButton";
import Paper from "@mui/material/Paper";
import List from "@mui/material/List";
import TablePagination from "@mui/material/TablePagination";
import { TablePaginationActionsAll } from "../React/TablePaginationActionsAll";
const pageSize = 20; const pageSize = 20;
@ -10,63 +14,34 @@ interface IProps {
} }
export function ServerAccordionContent(props: IProps): React.ReactElement { export function ServerAccordionContent(props: IProps): React.ReactElement {
if (props.workerScripts.length > pageSize) {
return <ServerAccordionContentPaginated workerScripts={props.workerScripts} />;
}
return (
<ul>
{props.workerScripts.map((ws) => {
return <WorkerScriptAccordion key={`${ws.name}_${ws.args}`} workerScript={ws} />;
})}
</ul>
);
}
export function ServerAccordionContentPaginated(props: IProps): React.ReactElement {
const [page, setPage] = useState(0); const [page, setPage] = useState(0);
const scripts: React.ReactElement[] = []; const [rowsPerPage, setRowsPerPage] = useState(10);
const maxPage = Math.ceil(props.workerScripts.length / pageSize); const handleChangePage = (event: unknown, newPage: number) => {
const maxScript = Math.min((page + 1) * pageSize, props.workerScripts.length); setPage(newPage);
for (let i = page * pageSize; i < maxScript; i++) { };
const ws = props.workerScripts[i];
scripts.push(<WorkerScriptAccordion key={`${ws.name}_${ws.args}`} workerScript={ws} />);
}
function capPage(page: number): number { const handleChangeRowsPerPage = (event: React.ChangeEvent<HTMLInputElement>) => {
if (page < 0) { setRowsPerPage(parseInt(event.target.value, 10));
page = 0; setPage(0);
} };
if (maxPage - 1 < page) {
page = maxPage - 1;
}
return page;
}
// in case we're on an invalid page number because scripts were killed.
const capped = capPage(page);
if (capped !== page) setPage(capped);
function changePage(n: number): void {
setPage((newPage) => {
newPage += n;
newPage = Math.round(newPage);
return capPage(newPage);
});
}
return ( return (
<> <>
<ul>{scripts}</ul> <List>
<AccordionButton onClick={() => changePage(-1e99)} text="<<" /> {props.workerScripts.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map((ws) => (
<AccordionButton onClick={() => changePage(-1)} text="<" /> <WorkerScriptAccordion key={`${ws.name}_${ws.args}`} workerScript={ws} />
<span className="text"> ))}
{page + 1} / {maxPage} </List>
</span> <TablePagination
<AccordionButton onClick={() => changePage(1)} text=">" /> rowsPerPageOptions={[10, 15, 20]}
<AccordionButton onClick={() => changePage(1e99)} text=">>" /> component="div"
count={props.workerScripts.length}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
ActionsComponent={TablePaginationActionsAll}
/>
</> </>
); );
} }

@ -6,10 +6,16 @@ import React, { useState, useEffect } from "react";
import { ServerAccordion } from "./ServerAccordion"; import { ServerAccordion } from "./ServerAccordion";
import TextField from "@mui/material/TextField";
import Typography from "@mui/material/Typography";
import Paper from "@mui/material/Paper";
import List from "@mui/material/List";
import TablePagination from "@mui/material/TablePagination";
import { WorkerScript } from "../../Netscript/WorkerScript"; import { WorkerScript } from "../../Netscript/WorkerScript";
import { WorkerScriptStartStopEventEmitter } from "../../Netscript/WorkerScriptStartStopEventEmitter"; import { WorkerScriptStartStopEventEmitter } from "../../Netscript/WorkerScriptStartStopEventEmitter";
import { getServer } from "../../Server/ServerHelpers"; import { getServer } from "../../Server/ServerHelpers";
import { BaseServer } from "../../Server/BaseServer"; import { BaseServer } from "../../Server/BaseServer";
import { TablePaginationActionsAll } from "../React/TablePaginationActionsAll";
// Map of server hostname -> all workerscripts on that server for all active scripts // Map of server hostname -> all workerscripts on that server for all active scripts
interface IServerData { interface IServerData {
@ -32,6 +38,9 @@ type IState = {
const subscriberId = "ActiveScriptsUI"; const subscriberId = "ActiveScriptsUI";
export function ServerAccordions(props: IProps): React.ReactElement { export function ServerAccordions(props: IProps): React.ReactElement {
const [filter, setFilter] = useState("");
const [page, setPage] = useState(0);
const [rowsPerPage, setRowsPerPage] = useState(10);
const setRerender = useState(false)[1]; const setRerender = useState(false)[1];
function rerender(): void { function rerender(): void {
setRerender((old) => !old); setRerender((old) => !old);
@ -45,6 +54,20 @@ export function ServerAccordions(props: IProps): React.ReactElement {
return () => WorkerScriptStartStopEventEmitter.removeSubscriber(subscriberId); return () => WorkerScriptStartStopEventEmitter.removeSubscriber(subscriberId);
}, []); }, []);
const handleChangePage = (event: unknown, newPage: number) => {
setPage(newPage);
};
const handleChangeRowsPerPage = (event: React.ChangeEvent<HTMLInputElement>) => {
setRowsPerPage(parseInt(event.target.value, 10));
setPage(0);
};
function handleFilterChange(event: React.ChangeEvent<HTMLInputElement>): void {
setFilter(event.target.value);
setPage(0);
}
const serverToScriptMap: IServerToScriptsMap = {}; const serverToScriptMap: IServerToScriptsMap = {};
for (const ws of props.workerScripts.values()) { for (const ws of props.workerScripts.values()) {
const server = getServer(ws.serverIp); const server = getServer(ws.serverIp);
@ -65,13 +88,40 @@ export function ServerAccordions(props: IProps): React.ReactElement {
if (data !== undefined) data.workerScripts.push(ws); if (data !== undefined) data.workerScripts.push(ws);
} }
const filtered = Object.values(serverToScriptMap).filter((data) => data && data.server.hostname.includes(filter));
return ( return (
<ul className="active-scripts-list" id="active-scripts-list"> <>
{Object.values(serverToScriptMap).map((data) => { <TextField
value={filter}
onChange={handleFilterChange}
color="primary"
autoFocus
variant="standard"
InputProps={{
startAdornment: <Typography m={1}>Filter:</Typography>,
spellCheck: false,
}}
/>
<List>
{filtered.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map((data) => {
return ( return (
data && <ServerAccordion key={data.server.hostname} server={data.server} workerScripts={data.workerScripts} /> data && (
<ServerAccordion key={data.server.hostname} server={data.server} workerScripts={data.workerScripts} />
)
); );
})} })}
</ul> </List>
<TablePagination
rowsPerPageOptions={[10, 15, 20]}
component="div"
count={filtered.length}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
ActionsComponent={TablePaginationActionsAll}
/>
</>
); );
} }

@ -7,6 +7,8 @@ import * as React from "react";
import { numeralWrapper } from "../numeralFormat"; import { numeralWrapper } from "../numeralFormat";
import Button from "@mui/material/Button"; import Button from "@mui/material/Button";
import Box from "@mui/material/Box";
import Paper from "@mui/material/Paper";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import Accordion from "@mui/material/Accordion"; import Accordion from "@mui/material/Accordion";
import AccordionSummary from "@mui/material/AccordionSummary"; import AccordionSummary from "@mui/material/AccordionSummary";
@ -15,6 +17,12 @@ import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import { AccordionButton } from "../React/AccordionButton"; import { AccordionButton } from "../React/AccordionButton";
import IconButton from "@mui/material/IconButton"; import IconButton from "@mui/material/IconButton";
import DeleteIcon from "@mui/icons-material/Delete"; import DeleteIcon from "@mui/icons-material/Delete";
import ListItemButton from "@mui/material/ListItemButton";
import ListItemText from "@mui/material/ListItemText";
import Collapse from "@mui/material/Collapse";
import ExpandMore from "@mui/icons-material/ExpandMore";
import ExpandLess from "@mui/icons-material/ExpandLess";
import { killWorkerScript } from "../../Netscript/killWorkerScript"; import { killWorkerScript } from "../../Netscript/killWorkerScript";
import { WorkerScript } from "../../Netscript/WorkerScript"; import { WorkerScript } from "../../Netscript/WorkerScript";
@ -30,6 +38,7 @@ type IProps = {
}; };
export function WorkerScriptAccordion(props: IProps): React.ReactElement { export function WorkerScriptAccordion(props: IProps): React.ReactElement {
const [open, setOpen] = React.useState(false);
const workerScript = props.workerScript; const workerScript = props.workerScript;
const scriptRef = workerScript.scriptRef; const scriptRef = workerScript.scriptRef;
@ -48,11 +57,13 @@ export function WorkerScriptAccordion(props: IProps): React.ReactElement {
const offlineEps = scriptRef.offlineExpGained / scriptRef.offlineRunningTime; const offlineEps = scriptRef.offlineExpGained / scriptRef.offlineRunningTime;
return ( return (
<Accordion TransitionProps={{ unmountOnExit: true }}> <>
<AccordionSummary expandIcon={<ExpandMoreIcon />}> <ListItemButton onClick={() => setOpen((old) => !old)} component={Paper}>
<Typography color="primary">{props.workerScript.name}</Typography> <ListItemText primary={<Typography style={{ whiteSpace: "pre-wrap" }}>{props.workerScript.name}</Typography>} />
</AccordionSummary> {open ? <ExpandLess /> : <ExpandMore />}
<AccordionDetails> </ListItemButton>
<Collapse in={open} timeout={0} unmountOnExit>
<Box m={3}>
<pre>Threads: {numeralWrapper.formatThreads(props.workerScript.scriptRef.threads)}</pre> <pre>Threads: {numeralWrapper.formatThreads(props.workerScript.scriptRef.threads)}</pre>
<pre>Args: {arrayToString(props.workerScript.args)}</pre> <pre>Args: {arrayToString(props.workerScript.args)}</pre>
<pre>Online Time: {convertTimeMsToTimeElapsedString(scriptRef.onlineRunningTime * 1e3)}</pre> <pre>Online Time: {convertTimeMsToTimeElapsedString(scriptRef.onlineRunningTime * 1e3)}</pre>
@ -80,7 +91,8 @@ export function WorkerScriptAccordion(props: IProps): React.ReactElement {
<IconButton onClick={killScriptClickHandler}> <IconButton onClick={killScriptClickHandler}>
<DeleteIcon color="error" /> <DeleteIcon color="error" />
</IconButton> </IconButton>
</AccordionDetails> </Box>
</Accordion> </Collapse>
</>
); );
} }

@ -257,7 +257,7 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
</ListItem> </ListItem>
<ListItem> <ListItem>
<FormControlLabel <FormControlLabel
control={<Switch color="primary" checked={suppressMessages} onChange={handleSuppressMessagesChange} />} control={<Switch checked={suppressMessages} onChange={handleSuppressMessagesChange} />}
label={ label={
<Tooltip <Tooltip
title={ title={
@ -275,13 +275,7 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
</ListItem> </ListItem>
<ListItem> <ListItem>
<FormControlLabel <FormControlLabel
control={ control={<Switch checked={suppressFactionInvites} onChange={handleSuppressFactionInvitesChange} />}
<Switch
color="primary"
checked={suppressFactionInvites}
onChange={handleSuppressFactionInvitesChange}
/>
}
label={ label={
<Tooltip <Tooltip
title={ title={
@ -299,11 +293,7 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
<ListItem> <ListItem>
<FormControlLabel <FormControlLabel
control={ control={
<Switch <Switch checked={suppressTravelConfirmations} onChange={handleSuppressTravelConfirmationsChange} />
color="primary"
checked={suppressTravelConfirmations}
onChange={handleSuppressTravelConfirmationsChange}
/>
} }
label={ label={
<Tooltip <Tooltip
@ -323,7 +313,6 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
<FormControlLabel <FormControlLabel
control={ control={
<Switch <Switch
color="primary"
checked={suppressBuyAugmentationConfirmation} checked={suppressBuyAugmentationConfirmation}
onChange={handleSuppressBuyAugmentationConfirmationChange} onChange={handleSuppressBuyAugmentationConfirmationChange}
/> />
@ -344,11 +333,7 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
<ListItem> <ListItem>
<FormControlLabel <FormControlLabel
control={ control={
<Switch <Switch checked={suppressHospitalizationPopup} onChange={handleSuppressHospitalizationPopupChange} />
color="primary"
checked={suppressHospitalizationPopup}
onChange={handleSuppressHospitalizationPopupChange}
/>
} }
label={ label={
<Tooltip <Tooltip
@ -368,11 +353,7 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
<ListItem> <ListItem>
<FormControlLabel <FormControlLabel
control={ control={
<Switch <Switch checked={suppressBladeburnerPopup} onChange={handleSuppressBladeburnerPopupChange} />
color="primary"
checked={suppressBladeburnerPopup}
onChange={handleSuppressBladeburnerPopupChange}
/>
} }
label={ label={
<Tooltip <Tooltip
@ -391,7 +372,7 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
)} )}
<ListItem> <ListItem>
<FormControlLabel <FormControlLabel
control={<Switch color="primary" checked={disableHotkeys} onChange={handleDisableHotkeysChange} />} control={<Switch checked={disableHotkeys} onChange={handleDisableHotkeysChange} />}
label={ label={
<Tooltip <Tooltip
title={ title={
@ -409,7 +390,7 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
</ListItem> </ListItem>
<ListItem> <ListItem>
<FormControlLabel <FormControlLabel
control={<Switch color="primary" checked={disableASCIIArt} onChange={handleDisableASCIIArtChange} />} control={<Switch checked={disableASCIIArt} onChange={handleDisableASCIIArtChange} />}
label={ label={
<Tooltip title={<Typography>If this is set all ASCII art will be disabled.</Typography>}> <Tooltip title={<Typography>If this is set all ASCII art will be disabled.</Typography>}>
<Typography>Disable ascii art</Typography> <Typography>Disable ascii art</Typography>
@ -419,9 +400,7 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
</ListItem> </ListItem>
<ListItem> <ListItem>
<FormControlLabel <FormControlLabel
control={ control={<Switch checked={disableTextEffects} onChange={handleDisableTextEffectsChange} />}
<Switch color="primary" checked={disableTextEffects} onChange={handleDisableTextEffectsChange} />
}
label={ label={
<Tooltip <Tooltip
title={ title={

@ -0,0 +1,69 @@
import * as React from "react";
import { useTheme } from "@mui/material/styles";
import Box from "@mui/material/Box";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableFooter from "@mui/material/TableFooter";
import TablePagination from "@mui/material/TablePagination";
import TableRow from "@mui/material/TableRow";
import Paper from "@mui/material/Paper";
import IconButton from "@mui/material/IconButton";
import FirstPageIcon from "@mui/icons-material/FirstPage";
import KeyboardArrowLeft from "@mui/icons-material/KeyboardArrowLeft";
import KeyboardArrowRight from "@mui/icons-material/KeyboardArrowRight";
import LastPageIcon from "@mui/icons-material/LastPage";
interface TablePaginationActionsProps {
count: number;
page: number;
rowsPerPage: number;
onPageChange: (event: React.MouseEvent<HTMLButtonElement>, newPage: number) => void;
}
export function TablePaginationActionsAll(props: TablePaginationActionsProps) {
const theme = useTheme();
const { count, page, rowsPerPage, onPageChange } = props;
const handleFirstPageButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
onPageChange(event, 0);
};
const handleBackButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
onPageChange(event, page - 1);
};
const handleNextButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
onPageChange(event, page + 1);
};
const handleLastPageButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
onPageChange(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1));
};
return (
<Box sx={{ flexShrink: 0, ml: 2.5 }}>
<IconButton onClick={handleFirstPageButtonClick} disabled={page === 0} aria-label="first page">
{theme.direction === "rtl" ? <LastPageIcon /> : <FirstPageIcon />}
</IconButton>
<IconButton onClick={handleBackButtonClick} disabled={page === 0} aria-label="previous page">
{theme.direction === "rtl" ? <KeyboardArrowRight /> : <KeyboardArrowLeft />}
</IconButton>
<IconButton
onClick={handleNextButtonClick}
disabled={page >= Math.ceil(count / rowsPerPage) - 1}
aria-label="next page"
>
{theme.direction === "rtl" ? <KeyboardArrowLeft /> : <KeyboardArrowRight />}
</IconButton>
<IconButton
onClick={handleLastPageButtonClick}
disabled={page >= Math.ceil(count / rowsPerPage) - 1}
aria-label="last page"
>
{theme.direction === "rtl" ? <FirstPageIcon /> : <LastPageIcon />}
</IconButton>
</Box>
);
}

@ -23,6 +23,10 @@ export const colors = {
warning: "#cc0", warning: "#cc0",
warningdark: "#990", warningdark: "#990",
infolight: "#69f",
info: "#36c",
infodark: "#039",
welllight: "#444", welllight: "#444",
well: "#222", well: "#222",
white: "#fff", white: "#fff",
@ -53,6 +57,11 @@ export const theme = createTheme({
main: colors.error, main: colors.error,
dark: colors.errordark, dark: colors.errordark,
}, },
info: {
light: colors.infolight,
main: colors.info,
dark: colors.infodark,
},
warning: { warning: {
light: colors.warninglight, light: colors.warninglight,
main: colors.warning, main: colors.warning,
@ -73,6 +82,7 @@ export const theme = createTheme({
styleOverrides: { styleOverrides: {
root: { root: {
backgroundColor: colors.well, backgroundColor: colors.well,
color: colors.primary,
}, },
input: { input: {
"&::placeholder": { "&::placeholder": {
@ -114,22 +124,22 @@ export const theme = createTheme({
}, },
}, },
}, },
// MuiButton: { MuiButton: {
// styleOverrides: { styleOverrides: {
// root: { root: {
// backgroundColor: "#333", backgroundColor: "#333",
// border: "1px solid " + colors.well, border: "1px solid " + colors.well,
// // color: colors.primary, // color: colors.primary,
// margin: "5px", margin: "5px",
// padding: "3px 5px", padding: "3px 5px",
// "&:hover": { "&:hover": {
// backgroundColor: colors.black, backgroundColor: colors.black,
// }, },
// borderRadius: 0, borderRadius: 0,
// }, },
// }, },
// }, },
MuiSelect: { MuiSelect: {
styleOverrides: { styleOverrides: {
icon: { icon: {
@ -233,11 +243,19 @@ export const theme = createTheme({
MuiPaper: { MuiPaper: {
styleOverrides: { styleOverrides: {
root: { root: {
borderRadius: 0,
backgroundColor: colors.black, backgroundColor: colors.black,
border: "1px solid " + colors.welllight, border: "1px solid " + colors.welllight,
}, },
}, },
}, },
MuiTablePagination: {
styleOverrides: {
select: {
color: colors.primary,
},
},
},
}, },
}); });