From 1ec305162ef29c8925cf23c4de9f6e7d76448b2b Mon Sep 17 00:00:00 2001 From: DC Date: Fri, 12 Aug 2016 20:54:57 -0700 Subject: [PATCH] Check for missing download path Fixes #646 --- src/renderer/controllers/prefs-controller.js | 2 ++ src/renderer/main.js | 27 ++++++++++++++--- src/renderer/views/preferences.js | 4 +-- src/renderer/views/torrent-list.js | 32 ++++++++++++++++---- static/main.css | 7 +++++ 5 files changed, 59 insertions(+), 13 deletions(-) diff --git a/src/renderer/controllers/prefs-controller.js b/src/renderer/controllers/prefs-controller.js index d220c2b1..97171c8a 100644 --- a/src/renderer/controllers/prefs-controller.js +++ b/src/renderer/controllers/prefs-controller.js @@ -1,4 +1,5 @@ const State = require('../lib/state') +const {dispatch} = require('../lib/dispatcher') const ipcRenderer = require('electron').ipcRenderer // Controls the Preferences screen @@ -50,5 +51,6 @@ module.exports = class PrefsController { } state.saved.prefs = Object.assign(state.saved.prefs || {}, state.unsaved.prefs) State.save(state) + dispatch('checkDownloadPath') } } diff --git a/src/renderer/main.js b/src/renderer/main.js index 181a7e63..bfb1c4f0 100644 --- a/src/renderer/main.js +++ b/src/renderer/main.js @@ -7,6 +7,7 @@ const dragDrop = require('drag-drop') const electron = require('electron') const React = require('react') const ReactDOM = require('react-dom') +const fs = require('fs') const config = require('../config') const App = require('./views/app') @@ -74,6 +75,12 @@ function onState (err, _state) { } }) + // Calling update() updates the UI given the current state + // Do this at least once a second to give every file in every torrentSummary + // a progress bar and to keep the cursor in sync when playing a video + setInterval(update, 1000) + app = ReactDOM.render(, document.querySelector('#body')) + // Restart everything we were torrenting last time the app ran resumeTorrents() @@ -83,11 +90,8 @@ function onState (err, _state) { // Listen for messages from the main process setupIpc() - // Calling update() updates the UI given the current state - // Do this at least once a second to give every file in every torrentSummary - // a progress bar and to keep the cursor in sync when playing a video - setInterval(update, 1000) - app = ReactDOM.render(, document.querySelector('#body')) + // Warn if the download dir is gone, eg b/c an external drive is unplugged + checkDownloadPath() // OS integrations: // ...drag and drop files/text to start torrenting or seeding @@ -212,6 +216,7 @@ const dispatchHandlers = { // Preferences screen 'preferences': () => controllers.prefs.show(), 'updatePreferences': (key, value) => controllers.prefs.update(key, value), + 'checkDownloadPath': checkDownloadPath, // Update (check for new versions on Linux, where there's no auto updater) 'updateAvailable': (version) => controllers.update.updateAvailable(version), @@ -433,3 +438,15 @@ function onFullscreenChanged (e, isFullScreen) { update() } + +function checkDownloadPath () { + state.downloadPathStatus = undefined + fs.stat(state.saved.prefs.downloadPath, function (err, stat) { + if (err) { + state.downloadPathStatus = 'missing' + return console.error(err) + } + if (stat.isDirectory()) state.downloadPathStatus = 'ok' + else state.downloadPathStatus = 'missing' + }) +} diff --git a/src/renderer/views/preferences.js b/src/renderer/views/preferences.js index a751e0d8..c4d2feba 100644 --- a/src/renderer/views/preferences.js +++ b/src/renderer/views/preferences.js @@ -22,12 +22,12 @@ function renderGeneralSection (state) { description: '', icon: 'settings' }, [ - renderDownloadDirSelector(state), + renderDownloadPathSelector(state), renderFileHandlers(state) ]) } -function renderDownloadDirSelector (state) { +function renderDownloadPathSelector (state) { return renderFileSelector({ key: 'download-path', label: 'Download Path', diff --git a/src/renderer/views/torrent-list.js b/src/renderer/views/torrent-list.js index 4b85d2dd..a4849906 100644 --- a/src/renderer/views/torrent-list.js +++ b/src/renderer/views/torrent-list.js @@ -8,16 +8,36 @@ const {dispatcher} = require('../lib/dispatcher') module.exports = class TorrentList extends React.Component { render () { var state = this.props.state - var torrentRows = state.saved.torrents.map( - (torrentSummary) => this.renderTorrent(torrentSummary) - ) - return ( -
- {torrentRows} + var contents + if (!state.downloadPathStatus) { + contents = '' + } else if (state.downloadPathStatus === 'missing') { + contents = ( +
+

Download path missing: {state.saved.prefs.downloadPath}

+

Check that all drives are connected?

+

Alternatively, choose a new download path in + Preferences +

+
+ ) + } else if (state.downloadPathStatus === 'ok') { + contents = state.saved.torrents.map( + (torrentSummary) => this.renderTorrent(torrentSummary) + ) + contents.push(
Drop a torrent file here or paste a magnet link
+ ) + } else { + throw new Error('Unhandled downloadPathStatus ' + state.downloadPathStatus) + } + + return ( +
+ {contents}
) } diff --git a/static/main.css b/static/main.css index d56c9838..902c4c4e 100644 --- a/static/main.css +++ b/static/main.css @@ -551,6 +551,13 @@ input[type='text'] { line-height: 1.5em; } +/* + * TORRENT LIST: ERRORS + */ +.torrent-list p { + padding: 5px 20px; +} + /* * TORRENT LIST: DRAG-DROP TARGET */