diff --git a/latest.yml b/latest.yml new file mode 100644 index 0000000..16a19d8 --- /dev/null +++ b/latest.yml @@ -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' diff --git a/main.js b/main.js index 66d6199..41c10ae 100644 --- a/main.js +++ b/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(); +} diff --git a/package-lock.json b/package-lock.json index 746ad92..6ce43e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index e16f68a..a351bd9 100644 --- a/package.json +++ b/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" ], diff --git a/preload.js b/preload.js index f47e665..39122e2 100644 --- a/preload.js +++ b/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) - }, -} \ No newline at end of file + // 设置窗口大小 + 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) + }, +} diff --git a/src/assets/updateBg.png b/src/assets/updateBg.png new file mode 100644 index 0000000..c54625b Binary files /dev/null and b/src/assets/updateBg.png differ diff --git a/src/components/UpdateModal/index.module.scss b/src/components/UpdateModal/index.module.scss index 1fdb8ee..13822e8 100644 --- a/src/components/UpdateModal/index.module.scss +++ b/src/components/UpdateModal/index.module.scss @@ -1 +1,35 @@ -.isUpdateModal {} \ No newline at end of file +.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; + } + } +} + diff --git a/src/components/UpdateModal/index.tsx b/src/components/UpdateModal/index.tsx index 2f8c1b6..a49d571 100644 --- a/src/components/UpdateModal/index.tsx +++ b/src/components/UpdateModal/index.tsx @@ -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 ( - <> - setIsUpdateModal(false)} - centered - width={'400px'} - > -
+import {Flex, Modal, Progress} from 'antd'; +import {forwardRef, useImperativeHandle, useState} from "react"; -
-
- - ) +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 ( + <> + closeModal()} + centered + width={'338px'} + > +
+
+ {updateContent} +
+ { + !progress ? +
+
window.electron.onDownload('1')}>立即更新 +
+
setIsUpdateModal(false)}>暂不更新
+
: +
+ 下载进度:{progress}% + + + +
+ } +
+
+ + ) }) -export default UpdateModal \ No newline at end of file +export default UpdateModal diff --git a/src/render.d.ts b/src/render.d.ts index a732862..993b57c 100644 --- a/src/render.d.ts +++ b/src/render.d.ts @@ -1,15 +1,17 @@ // electron-env.d.ts export interface IElectronAPI { - setMainWindowSize: (config: any) => void; - setViewStatus: (status: 'quit' | 'maximize' | 'minimize' | 'unmaximize') => void; - getIsMaximized: () => Promise; - 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; + 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; - } -} \ No newline at end of file + interface Window { + electron: IElectronAPI; + } +}