const { dialog } = require('electron') const { Logger } = require('lib/logger.js'); const { _ } = require('lib/locale.js'); const fetch = require('node-fetch'); const packageInfo = require('./packageInfo.js'); const compareVersions = require('compare-versions'); let autoUpdateLogger_ = new Logger(); let checkInBackground_ = false; let isCheckingForUpdate_ = false; let parentWindow_ = null; function showErrorMessageBox(message) { return dialog.showMessageBox(parentWindow_, { type: 'error', message: message, }); } function onCheckStarted() { autoUpdateLogger_.info('checkForUpdates: Starting...'); isCheckingForUpdate_ = true; } function onCheckEnded() { autoUpdateLogger_.info('checkForUpdates: Done.'); isCheckingForUpdate_ = false; } async function fetchLatestRelease() { const response = await fetch('https://api.github.com/repos/laurent22/joplin/releases/latest'); if (!response.ok) { const responseText = await response.text(); throw new Error('Cannot get latest release info: ' + responseText.substr(0,500)); } const json = await response.json(); const version = json.tag_name.substr(1); let downloadUrl = null; const platform = process.platform; for (let i = 0; i < json.assets.length; i++) { const asset = json.assets[i]; let found = false; if (platform === 'win32' && asset.name.indexOf('.exe') >= 0 && asset.name.indexOf('Setup') >= 0) { found = true; } else if (platform === 'darwin' && asset.name.indexOf('.dmg') >= 0) { found = true; } else if (platform === 'linux' && asset.name.indexOf('.AppImage') >= 0) { found = true; } if (found) { downloadUrl = asset.browser_download_url; break; } } if (!downloadUrl) throw new Error('Cannot find download Url: ' + JSON.stringify(json).substr(0,500)); return { version: version, downloadUrl: downloadUrl, notes: json.body, }; } function checkForUpdates(inBackground, window, logFilePath) { if (isCheckingForUpdate_) { autoUpdateLogger_.info('checkForUpdates: Skipping check because it is already running'); return; } parentWindow_ = window; onCheckStarted(); if (logFilePath && !autoUpdateLogger_.targets().length) { autoUpdateLogger_ = new Logger(); autoUpdateLogger_.addTarget('file', { path: logFilePath }); autoUpdateLogger_.setLevel(Logger.LEVEL_DEBUG); autoUpdateLogger_.info('checkForUpdates: Initializing...'); } checkInBackground_ = inBackground; fetchLatestRelease().then(release => { if (compareVersions(release.version, packageInfo.version) <= 0) { if (!checkInBackground_) dialog.showMessageBox({ message: _('Current version is up-to-date.') }) } else { const releaseNotes = release.notes.trim() ? "\n\n" + release.notes.trim() : ''; const buttonIndex = dialog.showMessageBox(parentWindow_, { type: 'info', message: _('An update is available, do you want to download it now?' + releaseNotes), buttons: [_('Yes'), _('No')] }); if (buttonIndex === 0) require('electron').shell.openExternal(release.downloadUrl); } }).catch(error => { autoUpdateLogger_.error(error); if (!checkInBackground_) showErrorMessageBox(error.message); }).then(() => { onCheckEnded(); }); } module.exports.checkForUpdates = checkForUpdates