1549469775 4 years ago
parent
commit
f393546583
  1. 88
      src/main/facilities/float/index.ts
  2. 52
      src/main/facilities/index.ts
  3. 101
      src/main/facilities/main/index.ts
  4. 48
      src/main/facilities/tray/index.ts
  5. 19
      src/main/index.ts
  6. 18
      src/render/views/Float/index.module.scss
  7. 49
      src/render/views/Float/index.tsx
  8. 32
      src/render/views/Float/usePositionElectron.ts
  9. 55
      src/render/views/Float/useTime.ts
  10. 5
      src/render/views/Home/index.tsx
  11. 2
      src/render/views/Home/usePositionElectron.ts

88
src/main/facilities/float/index.ts

@ -6,11 +6,34 @@ import { getFileUrl } from "@main/util"
const window: any = null //BrowserWindow.fromWebContents(webContents.getFocusedWebContents()) 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) {
if (Shared.data.floatWindow.isVisible()) { if (Shared.data.floatWindow.isVisible()) {
// createSuspensionWindow() // createSuspensionWindow()
@ -22,58 +45,36 @@ ipcMain.on("showSuspensionWindow", () => {
} }
}) })
ipcMain.on("createSuspensionMenu", e => { ipcMain.on("@func:float:showRightMenu", e => {
const rightM = Menu.buildFromTemplate([ const rightM = Menu.buildFromTemplate([
{ label: "添加闹钟", enabled: false },
{ label: "暂停全部任务", enabled: false },
{ {
label: "本次传输完自动关机", label: "添加闹钟",
click: () => { click: () => {
ipcMain.emit("@func:buildin:saveData", 32232) ipcMain.emit("@func:render:addClock")
} // Shared.data.floatWindow?.hide()
},
}, },
{ type: "separator" }, { type: "separator" },
{ {
label: "隐藏悬浮", label: "隐藏悬浮时钟",
click: () => { click: () => {
if (window) {
window.webContents.send("hideSuspension", false)
}
Shared.data.floatWindow?.hide() 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" }, { type: "separator" },
{ {
label: "加入qq群", label: "仓库地址",
click: () => {
shell.openExternal(
"tencent://groupwpa/?subcmd=all&param=7B2267726F757055696E223A3831343237303636392C2274696D655374616D70223A313533393531303138387D0A"
)
}
},
{
label: "GitHub地址",
click: () => { click: () => {
shell.openExternal("https://github.com/lihaotian0607/auth") shell.openExternal("https://github.com/lihaotian0607/auth")
} },
}, },
{ {
label: "退出软件", label: "退出软件",
click: () => { click: () => {
Shared.data.forceClose = true Shared.data.forceClose = true
app.quit() app.quit()
} },
} },
]) ])
rightM.popup({}) rightM.popup({})
}) })
@ -89,10 +90,10 @@ function createSuspensionWindow() {
webPreferences: { webPreferences: {
devTools: false, // 关闭调试工具 devTools: false, // 关闭调试工具
nodeIntegration: true, nodeIntegration: true,
contextIsolation: false contextIsolation: false,
}, },
transparent: true, // 设置透明 transparent: true, // 设置透明
alwaysOnTop: true // 窗口是否总是显示在其他窗口之前 alwaysOnTop: true, // 窗口是否总是显示在其他窗口之前
}) })
const size = screen.getPrimaryDisplay().workAreaSize // 获取显示器的宽高 const size = screen.getPrimaryDisplay().workAreaSize // 获取显示器的宽高
const winSize = Shared.data.floatWindow.getSize() // 获取窗口宽高 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 - winSize[0], size.height - winSize[1] - 40)
// Shared.data.floatWindow.setPosition(size.width / 2, size.height / 2) // 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.once("ready-to-show", () => {
Shared.data.floatWindow?.show() Shared.data.floatWindow?.show()
@ -109,12 +110,7 @@ function createSuspensionWindow() {
// alert(123) // alert(123)
// }) // })
Shared.data.floatWindow.on("close", () => { Shared.data.floatWindow.on("close", () => {
Shared.data.floatWindow?.destroy()
Shared.data.floatWindow = null Shared.data.floatWindow = null
}) })
} }
ipcMain.on("hideSuspensionWindow", () => {
if (Shared.data.floatWindow) {
Shared.data.floatWindow.hide()
}
})

52
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) => { ipcMain.on("@func:buildin:setTray", (event, x, y) => {
if (Shared.data.trayWindow) { if (Shared.data.trayWindow) {
Shared.data.mainWindow?.hide() // 调用 最小化实例方法 ipcMain.emit("@func:main:hide")
} else { } 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) { if (Shared.data.forceClose) {
Shared.data.mainWindow = null Shared.data.mainWindow = null
app.quit() app.quit()
@ -77,7 +38,7 @@ ipcMain.on("@func:buildin:quit", (event) => {
defaultId: 0, defaultId: 0,
cancelId: 0, cancelId: 0,
message: "确定要关闭吗?", message: "确定要关闭吗?",
buttons: ["没事", "直接退出"] buttons: ["没事", "直接退出"],
}) })
if (choice === 1) { if (choice === 1) {
Shared.data.mainWindow = null Shared.data.mainWindow = null
@ -86,7 +47,10 @@ ipcMain.on("@func:buildin:quit", (event) => {
Shared.data.forceClose = true Shared.data.forceClose = true
app.quit() // exit()直接关闭客户端,不会执行quit(); app.quit() // exit()直接关闭客户端,不会执行quit();
} else { } else {
} }
} }
}) })
ipcMain.on("@func:render:addClock", (event, x, y) => {
ipcMain.emit("@func:main:show", event , "about")
})

101
src/main/facilities/main/index.ts

@ -2,30 +2,81 @@ import { app, BrowserWindow, dialog, ipcMain } from "electron"
import Shared from "@main/share" import Shared from "@main/share"
import { getFileUrl } from "@main/util" import { getFileUrl } from "@main/util"
function createWindow() { /**
/** * @方法:窗口:展示
* Initial window options */
*/ ipcMain.on("@func:main:show", (event, url) => {
Shared.data.mainWindow = new BrowserWindow({ showWindow(url)
height: 95, })
useContentSize: true, ipcMain.on("@func:main:hide", () => {
width: 260, if (Shared.data.mainWindow) {
resizable: false, Shared.data.mainWindow.hide()
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("")) export default function showWindow(url?: string) {
Shared.data.mainWindow.on("close", (event: any) => { if (!Shared.data.mainWindow || Shared.data.mainWindow?.isDestroyed()) {
ipcMain.emit("@func:buildin:quitOrTray") /**
}) * 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))
}
} }

48
src/main/facilities/tray/index.ts

@ -3,29 +3,24 @@ import { app, BrowserWindow, ipcMain, Menu, Tray } from "electron"
const path = require("path") const path = require("path")
// 隐藏主窗口,并创建托盘,绑定关闭事件 export function setTrayMenu() {
export default function setTray(mainWindow?: BrowserWindow | null) {
if (Shared.data.trayWindow) {
mainWindow?.hide()
return
}
// 用一个 Tray 来表示一个图标,这个图标处于正在运行的系统的通知区 // 用一个 Tray 来表示一个图标,这个图标处于正在运行的系统的通知区
// 通常被添加到一个 context menu 上. // 通常被添加到一个 context menu 上.
// 系统托盘右键菜单 // 系统托盘右键菜单
const trayMenuTemplate = [ const trayMenuTemplate = [
{ {
// 系统托盘图标目录 // 系统托盘图标目录
label: "打开窗口", label: "打开窗口",
click: () => { click: () => {
mainWindow?.show() ipcMain.emit("@func:main:show")
} },
}, },
{ {
// 系统托盘图标目录 // 系统托盘图标目录
label: "打开悬浮", label: "打开悬浮时钟",
click: () => { click: () => {
ipcMain.emit("showSuspensionWindow") ipcMain.emit("@func:float:show")
} },
}, },
{ {
// 系统托盘图标目录 // 系统托盘图标目录
@ -33,32 +28,37 @@ export default function setTray(mainWindow?: BrowserWindow | null) {
click: () => { click: () => {
Shared.data.forceClose = true Shared.data.forceClose = true
app.quit() 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") const iconPath = path.join(__static, "/icon.png")
Shared.data.trayWindow = new Tray(iconPath) Shared.data.trayWindow = new Tray(iconPath)
// 图标的上下文菜单
const contextMenu = Menu.buildFromTemplate(trayMenuTemplate)
// 展示主窗口,隐藏主窗口 mainWindow.hide() // 展示主窗口,隐藏主窗口 mainWindow.hide()
mainWindow?.hide() ipcMain.emit("@func:main:hide")
// 设置托盘悬浮提示 // 设置托盘悬浮提示
Shared.data.trayWindow.setToolTip("never forget") Shared.data.trayWindow.setToolTip("never forget")
// 设置托盘菜单
Shared.data.trayWindow.setContextMenu(contextMenu)
// 单击托盘小图标显示应用 // 单击托盘小图标显示应用
Shared.data.trayWindow.on("double-click", () => { Shared.data.trayWindow.on("double-click", () => {
// 显示主程序 // 显示主程序
mainWindow?.show() ipcMain.emit("@func:main:show")
// 关闭托盘显示
// Shared.data.trayWindow.destroy();
}) })
return Shared.data.trayWindow return Shared.data.trayWindow
} }

19
src/main/index.ts

@ -2,8 +2,9 @@
* electron * electron
*/ */
"use strict" "use strict"
import "@main/facilities/float/float" import "@main/facilities/float"
import setTray from "@main/facilities/tray" import "@main/facilities/main"
import setTray, {setTrayMenu} from "@main/facilities/tray"
import { app, ipcMain } from "electron" import { app, ipcMain } from "electron"
import "@main/facilities" import "@main/facilities"
import Shared from "@main/share" 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() const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) { if (!gotTheLock) {
app.exit() app.exit()
} else { } else {
function createWindow() {
setTray() // 初始化磁盘
ipcMain.emit("showSuspensionWindow") //展示悬浮窗
}
app.on("second-instance", (event, commandLine, workingDirectory) => { app.on("second-instance", (event, commandLine, workingDirectory) => {
// 当运行第二个实例时,将会聚焦到mainWindow这个窗口 // 当运行第二个实例时,将会聚焦到mainWindow这个窗口
// if (Shared.data.mainWindow) { // if (Shared.data.mainWindow) {
@ -103,9 +106,7 @@ if (!gotTheLock) {
// } // }
}) })
app.on("ready", () => { app.on("ready", createWindow)
})
app.on("before-quit", event => { app.on("before-quit", event => {
if (Shared.data.forceClose) { if (Shared.data.forceClose) {

18
src/render/views/Float/index.module.scss

@ -1,10 +1,14 @@
.view-float { .clock {
width: 100px;
height: 25px;
line-height: 25px;
background-color: #fff;
position: fixed; 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; user-select: none;
border: 1px solid red; pointer-events: none;
} }

49
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 () { import React from "react"
biasX = 0 import style from "./index.module.scss"
biasY = 0 import useTime from "./useTime"
document.removeEventListener("mousemove", moveEvent) import usePositionElectron from "./usePositionElectron"
})
function moveEvent(e: any) { function Float(props: any) {
electron.ipcRenderer.send('@float:setPosition', e.screenX - biasX, e.screenY - biasY) let [nowDate] = useTime()
// win.setPosition(e.screenX - biasX, e.screenY - biasY) usePositionElectron()
}
}, [])
function dblclick(e: MouseEventHandler<HTMLDivElement>) {
alert("asd")
}
return ( return (
<div className={style["view-float"]} onDoubleClick={(e: any) => dblclick(e)}> <div className={style.clock}>
<div>{nowDate.year}-{nowDate.month}-{nowDate.day}</div>
<div>{nowDate.hour}:{nowDate.minute}:{nowDate.second}</div>
</div> </div>
) )
} }
export default Float

32
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)
}
}, [])
}

55
src/render/views/Float/useTime.ts

@ -0,0 +1,55 @@
import { Dispatch, SetStateAction, useEffect, useState } from "react"
type ITime<T = string | number> = {
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<SetStateAction<ITime>>] {
let [nowDate, setNowDate] = useState<ITime>({})
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]
}

5
src/render/views/Home/index.tsx

@ -14,12 +14,9 @@ export interface HomeProps {
} }
function Home(props: HomeProps) { function Home(props: HomeProps) {
let [nowDate] = useTime()
usePositionElectron()
return ( return (
<div className={style.clock}> <div className={style.clock}>
<div>{nowDate.year}-{nowDate.month}-{nowDate.day}</div> asdsadasdsdasad
<div>{nowDate.hour}:{nowDate.minute}:{nowDate.second}</div>
</div> </div>
) )
} }

2
src/render/views/Home/usePositionElectron.ts

@ -14,7 +14,7 @@ export default function() {
document.addEventListener("mousemove", moveEvent) document.addEventListener("mousemove", moveEvent)
break break
case 2: case 2:
electron.ipcRenderer.send("createSuspensionMenu") electron.ipcRenderer.send("@func:float:showRightMenu")
break break
} }
}) })

Loading…
Cancel
Save