From 7246ab2d9a1cd4d363e79b4bdd061a68335184f5 Mon Sep 17 00:00:00 2001 From: npmrun <1549469775@qq.com> Date: Thu, 27 Mar 2025 00:54:26 +0800 Subject: [PATCH] =?UTF-8?q?refactor(=E5=91=BD=E4=BB=A4=E6=A8=A1=E5=9D=97):?= =?UTF-8?q?=20=E5=B0=86=E5=91=BD=E4=BB=A4=E6=A8=A1=E5=9D=97=E4=BB=8E?= =?UTF-8?q?=E4=B8=BB=E8=BF=9B=E7=A8=8B=E8=BF=81=E7=A7=BB=E5=88=B0=E9=80=9A?= =?UTF-8?q?=E7=94=A8=E6=A8=A1=E5=9D=97=EF=BC=8C=E5=B9=B6=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将 `BasicCommand`、`TabsCommand` 和 `UpdateCommand` 从主进程迁移到 `common/event` 目录下,统一管理命令模块。同时,重构了 `PlatForm` 模块,使其使用新的 `ApiFactory` 进行 API 调用,提升了代码的可维护性和复用性。 --- .eslintrc.cjs | 47 +++++++----------- .prettierrc | 23 ++++++++- config/index.ts | 40 +++++++++------ packages/locales/index.ts | 64 ++++++++++++------------ packages/locales/main.ts | 64 ++++++++++++------------ src/common/_ioc.main.ts | 17 +++++++ src/common/event/PlatForm/index.ts | 13 +++-- src/common/event/PlatForm/main/command.ts | 81 +++++++++++++++++++++++++++++++ src/common/event/Tabs/main/command.ts | 65 +++++++++++++++++++++++++ src/common/event/update/index.ts | 8 +-- src/common/event/update/main.ts | 8 --- src/common/event/update/main/command.ts | 10 ++++ src/common/event/update/main/index.ts | 8 +++ src/common/lib/abstract.ts | 53 ++++++++++++++++++++ src/common/lib/browser.ts | 29 +++++++++++ src/common/lib/electron.ts | 20 ++++++++ src/main/App.ts | 4 +- src/main/_ioc.ts | 2 +- src/main/commands/BasicCommand.ts | 77 ----------------------------- src/main/commands/SettingCommand.ts | 12 ----- src/main/commands/TabsCommand.ts | 65 ------------------------- src/main/commands/UpdateCommand.ts | 10 ---- src/main/commands/_ioc.ts | 19 -------- src/renderer/src/main.ts | 15 +++++- tsconfig.node.json | 1 + tsconfig.web.json | 1 + 26 files changed, 444 insertions(+), 312 deletions(-) create mode 100644 src/common/_ioc.main.ts create mode 100644 src/common/event/PlatForm/main/command.ts create mode 100644 src/common/event/Tabs/main/command.ts delete mode 100644 src/common/event/update/main.ts create mode 100644 src/common/event/update/main/command.ts create mode 100644 src/common/event/update/main/index.ts create mode 100644 src/common/lib/abstract.ts create mode 100644 src/common/lib/browser.ts create mode 100644 src/common/lib/electron.ts delete mode 100644 src/main/commands/BasicCommand.ts delete mode 100644 src/main/commands/SettingCommand.ts delete mode 100644 src/main/commands/TabsCommand.ts delete mode 100644 src/main/commands/UpdateCommand.ts delete mode 100644 src/main/commands/_ioc.ts diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 99966b9..ac1e039 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,34 +1,23 @@ +const { readFileSync, readFile } = require("node:fs") + /* eslint-env node */ require("@rushstack/eslint-patch/modern-module-resolution") +const prettierConfig = JSON.parse(readFileSync("./.prettierrc.json", { encoding: "utf-8" })) + module.exports = { - extends: [ - "eslint:recommended", - "plugin:vue/vue3-recommended", - "@electron-toolkit", - "@electron-toolkit/eslint-config-ts/eslint-recommended", - "@vue/eslint-config-typescript/recommended", - "@vue/eslint-config-prettier", - ], - rules: { - "vue/require-default-prop": "off", - "vue/multi-word-component-names": "off", - "@typescript-eslint/no-explicit-any": "off", - "prettier/prettier": [ - "error", - { - tabWidth: 4, - useTabs: false, - semi: false, - singleQuote: false, - trailingComma: "all", - bracketSpacing: true, - arrowParens: "avoid", - printWidth: 140, - htmlWhitespaceSensitivity: "ignore", - proseWrap: "preserve", - endOfLine: "auto", - }, - ], - }, + extends: [ + "eslint:recommended", + "plugin:vue/vue3-recommended", + "@electron-toolkit", + "@electron-toolkit/eslint-config-ts/eslint-recommended", + "@vue/eslint-config-typescript/recommended", + "@vue/eslint-config-prettier", + ], + rules: { + "vue/require-default-prop": "off", + "vue/multi-word-component-names": "off", + "@typescript-eslint/no-explicit-any": "off", + "prettier/prettier": ["error", prettierConfig], + }, } diff --git a/.prettierrc b/.prettierrc index eab9949..ed0ee55 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,5 +1,5 @@ { - "tabWidth": 4, + "tabWidth": 2, "useTabs": false, "semi": false, "singleQuote": false, @@ -9,5 +9,24 @@ "printWidth": 140, "htmlWhitespaceSensitivity": "ignore", "proseWrap": "preserve", - "endOfLine": "auto" + "endOfLine": "auto", + "vueIndentScriptAndStyle": true, + "embeddedLanguageFormatting": "auto", + "jsxSingleQuote": false, + "jsxBracketSameLine": false, + "quoteProps": "as-needed", + "overrides": [ + { + "files": "*.json", + "options": { + "printWidth": 80 + } + }, + { + "files": ["*.vue", "*.tsx"], + "options": { + "singleAttributePerLine": false + } + } + ] } diff --git a/config/index.ts b/config/index.ts index b59754c..aa7e86b 100644 --- a/config/index.ts +++ b/config/index.ts @@ -1,19 +1,31 @@ +// 定义主题类型 +type ThemeType = "light" | "dark" | "auto" +// 定义语言类型 +type LanguageType = "zh" | "en" +// 定义编辑器logo类型 +type LogoType = "logo" | "bg" + +// 配置接口定义 +interface IDefaultConfig { + language: LanguageType + "common.theme": ThemeType + "desktop:wallpaper": string + "update.repo"?: string + "update.owner"?: string + "update.allowDowngrade": boolean + "update.allowPrerelease": boolean + "editor.bg": string + "editor.logoType": LogoType + "editor.fontFamily": string + storagePath: string +} + interface IConfig { app_title: string - default_config: { - language: "zh" | "en" - "common.theme": "light" | "dark" | "auto" - "desktop:wallpaper": string - "update.repo"?: string - "update.owner"?: string - "update.allowDowngrade": boolean - "update.allowPrerelease": boolean - "editor.bg": string - "editor.logoType": "logo" | "bg" - "editor.fontFamily": string - storagePath: string - } + default_config: IDefaultConfig } + +// 默认配置导出 export default { app_title: "zephyr", // 和风 default_config: { @@ -29,4 +41,4 @@ export default { "update.allowDowngrade": false, "update.allowPrerelease": false, }, -} as IConfig +} as const satisfies IConfig diff --git a/packages/locales/index.ts b/packages/locales/index.ts index e518c7b..dae47c4 100644 --- a/packages/locales/index.ts +++ b/packages/locales/index.ts @@ -1,41 +1,41 @@ if (import.meta.env.DEV) { - // 引入之后可以热更新 - import("./languages/zh.json") - import("./languages/en.json") + // 引入之后可以热更新 + import("./languages/zh.json") + import("./languages/en.json") } const datetimeFormats = { - en: { - short: { - year: "numeric", - month: "short", - day: "numeric", - }, - long: { - year: "numeric", - month: "short", - day: "numeric", - weekday: "short", - hour: "numeric", - minute: "numeric", - }, + en: { + short: { + year: "numeric", + month: "short", + day: "numeric", }, - zh: { - short: { - year: "numeric", - month: "short", - day: "numeric", - }, - long: { - year: "numeric", - month: "short", - day: "numeric", - weekday: "short", - hour: "numeric", - minute: "numeric", - hour12: true, - }, + long: { + year: "numeric", + month: "short", + day: "numeric", + weekday: "short", + hour: "numeric", + minute: "numeric", }, + }, + zh: { + short: { + year: "numeric", + month: "short", + day: "numeric", + }, + long: { + year: "numeric", + month: "short", + day: "numeric", + weekday: "short", + hour: "numeric", + minute: "numeric", + hour12: true, + }, + }, } export { datetimeFormats } diff --git a/packages/locales/main.ts b/packages/locales/main.ts index d217258..d49c0be 100644 --- a/packages/locales/main.ts +++ b/packages/locales/main.ts @@ -5,47 +5,47 @@ import zh from "./languages/zh.json" import en from "./languages/en.json" type FlattenObject = T extends object - ? { - [K in keyof T & (string | number)]: FlattenObject - }[keyof T & (string | number)] - : Prefix + ? { + [K in keyof T & (string | number)]: FlattenObject + }[keyof T & (string | number)] + : Prefix type FlattenKeys = FlattenObject type TranslationKey = FlattenKeys class Locale { - locale: string = "zh" - - constructor() { - try { - this.locale = app.getLocale() - } catch (e) { - console.log(e) - } - } + locale: string = "zh" - isCN(): boolean { - return this.locale.startsWith("zh") + constructor() { + try { + this.locale = app.getLocale() + } catch (e) { + console.log(e) } - - t(key: TranslationKey, replacements?: Record): string { - let text: string = this.isCN() ? get(zh, key) : get(en, key) - if (!text) { - text = get(zh, key) - if (!text) { - return key - } - } - if (replacements) { - // 替换所有形如 {key} 的占位符 - Object.entries(replacements).forEach(([key, value]) => { - console.log(text) - text = text.replace(new RegExp(`{${key}}`, "g"), value) - }) - } - return text + } + + isCN(): boolean { + return this.locale.startsWith("zh") + } + + t(key: TranslationKey, replacements?: Record): string { + let text: string = this.isCN() ? get(zh, key) : get(en, key) + if (!text) { + text = get(zh, key) + if (!text) { + return key + } + } + if (replacements) { + // 替换所有形如 {key} 的占位符 + Object.entries(replacements).forEach(([key, value]) => { + console.log(text) + text = text.replace(new RegExp(`{${key}}`, "g"), value) + }) } + return text + } } const Locales = new Locale() diff --git a/src/common/_ioc.main.ts b/src/common/_ioc.main.ts new file mode 100644 index 0000000..5efa038 --- /dev/null +++ b/src/common/_ioc.main.ts @@ -0,0 +1,17 @@ +import { Container, ContainerModule } from "inversify" +import UpdateCommand from "common/event/Update/main/command" +import PlatFormCommand from "common/event/PlatForm/main/command" +import TabsCommand from "common/event/Tabs/main/command" + +const modules = new ContainerModule(bind => { + bind("TabsCommand").to(TabsCommand).inSingletonScope() + bind("PlatFormCommand").to(PlatFormCommand).inSingletonScope() + bind("UpdateCommand").to(UpdateCommand).inSingletonScope() +}) + +async function destroyAllCommand(ioc: Container) { + await ioc.unloadAsync(modules) +} + +export { modules, destroyAllCommand } +export default modules diff --git a/src/common/event/PlatForm/index.ts b/src/common/event/PlatForm/index.ts index 2edf73e..267076a 100644 --- a/src/common/event/PlatForm/index.ts +++ b/src/common/event/PlatForm/index.ts @@ -1,24 +1,29 @@ import { _Base } from "common/lib/_Base" +import { ApiFactory } from "common/lib/abstract" class PlatForm extends _Base { constructor() { super() } + private get api() { + return ApiFactory.getApiClient() + } + async showAbout() { - return await fetch("api://fuck/BasicService/showAbout") + return this.api.call("BasicService.showAbout") } async isFullScreen() { - return await api.call("BasicCommand.isFullscreen") + return this.api.call("PlatFormCommand.isFullscreen") } async toggleFullScreen() { - return api.call("BasicCommand.fullscreen") + return this.api.call("PlatFormCommand.fullscreen") } async toggleDevTools() { - return api.call("BasicCommand.toggleDevTools") + return this.api.call("PlatFormCommand.toggleDevTools") } } diff --git a/src/common/event/PlatForm/main/command.ts b/src/common/event/PlatForm/main/command.ts new file mode 100644 index 0000000..46f7670 --- /dev/null +++ b/src/common/event/PlatForm/main/command.ts @@ -0,0 +1,81 @@ +import { app, dialog, nativeTheme, TitleBarOverlayOptions } from "electron" +import { inject } from "inversify" +import Tabs from "main/modules/tabs" +import WindowManager from "main/modules/window-manager" + +export default class PlatFormCommand { + constructor( + @inject(WindowManager) private _WindowManager: WindowManager, + @inject(Tabs) private _Tabs: Tabs, + ) {} + + setTheme(theme: typeof nativeTheme.themeSource) { + nativeTheme.themeSource = theme + } + + setTitlBar(options: TitleBarOverlayOptions) { + const mainWindow = this._WindowManager.getMainWindow() + if (mainWindow) { + mainWindow.setTitleBarOverlay(options) + } + } + + showAbout() { + this._WindowManager.showWindow("about") + } + + toggleDevTools() { + const focusedWindow = this._WindowManager.getFocusWindow() + if (focusedWindow) { + // @ts-ignore ... + focusedWindow.toggleDevTools() + } + } + fullscreen() { + const focusedWindow = this._WindowManager.getFocusWindow() + if (focusedWindow) { + const isFullScreen = focusedWindow!.isFullScreen() + focusedWindow!.setFullScreen(!isFullScreen) + } + } + + isFullscreen() { + const focusedWindow = this._WindowManager.getFocusWindow() + if (focusedWindow) { + return focusedWindow!.isFullScreen() + } + return false + } + + relunch() { + app.relaunch() + app.exit() + } + + reload() { + const focusedWindow = this._WindowManager.getFocusWindow() + // 重载之后, 刷新并关闭所有的次要窗体 + if (this._WindowManager.length() > 1 && focusedWindow && focusedWindow.$$opts!.name === this._WindowManager.mainInfo.name) { + const choice = dialog.showMessageBoxSync(focusedWindow, { + type: "question", + buttons: ["取消", "是的,继续", "不,算了"], + title: "警告", + defaultId: 2, + cancelId: 0, + message: "警告", + detail: "重载主窗口将关闭所有子窗口,是否继续", + }) + if (choice == 1) { + this._WindowManager.getWndows().forEach(win => { + if (win.$$opts!.name !== this._WindowManager.mainInfo.name) { + win.close() + } + }) + } else { + return + } + } + this._Tabs.closeAll() + focusedWindow!.reload() + } +} diff --git a/src/common/event/Tabs/main/command.ts b/src/common/event/Tabs/main/command.ts new file mode 100644 index 0000000..0619e17 --- /dev/null +++ b/src/common/event/Tabs/main/command.ts @@ -0,0 +1,65 @@ +import { inject } from "inversify" +import Tabs from "main/modules/tabs" +import WindowManager from "main/modules/window-manager" +import { broadcast } from "main/utils" + +class TabsCommand { + constructor( + @inject(Tabs) private _Tabs: Tabs, + @inject(WindowManager) private _WindowManager: WindowManager, + ) { + this._Tabs.events.on("update", this.listenerTabActive) + } + + listenerTabActive = () => { + broadcast("main:TabsCommand.update", this.getAllTabs()) + } + + bindElement(rect) { + this._Tabs.updateRect(rect) + } + + reload() { + this._WindowManager.getMainWindow()?.reload() + } + + sync() { + this.listenerTabActive() + if (!this.getAllTabs().length) { + this.add("about:blank") + } + } + + add(url) { + this._Tabs.add(url, true, this._WindowManager.getMainWindow()!) + } + + nagivate(index: number, url: string) { + this._Tabs.navigate(+index, url) + } + + closeAll() { + this._Tabs.closeAll() + } + + setActive(index) { + this._Tabs.changeActive(index) + } + + closeTab(e) { + this._Tabs.remove(e.body.active) + } + + getAllTabs() { + return this._Tabs._tabs.map(v => ({ + url: v.url, + showUrl: v.showUrl, + title: v.title, + favicons: v.favicons, + isActive: v.isActive, + })) + } +} + +export { TabsCommand } +export default TabsCommand diff --git a/src/common/event/update/index.ts b/src/common/event/update/index.ts index 5d11315..20f0ad3 100644 --- a/src/common/event/update/index.ts +++ b/src/common/event/update/index.ts @@ -1,9 +1,9 @@ -import type { AllKeys } from "../common" +// import type { AllKeys } from "../common" const curProgress = ref(0) -api.on("progress", () => { - curProgress.value = 10 -}) +// api.on("progress", () => { +// curProgress.value = 10 +// }) function useUpdate() { return { diff --git a/src/common/event/update/main.ts b/src/common/event/update/main.ts deleted file mode 100644 index 5f40482..0000000 --- a/src/common/event/update/main.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { broadcast } from "main/utils" -import { AllKeys } from "../common" - -function emitHotUpdateReady(...argu) { - broadcast("hot-update-ready", ...argu) -} - -export { emitHotUpdateReady } diff --git a/src/common/event/update/main/command.ts b/src/common/event/update/main/command.ts new file mode 100644 index 0000000..5407dc3 --- /dev/null +++ b/src/common/event/update/main/command.ts @@ -0,0 +1,10 @@ +import { inject } from "inversify" +import Updater from "main/modules/updater" + +export default class PlatFormCommand { + constructor(@inject(Updater) private _Updater: Updater) {} + + async triggerHotUpdate() { + await this._Updater.triggerHotUpdate() + } +} diff --git a/src/common/event/update/main/index.ts b/src/common/event/update/main/index.ts new file mode 100644 index 0000000..aa3132d --- /dev/null +++ b/src/common/event/update/main/index.ts @@ -0,0 +1,8 @@ +import { broadcast } from "main/utils" +import { AllKeys } from "common/event/common" + +function emitHotUpdateReady(...argu) { + broadcast("hot-update-ready", ...argu) +} + +export { emitHotUpdateReady } diff --git a/src/common/lib/abstract.ts b/src/common/lib/abstract.ts new file mode 100644 index 0000000..9712b8a --- /dev/null +++ b/src/common/lib/abstract.ts @@ -0,0 +1,53 @@ +import { ElectronApiClient } from "common/lib/electron" +import { BrowserApiClient } from "common/lib/browser" + +// 定义抽象 API 接口 +export interface IApiClient { + call(command: string, ...args: any[]): Promise + on(channel: K, callback: (...args: any[]) => void): void + off(channel: K, callback: (...args: any[]) => void): void + offAll(channel: K): void +} + +class NullApiClient implements IApiClient { + async call(command: string, ...args: any[]): Promise { + args + console.warn(`API call to ${command} failed: API client not initialized`) + return undefined as any + } + + on(channel: K, callback: (...args: any[]) => void): void { + callback + console.warn(`Failed to register listener for ${channel}: API client not initialized`) + } + + off(channel: K, callback: (...args: any[]) => void): void { + callback + console.warn(`Failed to unregister listener for ${channel}: API client not initialized`) + } + + offAll(channel: K): void { + console.warn(`Failed to unregister all listeners for ${channel}: API client not initialized`) + } +} + +// 创建 API 工厂 +export class ApiFactory { + private static instance: IApiClient = new NullApiClient() // 默认使用空实现 + + static setApiClient(client: IApiClient) { + this.instance = client + } + + static getApiClient(): IApiClient { + if (this.instance instanceof NullApiClient) { + // 根据环境选择合适的 API 客户端 + if (window.api && window.electron) { + this.instance = new ElectronApiClient() + } else { + this.instance = new BrowserApiClient() + } + } + return this.instance + } +} diff --git a/src/common/lib/browser.ts b/src/common/lib/browser.ts new file mode 100644 index 0000000..100e60d --- /dev/null +++ b/src/common/lib/browser.ts @@ -0,0 +1,29 @@ +import { IApiClient } from "./abstract" + +export class BrowserApiClient implements IApiClient { + call(command: string, ...args: any[]): Promise { + // 浏览器特定实现,可能使用 fetch 或其他方式 + const [service, method] = command.split(".") + return fetch(`/api/${service}/${method}`, { + method: "POST", + body: JSON.stringify(args), + headers: { "Content-Type": "application/json" }, + }).then(res => res.json()) + } + + // 实现其他方法... + on(channel: K, callback: (...args: any[]) => void): void { + // 浏览器中可能使用 WebSocket 或其他方式 + console.log("不支持 on 方法", channel, callback) + } + + off(channel: K, callback: (...args: any[]) => void): void { + // 相应的解绑实现 + console.log("不支持 on 方法", channel, callback) + } + + offAll(channel: K): void { + // 相应的全部解绑实现 + console.log("不支持 on 方法", channel) + } +} diff --git a/src/common/lib/electron.ts b/src/common/lib/electron.ts new file mode 100644 index 0000000..27908a5 --- /dev/null +++ b/src/common/lib/electron.ts @@ -0,0 +1,20 @@ +import { IApiClient } from "./abstract" + +export class ElectronApiClient implements IApiClient { + call(command: string, ...args: any[]): Promise { + // Electron 特定实现 + return window.api.call(command, ...args) + } + + on(channel: K, callback: (...args: any[]) => void): void { + window.api.on(channel, callback) + } + + off(channel: K, callback: (...args: any[]) => void): void { + window.api.off(channel, callback) + } + + offAll(channel: K): void { + window.api.offAll(channel) + } +} diff --git a/src/main/App.ts b/src/main/App.ts index 8dc4b67..b440f86 100644 --- a/src/main/App.ts +++ b/src/main/App.ts @@ -70,8 +70,8 @@ class App extends BaseClass { this._Zephyr.init() electronApp.setAppUserModelId("top.xieyaxin") this._WindowManager.showMainWindow() - this._Command.invoke("BasicCommand.setTheme", "light") - this._Command.invoke("BasicCommand.setTitlBar", { + this._Command.invoke("PlatFormCommand.setTheme", "light") + this._Command.invoke("PlatFormCommand.setTitlBar", { height: 29, color: "#F8F8F8", symbolColor: "#000000", diff --git a/src/main/_ioc.ts b/src/main/_ioc.ts index 6d5311c..7613d44 100644 --- a/src/main/_ioc.ts +++ b/src/main/_ioc.ts @@ -2,7 +2,7 @@ import IOC from "./_iocClass" import { Container } from "inversify" import iocModules, { destroyAllModules } from "./modules/_ioc" import iocController, { destroyAllController } from "./controller/_ioc" -import iocCommand, { destroyAllCommand } from "./commands/_ioc" +import iocCommand, { destroyAllCommand } from "common/_ioc.main" import App from "./App" async function destroyAll() { diff --git a/src/main/commands/BasicCommand.ts b/src/main/commands/BasicCommand.ts deleted file mode 100644 index c4c0fe1..0000000 --- a/src/main/commands/BasicCommand.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { app, dialog, nativeTheme, TitleBarOverlayOptions } from "electron" -import { inject } from "inversify" -import Tabs from "main/modules/tabs" -import WindowManager from "main/modules/window-manager" - -export default class BasicCommand { - constructor( - @inject(WindowManager) private _WindowManager: WindowManager, - @inject(Tabs) private _Tabs: Tabs, - ) {} - - setTheme(theme: typeof nativeTheme.themeSource) { - nativeTheme.themeSource = theme - } - - setTitlBar(options: TitleBarOverlayOptions) { - const mainWindow = this._WindowManager.getMainWindow() - if (mainWindow) { - mainWindow.setTitleBarOverlay(options) - } - } - - toggleDevTools() { - const focusedWindow = this._WindowManager.getFocusWindow() - if (focusedWindow) { - // @ts-ignore ... - focusedWindow.toggleDevTools() - } - } - fullscreen() { - const focusedWindow = this._WindowManager.getFocusWindow() - if (focusedWindow) { - const isFullScreen = focusedWindow!.isFullScreen() - focusedWindow!.setFullScreen(!isFullScreen) - } - } - - isFullscreen() { - const focusedWindow = this._WindowManager.getFocusWindow() - if (focusedWindow) { - return focusedWindow!.isFullScreen() - } - return false - } - - relunch() { - app.relaunch() - app.exit() - } - - reload() { - const focusedWindow = this._WindowManager.getFocusWindow() - // 重载之后, 刷新并关闭所有的次要窗体 - if (this._WindowManager.length() > 1 && focusedWindow && focusedWindow.$$opts!.name === this._WindowManager.mainInfo.name) { - const choice = dialog.showMessageBoxSync(focusedWindow, { - type: "question", - buttons: ["取消", "是的,继续", "不,算了"], - title: "警告", - defaultId: 2, - cancelId: 0, - message: "警告", - detail: "重载主窗口将关闭所有子窗口,是否继续", - }) - if (choice == 1) { - this._WindowManager.getWndows().forEach(win => { - if (win.$$opts!.name !== this._WindowManager.mainInfo.name) { - win.close() - } - }) - } else { - return - } - } - this._Tabs.closeAll() - focusedWindow!.reload() - } -} diff --git a/src/main/commands/SettingCommand.ts b/src/main/commands/SettingCommand.ts deleted file mode 100644 index 6ff9095..0000000 --- a/src/main/commands/SettingCommand.ts +++ /dev/null @@ -1,12 +0,0 @@ -// 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/commands/TabsCommand.ts b/src/main/commands/TabsCommand.ts deleted file mode 100644 index 0619e17..0000000 --- a/src/main/commands/TabsCommand.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { inject } from "inversify" -import Tabs from "main/modules/tabs" -import WindowManager from "main/modules/window-manager" -import { broadcast } from "main/utils" - -class TabsCommand { - constructor( - @inject(Tabs) private _Tabs: Tabs, - @inject(WindowManager) private _WindowManager: WindowManager, - ) { - this._Tabs.events.on("update", this.listenerTabActive) - } - - listenerTabActive = () => { - broadcast("main:TabsCommand.update", this.getAllTabs()) - } - - bindElement(rect) { - this._Tabs.updateRect(rect) - } - - reload() { - this._WindowManager.getMainWindow()?.reload() - } - - sync() { - this.listenerTabActive() - if (!this.getAllTabs().length) { - this.add("about:blank") - } - } - - add(url) { - this._Tabs.add(url, true, this._WindowManager.getMainWindow()!) - } - - nagivate(index: number, url: string) { - this._Tabs.navigate(+index, url) - } - - closeAll() { - this._Tabs.closeAll() - } - - setActive(index) { - this._Tabs.changeActive(index) - } - - closeTab(e) { - this._Tabs.remove(e.body.active) - } - - getAllTabs() { - return this._Tabs._tabs.map(v => ({ - url: v.url, - showUrl: v.showUrl, - title: v.title, - favicons: v.favicons, - isActive: v.isActive, - })) - } -} - -export { TabsCommand } -export default TabsCommand diff --git a/src/main/commands/UpdateCommand.ts b/src/main/commands/UpdateCommand.ts deleted file mode 100644 index d967bc7..0000000 --- a/src/main/commands/UpdateCommand.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { inject } from "inversify" -import Updater from "main/modules/updater" - -export default class BasicCommand { - constructor(@inject(Updater) private _Updater: Updater) {} - - async triggerHotUpdate() { - await this._Updater.triggerHotUpdate() - } -} diff --git a/src/main/commands/_ioc.ts b/src/main/commands/_ioc.ts deleted file mode 100644 index 8c00409..0000000 --- a/src/main/commands/_ioc.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Container, ContainerModule } from "inversify" -import BasicCommand from "./BasicCommand" -import TabsCommand from "./TabsCommand" -import UpdateCommand from "./UpdateCommand" - -// TODO 考虑迁移,将所有命令都注册common/event中 - -const modules = new ContainerModule(bind => { - bind("BasicCommand").to(BasicCommand).inSingletonScope() - bind("TabsCommand").to(TabsCommand).inSingletonScope() - bind("UpdateCommand").to(UpdateCommand).inSingletonScope() -}) - -async function destroyAllCommand(ioc: Container) { - await ioc.unloadAsync(modules) -} - -export { modules, destroyAllCommand } -export default modules diff --git a/src/renderer/src/main.ts b/src/renderer/src/main.ts index 904ede1..1102c55 100644 --- a/src/renderer/src/main.ts +++ b/src/renderer/src/main.ts @@ -10,6 +10,19 @@ import router from "./router" import i18n from "./i18n" const app = createApp(App) + +// 全局错误处理 +app.config.errorHandler = (err, instance, info) => { + console.error("应用错误:", err) + console.info("错误信息:", info) + // 可以添加错误上报逻辑 +} + +// 开发环境下的性能监控 +if (import.meta.env.DEV) { + app.config.performance = true +} + app.use(i18n) -app.use(router as any) +app.use(router) app.mount("#app") diff --git a/tsconfig.node.json b/tsconfig.node.json index c967ae0..78ada96 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -8,6 +8,7 @@ "src/types/**/*", "packages/locales/main.ts", "src/common/**/*.main.ts", + "src/common/**/main/**/*", "src/common/**/main.ts", "src/common/**/*.common.ts", "src/common/**/common.ts" diff --git a/tsconfig.web.json b/tsconfig.web.json index ad767d6..778190b 100644 --- a/tsconfig.web.json +++ b/tsconfig.web.json @@ -15,6 +15,7 @@ ], "exclude": [ "packages/locales/main.ts", + "src/common/**/main/**/*", "src/common/**/*.main.ts", "src/common/**/main.ts" ],