WGShare.Client.Electron/main.js

433 lines
14 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 {
app,
BrowserWindow,
screen,
Tray,
nativeImage,
Menu,
ipcMain,
clipboard,
dialog,
desktopCapturer,
} = require('electron');
const path = require('node:path')
const fs = require('fs');
const Registry = require('winreg');
const { autoUpdater, CancellationToken } = require('electron-updater');
const cancellationToken = new CancellationToken()
app.allowRendererProcessReuse = false;
let mainWindow = null;
let childWindow = {}
let isMaximized = false;
let env;
let regKey;
class AppWindow extends BrowserWindow {
constructor(config) {
const basicConfig = {
webPreferences: {
contextIsolation: false,
nodeIntegration: true,
enableRemoteModule: true,
nodeIntegrationInWorker: true,
allowMediaDevices: true,
preload: path.join(__dirname, 'preload.js')
},
show: false,
frame: false,
backgroundColor: '#00000000',
transparent: true,
};
const finalConfig = { ...basicConfig, ...config };
super(finalConfig);
if (env === 'development') {
// 开发
this.loadURL('http://localhost:3000');
} else {
// 测试 | 生产
this.loadFile(path.resolve(__dirname, './dist/index.html'));
}
this.once('ready-to-show', () => {
this.show();
});
}
}
function showWindow() {
// 如果主窗口已经存在但被最小化了,则恢复显示
if (mainWindow && mainWindow.isMinimized()) {
mainWindow.show();
}
// 如果主窗口已存在但不是焦点窗口,则将其置为焦点
if (mainWindow && !mainWindow.isFocused()) {
mainWindow.show();
mainWindow.focus();
}
// 如果主窗口还没有被创建,则创建它
if (!mainWindow) {
createWindow();
}
}
function quit() {
app.quit()
}
function createTray() {
const iconPath = `${__dirname}/src/assets/icon.png`;
const trayIcon = nativeImage.createFromPath(iconPath);
const tray = new Tray(trayIcon);
const contextMenu = Menu.buildFromTemplate([
{
label: '打开', click: () => {
showWindow()
},
// icon: iconPath,
},
{
label: '最小化到系统托盘', click: () => {
mainWindow.hide();
},
// icon: iconPath,
},
{
label: '退出', click: async () => {
quit()
},
// icon: iconPath,
},
]);
tray.setToolTip('智汇享');
tray.setContextMenu(contextMenu);
tray.on('click', () => {
if (mainWindow.isVisible()) {
mainWindow.hide()
} else {
mainWindow.show()
}
});
}
function createWindow() {
mainWindow = new AppWindow();
mainWindow.focus();
}
const additionalData = { myKey: 'myValue' }
// 退出房间
app.on('will-quit', async (event) => {
await mainWindow.webContents.send('quitAndInstall');
});
app.on('ready', () => {
const gotTheLock = app.requestSingleInstanceLock(additionalData)
if (gotTheLock) {
env = process.argv.find((arg) => arg.startsWith('--env='))?.split('=')[1];
if (env === 'development') {
Object.defineProperty(app, 'isPackaged', {
get() {
return true
}
})
autoUpdater.updateConfigPath = path.join('latest.yml')
}
createWindow()
updateHandle() // 检查更新
setInterval(() => {
updateHandle() // 每一小时检查更新
}, 1000 * 60 * 60)
createTray()
regKey = new Registry({
hive: Registry.HKCU,
key: '\\Software\\ZhiHuiXiang'
});
// 获取当前脚本所在目录的绝对路径
const currentDirectory = __dirname;
// 获取安装父目录
const parentDirectory = path.resolve(currentDirectory, '..');
const customFolderPath = path.join(parentDirectory, 'Downloads');
if (!fs.existsSync(customFolderPath)) {
// 如果不存在,则创建文件夹
fs.mkdirSync(customFolderPath);
}
// 监听f12打开控制台
mainWindow.webContents.on('before-input-event', (event, input) => {
// if (env === 'development') {
if (input.key === 'F12') {
mainWindow.webContents.openDevTools()
}
// }
});
// 监听移动
mainWindow.on('move', () => {
// 如果是全屏自动恢复到上次窗口大小
if (isMaximized) {
mainWindow.setResizable(true)
mainWindow.unmaximize()
isMaximized = false;
}
if (mainWindow.isMaximized()) {
isMaximized = true;
}
});
// 放大缩小退出窗口
ipcMain.handle('setViewStatus', async (event, status) => {
switch (status) {
case 'quit':
await mainWindow.webContents.send('onQuit');
break;
case 'maximize':
mainWindow.maximize()
mainWindow.setResizable(false)
break;
case 'unmaximize':
mainWindow.setResizable(true)
mainWindow.unmaximize()
break;
case 'minimize':
mainWindow.minimize()
break;
case 'hide':
mainWindow.hide()
break;
}
});
// 导出是否全屏
ipcMain.handle('getIsMaximized', () => {
return mainWindow.isMaximized();
});
// 获取版本号
ipcMain.handle('getVersion', () => {
return app.getVersion();
});
// 获取共享屏幕列表
ipcMain.handle('getSources', async () => {
return await desktopCapturer.getSources({
types: ['screen']
});
});
// 复制文字
ipcMain.handle('setWriteText', (event, text) => {
clipboard.writeText(text)
});
// 退出
ipcMain.handle('quit', async (event) => {
await mainWindow.webContents.send('quitAndInstall');
quit()
});
// 加入房间通知
ipcMain.handle('joinNotification', (event, user) => {
mainWindow.show()
mainWindow.focus();
});
// 通知下载包
ipcMain.handle('updateDownload', (event, data) => {
if (data === '0') { // 取消下载
cancleDownloadUpdate()
} else if (data === '1') { // 开始下载
downloadUpdate()
} else if (data === '2') { // 下载完成 点击安装
quitAndInstall()
}
});
// 选择文件夹
ipcMain.handle('selectFilePath', async (event, data) => {
const result = await dialog.showOpenDialog({
properties: ['openDirectory']
});
if (result.canceled) {
} else {
switch (data.key) {
case 'shareFilesPath':
case 'recordingFilesPath':
mainWindow.webContents.send('onFilePath', result.filePaths[0] + '\\', data.key);
break;
default:
mainWindow.webContents.send('downFile', {
downFilePaths: result.filePaths[0] + '\\',
fileName: data.fileName,
filePath: data.filePath,
});
break;
}
}
});
// 获取桌面大小
ipcMain.handle('getWindowSize', (event, config) => {
const primaryDisplay = screen.getPrimaryDisplay()
const { width, height } = primaryDisplay.workAreaSize
return { width, height }
});
// 设置桌面应用基础属性
ipcMain.handle('setMainWindowSize', (event, config) => {
// 设置最小窗口尺寸
mainWindow.setMinimumSize(config.width, config.height);
// 设置最大尺寸
const primaryDisplay = screen.getPrimaryDisplay()
const { width, height } = primaryDisplay.workAreaSize
if (config.key === 'login') {
mainWindow.setMaximumSize(config.width, config.height);
} else {
mainWindow.setMaximumSize(width, height);
}
// 设置窗口尺寸
mainWindow.setSize(config.width, config.height)
// 设置窗口位置使其居中于当前屏幕
mainWindowCenter()
});
// 写入注册表
ipcMain.handle('setRegistry', (event, uuid) => {
regKey.create((err) => {
if (err) {
return;
}
// 设置键和值
regKey.set('uuid', Registry.REG_SZ, uuid, (err) => {
if (err) {
return;
}
});
});
});
// 读取注册表
ipcMain.handle('getRegistry', async () => {
return new Promise((resolve, reject) => {
regKey.get('uuid', (err, item) => {
resolve(item)
})
});
});
// 创建子窗口
ipcMain.handle('createChildWindow', (event, config) => {
const child = new BrowserWindow({
parent: mainWindow,
webPreferences: {
contextIsolation: false,
nodeIntegration: true,
enableRemoteModule: true,
nodeIntegrationInWorker: true,
allowMediaDevices: true,
preload: path.join(__dirname, 'preload.js')
},
show: false,
frame: false,
backgroundColor: '#00000000',
transparent: true,
width: config.width,
height: config.height,
})
child.loadURL(config.url)
childWindow[config.key] = child
child.once('ready-to-show', () => {
childWindow[config.key].show()
windowOperation(config)
})
});
// 关闭子窗口
ipcMain.handle('closeChildWindow', (event, key) => {
childWindow[key].close()
childWindow[key] = ""
mainWindowCenter()
});
// 隐藏主窗口
ipcMain.handle('mainWindowHide', () => {
mainWindowHide()
});
// 居中主窗口
ipcMain.handle('mainWindowCenter', () => {
mainWindowCenter()
});
}
});
// 检测更新在你想要检查更新的时候执行renderer事件触发后的操作自行编写
function updateHandle() {
autoUpdater.checkForUpdates()
// autoUpdater.checkForUpdatesAndNotify().catch();
const message = {
error: '检查更新出错',
checking: '正在检查更新……',
updateAva: '检测到新版本,正在下载……',
updateNotAva: '已经是最新版本,不用更新'
}
autoUpdater.setFeedURL('https://meeting-api.23544.com/meeting/update')
autoUpdater.autoDownload = false // 不自动下载安装包
autoUpdater.autoInstallOnAppQuit = false // 不自动安装
autoUpdater.on('error', function (error) {
sendUpdateMessage(message.error)
})
autoUpdater.on('checking-for-update', function () {
sendUpdateMessage(message.checking)
})
autoUpdater.on('update-available', function (info) {
let messageStr = JSON.stringify({ type: '0' })
setTimeout(() => {
sendUpdateMessage(messageStr)
}, 5000)
})
autoUpdater.on('update-not-available', function (info) {
})
// 更新下载进度事件
autoUpdater.on('download-progress', function (progressObj) {
let message = JSON.stringify({
type: '1',
value: progressObj.percent
})
sendUpdateMessage(message)
})
autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
let message = JSON.stringify({
type: '2',
})
sendUpdateMessage(message)
})
}
// 通过main进程发送事件给renderer进程提示更新信息
// type: 0 检测到需要更新(打开窗口) 1 正在下载更新包
function sendUpdateMessage(text) {
mainWindow.webContents.send('update', text)
}
// 下载最新的包
function downloadUpdate() {
autoUpdater.downloadUpdate(cancellationToken)
}
// 取消下载
function cancleDownloadUpdate() {
autoUpdater.downloadUpdate(cancellationToken)
// stop download
cancellationToken.cancel()
}
// 完成下载立即安装
function quitAndInstall() {
autoUpdater.quitAndInstall();
}
function windowOperation(config) {
const child = childWindow[config.key];
if (config.key === 'shareScreenWindow') {
const display = screen.getDisplayMatching({ ...child.getBounds() });
const x = Math.round((display.workArea.width - child.getSize()[0]) / 2);
child.setPosition(x, 0);
child.setResizable(false)
child.setMovable(false)
mainWindowHide()
if (env === 'development') {
child.webContents.openDevTools()
}
}
}
// 主窗口居中
function mainWindowCenter() {
const display = screen.getDisplayMatching({ ...mainWindow.getBounds() });
const x = Math.round((display.workArea.width - mainWindow.getSize()[0]) / 2);
const y = Math.round((display.workArea.height - mainWindow.getSize()[1]) / 2);
mainWindow.setPosition(x, y);
}
// 主窗口隐藏
function mainWindowHide() {
mainWindow.setPosition(-999999, -999999);
}