diff --git a/package-lock.json b/package-lock.json index d6f7c72..819b952 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1734,7 +1734,7 @@ }, "@types/node": { "version": "15.14.3", - "resolved": "https://registry.nlark.com/@types/node/download/@types/node-15.14.3.tgz?cache=0&sync_timestamp=1627257813519&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-15.14.3.tgz", + "resolved": "https://registry.nlark.com/@types/node/download/@types/node-15.14.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-15.14.3.tgz", "integrity": "sha1-MwdjuXPQrKy3/czHWU4fsoHtGxw=", "dev": true }, @@ -4492,7 +4492,7 @@ }, "ejs": { "version": "3.1.6", - "resolved": "https://registry.nlark.com/ejs/download/ejs-3.1.6.tgz", + "resolved": "https://registry.npm.taobao.org/ejs/download/ejs-3.1.6.tgz", "integrity": "sha1-W/0KBol0O7UmizVQzO7rvBcCgio=", "dev": true, "requires": { @@ -6365,7 +6365,7 @@ }, "jake": { "version": "10.8.2", - "resolved": "https://registry.npm.taobao.org/jake/download/jake-10.8.2.tgz", + "resolved": "https://registry.npm.taobao.org/jake/download/jake-10.8.2.tgz?cache=0&sync_timestamp=1591684013969&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjake%2Fdownload%2Fjake-10.8.2.tgz", "integrity": "sha1-68nehVgWCmbYLQ6txqLlj7xQCns=", "dev": true, "requires": { @@ -6418,7 +6418,7 @@ }, "escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.nlark.com/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz", + "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz?cache=0&sync_timestamp=1618677243201&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescape-string-regexp%2Fdownload%2Fescape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, @@ -7196,7 +7196,7 @@ }, "object.assign": { "version": "4.1.2", - "resolved": "https://registry.nlark.com/object.assign/download/object.assign-4.1.2.tgz", + "resolved": "https://registry.npm.taobao.org/object.assign/download/object.assign-4.1.2.tgz?cache=0&sync_timestamp=1604115158081&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fobject.assign%2Fdownload%2Fobject.assign-4.1.2.tgz", "integrity": "sha1-DtVKNC7Os3s4/3brgxoOeIy2OUA=", "dev": true, "requires": { @@ -9157,7 +9157,7 @@ "dependencies": { "commander": { "version": "2.20.3", - "resolved": "https://registry.nlark.com/commander/download/commander-2.20.3.tgz?cache=0&sync_timestamp=1627358203890&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcommander%2Fdownload%2Fcommander-2.20.3.tgz", + "resolved": "https://registry.nlark.com/commander/download/commander-2.20.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcommander%2Fdownload%2Fcommander-2.20.3.tgz", "integrity": "sha1-/UhehMA+tIgcIHIrpIA16FMa6zM=", "dev": true }, @@ -9174,7 +9174,7 @@ }, "terser": { "version": "5.7.1", - "resolved": "https://registry.nlark.com/terser/download/terser-5.7.1.tgz?cache=0&sync_timestamp=1624884102109&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fterser%2Fdownload%2Fterser-5.7.1.tgz", + "resolved": "https://registry.nlark.com/terser/download/terser-5.7.1.tgz", "integrity": "sha1-LcemEAm2a7Y4MFyyqCR2OxFr94Q=", "dev": true, "requires": { @@ -9185,7 +9185,7 @@ "dependencies": { "source-map": { "version": "0.7.3", - "resolved": "https://registry.nlark.com/source-map/download/source-map-0.7.3.tgz", + "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.7.3.tgz", "integrity": "sha1-UwL4FpAxc1ImVECS5kmB91F1A4M=", "dev": true } @@ -9749,7 +9749,7 @@ }, "vite": { "version": "2.4.3", - "resolved": "https://registry.nlark.com/vite/download/vite-2.4.3.tgz", + "resolved": "https://registry.nlark.com/vite/download/vite-2.4.3.tgz?cache=0&sync_timestamp=1626783291368&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fvite%2Fdownload%2Fvite-2.4.3.tgz", "integrity": "sha1-/kqnjp3X02vLEuzL1SMTsmz633c=", "dev": true, "requires": { @@ -9923,7 +9923,7 @@ "dependencies": { "commander": { "version": "7.2.0", - "resolved": "https://registry.nlark.com/commander/download/commander-7.2.0.tgz?cache=0&sync_timestamp=1627358203890&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcommander%2Fdownload%2Fcommander-7.2.0.tgz", + "resolved": "https://registry.nlark.com/commander/download/commander-7.2.0.tgz?cache=0&sync_timestamp=1624609539421&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcommander%2Fdownload%2Fcommander-7.2.0.tgz", "integrity": "sha1-o2y1fQtQHOEI5NIFWaFQo5HZerc=", "dev": true } @@ -10515,7 +10515,7 @@ }, "websocket-driver": { "version": "0.7.4", - "resolved": "https://registry.nlark.com/websocket-driver/download/websocket-driver-0.7.4.tgz", + "resolved": "https://registry.npm.taobao.org/websocket-driver/download/websocket-driver-0.7.4.tgz", "integrity": "sha1-ia1Slbv2S0gKvLox5JU6ynBvV2A=", "dev": true, "requires": { diff --git a/src/main/disk.ts b/src/main/disk.ts new file mode 100644 index 0000000..a6e82e8 --- /dev/null +++ b/src/main/disk.ts @@ -0,0 +1,63 @@ +import Shared from "./share" +import { Menu, Tray, ipcMain, BrowserWindow, App } from "electron" +const path = require("path") + +// 隐藏主窗口,并创建托盘,绑定关闭事件 +export default function setTray(app: App, mainWindow: BrowserWindow) { + if (Shared.data.miniWindow) { + mainWindow.hide() + return + } + // 用一个 Tray 来表示一个图标,这个图标处于正在运行的系统的通知区 + // 通常被添加到一个 context menu 上. + // 系统托盘右键菜单 + const trayMenuTemplate = [ + { + // 系统托盘图标目录 + label: "打开主窗口", + click: () => { + mainWindow.show() + }, + }, + { + // 系统托盘图标目录 + label: "打开悬浮窗", + click: () => { + ipcMain.emit("showSuspensionWindow") + }, + }, + { + // 系统托盘图标目录 + label: "退出", + click: () => { + Shared.data.forceClose = true + app.quit() + }, + }, + ] + // 设置系统托盘图标 + const iconPath = path.join(__static, "/icon.png") + + Shared.data.miniWindow = new Tray(iconPath) + + // 图标的上下文菜单 + const contextMenu = Menu.buildFromTemplate(trayMenuTemplate) + + // 展示主窗口,隐藏主窗口 mainWindow.hide() + mainWindow.hide() + + // 设置托盘悬浮提示 + Shared.data.miniWindow.setToolTip("never forget") + + // 设置托盘菜单 + Shared.data.miniWindow.setContextMenu(contextMenu) + + // 单击托盘小图标显示应用 + Shared.data.miniWindow.on("double-click", () => { + // 显示主程序 + mainWindow.show() + // 关闭托盘显示 + // Shared.data.miniWindow.destroy(); + }) + return Shared.data.miniWindow +} diff --git a/src/main/facilities/index.ts b/src/main/facilities/index.ts new file mode 100644 index 0000000..b624373 --- /dev/null +++ b/src/main/facilities/index.ts @@ -0,0 +1,20 @@ +import { ipcMain, dialog } from "electron" + +/** + * 格式:@类型:扩展:函数 + */ + +// 保存数据 +ipcMain.on("@func:buildin:close", data => { + // dialog.showMessageBox( + // { + // type: "info", + // title: "Information", + // defaultId: 0, + // cancelId: 0, + // message: "确定要关闭吗?" + data, + // buttons: ["没事", "最小化到托盘", "直接退出"], + // }, + // index => {} + // ) +}) diff --git a/src/main/float.ts b/src/main/float.ts new file mode 100644 index 0000000..691e7eb --- /dev/null +++ b/src/main/float.ts @@ -0,0 +1,121 @@ +import Shared from "./share" +import { BrowserWindow, ipcMain, screen, Menu, shell, webContents } from "electron" +// webContents +console.log(webContents.getAllWebContents()) + +const window: any = null //BrowserWindow.fromWebContents(webContents.getFocusedWebContents()) +const winURL = + process.env.NODE_ENV === "development" ? `http://localhost:${process.env.PORT}/#/float` : `file://${__dirname}/index.html#/float` + +ipcMain.on("@float:setPosition", (event, x, y) => { + Shared.data.floatWindow?.setPosition(x, y) +}) + +ipcMain.on("showSuspensionWindow", () => { + console.log(24324) + + if (Shared.data.floatWindow) { + if (Shared.data.floatWindow.isVisible()) { + createSuspensionWindow() + } else { + Shared.data.floatWindow.showInactive() + } + } else { + createSuspensionWindow() + } +}) + +ipcMain.on("createSuspensionMenu", e => { + const rightM = Menu.buildFromTemplate([ + { label: "开始全部任务", enabled: false }, + { label: "暂停全部任务", enabled: false }, + { + label: "本次传输完自动关机", + click: () => { + ipcMain.emit("@func:buildin:saveData", 32232) + }, + }, + { type: "separator" }, + { + label: "隐藏悬浮窗", + click: () => { + if (window) { + window.webContents.send("hideSuspension", false) + } + Shared.data.floatWindow.hide() + }, + }, + { + label: "打开主窗口", + click: () => { + // && !Shared.data.mainWindow.isVisible() + if (Shared.data.mainWindow) { + Shared.data.mainWindow.show() + } + // window.webContents.send('hideSuspension', false) + }, + }, + { type: "separator" }, + { + label: "加入qq群", + click: () => { + shell.openExternal( + "tencent://groupwpa/?subcmd=all¶m=7B2267726F757055696E223A3831343237303636392C2274696D655374616D70223A313533393531303138387D0A" + ) + }, + }, + { + label: "GitHub地址", + click: () => { + shell.openExternal("https://github.com/lihaotian0607/auth") + }, + }, + { + label: "退出软件", + click: () => { + Shared.data.mainWindow.close() + }, + }, + ]) + rightM.popup({}) +}) + +function createSuspensionWindow() { + Shared.data.floatWindow = new BrowserWindow({ + width: 102, // 悬浮窗口的宽度 比实际DIV的宽度要多2px 因为有1px的边框 + height: 27, // 悬浮窗口的高度 比实际DIV的高度要多2px 因为有1px的边框 + type: "toolbar", // 创建的窗口类型为工具栏窗口 + frame: false, // 要创建无边框窗口 + resizable: false, // 禁止窗口大小缩放 + show: false, // 先不让窗口显示 + webPreferences: { + devTools: false, // 关闭调试工具 + nodeIntegration: true, + contextIsolation: false, + }, + transparent: true, // 设置透明 + alwaysOnTop: true, // 窗口是否总是显示在其他窗口之前 + }) + const size = screen.getPrimaryDisplay().workAreaSize // 获取显示器的宽高 + const winSize = Shared.data.floatWindow.getSize() // 获取窗口宽高 + // 设置窗口的位置 注意x轴要桌面的宽度 - 窗口的宽度 + Shared.data.floatWindow.setPosition(size.width - winSize[0], 100) + Shared.data.floatWindow.setPosition(size.width / 2, size.height / 2) + Shared.data.floatWindow.loadURL(winURL) + + Shared.data.floatWindow.once("ready-to-show", () => { + Shared.data.floatWindow.show() + }) + Shared.data.floatWindow.on("double-click", () => { + alert(123) + }) + Shared.data.floatWindow.on("close", () => { + Shared.data.floatWindow = null + }) +} + +ipcMain.on("hideSuspensionWindow", () => { + if (Shared.data.floatWindow) { + Shared.data.floatWindow.hide() + } +}) diff --git a/src/main/index.ts b/src/main/index.ts index a8b5d88..b45e816 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -1,54 +1,134 @@ /** * electron 主文件 */ -// import "@src/common/patch" -import Shared from "./share" -const { join } = require("path") -const { app, BrowserWindow } = require("electron") -import "./menu" +'use strict' +import Shared from './share' +import setTray from './disk' +// import '../renderer/store' +import './facilities' +import { app, BrowserWindow, dialog } from 'electron' Shared.data = { mainWindow: null, floatWindow: null, miniWindow: null, - forceClose: false, + forceClose: false } +console.log('asdasadsads') +/** + * Set `__static` path to static files in production + * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html + */ + let isDev = process.env.NODE_ENV == "development" ? true : false -let isDev = process.env.NODE_ENV == "development" ? true : false + if (!isDev) { + // @ts-ignore + global.__static = require("path").join(__dirname, "/static").replace(/\\/g, "\\\\") + } -if (!isDev) { - // @ts-ignore - global.__static = require("path").join(__dirname, "/static").replace(/\\/g, "\\\\") -} - -function createWin() { - // 创建浏览器窗口dsaasdad + +const winURL = process.env.NODE_ENV === 'development' ? `http://localhost:${process.env.PORT}/#/` : `file://${__dirname}/index.html` +let lastChoice = -1 + +function createWindow() { + /** + * Initial window options + */ Shared.data.mainWindow = new BrowserWindow({ - height: 800, + height: 400, useContentSize: true, - width: 900, - // resizable: false, - // minWidth: 450, - // minHeight: 400, + width: 600, + resizable: true, + minWidth: 450, + minHeight: 400, // frame: false, // transparent: true, - alwaysOnTop: true, - icon: __static + "/icon.png", + alwaysOnTop: false, webPreferences: { - // 下面两个必须这么用,看a.md的文档 nodeIntegration: true, - contextIsolation: false, - // 预加载动画 - // preload: join(__dirname, "../../src/preload/index.js"), - }, + contextIsolation: false + } }) - const URL = app.isPackaged - ? `file://${__dirname}/index.html` // vite 构建后的静态文件地址 - : `http://localhost:${process.env.PORT}/#/` // vite 启动的服务器地址 - // : `http://localhost:8080/#/` // vite 启动的服务器地址 - - Shared.data.mainWindow?.loadURL(URL) + Shared.data.mainWindow.loadURL(winURL) + Shared.data.mainWindow.on('close', (event:any) => { + if (Shared.data.forceClose) { + Shared.data.mainWindow = null + app.quit() + } else if (Shared.data.mainWindow) { + if (lastChoice === 1) { + if (Shared.data.miniWindow) { + Shared.data.mainWindow.hide() // 调用 最小化实例方法 + } else { + setTray(app, Shared.data.mainWindow) + } + event.preventDefault() + } else { + const choice = dialog.showMessageBoxSync(Shared.data.mainWindow, { + type: 'info', + title: 'Information', + defaultId: 0, + cancelId: 0, + message: '确定要关闭吗?', + buttons: ['没事', '最小化到托盘', '直接退出'] + }) + if (choice === 1) { + lastChoice = 1 + if (Shared.data.miniWindow) { + Shared.data.mainWindow.hide() // 调用 最小化实例方法 + } else { + setTray(app, Shared.data.mainWindow) + } + event.preventDefault() + } else if (choice === 2) { + Shared.data.mainWindow = null + // app.quit() + // 不要用quit();试了会弹两次 + Shared.data.forceClose = true + app.quit() // exit()直接关闭客户端,不会执行quit(); + } else { + event.preventDefault() + } + } + } + }) } -app.whenReady().then(createWin) +const gotTheLock = app.requestSingleInstanceLock() +if (!gotTheLock) { + app.exit() +} else { + require('./menu') + require('./float') + + app.on('second-instance', (event, commandLine, workingDirectory) => { + // 当运行第二个实例时,将会聚焦到mainWindow这个窗口 + if (Shared.data.mainWindow) { + if (Shared.data.mainWindow.isMinimized()) Shared.data.mainWindow.restore() + Shared.data.mainWindow.focus() + Shared.data.mainWindow.show() + } + }) + + app.on('ready', createWindow) + + app.on('before-quit', event => { + if (Shared.data.forceClose) { + app.exit() + } else { + event.preventDefault() + } + }) + + app.on('window-all-closed', () => { + if (process.platform !== 'darwin') { + app.exit() + } + }) + + app.on('activate', () => { + if (Shared.data.mainWindow === null) { + createWindow() + } + }) +} diff --git a/src/main/menu copy.ts b/src/main/menu copy.ts new file mode 100644 index 0000000..3f003e6 --- /dev/null +++ b/src/main/menu copy.ts @@ -0,0 +1,66 @@ +import electron from "electron" + +const BrowserWindow = electron.BrowserWindow +const Menu = electron.Menu +const app = electron.app +const dialog = electron.dialog +const ipcMain = electron.ipcMain + +let newwin:electron.BrowserWindow|null = null + +let template = [ + { + label: "关于", + click: function (item:any, focusedWindow:any) { + // https://www.electronjs.org/docs/api/browser-window#winsetmenubarvisibilityvisible-windows-linux + if (focusedWindow && !newwin) { + newwin = new BrowserWindow({ + width: 600, + height: 200, + // modal: true, + show: false, + resizable: true, + parent: focusedWindow, // win是主窗口 + // + webPreferences: { + // 下面两个必须这么用,看a.md的文档 + nodeIntegration: true, + contextIsolation: false, + // 预加载动画 + // preload: join(__dirname, "../../src/preload/index.js"), + }, + }) + // 隐藏菜单 + newwin.setMenuBarVisibility(false) + newwin.loadURL(process.env.NODE_ENV === "development" ? `http://localhost:${process.env.PORT}/#/about` : `file://${__dirname}/index.html#/about`); + newwin.on("ready-to-show", () => { + newwin?.show() + }) + newwin.on("closed", () => { + newwin = null + }) + } + }, + }, +] + +// if (process.platform === 'darwin') { +// +// } +// +// if (process.platform === 'win32') { +// +// } +app.on("ready", function () { + const menu = Menu.buildFromTemplate(template) + Menu.setApplicationMenu(menu) +}) +app.on("browser-window-created", function () { + // let reopenMenuItem = findReopenMenuItem() + // if (reopenMenuItem) reopenMenuItem.enabled = false +}) +app.on("window-all-closed", function () { + app.exit() + // let reopenMenuItem = findReopenMenuItem() + // if (reopenMenuItem) reopenMenuItem.enabled = true +}) diff --git a/src/main/menu.ts b/src/main/menu.ts index 3f003e6..2bb905e 100644 --- a/src/main/menu.ts +++ b/src/main/menu.ts @@ -1,58 +1,176 @@ -import electron from "electron" - -const BrowserWindow = electron.BrowserWindow +// const path = require('path') +import { BrowserWindow } from "electron" +import Shared from "./share" +const electron = require("electron") +const setTray = require("./disk").default +// const BrowserWindow = electron.BrowserWindow const Menu = electron.Menu const app = electron.app const dialog = electron.dialog const ipcMain = electron.ipcMain -let newwin:electron.BrowserWindow|null = null +let newwin:BrowserWindow |null let template = [ { + label: "选择保存目录", + click: function (item:any, focusedWindow:BrowserWindow) { + dialog + .showOpenDialog(focusedWindow, { + properties: ["openDirectory"], + }) + .then(result => { + ipcMain.emit("@menu:selectDir", result) + }) + .catch(err => { + throw err + }) + }, + }, + { + label: "置顶", + key: "alwaysTop", + click: function (item: any, focusedWindow:BrowserWindow) { + if (Shared.data.mainWindow.isAlwaysOnTop()) { + Shared.data.mainWindow.setAlwaysOnTop(false) + } else { + Shared.data.mainWindow.setAlwaysOnTop(true) + } + }, + }, + { + label: "重载", + accelerator: "CmdOrCtrl+R", + click: function (item: any, focusedWindow:BrowserWindow) { + if (focusedWindow) { + // 重载之后, 刷新并关闭所有的次要窗体 + if (focusedWindow.id === 1) { + BrowserWindow.getAllWindows().forEach(function (win) { + if (win.id > 1) { + win.close() + } + }) + } + focusedWindow.reload() + } + }, + }, + { + label: "功能", + submenu: [ + { + label: "悬浮窗", + click: function (item: any, focusedWindow:BrowserWindow) { + ipcMain.emit("showSuspensionWindow") + }, + }, + { + label: "最小化到托盘", + click: function (item: any, focusedWindow:BrowserWindow) { + setTray(app, Shared.data.mainWindow) + }, + }, + { + label: "切换全屏", + accelerator: (function () { + if (process.platform === "darwin") { + return "Ctrl+Command+F" + } else { + return "F11" + } + })(), + click: function (item: any, focusedWindow:BrowserWindow) { + if (focusedWindow) { + focusedWindow.setFullScreen(!focusedWindow.isFullScreen()) + } + }, + }, + ], + }, + { + label: "开发者", + submenu: [ + { + label: "切换开发者工具", + accelerator: (function () { + if (process.platform === "darwin") { + return "Alt+Command+I" + } else { + return "Ctrl+Shift+I" + } + })(), + click: function (item: any, focusedWindow: BrowserWindow) { + if (focusedWindow) { + // @ts-ignore + focusedWindow.toggleDevTools() + } + }, + }, + ], + }, + // { + // label: '重新启动', + // click: function(item, focusedWindow) { + // app.exit() + // app.relaunch() + // // app.relaunch({ args: process.argv.slice(1).concat(['--relaunch']) }) + // // app.quit() + // } + // }, + { label: "关于", - click: function (item:any, focusedWindow:any) { + click: function (item: any, focusedWindow: BrowserWindow) { // https://www.electronjs.org/docs/api/browser-window#winsetmenubarvisibilityvisible-windows-linux if (focusedWindow && !newwin) { newwin = new BrowserWindow({ width: 600, height: 200, - // modal: true, + minimizable: false, + darkTheme: true, + modal: true, show: false, - resizable: true, - parent: focusedWindow, // win是主窗口 - // - webPreferences: { - // 下面两个必须这么用,看a.md的文档 - nodeIntegration: true, - contextIsolation: false, - // 预加载动画 - // preload: join(__dirname, "../../src/preload/index.js"), - }, + resizable: false, + webPreferences:{ + nodeIntegration: true, + contextIsolation: false + } + // parent: focusedWindow // win是主窗口 }) // 隐藏菜单 newwin.setMenuBarVisibility(false) - newwin.loadURL(process.env.NODE_ENV === "development" ? `http://localhost:${process.env.PORT}/#/about` : `file://${__dirname}/index.html#/about`); + // vue是单页面,需要改成多页面才行 + newwin.loadURL(process.env.NODE_ENV === "development" ? `http://localhost:${process.env.PORT}/#/about` : `file://${__dirname}#/about`) newwin.on("ready-to-show", () => { newwin?.show() }) - newwin.on("closed", () => { + newwin.on("close", () => { newwin = null }) } }, }, ] - -// if (process.platform === 'darwin') { -// -// } -// -// if (process.platform === 'win32') { -// +// function findTopItem() { +// const menu = Menu.getApplicationMenu() +// if (!menu) return +// let reopenMenuItem +// menu.items.forEach(function(item) { +// if (item.key === 'alwaysTop') { +// reopenMenuItem = item +// } +// // if (item.submenu) { +// // item.submenu.items.forEach(function(item) { +// // if (item.key === 'alwaysTop') { +// // reopenMenuItem = item +// // } +// // }) +// // } +// }) +// console.log(reopenMenuItem) +// return reopenMenuItem // } app.on("ready", function () { - const menu = Menu.buildFromTemplate(template) + const menu = Menu.buildFromTemplate(template) Menu.setApplicationMenu(menu) }) app.on("browser-window-created", function () { @@ -60,7 +178,6 @@ app.on("browser-window-created", function () { // if (reopenMenuItem) reopenMenuItem.enabled = false }) app.on("window-all-closed", function () { - app.exit() // let reopenMenuItem = findReopenMenuItem() // if (reopenMenuItem) reopenMenuItem.enabled = true }) diff --git a/src/render/route.tsx b/src/render/route.tsx index cbec56c..461df15 100644 --- a/src/render/route.tsx +++ b/src/render/route.tsx @@ -43,6 +43,15 @@ export default [ ], }, { + path: "/float", + component: lazy(() => import("@/views/Float")), + exact: true, + meta: { + auth: false, + }, + children: [], + }, + { path: "/home", component: lazy(() => import("@/views/Home")), exact: true, diff --git a/src/render/views/Float/index.module.scss b/src/render/views/Float/index.module.scss new file mode 100644 index 0000000..332ceb9 --- /dev/null +++ b/src/render/views/Float/index.module.scss @@ -0,0 +1,10 @@ +.view-float { + width: 100px; + height: 25px; + line-height: 25px; + background-color: #fff; + position: fixed; + overflow: auto; + user-select: none; + border: 1px solid red; +} diff --git a/src/render/views/Float/index.tsx b/src/render/views/Float/index.tsx new file mode 100644 index 0000000..35b87a8 --- /dev/null +++ b/src/render/views/Float/index.tsx @@ -0,0 +1,43 @@ +import React, { MouseEventHandler, useEffect } from "react" +import electron from "@/plugins/electron" +import style from "./index.module.scss" +import { useLocation, Route, Switch, useHistory } from "react-router-dom" + +export default function Float(props: any) { + useEffect(() => { + // let win = electron.remote.getCurrentWindow() + let biasX = 0 + let biasY = 0 + document.addEventListener("mousedown", function (e) { + switch (e.button) { + case 0: + biasX = e.x + biasY = e.y + document.addEventListener("mousemove", moveEvent) + break + case 2: + electron.ipcRenderer.send("createSuspensionMenu") + break + } + }) + + document.addEventListener("mouseup", function () { + biasX = 0 + biasY = 0 + document.removeEventListener("mousemove", moveEvent) + }) + + function moveEvent(e: any) { + electron.ipcRenderer.send('@float:setPosition', e.screenX - biasX, e.screenY - biasY) + // win.setPosition(e.screenX - biasX, e.screenY - biasY) + } + }, []) + function dblclick(e: MouseEventHandler) { + alert("asd") + } + return ( +
dblclick(e)}> + 悬浮窗 +
+ ) +} diff --git a/src/render/views/Home/index.tsx b/src/render/views/Home/index.tsx index c732766..08eb200 100644 --- a/src/render/views/Home/index.tsx +++ b/src/render/views/Home/index.tsx @@ -27,6 +27,7 @@ function Home(props: HomeProps) { 首页
关于
登录
+ Float