Convert editors
This commit is contained in:
parent
001a50e762
commit
91341958d4
|
@ -1,91 +1,65 @@
|
||||||
import {React, Settings, Events, Strings} from "modules";
|
import {React, Settings, Events, Strings} from "modules";
|
||||||
|
|
||||||
import Editor from "./editor";
|
import Editor from "./editor";
|
||||||
// import Checkbox from "./checkbox";
|
|
||||||
import Refresh from "../icons/reload";
|
import Refresh from "../icons/reload";
|
||||||
import Save from "../icons/save";
|
import Save from "../icons/save";
|
||||||
import Edit from "../icons/edit";
|
import Edit from "../icons/edit";
|
||||||
import Detach from "../icons/detach";
|
import Detach from "../icons/detach";
|
||||||
|
|
||||||
export default class CssEditor extends React.Component {
|
const {useState, useCallback, useEffect, forwardRef, useImperativeHandle, useRef} = React;
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.hasUnsavedChanges = false;
|
export default forwardRef(function CssEditor({css, openNative, update, save, onChange: notifyParent, readOnly = false, id = "bd-customcss-editor", openDetached = false}, ref) {
|
||||||
|
const editorRef = useRef(null);
|
||||||
|
const [hasUnsavedChanges, setUnsaved] = useState(false);
|
||||||
|
|
||||||
this.onChange = this.onChange.bind(this);
|
const updateEditor = useCallback((newCSS) => {
|
||||||
this.toggleLiveUpdate = this.toggleLiveUpdate.bind(this);
|
editorRef.current.value = newCSS;
|
||||||
this.updateCss = this.updateCss.bind(this);
|
}, [editorRef]);
|
||||||
this.saveCss = this.saveCss.bind(this);
|
|
||||||
this.openDetached = this.props.openDetached ? this.openDetached.bind(this) : null;
|
|
||||||
this.openNative = this.openNative.bind(this);
|
|
||||||
this.updateEditor = this.updateEditor.bind(this);
|
|
||||||
|
|
||||||
this.controls = [
|
useImperativeHandle(ref, () => {
|
||||||
{label: React.createElement(Refresh, {size: "18px"}), tooltip: Strings.CustomCSS.update, onClick: this.updateCss},
|
return {
|
||||||
{label: React.createElement(Save, {size: "18px"}), tooltip: Strings.CustomCSS.save, onClick: this.saveCss},
|
resize() {editorRef.current.resize();},
|
||||||
{label: React.createElement(Edit, {size: "18px"}), tooltip: Strings.CustomCSS.openNative, onClick: this.openNative},
|
showSettings() {editorRef.current.showSettings();},
|
||||||
{label: Strings.Collections.settings.customcss.liveUpdate.name, type: "checkbox", onChange: this.toggleLiveUpdate, checked: Settings.get("settings", "customcss", "liveUpdate"), side: "right"}
|
get value() {return editorRef.current.getValue();},
|
||||||
];
|
set value(newValue) {editorRef.current.setValue(newValue);},
|
||||||
if (this.openDetached) this.controls.push({label: React.createElement(Detach, {size: "18px"}), tooltip: Strings.CustomCSS.openDetached, onClick: this.openDetached, side: "right"});
|
get hasUnsavedChanges() {return hasUnsavedChanges;}
|
||||||
}
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
componentDidMount() {
|
useEffect(() => {
|
||||||
Events.on("customcss-updated", this.updateEditor);
|
Events.on("customcss-updated", updateEditor);
|
||||||
}
|
return () => Events.off("customcss-updated", updateEditor);
|
||||||
|
});
|
||||||
|
|
||||||
componentWillUnmount() {
|
const toggleLiveUpdate = useCallback((checked) => Settings.set("settings", "customcss", "liveUpdate", checked), []);
|
||||||
Events.off("customcss-updated", this.updateEditor);
|
const updateCss = useCallback((event, newCSS) => update?.(newCSS), []);
|
||||||
}
|
const popoutNative = useCallback(() => openNative?.(), []);
|
||||||
|
const popout = useCallback((event, currentCSS) => openDetached?.(currentCSS), []);
|
||||||
|
|
||||||
updateEditor(newCSS) {
|
const onChange = useCallback((newCSS) => {
|
||||||
if (!this.editor) return;
|
notifyParent?.(newCSS);
|
||||||
this.editor.value = newCSS;
|
setUnsaved(true);
|
||||||
}
|
}, []);
|
||||||
|
|
||||||
get value() {return this.editor.session.getValue();}
|
const saveCss = useCallback((event, newCSS) => {
|
||||||
set value(newValue) {
|
save?.(newCSS);
|
||||||
this.editor.setValue(newValue);
|
setUnsaved(false);
|
||||||
}
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
showSettings() {return this.editor.keyBinding.$defaultHandler.commands.showSettingsMenu.exec(this.editor);}
|
return <Editor
|
||||||
resize() {return this.editor.resize();}
|
ref={editorRef}
|
||||||
|
readOnly={readOnly}
|
||||||
setEditorRef(editor) {
|
id={id}
|
||||||
this.editor = editor;
|
onChange={onChange}
|
||||||
if (this.props.editorRef && typeof(this.props.editorRef.current) !== "undefined") this.props.editorRef.current = editor;
|
controls={[
|
||||||
else if (this.props.editorRef) this.props.editorRef = editor;
|
{label: <Refresh size="18px" />, tooltip: Strings.CustomCSS.update, onClick: updateCss},
|
||||||
}
|
{label: <Save size="18px" />, tooltip: Strings.CustomCSS.save, onClick: saveCss},
|
||||||
|
{label: <Edit size="18px" />, tooltip: Strings.CustomCSS.openNative, onClick: popoutNative},
|
||||||
onChange() {
|
{label: Strings.Collections.settings.customcss.liveUpdate.name, type: "checkbox", onChange: toggleLiveUpdate, checked: Settings.get("settings", "customcss", "liveUpdate"), side: "right"},
|
||||||
this.hasUnsavedChanges = true;
|
openDetached && {label: <Detach size="18px" />, tooltip: Strings.CustomCSS.openDetached, onClick: popout, side: "right"}
|
||||||
if (this.props.onChange) this.props.onChange(...arguments);
|
].filter(c => c)}
|
||||||
}
|
value={css}
|
||||||
|
/>;
|
||||||
render() {
|
});
|
||||||
return <Editor ref={this.setEditorRef.bind(this)} readOnly={this.props.readOnly} id={this.props.id || "bd-customcss-editor"} onChange={this.onChange} controls={this.controls} value={this.props.css} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleLiveUpdate(checked) {
|
|
||||||
Settings.set("settings", "customcss", "liveUpdate", checked);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateCss(event, newCss) {
|
|
||||||
if (this.props.update) this.props.update(newCss);
|
|
||||||
}
|
|
||||||
|
|
||||||
saveCss(event, newCss) {
|
|
||||||
this.hasUnsavedChanges = false;
|
|
||||||
if (this.props.save) this.props.save(newCss);
|
|
||||||
}
|
|
||||||
|
|
||||||
openDetached(event, currentCSS) {
|
|
||||||
if (!this.props.openDetached) return;
|
|
||||||
this.props.openDetached(currentCSS);
|
|
||||||
}
|
|
||||||
|
|
||||||
openNative() {
|
|
||||||
if (this.props.openNative) this.props.openNative();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,41 +2,76 @@ import {React, DiscordModules, Settings} from "modules";
|
||||||
|
|
||||||
import Checkbox from "./checkbox";
|
import Checkbox from "./checkbox";
|
||||||
|
|
||||||
|
const {useState, useCallback, useEffect, forwardRef, useMemo, useImperativeHandle} = React;
|
||||||
const ThemeStore = DiscordModules.ThemeStore;
|
const ThemeStore = DiscordModules.ThemeStore;
|
||||||
|
|
||||||
|
|
||||||
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"];
|
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 {
|
function makeButton(button, value) {
|
||||||
static get defaultId() {return "bd-editor";}
|
return <DiscordModules.Tooltip color="primary" position="top" text={button.tooltip}>
|
||||||
|
{props => {
|
||||||
|
return <button {...props} className="btn btn-primary" onClick={(event) => {button.onClick(event, value?.());}}>{button.label}</button>;
|
||||||
|
}}
|
||||||
|
</DiscordModules.Tooltip>;
|
||||||
|
}
|
||||||
|
|
||||||
constructor(props) {
|
function makeCheckbox(checkbox) {
|
||||||
super(props);
|
return <Checkbox text={checkbox.label} onChange={checkbox.onChange} checked={checkbox.checked} />;
|
||||||
|
}
|
||||||
|
|
||||||
this.props.theme = ThemeStore?.theme === "light" ? "vs" : "vs-dark";
|
function buildControl(value, control) {
|
||||||
|
if (control.type == "checkbox") return makeCheckbox(control);
|
||||||
|
return makeButton(control, value);
|
||||||
|
}
|
||||||
|
|
||||||
this.props.language = this.props.language.toLowerCase().replace(/ /g, "_");
|
export default forwardRef(function CodeEditor({value, language: requestedLang = "css", id = "bd-editor", controls = [], onChange: notifyParent}, ref) {
|
||||||
if (!languages.includes(this.props.language)) this.props.language = CodeEditor.defaultProps.language;
|
const language = useMemo(() => {
|
||||||
|
const requested = requestedLang.toLowerCase().replace(/ /g, "_");
|
||||||
|
if (!languages.includes(requested)) return "css";
|
||||||
|
return requested;
|
||||||
|
}, [requestedLang]);
|
||||||
|
|
||||||
this.bindings = [];
|
const [theme, setTheme] = useState(() => ThemeStore?.theme === "light" ? "vs" : "vs-dark");
|
||||||
this.resize = this.resize.bind(this);
|
const [editor, setEditor] = useState(null);
|
||||||
this.onChange = this.onChange.bind(this);
|
const [bindings, setBindings] = useState([]);
|
||||||
this.onThemeChange = this.onThemeChange.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
static get defaultProps() {
|
const onThemeChange = useCallback(() => {
|
||||||
|
const newTheme = ThemeStore?.theme === "light" ? "vs" : "vs-dark";
|
||||||
|
if (newTheme === theme) return;
|
||||||
|
if (window.monaco?.editor) window.monaco.editor.setTheme(newTheme);
|
||||||
|
setTheme(newTheme);
|
||||||
|
}, [theme]);
|
||||||
|
|
||||||
|
const onChange = useCallback(() => {
|
||||||
|
notifyParent?.(editor?.getValue());
|
||||||
|
}, [editor]);
|
||||||
|
const resize = useCallback(() => editor.layout(), [editor]);
|
||||||
|
const showSettings = useCallback(() => editor.keyBinding.$defaultHandler.commands.showSettingsMenu.exec(editor), [editor]);
|
||||||
|
|
||||||
|
useImperativeHandle(ref, () => {
|
||||||
return {
|
return {
|
||||||
controls: [],
|
resize,
|
||||||
language: "css",
|
showSettings,
|
||||||
id: this.defaultId
|
get value() {return editor.getValue();},
|
||||||
|
set value(newValue) {editor.setValue(newValue);}
|
||||||
};
|
};
|
||||||
}
|
}, [editor]);
|
||||||
|
|
||||||
componentDidMount() {
|
useEffect(() => {
|
||||||
|
setBindings([...bindings, editor?.onDidChangeModelContent(onChange)]);
|
||||||
|
return () => {
|
||||||
|
for (const binding of bindings) binding?.dispose();
|
||||||
|
setBindings([]);
|
||||||
|
};
|
||||||
|
}, [editor]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
if (window.monaco?.editor) {
|
if (window.monaco?.editor) {
|
||||||
this.editor = window.monaco.editor.create(document.getElementById(this.props.id), {
|
const monacoEditor = window.monaco.editor.create(document.getElementById(id), {
|
||||||
value: this.props.value,
|
value: value,
|
||||||
language: this.props.language,
|
language: language,
|
||||||
theme: ThemeStore?.theme == "light" ? "vs" : "vs-dark",
|
theme: theme,
|
||||||
fontSize: Settings.get("settings", "editor", "fontSize"),
|
fontSize: Settings.get("settings", "editor", "fontSize"),
|
||||||
lineNumbers: Settings.get("settings", "editor", "lineNumbers"),
|
lineNumbers: Settings.get("settings", "editor", "lineNumbers"),
|
||||||
minimap: {enabled: Settings.get("settings", "editor", "minimap")},
|
minimap: {enabled: Settings.get("settings", "editor", "minimap")},
|
||||||
|
@ -49,89 +84,53 @@ export default class CodeEditor extends React.Component {
|
||||||
renderWhitespace: Settings.get("settings", "editor", "renderWhitespace")
|
renderWhitespace: Settings.get("settings", "editor", "renderWhitespace")
|
||||||
});
|
});
|
||||||
|
|
||||||
this.bindings.push(this.editor.onDidChangeModelContent(this.onChange));
|
setEditor(monacoEditor);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
const textarea = document.createElement("textarea");
|
const textarea = document.createElement("textarea");
|
||||||
textarea.className = "bd-fallback-editor";
|
textarea.className = "bd-fallback-editor";
|
||||||
textarea.value = this.props.value;
|
textarea.value = value;
|
||||||
textarea.onchange = (e) => this.onChange(e.target.value);
|
textarea.onchange = (e) => onChange(e.target.value);
|
||||||
textarea.oninput = (e) => this.onChange(e.target.value);
|
textarea.oninput = (e) => onChange(e.target.value);
|
||||||
|
|
||||||
this.editor = {
|
setEditor({
|
||||||
dispose: () => textarea.remove(),
|
dispose: () => textarea.remove(),
|
||||||
getValue: () => textarea.value,
|
getValue: () => textarea.value,
|
||||||
setValue: (value) => textarea.value = value,
|
setValue: (val) => textarea.value = val,
|
||||||
layout: () => {},
|
layout: () => {},
|
||||||
};
|
});
|
||||||
|
|
||||||
document.getElementById(this.props.id).appendChild(textarea);
|
document.getElementById(id).appendChild(textarea);
|
||||||
}
|
}
|
||||||
|
|
||||||
ThemeStore?.addChangeListener?.(this.onThemeChange);
|
ThemeStore?.addChangeListener?.(onThemeChange);
|
||||||
window.addEventListener("resize", this.resize);
|
window.addEventListener("resize", resize);
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
return () => {
|
||||||
window.removeEventListener("resize", this.resize);
|
window.removeEventListener("resize", resize);
|
||||||
ThemeStore?.removeChangeListener?.(this.onThemeChange);
|
ThemeStore?.removeChangeListener?.(onThemeChange);
|
||||||
for (const binding of this.bindings) binding.dispose();
|
editor?.dispose();
|
||||||
this.editor.dispose();
|
};
|
||||||
}
|
}, []);
|
||||||
|
|
||||||
onThemeChange() {
|
|
||||||
const newTheme = ThemeStore?.theme === "light" ? "vs" : "vs-dark";
|
|
||||||
if (newTheme === this.props.theme) return;
|
|
||||||
this.props.theme = newTheme;
|
|
||||||
if (window.monaco?.editor) window.monaco.editor.setTheme(this.props.theme);
|
|
||||||
}
|
|
||||||
|
|
||||||
get value() {return this.editor.getValue();}
|
if (editor && editor.layout) editor.layout();
|
||||||
set value(newValue) {this.editor.setValue(newValue);}
|
|
||||||
|
|
||||||
onChange() {
|
const controlsLeft = controls.filter(c => c.side != "right").map(buildControl.bind(null, () => editor?.getValue()));
|
||||||
if (this.props.onChange) this.props.onChange(this.value);
|
const controlsRight = controls.filter(c => c.side == "right").map(buildControl.bind(null, () => editor?.getValue()));
|
||||||
}
|
|
||||||
|
|
||||||
showSettings() {return this.editor.keyBinding.$defaultHandler.commands.showSettingsMenu.exec(this.editor);}
|
return <div id="bd-editor-panel" className={theme}>
|
||||||
resize() {this.editor.layout();}
|
<div id="bd-editor-controls">
|
||||||
|
<div className="controls-section controls-left">
|
||||||
buildControl(control) {
|
{controlsLeft}
|
||||||
if (control.type == "checkbox") return this.makeCheckbox(control);
|
|
||||||
return this.makeButton(control);
|
|
||||||
}
|
|
||||||
|
|
||||||
makeCheckbox(checkbox) {
|
|
||||||
return <Checkbox text={checkbox.label} onChange={checkbox.onChange} checked={checkbox.checked} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
makeButton(button) {
|
|
||||||
return <DiscordModules.Tooltip color="primary" position="top" text={button.tooltip}>
|
|
||||||
{props => {
|
|
||||||
return <button {...props} className="btn btn-primary" onClick={(event) => {button.onClick(event, this.value);}}>{button.label}</button>;
|
|
||||||
}}
|
|
||||||
</DiscordModules.Tooltip>;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
if (this.editor && this.editor.layout) this.editor.layout();
|
|
||||||
|
|
||||||
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}>
|
|
||||||
<div id="bd-editor-controls">
|
|
||||||
<div className="controls-section controls-left">
|
|
||||||
{controlsLeft}
|
|
||||||
</div>
|
|
||||||
<div className="controls-section controls-right">
|
|
||||||
{controlsRight}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="editor-wrapper">
|
<div className="controls-section controls-right">
|
||||||
<div id={this.props.id} className={"editor " + this.props.theme}></div>
|
{controlsRight}
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>
|
||||||
}
|
<div className="editor-wrapper">
|
||||||
}
|
<div id={id} className={"editor " + theme}></div>
|
||||||
|
</div>
|
||||||
|
</div>;
|
||||||
|
});
|
|
@ -4,60 +4,39 @@ import Editor from "../customcss/editor";
|
||||||
import Save from "../icons/save";
|
import Save from "../icons/save";
|
||||||
import Edit from "../icons/edit";
|
import Edit from "../icons/edit";
|
||||||
|
|
||||||
export default class AddonEditor extends React.Component {
|
const {useState, useCallback, forwardRef, useImperativeHandle, useRef} = React;
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.hasUnsavedChanges = false;
|
export default forwardRef(function AddonEditor({content, language, save, openNative, id = "bd-addon-editor"}, ref) {
|
||||||
this.onChange = this.onChange.bind(this);
|
const editorRef = useRef(null);
|
||||||
this.save = this.save.bind(this);
|
const [hasUnsavedChanges, setUnsaved] = useState(false);
|
||||||
this.openNative = this.openNative.bind(this);
|
|
||||||
this.update = this.update.bind(this);
|
|
||||||
|
|
||||||
this.controls = [
|
useImperativeHandle(ref, () => {
|
||||||
{label: React.createElement(Save, {size: "18px"}), tooltip: Strings.CustomCSS.save, onClick: this.save},
|
return {
|
||||||
{label: React.createElement(Edit, {size: "18px"}), tooltip: Strings.CustomCSS.openNative, onClick: this.openNative}
|
resize() {editorRef.current.resize();},
|
||||||
];
|
showSettings() {editorRef.current.showSettings();},
|
||||||
}
|
get value() {return editorRef.current.getValue();},
|
||||||
|
set value(newValue) {editorRef.current.setValue(newValue);},
|
||||||
|
get hasUnsavedChanges() {return hasUnsavedChanges;}
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
update() {
|
const popoutNative = useCallback(() => openNative?.(), []);
|
||||||
this.forceUpdate();
|
const onChange = useCallback(() => setUnsaved(true), []);
|
||||||
}
|
const saveAddon = useCallback((event, newCSS) => {
|
||||||
|
save?.(newCSS);
|
||||||
|
setUnsaved(false);
|
||||||
|
}, []);
|
||||||
|
|
||||||
updateEditor(newCSS) {
|
return <Editor
|
||||||
if (!this.editor) return;
|
ref={editorRef}
|
||||||
this.editor.value = newCSS;
|
language={language}
|
||||||
}
|
id={id}
|
||||||
|
controls={[
|
||||||
get value() {return this.editor.session.getValue();}
|
{label: <Save size="18px" />, tooltip: Strings.CustomCSS.save, onClick: saveAddon},
|
||||||
set value(newValue) {
|
{label: <Edit size="18px" />, tooltip: Strings.CustomCSS.openNative, onClick: popoutNative}
|
||||||
this.editor.setValue(newValue);
|
]}
|
||||||
}
|
value={content}
|
||||||
|
onChange={onChange}
|
||||||
showSettings() {return this.editor.keyBinding.$defaultHandler.commands.showSettingsMenu.exec(this.editor);}
|
/>;
|
||||||
resize() {return this.editor.resize();}
|
});
|
||||||
|
|
||||||
setEditorRef(editor) {
|
|
||||||
this.editor = editor;
|
|
||||||
if (this.props.editorRef && typeof(this.props.editorRef.current) !== "undefined") this.props.editorRef.current = editor;
|
|
||||||
else if (this.props.editorRef) this.props.editorRef = editor;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return <Editor ref={this.setEditorRef.bind(this)} language={this.props.language} id={this.props.id || "bd-addon-editor"} controls={this.controls} value={this.props.content} onChange={this.onChange} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
onChange() {
|
|
||||||
this.hasUnsavedChanges = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
save(event, content) {
|
|
||||||
this.hasUnsavedChanges = false;
|
|
||||||
if (this.props.save) this.props.save(content);
|
|
||||||
}
|
|
||||||
|
|
||||||
openNative() {
|
|
||||||
if (this.props.openNative) this.props.openNative();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,3 @@
|
||||||
import Logger from "common/logger";
|
|
||||||
import {React, Strings, Events, DataStore, DiscordModules} from "modules";
|
import {React, Strings, Events, DataStore, DiscordModules} from "modules";
|
||||||
|
|
||||||
import Modals from "../modals";
|
import Modals from "../modals";
|
||||||
|
|
Loading…
Reference in New Issue