From 6eccfbd7b981f4910483cc779f6b8a3be7f180f4 Mon Sep 17 00:00:00 2001 From: Thomas Beverley Date: Wed, 3 Feb 2016 20:56:31 +0000 Subject: [PATCH] Updates to the downloading #63 --- package.json | 4 +- .../stores/settings/settingsActions.js | 18 ++++++ src/mailbox/stores/settings/settingsStore.js | 11 ++++ src/mailbox/ui/Mailbox/GoogleMailboxWindow.js | 35 +++++++---- src/mailbox/ui/Settings/GeneralSettings.js | 3 +- src/main/MailboxesDownloadManager.js | 62 +++++++++++++++++++ src/main/WMailWindow.js | 8 +++ src/main/main.js | 13 +++- 8 files changed, 138 insertions(+), 16 deletions(-) create mode 100644 src/main/MailboxesDownloadManager.js diff --git a/package.json b/package.json index c0d5b65e..ff79cd61 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "electron-google-oauth": "^1.3.1", "electron-localshortcut": "^0.6.0", "flexboxgrid": "^6.3.0", + "fs-extra": "^0.26.5", "googleapis": "^2.1.7", "https-proxy-agent": "^1.0.0", "material-ui": "^0.14.2", @@ -60,6 +61,7 @@ "react-dom": "^0.14.6", "react-tap-event-plugin": "^0.2.1", "react-timer-mixin": "^0.13.3", - "typo-js": "^1.0.1" + "typo-js": "^1.0.1", + "uuid": "^2.0.1" } } diff --git a/src/mailbox/stores/settings/settingsActions.js b/src/mailbox/stores/settings/settingsActions.js index ae7b3c82..97e303a4 100644 --- a/src/mailbox/stores/settings/settingsActions.js +++ b/src/mailbox/stores/settings/settingsActions.js @@ -90,6 +90,24 @@ class SettingsActions { return this.mergeUpdates({ spellcheckerEnabled: enabled }) } + /* **************************************************************************/ + // Downloads + /* **************************************************************************/ + + /** + * @param ask: true to always ask, false otherwise + */ + setAlwaysAskDownloadLocation (ask) { + return this.mergeUpdates({ alwaysAskDownloadLocation: ask }) + } + + /** + * @param path: the path to download files to automatically + */ + setDefaultDownloadLocation (path) { + return this.mergeUpdates({ defaultDownloadLocation: path }) + } + } module.exports = alt.createActions(SettingsActions) diff --git a/src/mailbox/stores/settings/settingsStore.js b/src/mailbox/stores/settings/settingsStore.js index c8a096b8..b182e961 100644 --- a/src/mailbox/stores/settings/settingsStore.js +++ b/src/mailbox/stores/settings/settingsStore.js @@ -84,6 +84,17 @@ class SettingsStore { return this.__valuediff__('spellcheckerEnabled', true) } + /* ****************************************/ + // Downloads + /* ****************************************/ + + this.alwaysAskDownloadLocation = () => { + return this.__value__('alwaysAskDownloadLocation', true) + } + this.defaultDownloadLocation = () => { + return this.__value__('defaultDownloadLocation', undefined) + } + /* ****************************************/ // Higher order /* ****************************************/ diff --git a/src/mailbox/ui/Mailbox/GoogleMailboxWindow.js b/src/mailbox/ui/Mailbox/GoogleMailboxWindow.js index b12cdab3..2011f04b 100644 --- a/src/mailbox/ui/Mailbox/GoogleMailboxWindow.js +++ b/src/mailbox/ui/Mailbox/GoogleMailboxWindow.js @@ -14,6 +14,7 @@ const session = remote.require('session') const ipc = window.nativeRequire('electron').ipcRenderer const mailboxDispatch = require('../Dispatch/mailboxDispatch') const TimerMixin = require('react-timer-mixin') +const uuid = require('uuid') /* eslint-disable react/prop-types */ @@ -141,6 +142,26 @@ module.exports = React.createClass({ } }, + /* **************************************************************************/ + // Webview events + /* **************************************************************************/ + + /** + * Handles the download + * @param evt: the event that fired + * @param item: the item that's downloading + */ + handleDownload: function (evt, item) { + const totalBytes = item.getTotalBytes() + const id = uuid.v4() + item.on('updated', () => { + ipc.send('download-progress', { id: id, received: item.getReceivedBytes(), total: totalBytes }) + }) + item.on('done', (e, state) => { + ipc.send('download-complete', { id: id }) + }) + }, + /* **************************************************************************/ // Rendering /* **************************************************************************/ @@ -153,19 +174,9 @@ module.exports = React.createClass({ renderWebviewDOMNode: function () { // Setup the session that will be used const partition = 'persist:' + this.state.mailbox.id - var ses = session.fromPartition(partition) + const ses = session.fromPartition(partition) ses.setDownloadPath(app.getPath('downloads')) - /* ses.on('will-download', (evt, item) => { - const totalBytes = item.getTotalBytes() - item.setSavePath(path.join(app.getPath('downloads'), item.getFilename()) - - item.on('updated', () => { - win.setProgressBar(item.getReceivedBytes() / totalBytes); - }) - item.on('done', (e, state) => { - win.setProgressBar(-1) - }) - })*/ + ses.on('will-download', this.handleDownload) // Build the dom const webview = document.createElement('webview') diff --git a/src/mailbox/ui/Settings/GeneralSettings.js b/src/mailbox/ui/Settings/GeneralSettings.js index 828987fc..2617c801 100644 --- a/src/mailbox/ui/Settings/GeneralSettings.js +++ b/src/mailbox/ui/Settings/GeneralSettings.js @@ -97,12 +97,11 @@ module.exports = React.createClass({ label='Show tray icon' onToggle={this.handleToggleShowTrayIcon} /> - + Spell-checker (Experimental, requires restart))} onToggle={this.handleToggleSpellchecker} /> - ) diff --git a/src/main/MailboxesDownloadManager.js b/src/main/MailboxesDownloadManager.js new file mode 100644 index 00000000..03bb8ea0 --- /dev/null +++ b/src/main/MailboxesDownloadManager.js @@ -0,0 +1,62 @@ +'use strict' + +class MailboxesDownloadManager { + + /* ****************************************************************************/ + // Lifecycle + /* ****************************************************************************/ + + constructor (mailboxWindow) { + this.inProgress = { } + this.mailboxWindow = mailboxWindow + } + + /* ****************************************************************************/ + // App + /* ****************************************************************************/ + + /** + * Updates the progress bar in the dock + */ + updateProgressBar () { + const all = Object.keys(this.inProgress).reduce((acc, id) => { + acc.received += this.inProgress[id].received + acc.total += this.inProgress[id].total + return acc + }, { received: 0, total: 0 }) + + if (all.received === 0 && all.total === 0) { + this.mailboxWindow.setProgressBar(-1) + } else { + this.mailboxWindow.setProgressBar(all.received / all.total) + } + } + + /* ****************************************************************************/ + // Updates + /* ****************************************************************************/ + + /** + * Updates the progress on a download + * @param id: the download id + * @param received: the bytes received + * @param total: the total bytes to download + */ + updateProgress (id, received, total) { + this.inProgress[id] = this.inProgress[id] || {} + this.inProgress[id].received = received + this.inProgress[id].total = total + this.updateProgressBar() + } + + /** + * Indicates that a download has finished + * @param id: the download id + */ + downloadFinished (id) { + delete this.inProgress[id] + this.updateProgressBar() + } +} + +module.exports = MailboxesDownloadManager diff --git a/src/main/WMailWindow.js b/src/main/WMailWindow.js index 37741e7f..92709553 100644 --- a/src/main/WMailWindow.js +++ b/src/main/WMailWindow.js @@ -176,6 +176,14 @@ class WMailWindow extends EventEmitter { isFocused () { return this.window.isFocused() } + + /** + * Sets the download progress + * @param v: the download progress to set + */ + setProgressBar (v) { + this.window.setProgressBar(v) + } } module.exports = WMailWindow diff --git a/src/main/main.js b/src/main/main.js index 301e0aea..c3e4fe09 100644 --- a/src/main/main.js +++ b/src/main/main.js @@ -15,6 +15,7 @@ const WindowManager = require('./WindowManager') const constants = require('../shared/constants') const exec = require('child_process').exec const AppSettings = require('./AppSettings') +const MailboxesDownloadManager = require('./MailboxesDownloadManager') /* ****************************************************************************/ // Global objects @@ -24,7 +25,9 @@ const appDirectory = new AppDirectory(pkg.name) const localStorage = new LocalStorage(appDirectory.userData()) const appSettings = new AppSettings(localStorage) const analytics = new AppAnalytics(localStorage, appSettings) -const windowManager = new WindowManager(new MailboxesWindow(analytics, localStorage, appSettings)) +const mailboxesWindow = new MailboxesWindow(analytics, localStorage, appSettings) +const mailboxesDownloadManager = new MailboxesDownloadManager(mailboxesWindow) +const windowManager = new WindowManager(mailboxesWindow) const appMenuSelectors = { fullQuit: () => { windowManager.quit() }, @@ -80,6 +83,14 @@ ipcMain.on('settings-update', (evt, settings) => { appSettings.update(settings) }) +ipcMain.on('download-progress', (evt, data) => { + mailboxesDownloadManager.updateProgress(data.id, data.received, data.total) +}) + +ipcMain.on('download-complete', (evt, data) => { + mailboxesDownloadManager.downloadFinished(data.id) +}) + /* ****************************************************************************/ // App Events /* ****************************************************************************/