Add the ability to filter open scripts

* icon that opens up on click and reset and closes on X
This commit is contained in:
phyzical 2022-03-15 20:37:11 +08:00
parent bb433d4629
commit 61ed4a4d43

@ -17,6 +17,7 @@ import { calculateRamUsage, checkInfiniteLoop } from "../../Script/RamCalculatio
import { RamCalculationErrorCode } from "../../Script/RamCalculationErrorCodes"; import { RamCalculationErrorCode } from "../../Script/RamCalculationErrorCodes";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd"; import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
import SearchIcon from "@mui/icons-material/Search";
import { NetscriptFunctions } from "../../NetscriptFunctions"; import { NetscriptFunctions } from "../../NetscriptFunctions";
import { WorkerScript } from "../../Netscript/WorkerScript"; import { WorkerScript } from "../../Netscript/WorkerScript";
@ -42,7 +43,7 @@ import { PromptEvent } from "../../ui/React/PromptManager";
import { Modal } from "../../ui/React/Modal"; import { Modal } from "../../ui/React/Modal";
import libSource from "!!raw-loader!../NetscriptDefinitions.d.ts"; import libSource from "!!raw-loader!../NetscriptDefinitions.d.ts";
import { Tooltip } from "@mui/material"; import { TextField, Tooltip } from "@mui/material";
interface IProps { interface IProps {
// Map of filename -> code // Map of filename -> code
@ -53,7 +54,7 @@ interface IProps {
vim: boolean; vim: boolean;
} }
// TODO: try to removve global symbols // TODO: try to remove global symbols
let symbolsLoaded = false; let symbolsLoaded = false;
let symbols: string[] = []; let symbols: string[] = [];
export function SetupTextEditor(): void { export function SetupTextEditor(): void {
@ -113,6 +114,8 @@ export function Root(props: IProps): React.ReactElement {
const vimStatusRef = useRef<HTMLElement>(null); const vimStatusRef = useRef<HTMLElement>(null);
const [vimEditor, setVimEditor] = useState<any>(null); const [vimEditor, setVimEditor] = useState<any>(null);
const [editor, setEditor] = useState<IStandaloneCodeEditor | null>(null); const [editor, setEditor] = useState<IStandaloneCodeEditor | null>(null);
const [filter, setFilter] = useState("");
const [searchExpanded, setSearchExpanded] = useState(false);
const [ram, setRAM] = useState("RAM: ???"); const [ram, setRAM] = useState("RAM: ???");
const [ramEntries, setRamEntries] = useState<string[][]>([["???", ""]]); const [ramEntries, setRamEntries] = useState<string[][]>([["???", ""]]);
@ -232,7 +235,7 @@ export function Root(props: IProps): React.ReactElement {
MonacoVim.VimMode.Vim.mapCommand("gT", "action", "prevTabs", {}, { context: "normal" }); MonacoVim.VimMode.Vim.mapCommand("gT", "action", "prevTabs", {}, { context: "normal" });
editor.focus(); editor.focus();
}); });
} catch {} } catch { }
} else if (!options.vim) { } else if (!options.vim) {
// Whem vim mode is disabled // Whem vim mode is disabled
vimEditor?.dispose(); vimEditor?.dispose();
@ -478,7 +481,7 @@ export function Root(props: IProps): React.ReactElement {
} }
try { try {
infLoop(newCode); infLoop(newCode);
} catch (err) {} } catch (err) { }
} }
function saveScript(scriptToSave: OpenScript): void { function saveScript(scriptToSave: OpenScript): void {
@ -787,6 +790,16 @@ export function Root(props: IProps): React.ReactElement {
const serverScript = server.scripts.find((s) => s.filename === openScript.fileName); const serverScript = server.scripts.find((s) => s.filename === openScript.fileName);
return serverScript?.code ?? null; 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: // Toolbars are roughly 112px:
// 8px body margin top // 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 editorHeight = dimensions.height - (130 + (options.vim ? 34 : 0));
const tabsMaxWidth = 1640; const tabsMaxWidth = 1640;
const tabMargin = 5; 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 tabIconWidth = 25;
const tabTextWidth = tabMaxWidth - tabIconWidth * 2; const tabTextWidth = tabMaxWidth - tabIconWidth * 2;
return ( return (
@ -821,23 +834,36 @@ export function Root(props: IProps): React.ReactElement {
overflowX: "scroll", 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 iconButtonStyle = { const iconButtonStyle = {
maxWidth: `${tabIconWidth}px`, maxWidth: `${tabIconWidth}px`,
minWidth: `${tabIconWidth}px`, minWidth: `${tabIconWidth}px`,
minHeight: "38.5px", minHeight: "38.5px",
maxHeight: "38.5px", maxHeight: "38.5px",
...(currentScript?.fileName === openScripts[index].fileName ...(currentScript?.fileName === filteredOpenScripts[index].fileName
? { ? {
background: Settings.theme.button, background: Settings.theme.button,
borderColor: Settings.theme.button, borderColor: Settings.theme.button,
color: Settings.theme.primary, color: Settings.theme.primary,
} }
: { : {
background: Settings.theme.backgroundsecondary, background: Settings.theme.backgroundsecondary,
borderColor: Settings.theme.backgroundsecondary, borderColor: Settings.theme.backgroundsecondary,
color: Settings.theme.secondary, color: Settings.theme.secondary,
}), }),
}; };
const scriptTabText = `${hostname}:~/${fileName} ${dirty(index)}`; const scriptTabText = `${hostname}:~/${fileName} ${dirty(index)}`;
@ -871,17 +897,17 @@ export function Root(props: IProps): React.ReactElement {
style={{ style={{
maxWidth: `${tabTextWidth}px`, maxWidth: `${tabTextWidth}px`,
overflow: "hidden", overflow: "hidden",
...(currentScript?.fileName === openScripts[index].fileName ...(currentScript?.fileName === filteredOpenScripts[index].fileName
? { ? {
background: Settings.theme.button, background: Settings.theme.button,
borderColor: Settings.theme.button, borderColor: Settings.theme.button,
color: Settings.theme.primary, color: Settings.theme.primary,
} }
: { : {
background: Settings.theme.backgroundsecondary, background: Settings.theme.backgroundsecondary,
borderColor: Settings.theme.backgroundsecondary, borderColor: Settings.theme.backgroundsecondary,
color: Settings.theme.secondary, color: Settings.theme.secondary,
}), }),
}} }}
> >
<span style={{ overflow: "hidden", direction: "rtl", textOverflow: "ellipsis" }}> <span style={{ overflow: "hidden", direction: "rtl", textOverflow: "ellipsis" }}>