diff --git a/src/background.ts b/src/background.ts index 65a14b26cc..0f26b0abe2 100644 --- a/src/background.ts +++ b/src/background.ts @@ -4,7 +4,8 @@ import { app, protocol, BrowserWindow, ipcMain, shell, Menu } from 'electron' import { createProtocol } from 'vue-cli-plugin-electron-builder/lib' import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer' import { quitAndRenameLogger } from './utils/logger' -import updateChecker, { createUpdateWindow } from './main/updateChecker' +import { createUpdateWindow, autoDownload } from './main/updateDownloader' +import { getCurrentLang } from './main/updateChecker' import getMenuTemplate from './main/getMenuTemplate' import saveFile from './main/saveFile' import saveExcel from './main/saveExcel' @@ -12,6 +13,7 @@ import newWindow from './main/newWindow' import { onSystemThemeChanged } from './main/systemTheme' import useConnection, { initOptionModel } from '@/database/useConnection' import useServices from '@/database/useServices' +import { dialog } from 'electron' declare const __static: string @@ -49,8 +51,8 @@ function handleIpcMessages() { Menu.setApplicationMenu(menu) } }) - ipcMain.on('checkUpdate', () => { - updateChecker(false) + ipcMain.on('clickUpdate', (event: Electron.IpcMainEvent) => { + event.sender.send('clickUpdate') }) ipcMain.on('exportData', (event: Electron.IpcMainEvent, ...args: any[]) => { const [filename, content, type] = args @@ -73,6 +75,20 @@ function handleIpcMessages() { event.sender.send('getWindowSize', win.getBounds()) } }) + ipcMain.on('startDownloadProgress', (event, updateDetail) => { + getCurrentLang().then((lang) => { + electronStore.set('isShow', false) + autoDownload(event, updateDetail, lang) + }) + }) + ipcMain.on('showMsg', (event) => { + dialog.showMessageBox({ + type: 'info', + title: '', + buttons: ['OK'], + message: 'There are currently no updates available.', + }) + }) } // handle event when APP quit @@ -154,10 +170,6 @@ async function createWindow() { beforeAppQuit() }) handleIpcMessages() - if (autoCheckUpdate) { - updateChecker() - } - // updateWindow electronStore.get('isShow') && createUpdateWindow() } diff --git a/src/lang/index.ts b/src/lang/index.ts index 60199128bf..59c8362b92 100644 --- a/src/lang/index.ts +++ b/src/lang/index.ts @@ -9,7 +9,7 @@ import huLocale from 'element-ui/lib/locale/lang/hu' import { formati18n } from '@/utils/i18n' const supportLang: SupportLangModel = ['zh', 'en', 'ja', 'tr', 'hu'] -const i18nModules: i18nLocaleModel = ['connections', 'settings', 'common', 'about', 'script', 'log', 'help'] +const i18nModules: i18nLocaleModel = ['connections', 'settings', 'common', 'about', 'script', 'log', 'help', 'update'] const { en, zh, ja, tr, hu }: VueI18n.LocaleMessages = formati18n(i18nModules, supportLang) diff --git a/src/lang/update.ts b/src/lang/update.ts new file mode 100644 index 0000000000..ce79090e88 --- /dev/null +++ b/src/lang/update.ts @@ -0,0 +1,65 @@ +export default { + updateTitle: { + zh: '新版本更新', + en: 'New Version Update', + ja: '新しいバージョンの更新', + tr: 'Yeni Sürüm Güncellemesi', + hu: 'Új verzió frissítés', + }, + ignoreVersion: { + zh: '忽略此版本', + en: 'Ignore this version', + ja: 'このバージョンを無視する', + tr: 'Bu sürümü yoksay', + hu: 'Figyelmen kívül hagyás', + }, + nextRemind: { + zh: '以后提醒', + en: 'Remind me later', + ja: '後でリマインドする', + tr: 'Daha sonra hatırlat', + hu: 'Később emlékeztessen', + }, + update: { + zh: '更新', + en: 'Update', + ja: '更新', + tr: 'Güncelle', + hu: 'Frissítés', + }, + downloadProgress: { + zh: '下载进度', + en: 'Download Progress', + ja: 'ダウンロード進行状況', + tr: 'İndirme İlerlemesi', + hu: 'Letöltési Előrehaladás', + }, + downloading: { + zh: '正在下载更新...', + en: 'Downloading update...', + ja: '更新をダウンロード中...', + tr: 'Güncelleme indiriliyor...', + hu: 'Frissítés letöltése...', + }, + downloaded: { + zh: '下载完毕,点击安装并重启', + en: 'Download completed. Click to install and restart', + ja: 'ダウンロードが完了しました。クリックしてインストールして再起動してください', + tr: 'İndirme tamamlandı. Kurmak ve yeniden başlatmak için tıklayın', + hu: 'Letöltés kész. Kattintson a telepítéshez és az újraindításhoz', + }, + cancel: { + zh: '取消更新', + en: 'Cancel update', + ja: '更新をキャンセル', + tr: 'Güncellemeyi iptal et', + hu: 'Frissítés megszakítása', + }, + install: { + zh: '安装并重启', + en: 'Install and Restart', + ja: 'インストールして再起動', + tr: 'Kur ve Yeniden Başlat', + hu: 'Telepítés és újraindítás', + }, +} diff --git a/src/main/getMenuTemplate.ts b/src/main/getMenuTemplate.ts index 0855243ddb..af8d334690 100644 --- a/src/main/getMenuTemplate.ts +++ b/src/main/getMenuTemplate.ts @@ -1,5 +1,4 @@ import { app, shell, BrowserWindow } from 'electron' -import updateChecker from './updateChecker' import translations from '../lang/menu' const isMac = process.platform === 'darwin' @@ -35,7 +34,7 @@ const getMenuTemplate = (win: BrowserWindow, lang?: Language): $TSFixed => { { label: labels.checkForUpdate, click: () => { - updateChecker(false) + win.webContents.send('clickUpdate') }, }, { type: 'separator' }, diff --git a/src/main/updateChecker.ts b/src/main/updateChecker.ts index e21bc60d2d..8eb989cd22 100644 --- a/src/main/updateChecker.ts +++ b/src/main/updateChecker.ts @@ -1,9 +1,9 @@ -import { dialog, BrowserWindow } from 'electron' +import { BrowserWindow } from 'electron' import axios from 'axios' import version from '@/version' import useServices from '@/database/useServices' -const { autoUpdater } = require('electron-updater') +const { dialog } = require('electron') const Store = require('electron-store') const electronStore = new Store() @@ -28,12 +28,13 @@ log4js.configure({ }) const logger = log4js.getLogger('file') -interface versionDetail { + +export interface versionDetail { version: string detail: string } -const getCurrentLang = async (): Promise => { +export const getCurrentLang = async (): Promise => { let language: string = 'en' const { settingService } = useServices() await settingService.set() @@ -44,12 +45,6 @@ const getCurrentLang = async (): Promise => { return language === 'zh' ? 'zh' : 'en' } -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) @@ -70,76 +65,7 @@ const getUpdateDtail = async (current: string): Promise => return null } -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('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', () => { - 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 => { +export const updateChecker = async (isAuto: boolean = true): Promise => { const currentVersion = `v${version}` const updateDatail: versionDetail | null = await getUpdateDtail(currentVersion) const language: string = await getCurrentLang() @@ -147,33 +73,8 @@ const updateChecker = async (isAuto: boolean = true): Promise => 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.', - }) + return updateDatail } else { return false } } - -export async function createUpdateWindow() { - const updateWindow = new BrowserWindow({ - width: 600, - height: 500, - webPreferences: { - nodeIntegration: true, - contextIsolation: false, - enableRemoteModule: true, - }, - }) - const language: string = await getCurrentLang() - let link: string = 'https://mqttx.app' - link = language === 'zh' ? `${link}/zh` : link - updateWindow.loadURL(`${link}/changelogs/v${version}`) - electronStore.set('isShow', false) -} -export default updateChecker diff --git a/src/main/updateDownloader.ts b/src/main/updateDownloader.ts new file mode 100644 index 0000000000..a4abbc012a --- /dev/null +++ b/src/main/updateDownloader.ts @@ -0,0 +1,56 @@ +import { BrowserWindow, IpcMain, IpcMainEvent, ipcMain } from 'electron' +import version from '@/version' +import { getCurrentLang, versionDetail } from './updateChecker' +import { resolve } from 'path' +const { autoUpdater } = require('electron-updater') +const Store = require('electron-store') +const electronStore = new Store() + +export const autoDownload = (event: IpcMainEvent, updateDatail: versionDetail, language: string) => { + const downloadUrl = `https://www.emqx.com/${language}/downloads/MQTTX/${updateDatail.version}` + autoUpdater.setFeedURL(downloadUrl) + autoUpdater.autoDownload = false + autoUpdater.autoInstallOnAppQuit = false + autoUpdater.checkForUpdatesAndNotify() + autoUpdater.on('update-available', () => { + autoUpdater.downloadUpdate() + }) + autoUpdater.on('error', (e: any) => { + console.log(e) + }) + autoUpdater.on('download-progress', (progressObj: any) => { + event.sender.send('downloadProgressPercent', progressObj.percent) + }) + autoUpdater.on('update-downloaded', () => { + event.sender.send('downloadProgressPercent', 100) + }) + autoUpdater.on('before-quit-for-update', () => { + electronStore.set('isShow', true) + }) + ipcMain.on('toQuitAndInstall', () => { + autoUpdater.quitAndInstall() + }) + ipcMain.on('cancelDownload', () => { + autoUpdater.removeAllListeners() + autoUpdater.autoDownload = false + autoUpdater.autoInstallOnAppQuit = false + autoUpdater.autoCheckForUpdates = false + }) +} + +export async function createUpdateWindow() { + const updateWindow = new BrowserWindow({ + width: 600, + height: 500, + webPreferences: { + nodeIntegration: true, + contextIsolation: false, + enableRemoteModule: true, + }, + }) + const language: string = await getCurrentLang() + let link: string = 'https://mqttx.app' + link = language === 'zh' ? `${link}/zh` : link + updateWindow.loadURL(`${link}/changelogs/v${version}`) + electronStore.set('isShow', false) +} diff --git a/src/types/locale.d.ts b/src/types/locale.d.ts index 6f850d4555..7c5675ab67 100644 --- a/src/types/locale.d.ts +++ b/src/types/locale.d.ts @@ -6,7 +6,7 @@ declare module 'element-ui/lib/locale/lang/ja' {} declare module 'element-ui/lib/locale/lang/tr-TR' {} declare module 'element-ui/lib/locale/lang/hu' {} -type i18nLocaleModel = ['connections', 'settings', 'common', 'about', 'script', 'log', 'help'] +type i18nLocaleModel = ['connections', 'settings', 'common', 'about', 'script', 'log', 'help', 'update'] type SupportLangModel = ['zh', 'en', 'ja', 'tr', 'hu'] declare module '*.json' { diff --git a/src/utils/element.ts b/src/utils/element.ts index 6ee0c8b4ee..53b39f8328 100644 --- a/src/utils/element.ts +++ b/src/utils/element.ts @@ -51,7 +51,7 @@ import { Row, Col, // Upload, - // Progress, + Progress, Badge, Card, // Rate, @@ -124,7 +124,7 @@ export default (Vue: typeof _Vue) => { Vue.use(Row) Vue.use(Col) // Vue.use(Upload) - // Vue.use(Progress) + Vue.use(Progress) Vue.use(Badge) Vue.use(Card) // Vue.use(Rate) diff --git a/src/utils/i18n.ts b/src/utils/i18n.ts index 3adb25fc29..b684e40082 100644 --- a/src/utils/i18n.ts +++ b/src/utils/i18n.ts @@ -15,6 +15,7 @@ export const formati18n = (transItems: i18nLocaleModel, langs: SupportLangModel) script: {}, log: {}, help: {}, + update: {}, } }) transItems.forEach((item) => { diff --git a/src/views/Home.vue b/src/views/Home.vue index 12d3907e5b..047e20c4cb 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -3,6 +3,7 @@ + @@ -12,11 +13,13 @@ import { Getter, Action } from 'vuex-class' import { remote } from 'electron' import Ipc from '@/components/Ipc.vue' import Leftbar from '@/components/Leftbar.vue' +import Update from '@/views/update/index.vue' @Component({ components: { Ipc, Leftbar, + Update, }, }) export default class Home extends Vue { diff --git a/src/views/about/index.vue b/src/views/about/index.vue index 8716f179b0..aa953ffa27 100644 --- a/src/views/about/index.vue +++ b/src/views/about/index.vue @@ -9,7 +9,7 @@

{{ $t('common.version') }} v{{ version }}

- {{ $t('about.update') }} + {{ $t('about.update') }} {{ $t('about.releases') }} @@ -128,7 +128,7 @@ export default class About extends Vue { } private checkUpdate(): void { - ipcRenderer.send('checkUpdate') + ipcRenderer.send('clickUpdate') } private goToLink(url: string) { diff --git a/src/views/update/index.vue b/src/views/update/index.vue new file mode 100644 index 0000000000..653652e747 --- /dev/null +++ b/src/views/update/index.vue @@ -0,0 +1,172 @@ + + + + +