diff --git a/.gitignore b/.gitignore index 4444cf2..7aa3eac 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ out .idea .vscode dist/electron +计划.md diff --git a/a.md b/a.md index a78bee5..cd154ec 100644 --- a/a.md +++ b/a.md @@ -12,4 +12,8 @@ https://www.jianshu.com/p/4699b825d285 https://github.com/webpack/webpack/issues/11767 - https://vite-rollup-plugins.patak.dev/ \ No newline at end of file + https://vite-rollup-plugins.patak.dev/ + + + https://www.npmjs.com/package/node-schedule + https://www.electronjs.org/community \ No newline at end of file diff --git a/resource/electron/static/font/Mouse.otf b/resource/electron/static/font/Mouse.otf new file mode 100644 index 0000000..d4ebdac Binary files /dev/null and b/resource/electron/static/font/Mouse.otf differ diff --git a/resource/electron/static/font/bb3273.ttf b/resource/electron/static/font/bb3273.ttf new file mode 100644 index 0000000..563bee5 Binary files /dev/null and b/resource/electron/static/font/bb3273.ttf differ diff --git a/resource/electron/static/icon.png b/resource/electron/static/icon.png index b3ab3b8..7c43276 100644 Binary files a/resource/electron/static/icon.png and b/resource/electron/static/icon.png differ diff --git a/src/main/float.ts b/src/main/facilities/float/index.ts similarity index 75% rename from src/main/float.ts rename to src/main/facilities/float/index.ts index baa4ffe..335d989 100644 --- a/src/main/float.ts +++ b/src/main/facilities/float/index.ts @@ -1,8 +1,8 @@ -import Shared from "./share" -import { getFileUrl } from './util' -import { BrowserWindow, ipcMain, screen, Menu, shell, webContents, app } from "electron" +import { app, BrowserWindow, ipcMain, Menu, screen, shell } from "electron" +import Shared from "@main/share" +import { getFileUrl } from "@main/util" // webContents -console.log(webContents.getAllWebContents()) +// console.log(webContents.getAllWebContents()) const window: any = null //BrowserWindow.fromWebContents(webContents.getFocusedWebContents()) @@ -24,13 +24,13 @@ ipcMain.on("showSuspensionWindow", () => { ipcMain.on("createSuspensionMenu", e => { const rightM = Menu.buildFromTemplate([ - { label: "开始全部任务", enabled: false }, + { label: "添加闹钟", enabled: false }, { label: "暂停全部任务", enabled: false }, { label: "本次传输完自动关机", click: () => { ipcMain.emit("@func:buildin:saveData", 32232) - }, + } }, { type: "separator" }, { @@ -39,8 +39,8 @@ ipcMain.on("createSuspensionMenu", e => { if (window) { window.webContents.send("hideSuspension", false) } - Shared.data.floatWindow.hide() - }, + Shared.data.floatWindow?.hide() + } }, { label: "打开主窗口", @@ -50,7 +50,7 @@ ipcMain.on("createSuspensionMenu", e => { Shared.data.mainWindow.show() } // window.webContents.send('hideSuspension', false) - }, + } }, { type: "separator" }, { @@ -59,29 +59,29 @@ ipcMain.on("createSuspensionMenu", e => { shell.openExternal( "tencent://groupwpa/?subcmd=all¶m=7B2267726F757055696E223A3831343237303636392C2274696D655374616D70223A313533393531303138387D0A" ) - }, + } }, { label: "GitHub地址", click: () => { shell.openExternal("https://github.com/lihaotian0607/auth") - }, + } }, { label: "退出软件", click: () => { Shared.data.forceClose = true app.quit() - }, - }, + } + } ]) rightM.popup({}) }) function createSuspensionWindow() { Shared.data.floatWindow = new BrowserWindow({ - width: 102, // 悬浮窗口的宽度 比实际DIV的宽度要多2px 因为有1px的边框 - height: 27, // 悬浮窗口的高度 比实际DIV的高度要多2px 因为有1px的边框 + width: 260, // 悬浮窗口的宽度 比实际DIV的宽度要多2px 因为有1px的边框 + height: 95, // 悬浮窗口的高度 比实际DIV的高度要多2px 因为有1px的边框 type: "toolbar", // 创建的窗口类型为工具栏窗口 frame: false, // 要创建无边框窗口 resizable: false, // 禁止窗口大小缩放 @@ -89,24 +89,25 @@ function createSuspensionWindow() { webPreferences: { devTools: false, // 关闭调试工具 nodeIntegration: true, - contextIsolation: false, + contextIsolation: false }, transparent: true, // 设置透明 - alwaysOnTop: 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(getFileUrl("float")) + Shared.data.floatWindow.setPosition(size.width - winSize[0], size.height - winSize[1] - 40) + // Shared.data.floatWindow.setPosition(size.width / 2, size.height / 2) + + Shared.data.floatWindow.loadURL(getFileUrl("")) Shared.data.floatWindow.once("ready-to-show", () => { - Shared.data.floatWindow.show() - }) - Shared.data.floatWindow.on("double-click", () => { - alert(123) + Shared.data.floatWindow?.show() }) + // Shared.data.floatWindow.on("double-click", () => { + // alert(123) + // }) Shared.data.floatWindow.on("close", () => { Shared.data.floatWindow = null }) diff --git a/src/main/facilities/index.ts b/src/main/facilities/index.ts index b624373..ce4889a 100644 --- a/src/main/facilities/index.ts +++ b/src/main/facilities/index.ts @@ -1,20 +1,92 @@ -import { ipcMain, dialog } from "electron" +import Shared from "@main/share" +import setTray from "@main/facilities/tray" +import { app, dialog, ipcMain } from "electron" +import Share from "../share" /** * 格式:@类型:扩展:函数 */ -// 保存数据 -ipcMain.on("@func:buildin:close", data => { - // dialog.showMessageBox( - // { - // type: "info", - // title: "Information", - // defaultId: 0, - // cancelId: 0, - // message: "确定要关闭吗?" + data, - // buttons: ["没事", "最小化到托盘", "直接退出"], - // }, - // index => {} - // ) +/** + * @方法:内置:设置窗口位置 + */ +ipcMain.on("@func:buildin:setPosition", (event, x, y) => { + Share.data.floatWindow?.setPosition(x, y) +}) +/** + * @方法:内置:磁盘化 + */ +ipcMain.on("@func:buildin:setTray", (event, x, y) => { + if (Shared.data.trayWindow) { + Shared.data.mainWindow?.hide() // 调用 最小化实例方法 + } else { + setTray(Shared.data.mainWindow) + } +}) + +/** + * @方法:内置:退出或者磁盘化 + */ +ipcMain.on("@func:buildin:quitOrTray", (event) => { + if (Shared.data.forceClose) { + Shared.data.mainWindow?.destroy() + Shared.data.mainWindow = null + app.quit() + } else if (Shared.data.mainWindow) { + if (Shared.data.lastChoice === 1) { + ipcMain.emit("@func:buildin:setTray") + event.preventDefault() + } else { + const choice = dialog.showMessageBoxSync(Shared.data.mainWindow, { + type: "info", + title: "Information", + defaultId: 0, + cancelId: 0, + message: "确定要关闭吗?", + buttons: ["没事", "最小化到托盘", "直接退出"] + }) + if (choice === 1) { + Shared.data.lastChoice = 1 + ipcMain.emit("@func:buildin:setTray") + event.preventDefault() + } else if (choice === 2) { + Shared.data.mainWindow = null + // app.quit() + // 不要用quit();试了会弹两次 + Shared.data.forceClose = true + app.quit() // exit()直接关闭客户端,不会执行quit(); + } else { + event.preventDefault() + } + } + } +}) + + +/** + * @方法:内置:退出 + */ +ipcMain.on("@func:buildin:quit", (event) => { + if (Shared.data.forceClose) { + Shared.data.mainWindow = null + app.quit() + } else if (Shared.data.mainWindow) { + const choice = dialog.showMessageBoxSync({ + type: "info", + title: "Information", + defaultId: 0, + cancelId: 0, + message: "确定要关闭吗?", + buttons: ["没事", "直接退出"] + }) + if (choice === 1) { + Shared.data.mainWindow = null + // app.quit() + // 不要用quit();试了会弹两次 + Shared.data.forceClose = true + app.quit() // exit()直接关闭客户端,不会执行quit(); + } else { + + } + } }) diff --git a/src/main/facilities/main/index.ts b/src/main/facilities/main/index.ts new file mode 100644 index 0000000..176f1ba --- /dev/null +++ b/src/main/facilities/main/index.ts @@ -0,0 +1,31 @@ +import { app, BrowserWindow, dialog, ipcMain } from "electron" +import Shared from "@main/share" +import { getFileUrl } from "@main/util" + +function createWindow() { + /** + * Initial window options + */ + Shared.data.mainWindow = new BrowserWindow({ + height: 95, + useContentSize: true, + width: 260, + resizable: false, + minWidth: 260, + minHeight: 95, + icon: __static + "/icon.png", + show: false, + frame: false, // 去除原生的菜单 + transparent: true, // 背景透明 + alwaysOnTop: true, + webPreferences: { + nodeIntegration: true, + contextIsolation: false + } + }) + + Shared.data.mainWindow.loadURL(getFileUrl("")) + Shared.data.mainWindow.on("close", (event: any) => { + ipcMain.emit("@func:buildin:quitOrTray") + }) +} diff --git a/src/main/disk.ts b/src/main/facilities/tray/index.ts similarity index 64% rename from src/main/disk.ts rename to src/main/facilities/tray/index.ts index a6e82e8..f3e0583 100644 --- a/src/main/disk.ts +++ b/src/main/facilities/tray/index.ts @@ -1,11 +1,12 @@ -import Shared from "./share" -import { Menu, Tray, ipcMain, BrowserWindow, App } from "electron" +import Shared from "@main/share" +import { app, BrowserWindow, ipcMain, Menu, Tray } from "electron" + const path = require("path") // 隐藏主窗口,并创建托盘,绑定关闭事件 -export default function setTray(app: App, mainWindow: BrowserWindow) { - if (Shared.data.miniWindow) { - mainWindow.hide() +export default function setTray(mainWindow?: BrowserWindow | null) { + if (Shared.data.trayWindow) { + mainWindow?.hide() return } // 用一个 Tray 来表示一个图标,这个图标处于正在运行的系统的通知区 @@ -16,15 +17,15 @@ export default function setTray(app: App, mainWindow: BrowserWindow) { // 系统托盘图标目录 label: "打开主窗口", click: () => { - mainWindow.show() - }, + mainWindow?.show() + } }, { // 系统托盘图标目录 label: "打开悬浮窗", click: () => { ipcMain.emit("showSuspensionWindow") - }, + } }, { // 系统托盘图标目录 @@ -32,32 +33,32 @@ export default function setTray(app: App, mainWindow: BrowserWindow) { click: () => { Shared.data.forceClose = true app.quit() - }, - }, + } + } ] // 设置系统托盘图标 const iconPath = path.join(__static, "/icon.png") - Shared.data.miniWindow = new Tray(iconPath) + Shared.data.trayWindow = new Tray(iconPath) // 图标的上下文菜单 const contextMenu = Menu.buildFromTemplate(trayMenuTemplate) // 展示主窗口,隐藏主窗口 mainWindow.hide() - mainWindow.hide() + mainWindow?.hide() // 设置托盘悬浮提示 - Shared.data.miniWindow.setToolTip("never forget") + Shared.data.trayWindow.setToolTip("never forget") // 设置托盘菜单 - Shared.data.miniWindow.setContextMenu(contextMenu) + Shared.data.trayWindow.setContextMenu(contextMenu) // 单击托盘小图标显示应用 - Shared.data.miniWindow.on("double-click", () => { + Shared.data.trayWindow.on("double-click", () => { // 显示主程序 - mainWindow.show() + mainWindow?.show() // 关闭托盘显示 - // Shared.data.miniWindow.destroy(); + // Shared.data.trayWindow.destroy(); }) - return Shared.data.miniWindow + return Shared.data.trayWindow } diff --git a/src/main/index.dev.ts b/src/main/index.dev.ts index 3240246..9dc7172 100644 --- a/src/main/index.dev.ts +++ b/src/main/index.dev.ts @@ -2,7 +2,7 @@ // Install `electron-debug` with `devtron` import electronDebug from "electron-debug" -electronDebug({ showDevTools: true }) +electronDebug({ showDevTools: false }) // Install `vue-devtools` require('electron').app.on('ready', () => { @@ -15,4 +15,4 @@ require('electron').app.on('ready', () => { }) // Require `main` process to boot app -import './index' \ No newline at end of file +import './index' diff --git a/src/main/index.ts b/src/main/index.ts index d429f1e..68a6f6a 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -2,21 +2,12 @@ * electron 主文件 */ "use strict" -import Shared from "./share" -import setTray from "./disk" -import { getFileUrl } from "./util" -// import '../renderer/store' -import "./facilities" -import { app, BrowserWindow, dialog } from "electron" +import "@main/facilities/float/float" +import setTray from "@main/facilities/tray" +import { app, ipcMain } from "electron" +import "@main/facilities" +import Shared from "@main/share" -Shared.data = { - mainWindow: null, // 主窗口 - floatWindow: null, // 浮动窗口 - miniWindow: null, - forceClose: false, - lastChoice: -1, // 做过的选择 -} -console.log("asdasadsads") /** * Set `__static` path to static files in production * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html @@ -28,88 +19,93 @@ if (!isDev) { global.__static = require("path").join(__dirname, "/static").replace(/\\/g, "\\\\") } -function createWindow() { - /** - * Initial window options - */ - Shared.data.mainWindow = new BrowserWindow({ - height: 400, - useContentSize: true, - width: 600, - resizable: true, - minWidth: 450, - minHeight: 400, - icon: __static + "/icon.png", - // frame: false, - // transparent: true, - alwaysOnTop: false, - webPreferences: { - nodeIntegration: true, - contextIsolation: false, - }, - }) - Shared.data.mainWindow.loadURL(getFileUrl("")) - Shared.data.mainWindow.on("close", (event: any) => { - if (Shared.data.forceClose) { - Shared.data.mainWindow = null - app.quit() - } else if (Shared.data.mainWindow) { - if (Shared.data.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) { - Shared.data.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() - } - } - } - }) -} +// function createWindow() { +// /** +// * Initial window options +// */ +// Shared.data.mainWindow = new BrowserWindow({ +// height: 95, +// useContentSize: true, +// width: 260, +// resizable: false, +// minWidth: 260, +// minHeight: 95, +// icon: __static + "/icon.png", +// show: false, +// frame: false, // 去除原生的菜单 +// transparent: true, // 背景透明 +// alwaysOnTop: true, +// webPreferences: { +// nodeIntegration: true, +// contextIsolation: false, +// }, +// }) +// +// Shared.data.mainWindow.loadURL(getFileUrl("")) +// Shared.data.mainWindow.on("close", (event: any) => { +// if (Shared.data.forceClose) { +// Shared.data.mainWindow = null +// app.quit() +// } else if (Shared.data.mainWindow) { +// if (Shared.data.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) { +// Shared.data.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() +// } +// } +// } +// }) +// } const gotTheLock = app.requestSingleInstanceLock() if (!gotTheLock) { app.exit() } else { - require("./menu") - require("./float") - + function createWindow() { + setTray() // 初始化磁盘 + ipcMain.emit("showSuspensionWindow") //展示悬浮窗 + } 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() - } + // 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("ready", () => { + + }) app.on("before-quit", event => { if (Shared.data.forceClose) { @@ -126,6 +122,7 @@ if (!gotTheLock) { }) app.on("activate", () => { + if (Shared.data.mainWindow === null) { createWindow() } diff --git a/src/main/menu copy.ts b/src/main/menu copy.ts deleted file mode 100644 index 3f003e6..0000000 --- a/src/main/menu copy.ts +++ /dev/null @@ -1,66 +0,0 @@ -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 deleted file mode 100644 index fe14adb..0000000 --- a/src/main/menu.ts +++ /dev/null @@ -1,189 +0,0 @@ -// const path = require('path') -import { BrowserWindow } from "electron" -import Shared from "./share" -import { getFileUrl } from "./util" -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: 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) { - Shared.data.lastChoice = 1 - if (Shared.data.miniWindow) { - Shared.data.mainWindow.hide() // 调用 最小化实例方法 - } else { - 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: BrowserWindow) { - // https://www.electronjs.org/docs/api/browser-window#winsetmenubarvisibilityvisible-windows-linux - if (focusedWindow && !newwin) { - newwin = new BrowserWindow({ - width: 600, - height: 200, - minimizable: false, - darkTheme: true, - modal: true, - show: false, - resizable: false, - webPreferences: { - nodeIntegration: true, - contextIsolation: false, - }, - // parent: focusedWindow // win是主窗口 - }) - // 隐藏菜单 - newwin.setMenuBarVisibility(false) - // vue是单页面,需要改成多页面才行 - newwin.loadURL(getFileUrl("about")) - newwin.on("ready-to-show", () => { - newwin?.show() - }) - newwin.on("close", () => { - newwin = null - }) - } - }, - }, -] -// 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) - Menu.setApplicationMenu(menu) -}) -app.on("browser-window-created", function () { - // let reopenMenuItem = findReopenMenuItem() - // if (reopenMenuItem) reopenMenuItem.enabled = false -}) -app.on("window-all-closed", function () { - // let reopenMenuItem = findReopenMenuItem() - // if (reopenMenuItem) reopenMenuItem.enabled = true -}) diff --git a/src/main/share/index.ts b/src/main/share/index.ts index 118d9bd..708b231 100644 --- a/src/main/share/index.ts +++ b/src/main/share/index.ts @@ -1,12 +1,25 @@ +import { BrowserWindow, Tray } from "electron" + interface IPayload{ data: { + mainWindow: BrowserWindow|null; + floatWindow: BrowserWindow|null; + trayWindow: Tray|null; + forceClose: boolean; + lastChoice: number; [propName:string]: any; }; [propName:string]: any; } const payload:IPayload = { - data: {} + data: { + mainWindow: null, // 主窗口 + floatWindow: null, // 浮动窗口 + trayWindow: null, + forceClose: false, + lastChoice: -1 // 做过的选择 + } } -export default payload \ No newline at end of file +export default payload diff --git a/src/render/assets/style/_font.scss b/src/render/assets/style/_font.scss index ea6d3d7..e251421 100644 --- a/src/render/assets/style/_font.scss +++ b/src/render/assets/style/_font.scss @@ -110,3 +110,10 @@ src: url(https://fonts.gstatic.com/s/sourcesanspro/v14/6xKydSBYKcSV-LCoeQqfX1RYOo3ik4zwlxdu.woff2) format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } + +@font-face { + font-family: 'pixi'; + src:url('__static/font/bb3273.ttf') format('truetype'); + font-weight: normal; + font-style: normal; +} diff --git a/src/render/views/Home/index.module.scss b/src/render/views/Home/index.module.scss new file mode 100644 index 0000000..d616625 --- /dev/null +++ b/src/render/views/Home/index.module.scss @@ -0,0 +1,14 @@ +.clock { + position: fixed; + left: 0; + top: 0; + transform: translate(-50% -50%); + font-size: 40px; + font-weight: bolder; + text-align: center; + line-height: 1.3; + color: #CD1110; + font-family: "pixi"; + user-select: none; + pointer-events: none; +} diff --git a/src/render/views/Home/index.tsx b/src/render/views/Home/index.tsx index 08eb200..0ac89fc 100644 --- a/src/render/views/Home/index.tsx +++ b/src/render/views/Home/index.tsx @@ -1,49 +1,38 @@ import { addTodo, removeTodo } from "@/store/action/todo" -import React, { FormEvent, useRef, useContext } from "react" +import React from "react" import { connect } from "react-redux" -import { NavLink } from "react-router-dom" +import style from "./index.module.scss" +import useTime from "./useTime" +import usePositionElectron from "./usePositionElectron" export interface HomeProps { add(text: string): void + todo: ITodo[] + remove(id: number): void } function Home(props: HomeProps) { - const { todo, add, remove } = props - const inputRef = useRef(null) - - function addOne(e: FormEvent) { - e.preventDefault() - let text = inputRef.current!.value - if (text) { - inputRef.current!.value = "" - add(text) - } - } - + let [nowDate] = useTime() + usePositionElectron() return ( -
- 首页
- 关于
- 登录
- Float
-
- -
+
+
{nowDate.year}-{nowDate.month}-{nowDate.day}
+
{nowDate.hour}:{nowDate.minute}:{nowDate.second}
) } const mapStateToProps = (state: any) => { return { - todo: state.todo, + todo: state.todo } } const mapDispatchToProps = (dispatch: any) => ({ add: (text: string) => dispatch(addTodo(text)), - remove: (id: string | number) => dispatch(removeTodo(id)), + remove: (id: string | number) => dispatch(removeTodo(id)) }) export default connect(mapStateToProps, mapDispatchToProps)(Home) diff --git a/src/render/views/Home/usePositionElectron.ts b/src/render/views/Home/usePositionElectron.ts new file mode 100644 index 0000000..0cb63fe --- /dev/null +++ b/src/render/views/Home/usePositionElectron.ts @@ -0,0 +1,32 @@ +import electron from "@/plugins/electron" +import { useEffect } from "react" + + +export default function() { + useEffect(() => { + 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("@func:buildin:setPosition", e.screenX - biasX, e.screenY - biasY) + } + }, []) +} diff --git a/src/render/views/Home/useTime.ts b/src/render/views/Home/useTime.ts new file mode 100644 index 0000000..a05340c --- /dev/null +++ b/src/render/views/Home/useTime.ts @@ -0,0 +1,55 @@ +import { Dispatch, SetStateAction, useEffect, useState } from "react" + +type ITime = { + year?: T; + month?: T; + day?: T; + hour?: T; + minute?: T; + second?: T; +} + +function isLow10(value:string | number) { + if (+value< 10){ + return "0"+value + } + return value +} + + +export default function(isUpdate = true): [ITime, Dispatch>] { + let [nowDate, setNowDate] = useState({}) + + function updateTime() { + let date: ITime = {} + let newDate = new Date() + date.year = isLow10(newDate.getFullYear()) + date.month = isLow10(newDate.getMonth() + 1) + date.day = isLow10(newDate.getDate()) + date.hour = isLow10(newDate.getHours()) + date.minute = isLow10(newDate.getMinutes()) + date.second = isLow10(newDate.getSeconds()) + setNowDate(date) + return newDate.getMilliseconds() + } + + if (isUpdate) { + useEffect(() => { + + function cicleCall(millis: number): NodeJS.Timeout { + let timeID = setTimeout(() => { + let millis = 1000 - updateTime() + cicleCall(millis) + }, millis) + return timeID + } + + let millis = 1000 - updateTime() + let timeID = cicleCall(millis) + return () => { + clearTimeout(timeID) + } + }, []) + } + return [nowDate, setNowDate] +}