dootask/electron/main.js
2022-01-16 01:11:19 +08:00

424 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const fs = require('fs')
const fse = require('fs-extra')
const os = require("os");
const path = require('path')
const XLSX = require('xlsx');
const {app, BrowserWindow, ipcMain, dialog} = require('electron')
const utils = require('./utils');
const config = require('./package.json');
const log = require("electron-log");
let mainWindow = null,
subWindow = [],
willQuitApp = false,
inheritClose = false,
devloadUrl = "",
devloadCachePath = path.resolve(__dirname, ".devload"),
downloadList = [],
downloadCacheFile = path.join(app.getPath('cache'), config.name, '.downloadCache');
if (fs.existsSync(devloadCachePath)) {
devloadUrl = fs.readFileSync(devloadCachePath, 'utf8')
}
if (fs.existsSync(downloadCacheFile)) {
downloadList = utils.jsonParse(fs.readFileSync(downloadCacheFile, 'utf8'), [])
} else {
fse.ensureDirSync(path.join(app.getPath('cache'), config.name))
}
function downloadUpdate(item) {
const chain = item.getURLChain()
if (chain.length == 0) {
return
}
let currentState = item.getState()
if (currentState == "progressing" && item.isPaused()) {
currentState = "paused"
}
//
const downloadItem = downloadList.find(item => item.url == chain[0])
if (downloadItem && downloadItem.state != currentState) {
downloadItem.state = currentState;
downloadItem.result = {
url: item.getURL(),
name: item.getFilename(),
savePath: item.getSavePath(),
mimeType: item.getMimeType(),
totalBytes: item.getTotalBytes(),
chain,
};
fs.writeFileSync(downloadCacheFile, utils.jsonStringify(downloadList), 'utf8');
//
if (currentState == 'completed') {
mainWindow.webContents.send("downloadDone", downloadItem)
log.info("下载完成", downloadItem)
} else {
mainWindow.webContents.send("downloadUpdate", downloadItem)
log.info("下载更新", downloadItem)
}
}
}
function createMainWindow() {
mainWindow = new BrowserWindow({
width: 1280,
height: 800,
center: true,
autoHideMenuBar: true,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: true,
contextIsolation: false
}
})
mainWindow.webContents.setUserAgent(mainWindow.webContents.getUserAgent() + " MainTaskWindow/" + process.platform + "/" + os.arch() + "/1.0");
if (devloadUrl) {
mainWindow.loadURL(devloadUrl).then(r => {
})
} else {
mainWindow.loadFile('./public/index.html').then(r => {
})
}
mainWindow.on('page-title-updated', (event, title) => {
if (title == "index.html") {
event.preventDefault()
}
})
mainWindow.on('close', (e) => {
if (!willQuitApp) {
e.preventDefault();
if (inheritClose) {
mainWindow.webContents.send("windowClose", {})
} else {
if (process.platform === 'darwin') {
app.hide();
} else {
app.quit();
}
}
}
})
mainWindow.webContents.session.on('will-download', (event, item) => {
item.setSavePath(path.join(app.getPath('cache'), config.name, item.getFilename()));
item.on('updated', () => {
downloadUpdate(item)
})
item.on('done', () => {
downloadUpdate(item)
})
})
}
function createSubWindow(args) {
if (!args) {
return;
}
if (typeof args !== "object") {
args = {
path: args,
config: {},
}
}
let name = args.name || "auto_" + utils.randomString(6);
let item = subWindow.find(item => item.name == name);
let browser = item ? item.browser : null;
if (browser) {
browser.focus();
if (args.force === false) {
return;
}
} else {
let config = args.config || {};
if (typeof args.title !== "undefined") {
config.title = args.title;
}
browser = new BrowserWindow(Object.assign({
width: 1280,
height: 800,
center: true,
parent: mainWindow,
autoHideMenuBar: true,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
devTools: args.devTools !== false,
nodeIntegration: true,
contextIsolation: false
}
}, config))
browser.on('page-title-updated', (event, title) => {
if (title == "index.html" || args.titleFixed === true) {
event.preventDefault()
}
})
browser.on('close', () => {
let index = subWindow.findIndex(item => item.name == name);
if (index > -1) {
subWindow.splice(index, 1)
}
})
subWindow.push({ name, browser })
}
browser.webContents.setUserAgent(browser.webContents.getUserAgent() + " SubTaskWindow/" + process.platform + "/" + os.arch() + "/1.0" + (args.userAgent ? (" " + args.userAgent) : ""));
if (devloadUrl) {
browser.loadURL(devloadUrl + '#' + (args.hash || args.path)).then(r => {
})
} else {
browser.loadFile('./public/index.html', {
hash: args.hash || args.path
}).then(r => {
})
}
}
app.whenReady().then(() => {
createMainWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createMainWindow()
})
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('before-quit', () => {
willQuitApp = true
})
/**
* 继承关闭窗口事件
*/
ipcMain.on('inheritClose', (event) => {
inheritClose = true
event.returnValue = "ok"
})
/**
* 下载文件
* @param args {url}
*/
ipcMain.on('downloadFile', (event, args) => {
event.returnValue = "ok"
//
let appendJson = {state: "progressing", startTime: utils.Time()}
let downloadItem = downloadList.find(({url}) => url == args.url)
if (downloadItem) {
switch (downloadItem.state) {
case "completed":
if (fs.existsSync(downloadItem.result.savePath)) { // 下载完成,文件存在
log.info("下载已完成", downloadItem)
mainWindow.webContents.send("downloadDone", downloadItem)
return
}
break;
case "progressing":
if (downloadItem.startTime + 480 > utils.Time()) { // 下载中未超时超时时间8分钟
log.info("下载已存在", downloadItem)
return;
}
break;
}
downloadItem = Object.assign(downloadItem, appendJson)
} else {
downloadList.push(downloadItem = Object.assign(args, appendJson))
}
fs.writeFileSync(downloadCacheFile, utils.jsonStringify(downloadList), 'utf8');
mainWindow.webContents.downloadURL(downloadItem.url);
log.info("下载开始", downloadItem)
})
/**
* 打开文件
* @param args {path}
*/
ipcMain.on('openFile', (event, args) => {
utils.openFile(args.path)
event.returnValue = "ok"
})
/**
* 退出客户端
*/
ipcMain.on('windowQuit', (event) => {
event.returnValue = "ok"
app.quit();
})
/**
* 创建路由窗口
* @param args {path, ?}
*/
ipcMain.on('windowRouter', (event, args) => {
createSubWindow(args)
event.returnValue = "ok"
})
/**
* 隐藏窗口mac隐藏其他关闭
*/
ipcMain.on('windowHidden', (event) => {
if (process.platform === 'darwin') {
app.hide();
} else {
app.quit();
}
event.returnValue = "ok"
})
/**
* 关闭窗口
*/
ipcMain.on('windowClose', (event) => {
const win = BrowserWindow.fromWebContents(event.sender);
win.close()
event.returnValue = "ok"
})
/**
* 设置窗口尺寸
* @param args {width, height, autoZoom, minWidth, minHeight, maxWidth, maxHeight}
*/
ipcMain.on('windowSize', (event, args) => {
const win = BrowserWindow.fromWebContents(event.sender);
if (win) {
if (args.width || args.height) {
let [w, h] = win.getSize()
const width = args.width || w
const height = args.height || h
win.setSize(width, height, args.animate === true)
//
if (args.autoZoom === true) {
let move = false
let [x, y] = win.getPosition()
if (Math.abs(width - w) > 10) {
move = true
x -= (width - w) / 2
}
if (Math.abs(height - h) > 10) {
move = true
y -= (height - h) / 2
}
if (move) {
win.setPosition(Math.max(0, Math.floor(x)), Math.max(0, Math.floor(y)))
}
}
}
if (args.minWidth || args.minHeight) {
win.setMinimumSize(args.minWidth || win.getMinimumSize()[0], args.minHeight || win.getMinimumSize()[1])
}
if (args.maxWidth || args.maxHeight) {
win.setMaximumSize(args.maxWidth || win.getMaximumSize()[0], args.maxHeight || win.getMaximumSize()[1])
}
}
event.returnValue = "ok"
})
/**
* 设置窗口最小尺寸
* @param args {minWidth, minHeight}
*/
ipcMain.on('windowMinSize', (event, args) => {
const win = BrowserWindow.fromWebContents(event.sender);
if (win) {
win.setMinimumSize(args.minWidth || win.getMinimumSize()[0], args.minHeight || win.getMinimumSize()[1])
}
event.returnValue = "ok"
})
/**
* 设置窗口最大尺寸
* @param args {maxWidth, maxHeight}
*/
ipcMain.on('windowMaxSize', (event, args) => {
const win = BrowserWindow.fromWebContents(event.sender);
if (win) {
win.setMaximumSize(args.maxWidth || win.getMaximumSize()[0], args.maxHeight || win.getMaximumSize()[1])
}
event.returnValue = "ok"
})
/**
* 窗口居中
*/
ipcMain.on('windowCenter', (event) => {
const win = BrowserWindow.fromWebContents(event.sender);
if (win) {
win.center();
}
event.returnValue = "ok"
})
/**
* 窗口最大化或恢复
*/
ipcMain.on('windowMax', (event) => {
const win = BrowserWindow.fromWebContents(event.sender);
if (win.isMaximized()) {
win.restore();
} else {
win.maximize();
}
event.returnValue = "ok"
})
/**
* 给主窗口发送信息
* @param args {channel, data}
*/
ipcMain.on('sendForwardMain', (event, args) => {
if (mainWindow) {
mainWindow.webContents.send(args.channel, args.data)
}
event.returnValue = "ok"
})
/**
* 设置Dock标记
* @param args
*/
ipcMain.on('setDockBadge', (event, args) => {
if(process.platform !== 'darwin'){
// Mac only
return;
}
if (utils.runNum(args) > 0) {
app.dock.setBadge(String(args))
} else {
app.dock.setBadge("")
}
event.returnValue = "ok"
})
/**
* 保存sheets
*/
ipcMain.on('saveSheet', (event, data, filename, opts) => {
const EXTENSIONS = "xls|xlsx|xlsm|xlsb|xml|csv|txt|dif|sylk|slk|prn|ods|fods|htm|html".split("|");
dialog.showSaveDialog({
title: 'Save file as',
defaultPath: filename,
filters: [{
name: "Spreadsheets",
extensions: EXTENSIONS
}]
}).then(o => {
XLSX.writeFile(data, o.filePath, opts);
});
event.returnValue = "ok"
})