diff --git a/src/ScriptEditor/ui/OptionsModal.tsx b/src/ScriptEditor/ui/OptionsModal.tsx
index 65e12db1f..70fb9e361 100644
--- a/src/ScriptEditor/ui/OptionsModal.tsx
+++ b/src/ScriptEditor/ui/OptionsModal.tsx
@@ -9,10 +9,6 @@ import Select from "@mui/material/Select";
import Switch from "@mui/material/Switch";
import MenuItem from "@mui/material/MenuItem";
import TextField from "@mui/material/TextField";
-import EditIcon from '@mui/icons-material/Edit';
-import SaveIcon from '@mui/icons-material/Save';
-
-import { ThemeEditorModal } from "./ThemeEditorModal";
interface IProps {
options: Options;
@@ -27,7 +23,6 @@ export function OptionsModal(props: IProps): React.ReactElement {
const [fontSize, setFontSize] = useState(props.options.fontSize);
const [wordWrap, setWordWrap] = useState(props.options.wordWrap);
const [vim, setVim] = useState(props.options.vim);
- const [themeEditorOpen, setThemeEditorOpen] = useState(false);
function save(): void {
props.save({
@@ -48,10 +43,6 @@ export function OptionsModal(props: IProps): React.ReactElement {
return (
- setThemeEditorOpen(false)}
- />
Theme:
-
@@ -93,7 +80,7 @@ export function OptionsModal(props: IProps): React.ReactElement {
- }>Save
+
);
}
diff --git a/src/ScriptEditor/ui/ScriptEditorRoot.tsx b/src/ScriptEditor/ui/ScriptEditorRoot.tsx
index 2dc20212b..1e3d529d9 100644
--- a/src/ScriptEditor/ui/ScriptEditorRoot.tsx
+++ b/src/ScriptEditor/ui/ScriptEditorRoot.tsx
@@ -25,7 +25,7 @@ import { Settings } from "../../Settings/Settings";
import { iTutorialNextStep, ITutorial, iTutorialSteps } from "../../InteractiveTutorial";
import { debounce } from "lodash";
import { saveObject } from "../../SaveObject";
-import { loadThemes, makeTheme, sanitizeTheme } from "./themes";
+import { loadThemes } from "./themes";
import { GetServer } from "../../Server/AllServers";
import Button from "@mui/material/Button";
@@ -362,8 +362,6 @@ export function Root(props: IProps): React.ReactElement {
monaco.languages.typescript.javascriptDefaults.addExtraLib(source, "netscript.d.ts");
monaco.languages.typescript.typescriptDefaults.addExtraLib(source, "netscript.d.ts");
loadThemes(monaco);
- sanitizeTheme(Settings.EditorTheme);
- monaco.editor.defineTheme("customTheme", makeTheme(Settings.EditorTheme));
}
// When the editor is mounted
@@ -995,11 +993,7 @@ export function Root(props: IProps): React.ReactElement {
{
- sanitizeTheme(Settings.EditorTheme);
- monacoRef.current?.editor.defineTheme("customTheme", makeTheme(Settings.EditorTheme));
- setOptionsOpen(false);
- }}
+ onClose={() => setOptionsOpen(false)}
options={{
theme: Settings.MonacoTheme,
insertSpaces: Settings.MonacoInsertSpaces,
@@ -1008,8 +1002,6 @@ export function Root(props: IProps): React.ReactElement {
vim: Settings.MonacoVim,
}}
save={(options: Options) => {
- sanitizeTheme(Settings.EditorTheme);
- monacoRef.current?.editor.defineTheme("customTheme", makeTheme(Settings.EditorTheme));
setOptions(options);
Settings.MonacoTheme = options.theme;
Settings.MonacoInsertSpaces = options.insertSpaces;
diff --git a/src/ScriptEditor/ui/ThemeEditorModal.tsx b/src/ScriptEditor/ui/ThemeEditorModal.tsx
deleted file mode 100644
index 0bf75ed03..000000000
--- a/src/ScriptEditor/ui/ThemeEditorModal.tsx
+++ /dev/null
@@ -1,276 +0,0 @@
-import React, { useState } from "react";
-import { Modal } from "../../ui/React/Modal";
-import { defaultMonacoTheme, IScriptEditorTheme } from "./themes";
-
-import Typography from "@mui/material/Typography";
-import Button from "@mui/material/Button";
-import Box from "@mui/material/Box";
-import Tooltip from "@mui/material/Tooltip";
-import TextField from "@mui/material/TextField";
-import Paper from "@mui/material/Paper";
-import IconButton from "@mui/material/IconButton";
-import ReplyIcon from "@mui/icons-material/Reply";
-import HistoryIcon from '@mui/icons-material/History';
-import SaveIcon from '@mui/icons-material/Save';
-
-import { Settings } from "../../Settings/Settings";
-import { OptionSwitch } from "../../ui/React/OptionSwitch";
-import _ from "lodash";
-
-import { Color, ColorPicker } from "material-ui-color";
-
-interface IProps {
- onClose: () => void;
- open: boolean;
-}
-
-interface IColorEditorProps {
- label: string;
- themePath: string;
- color: string | undefined;
- onColorChange: (name: string, value: string) => void;
- defaultColor: string;
-}
-
-// Slightly tweaked version of the same function found in game options
-function ColorEditor({ label, themePath, onColorChange, color, defaultColor }: IColorEditorProps): React.ReactElement {
- if (color === undefined) {
- console.error(`color ${themePath} was undefined, reverting to default`);
- color = defaultColor;
- }
-
- return (
- <>
-
-
-
- onColorChange(themePath, newColor.hex)}
- disableAlpha
- />
- >
- ),
- endAdornment: (
- <>
- onColorChange(themePath, defaultColor)}>
-
-
- >
- ),
- }}
- />
-
-
- >
- );
-}
-
-export function ThemeEditorModal(props: IProps): React.ReactElement {
- const setRerender = useState(false)[1];
- function rerender(): void {
- setRerender((o) => !o);
- }
-
- // Need to deep copy the object since it has nested attributes
- const [themeCopy, setThemeCopy] = useState(JSON.parse(JSON.stringify(Settings.EditorTheme)));
-
- function onColorChange(name: string, value: string): void {
- setThemeCopy(_.set(themeCopy, name, value));
- rerender();
- }
-
- function onThemeChange(event: React.ChangeEvent): void {
- try {
- const importedTheme = JSON.parse(event.target.value);
- if (typeof importedTheme !== "object") return;
- setThemeCopy(importedTheme);
- } catch (err) {
- // ignore
- }
- }
-
- return (
- {
- setThemeCopy(Settings.EditorTheme);
- props.onClose();
- }}>
- Customize Editor theme
- Hover over input boxes for more information
-
- {
- setThemeCopy(_.set(themeCopy, "base", val ? "vs" : "vs-dark"));
- rerender();
- }}
- text="Use light theme as base"
- tooltip={
- <>
- If enabled, the vs
light theme will be used as the
- theme base, otherwise, vs-dark
will be used.
- >
- }
- />
-
-
- UI
-
-
-
-
-
-
-
-
-
- Syntax
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- )
-}
diff --git a/src/ScriptEditor/ui/themes.ts b/src/ScriptEditor/ui/themes.ts
index d9f35d100..79a698727 100644
--- a/src/ScriptEditor/ui/themes.ts
+++ b/src/ScriptEditor/ui/themes.ts
@@ -1,216 +1,3 @@
-export interface IScriptEditorTheme {
- [key: string]: any;
- base: string;
- inherit: boolean;
- common: {
- [key: string]: string;
- accent: string;
- bg: string;
- fg: string;
- };
- syntax: {
- [key: string]: string;
- tag: string;
- entity: string;
- string: string;
- regexp: string;
- markup: string;
- keyword: string;
- comment: string;
- constant: string;
- error: string;
- };
- ui: {
- [key: string]: any;
- line: string;
- panel: {
- [key: string]: string;
- bg: string;
- selected: string;
- border: string;
- };
- selection: {
- [key: string]: string;
- bg: string;
- };
- };
-}
-
-export const defaultMonacoTheme: IScriptEditorTheme = {
- base: "vs-dark",
- inherit: true,
- common: {
- accent: "B5CEA8",
- bg: "1E1E1E",
- fg: "D4D4D4",
- },
- syntax: {
- tag: "569CD6",
- entity: "569CD6",
- string: "CE9178",
- regexp: "646695",
- markup: "569CD6",
- keyword: "569CD6",
- comment: "6A9955",
- constant: "569CD6",
- error: "F44747"
- },
- ui: {
- line: "1E1E1E",
- panel: {
- bg: "252526",
- selected: "252526",
- border: "1E1E1E"
- },
- selection: {
- bg: "ADD6FF26"
- }
- }
-}
-
-// Regex used for token color validation
-// https://github.com/microsoft/vscode/blob/973684056e67153952f495fce93bf50d0ec0b892/src/vs/editor/common/languages/supports/tokenization.ts#L153
-const colorRegExp = /^#?([0-9A-Fa-f]{6})([0-9A-Fa-f]{2})?$/;
-
-// Recursively sanitize the theme data to prevent errors
-// Invalid data will be replaced with FF0000 (bright red)
-export const sanitizeTheme = (theme: IScriptEditorTheme): void => {
- for (const [k, v] of Object.entries(theme)) {
- switch (k) {
- case "base":
- if (!["vs-dark", "vs"].includes(theme.base)) theme.base = "vs-dark";
- continue;
- case "inherit":
- if (typeof theme.inherit !== "boolean") theme.inherit = true;
- continue;
- }
-
- const repairBlock = (block: { [key: string]: any }): void => {
- for (const [k, v] of Object.entries(block)) {
- if (typeof v === "object") {
- repairBlock(v as { [key: string]: string });
- } else {
- if (!v.match(colorRegExp)) block[k] = "FF0000";
- }
- }
- }
- repairBlock(v);
- }
-}
-
-export function makeTheme(theme: IScriptEditorTheme): any {
- const themeRules = [
- {
- token: "",
- background: theme.ui.line,
- foreground: theme.common.fg
- },
- {
- token: "identifier",
- foreground: theme.common.accent
- },
- {
- token: "keyword",
- foreground: theme.syntax.keyword
- },
- {
- token: "string",
- foreground: theme.syntax.string
- },
- {
- token: "string.escape",
- foreground: theme.syntax.regexp
- },
- {
- token: "comment",
- foreground: theme.syntax.comment
- },
- {
- token: "constant",
- foreground: theme.syntax.constant
- },
- {
- token: "entity",
- foreground: theme.syntax.entity
- },
- {
- token: "type",
- foreground: theme.syntax.tag
- },
- {
- token: "tag",
- foreground: theme.syntax.tag
- },
- {
- token: "regexp",
- foreground: theme.syntax.regexp
- },
- {
- token: "attribute",
- foreground: theme.syntax.tag
- },
- {
- token: "constructor",
- foreground: theme.syntax.markup
- },
- {
- token: "invalid",
- foreground: theme.syntax.error
- },
- {
- token: "number",
- foreground: theme.common.accent
- },
- {
- token: "delimiter",
- foreground: theme.common.fg
- },
- // Custom tokens
- {
- token: "ns",
- foreground: theme.syntax.tag
- },
- {
- token: "netscriptfunction",
- foreground: theme.syntax.markup
- },
- {
- token: "otherkeywords",
- foreground: theme.syntax.keyword
- },
- {
- token: "otherkeyvars",
- foreground: theme.common.accent
- },
- {
- token: "this",
- foreground: theme.syntax.tag
- }
- ];
-
- const themeColors = Object.fromEntries([
- ["editor.background", theme.common.bg],
- ["editor.foreground", theme.common.fg],
- ["editor.lineHighlightBackground", theme.ui.line],
- ["editor.selectionBackground", theme.ui.selection.bg],
-
- ["editorSuggestWidget.background", theme.ui.panel.bg],
- ["editorSuggestWidget.border", theme.ui.panel.border],
- ["editorSuggestWidget.selectedBackground", theme.ui.panel.selected],
-
- ["editorHoverWidget.background", theme.ui.panel.bg],
- ["editorHoverWidget.border", theme.ui.panel.border],
-
- ["editorWidget.background", theme.ui.panel.bg],
- ["editorWidget.border", theme.ui.panel.border],
-
- ["input.background", theme.ui.panel.bg],
- ["input.border", theme.ui.panel.border]
- ].map(([k, v]) => [k, "#" + v]));
-
- return { base: theme.base, inherit: theme.inherit, rules: themeRules, colors: themeColors }
-}
-
export async function loadThemes(monaco: { editor: any }): Promise {
monaco.editor.defineTheme("monokai", {
base: "vs-dark",
diff --git a/src/Settings/Settings.ts b/src/Settings/Settings.ts
index c8d1cfd0c..906c9ca2d 100644
--- a/src/Settings/Settings.ts
+++ b/src/Settings/Settings.ts
@@ -5,7 +5,6 @@ import { defaultStyles } from "../Themes/Styles";
import { WordWrapOptions } from "../ScriptEditor/ui/Options";
import { OverviewSettings } from "../ui/React/Overview";
import { IStyleSettings } from "../ScriptEditor/NetscriptDefinitions";
-import { defaultMonacoTheme, IScriptEditorTheme } from "../ScriptEditor/ui/themes";
/**
* Represents the default settings the player could customize.
@@ -158,11 +157,6 @@ interface IDefaultSettings {
* If the game's sidebar is opened
*/
IsSidebarOpened: boolean;
-
- /**
- * Script editor theme data
- */
- EditorTheme: IScriptEditorTheme;
}
/**
@@ -222,8 +216,6 @@ export const defaultSettings: IDefaultSettings = {
theme: defaultTheme,
styles: defaultStyles,
overview: { x: 0, y: 0, opened: true },
-
- EditorTheme: defaultMonacoTheme,
};
/**
@@ -270,7 +262,6 @@ export const Settings: ISettings & ISelfInitializer & ISelfLoading = {
theme: { ...defaultTheme },
styles: { ...defaultStyles },
overview: defaultSettings.overview,
- EditorTheme: { ...defaultMonacoTheme },
init() {
Object.assign(Settings, defaultSettings);
},
@@ -282,8 +273,6 @@ export const Settings: ISettings & ISelfInitializer & ISelfLoading = {
delete save.styles;
Object.assign(Settings.overview, save.overview);
delete save.overview;
- Object.assign(Settings.EditorTheme, save.EditorTheme);
- delete save.EditorTheme;
Object.assign(Settings, save);
},
};
diff --git a/src/Themes/ui/ThemeEditorModal.tsx b/src/Themes/ui/ThemeEditorModal.tsx
index 882b8d761..602c45655 100644
--- a/src/Themes/ui/ThemeEditorModal.tsx
+++ b/src/Themes/ui/ThemeEditorModal.tsx
@@ -366,9 +366,9 @@ export function ThemeEditorModal(props: IProps): React.ReactElement {
sx={{ mb: 1 }}
multiline
fullWidth
- maxRows={10}
+ maxRows={3}
label={"import / export theme"}
- value={JSON.stringify(customTheme, undefined, 2)}
+ value={JSON.stringify(customTheme)}
onChange={onThemeChange}
/>
<>