npmrun 2 months ago
parent
commit
a4e4373737
  1. 1
      .npmrc
  2. 2
      electron.vite.config.ts
  3. 5
      package.json
  4. 5
      packages/IPC/common/utils.ts
  5. 0
      packages/IPC/main/index.ts
  6. 12
      packages/IPC/package.json
  7. 0
      packages/IPC/renderer/index.ts
  8. 4
      packages/IPC/tsconfig.json
  9. 10
      packages/IPC/tsconfig.node.json
  10. 12
      packages/IPC/tsconfig.web.json
  11. 0
      packages/IPC/types/index.d.ts
  12. 4
      pnpm-lock.yaml
  13. 2
      pnpm-workspace.yaml
  14. 3
      src/main/App.ts
  15. 13
      src/main/commands/TabsCommand.ts
  16. 6
      src/main/controller/BasicService.ts
  17. 6
      src/main/controller/TabsService.ts
  18. 4
      src/main/index.ts
  19. 4
      src/main/modules/_ioc.ts
  20. 6
      src/main/modules/api/index.ts
  21. 6
      src/main/modules/commands/index.ts
  22. 2
      src/main/modules/db/index.ts
  23. 2
      src/main/modules/setting/index.ts
  24. 2
      src/main/modules/tabs/Tab.ts
  25. 6
      src/main/modules/tabs/index.ts
  26. 112
      src/main/modules/updater/index.ts
  27. 2
      src/main/modules/window-manager/index.ts
  28. 2
      src/main/modules/window-manager/windowsMap.ts
  29. 8
      src/main/modules/zephyr/index.ts
  30. 7
      src/renderer/src/App.vue
  31. 2
      tsconfig.node.json

1
.npmrc

@ -1,3 +1,4 @@
electron_mirror=https://npmmirror.com/mirrors/electron/
electron_builder_binaries_mirror=https://npmmirror.com/mirrors/electron-builder-binaries/
shamefully-hoist=true
link-workspace-packages=true

2
electron.vite.config.ts

@ -8,7 +8,7 @@ export default defineConfig({
resolve: {
alias: {
config: resolve("config"),
vc: resolve("src/main"),
main: resolve("src/main"),
res: resolve("resources"),
},
},

5
package.json

@ -1,6 +1,7 @@
{
"name": "my-app",
"name": "zephyr",
"type": "module",
"private": true,
"version": "1.0.0",
"description": "An Electron application with Vue and TypeScript",
"main": "./out/main/index.js",
@ -53,7 +54,7 @@
"typescript": "^5.5.2",
"unocss": "^0.64.1",
"vite": "^5.3.1",
"vue": "^3.4.30",
"vue": "^3.5.12",
"vue-tsc": "^2.0.22"
}
}

5
packages/IPC/common/utils.ts

@ -0,0 +1,5 @@
import { webContents } from "electron"
export const broadcast = (event: string, ...args: any[]) => {
webContents.getAllWebContents().forEach(browser => browser.send(event, ...args))
}

0
packages/IPC/main/index.ts

12
packages/IPC/package.json

@ -0,0 +1,12 @@
{
"name": "z-ipc",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}

0
packages/IPC/renderer/index.ts

4
packages/IPC/tsconfig.json

@ -0,0 +1,4 @@
{
"files": [],
"references": [{ "path": "./tsconfig.node.json" }, { "path": "./tsconfig.web.json" }]
}

10
packages/IPC/tsconfig.node.json

@ -0,0 +1,10 @@
{
"extends": "@electron-toolkit/tsconfig/tsconfig.node.json",
"include": ["main/**/*", "preload/**/*", "common/**/*", "types/**/*"],
"compilerOptions": {
"composite": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"types": ["electron-vite/node"],
}
}

12
packages/IPC/tsconfig.web.json

@ -0,0 +1,12 @@
{
"extends": "@electron-toolkit/tsconfig/tsconfig.web.json",
"include": [
"renderer/**/*",
"preload/**/*",
"common/**/*",
"types/**/*"
],
"compilerOptions": {
"composite": true
}
}

0
packages/IPC/types/index.d.ts

4
pnpm-lock.yaml

@ -94,12 +94,14 @@ importers:
specifier: ^5.3.1
version: 5.4.11(@types/node@20.15.0)(sass@1.81.0)
vue:
specifier: ^3.4.30
specifier: ^3.5.12
version: 3.5.12(typescript@5.6.3)
vue-tsc:
specifier: ^2.0.22
version: 2.1.10(typescript@5.6.3)
packages/IPC: {}
packages:
7zip-bin@5.2.0:

2
pnpm-workspace.yaml

@ -0,0 +1,2 @@
packages:
- "packages/*"

3
src/main/App.ts

@ -10,6 +10,7 @@ import BaseClass from "./base/base"
import IOC from "./_ioc"
import DB from "./modules/db"
import Zephyr from "./modules/zephyr"
import Updater from "./modules/updater"
protocol.registerSchemesAsPrivileged([
// {
@ -54,11 +55,13 @@ class App extends BaseClass {
@inject(DB) private _DB: DB,
@inject(WindowManager) private _WindowManager: WindowManager,
@inject(Zephyr) private _Zephyr: Zephyr,
@inject(Updater) private _Updater: Updater,
) {
super()
}
async init() {
this._Updater.init()
this._DB.init()
this._Command.init()
this._WindowManager.init()

13
src/main/commands/TabsCommand.ts

@ -1,7 +1,7 @@
import { inject } from "inversify"
import Tabs from "vc/modules/tabs"
import WindowManager from "vc/modules/window-manager"
import { broadcast } from "vc/utils"
import Tabs from "main/modules/tabs"
import WindowManager from "main/modules/window-manager"
import { broadcast } from "main/utils"
class TabsCommand {
static name: string = "TabsCommand"
@ -11,12 +11,7 @@ class TabsCommand {
@inject(WindowManager) private _WindowManager: WindowManager,
) {
this.listenerTabActive = this.listenerTabActive.bind(this)
this._Tabs.events.addListener("update", this.listenerTabActive)
}
init() {
const mainWindow = this._WindowManager.getMainWindow()
this._Tabs.init(mainWindow)
this._Tabs.events.on("update", this.listenerTabActive)
}
bindElement(rect) {

6
src/main/controller/BasicService.ts

@ -1,7 +1,7 @@
import { inject, injectable } from "inversify"
import BaseContainer from "vc/base/baseContainer"
import Tabs from "vc/modules/tabs"
import WindowManager from "vc/modules/window-manager"
import BaseContainer from "main/base/baseContainer"
import Tabs from "main/modules/tabs"
import WindowManager from "main/modules/window-manager"
@injectable()
class BasicService extends BaseContainer {

6
src/main/controller/TabsService.ts

@ -1,7 +1,7 @@
import { inject, injectable } from "inversify"
import BaseContainer from "vc/base/baseContainer"
import Tabs from "vc/modules/tabs"
import WindowManager from "vc/modules/window-manager"
import BaseContainer from "main/base/baseContainer"
import Tabs from "main/modules/tabs"
import WindowManager from "main/modules/window-manager"
@injectable()
class TabsService extends BaseContainer {

4
src/main/index.ts

@ -1,6 +1,6 @@
import "reflect-metadata"
import { _ioc } from "vc/_ioc"
import { App } from "vc/App"
import { _ioc } from "main/_ioc"
import { App } from "main/App"
const curApp = _ioc.get(App)
curApp.init()

4
src/main/modules/_ioc.ts

@ -6,10 +6,12 @@ import { WindowManager } from "./window-manager"
import { Tabs } from "./tabs"
import Commands from "./commands"
import Zephyr from "./zephyr"
import Updater from "./updater"
const modules = new ContainerModule(bind => {
bind(Setting).toConstantValue(new Setting())
bind(Zephyr).toSelf().inSingletonScope()
bind(Updater).toSelf().inSingletonScope()
bind(Api).toSelf().inSingletonScope()
bind(WindowManager).toSelf().inSingletonScope()
bind(Commands).toSelf().inSingletonScope()
@ -22,6 +24,8 @@ async function destroyAllModules(ioc: Container) {
ioc.get(Setting).destroy(),
ioc.get(WindowManager).destroy(),
ioc.get(Commands).destroy(),
ioc.get(Updater).destroy(),
ioc.get(Zephyr).destroy(),
ioc.get(Tabs).destroy(),
ioc.get(Api).destroy(),
ioc.get(DB).destroy(),

6
src/main/modules/api/index.ts

@ -1,7 +1,7 @@
import { session, net } from "electron"
import { inject, injectable } from "inversify"
import IOC from "vc/_ioc"
import BaseClass from "vc/base/base"
import IOC from "main/_ioc"
import BaseClass from "main/base/base"
@injectable()
class Api extends BaseClass {
@ -32,7 +32,7 @@ class Api extends BaseClass {
const fnName = array[array.length - 1]
// https://vitejs.cn/vite5-cn/guide/features.html#dynamic-import
const module = await this._IOC.getAsync(routePath)
// const module = await import(`vc/controller/${routePath}.ts`)
// const module = await import(`main/controller/${routePath}.ts`)
const opts = { body: {}, query: {} }
if (isPost) {
opts.body = await request.json()

6
src/main/modules/commands/index.ts

@ -1,9 +1,9 @@
import { IMenuItemOption, IPopupMenuOption } from "#"
import { ipcMain, Menu, MenuItem } from "electron"
import { inject } from "inversify"
import IOC from "vc/_ioc"
import BaseClass from "vc/base/base"
import { isPromise } from "vc/utils"
import IOC from "main/_ioc"
import BaseClass from "main/base/base"
import { isPromise } from "main/utils"
import WindowManager from "../window-manager"
export default class Commands extends BaseClass {

2
src/main/modules/db/index.ts

@ -2,7 +2,7 @@ import { inject, injectable } from "inversify"
import Setting from "../setting"
import { CustomAdapter, CustomLow } from "./custom"
import path from "node:path"
import BaseClass from "vc/base/base"
import BaseClass from "main/base/base"
import _debug from "debug"
const debug = _debug("app:db")

2
src/main/modules/setting/index.ts

@ -5,7 +5,7 @@ import { cloneDeep } from "lodash"
import { injectable } from "inversify"
import Config from "config"
import _debug from "debug"
import BaseClass from "vc/base/base"
import BaseClass from "main/base/base"
const debug = _debug("app:setting")

2
src/main/modules/tabs/Tab.ts

@ -1,6 +1,6 @@
import { BrowserWindow, WebContentsView, WebPreferences } from "electron"
import { join } from "node:path"
import BaseClass from "vc/base/base"
import BaseClass from "main/base/base"
import _debug from "debug"
// import { Layout } from "./Constant"
import FuckHTML from "res/fuck.html?asset"

6
src/main/modules/tabs/index.ts

@ -1,5 +1,5 @@
import Tab from "./Tab"
import BaseClass from "vc/base/base"
import BaseClass from "main/base/base"
import _debug from "debug"
import { BrowserWindow } from "electron"
import EventEmitter from "events"
@ -34,8 +34,8 @@ class Tabs extends BaseClass {
_tabs: Tab[] = []
init(mainWindow) {
this.add("about:blank", true, mainWindow)
init() {
// 初始化
}
updateRect(curRect: IRect) {

112
src/main/modules/updater/index.ts

@ -0,0 +1,112 @@
import pkg from "electron-updater"
import { app, dialog } from "electron"
import { injectable, inject } from "inversify"
import BaseClass from "main/base/base"
import { Setting } from "../setting"
import _debug from "debug"
import EventEmitter from "events"
const debug = _debug("app:updater")
const { autoUpdater } = pkg
@injectable()
export class Updater extends BaseClass {
public events = new EventEmitter()
constructor(@inject(Setting) private _Setting: Setting) {
super()
// 配置自动更新
autoUpdater.autoDownload = false
autoUpdater.autoInstallOnAppQuit = true
// 检查更新错误
autoUpdater.on("error", error => {
debug("Update error:", error)
})
// 检查更新
autoUpdater.on("checking-for-update", () => {
debug("Checking for updates...")
})
// 有可用更新
autoUpdater.on("update-available", info => {
debug("Update available:", info)
this.promptUserToUpdate()
})
// 没有可用更新
autoUpdater.on("update-not-available", info => {
debug("Update not available:", info)
})
// 更新下载进度
autoUpdater.on("download-progress", progressObj => {
debug(
`Download speed: ${progressObj.bytesPerSecond} - Downloaded ${progressObj.percent}% (${progressObj.transferred}/${progressObj.total})`,
)
})
// 更新下载完成
autoUpdater.on("update-downloaded", info => {
debug("Update downloaded:", info)
this.promptUserToInstall()
})
}
init() {
// 定期检查更新
this.checkForUpdates()
setInterval(
() => {
this.checkForUpdates()
},
1000 * 60 * 60,
) // 每小时检查一次
}
destroy() {
// 清理工作
}
private async checkForUpdates() {
if (app.isPackaged) {
try {
await autoUpdater.checkForUpdates()
} catch (error) {
debug("Failed to check for updates:", error)
}
}
}
private async promptUserToUpdate() {
const result = await dialog.showMessageBox({
type: "info",
title: "发现新版本",
message: "是否下载新版本?",
buttons: ["下载", "暂不更新"],
defaultId: 0,
})
if (result.response === 0) {
autoUpdater.downloadUpdate()
}
}
private async promptUserToInstall() {
const result = await dialog.showMessageBox({
type: "info",
title: "更新已就绪",
message: "新版本已下载完成,是否立即安装?",
buttons: ["立即安装", "稍后安装"],
defaultId: 0,
})
if (result.response === 0) {
autoUpdater.quitAndInstall(false, true)
}
}
}
export default Updater

2
src/main/modules/window-manager/index.ts

@ -2,7 +2,7 @@ import { BrowserWindow, app, dialog } from "electron"
import { cloneDeep, merge } from "lodash"
import { defaultConfig, defaultWindowConfig, getWindowsMap, IConfig, Param } from "./windowsMap"
import { optimizer } from "@electron-toolkit/utils"
import BaseClass from "vc/base/base"
import BaseClass from "main/base/base"
import _debug from "debug"
const debug = _debug("app:window-manager")

2
src/main/modules/window-manager/windowsMap.ts

@ -1,6 +1,6 @@
import config from "config"
import { BrowserWindowConstructorOptions } from "electron"
import { getFileUrl } from "vc/utils"
import { getFileUrl } from "main/utils"
import icon from "res/icon.png?asset"
import { join } from "path"

8
src/main/modules/zephyr/index.ts

@ -1,13 +1,17 @@
import { session, net } from "electron"
import { inject, injectable } from "inversify"
import IOC from "vc/_ioc"
import BaseClass from "vc/base/base"
import IOC from "main/_ioc"
import BaseClass from "main/base/base"
import _debug from "debug"
const debug = _debug("app:zephyr")
@injectable()
class Zephyr extends BaseClass {
constructor(@inject(IOC) private _IOC: IOC) {
super()
this.interceptHandlerZephyr = this.interceptHandlerZephyr.bind(this)
debug("aaaaaaaaaaaaaaaaaaaaaa")
}
destroy() {

7
src/renderer/src/App.vue

@ -1,11 +1,11 @@
<script setup lang="ts">
import NavBar from "@renderer/components/NavBar.vue"
import { onBeforeMount, onBeforeUnmount, onMounted, ref } from "vue"
import { onBeforeMount, onBeforeUnmount, onMounted, ref, useTemplateRef } from "vue"
import { PopupMenu } from "./bridge/PopupMenu"
const PlaceHolder = ref<HTMLDivElement>()
const PlaceHolderRef = useTemplateRef("PlaceHolder")
function OnResize() {
const el = PlaceHolder.value
const el = PlaceHolderRef.value
if (el) {
const rect = el.getBoundingClientRect().toJSON()
console.log(rect)
@ -36,7 +36,6 @@ if (import.meta.hot) {
}
api.on("TabsCommand.update", listener)
onMounted(() => {
api.call("TabsCommand.init")
api.call("TabsCommand.sync")
})

2
tsconfig.node.json

@ -12,7 +12,7 @@
"#/*": ["src/types/*"],
"config": ["config/index.ts"],
"config/*": ["config/*"],
"vc/*": ["src/main/*"],
"main/*": ["src/main/*"],
"res/*": ["resources/*"],
}
}

Loading…
Cancel
Save