Skip to content

Commit

Permalink
♻️ 重构vscode功能
Browse files Browse the repository at this point in the history
  • Loading branch information
CodFrm committed Nov 16, 2022
1 parent 06dfc18 commit f5ec7a4
Show file tree
Hide file tree
Showing 9 changed files with 214 additions and 17 deletions.
7 changes: 2 additions & 5 deletions src/app/service/script/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
SCRIPT_STATUS_ENABLE,
ScriptDAO,
} from "../../repo/scripts";
import ScriptManager from "./manager";
import ScriptManager, { InstallSource } from "./manager";

export type ScriptEvent =
| "upsert"
Expand Down Expand Up @@ -49,10 +49,7 @@ export default class ScriptEventListener {

// 安装或者更新脚本,将数据保存到数据库
@ListenEventDecorator("upsert")
public upsertHandler(
script: Script,
upsertBy: "user" | "system" | "sync" = "user"
) {
public upsertHandler(script: Script, upsertBy: InstallSource = "user") {
return new Promise((resolve, reject) => {
const logger = this.logger.with({
scriptId: script.id,
Expand Down
5 changes: 4 additions & 1 deletion src/app/service/script/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Script, SCRIPT_STATUS_DISABLE, ScriptDAO } from "../../repo/scripts";
import ScriptEventListener from "./event";
import Hook from "../hook";

export type InstallSource = "user" | "system" | "sync" | "subscribe";
export type InstallSource = "user" | "system" | "sync" | "subscribe" | "vscode";

// 脚本管理器,负责脚本实际的安装、卸载、更新等操作
@IoC.Singleton(MessageHander, SystemConfig)
Expand Down Expand Up @@ -52,6 +52,9 @@ export class ScriptManager extends Manager {
// 启动脚本检查更新
// 十分钟对符合要求的脚本进行检查更新
setInterval(() => {
if (!this.systemConfig.checkScriptUpdateCycle) {
return;
}
this.logger.debug("start check update");
this.scriptDAO.table
.where("checktime")
Expand Down
3 changes: 3 additions & 0 deletions src/app/service/subscribe/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ export default class SubscribeManager extends Manager {
// 启动订阅检查更新
// 十分钟对符合要求的订阅进行检查更新
setInterval(() => {
if (!this.systemConfig.checkScriptUpdateCycle) {
return;
}
this.logger.debug("start check update");
this.subscribeDAO.table
.where("checktime")
Expand Down
17 changes: 17 additions & 0 deletions src/app/service/system/controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import IoC from "@App/app/ioc";
import MessageInternal from "@App/app/message/internal";
import Controller from "../controller";

@IoC.Singleton(MessageInternal)
export default class SystemController extends Controller {
internal: MessageInternal;

constructor(internal: MessageInternal) {
super(internal, "system");
this.internal = internal;
}

connectVSCode() {
return this.dispatchEvent("connectVSCode", {});
}
}
77 changes: 77 additions & 0 deletions src/app/service/system/manager.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { ExternalMessage, ExtVersion, ExtServer } from "@App/app/const";
import IoC from "@App/app/ioc";
import { v5 as uuidv5 } from "uuid";
import { MessageHander } from "@App/app/message/message";
import { ScriptDAO } from "@App/app/repo/scripts";
import { SystemConfig } from "@App/pkg/config/config";
import { prepareScriptByCode } from "@App/pkg/utils/script";
import semver from "semver";
import Manager from "../manager";
import ScriptManager from "../script/manager";

// value管理器,负责value等更新获取等操作
@IoC.Singleton(MessageHander, SystemConfig)
Expand All @@ -13,10 +16,15 @@ export class SystemManager extends Manager {

scriptDAO: ScriptDAO;

scriptManager: ScriptManager;

wsVscode?: WebSocket;

constructor(message: MessageHander, systemConfig: SystemConfig) {
super(message, "system");
this.scriptDAO = new ScriptDAO();
this.systemConfig = systemConfig;
this.scriptManager = IoC.instance(ScriptManager) as ScriptManager;
}

init() {
Expand Down Expand Up @@ -92,6 +100,75 @@ export class SystemManager extends Manager {
return Promise.resolve(false);
}
);
this.listenEvent("connectVSCode", this.connectVSCode.bind(this));

this.reconnectVSCode();
}

reconnectVSCode() {
let connectVSCodeTimer: any;
const handler = () => {
if (!this.wsVscode) {
this.connectVSCode();
}
};
if (this.systemConfig.vscodeReconnect) {
connectVSCodeTimer = setInterval(() => {
handler();
}, 30 * 1000);
}

SystemConfig.hook.addListener("update", (key, val) => {
if (key === "vscodeReconnect") {
if (val) {
connectVSCodeTimer = setInterval(() => {
handler();
}, 30 * 1000);
} else {
clearInterval(connectVSCodeTimer);
}
}
});
}

connectVSCode() {
return new Promise<void>((resolve, reject) => {
// 与vsc扩展建立连接
if (this.wsVscode) {
this.wsVscode.close();
}
try {
this.wsVscode = new WebSocket(this.systemConfig.vscodeUrl);
} catch (e: any) {
reject(e);
return;
}
this.wsVscode.addEventListener("open", () => {
this.wsVscode!.send('{"action":"hello"}');
resolve();
});
this.wsVscode.addEventListener("message", async (ev) => {
const data = JSON.parse(ev.data);
switch (data.action) {
case "onchange": {
const code = data.data.script;
const script = await prepareScriptByCode(
code,
"",
uuidv5(code.data.uri, uuidv5.URL)
);
this.scriptManager.event.upsertHandler(script, "vscode");
break;
}
default:
}
});

this.wsVscode.addEventListener("error", () => {
reject(new Error("VSCode连接失败"));
this.wsVscode = undefined;
});
});
}

getNotice(): Promise<{ notice: string; isRead: boolean }> {
Expand Down
27 changes: 26 additions & 1 deletion src/pages/options/routes/Setting.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import React, { useState } from "react";
import { Button, Card, Checkbox, Message, Space } from "@arco-design/web-react";
import {
Button,
Card,
Checkbox,
Message,
Select,
Space,
} from "@arco-design/web-react";
import FileSystemParams from "@App/pages/components/FileSystemParams";
import { SystemConfig } from "@App/pkg/config/config";
import IoC from "@App/app/ioc";
Expand Down Expand Up @@ -94,6 +101,24 @@ function Setting() {
</Card>
<Card title="更新" bordered={false}>
<Space direction="vertical">
<Space>
<span>脚本/订阅检查更新间隔:</span>
<Select
defaultValue={systemConfig.checkScriptUpdateCycle.toString()}
style={{
width: 100,
}}
onChange={(value) => {
systemConfig.checkScriptUpdateCycle = parseInt(value, 10);
}}
>
<Select.Option value="0">从不</Select.Option>
<Select.Option value="21600">6小时</Select.Option>
<Select.Option value="43200">12小时</Select.Option>
<Select.Option value="86400">每天</Select.Option>
<Select.Option value="604800">每周</Select.Option>
</Select>
</Space>
<Checkbox
onChange={(checked) => {
systemConfig.updateDisableScript = checked;
Expand Down
63 changes: 61 additions & 2 deletions src/pages/options/routes/Tools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useRef, useState } from "react";
import {
Button,
Card,
Checkbox,
Drawer,
Empty,
Input,
Expand All @@ -18,6 +19,9 @@ import { SystemConfig } from "@App/pkg/config/config";
import { File, FileReader } from "@Pkg/filesystem/filesystem";
import { formatUnixTime } from "@App/pkg/utils/utils";
import FileSystemParams from "@App/pages/components/FileSystemParams";
import { IconQuestionCircleFill } from "@arco-design/web-react/icon";
import { RefInputType } from "@arco-design/web-react/es/Input/interface";
import SystemController from "@App/app/service/system/controller";

function Tools() {
const [loading, setLoading] = useState<{ [key: string]: boolean }>({});
Expand All @@ -32,6 +36,8 @@ function Tools() {
}>(systemConfig.backup.params[fileSystemType] || {});
const [backupFileList, setBackupFileList] = useState<File[]>([]);

const vscodeRef = useRef<RefInputType>(null);

return (
<Space
direction="vertical"
Expand Down Expand Up @@ -240,10 +246,63 @@ function Tools() {
</Space>
</Card>

<Card title="开发调试" bordered={false}>
<Card
title={
<>
<span>开发调试</span>
<Button
type="text"
style={{
height: 24,
}}
icon={
<IconQuestionCircleFill
style={{
margin: 0,
}}
/>
}
href="https://www.bilibili.com/video/BV16q4y157CP"
target="_blank"
iconOnly
/>
</>
}
bordered={false}
>
<Space direction="vertical">
<Title heading={6}>VSCode地址</Title>
<Input />
<Input
ref={vscodeRef}
defaultValue={systemConfig.vscodeUrl}
onChange={(value) => {
systemConfig.vscodeUrl = value;
}}
/>
<Checkbox
onChange={(checked) => {
systemConfig.vscodeReconnect = checked;
}}
defaultChecked={systemConfig.vscodeReconnect}
>
自动连接vscode服务
</Checkbox>
<Button
type="primary"
onClick={() => {
const ctrl = IoC.instance(SystemController) as SystemController;
ctrl
.connectVSCode()
.then(() => {
Message.success("连接成功");
})
.catch((e) => {
Message.error(`连接失败: ${e}`);
});
}}
>
连接
</Button>
</Space>
</Card>
</Space>
Expand Down
14 changes: 11 additions & 3 deletions src/pages/options/routes/script/ScriptEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,7 @@ function ScriptEditor() {
))}
</Tabs>
<div className="flex flex-grow flex-1">
{editors.map((item, index) => {
{editors.map((item) => {
// 先这样吧
setTimeout(() => {
if (item.active && item.editor) {
Expand All @@ -668,15 +668,23 @@ function ScriptEditor() {
hotKeys={item.hotKeys}
callbackEditor={(e) => {
setEditors((prev) => {
prev[index].editor = e;
prev.forEach((v) => {
if (v.script.uuid === item.script.uuid) {
v.editor = e;
}
});
return [...prev];
});
}}
onChange={(code) => {
const isChanged = !(item.code === code);
if (isChanged !== item.isChanged) {
setEditors((prev) => {
prev[index].isChanged = isChanged;
prev.forEach((v) => {
if (v.script.id === item.script.id) {
v.isChanged = isChanged;
}
});
return [...prev];
});
}
Expand Down
18 changes: 13 additions & 5 deletions src/pkg/utils/script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export async function fetchScriptInfo(
export function copyScript(script: Script, old: Script): Script {
const ret = script;
ret.id = old.id;
ret.uuid = old.uuid;
// ret.uuid = old.uuid;
ret.createtime = old.createtime;
ret.lastruntime = old.lastruntime;
// ret.delayruntime = old.delayruntime;
Expand Down Expand Up @@ -247,11 +247,16 @@ export function prepareScriptByCode(
[, domain] = urlSplit;
}
}
// N1-MTIwLjIyOC4wLjE4ODoxNjY4NTIyOTgyOjQ3OTYzNDc5NTMxMzQ1MzM0OQ==
// N1-MTIwLjIyOC4wLjE4ODoxNjY4NTIyOTgyOjQ3OTYzNDc5NTMxMzQ1MzM0OQ==
if (!uuid) {
if (url) {
uuid = uuidv5(url, uuidv5.URL);
} else {
uuid = uuidv4();
}
}
let script: Script & { oldScript?: Script } = {
id: 0,
uuid: uuid || uuidv4(),
uuid,
name: metadata.name[0],
code,
author: metadata.author && metadata.author[0],
Expand All @@ -273,8 +278,11 @@ export function prepareScriptByCode(
};
const handler = async () => {
let old: Script | undefined;
if (uuid !== undefined) {
if (uuid) {
old = await dao.findByUUID(uuid);
if (!old && url) {
old = await dao.findByNameAndNamespace(script.name, script.namespace);
}
} else {
old = await dao.findByNameAndNamespace(script.name, script.namespace);
if (!old) {
Expand Down

0 comments on commit f5ec7a4

Please sign in to comment.