diff --git a/src/app/applyDownloadNotification.js b/src/app/applyDownloadNotification.js index 504d88ac..5b9cd477 100644 --- a/src/app/applyDownloadNotification.js +++ b/src/app/applyDownloadNotification.js @@ -26,14 +26,14 @@ export function applyDownloadNotification(browserWindow) { notification.on('click', () => { shell.showItemInFolder(pathToFile) }) - } else { + } else if (state === 'interrupted') { notification = new Notification({ title: 'Download Failed', body: `Something went wrong with the download of '${base}'.`, }) } - notification.show() + notification?.show() }) }) } diff --git a/src/app/externalLinkHandlers.js b/src/app/externalLinkHandlers.js index 00e60067..b81d71a2 100644 --- a/src/app/externalLinkHandlers.js +++ b/src/app/externalLinkHandlers.js @@ -34,7 +34,6 @@ function isExternalLink(url) { * @return {{action: 'deny'} | {action: 'allow', outlivesOpener?: boolean, overrideBrowserWindowOptions?: import('electron').BrowserWindowConstructorOptions}} */ function windowOpenExternalLinkHandler(details, browserWindowOptions = {}) { - // TODO: Should handle different types of details.disposition? I.e. save-to-disk? if (isExternalLink(details.url)) { shell.openExternal(details.url) return { action: 'deny' } diff --git a/src/main.js b/src/main.js index 50d4eb4f..4d5d3c70 100644 --- a/src/main.js +++ b/src/main.js @@ -275,6 +275,8 @@ app.whenReady().then(async () => { isInWindowRelaunch = false }) + ipcMain.on('app:downloadURL', (event, url) => mainWindow.webContents.downloadURL(url)) + // On OS X it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. app.on('activate', () => { diff --git a/src/preload.js b/src/preload.js index e6fdae37..5666e1f4 100644 --- a/src/preload.js +++ b/src/preload.js @@ -106,6 +106,11 @@ const TALK_DESKTOP = { * @return {Promise} */ setAppConfig: (key, value) => ipcRenderer.invoke('app:config:set', key, value), + /** + * Trigger download of a URL + * @param {string} url - URL to download + */ + downloadURL: (url) => ipcRenderer.send('app:downloadURL', url), /** * Send appData to main process on restore * diff --git a/src/shared/setupWebPage.js b/src/shared/setupWebPage.js index 6e341afd..b61359eb 100644 --- a/src/shared/setupWebPage.js +++ b/src/shared/setupWebPage.js @@ -199,6 +199,19 @@ function applyHeaderHeight() { document.documentElement.style.setProperty('--header-height', `${TITLE_BAR_HEIGHT}px`, 'important') } +/** + * Handle download links + */ +function applyDownloadLinkHandler() { + document.addEventListener('click', (event) => { + const link = event.target.closest('a') + if (link && link.hasAttribute('download')) { + event.preventDefault() + window.TALK_DESKTOP.downloadURL(link.href) + } + }) +} + /** * Make all required initial setup for the web page for authorized user: server-rendered data, globals and ect. */ @@ -214,4 +227,5 @@ export async function setupWebPage() { applyHeaderHeight() applyAxiosInterceptors() await applyL10n() + applyDownloadLinkHandler() }