mirror of
https://github.com/go-gost/gost-ui.git
synced 2024-08-11 17:53:29 +00:00
monaco-editor 加载优化
This commit is contained in:
+6
-2
@@ -6,8 +6,12 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<script src="%VITE_MONACO_URL%/min/vs/loader.js"></script>
|
||||
<!-- <script src="//unpkg.com/monaco-editor@0.47.0/min/vs/loader.js"></script> -->
|
||||
<script id="nonaco" src="%VITE_MONACO_URL%/min/vs/loader.js"></script>
|
||||
<script>
|
||||
(function(){
|
||||
require.config({ paths: { vs: document.getElementById("nonaco").src.replace(/\/loader\.js/,'') } });
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
Generated
-1
@@ -7,7 +7,6 @@
|
||||
"": {
|
||||
"name": "gost-ui",
|
||||
"version": "0.0.0",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.2.6",
|
||||
"antd": "^5.11.0",
|
||||
|
||||
+1
-4
@@ -10,10 +10,7 @@
|
||||
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
||||
"preview": "vite preview",
|
||||
"init:monaco": "cpx ./node_modules/monaco-editor/min/** ./public/monaco-editor/min",
|
||||
"postinstall": "npm run init:monaco",
|
||||
"predev": "npm run init:monaco",
|
||||
"prebuild": "npm run init:monaco",
|
||||
"preanalyzer": "npm run init:monaco"
|
||||
"prebuild": "npm run init:monaco"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.2.6",
|
||||
|
||||
@@ -14,6 +14,8 @@ body {
|
||||
|
||||
.g-boder {
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:root.theme-dark {
|
||||
|
||||
+7
-5
@@ -105,12 +105,14 @@ function App() {
|
||||
}
|
||||
}, [info]);
|
||||
useEffect(() => {
|
||||
if(isDark){
|
||||
document.documentElement.classList.add("theme-dark")
|
||||
}else{
|
||||
document.documentElement.classList.remove("theme-dark")
|
||||
if (isDark) {
|
||||
document.documentElement.classList.add("theme-dark");
|
||||
(window as any)?.monaco?.editor.setTheme("vs-dark");
|
||||
} else {
|
||||
document.documentElement.classList.remove("theme-dark");
|
||||
(window as any)?.monaco?.editor.setTheme("vs");
|
||||
}
|
||||
},[isDark])
|
||||
}, [isDark]);
|
||||
return (
|
||||
<Ctx.Provider
|
||||
value={{
|
||||
|
||||
+69
-71
@@ -141,14 +141,12 @@ const Manage = () => {
|
||||
key: "new",
|
||||
label: "打开新链接",
|
||||
onClick: () => {
|
||||
console.log(location.href);
|
||||
window.open(location.href, undefined, "noopener");
|
||||
},
|
||||
});
|
||||
return items;
|
||||
}, [locals]);
|
||||
|
||||
console.log("gostInfo", info);
|
||||
return (
|
||||
<Layout style={{ height: "100vh", overflow: "hidden" }}>
|
||||
<Layout.Header style={{ color: "#FFF", paddingInline: 20 }}>
|
||||
@@ -215,7 +213,6 @@ const Manage = () => {
|
||||
layout="horizontal"
|
||||
labelCol={{ span: 4 }}
|
||||
onValuesChange={(v, vs) => {
|
||||
console.log(v, vs);
|
||||
Object.assign(info, v);
|
||||
useInfo.set(info);
|
||||
if (info.isLocal) {
|
||||
@@ -238,74 +235,75 @@ const Manage = () => {
|
||||
</Form>
|
||||
</Modal>
|
||||
</Layout.Header>
|
||||
<Layout.Content style={{ height: "100%", overflow: "auto" }}>
|
||||
<Row style={{ padding: 16, overflow: "hidden" }}>
|
||||
<Row gutter={[16, 16]}>
|
||||
{/* <Col {...colSpan} xxl={16}> */}
|
||||
<ServiceCard colSpan={colSpan}></ServiceCard>
|
||||
{/* </Col> */}
|
||||
<Col {...colSpan}>
|
||||
<ChainCard></ChainCard>
|
||||
</Col>
|
||||
<Col {...colSpan}>
|
||||
<HopsCard />
|
||||
</Col>
|
||||
<Col {...colSpan}>
|
||||
<ListCard module="auther" />
|
||||
</Col>
|
||||
<Col {...colSpan}>
|
||||
<ListCard module="admission" />
|
||||
</Col>
|
||||
<Col {...colSpan}>
|
||||
<ListCard module="bypass" />
|
||||
</Col>
|
||||
<Col {...colSpan}>
|
||||
<ListCard module="host" />
|
||||
</Col>
|
||||
<Col {...colSpan}>
|
||||
<ListCard module="ingress" />
|
||||
</Col>
|
||||
<Col {...colSpan}>
|
||||
<ListCard module="resolver" />
|
||||
</Col>
|
||||
<Col {...colSpan}>
|
||||
<ListCard module="sd" />
|
||||
</Col>
|
||||
<Col {...colSpan}>
|
||||
<ListCard module="observer" />
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<ProCard boxShadow title="限速限流">
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col {...colSpan1}>
|
||||
<ListCard module="limiter" bordered boxShadow={false} />
|
||||
</Col>
|
||||
<Col {...colSpan1}>
|
||||
<ListCard module="rlimiter" bordered boxShadow={false} />
|
||||
</Col>
|
||||
<Col {...colSpan1}>
|
||||
<ListCard module="climiter" bordered boxShadow={false} />
|
||||
</Col>
|
||||
</Row>
|
||||
</ProCard>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<ProCard boxShadow title="All Config JSON">
|
||||
{/* <pre>{jsonFormat(gostConfig!)}</pre> */}
|
||||
<CodeEditor
|
||||
className={"g-boder"}
|
||||
value={jsonFormat(gostConfig!)}
|
||||
height={500}
|
||||
language="json"
|
||||
options={{
|
||||
// selectOnLineNumbers: true,
|
||||
minimap: { enabled: false },
|
||||
readOnly: true,
|
||||
}}
|
||||
></CodeEditor>
|
||||
</ProCard>
|
||||
</Col>
|
||||
</Row>
|
||||
<Layout.Content style={{ height: "100%", padding: 16, boxSizing:'border-box', overflow: "auto" }}>
|
||||
<Row gutter={[16, 16]} style={{ overflow: "hidden" }}>
|
||||
{/* <Col {...colSpan} xxl={16}> */}
|
||||
<ServiceCard colSpan={colSpan}></ServiceCard>
|
||||
{/* </Col> */}
|
||||
<Col {...colSpan}>
|
||||
<ChainCard></ChainCard>
|
||||
</Col>
|
||||
<Col {...colSpan}>
|
||||
<HopsCard />
|
||||
</Col>
|
||||
<Col {...colSpan}>
|
||||
<ListCard module="auther" />
|
||||
</Col>
|
||||
<Col {...colSpan}>
|
||||
<ListCard module="admission" />
|
||||
</Col>
|
||||
<Col {...colSpan}>
|
||||
<ListCard module="bypass" />
|
||||
</Col>
|
||||
<Col {...colSpan}>
|
||||
<ListCard module="host" />
|
||||
</Col>
|
||||
<Col {...colSpan}>
|
||||
<ListCard module="ingress" />
|
||||
</Col>
|
||||
<Col {...colSpan}>
|
||||
<ListCard module="resolver" />
|
||||
</Col>
|
||||
<Col {...colSpan}>
|
||||
<ListCard module="sd" />
|
||||
</Col>
|
||||
<Col {...colSpan}>
|
||||
<ListCard module="observer" />
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<ProCard boxShadow title="限速限流">
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col {...colSpan1}>
|
||||
<ListCard module="limiter" bordered boxShadow={false} />
|
||||
</Col>
|
||||
<Col {...colSpan1}>
|
||||
<ListCard module="rlimiter" bordered boxShadow={false} />
|
||||
</Col>
|
||||
<Col {...colSpan1}>
|
||||
<ListCard module="climiter" bordered boxShadow={false} />
|
||||
</Col>
|
||||
</Row>
|
||||
</ProCard>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<ProCard
|
||||
boxShadow
|
||||
title="All Config JSON"
|
||||
styles={{ body: { padding: 20 } }}
|
||||
>
|
||||
<CodeEditor
|
||||
className={"g-boder"}
|
||||
value={jsonFormat(gostConfig!)}
|
||||
height={500}
|
||||
language="json"
|
||||
options={{
|
||||
// selectOnLineNumbers: true,
|
||||
minimap: { enabled: false },
|
||||
readOnly: true,
|
||||
}}
|
||||
></CodeEditor>
|
||||
</ProCard>
|
||||
</Col>
|
||||
</Row>
|
||||
</Layout.Content>
|
||||
</Layout>
|
||||
|
||||
@@ -213,7 +213,6 @@ export const showJsonForm = (props: JsonFromProps) => {
|
||||
}
|
||||
|
||||
function destroy() {
|
||||
console.log("destroy");
|
||||
root.unmount();
|
||||
document.body.removeChild(container);
|
||||
}
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ export const jsonParse = (str: string) => {
|
||||
const errs: any[] = [];
|
||||
const obj = parse(str, errs, { allowTrailingComma: true });
|
||||
if (errs.length) {
|
||||
console.log(errs);
|
||||
console.error(errs);
|
||||
throw errs[0];
|
||||
}
|
||||
return obj;
|
||||
|
||||
+116
-96
@@ -3,37 +3,41 @@ import { useBindValue } from "./use";
|
||||
import type * as Monaco from "monaco-editor";
|
||||
import classnames from "classnames";
|
||||
import { useIsDark } from "./useTheme";
|
||||
import { Input } from "antd";
|
||||
|
||||
(function () {
|
||||
const require = (window as any).require;
|
||||
let monacoURL;
|
||||
const MONACO_URL = import.meta.env.VITE_MONACO_URL || '/monaco-editor';
|
||||
if(/^(http[s]:)?\/\//.test(MONACO_URL)){
|
||||
monacoURL = MONACO_URL + '/min/vs'
|
||||
}else{
|
||||
const baseURL = new URL(import.meta.env.BASE_URL, location.href).href;
|
||||
monacoURL = new URL(`${MONACO_URL}/min/vs`, baseURL).href;
|
||||
}
|
||||
|
||||
// let monacoURL;
|
||||
// const MONACO_URL = import.meta.env.VITE_MONACO_URL || '/monaco-editor';
|
||||
// if(/^(http[s]:)?\/\//.test(MONACO_URL)){
|
||||
// monacoURL = MONACO_URL + '/min/vs'
|
||||
// }else{
|
||||
// const baseURL = new URL(import.meta.env.BASE_URL, location.href).href;
|
||||
// monacoURL = new URL(`${MONACO_URL}/min/vs`, baseURL).href;
|
||||
// }
|
||||
|
||||
// if(import.meta.env.PROD && import.meta.env.VITE_MONACO_URL){
|
||||
// monacoURL = import.meta.env.VITE_MONACO_URL + '/min/vs';
|
||||
// }else{
|
||||
// const baseURL = new URL(import.meta.env.BASE_URL, location.href).href;
|
||||
// monacoURL = new URL("./monaco-editor/min/vs", baseURL).href;
|
||||
// }
|
||||
|
||||
|
||||
// console.log(`import_meta_env_BASE_URL`, import.meta.env.BASE_URL);
|
||||
// console.log("baseURL", baseURL);
|
||||
// const monacoURL = `//unpkg.com/monaco-editor@0.47.0/min/vs`
|
||||
require.config({ paths: { vs: `${monacoURL}` } });
|
||||
require.config({
|
||||
"vs/nls": {
|
||||
availableLanguages: {
|
||||
"*": "zh-cn",
|
||||
// require.config({ paths: { vs: `${monacoURL}` } });
|
||||
if (require) {
|
||||
require.config({
|
||||
"vs/nls": {
|
||||
availableLanguages: {
|
||||
"*": "zh-cn",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
(window as any).monacoIsReady = new Promise((resolve, reject) => {
|
||||
if (!require) return reject("Not loaded monaco loader.js");
|
||||
require(["vs/editor/editor.main"], function () {
|
||||
resolve(monaco);
|
||||
});
|
||||
@@ -79,10 +83,10 @@ const CodeEditor_: React.ForwardRefRenderFunction<
|
||||
const editor = useRef<any>(null);
|
||||
const self = useRef<any>({});
|
||||
const isDark = useIsDark();
|
||||
const _theme = useMemo(()=>{
|
||||
if(theme) return theme;
|
||||
return isDark ? 'vs-dark' : 'vs'
|
||||
},[theme, isDark])
|
||||
const _theme = useMemo(() => {
|
||||
if (theme) return theme;
|
||||
return isDark ? "vs-dark" : "vs";
|
||||
}, [theme, isDark]);
|
||||
|
||||
React.useImperativeHandle(ref, () => {
|
||||
return editor.current!;
|
||||
@@ -97,82 +101,87 @@ const CodeEditor_: React.ForwardRefRenderFunction<
|
||||
},
|
||||
[onChange]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
// let editor: any;
|
||||
if (divEl.current) {
|
||||
const el = divEl.current;
|
||||
let _editor: Monaco.editor.IStandaloneCodeEditor;
|
||||
monacoIsReady.then(() => {
|
||||
_editor = editor.current = monaco.editor.create(el, {
|
||||
value: value,
|
||||
language: language,
|
||||
theme: _theme,
|
||||
...defOptions,
|
||||
...options,
|
||||
});
|
||||
console.log("editor.current", editor.current.getDomNode());
|
||||
_editor.onDidChangeModelContent(function (event: any) {
|
||||
const _value = _editor.getValue();
|
||||
setValue(_value);
|
||||
self.current?.onChange?.(_value);
|
||||
});
|
||||
|
||||
_editor.addCommand(monaco.KeyMod.Alt | monaco.KeyCode.KeyX, (e) => {
|
||||
_editor.getAction("my-autoWrap-toggle")?.run();
|
||||
});
|
||||
|
||||
_editor.addAction({
|
||||
id: "my-autoWrap-toggle",
|
||||
label: "切换自动换行",
|
||||
keybindings: [
|
||||
monaco.KeyMod.Alt | monaco.KeyCode.KeyZ,
|
||||
// monaco.KeyMod.chord(
|
||||
// monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyK,
|
||||
// monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyM
|
||||
// ),
|
||||
],
|
||||
|
||||
// A precondition for this action.
|
||||
// precondition: null,
|
||||
|
||||
// A rule to evaluate on top of the precondition in order to dispatch the keybindings.
|
||||
// keybindingContext: null,
|
||||
|
||||
// contextMenuGroupId: "navigation",
|
||||
// contextMenuOrder: 1.5,
|
||||
|
||||
// Method that will be executed when the action is triggered.
|
||||
// @param editor The editor instance is passed in as a convenience
|
||||
run: function (ed, arg) {
|
||||
// alert("i'm running => " + ed.getPosition());
|
||||
// console.log("my-autoWrap-toggle", arg);
|
||||
const workWrap = ed.getOption(monaco.editor.EditorOption.wordWrap);
|
||||
ed.updateOptions({
|
||||
wordWrap: workWrap === "on" ? "off" : "on",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
setReady(true);
|
||||
});
|
||||
// let xc: any;
|
||||
// const resizeObserver = new ResizeObserver((entries) => {
|
||||
// // _editor?.layout();
|
||||
// // console.log("resizeObserver");
|
||||
// if (xc) clearTimeout(xc);
|
||||
// xc = setTimeout(() => {
|
||||
// _editor?.layout();
|
||||
// }, 100);
|
||||
// });
|
||||
// resizeObserver.observe(el);
|
||||
return () => {
|
||||
_editor?.dispose?.();
|
||||
// resizeObserver.unobserve(el);
|
||||
// resizeObserver.disconnect();
|
||||
};
|
||||
}
|
||||
monacoIsReady.then(() => {
|
||||
setReady(true);
|
||||
});
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
if (isReady) {
|
||||
if (divEl.current) {
|
||||
const devel = divEl.current;
|
||||
let _editor: Monaco.editor.IStandaloneCodeEditor;
|
||||
monacoIsReady.then(() => {
|
||||
_editor = editor.current = monaco.editor.create(devel, {
|
||||
value: value,
|
||||
language: language,
|
||||
theme: _theme,
|
||||
...defOptions,
|
||||
...options,
|
||||
});
|
||||
_editor.onDidChangeModelContent(function (event: any) {
|
||||
const _value = _editor.getValue();
|
||||
setValue(_value);
|
||||
self.current?.onChange?.(_value);
|
||||
});
|
||||
|
||||
_editor.addCommand(monaco.KeyMod.Alt | monaco.KeyCode.KeyX, (e) => {
|
||||
_editor.getAction("my-autoWrap-toggle")?.run();
|
||||
});
|
||||
|
||||
_editor.addAction({
|
||||
id: "my-autoWrap-toggle",
|
||||
label: "切换自动换行",
|
||||
keybindings: [
|
||||
monaco.KeyMod.Alt | monaco.KeyCode.KeyZ,
|
||||
// monaco.KeyMod.chord(
|
||||
// monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyK,
|
||||
// monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyM
|
||||
// ),
|
||||
],
|
||||
|
||||
// A precondition for this action.
|
||||
// precondition: null,
|
||||
|
||||
// A rule to evaluate on top of the precondition in order to dispatch the keybindings.
|
||||
// keybindingContext: null,
|
||||
|
||||
// contextMenuGroupId: "navigation",
|
||||
// contextMenuOrder: 1.5,
|
||||
|
||||
// Method that will be executed when the action is triggered.
|
||||
// @param editor The editor instance is passed in as a convenience
|
||||
run: function (ed, arg) {
|
||||
// alert("i'm running => " + ed.getPosition());
|
||||
// console.log("my-autoWrap-toggle", arg);
|
||||
const workWrap = ed.getOption(
|
||||
monaco.editor.EditorOption.wordWrap
|
||||
);
|
||||
ed.updateOptions({
|
||||
wordWrap: workWrap === "on" ? "off" : "on",
|
||||
});
|
||||
},
|
||||
});
|
||||
});
|
||||
// let xc: any;
|
||||
// const resizeObserver = new ResizeObserver((entries) => {
|
||||
// // _editor?.layout();
|
||||
// // console.log("resizeObserver");
|
||||
// if (xc) clearTimeout(xc);
|
||||
// xc = setTimeout(() => {
|
||||
// _editor?.layout();
|
||||
// }, 100);
|
||||
// });
|
||||
// resizeObserver.observe(el);
|
||||
return () => {
|
||||
_editor?.dispose?.();
|
||||
// resizeObserver.unobserve(el);
|
||||
// resizeObserver.disconnect();
|
||||
};
|
||||
}
|
||||
}
|
||||
// let editor: any;
|
||||
}, [isReady]);
|
||||
|
||||
useEffect(() => {
|
||||
if (editor.current) {
|
||||
@@ -182,7 +191,7 @@ const CodeEditor_: React.ForwardRefRenderFunction<
|
||||
}
|
||||
}, [value]);
|
||||
|
||||
return (
|
||||
return isReady ? (
|
||||
<div
|
||||
className={classnames(className)}
|
||||
style={{
|
||||
@@ -194,6 +203,17 @@ const CodeEditor_: React.ForwardRefRenderFunction<
|
||||
}}
|
||||
ref={divEl}
|
||||
></div>
|
||||
) : (
|
||||
<Input.TextArea
|
||||
style={{ height: height || "100%" }}
|
||||
className={classnames(className)}
|
||||
value={value}
|
||||
onChange={(event) => {
|
||||
const _value = event.target.value;
|
||||
setValue(_value);
|
||||
self.current?.onChange?.(_value);
|
||||
}}
|
||||
></Input.TextArea>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
+2
-3
@@ -6,9 +6,8 @@ import { analyzer } from "vite-bundle-analyzer";
|
||||
export default defineConfig(({ command, mode }) => {
|
||||
const config: UserConfig = {
|
||||
base: "./",
|
||||
plugins: [
|
||||
react()
|
||||
],
|
||||
plugins: [react()],
|
||||
define: {},
|
||||
};
|
||||
|
||||
if (mode === "development") {
|
||||
|
||||
Reference in New Issue
Block a user