Files
bitburner-src/src/ui/ActiveScripts/ServerAccordions.tsx
T
2021-09-08 23:47:34 -04:00

103 lines
2.5 KiB
TypeScript

/**
* React Component for rendering the Accordion elements for all servers
* on which scripts are running
*/
import * as React from "react";
import { ServerAccordion } from "./ServerAccordion";
import { WorkerScript } from "../../Netscript/WorkerScript";
import { WorkerScriptStartStopEventEmitter } from "../../Netscript/WorkerScriptStartStopEventEmitter";
import { getServer } from "../../Server/ServerHelpers";
import { BaseServer } from "../../Server/BaseServer";
// Map of server hostname -> all workerscripts on that server for all active scripts
interface IServerData {
server: BaseServer;
workerScripts: WorkerScript[];
}
interface IServerToScriptsMap {
[key: string]: IServerData;
}
type IProps = {
workerScripts: Map<number, WorkerScript>;
};
type IState = {
rerenderFlag: boolean;
};
const subscriberId = "ActiveScriptsUI";
export class ServerAccordions extends React.Component<IProps, IState> {
serverToScriptMap: IServerToScriptsMap = {};
constructor(props: IProps) {
super(props);
this.state = {
rerenderFlag: false,
};
this.updateServerToScriptsMap();
this.rerender = this.rerender.bind(this);
}
componentDidMount(): void {
WorkerScriptStartStopEventEmitter.addSubscriber({
cb: this.rerender,
id: subscriberId,
});
}
componentWillUnmount(): void {
WorkerScriptStartStopEventEmitter.removeSubscriber(subscriberId);
}
updateServerToScriptsMap(): void {
const map: IServerToScriptsMap = {};
for (const ws of this.props.workerScripts.values()) {
const server = getServer(ws.serverIp);
if (server == null) {
console.warn(`WorkerScript has invalid IP address: ${ws.serverIp}`);
continue;
}
if (map[server.hostname] == null) {
map[server.hostname] = {
server: server,
workerScripts: [],
};
}
map[server.hostname].workerScripts.push(ws);
}
this.serverToScriptMap = map;
}
rerender(): void {
this.updateServerToScriptsMap();
this.setState((prevState) => {
return { rerenderFlag: !prevState.rerenderFlag };
});
}
render(): React.ReactNode {
const elems = Object.keys(this.serverToScriptMap).map((serverName) => {
const data = this.serverToScriptMap[serverName];
return <ServerAccordion key={serverName} server={data.server} workerScripts={data.workerScripts} />;
});
return (
<ul className="active-scripts-list" id="active-scripts-list">
{elems}
</ul>
);
}
}