From 3c434df31c31e1e59fc464e77b620017c634ca2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=A2=E4=BA=9A=E6=98=95?= <1549469775@qq.com> Date: Mon, 24 Mar 2025 17:01:53 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E4=B8=9C=E8=A5=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/index.ts | 19 +++---- electron.vite.config.ts | 5 +- package.json | 20 +++---- src/common/event/update/common.ts | 7 +++ src/common/event/update/main.ts | 10 ++++ src/common/event/update/renderer.ts | 14 +++++ src/main/commands/SettingCommand.ts | 12 +++++ src/main/modules/commands/index.ts | 2 +- src/main/modules/tabs/Tab.ts | 2 +- src/main/modules/updater/hot/gen.ts | 62 ++++++++++++++++++++++ src/main/modules/updater/index.ts | 8 ++- src/main/modules/window-manager/index.ts | 6 ++- src/main/modules/window-manager/windowsMap.ts | 2 +- src/main/utils/index.ts | 2 +- src/preload/index.d.ts | 8 --- src/preload/index.ts | 2 +- src/renderer/src/bridge/PopupMenu.ts | 2 +- .../src/components/CodeEditor/code-editor.vue | 12 +++-- src/renderer/src/global.d.ts | 1 - src/types/global.d.ts | 21 ++++++++ src/types/index.d.ts | 10 ---- src/types/popup-menu.ts | 12 +++++ tsconfig.node.json | 6 ++- tsconfig.web.json | 4 ++ 24 files changed, 194 insertions(+), 55 deletions(-) create mode 100644 src/common/event/update/common.ts create mode 100644 src/common/event/update/main.ts create mode 100644 src/common/event/update/renderer.ts create mode 100644 src/main/commands/SettingCommand.ts create mode 100644 src/main/modules/updater/hot/gen.ts delete mode 100644 src/preload/index.d.ts delete mode 100644 src/renderer/src/global.d.ts create mode 100644 src/types/global.d.ts delete mode 100644 src/types/index.d.ts create mode 100644 src/types/popup-menu.ts diff --git a/config/index.ts b/config/index.ts index f6a2eb2..b59754c 100644 --- a/config/index.ts +++ b/config/index.ts @@ -1,20 +1,17 @@ interface IConfig { app_title: string default_config: { - language: "zh" | "en" // i18n - "common.theme": "light" | "dark" | "auto" // 主题 + language: "zh" | "en" + "common.theme": "light" | "dark" | "auto" "desktop:wallpaper": string - "update.repo"?: string // 更新地址 - "update.owner"?: string // 更新通道 + "update.repo"?: string + "update.owner"?: string "update.allowDowngrade": boolean "update.allowPrerelease": boolean - "editor.bg": string // 更新通道 - "editor.logoType": "logo" | "bg" // 更新通道 - "editor.fontFamily": string // 更新通道 - // "snippet.storagePath": string // 代码片段保存位置 - // "bookmark.storagePath": string // 书签保存位置 - // backup_rule: string // 备份规则 - storagePath: string // 存储地址 + "editor.bg": string + "editor.logoType": "logo" | "bg" + "editor.fontFamily": string + storagePath: string } } export default { diff --git a/electron.vite.config.ts b/electron.vite.config.ts index 30b88af..659b9ed 100644 --- a/electron.vite.config.ts +++ b/electron.vite.config.ts @@ -18,7 +18,8 @@ export default defineConfig({ alias: { config: resolve("config"), main: resolve("src/main"), - res: resolve("resources"), + "common": resolve("src/common"), + "@res": resolve("resources"), }, }, plugins: [externalizeDepsPlugin()], @@ -31,6 +32,7 @@ export default defineConfig({ resolve: { alias: { config: resolve("config"), + "common": resolve("src/common"), "@": resolve("src/renderer/src"), "@res": resolve("resources"), }, @@ -39,6 +41,7 @@ export default defineConfig({ preprocessorOptions: { scss: { additionalData: `@use "@/assets/style/global" as *;\n`, + api: "modern-compiler" }, }, }, diff --git a/package.json b/package.json index 4153ea0..1275f79 100644 --- a/package.json +++ b/package.json @@ -27,19 +27,10 @@ "dependencies": { "@electron-toolkit/preload": "^3.0.1", "@electron-toolkit/utils": "^3.0.0", - "@types/debug": "^4.1.12", - "@unocss/reset": "^0.64.1", - "@vueuse/core": "^12.7.0", "electron-updater": "^6.3.9", "inversify": "^6.2.2", "lowdb": "^7.0.1", - "reflect-metadata": "^0.2.2", - "sass": "^1.85.0", - "unplugin-auto-import": "^19.1.0", - "unplugin-vue-components": "^28.4.0", - "unplugin-vue-macros": "^2.14.2", - "unplugin-vue-router": "^0.11.2", - "vue-router": "^4.5.0" + "reflect-metadata": "^0.2.2" }, "devDependencies": { "@electron-toolkit/eslint-config": "^1.0.2", @@ -47,12 +38,15 @@ "@electron-toolkit/tsconfig": "^1.0.1", "@intlify/unplugin-vue-i18n": "^6.0.3", "@rushstack/eslint-patch": "^1.10.5", + "@types/debug": "^4.1.12", "@types/node": "^20.17.19", "@unocss/preset-rem-to-px": "^0.64.1", + "@unocss/reset": "^0.64.1", "@vitejs/plugin-vue": "^5.2.1", "@vitejs/plugin-vue-jsx": "^4.1.1", "@vue/eslint-config-prettier": "^9.0.0", "@vue/eslint-config-typescript": "^13.0.0", + "@vueuse/core": "^12.7.0", "debug": "^4.4.0", "electron": "^31.7.7", "electron-builder": "^24.13.3", @@ -64,14 +58,20 @@ "monaco-editor": "^0.52.2", "prettier": "^3.5.1", "rotating-file-stream": "^3.2.6", + "sass": "^1.85.0", "simplebar-vue": "^2.4.0", "typescript": "^5.7.3", "unocss": "^0.64.1", + "unplugin-auto-import": "^19.1.0", + "unplugin-vue-components": "^28.4.0", + "unplugin-vue-macros": "^2.14.2", + "unplugin-vue-router": "^0.11.2", "vite": "^5.4.14", "vite-plugin-monaco-editor": "^1.1.0", "vite-plugin-vue-layouts": "^0.11.0", "vue": "^3.5.13", "vue-i18n": "^11.1.1", + "vue-router": "^4.5.0", "vue-tsc": "^2.1.10" } } diff --git a/src/common/event/update/common.ts b/src/common/event/update/common.ts new file mode 100644 index 0000000..6b969cf --- /dev/null +++ b/src/common/event/update/common.ts @@ -0,0 +1,7 @@ +const keys = ["progress"] as const + +type AllKeys = (typeof keys)[number] + +export type{ + AllKeys +} \ No newline at end of file diff --git a/src/common/event/update/main.ts b/src/common/event/update/main.ts new file mode 100644 index 0000000..7ce5aa0 --- /dev/null +++ b/src/common/event/update/main.ts @@ -0,0 +1,10 @@ +import { broadcast } from "main/utils" +import { AllKeys } from "./common" + +function emitProgress(...argu) { + broadcast("progress", ...argu) +} + +export { + emitProgress +} \ No newline at end of file diff --git a/src/common/event/update/renderer.ts b/src/common/event/update/renderer.ts new file mode 100644 index 0000000..7ccdfaa --- /dev/null +++ b/src/common/event/update/renderer.ts @@ -0,0 +1,14 @@ +import type { AllKeys } from "./common" + +const curProgress = ref(0) +api.on("progress", () => { + curProgress.value = 10 +}) + +function useUpdate() { + return { + curProgress, + } +} + +export { useUpdate } diff --git a/src/main/commands/SettingCommand.ts b/src/main/commands/SettingCommand.ts new file mode 100644 index 0000000..6ff9095 --- /dev/null +++ b/src/main/commands/SettingCommand.ts @@ -0,0 +1,12 @@ +// import { inject } from "inversify" +// import Setting from "main/modules/setting" + +// class SettingCommand { +// constructor(@inject(Setting) private _Setting: Setting) { +// console.log(this._Setting) +// } + +// getAll() { +// return this._Setting.config() +// } +// } diff --git a/src/main/modules/commands/index.ts b/src/main/modules/commands/index.ts index b5d1727..91897ff 100644 --- a/src/main/modules/commands/index.ts +++ b/src/main/modules/commands/index.ts @@ -1,4 +1,4 @@ -import { IMenuItemOption, IPopupMenuOption } from "#" +import { IMenuItemOption, IPopupMenuOption } from "#/popup-menu" import { ipcMain, Menu, MenuItem } from "electron" import { inject } from "inversify" import IOC from "main/_ioc" diff --git a/src/main/modules/tabs/Tab.ts b/src/main/modules/tabs/Tab.ts index 6d24bd4..c9207db 100644 --- a/src/main/modules/tabs/Tab.ts +++ b/src/main/modules/tabs/Tab.ts @@ -3,7 +3,7 @@ import { join } from "node:path" import BaseClass from "main/base/base" import _debug from "debug" // import { Layout } from "./Constant" -import FuckHTML from "res/fuck.html?asset" +import FuckHTML from "@res/fuck.html?asset" import { fileURLToPath, pathToFileURL } from "node:url" const debug = _debug("app:tab") diff --git a/src/main/modules/updater/hot/gen.ts b/src/main/modules/updater/hot/gen.ts new file mode 100644 index 0000000..d3fd4d1 --- /dev/null +++ b/src/main/modules/updater/hot/gen.ts @@ -0,0 +1,62 @@ +import { spawn } from "node:child_process" +import fs from "node:fs" +import path from "node:path" +import os from "node:os" +import { app } from "electron" + +function getUpdateScriptTemplate() { + return process.platform === "win32" + ? ` + @echo off + timeout /t 2 + taskkill /IM "{{EXE_NAME}}" /F + xcopy /Y /E "{{UPDATE_DIR}}\\*" "{{APP_PATH}}" + start "" "{{EXE_PATH}}" + ` + : ` + #!/bin/bash + sleep 2 + pkill -f "{{EXE_NAME}}" + cp -Rf "{{UPDATE_DIR}}/*" "{{APP_PATH}}/" + open "{{EXE_PATH}}" + ` +} + +function generateUpdateScript() { + const scriptContent = getUpdateScriptTemplate() + .replace(/{{APP_PATH}}/g, process.platform === "win32" ? "%APP_PATH%" : "$APP_PATH") + .replace(/{{UPDATE_DIR}}/g, process.platform === "win32" ? "%UPDATE_DIR%" : "$UPDATE_DIR") + .replace(/{{EXE_PATH}}/g, process.platform === "win32" ? "%EXE_PATH%" : "$EXE_PATH") + .replace(/{{EXE_NAME}}/g, process.platform === "win32" ? "%EXE_NAME%" : "$EXE_NAME") + + const scriptPath = path.join(os.tmpdir(), `update.${process.platform === "win32" ? "bat" : "sh"}`) + fs.writeFileSync(scriptPath, scriptContent) + return scriptPath +} + +app.on("will-quit", event => { + event.preventDefault() + + // 假设已下载更新到临时目录 + const updateTempDir = path.join(os.tmpdir(), "app-update") + const appPath = app.getAppPath() + const appExePath = process.execPath + + // 生成动态脚本 + const scriptPath = generateUpdateScript() + + fs.chmodSync(scriptPath, 0o755) + + // 执行脚本 + const child = spawn(scriptPath, [], { + detached: true, + shell: true, + env: { + APP_PATH: appPath, + UPDATE_DIR: updateTempDir, + EXE_PATH: appExePath, + }, + }) + child.unref() + app.exit() +}) diff --git a/src/main/modules/updater/index.ts b/src/main/modules/updater/index.ts index 7846a4e..82080bb 100644 --- a/src/main/modules/updater/index.ts +++ b/src/main/modules/updater/index.ts @@ -12,6 +12,7 @@ const { autoUpdater } = pkg @injectable() export class Updater extends BaseClass { public events = new EventEmitter() + private timer: ReturnType | null = null constructor( // @inject(Setting) private _Setting: Setting @@ -60,7 +61,8 @@ export class Updater extends BaseClass { init() { // 定期检查更新 this.checkForUpdates() - setInterval( + this.timer && clearInterval(this.timer) + this.timer = setInterval( () => { this.checkForUpdates() }, @@ -70,6 +72,10 @@ export class Updater extends BaseClass { destroy() { // 清理工作 + if(this.timer){ + clearInterval(this.timer) + this.timer = null + } } private async checkForUpdates() { diff --git a/src/main/modules/window-manager/index.ts b/src/main/modules/window-manager/index.ts index df9d72c..944dc1e 100644 --- a/src/main/modules/window-manager/index.ts +++ b/src/main/modules/window-manager/index.ts @@ -246,7 +246,11 @@ export default class WindowManager extends BaseClass { } showCurrentWindow() { - debug(`current open window: ${this.#windows.map(v => v.$$opts!.name).join(",")}`) + if(this.#windows.length) { + debug(`current open window: ${this.#windows.map(v => v.$$opts!.name).join(",")}`) + } else { + debug(`all closed`) + } } #onClose(name: string) { diff --git a/src/main/modules/window-manager/windowsMap.ts b/src/main/modules/window-manager/windowsMap.ts index 1c1744e..ed30553 100644 --- a/src/main/modules/window-manager/windowsMap.ts +++ b/src/main/modules/window-manager/windowsMap.ts @@ -1,7 +1,7 @@ import config from "config" import { BrowserWindowConstructorOptions } from "electron" import { getFileUrl } from "main/utils" -import icon from "res/icon.png?asset" +import icon from "@res/icon.png?asset" import { join } from "path" export type Param = Partial & Required> diff --git a/src/main/utils/index.ts b/src/main/utils/index.ts index f01e550..3d43098 100644 --- a/src/main/utils/index.ts +++ b/src/main/utils/index.ts @@ -16,7 +16,7 @@ export function isPromise(value: () => any) { return value && Object.prototype.toString.call(value) === "[object Promise]" } -export const broadcast = (event: string, ...args: any[]) => { +export const broadcast = (event: T, ...args: any[]) => { webContents.getAllWebContents().forEach(browser => browser.send(event, ...args)) } diff --git a/src/preload/index.d.ts b/src/preload/index.d.ts deleted file mode 100644 index 2d45fc3..0000000 --- a/src/preload/index.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { ElectronAPI } from "@electron-toolkit/preload" - -declare global { - interface Window { - electron: ElectronAPI - api: unknown - } -} diff --git a/src/preload/index.ts b/src/preload/index.ts index b453789..e3a5855 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -1,7 +1,7 @@ import { contextBridge, ipcRenderer, IpcRendererEvent } from "electron" import { electronAPI } from "@electron-toolkit/preload" import { call, callLong, callSync } from "./call" -import { IPopupMenuOption } from "#" +import { IPopupMenuOption } from "#/popup-menu" document.addEventListener("DOMContentLoaded", () => { const initStyle = document.createElement("style") initStyle.textContent = ` diff --git a/src/renderer/src/bridge/PopupMenu.ts b/src/renderer/src/bridge/PopupMenu.ts index cd28cbb..96820ed 100644 --- a/src/renderer/src/bridge/PopupMenu.ts +++ b/src/renderer/src/bridge/PopupMenu.ts @@ -4,7 +4,7 @@ * @homepage: https://oldj.net */ -import { IMenuItemOption } from "#" +import { IMenuItemOption } from "#/popup-menu" import type { PopupOptions } from "electron" let _idx: number = 0 diff --git a/src/renderer/src/components/CodeEditor/code-editor.vue b/src/renderer/src/components/CodeEditor/code-editor.vue index 7bf97c0..c6d7c9a 100644 --- a/src/renderer/src/components/CodeEditor/code-editor.vue +++ b/src/renderer/src/components/CodeEditor/code-editor.vue @@ -98,7 +98,6 @@ function updateModel(name: string, content: string) { const code = model.getValue() emit("update:modelValue", code) emit("change", code) - console.log(343) } }) if (oldModel) { @@ -186,7 +185,13 @@ onMounted(() => { } }, ) -}) +}) +if (import.meta.hot) { + import.meta.hot.accept((newModule) => { + console.log(newModule); + + }) +} onBeforeUnmount(() => { if (editorRef.value) { editorRef.value.removeEventListener("resize", resizeLayout) @@ -196,9 +201,8 @@ onBeforeUnmount(() => { if (oldModel) { oldModel.dispose() } - editor?.dispose() + editor.dispose() editor = null - console.log("editor dispose") } }) const style = computed(() => { diff --git a/src/renderer/src/global.d.ts b/src/renderer/src/global.d.ts deleted file mode 100644 index c3453cb..0000000 --- a/src/renderer/src/global.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare const api diff --git a/src/types/global.d.ts b/src/types/global.d.ts new file mode 100644 index 0000000..49fda75 --- /dev/null +++ b/src/types/global.d.ts @@ -0,0 +1,21 @@ + +type Api = { + call: (command: string, ...args: any[]) => Promise + callLong: (command: string, ...args: any[]) => Promise + callSync: (command: string, ...args: any[]) => any + send: (command: string, ...argu: any[]) => any + sendSync: (command: string, ...argu: any[]) => any + on: (command: T, cb: (event: IpcRendererEvent, ...args: any[]) => void) => () => void + once: (command: string, cb: (event: IpcRendererEvent, ...args: any[]) => void) => () => void + off: (command: string, cb: (event: IpcRendererEvent, ...args: any[]) => void) => void + offAll: (command: string) => void + popupMenu: (options: IPopupMenuOption) => void +} + +declare const electron: typeof import("@electron-toolkit/preload").electronAPI +declare const api: Api + +interface Window { + electron: typeof import("@electron-toolkit/preload").electronAPI + api: Api +} diff --git a/src/types/index.d.ts b/src/types/index.d.ts deleted file mode 100644 index 77eb2fd..0000000 --- a/src/types/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -interface IMenuItemOption extends Electron.MenuItemConstructorOptions { - // 参见:https://www.electronjs.org/docs/api/menu-item - _click_evt?: string -} - -export interface IPopupMenuOption { - menu_id: string - items: IMenuItemOption[] - popupOptions?: PopupOptions -} diff --git a/src/types/popup-menu.ts b/src/types/popup-menu.ts new file mode 100644 index 0000000..c0501ef --- /dev/null +++ b/src/types/popup-menu.ts @@ -0,0 +1,12 @@ +import type { PopupOptions } from "electron" + +export interface IMenuItemOption extends Electron.MenuItemConstructorOptions { + // 参见:https://www.electronjs.org/docs/api/menu-item + _click_evt?: string +} + +export interface IPopupMenuOption { + menu_id: string + items: IMenuItemOption[] + popupOptions?: PopupOptions +} diff --git a/tsconfig.node.json b/tsconfig.node.json index b022560..a1b5b17 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -1,6 +1,7 @@ { "extends": "@electron-toolkit/tsconfig/tsconfig.node.json", - "include": ["electron.vite.config.*", "src/main/**/*", "src/preload/**/*", "config/**/*", "src/types/**/*", "packages/locales/main.ts"], + "include": ["electron.vite.config.*", "src/main/**/*", "src/preload/**/*", "config/**/*", "src/types/**/*", "packages/locales/main.ts", + "src/common/**/*.main.ts", "src/common/**/main.ts", "src/common/**/*.common.ts", "src/common/**/common.ts"], "compilerOptions": { "composite": true, "emitDecoratorMetadata": true, @@ -13,7 +14,8 @@ "config": ["config/index.ts"], "config/*": ["config/*"], "main/*": ["src/main/*"], - "res/*": ["resources/*"], + "common/*": ["src/common/*"], + "@res/*": ["resources/*"], "locales/*": ["packages/locales/*"], } } diff --git a/tsconfig.web.json b/tsconfig.web.json index 8ee5b4b..14fed57 100644 --- a/tsconfig.web.json +++ b/tsconfig.web.json @@ -10,6 +10,9 @@ "src/types/**/*", "config/**/*", "./typed-router.d.ts", + "src/common/**/*.renderer.ts", + "src/common/**/renderer.ts", + "src/common/**/*.common.ts", "src/common/**/common.ts", ], "vueCompilerOptions": { "plugins": ["unplugin-vue-macros/volar"], @@ -24,6 +27,7 @@ "#/*": ["src/types/*"], "config": ["config/index.ts"], "config/*": ["config/*"], + "common/*": ["src/common/*"], "@/*": [ "src/renderer/src/*" ],