mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-10 09:43:54 +01:00
Merge pull request #3422 from danielyxie/revert-2876-feature/monaco-theme-editor
Revert "[Feature] Script Editor Theme Customization"
This commit is contained in:
commit
476e9df5bb
@ -9,10 +9,6 @@ import Select from "@mui/material/Select";
|
|||||||
import Switch from "@mui/material/Switch";
|
import Switch from "@mui/material/Switch";
|
||||||
import MenuItem from "@mui/material/MenuItem";
|
import MenuItem from "@mui/material/MenuItem";
|
||||||
import TextField from "@mui/material/TextField";
|
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 {
|
interface IProps {
|
||||||
options: Options;
|
options: Options;
|
||||||
@ -27,7 +23,6 @@ export function OptionsModal(props: IProps): React.ReactElement {
|
|||||||
const [fontSize, setFontSize] = useState(props.options.fontSize);
|
const [fontSize, setFontSize] = useState(props.options.fontSize);
|
||||||
const [wordWrap, setWordWrap] = useState(props.options.wordWrap);
|
const [wordWrap, setWordWrap] = useState(props.options.wordWrap);
|
||||||
const [vim, setVim] = useState(props.options.vim);
|
const [vim, setVim] = useState(props.options.vim);
|
||||||
const [themeEditorOpen, setThemeEditorOpen] = useState(false);
|
|
||||||
|
|
||||||
function save(): void {
|
function save(): void {
|
||||||
props.save({
|
props.save({
|
||||||
@ -48,10 +43,6 @@ export function OptionsModal(props: IProps): React.ReactElement {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal open={props.open} onClose={props.onClose}>
|
<Modal open={props.open} onClose={props.onClose}>
|
||||||
<ThemeEditorModal
|
|
||||||
open={themeEditorOpen}
|
|
||||||
onClose={() => setThemeEditorOpen(false)}
|
|
||||||
/>
|
|
||||||
<Box display="flex" flexDirection="row" alignItems="center">
|
<Box display="flex" flexDirection="row" alignItems="center">
|
||||||
<Typography>Theme: </Typography>
|
<Typography>Theme: </Typography>
|
||||||
<Select onChange={(event) => setTheme(event.target.value)} value={theme}>
|
<Select onChange={(event) => setTheme(event.target.value)} value={theme}>
|
||||||
@ -62,11 +53,7 @@ export function OptionsModal(props: IProps): React.ReactElement {
|
|||||||
<MenuItem value="light">light</MenuItem>
|
<MenuItem value="light">light</MenuItem>
|
||||||
<MenuItem value="dracula">dracula</MenuItem>
|
<MenuItem value="dracula">dracula</MenuItem>
|
||||||
<MenuItem value="one-dark">one-dark</MenuItem>
|
<MenuItem value="one-dark">one-dark</MenuItem>
|
||||||
<MenuItem value="customTheme">Custom theme</MenuItem>
|
|
||||||
</Select>
|
</Select>
|
||||||
<Button onClick={() => setThemeEditorOpen(true)} sx={{ mx: 1 }} startIcon={<EditIcon />}>
|
|
||||||
Edit custom theme
|
|
||||||
</Button>
|
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box display="flex" flexDirection="row" alignItems="center">
|
<Box display="flex" flexDirection="row" alignItems="center">
|
||||||
@ -93,7 +80,7 @@ export function OptionsModal(props: IProps): React.ReactElement {
|
|||||||
<TextField type="number" label="Font size" value={fontSize} onChange={onFontChange} />
|
<TextField type="number" label="Font size" value={fontSize} onChange={onFontChange} />
|
||||||
</Box>
|
</Box>
|
||||||
<br />
|
<br />
|
||||||
<Button onClick={save} startIcon={<SaveIcon />}>Save</Button>
|
<Button onClick={save}>Save</Button>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ import { Settings } from "../../Settings/Settings";
|
|||||||
import { iTutorialNextStep, ITutorial, iTutorialSteps } from "../../InteractiveTutorial";
|
import { iTutorialNextStep, ITutorial, iTutorialSteps } from "../../InteractiveTutorial";
|
||||||
import { debounce } from "lodash";
|
import { debounce } from "lodash";
|
||||||
import { saveObject } from "../../SaveObject";
|
import { saveObject } from "../../SaveObject";
|
||||||
import { loadThemes, makeTheme, sanitizeTheme } from "./themes";
|
import { loadThemes } from "./themes";
|
||||||
import { GetServer } from "../../Server/AllServers";
|
import { GetServer } from "../../Server/AllServers";
|
||||||
|
|
||||||
import Button from "@mui/material/Button";
|
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.javascriptDefaults.addExtraLib(source, "netscript.d.ts");
|
||||||
monaco.languages.typescript.typescriptDefaults.addExtraLib(source, "netscript.d.ts");
|
monaco.languages.typescript.typescriptDefaults.addExtraLib(source, "netscript.d.ts");
|
||||||
loadThemes(monaco);
|
loadThemes(monaco);
|
||||||
sanitizeTheme(Settings.EditorTheme);
|
|
||||||
monaco.editor.defineTheme("customTheme", makeTheme(Settings.EditorTheme));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the editor is mounted
|
// When the editor is mounted
|
||||||
@ -995,11 +993,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
</Box>
|
</Box>
|
||||||
<OptionsModal
|
<OptionsModal
|
||||||
open={optionsOpen}
|
open={optionsOpen}
|
||||||
onClose={() => {
|
onClose={() => setOptionsOpen(false)}
|
||||||
sanitizeTheme(Settings.EditorTheme);
|
|
||||||
monacoRef.current?.editor.defineTheme("customTheme", makeTheme(Settings.EditorTheme));
|
|
||||||
setOptionsOpen(false);
|
|
||||||
}}
|
|
||||||
options={{
|
options={{
|
||||||
theme: Settings.MonacoTheme,
|
theme: Settings.MonacoTheme,
|
||||||
insertSpaces: Settings.MonacoInsertSpaces,
|
insertSpaces: Settings.MonacoInsertSpaces,
|
||||||
@ -1008,8 +1002,6 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
vim: Settings.MonacoVim,
|
vim: Settings.MonacoVim,
|
||||||
}}
|
}}
|
||||||
save={(options: Options) => {
|
save={(options: Options) => {
|
||||||
sanitizeTheme(Settings.EditorTheme);
|
|
||||||
monacoRef.current?.editor.defineTheme("customTheme", makeTheme(Settings.EditorTheme));
|
|
||||||
setOptions(options);
|
setOptions(options);
|
||||||
Settings.MonacoTheme = options.theme;
|
Settings.MonacoTheme = options.theme;
|
||||||
Settings.MonacoInsertSpaces = options.insertSpaces;
|
Settings.MonacoInsertSpaces = options.insertSpaces;
|
||||||
|
@ -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 (
|
|
||||||
<>
|
|
||||||
<Tooltip title={label}>
|
|
||||||
<span>
|
|
||||||
<TextField
|
|
||||||
label={themePath}
|
|
||||||
value={"#" + color}
|
|
||||||
sx={{ display: "block", my: 1 }}
|
|
||||||
InputProps={{
|
|
||||||
startAdornment: (
|
|
||||||
<>
|
|
||||||
<ColorPicker
|
|
||||||
hideTextfield
|
|
||||||
deferred
|
|
||||||
value={"#" + color}
|
|
||||||
onChange={(newColor: Color) => onColorChange(themePath, newColor.hex)}
|
|
||||||
disableAlpha
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
),
|
|
||||||
endAdornment: (
|
|
||||||
<>
|
|
||||||
<IconButton onClick={() => onColorChange(themePath, defaultColor)}>
|
|
||||||
<ReplyIcon color="primary" />
|
|
||||||
</IconButton>
|
|
||||||
</>
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</Tooltip>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
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<IScriptEditorTheme>(JSON.parse(JSON.stringify(Settings.EditorTheme)));
|
|
||||||
|
|
||||||
function onColorChange(name: string, value: string): void {
|
|
||||||
setThemeCopy(_.set(themeCopy, name, value));
|
|
||||||
rerender();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onThemeChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
|
||||||
try {
|
|
||||||
const importedTheme = JSON.parse(event.target.value);
|
|
||||||
if (typeof importedTheme !== "object") return;
|
|
||||||
setThemeCopy(importedTheme);
|
|
||||||
} catch (err) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal open={props.open} onClose={() => {
|
|
||||||
setThemeCopy(Settings.EditorTheme);
|
|
||||||
props.onClose();
|
|
||||||
}}>
|
|
||||||
<Typography variant="h4">Customize Editor theme</Typography>
|
|
||||||
<Typography>Hover over input boxes for more information</Typography>
|
|
||||||
<Paper sx={{ p: 1, my: 1 }}>
|
|
||||||
<OptionSwitch
|
|
||||||
checked={themeCopy.base === "vs"}
|
|
||||||
onChange={(val) => {
|
|
||||||
setThemeCopy(_.set(themeCopy, "base", val ? "vs" : "vs-dark"));
|
|
||||||
rerender();
|
|
||||||
}}
|
|
||||||
text="Use light theme as base"
|
|
||||||
tooltip={
|
|
||||||
<>
|
|
||||||
If enabled, the <code>vs</code> light theme will be used as the
|
|
||||||
theme base, otherwise, <code>vs-dark</code> will be used.
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Box display="grid" sx={{ gridTemplateColumns: "1fr 1fr", width: "fit-content", gap: 1 }}>
|
|
||||||
<Box>
|
|
||||||
<Typography variant="h6">UI</Typography>
|
|
||||||
<ColorEditor
|
|
||||||
label="Background color"
|
|
||||||
themePath="common.bg"
|
|
||||||
onColorChange={onColorChange}
|
|
||||||
color={themeCopy.common.bg}
|
|
||||||
defaultColor={defaultMonacoTheme.common.bg}
|
|
||||||
/>
|
|
||||||
<ColorEditor
|
|
||||||
label="Current line and minimap background color"
|
|
||||||
themePath="ui.line"
|
|
||||||
onColorChange={onColorChange}
|
|
||||||
color={themeCopy.ui.line}
|
|
||||||
defaultColor={defaultMonacoTheme.ui.line}
|
|
||||||
/>
|
|
||||||
<ColorEditor
|
|
||||||
label="Base text color"
|
|
||||||
themePath="common.fg"
|
|
||||||
onColorChange={onColorChange}
|
|
||||||
color={themeCopy.common.fg}
|
|
||||||
defaultColor={defaultMonacoTheme.common.fg}
|
|
||||||
/>
|
|
||||||
<ColorEditor
|
|
||||||
label="Popup background color"
|
|
||||||
themePath="ui.panel.bg"
|
|
||||||
onColorChange={onColorChange}
|
|
||||||
color={themeCopy.ui.panel.bg}
|
|
||||||
defaultColor={defaultMonacoTheme.ui.panel.bg}
|
|
||||||
/>
|
|
||||||
<ColorEditor
|
|
||||||
label="Background color for selected item in popup"
|
|
||||||
themePath="ui.panel.selected"
|
|
||||||
onColorChange={onColorChange}
|
|
||||||
color={themeCopy.ui.panel.selected}
|
|
||||||
defaultColor={defaultMonacoTheme.ui.panel.selected}
|
|
||||||
/>
|
|
||||||
<ColorEditor
|
|
||||||
label="Popup border color"
|
|
||||||
themePath="ui.panel.border"
|
|
||||||
onColorChange={onColorChange}
|
|
||||||
color={themeCopy.ui.panel.border}
|
|
||||||
defaultColor={defaultMonacoTheme.ui.panel.border}
|
|
||||||
/>
|
|
||||||
<ColorEditor
|
|
||||||
label="Background color of highlighted text"
|
|
||||||
themePath="ui.selection.bg"
|
|
||||||
onColorChange={onColorChange}
|
|
||||||
color={themeCopy.ui.selection.bg}
|
|
||||||
defaultColor={defaultMonacoTheme.ui.selection.bg}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
<Box>
|
|
||||||
<Typography variant="h6">Syntax</Typography>
|
|
||||||
<ColorEditor
|
|
||||||
label="Numbers, function names, and other key vars"
|
|
||||||
themePath="common.accent"
|
|
||||||
onColorChange={onColorChange}
|
|
||||||
color={themeCopy.common.accent}
|
|
||||||
defaultColor={defaultMonacoTheme.common.accent}
|
|
||||||
/>
|
|
||||||
<ColorEditor
|
|
||||||
label="Keywords"
|
|
||||||
themePath="syntax.keyword"
|
|
||||||
onColorChange={onColorChange}
|
|
||||||
color={themeCopy.syntax.keyword}
|
|
||||||
defaultColor={defaultMonacoTheme.syntax.keyword}
|
|
||||||
/>
|
|
||||||
<ColorEditor
|
|
||||||
label="Strings"
|
|
||||||
themePath="syntax.string"
|
|
||||||
onColorChange={onColorChange}
|
|
||||||
color={themeCopy.syntax.string}
|
|
||||||
defaultColor={defaultMonacoTheme.syntax.string}
|
|
||||||
/>
|
|
||||||
<ColorEditor
|
|
||||||
label="Regexp literals as well as escapes within strings"
|
|
||||||
themePath="syntax.regexp"
|
|
||||||
onColorChange={onColorChange}
|
|
||||||
color={themeCopy.syntax.regexp}
|
|
||||||
defaultColor={defaultMonacoTheme.syntax.regexp}
|
|
||||||
/>
|
|
||||||
<ColorEditor
|
|
||||||
label="Constants"
|
|
||||||
themePath="syntax.constant"
|
|
||||||
onColorChange={onColorChange}
|
|
||||||
color={themeCopy.syntax.constant}
|
|
||||||
defaultColor={defaultMonacoTheme.syntax.constant}
|
|
||||||
/>
|
|
||||||
<ColorEditor
|
|
||||||
label="Entities"
|
|
||||||
themePath="syntax.entity"
|
|
||||||
onColorChange={onColorChange}
|
|
||||||
color={themeCopy.syntax.entity}
|
|
||||||
defaultColor={defaultMonacoTheme.syntax.entity}
|
|
||||||
/>
|
|
||||||
<ColorEditor
|
|
||||||
label="'this', 'ns', types, and tags"
|
|
||||||
themePath="syntax.tag"
|
|
||||||
onColorChange={onColorChange}
|
|
||||||
color={themeCopy.syntax.tag}
|
|
||||||
defaultColor={defaultMonacoTheme.syntax.tag}
|
|
||||||
/>
|
|
||||||
<ColorEditor
|
|
||||||
label="Netscript functions and constructors"
|
|
||||||
themePath="syntax.markup"
|
|
||||||
onColorChange={onColorChange}
|
|
||||||
color={themeCopy.syntax.markup}
|
|
||||||
defaultColor={defaultMonacoTheme.syntax.markup}
|
|
||||||
/>
|
|
||||||
<ColorEditor
|
|
||||||
label="Errors"
|
|
||||||
themePath="syntax.error"
|
|
||||||
onColorChange={onColorChange}
|
|
||||||
color={themeCopy.syntax.error}
|
|
||||||
defaultColor={defaultMonacoTheme.syntax.error}
|
|
||||||
/>
|
|
||||||
<ColorEditor
|
|
||||||
label="Comments"
|
|
||||||
themePath="syntax.comment"
|
|
||||||
onColorChange={onColorChange}
|
|
||||||
color={themeCopy.syntax.comment}
|
|
||||||
defaultColor={defaultMonacoTheme.syntax.comment}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
</Paper>
|
|
||||||
<Paper sx={{ p: 1 }}>
|
|
||||||
<TextField
|
|
||||||
multiline
|
|
||||||
fullWidth
|
|
||||||
maxRows={10}
|
|
||||||
label={"import / export theme"}
|
|
||||||
value={JSON.stringify(themeCopy, undefined, 2)}
|
|
||||||
onChange={onThemeChange}
|
|
||||||
/>
|
|
||||||
<Box sx={{ mt: 1 }}>
|
|
||||||
<Button onClick={() => {
|
|
||||||
Settings.EditorTheme = { ...themeCopy };
|
|
||||||
props.onClose()
|
|
||||||
}} startIcon={<SaveIcon />}>Save</Button>
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
setThemeCopy(defaultMonacoTheme);
|
|
||||||
rerender();
|
|
||||||
}}
|
|
||||||
startIcon={<HistoryIcon />}
|
|
||||||
>Reset to default</Button>
|
|
||||||
</Box>
|
|
||||||
</Paper>
|
|
||||||
</Modal>
|
|
||||||
)
|
|
||||||
}
|
|
@ -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<void> {
|
export async function loadThemes(monaco: { editor: any }): Promise<void> {
|
||||||
monaco.editor.defineTheme("monokai", {
|
monaco.editor.defineTheme("monokai", {
|
||||||
base: "vs-dark",
|
base: "vs-dark",
|
||||||
|
@ -5,7 +5,6 @@ import { defaultStyles } from "../Themes/Styles";
|
|||||||
import { WordWrapOptions } from "../ScriptEditor/ui/Options";
|
import { WordWrapOptions } from "../ScriptEditor/ui/Options";
|
||||||
import { OverviewSettings } from "../ui/React/Overview";
|
import { OverviewSettings } from "../ui/React/Overview";
|
||||||
import { IStyleSettings } from "../ScriptEditor/NetscriptDefinitions";
|
import { IStyleSettings } from "../ScriptEditor/NetscriptDefinitions";
|
||||||
import { defaultMonacoTheme, IScriptEditorTheme } from "../ScriptEditor/ui/themes";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the default settings the player could customize.
|
* Represents the default settings the player could customize.
|
||||||
@ -158,11 +157,6 @@ interface IDefaultSettings {
|
|||||||
* If the game's sidebar is opened
|
* If the game's sidebar is opened
|
||||||
*/
|
*/
|
||||||
IsSidebarOpened: boolean;
|
IsSidebarOpened: boolean;
|
||||||
|
|
||||||
/**
|
|
||||||
* Script editor theme data
|
|
||||||
*/
|
|
||||||
EditorTheme: IScriptEditorTheme;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -222,8 +216,6 @@ export const defaultSettings: IDefaultSettings = {
|
|||||||
theme: defaultTheme,
|
theme: defaultTheme,
|
||||||
styles: defaultStyles,
|
styles: defaultStyles,
|
||||||
overview: { x: 0, y: 0, opened: true },
|
overview: { x: 0, y: 0, opened: true },
|
||||||
|
|
||||||
EditorTheme: defaultMonacoTheme,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -270,7 +262,6 @@ export const Settings: ISettings & ISelfInitializer & ISelfLoading = {
|
|||||||
theme: { ...defaultTheme },
|
theme: { ...defaultTheme },
|
||||||
styles: { ...defaultStyles },
|
styles: { ...defaultStyles },
|
||||||
overview: defaultSettings.overview,
|
overview: defaultSettings.overview,
|
||||||
EditorTheme: { ...defaultMonacoTheme },
|
|
||||||
init() {
|
init() {
|
||||||
Object.assign(Settings, defaultSettings);
|
Object.assign(Settings, defaultSettings);
|
||||||
},
|
},
|
||||||
@ -282,8 +273,6 @@ export const Settings: ISettings & ISelfInitializer & ISelfLoading = {
|
|||||||
delete save.styles;
|
delete save.styles;
|
||||||
Object.assign(Settings.overview, save.overview);
|
Object.assign(Settings.overview, save.overview);
|
||||||
delete save.overview;
|
delete save.overview;
|
||||||
Object.assign(Settings.EditorTheme, save.EditorTheme);
|
|
||||||
delete save.EditorTheme;
|
|
||||||
Object.assign(Settings, save);
|
Object.assign(Settings, save);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -366,9 +366,9 @@ export function ThemeEditorModal(props: IProps): React.ReactElement {
|
|||||||
sx={{ mb: 1 }}
|
sx={{ mb: 1 }}
|
||||||
multiline
|
multiline
|
||||||
fullWidth
|
fullWidth
|
||||||
maxRows={10}
|
maxRows={3}
|
||||||
label={"import / export theme"}
|
label={"import / export theme"}
|
||||||
value={JSON.stringify(customTheme, undefined, 2)}
|
value={JSON.stringify(customTheme)}
|
||||||
onChange={onThemeChange}
|
onChange={onThemeChange}
|
||||||
/>
|
/>
|
||||||
<>
|
<>
|
||||||
|
Loading…
Reference in New Issue
Block a user