Skip to content

Commit

Permalink
feat(update):add download process bar
Browse files Browse the repository at this point in the history
  • Loading branch information
ni00 committed Jun 7, 2023
1 parent 0cb478a commit 9368b45
Show file tree
Hide file tree
Showing 12 changed files with 366 additions and 125 deletions.
26 changes: 19 additions & 7 deletions src/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ 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'
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

Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -154,10 +170,6 @@ async function createWindow() {
beforeAppQuit()
})
handleIpcMessages()
if (autoCheckUpdate) {
updateChecker()
}
// updateWindow
electronStore.get('isShow') && createUpdateWindow()
}

Expand Down
2 changes: 1 addition & 1 deletion src/lang/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
65 changes: 65 additions & 0 deletions src/lang/update.ts
Original file line number Diff line number Diff line change
@@ -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',
},
}
3 changes: 1 addition & 2 deletions src/main/getMenuTemplate.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { app, shell, BrowserWindow } from 'electron'
import updateChecker from './updateChecker'
import translations from '../lang/menu'

const isMac = process.platform === 'darwin'
Expand Down Expand Up @@ -35,7 +34,7 @@ const getMenuTemplate = (win: BrowserWindow, lang?: Language): $TSFixed => {
{
label: labels.checkForUpdate,
click: () => {
updateChecker(false)
win.webContents.send('clickUpdate')
},
},
{ type: 'separator' },
Expand Down
123 changes: 13 additions & 110 deletions src/main/updateChecker.ts
Original file line number Diff line number Diff line change
@@ -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()

Expand All @@ -28,12 +28,13 @@ log4js.configure({
})

const logger = log4js.getLogger('file')
interface versionDetail {

export interface versionDetail {
version: string
detail: string
}

const getCurrentLang = async (): Promise<string> => {
export const getCurrentLang = async (): Promise<string> => {
let language: string = 'en'
const { settingService } = useServices()
await settingService.set()
Expand All @@ -44,12 +45,6 @@ const getCurrentLang = async (): Promise<string> => {
return language === 'zh' ? 'zh' : 'en'
}

const closeAutoCheck = async (): Promise<void> => {
const { settingService } = useServices()
await settingService.set()
await settingService.update({ autoCheck: false })
}

const getUpdateDtail = async (current: string): Promise<versionDetail | null> => {
const tagsUrl = 'https://api.github.com/repos/emqx/MQTTX/tags'
const tagsRes = await axios.get(tagsUrl)
Expand All @@ -58,122 +53,30 @@ const getUpdateDtail = async (current: string): Promise<versionDetail | null> =>
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) {
const versionRes = await axios.get(
`https://community-sites.emqx.com/api/v1/changelogs?product=MQTTX&version=${latestVersion}`,
)
if (latestVersion && versionRes.status === 200) {
return {
version: versionRes.data.name,
detail: versionRes.data.body,
version: latestVersion,
detail: versionRes.data.data.changelog,
}
}
}
}
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<void | boolean> => {
export const updateChecker = async (isAuto: boolean = true): Promise<void | versionDetail | boolean> => {
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.',
})
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
54 changes: 54 additions & 0 deletions src/main/updateDownloader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
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)
})
ipcMain.on('toQuitAndInstall', () => {
electronStore.set('isShow', true)
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)
}
2 changes: 1 addition & 1 deletion src/types/locale.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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' {
Expand Down
Loading

0 comments on commit 9368b45

Please sign in to comment.