From 0cb478abb0a17fc349c29c6cbdcdbc80fd0bfb92 Mon Sep 17 00:00:00 2001 From: ni00 Date: Mon, 5 Jun 2023 17:14:11 +0800 Subject: [PATCH] refactor(updateChecker):Fix bugs and refactor code --- src/main/updateChecker.ts | 202 +++++++++++++++++++++++++------------- 1 file changed, 136 insertions(+), 66 deletions(-) diff --git a/src/main/updateChecker.ts b/src/main/updateChecker.ts index f64b2efe92..e21bc60d2d 100644 --- a/src/main/updateChecker.ts +++ b/src/main/updateChecker.ts @@ -7,84 +7,159 @@ const { autoUpdater } = require('electron-updater') const Store = require('electron-store') const electronStore = new Store() -const release = 'https://api.github.com/repos/emqx/MQTTX/releases/latest' -let language: string = 'en' +const log4js = require('log4js') -const isUpdate = (latest: string, current: string): boolean => { - const latestVersion: number[] = latest.split('.').map((item) => parseInt(item, 10)) - const currentVersion: number[] = current.split('.').map((item) => parseInt(item, 10)) - let update: boolean = false +log4js.configure({ + appenders: { + console: { + type: 'console', + }, + file: { + type: 'file', + filename: './logs/app.log', // 指定日志文件路径 + }, + }, + categories: { + default: { + appenders: ['console', 'file'], + level: 'debug', + }, + }, +}) - for (let i: number = 0; i < 3; i++) { - if (currentVersion[i] < latestVersion[i]) { - update = true - } +const logger = log4js.getLogger('file') +interface versionDetail { + version: string + detail: string +} + +const getCurrentLang = async (): Promise => { + let language: string = 'en' + const { settingService } = useServices() + await settingService.set() + const setting = await settingService.get() + if (setting) { + language = setting.currentLang } + return language === 'zh' ? 'zh' : 'en' +} - return update +const closeAutoCheck = async (): Promise => { + const { settingService } = useServices() + await settingService.set() + await settingService.update({ autoCheck: false }) +} + +const getUpdateDtail = async (current: string): Promise => { + const tagsUrl = 'https://api.github.com/repos/emqx/MQTTX/tags' + const tagsRes = await axios.get(tagsUrl) + if (tagsRes.status === 200) { + const tagsList: string[] = tagsRes.data.map((item: any) => item.name) + const latestTagsList: string[] = tagsList.slice(0, tagsList.indexOf(current)) + while (latestTagsList.length > 0) { + const latestVersion = latestTagsList.shift() + const versionRes = await axios.get(`https://api.github.com/repos/emqx/MQTTX/releases/tags/${latestVersion}`) + if (versionRes.status === 200 && !versionRes.data.prerelease) { + return { + version: versionRes.data.name, + detail: versionRes.data.body, + } + } + } + } + return null } -const autoDownload = (latest: string, language: string): void => { - const urlLang = language === 'zh' ? 'zh' : 'en' - const downloadUrl = `https://www.emqx.com/${urlLang}/downloads/MQTTX/${latest}` +const autoDownload = (currentVersion: string, updateDatail: versionDetail, language: string): void => { + let msgClick: boolean = false + let updateAvailable: boolean = true + let updateDownloaded: boolean = true + const downloadUrl = `https://www.emqx.com/${language}/downloads/MQTTX/${updateDatail.version}` autoUpdater.setFeedURL(downloadUrl) + autoUpdater.autoDownload = false autoUpdater.checkForUpdatesAndNotify() - autoUpdater.on('checking-for-update', () => {}) - autoUpdater.on('update-available', () => {}) - autoUpdater.on('update-not-available', () => {}) - autoUpdater.on('error', () => {}) - autoUpdater.on('download-progress', () => {}) + autoUpdater.on('update-available', () => { + // TODO: Replace dialog.showMessageBox with BrowserWindow and display the update logs (versionDetail.detail). + if (updateAvailable) { + updateAvailable = false + dialog + .showMessageBox({ + type: 'info', + title: `Update Infomation ${currentVersion}->${updateDatail.version}`, + message: `The software needs to be updated. Do you want to update it immediately?\n${ + updateDatail.detail.slice(0, 300) + '...' + }`, + buttons: ['Remind me next time', 'Update now', 'Never Update', 'Ignore this Verion Update'], + }) + .then((res) => { + if (res.response === 0) { + autoUpdater.autoDownload = false + } else if (res.response === 1) { + msgClick = true + autoUpdater.autoDownload = true + autoUpdater.downloadUpdate() + } else if (res.response === 2) { + // FIXME: The settings page did not change in time.(will change on the next launch) + closeAutoCheck() + } else { + electronStore.set('isIgnore', updateDatail.version) + } + }) + } + }) + autoUpdater.on('error', (e: any) => { + logger.debug(e) + }) + autoUpdater.on('download-progress', (progressObj: any) => { + // TODO:Add a progress bar for updates. + //ipcRenderer.send('progress', progressObj.percent / 100) + }) autoUpdater.on('update-downloaded', () => { - electronStore.set('isShow', true) - dialog - .showMessageBox({ - type: 'info', - title: 'New Version', - buttons: ['Install', 'No'], - message: `Update available: ${latest}`, - }) - .then((res) => { - if (res.response === 0) { - // if selected yes - autoUpdater.quitAndInstall() - } else { - dialog.showMessageBox({ - type: 'info', - message: 'Automatic update on do not shut down the computer immediately', - }) - } - }) + if (msgClick && updateDownloaded) { + updateDownloaded = false + dialog + .showMessageBox({ + type: 'info', + title: `New Version`, + buttons: ['Quit and Install Now', 'No'], + message: `Update available: ${updateDatail.version}`, + }) + .then((res) => { + if (res.response === 0) { + electronStore.set('isShow', true) + autoUpdater.quitAndInstall() + } else { + dialog.showMessageBox({ + type: 'info', + message: 'MQTTX will be updated automatically after the next launch.', + }) + } + }) + } }) } const updateChecker = async (isAuto: boolean = true): Promise => { - const response = await axios.get(release) - const { settingService } = useServices() - await settingService.set() - const setting = await settingService.get() - if (setting) { - language = setting.currentLang - } - if (response.status === 200) { - const latest: string = response.data.name - const isPrerelease: boolean = response.data.prerelease - if (latest && isUpdate(latest.slice(1, 6), version) && !isPrerelease) { - autoDownload(latest, language) - } else { - if (!isAuto) { - dialog.showMessageBox({ - type: 'info', - title: '', - buttons: ['OK'], - message: 'There are currently no updates available.', - }) - } + const currentVersion = `v${version}` + const updateDatail: versionDetail | null = await getUpdateDtail(currentVersion) + const language: string = await getCurrentLang() + if (updateDatail) { + if (isAuto && electronStore.get('isIgnore') === updateDatail.version) { + return false } + autoDownload(currentVersion, updateDatail, language) + } else if (!isAuto) { + dialog.showMessageBox({ + type: 'info', + title: '', + buttons: ['OK'], + message: 'There are currently no updates available.', + }) } else { return false } } -//what's new window + export async function createUpdateWindow() { const updateWindow = new BrowserWindow({ width: 600, @@ -95,12 +170,7 @@ export async function createUpdateWindow() { enableRemoteModule: true, }, }) - const { settingService } = useServices() - await settingService.set() - const setting = await settingService.get() - if (setting) { - language = setting.currentLang - } + const language: string = await getCurrentLang() let link: string = 'https://mqttx.app' link = language === 'zh' ? `${link}/zh` : link updateWindow.loadURL(`${link}/changelogs/v${version}`)