From f393546583b86fe00ec1ec1658323f374a2bf3ad Mon Sep 17 00:00:00 2001 From: 1549469775 <1549469775@qq.com> Date: Mon, 2 Aug 2021 11:09:20 +0800 Subject: [PATCH] add --- src/main/facilities/float/index.ts | 88 +++++++++++----------- src/main/facilities/index.ts | 52 ++----------- src/main/facilities/main/index.ts | 101 +++++++++++++++++++------- src/main/facilities/tray/index.ts | 48 ++++++------ src/main/index.ts | 19 ++--- src/render/views/Float/index.module.scss | 18 +++-- src/render/views/Float/index.tsx | 49 +++---------- src/render/views/Float/usePositionElectron.ts | 32 ++++++++ src/render/views/Float/useTime.ts | 55 ++++++++++++++ src/render/views/Home/index.tsx | 5 +- src/render/views/Home/usePositionElectron.ts | 2 +- 11 files changed, 272 insertions(+), 197 deletions(-) create mode 100644 src/render/views/Float/usePositionElectron.ts create mode 100644 src/render/views/Float/useTime.ts diff --git a/src/main/facilities/float/index.ts b/src/main/facilities/float/index.ts index 335d989..7644a84 100644 --- a/src/main/facilities/float/index.ts +++ b/src/main/facilities/float/index.ts @@ -6,11 +6,34 @@ import { getFileUrl } from "@main/util" const window: any = null //BrowserWindow.fromWebContents(webContents.getFocusedWebContents()) -ipcMain.on("@float:setPosition", (event, x, y) => { - Shared.data.floatWindow?.setPosition(x, y) +/** + * @方法:悬浮:设置位置 + */ +ipcMain.on("@func:float:setPosition", (event, x, y) => { + if (Shared.data.floatWindow) { + const size = screen.getPrimaryDisplay().workAreaSize // 获取显示器的宽高 + const winSize = Shared.data.floatWindow.getSize() // 获取窗口宽高 + let rx = x, + ry = y + if (x < 0) { + rx = 0 + } + if (y < 0) { + ry = 0 + } + if (x > size.width - winSize[0]) { + rx = size.width - winSize[0] + } + if (y > size.height - winSize[1]) { + ry = size.height - winSize[1] + } + Shared.data.floatWindow.setPosition(rx, ry) + } }) - -ipcMain.on("showSuspensionWindow", () => { +/** + * @方法:悬浮:展示 + */ +ipcMain.on("@func:float:show", () => { if (Shared.data.floatWindow) { if (Shared.data.floatWindow.isVisible()) { // createSuspensionWindow() @@ -22,58 +45,36 @@ ipcMain.on("showSuspensionWindow", () => { } }) -ipcMain.on("createSuspensionMenu", e => { +ipcMain.on("@func:float:showRightMenu", e => { const rightM = Menu.buildFromTemplate([ - { label: "添加闹钟", enabled: false }, - { label: "暂停全部任务", enabled: false }, { - label: "本次传输完自动关机", + label: "添加闹钟", click: () => { - ipcMain.emit("@func:buildin:saveData", 32232) - } + ipcMain.emit("@func:render:addClock") + // Shared.data.floatWindow?.hide() + }, }, { type: "separator" }, { - label: "隐藏悬浮窗", + 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地址", + label: "仓库地址", click: () => { shell.openExternal("https://github.com/lihaotian0607/auth") - } + }, }, { label: "退出软件", click: () => { Shared.data.forceClose = true app.quit() - } - } + }, + }, ]) rightM.popup({}) }) @@ -89,10 +90,10 @@ 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() // 获取窗口宽高 @@ -100,7 +101,7 @@ function createSuspensionWindow() { 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.loadURL(getFileUrl("float")) Shared.data.floatWindow.once("ready-to-show", () => { Shared.data.floatWindow?.show() @@ -109,12 +110,7 @@ function createSuspensionWindow() { // alert(123) // }) Shared.data.floatWindow.on("close", () => { + Shared.data.floatWindow?.destroy() Shared.data.floatWindow = null }) } - -ipcMain.on("hideSuspensionWindow", () => { - if (Shared.data.floatWindow) { - Shared.data.floatWindow.hide() - } -}) diff --git a/src/main/facilities/index.ts b/src/main/facilities/index.ts index ce4889a..379a94d 100644 --- a/src/main/facilities/index.ts +++ b/src/main/facilities/index.ts @@ -18,55 +18,16 @@ ipcMain.on("@func:buildin:setPosition", (event, x, y) => { */ ipcMain.on("@func:buildin:setTray", (event, x, y) => { if (Shared.data.trayWindow) { - Shared.data.mainWindow?.hide() // 调用 最小化实例方法 + ipcMain.emit("@func:main:hide") } else { - setTray(Shared.data.mainWindow) + setTray() } }) /** - * @方法:内置:退出或者磁盘化 - */ -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) => { +ipcMain.on("@func:buildin:quit", event => { if (Shared.data.forceClose) { Shared.data.mainWindow = null app.quit() @@ -77,7 +38,7 @@ ipcMain.on("@func:buildin:quit", (event) => { defaultId: 0, cancelId: 0, message: "确定要关闭吗?", - buttons: ["没事", "直接退出"] + buttons: ["没事", "直接退出"], }) if (choice === 1) { Shared.data.mainWindow = null @@ -86,7 +47,10 @@ ipcMain.on("@func:buildin:quit", (event) => { Shared.data.forceClose = true app.quit() // exit()直接关闭客户端,不会执行quit(); } else { - } } }) + +ipcMain.on("@func:render:addClock", (event, x, y) => { + ipcMain.emit("@func:main:show", event , "about") +}) diff --git a/src/main/facilities/main/index.ts b/src/main/facilities/main/index.ts index 176f1ba..b15bfc9 100644 --- a/src/main/facilities/main/index.ts +++ b/src/main/facilities/main/index.ts @@ -2,30 +2,81 @@ 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 - } - }) +/** + * @方法:窗口:展示 + */ +ipcMain.on("@func:main:show", (event, url) => { + showWindow(url) +}) +ipcMain.on("@func:main:hide", () => { + if (Shared.data.mainWindow) { + Shared.data.mainWindow.hide() + } +}) - Shared.data.mainWindow.loadURL(getFileUrl("")) - Shared.data.mainWindow.on("close", (event: any) => { - ipcMain.emit("@func:buildin:quitOrTray") - }) +export default function showWindow(url?: string) { + if (!Shared.data.mainWindow || Shared.data.mainWindow?.isDestroyed()) { + /** + * Initial window options + */ + Shared.data.mainWindow = new BrowserWindow({ + height: 95, + useContentSize: true, + width: 260, + resizable: true, + minWidth: 260, + minHeight: 95, + icon: __static + "/icon.png", + // show: false, + // frame: false, // 去除原生的菜单 + // transparent: true, // 背景透明 + alwaysOnTop: true, + webPreferences: { + nodeIntegration: true, + contextIsolation: false, + }, + }) + Shared.data.mainWindow.on("close", (event: any) => { + // 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() + // } + // } + // } + }) + } else { + Shared.data.mainWindow?.showInactive() + } + + if(!url){ + Shared.data.mainWindow.loadURL(getFileUrl("")) + }else{ + Shared.data.mainWindow.loadURL(getFileUrl(url)) + } } diff --git a/src/main/facilities/tray/index.ts b/src/main/facilities/tray/index.ts index f3e0583..905218e 100644 --- a/src/main/facilities/tray/index.ts +++ b/src/main/facilities/tray/index.ts @@ -3,29 +3,24 @@ import { app, BrowserWindow, ipcMain, Menu, Tray } from "electron" const path = require("path") -// 隐藏主窗口,并创建托盘,绑定关闭事件 -export default function setTray(mainWindow?: BrowserWindow | null) { - if (Shared.data.trayWindow) { - mainWindow?.hide() - return - } +export function setTrayMenu() { // 用一个 Tray 来表示一个图标,这个图标处于正在运行的系统的通知区 // 通常被添加到一个 context menu 上. // 系统托盘右键菜单 const trayMenuTemplate = [ { // 系统托盘图标目录 - label: "打开主窗口", + label: "打开窗口", click: () => { - mainWindow?.show() - } + ipcMain.emit("@func:main:show") + }, }, { // 系统托盘图标目录 - label: "打开悬浮窗", + label: "打开悬浮时钟", click: () => { - ipcMain.emit("showSuspensionWindow") - } + ipcMain.emit("@func:float:show") + }, }, { // 系统托盘图标目录 @@ -33,32 +28,37 @@ export default function setTray(mainWindow?: BrowserWindow | null) { click: () => { Shared.data.forceClose = true app.quit() - } - } + }, + }, ] + // 图标的上下文菜单 + const contextMenu = Menu.buildFromTemplate(trayMenuTemplate) + + // 设置托盘菜单 + Shared.data.trayWindow?.setContextMenu(contextMenu) +} + +// 隐藏主窗口,并创建托盘,绑定关闭事件 +export default function setTray() { + if (Shared.data.trayWindow) { + ipcMain.emit("@func:main:hide") + return + } // 设置系统托盘图标 const iconPath = path.join(__static, "/icon.png") Shared.data.trayWindow = new Tray(iconPath) - // 图标的上下文菜单 - const contextMenu = Menu.buildFromTemplate(trayMenuTemplate) - // 展示主窗口,隐藏主窗口 mainWindow.hide() - mainWindow?.hide() + ipcMain.emit("@func:main:hide") // 设置托盘悬浮提示 Shared.data.trayWindow.setToolTip("never forget") - // 设置托盘菜单 - Shared.data.trayWindow.setContextMenu(contextMenu) - // 单击托盘小图标显示应用 Shared.data.trayWindow.on("double-click", () => { // 显示主程序 - mainWindow?.show() - // 关闭托盘显示 - // Shared.data.trayWindow.destroy(); + ipcMain.emit("@func:main:show") }) return Shared.data.trayWindow } diff --git a/src/main/index.ts b/src/main/index.ts index 68a6f6a..201fd05 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -2,8 +2,9 @@ * electron 主文件 */ "use strict" -import "@main/facilities/float/float" -import setTray from "@main/facilities/tray" +import "@main/facilities/float" +import "@main/facilities/main" +import setTray, {setTrayMenu} from "@main/facilities/tray" import { app, ipcMain } from "electron" import "@main/facilities" import Shared from "@main/share" @@ -85,15 +86,17 @@ if (!isDev) { // } // }) // } +function createWindow() { + // createMainWindow() // 初始化磁盘 + setTray() // 初始化磁盘 + setTrayMenu() + ipcMain.emit("@func:float:show") //展示悬浮窗 +} const gotTheLock = app.requestSingleInstanceLock() if (!gotTheLock) { app.exit() } else { - function createWindow() { - setTray() // 初始化磁盘 - ipcMain.emit("showSuspensionWindow") //展示悬浮窗 - } app.on("second-instance", (event, commandLine, workingDirectory) => { // 当运行第二个实例时,将会聚焦到mainWindow这个窗口 // if (Shared.data.mainWindow) { @@ -103,9 +106,7 @@ if (!gotTheLock) { // } }) - app.on("ready", () => { - - }) + app.on("ready", createWindow) app.on("before-quit", event => { if (Shared.data.forceClose) { diff --git a/src/render/views/Float/index.module.scss b/src/render/views/Float/index.module.scss index 332ceb9..d616625 100644 --- a/src/render/views/Float/index.module.scss +++ b/src/render/views/Float/index.module.scss @@ -1,10 +1,14 @@ -.view-float { - width: 100px; - height: 25px; - line-height: 25px; - background-color: #fff; +.clock { position: fixed; - overflow: auto; + 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; - border: 1px solid red; + pointer-events: none; } diff --git a/src/render/views/Float/index.tsx b/src/render/views/Float/index.tsx index 35b87a8..9e40472 100644 --- a/src/render/views/Float/index.tsx +++ b/src/render/views/Float/index.tsx @@ -1,43 +1,18 @@ -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) - }) +import React from "react" +import style from "./index.module.scss" +import useTime from "./useTime" +import usePositionElectron from "./usePositionElectron" - 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") - } +function Float(props: any) { + let [nowDate] = useTime() + usePositionElectron() return ( -
dblclick(e)}> - 悬浮窗 +
+
{nowDate.year}-{nowDate.month}-{nowDate.day}
+
{nowDate.hour}:{nowDate.minute}:{nowDate.second}
) } + +export default Float diff --git a/src/render/views/Float/usePositionElectron.ts b/src/render/views/Float/usePositionElectron.ts new file mode 100644 index 0000000..ae76ae2 --- /dev/null +++ b/src/render/views/Float/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("@func:float:showRightMenu") + break + } + }) + + document.addEventListener("mouseup", function() { + biasX = 0 + biasY = 0 + document.removeEventListener("mousemove", moveEvent) + }) + + function moveEvent(e: any) { + electron.ipcRenderer.send("@func:float:setPosition", e.screenX - biasX, e.screenY - biasY) + } + }, []) +} diff --git a/src/render/views/Float/useTime.ts b/src/render/views/Float/useTime.ts new file mode 100644 index 0000000..a05340c --- /dev/null +++ b/src/render/views/Float/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] +} diff --git a/src/render/views/Home/index.tsx b/src/render/views/Home/index.tsx index 0ac89fc..d1f9aaf 100644 --- a/src/render/views/Home/index.tsx +++ b/src/render/views/Home/index.tsx @@ -14,12 +14,9 @@ export interface HomeProps { } function Home(props: HomeProps) { - let [nowDate] = useTime() - usePositionElectron() return (
-
{nowDate.year}-{nowDate.month}-{nowDate.day}
-
{nowDate.hour}:{nowDate.minute}:{nowDate.second}
+ asdsadasdsdasad
) } diff --git a/src/render/views/Home/usePositionElectron.ts b/src/render/views/Home/usePositionElectron.ts index 0cb63fe..fac9228 100644 --- a/src/render/views/Home/usePositionElectron.ts +++ b/src/render/views/Home/usePositionElectron.ts @@ -14,7 +14,7 @@ export default function() { document.addEventListener("mousemove", moveEvent) break case 2: - electron.ipcRenderer.send("createSuspensionMenu") + electron.ipcRenderer.send("@func:float:showRightMenu") break } })