Skip to content

Commit

Permalink
feat(web): support ai code completion (#1877)
Browse files Browse the repository at this point in the history
  • Loading branch information
0fatal committed Mar 1, 2024
1 parent fdf96bb commit 1c688b8
Show file tree
Hide file tree
Showing 10 changed files with 190 additions and 81 deletions.
21 changes: 21 additions & 0 deletions web/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"react-icons": "^4.8.0",
"react-image-crop": "^10.1.5",
"react-markdown": "^8.0.7",
"react-monaco-copilot": "^1.0.3",
"react-router-dom": "^6.11.2",
"react-syntax-highlighter": "^15.5.0",
"react-window": "^1.8.10",
Expand Down
5 changes: 3 additions & 2 deletions web/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -239,15 +239,16 @@
"FuncListDisplay": "Function List Display",
"ListDisplay": "List Display",
"EditorLanguageServer": "Editor Language Server",
"isOpenLanguageServer": "Enable or Close Language server (only effective when the app config is above 0.5C 1G)",
"isOpenLanguageServer": "Enable typescript language server (only effective when the spec of the app is above 0.5C 1G)",
"Editor": "Editor",
"FuncList": "Function List",
"EditorMode": "Editor Mode",
"OldLogs": "Old Logs",
"MonitorSetting": "Resource Monitor",
"DatabaseMonitor": "Database monitor",
"RuntimeMonitor": "Runtime monitor",
"ClientSetting": "Client settings"
"ClientSetting": "Client settings",
"AICompletion": "Enable code intelligent completion (need refresh)"
},
"StoragePanel": {
"All": "Total Capacity",
Expand Down
7 changes: 4 additions & 3 deletions web/public/locales/zh-CN/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -239,15 +239,16 @@
"FuncListDisplay": "函数列表显示",
"ListDisplay": "列表显示",
"EditorLanguageServer": "编辑器语言服务",
"isOpenLanguageServer": "是否开启语言服务(仅在应用配置高于 0.5C 1G 时生效)",
"isOpenLanguageServer": "是否开启 TypeScript 语言服务(体验更好的类型提示,仅在应用配置高于 0.5C 1G 时生效)",
"Editor": "编辑器",
"FuncList": "函数列表",
"EditorMode": "使用编辑器模式",
"OldLogs": "旧版日志",
"MonitorSetting": "资源监控",
"DatabaseMonitor": "数据库监控",
"RuntimeMonitor": "运行时监控",
"ClientSetting": "客户端设置"
"ClientSetting": "客户端设置",
"AICompletion": "是否开启代码智能补全(需刷新生效)"
},
"StoragePanel": {
"All": "总容量",
Expand Down Expand Up @@ -757,4 +758,4 @@
"Title": "Laf 新版本已经准备好了!",
"Description": "点击立即更新"
}
}
}
7 changes: 4 additions & 3 deletions web/public/locales/zh/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -239,15 +239,16 @@
"FuncListDisplay": "函数列表显示",
"ListDisplay": "列表显示",
"EditorLanguageServer": "编辑器语言服务",
"isOpenLanguageServer": "是否开启语言服务(仅在应用配置高于 0.5C 1G 时生效)",
"isOpenLanguageServer": "是否开启 TypeScript 语言服务(体验更好的类型提示,仅在应用配置高于 0.5C 1G 时生效)",
"Editor": "编辑器",
"FuncList": "函数列表",
"EditorMode": "使用编辑器模式",
"OldLogs": "旧版日志",
"MonitorSetting": "资源监控",
"DatabaseMonitor": "数据库监控",
"RuntimeMonitor": "运行时监控",
"ClientSetting": "客户端设置"
"ClientSetting": "客户端设置",
"AICompletion": "是否开启代码智能补全(需刷新生效)"
},
"StoragePanel": {
"All": "总容量",
Expand Down Expand Up @@ -757,4 +758,4 @@
"Title": "Laf 新版本已经准备好了!",
"Description": "点击立即更新"
}
}
}
19 changes: 18 additions & 1 deletion web/src/components/Editor/FunctionEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useEffect, useMemo, useRef, useState } from "react";
import { useCompletionFeature } from "react-monaco-copilot";
import * as monaco from "monaco-editor/esm/vs/editor/editor.api";
import {
RegisteredFileSystemProvider,
Expand All @@ -15,7 +16,9 @@ import { createUrl, createWebSocketAndStartClient, performInit } from "./Languag
import { TFunction } from "@/apis/typing";
import useFunctionCache from "@/hooks/useFunctionCache";
import useFunctionStore from "@/pages/app/functions/store";
import useCustomSettingStore from "@/pages/customSetting";
import useGlobalStore from "@/pages/globalStore";
import useSiteSettingStore from "@/pages/siteSetting";

export const fileSystemProvider = new RegisteredFileSystemProvider(false);
registerFileSystemOverlay(1, fileSystemProvider);
Expand All @@ -37,11 +40,14 @@ function FunctionEditor(props: {
}) {
const { onChange, path, className, colorMode = COLOR_MODE.light, fontSize = 14, value } = props;

const editorRef = useRef<monaco.editor.IStandaloneCodeEditor | null>();
const editorRef = useRef<monaco.editor.IStandaloneCodeEditor>();
const subscriptionRef = useRef<monaco.IDisposable | undefined>(undefined);
const monacoEl = useRef(null);
const globalStore = useGlobalStore((state) => state);
const { allFunctionList, setLSPStatus, LSPStatus } = useFunctionStore((state) => state);
const { commonSettings } = useCustomSettingStore();
const { siteSettings } = useSiteSettingStore();

const functionCache = useFunctionCache();
const [functionList, setFunctionList] = useState(allFunctionList);
const baseUrl = globalStore.currentApp.host;
Expand All @@ -53,6 +59,13 @@ function FunctionEditor(props: {
}
}, [baseUrl]);

const aiCompleteUrl = siteSettings.ai_complete_url?.value;
const completionFeature = useCompletionFeature({
monaco: monaco,
editor: editorRef.current,
apiUrl: aiCompleteUrl || "",
});

useEffect(() => {
const startLSP = () => {
const lspWebSocket = createWebSocketAndStartClient(url, globalStore.currentApp.develop_token);
Expand Down Expand Up @@ -152,6 +165,10 @@ function FunctionEditor(props: {
keybinding: monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyP,
command: null,
});

if (commonSettings.useCopilot && aiCompleteUrl) {
completionFeature.onMounted();
}
});
}

Expand Down
25 changes: 20 additions & 5 deletions web/src/components/Editor/TSEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useEffect, useRef } from "react";
import { useCompletionFeature } from "react-monaco-copilot";
import { Spinner } from "@chakra-ui/react";
import { Editor, Monaco } from "@monaco-editor/react";
import * as monaco from "monaco-editor/esm/vs/editor/editor.api";
Expand All @@ -10,6 +11,8 @@ import "./useWorker";

import useFunctionCache from "@/hooks/useFunctionCache";
import useFunctionStore from "@/pages/app/functions/store";
import useCustomSettingStore from "@/pages/customSetting";
import useSiteSettingStore from "@/pages/siteSetting";

const autoImportTypings = new AutoImportTypings();

Expand All @@ -24,14 +27,23 @@ export default function TSEditor(props: {

const functionCache = useFunctionCache();
const { currentFunction, allFunctionList } = useFunctionStore((state) => state);
const { commonSettings } = useCustomSettingStore();
const { siteSettings } = useSiteSettingStore();

const aiCompleteUrl = siteSettings.ai_complete_url?.value;

const monacoRef = useRef<Monaco>();
const editorRef = useRef<monaco.editor.IStandaloneCodeEditor>();
const loadModalsRef = useRef(loadModals);
const loadModelsRef = useRef(loadModels);
const completionFeature = useCompletionFeature({
monaco: monacoRef.current,
editor: editorRef.current,
apiUrl: aiCompleteUrl || "",
});

loadModalsRef.current = loadModals;
loadModelsRef.current = loadModels;

function loadModals(monaco: Monaco) {
function loadModels(monaco: Monaco) {
allFunctionList.forEach((item: any) => {
const uri = monaco.Uri.file(`${RUNTIMES_PATH}/${item.name}.ts`);
if (!monaco.editor.getModel(uri)) {
Expand All @@ -47,15 +59,18 @@ export default function TSEditor(props: {
function handleEditorDidMount(editor: monaco.editor.IStandaloneCodeEditor, monaco: Monaco) {
monacoRef.current = monaco;
editorRef.current = editor;
if (commonSettings.useCopilot && aiCompleteUrl) {
completionFeature.onMounted();
}
setTimeout(() => {
loadModalsRef.current(monacoRef.current!);
loadModelsRef.current(monacoRef.current!);
autoImportTypings.loadDefaults(monacoRef.current);
}, 10);
}

useEffect(() => {
if (monacoRef.current) {
loadModalsRef.current(monacoRef.current!);
loadModelsRef.current(monacoRef.current!);
}
}, [allFunctionList]);

Expand Down
Loading

0 comments on commit 1c688b8

Please sign in to comment.