diff --git a/src/main/menu.js b/src/main/menu.js index 37f34551..b8f1c691 100644 --- a/src/main/menu.js +++ b/src/main/menu.js @@ -288,6 +288,14 @@ function getMenuTemplate () { { label: 'Resume All', click: () => windows.main.dispatch('resumeAllTorrents') + }, + { + label: 'Remove All From List', + click: () => windows.main.dispatch('confirmDeleteAllTorrents', false) + }, + { + label: 'Remove All Data Files', + click: () => windows.main.dispatch('confirmDeleteAllTorrents', true) } ] }, diff --git a/src/renderer/components/delete-all-torrents-modal.js b/src/renderer/components/delete-all-torrents-modal.js new file mode 100644 index 00000000..f3424dc0 --- /dev/null +++ b/src/renderer/components/delete-all-torrents-modal.js @@ -0,0 +1,31 @@ +const React = require('react') + +const ModalOKCancel = require('./modal-ok-cancel') +const { dispatch, dispatcher } = require('../lib/dispatcher') + +module.exports = class DeleteAllTorrentsModal extends React.Component { + render () { + const { state: { modal: { deleteData } } } = this.props + const message = deleteData + ? 'Are you sure you want to remove all the torrents from the list and delete the data files?' + : 'Are you sure you want to remove all the torrents from the list?' + const buttonText = deleteData ? 'REMOVE DATA' : 'REMOVE' + + return ( +
+

{message}

+ +
+ ) + + function handleRemove () { + dispatch('deleteAllTorrents', deleteData) + dispatch('exitModal') + } + } +} diff --git a/src/renderer/controllers/torrent-list-controller.js b/src/renderer/controllers/torrent-list-controller.js index fbfba2e2..2cb8bb82 100644 --- a/src/renderer/controllers/torrent-list-controller.js +++ b/src/renderer/controllers/torrent-list-controller.js @@ -201,26 +201,38 @@ module.exports = class TorrentListController { } } + confirmDeleteAllTorrents (deleteData) { + this.state.modal = { + id: 'delete-all-torrents-modal', + deleteData + } + } + // TODO: use torrentKey, not infoHash deleteTorrent (infoHash, deleteData) { - ipcRenderer.send('wt-stop-torrenting', infoHash) - const index = this.state.saved.torrents.findIndex((x) => x.infoHash === infoHash) if (index > -1) { const summary = this.state.saved.torrents[index] - - // remove torrent and poster file - deleteFile(TorrentSummary.getTorrentPath(summary)) - deleteFile(TorrentSummary.getPosterPath(summary)) - - // optionally delete the torrent data - if (deleteData) moveItemToTrash(summary) + deleteTorrentFile(summary, deleteData) // remove torrent from saved list this.state.saved.torrents.splice(index, 1) dispatch('stateSave') + + // prevent user from going forward to a deleted torrent + this.state.location.clearForward('player') + sound.play('DELETE') + } else { + throw new TorrentKeyNotFoundError(infoHash) } + } + + deleteAllTorrents (deleteData) { + this.state.saved.torrents.forEach((summary) => deleteTorrentFile(summary, deleteData)) + + this.state.saved.torrents = [] + dispatch('stateSave') // prevent user from going forward to a deleted torrent this.state.location.clearForward('player') @@ -286,7 +298,7 @@ module.exports = class TorrentListController { // Shows a Save File dialog, then saves the .torrent file wherever the user requests saveTorrentFileAs (torrentKey) { const torrentSummary = TorrentSummary.getByKey(this.state, torrentKey) - if (!torrentSummary) throw new Error('Missing torrentKey: ' + torrentKey) + if (!torrentSummary) throw new TorrentKeyNotFoundError(torrentKey) const downloadPath = this.state.saved.prefs.downloadPath const newFileName = path.parse(torrentSummary.name).name + '.torrent' const win = electron.remote.getCurrentWindow() @@ -372,3 +384,14 @@ function moveItemToTrash (torrentSummary) { function showItemInFolder (torrentSummary) { ipcRenderer.send('showItemInFolder', TorrentSummary.getFileOrFolder(torrentSummary)) } + +function deleteTorrentFile (torrentSummary, deleteData) { + ipcRenderer.send('wt-stop-torrenting', torrentSummary.infoHash) + + // remove torrent and poster file + deleteFile(TorrentSummary.getTorrentPath(torrentSummary)) + deleteFile(TorrentSummary.getPosterPath(torrentSummary)) + + // optionally delete the torrent data + if (deleteData) moveItemToTrash(torrentSummary) +} diff --git a/src/renderer/main.js b/src/renderer/main.js index a551893c..be363d6c 100644 --- a/src/renderer/main.js +++ b/src/renderer/main.js @@ -255,6 +255,10 @@ const dispatchHandlers = { controllers.torrentList().confirmDeleteTorrent(infoHash, deleteData), deleteTorrent: (infoHash, deleteData) => controllers.torrentList().deleteTorrent(infoHash, deleteData), + confirmDeleteAllTorrents: (deleteData) => + controllers.torrentList().confirmDeleteAllTorrents(deleteData), + deleteAllTorrents: (deleteData) => + controllers.torrentList().deleteAllTorrents(deleteData), toggleSelectTorrent: (infoHash) => controllers.torrentList().toggleSelectTorrent(infoHash), openTorrentContextMenu: (infoHash) => diff --git a/src/renderer/pages/app.js b/src/renderer/pages/app.js index 77de5a9a..1709f127 100644 --- a/src/renderer/pages/app.js +++ b/src/renderer/pages/app.js @@ -24,7 +24,9 @@ const Modals = { ), 'remove-torrent-modal': createGetter(() => require('../components/remove-torrent-modal')), 'update-available-modal': createGetter(() => require('../components/update-available-modal')), - 'unsupported-media-modal': createGetter(() => require('../components/unsupported-media-modal')) + 'unsupported-media-modal': createGetter(() => require('../components/unsupported-media-modal')), + 'delete-all-torrents-modal': + createGetter(() => require('../components/delete-all-torrents-modal')) } const fontFamily = process.platform === 'win32'