自动更新
This commit is contained in:
parent
f5ba7b4284
commit
52fd0e3410
|
|
@ -0,0 +1,8 @@
|
|||
version: 0.0.3
|
||||
files:
|
||||
- url: 智汇享 Setup 0.0.3.exe
|
||||
sha512: E8CIX2h4+VYvFcdIxUUolwfZgG+ZAQTdIAoVmyst11/x6aTA19Mx2/Lfuy5wCuMC0YA8ci5oXD91CEIev7r+TQ==
|
||||
size: 117050951
|
||||
path: 智汇享 Setup 0.0.3.exe
|
||||
sha512: E8CIX2h4+VYvFcdIxUUolwfZgG+ZAQTdIAoVmyst11/x6aTA19Mx2/Lfuy5wCuMC0YA8ci5oXD91CEIev7r+TQ==
|
||||
releaseDate: '2024-07-24T02:13:28.542Z'
|
||||
457
main.js
457
main.js
|
|
@ -1,177 +1,304 @@
|
|||
const { app, BrowserWindow, screen, Tray, nativeImage, Menu, ipcMain, clipboard, dialog, webFrame, Notification } = require('electron');
|
||||
const {
|
||||
app,
|
||||
BrowserWindow,
|
||||
screen,
|
||||
Tray,
|
||||
nativeImage,
|
||||
Menu,
|
||||
ipcMain,
|
||||
clipboard,
|
||||
dialog,
|
||||
webFrame,
|
||||
Notification
|
||||
} = require('electron');
|
||||
const path = require('node:path')
|
||||
const {autoUpdater, CancellationToken} = require('electron-updater');
|
||||
const cancellationToken = new CancellationToken()
|
||||
app.allowRendererProcessReuse = false;
|
||||
let mainWindow = null;
|
||||
let isMaximized = false;
|
||||
|
||||
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);
|
||||
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);
|
||||
const env = process.argv.find((arg) => arg.startsWith('--env='))?.split('=')[1];
|
||||
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 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: async () => {
|
||||
await mainWindow.webContents.send('quit');
|
||||
app.quit();
|
||||
mainWindow = null;
|
||||
},
|
||||
// icon: iconPath,
|
||||
},
|
||||
{
|
||||
label: '退出到系统托盘', click: () => {
|
||||
mainWindow.hide();
|
||||
},
|
||||
// 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();
|
||||
}
|
||||
|
||||
function createNotification(user) {
|
||||
const notification = new Notification({
|
||||
title: `${user.name} 邀请你加入`,
|
||||
body: user.body,
|
||||
// icon: path.join(`${__dirname}/src/assets/avatar.png`)
|
||||
});
|
||||
notification.show();
|
||||
mainWindow.focus();
|
||||
}
|
||||
|
||||
app.on('ready', () => {
|
||||
const env = process.argv.find((arg) => arg.startsWith('--env='))?.split('=')[1];
|
||||
if (env === 'development') {
|
||||
// 开发
|
||||
this.loadURL('http://localhost:3000');
|
||||
} else {
|
||||
// 测试 | 生产
|
||||
this.loadFile(path.resolve(__dirname, './dist/index.html'));
|
||||
Object.defineProperty(app, 'isPackaged', {
|
||||
get() {
|
||||
return true
|
||||
}
|
||||
})
|
||||
autoUpdater.updateConfigPath = path.join('latest.yml')
|
||||
// autoUpdater.updateConfigPath = path.join('http://test.bossmei.top/electron/latest.yml')
|
||||
}
|
||||
this.once('ready-to-show', () => {
|
||||
this.show();
|
||||
// autoUpdater.updateConfigPath = path.join('http://test.bossmei.top/electron/latest.yml')
|
||||
console.log(123123123)
|
||||
createWindow()
|
||||
updateHandle() // 检查更新
|
||||
createTray()
|
||||
// 监听f12打开控制台
|
||||
mainWindow.webContents.on('before-input-event', (event, input) => {
|
||||
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('quit');
|
||||
app.quit();
|
||||
mainWindow = null;
|
||||
break;
|
||||
case 'maximize':
|
||||
mainWindow.maximize()
|
||||
mainWindow.setResizable(false)
|
||||
break;
|
||||
case 'unmaximize':
|
||||
mainWindow.setResizable(true)
|
||||
mainWindow.unmaximize()
|
||||
break;
|
||||
case 'minimize':
|
||||
mainWindow.minimize()
|
||||
break;
|
||||
}
|
||||
});
|
||||
// 导出是否全屏
|
||||
ipcMain.handle('getIsMaximized', () => {
|
||||
return mainWindow.isMaximized();
|
||||
});
|
||||
// 复制文字
|
||||
ipcMain.handle('setWriteText', (event, text) => {
|
||||
clipboard.writeText(text)
|
||||
});
|
||||
// 加入房间通知
|
||||
ipcMain.handle('joinNotification', (event, user) => {
|
||||
createNotification(user)
|
||||
});
|
||||
// 通知下载包
|
||||
ipcMain.handle('updateDownload', (event, data) => {
|
||||
if (data === '0') { // 取消下载
|
||||
cancleDownloadUpdate()
|
||||
} else if (data === '1') { // 开始下载
|
||||
downloadUpdate()
|
||||
} else if (data === '2') { // 下载完成 点击安装
|
||||
quitAndInstall()
|
||||
}
|
||||
});
|
||||
// 设置桌面应用基础属性
|
||||
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)
|
||||
// 设置窗口位置使其居中于当前屏幕
|
||||
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 showWindow() {
|
||||
// 如果主窗口已经存在但被最小化了,则恢复显示
|
||||
if (mainWindow && mainWindow.isMinimized()) {
|
||||
mainWindow.show();
|
||||
}
|
||||
// 如果主窗口已存在但不是焦点窗口,则将其置为焦点
|
||||
if (mainWindow && !mainWindow.isFocused()) {
|
||||
mainWindow.show();
|
||||
mainWindow.focus();
|
||||
}
|
||||
// 如果主窗口还没有被创建,则创建它
|
||||
if (!mainWindow) {
|
||||
createWindow();
|
||||
}
|
||||
}
|
||||
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: async () => {
|
||||
await mainWindow.webContents.send('quit');
|
||||
app.quit();
|
||||
mainWindow = null;
|
||||
},
|
||||
// icon: iconPath,
|
||||
},
|
||||
{
|
||||
label: '退出到系统托盘', click: () => {
|
||||
mainWindow.hide();
|
||||
},
|
||||
// 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();
|
||||
}
|
||||
function createNotification(user) {
|
||||
const notification = new Notification({
|
||||
title: `${user.name} 邀请你加入`,
|
||||
body: user.body,
|
||||
// icon: path.join(`${__dirname}/src/assets/avatar.png`)
|
||||
});
|
||||
notification.show();
|
||||
mainWindow.focus();
|
||||
}
|
||||
app.on('ready', () => {
|
||||
createWindow()
|
||||
createTray()
|
||||
// 监听f12打开控制台
|
||||
mainWindow.webContents.on('before-input-event', (event, input) => {
|
||||
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('quit');
|
||||
app.quit();
|
||||
mainWindow = null;
|
||||
break;
|
||||
case 'maximize':
|
||||
mainWindow.maximize()
|
||||
mainWindow.setResizable(false)
|
||||
break;
|
||||
case 'unmaximize':
|
||||
mainWindow.setResizable(true)
|
||||
mainWindow.unmaximize()
|
||||
break;
|
||||
case 'minimize':
|
||||
mainWindow.minimize()
|
||||
break;
|
||||
}
|
||||
});
|
||||
// 导出是否全屏
|
||||
ipcMain.handle('getIsMaximized', () => {
|
||||
return mainWindow.isMaximized();
|
||||
});
|
||||
// 复制文字
|
||||
ipcMain.handle('setWriteText', (event, text) => {
|
||||
clipboard.writeText(text)
|
||||
});
|
||||
// 加入房间通知
|
||||
ipcMain.handle('joinNotification', (event, user) => {
|
||||
createNotification(user)
|
||||
});
|
||||
// 设置桌面应用基础属性
|
||||
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)
|
||||
// 设置窗口位置使其居中于当前屏幕
|
||||
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);
|
||||
});
|
||||
});
|
||||
|
||||
// 检测更新,在你想要检查更新的时候执行,renderer事件触发后的操作自行编写
|
||||
function updateHandle() {
|
||||
autoUpdater.checkForUpdates()
|
||||
// autoUpdater.checkForUpdatesAndNotify().catch();
|
||||
const message = {
|
||||
error: '检查更新出错',
|
||||
checking: '正在检查更新……',
|
||||
updateAva: '检测到新版本,正在下载……',
|
||||
updateNotAva: '现在使用的就是最新版本,不用更新'
|
||||
}
|
||||
autoUpdater.setFeedURL('http://test.bossmei.top/electron')
|
||||
autoUpdater.autoDownload = false // 不自动下载安装包
|
||||
autoUpdater.autoInstallOnAppQuit = false // 不自动安装
|
||||
// eslint-disable-next-line handle-callback-err
|
||||
autoUpdater.on('error', function (error) {
|
||||
// sendUpdateError(JSON.stringify(error))
|
||||
sendUpdateMessage(message.error)
|
||||
})
|
||||
autoUpdater.on('checking-for-update', function () {
|
||||
console.log('开始检测')
|
||||
console.log('checking-for-update')
|
||||
sendUpdateMessage(message.checking)
|
||||
})
|
||||
autoUpdater.on('update-available', function (info) {
|
||||
console.log('update-available', info)
|
||||
let messageStr = JSON.stringify({type: '0'})
|
||||
// todo 延迟5秒打开弹窗(逻辑要改)
|
||||
setTimeout(() => {
|
||||
sendUpdateMessage(messageStr)
|
||||
}, 5000)
|
||||
// sendUpdateMessage(message.updateAva)
|
||||
})
|
||||
autoUpdater.on('update-not-available', function (info) {
|
||||
console.log(info)
|
||||
// sendUpdateMessage(message.updateNotAva)
|
||||
})
|
||||
// 更新下载进度事件
|
||||
autoUpdater.on('download-progress', function (progressObj) {
|
||||
let message = JSON.stringify({
|
||||
type: '1',
|
||||
value: progressObj.percent
|
||||
})
|
||||
sendUpdateMessage(message)
|
||||
console.log(progressObj.percent)
|
||||
// mainWindow.webContents.send('downloadProgress', progressObj)
|
||||
})
|
||||
autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
|
||||
console.log('下载完成---------------')
|
||||
let message = JSON.stringify({
|
||||
type: '3',
|
||||
})
|
||||
// sendUpdateMessage(message)
|
||||
autoUpdater.quitAndInstall()
|
||||
ipcMain.on('isUpdateNow', (e, arg) => {
|
||||
console.log(arg)
|
||||
console.log('开始更新')
|
||||
// some code here to handle event
|
||||
autoUpdater.quitAndInstall()
|
||||
})
|
||||
// mainWindow.webContents.send('isUpdateNow')
|
||||
})
|
||||
}
|
||||
|
||||
// 通过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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "multi.person.meeting",
|
||||
"version": "0.0.0",
|
||||
"version": "0.0.1",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "multi.person.meeting",
|
||||
"version": "0.0.0",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.3.7",
|
||||
"@microsoft/signalr": "^8.0.0",
|
||||
|
|
@ -18,6 +18,7 @@
|
|||
"crypto-js": "^4.2.0",
|
||||
"dayjs": "^1.11.11",
|
||||
"electron-squirrel-startup": "^1.0.1",
|
||||
"electron-updater": "^6.2.1",
|
||||
"os": "^0.1.2",
|
||||
"path": "^0.12.7",
|
||||
"postcss-px-to-viewport-8-plugin": "^1.2.5",
|
||||
|
|
@ -3123,8 +3124,7 @@
|
|||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||
"dev": true
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||
},
|
||||
"node_modules/aria-hidden": {
|
||||
"version": "1.2.4",
|
||||
|
|
@ -4413,7 +4413,6 @@
|
|||
"version": "4.3.5",
|
||||
"resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.5.tgz",
|
||||
"integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
},
|
||||
|
|
@ -5165,6 +5164,33 @@
|
|||
"integrity": "sha512-VY+J0e4SFcNfQy19MEoMdaIcZLmDCprqvBtkii1WTCTQHpRvf5N8+3kTYCgL/PcntvwQvmMJWTuDPsq+IlhWKQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/electron-updater": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-6.2.1.tgz",
|
||||
"integrity": "sha512-83eKIPW14qwZqUUM6wdsIRwVKZyjmHxQ4/8G+1C6iS5PdDt7b1umYQyj1/qPpH510GmHEQe4q0kCPe3qmb3a0Q==",
|
||||
"dependencies": {
|
||||
"builder-util-runtime": "9.2.4",
|
||||
"fs-extra": "^10.1.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"lazy-val": "^1.0.5",
|
||||
"lodash.escaperegexp": "^4.1.2",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
"semver": "^7.3.8",
|
||||
"tiny-typed-emitter": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-updater/node_modules/builder-util-runtime": {
|
||||
"version": "9.2.4",
|
||||
"resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz",
|
||||
"integrity": "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==",
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4",
|
||||
"sax": "^1.2.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/electron/node_modules/@electron/get": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/@electron/get/-/get-2.0.3.tgz",
|
||||
|
|
@ -6299,7 +6325,6 @@
|
|||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
|
|
@ -7608,7 +7633,6 @@
|
|||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1"
|
||||
},
|
||||
|
|
@ -7733,8 +7757,7 @@
|
|||
"node_modules/lazy-val": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/lazy-val/-/lazy-val-1.0.5.tgz",
|
||||
"integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==",
|
||||
"dev": true
|
||||
"integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q=="
|
||||
},
|
||||
"node_modules/lazystream": {
|
||||
"version": "1.0.1",
|
||||
|
|
@ -7821,6 +7844,11 @@
|
|||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/lodash.escaperegexp": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz",
|
||||
"integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw=="
|
||||
},
|
||||
"node_modules/lodash.isequal": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||
|
|
@ -10294,8 +10322,7 @@
|
|||
"node_modules/sax": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/sax/-/sax-1.4.1.tgz",
|
||||
"integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="
|
||||
},
|
||||
"node_modules/scheduler": {
|
||||
"version": "0.23.2",
|
||||
|
|
@ -10334,7 +10361,6 @@
|
|||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.6.2.tgz",
|
||||
"integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
|
|
@ -11068,6 +11094,11 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tiny-typed-emitter": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz",
|
||||
"integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA=="
|
||||
},
|
||||
"node_modules/tldraw": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/tldraw/-/tldraw-2.3.0.tgz",
|
||||
|
|
@ -14183,8 +14214,7 @@
|
|||
"argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||
"dev": true
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||
},
|
||||
"aria-hidden": {
|
||||
"version": "1.2.4",
|
||||
|
|
@ -15142,7 +15172,6 @@
|
|||
"version": "4.3.5",
|
||||
"resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.5.tgz",
|
||||
"integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
|
|
@ -15791,6 +15820,32 @@
|
|||
"integrity": "sha512-VY+J0e4SFcNfQy19MEoMdaIcZLmDCprqvBtkii1WTCTQHpRvf5N8+3kTYCgL/PcntvwQvmMJWTuDPsq+IlhWKQ==",
|
||||
"dev": true
|
||||
},
|
||||
"electron-updater": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-6.2.1.tgz",
|
||||
"integrity": "sha512-83eKIPW14qwZqUUM6wdsIRwVKZyjmHxQ4/8G+1C6iS5PdDt7b1umYQyj1/qPpH510GmHEQe4q0kCPe3qmb3a0Q==",
|
||||
"requires": {
|
||||
"builder-util-runtime": "9.2.4",
|
||||
"fs-extra": "^10.1.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"lazy-val": "^1.0.5",
|
||||
"lodash.escaperegexp": "^4.1.2",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
"semver": "^7.3.8",
|
||||
"tiny-typed-emitter": "^2.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"builder-util-runtime": {
|
||||
"version": "9.2.4",
|
||||
"resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz",
|
||||
"integrity": "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==",
|
||||
"requires": {
|
||||
"debug": "^4.3.4",
|
||||
"sax": "^1.2.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"enabled": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/enabled/-/enabled-2.0.0.tgz",
|
||||
|
|
@ -16533,7 +16588,6 @@
|
|||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
|
|
@ -17514,7 +17568,6 @@
|
|||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"argparse": "^2.0.1"
|
||||
}
|
||||
|
|
@ -17616,8 +17669,7 @@
|
|||
"lazy-val": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/lazy-val/-/lazy-val-1.0.5.tgz",
|
||||
"integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==",
|
||||
"dev": true
|
||||
"integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q=="
|
||||
},
|
||||
"lazystream": {
|
||||
"version": "1.0.1",
|
||||
|
|
@ -17688,6 +17740,11 @@
|
|||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.escaperegexp": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz",
|
||||
"integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw=="
|
||||
},
|
||||
"lodash.isequal": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||
|
|
@ -19468,8 +19525,7 @@
|
|||
"sax": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/sax/-/sax-1.4.1.tgz",
|
||||
"integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="
|
||||
},
|
||||
"scheduler": {
|
||||
"version": "0.23.2",
|
||||
|
|
@ -19505,8 +19561,7 @@
|
|||
"semver": {
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.6.2.tgz",
|
||||
"integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w=="
|
||||
},
|
||||
"semver-compare": {
|
||||
"version": "1.0.0",
|
||||
|
|
@ -20109,6 +20164,11 @@
|
|||
"resolved": "https://registry.npmmirror.com/timed-out/-/timed-out-4.0.1.tgz",
|
||||
"integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA=="
|
||||
},
|
||||
"tiny-typed-emitter": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz",
|
||||
"integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA=="
|
||||
},
|
||||
"tldraw": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/tldraw/-/tldraw-2.3.0.tgz",
|
||||
|
|
|
|||
10
package.json
10
package.json
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "multi.person.meeting",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"version": "0.0.3",
|
||||
"main": "main.js",
|
||||
"authors": "yj",
|
||||
"description": "test",
|
||||
|
|
@ -33,6 +33,7 @@
|
|||
"crypto-js": "^4.2.0",
|
||||
"dayjs": "^1.11.11",
|
||||
"electron-squirrel-startup": "^1.0.1",
|
||||
"electron-updater": "^6.2.1",
|
||||
"os": "^0.1.2",
|
||||
"path": "^0.12.7",
|
||||
"postcss-px-to-viewport-8-plugin": "^1.2.5",
|
||||
|
|
@ -63,7 +64,12 @@
|
|||
"buildDependenciesFromSource": true,
|
||||
"compression": "normal",
|
||||
"productName": "智汇享",
|
||||
"publish": [],
|
||||
"publish": [
|
||||
{
|
||||
"provider": "generic",
|
||||
"url": "http://test.bossmei.top/electron"
|
||||
}
|
||||
],
|
||||
"files": [
|
||||
"!*.log"
|
||||
],
|
||||
|
|
|
|||
69
preload.js
69
preload.js
|
|
@ -1,32 +1,41 @@
|
|||
// // 在 preload 脚本中。
|
||||
const { ipcRenderer } = require('electron')
|
||||
const {ipcRenderer, contextBridge} = require('electron')
|
||||
|
||||
// contextBridge.exposeInMainWorld("elecAPI", {
|
||||
// onUpdate: (callback) => ipcRenderer.on("update", callback),
|
||||
// checkForUpdate: () => ipcRenderer.send("checkForUpdate"),
|
||||
// });
|
||||
window.electron = {
|
||||
// 设置窗口大小
|
||||
setMainWindowSize: (config) => {
|
||||
ipcRenderer.invoke('setMainWindowSize', { ...config })
|
||||
},
|
||||
// 设置窗口状态
|
||||
setViewStatus: (status) => {
|
||||
ipcRenderer.invoke('setViewStatus', status)
|
||||
},
|
||||
// 获取当前是否全屏
|
||||
getIsMaximized: () => {
|
||||
return ipcRenderer.invoke('getIsMaximized')
|
||||
},
|
||||
// 复制文字
|
||||
setWriteText: (text) => {
|
||||
return ipcRenderer.invoke('setWriteText', text)
|
||||
},
|
||||
// 加入房间通知
|
||||
joinNotification: (user) => {
|
||||
ipcRenderer.invoke('joinNotification', user)
|
||||
},
|
||||
// 监听退出
|
||||
onQuit: (callback) => {
|
||||
ipcRenderer.on('quit', callback)
|
||||
},
|
||||
// 监听更新
|
||||
onUpdate: (callback) => {
|
||||
ipcRenderer.on('update', callback)
|
||||
},
|
||||
}
|
||||
// 设置窗口大小
|
||||
setMainWindowSize: (config) => {
|
||||
ipcRenderer.invoke('setMainWindowSize', {...config})
|
||||
},
|
||||
// 设置窗口状态
|
||||
setViewStatus: (status) => {
|
||||
ipcRenderer.invoke('setViewStatus', status)
|
||||
},
|
||||
// 获取当前是否全屏
|
||||
getIsMaximized: () => {
|
||||
return ipcRenderer.invoke('getIsMaximized')
|
||||
},
|
||||
// 复制文字
|
||||
setWriteText: (text) => {
|
||||
return ipcRenderer.invoke('setWriteText', text)
|
||||
},
|
||||
// 加入房间通知
|
||||
joinNotification: (user) => {
|
||||
ipcRenderer.invoke('joinNotification', user)
|
||||
},
|
||||
// 监听退出
|
||||
onQuit: (callback) => {
|
||||
ipcRenderer.on('quit', callback)
|
||||
},
|
||||
// 监听更新
|
||||
onUpdate: (callback) => {
|
||||
ipcRenderer.on('update', callback)
|
||||
},
|
||||
// 通知下载最新的包
|
||||
onDownload: (type) => {
|
||||
ipcRenderer.invoke('updateDownload', type)
|
||||
},
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
|
|
@ -1 +1,35 @@
|
|||
.isUpdateModal {}
|
||||
.isUpdateModal {
|
||||
width: 338px;
|
||||
height: 432px;
|
||||
background: url("../../assets/updateBg.png");
|
||||
background-size: 100% 100%;
|
||||
color: #ffffff;
|
||||
padding: 230px 30px 0;
|
||||
box-sizing: border-box;
|
||||
|
||||
.remarks {
|
||||
width: 100%;
|
||||
color: #C8C8C8;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
width: 100%;
|
||||
margin-top: 32px;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
|
||||
.button1 {
|
||||
width: 100%;
|
||||
height: 44px;
|
||||
background-color: #5575F2;
|
||||
line-height: 44px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.button2 {
|
||||
margin-top: 20px;
|
||||
color: #555454;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,29 +1,80 @@
|
|||
import styles from '@/components/UpdateModal/index.module.scss'
|
||||
import { Modal } from 'antd';
|
||||
import { useState, useImperativeHandle, forwardRef } from "react";
|
||||
const UpdateModal = forwardRef((props: any, ref: any) => {
|
||||
useImperativeHandle(ref, () => ({
|
||||
changeModal: (data: any) => {
|
||||
setIsUpdateModal(true)
|
||||
}
|
||||
}))
|
||||
const [isUpdateModal, setIsUpdateModal] = useState(false);
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
title="更新"
|
||||
open={isUpdateModal}
|
||||
footer={null}
|
||||
onCancel={() => setIsUpdateModal(false)}
|
||||
centered
|
||||
width={'400px'}
|
||||
>
|
||||
<div className={styles.isUpdateModal}>
|
||||
import {Flex, Modal, Progress} from 'antd';
|
||||
import {forwardRef, useImperativeHandle, useState} from "react";
|
||||
|
||||
</div>
|
||||
</Modal>
|
||||
</>
|
||||
)
|
||||
const UpdateModal = forwardRef((props: any, ref: any) => {
|
||||
useImperativeHandle(ref, () => ({
|
||||
changeModal: (data: any) => {
|
||||
let dataJson = JSON.parse(data)
|
||||
console.log(dataJson)
|
||||
setIsUpdateModal(true)
|
||||
getContent()
|
||||
if (dataJson.type === '0') { // 打开弹窗
|
||||
setIsUpdateModal(true)
|
||||
} else if (dataJson.type === '1') { // 下载中 返回进度值
|
||||
console.log('下载中', dataJson.value.toFixed(2))
|
||||
setProgress(dataJson.value.toFixed(2))
|
||||
}
|
||||
}
|
||||
}))
|
||||
const [isUpdateModal, setIsUpdateModal] = useState(false);
|
||||
const [progress, setProgress] = useState(0); // 下载进度值
|
||||
const [updateContent, setUpdateContent] = useState('') // 版本更新内容
|
||||
|
||||
function getContent() {
|
||||
fetch('http://test.bossmei.top/electron/update.txt') // 配置服务器地址
|
||||
.then(async response => {
|
||||
if (response.status === 200) {
|
||||
return setUpdateContent(await response.text())
|
||||
}
|
||||
throw new Error('Network response was not ok.');
|
||||
})
|
||||
.then(textContent => {
|
||||
console.log(textContent);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('There has been a problem with your fetch operation:', error);
|
||||
});
|
||||
}
|
||||
|
||||
function closeModal() {
|
||||
window.electron.onDownload('0') // 取消下载
|
||||
setIsUpdateModal(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
title=""
|
||||
open={isUpdateModal}
|
||||
footer={null}
|
||||
onCancel={() => closeModal()}
|
||||
centered
|
||||
width={'338px'}
|
||||
>
|
||||
<div className={styles.isUpdateModal}>
|
||||
<div className={styles.remarks}>
|
||||
{updateContent}
|
||||
</div>
|
||||
{
|
||||
!progress ?
|
||||
<div className={styles.buttons}>
|
||||
<div className={styles.button1}
|
||||
onClick={() => window.electron.onDownload('1')}>立即更新
|
||||
</div>
|
||||
<div className={styles.button2} onClick={() => setIsUpdateModal(false)}>暂不更新</div>
|
||||
</div> :
|
||||
<div className={styles.progress}>
|
||||
下载进度:{progress}%
|
||||
<Flex gap="small" vertical>
|
||||
<Progress percent={progress} showInfo={false}/>
|
||||
</Flex>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</Modal>
|
||||
</>
|
||||
)
|
||||
})
|
||||
|
||||
export default UpdateModal
|
||||
export default UpdateModal
|
||||
|
|
|
|||
|
|
@ -1,15 +1,17 @@
|
|||
// electron-env.d.ts
|
||||
export interface IElectronAPI {
|
||||
setMainWindowSize: (config: any) => void;
|
||||
setViewStatus: (status: 'quit' | 'maximize' | 'minimize' | 'unmaximize') => void;
|
||||
getIsMaximized: () => Promise<boolean>;
|
||||
setWriteText: (text: string) => void;
|
||||
onQuit: (callBack:Function) => void;
|
||||
onUpdate: (callBack:Function) => void;
|
||||
joinNotification: (data: { name: string, body: string }) => void
|
||||
setMainWindowSize: (config: any) => void;
|
||||
setViewStatus: (status: 'quit' | 'maximize' | 'minimize' | 'unmaximize') => void;
|
||||
getIsMaximized: () => Promise<boolean>;
|
||||
setWriteText: (text: string) => void;
|
||||
onQuit: (callBack: Function) => void;
|
||||
onUpdate: (callBack: Function) => void;
|
||||
joinNotification: (data: { name: string, body: string }) => void;
|
||||
onDownload: (data: string) => void
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
electron: IElectronAPI;
|
||||
}
|
||||
}
|
||||
interface Window {
|
||||
electron: IElectronAPI;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue