mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-16 22:38:34 +02:00
Merge branch 'dev' into bugfix/2958
This commit is contained in:
@@ -17,6 +17,7 @@ import { calculateRamUsage, checkInfiniteLoop } from "../../Script/RamCalculatio
|
||||
import { RamCalculationErrorCode } from "../../Script/RamCalculationErrorCodes";
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
|
||||
import SearchIcon from "@mui/icons-material/Search";
|
||||
|
||||
import { NetscriptFunctions } from "../../NetscriptFunctions";
|
||||
import { WorkerScript } from "../../Netscript/WorkerScript";
|
||||
@@ -42,7 +43,7 @@ import { PromptEvent } from "../../ui/React/PromptManager";
|
||||
import { Modal } from "../../ui/React/Modal";
|
||||
|
||||
import libSource from "!!raw-loader!../NetscriptDefinitions.d.ts";
|
||||
import { Tooltip } from "@mui/material";
|
||||
import { TextField, Tooltip } from "@mui/material";
|
||||
|
||||
interface IProps {
|
||||
// Map of filename -> code
|
||||
@@ -113,6 +114,8 @@ export function Root(props: IProps): React.ReactElement {
|
||||
const vimStatusRef = useRef<HTMLElement>(null);
|
||||
const [vimEditor, setVimEditor] = useState<any>(null);
|
||||
const [editor, setEditor] = useState<IStandaloneCodeEditor | null>(null);
|
||||
const [filter, setFilter] = useState("");
|
||||
const [searchExpanded, setSearchExpanded] = useState(false);
|
||||
|
||||
const [ram, setRAM] = useState("RAM: ???");
|
||||
const [ramEntries, setRamEntries] = useState<string[][]>([["???", ""]]);
|
||||
@@ -523,7 +526,7 @@ export function Root(props: IProps): React.ReactElement {
|
||||
const textFile = new TextFile(scriptToSave.fileName, scriptToSave.code);
|
||||
server.textFiles.push(textFile);
|
||||
} else {
|
||||
dialogBoxCreate("Invalid filename. Must be either a script (.script, .js, or .ns) or " + " or text file (.txt)");
|
||||
dialogBoxCreate("Invalid filename. Must be either a script (.script, .js, or .ns) or a text file (.txt)");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -607,7 +610,7 @@ export function Root(props: IProps): React.ReactElement {
|
||||
const textFile = new TextFile(currentScript.fileName, currentScript.code);
|
||||
server.textFiles.push(textFile);
|
||||
} else {
|
||||
dialogBoxCreate("Invalid filename. Must be either a script (.script, .js, or .ns) or " + " or text file (.txt)");
|
||||
dialogBoxCreate("Invalid filename. Must be either a script (.script, .js, or .ns) or a text file (.txt)");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -688,7 +691,7 @@ export function Root(props: IProps): React.ReactElement {
|
||||
if (serverScriptIndex === -1 || savedScriptCode !== server.scripts[serverScriptIndex as number].code) {
|
||||
PromptEvent.emit({
|
||||
txt: `Do you want to save changes to ${closingScript.fileName} on ${closingScript.hostname}?`,
|
||||
resolve: (result: boolean) => {
|
||||
resolve: (result: boolean | string) => {
|
||||
if (result) {
|
||||
// Save changes
|
||||
closingScript.code = savedScriptCode;
|
||||
@@ -745,7 +748,7 @@ export function Root(props: IProps): React.ReactElement {
|
||||
"Do you want to overwrite the current editor content with the contents of " +
|
||||
openScript.fileName +
|
||||
" on the server? This cannot be undone.",
|
||||
resolve: (result: boolean) => {
|
||||
resolve: (result: boolean | string) => {
|
||||
if (result) {
|
||||
// Save changes
|
||||
openScript.code = serverScriptCode;
|
||||
@@ -787,6 +790,16 @@ export function Root(props: IProps): React.ReactElement {
|
||||
const serverScript = server.scripts.find((s) => s.filename === openScript.fileName);
|
||||
return serverScript?.code ?? null;
|
||||
}
|
||||
function handleFilterChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||
setFilter(event.target.value);
|
||||
}
|
||||
function handleExpandSearch(): void {
|
||||
setFilter("")
|
||||
setSearchExpanded(!searchExpanded)
|
||||
}
|
||||
const filteredOpenScripts = Object.values(openScripts).filter(
|
||||
(script) => (script.hostname.includes(filter) || script.fileName.includes(filter))
|
||||
);
|
||||
|
||||
// Toolbars are roughly 112px:
|
||||
// 8px body margin top
|
||||
@@ -797,7 +810,7 @@ export function Root(props: IProps): React.ReactElement {
|
||||
const editorHeight = dimensions.height - (130 + (options.vim ? 34 : 0));
|
||||
const tabsMaxWidth = 1640;
|
||||
const tabMargin = 5;
|
||||
const tabMaxWidth = openScripts.length ? tabsMaxWidth / openScripts.length - tabMargin : 0;
|
||||
const tabMaxWidth = filteredOpenScripts.length ? tabsMaxWidth / filteredOpenScripts.length - tabMargin : 0;
|
||||
const tabIconWidth = 25;
|
||||
const tabTextWidth = tabMaxWidth - tabIconWidth * 2;
|
||||
return (
|
||||
@@ -821,7 +834,20 @@ export function Root(props: IProps): React.ReactElement {
|
||||
overflowX: "scroll",
|
||||
}}
|
||||
>
|
||||
{openScripts.map(({ fileName, hostname }, index) => {
|
||||
<Tooltip title={"Search Open Scripts"}>
|
||||
{searchExpanded ?
|
||||
<TextField
|
||||
value={filter}
|
||||
onChange={handleFilterChange}
|
||||
autoFocus
|
||||
InputProps={{
|
||||
startAdornment: <SearchIcon />,
|
||||
spellCheck: false,
|
||||
endAdornment: <CloseIcon onClick={handleExpandSearch} />
|
||||
}}
|
||||
/> : <Button onClick={handleExpandSearch} ><SearchIcon /></Button>}
|
||||
</Tooltip>
|
||||
{filteredOpenScripts.map(({ fileName, hostname }, index) => {
|
||||
const editingCurrentScript = currentScript?.fileName === openScripts[index].fileName &&
|
||||
currentScript?.hostname === openScripts[index].hostname
|
||||
const externalScript = hostname !== 'home'
|
||||
@@ -838,7 +864,6 @@ export function Root(props: IProps): React.ReactElement {
|
||||
if (externalScript) {
|
||||
colorProps.color = Settings.theme.info
|
||||
}
|
||||
|
||||
const iconButtonStyle = {
|
||||
maxWidth: `${tabIconWidth}px`,
|
||||
minWidth: `${tabIconWidth}px`,
|
||||
|
||||
Reference in New Issue
Block a user