BetterDiscordApp-rauenzi/renderer/src/ui/customcss/editor.jsx

117 lines
6.1 KiB
React
Raw Normal View History

2022-02-05 09:35:07 +01:00
import {React, WebpackModules, DiscordModules, Settings} from "modules";
2019-06-10 22:37:50 +02:00
import Checkbox from "./checkbox";
2019-06-15 04:11:19 +02:00
const Tooltip = WebpackModules.getByDisplayName("Tooltip");
2019-06-12 06:28:18 +02:00
const languages = ["abap", "abc", "actionscript", "ada", "apache_conf", "asciidoc", "assembly_x86", "autohotkey", "batchfile", "bro", "c_cpp", "c9search", "cirru", "clojure", "cobol", "coffee", "coldfusion", "csharp", "csound_document", "csound_orchestra", "csound_score", "css", "curly", "d", "dart", "diff", "dockerfile", "dot", "drools", "dummy", "dummysyntax", "eiffel", "ejs", "elixir", "elm", "erlang", "forth", "fortran", "ftl", "gcode", "gherkin", "gitignore", "glsl", "gobstones", "golang", "graphqlschema", "groovy", "haml", "handlebars", "haskell", "haskell_cabal", "haxe", "hjson", "html", "html_elixir", "html_ruby", "ini", "io", "jack", "jade", "java", "javascript", "json", "jsoniq", "jsp", "jssm", "jsx", "julia", "kotlin", "latex", "less", "liquid", "lisp", "livescript", "logiql", "lsl", "lua", "luapage", "lucene", "makefile", "markdown", "mask", "matlab", "maze", "mel", "mushcode", "mysql", "nix", "nsis", "objectivec", "ocaml", "pascal", "perl", "pgsql", "php", "pig", "powershell", "praat", "prolog", "properties", "protobuf", "python", "r", "razor", "rdoc", "red", "rhtml", "rst", "ruby", "rust", "sass", "scad", "scala", "scheme", "scss", "sh", "sjs", "smarty", "snippets", "soy_template", "space", "sql", "sqlserver", "stylus", "svg", "swift", "tcl", "tex", "text", "textile", "toml", "tsx", "twig", "typescript", "vala", "vbscript", "velocity", "verilog", "vhdl", "wollok", "xml", "xquery", "yaml", "django"];
export default class CodeEditor extends React.Component {
static get defaultId() {return "bd-editor";}
2019-06-10 22:37:50 +02:00
constructor(props) {
super(props);
2019-06-12 06:28:18 +02:00
2020-11-05 00:04:44 +01:00
this.props.theme = DiscordModules.UserSettingsStore && DiscordModules.UserSettingsStore.theme === "light" ? "vs" : "vs-dark";
2019-06-10 22:37:50 +02:00
2019-06-12 06:28:18 +02:00
this.props.language = this.props.language.toLowerCase().replace(/ /g, "_");
2019-06-15 04:11:19 +02:00
if (!languages.includes(this.props.language)) this.props.language = CodeEditor.defaultProps.language;
this.bindings = [];
2020-11-05 00:04:44 +01:00
this.resize = this.resize.bind(this);
2019-06-15 04:11:19 +02:00
this.onChange = this.onChange.bind(this);
2020-11-05 00:04:44 +01:00
this.onThemeChange = this.onThemeChange.bind(this);
2019-06-12 06:28:18 +02:00
}
static get defaultProps() {
return {
2019-06-15 04:11:19 +02:00
controls: [],
2019-06-12 06:28:18 +02:00
language: "css",
2020-11-05 00:04:44 +01:00
id: this.defaultId
2019-06-12 06:28:18 +02:00
};
2019-06-10 22:37:50 +02:00
}
componentDidMount() {
this.editor = window.monaco.editor.create(document.getElementById(this.props.id), {
value: this.props.value,
language: this.props.language,
2022-02-05 09:35:07 +01:00
theme: DiscordModules.UserSettingsStore.theme == "light" ? "vs" : "vs-dark",
fontSize: Settings.get("settings", "editor", "fontSize"),
lineNumbers: Settings.get("settings", "editor", "lineNumbers"),
minimap: {enabled: Settings.get("settings", "editor", "minimap")},
2022-02-06 00:13:38 +01:00
hover: {enabled: Settings.get("settings", "editor", "hover")},
quickSuggestions: {
other: Settings.get("settings", "editor", "quickSuggestions"),
comments: Settings.get("settings", "editor", "quickSuggestions"),
strings: Settings.get("settings", "editor", "quickSuggestions")
},
2022-02-05 09:35:07 +01:00
renderWhitespace: Settings.get("settings", "editor", "renderWhitespace")
});
2019-06-10 22:37:50 +02:00
2020-11-05 00:04:44 +01:00
window.addEventListener("resize", this.resize);
if (DiscordModules.UserSettingsStore) DiscordModules.UserSettingsStore.addChangeListener(this.onThemeChange);
this.bindings.push(this.editor.onDidChangeModelContent(this.onChange));
2019-06-10 22:37:50 +02:00
}
componentWillUnmount() {
2020-11-05 00:04:44 +01:00
window.removeEventListener("resize", this.resize);
if (DiscordModules.UserSettingsStore) DiscordModules.UserSettingsStore.removeChangeListener(this.onThemeChange);
for (const binding of this.bindings) binding.dispose();
this.editor.dispose();
2019-06-10 22:37:50 +02:00
}
2020-11-05 00:04:44 +01:00
onThemeChange() {
const newTheme = DiscordModules.UserSettingsStore.theme === "light" ? "vs" : "vs-dark";
if (newTheme === this.props.theme) return;
this.props.theme = newTheme;
window.monaco.editor.setTheme(this.props.theme);
}
get value() {return this.editor.getValue();}
set value(newValue) {this.editor.setValue(newValue);}
2019-06-15 04:11:19 +02:00
onChange() {
if (this.props.onChange) this.props.onChange(this.value);
}
2019-06-10 22:37:50 +02:00
2019-06-12 06:28:18 +02:00
showSettings() {return this.editor.keyBinding.$defaultHandler.commands.showSettingsMenu.exec(this.editor);}
2020-11-05 00:04:44 +01:00
resize() {this.editor.layout();}
2019-06-10 22:37:50 +02:00
2019-06-15 04:11:19 +02:00
buildControl(control) {
if (control.type == "checkbox") return this.makeCheckbox(control);
return this.makeButton(control);
}
2019-06-10 22:37:50 +02:00
2019-06-15 04:11:19 +02:00
makeCheckbox(checkbox) {
return <Checkbox text={checkbox.label} onChange={checkbox.onChange} checked={checkbox.checked} />;
}
2019-06-10 22:37:50 +02:00
2019-06-15 04:11:19 +02:00
makeButton(button) {
return <Tooltip color="primary" position="top" text={button.tooltip}>
2019-06-15 04:11:19 +02:00
{props => {
return <button {...props} className="btn btn-primary" onClick={(event) => {button.onClick(event, this.value);}}>{button.label}</button>;
}}
</Tooltip>;
}
2019-06-10 22:37:50 +02:00
2019-06-15 04:11:19 +02:00
render() {
2020-11-05 00:04:44 +01:00
if (this.editor && this.editor.layout) this.editor.layout();
2019-06-15 04:11:19 +02:00
const controlsLeft = this.props.controls.filter(c => c.side != "right").map(this.buildControl.bind(this));
const controlsRight = this.props.controls.filter(c => c.side == "right").map(this.buildControl.bind(this));
return <div id="bd-editor-panel" className={this.props.theme}>
2019-06-12 06:28:18 +02:00
<div id="bd-editor-controls">
2019-06-15 04:11:19 +02:00
<div className="controls-section controls-left">
{controlsLeft}
</div>
<div className="controls-section controls-right">
{controlsRight}
2019-06-12 06:28:18 +02:00
</div>
2019-06-15 04:11:19 +02:00
</div>
<div className="editor-wrapper">
<div id={this.props.id} className={"editor " + this.props.theme}></div>
2019-06-12 06:28:18 +02:00
</div>
</div>;
2019-06-10 22:37:50 +02:00
}
}