diff --git a/renderer/index.css b/renderer/index.css index b3424bef..23e51720 100644 --- a/renderer/index.css +++ b/renderer/index.css @@ -113,6 +113,10 @@ table { opacity: 0.3; } +.clickable { + cursor: pointer; +} + .float-right { float: right; } @@ -597,7 +601,7 @@ body.drag .app::after { } .torrent-details { - padding: 8em 20px 20px 20px; + padding: 8em 12px 20px 20px; } .torrent-details table { @@ -611,6 +615,10 @@ body.drag .app::after { height: 28px; } +.torrent-details td { + vertical-align: center; +} + .torrent-details tr:hover { background-color: rgba(200, 200, 200, 0.3); } @@ -621,16 +629,16 @@ body.drag .app::after { vertical-align: bottom; } -.torrent-details td.col-icon { - width: 2em; -} - -.torrent-details td.col-icon .icon { +.torrent-details td .icon { font-size: 18px; position: relative; top: 3px; } +.torrent-details td.col-icon { + width: 2em; +} + .torrent-details td.col-name { width: auto; text-overflow: ellipsis; @@ -646,6 +654,11 @@ body.drag .app::after { text-align: right; } +.torrent-details td.col-select { + width: 2em; + text-align: right; +} + /* * PLAYER */ diff --git a/renderer/index.js b/renderer/index.js index 4e05c997..56ae762a 100644 --- a/renderer/index.js +++ b/renderer/index.js @@ -153,6 +153,11 @@ function cleanUpConfig () { delete ts.posterURL ts.posterFileName = infoHash + extension } + + // Migration: add per-file selections + if (!ts.selections) { + ts.selections = ts.files.map((x) => true) + } }) } @@ -231,6 +236,9 @@ function dispatch (action, ...args) { if (action === 'toggleSelectTorrent') { toggleSelectTorrent(args[0] /* infoHash */) } + if (action === 'toggleTorrentFile') { + toggleTorrentFile(args[0] /* infoHash */, args[1] /* index */) + } if (action === 'openTorrentContextMenu') { openTorrentContextMenu(args[0] /* infoHash */) } @@ -709,7 +717,7 @@ function startTorrentingSummary (torrentSummary) { } console.log('start torrenting %s %s', s.torrentKey, torrentID) - ipcRenderer.send('wt-start-torrenting', s.torrentKey, torrentID, path, s.fileModtimes) + ipcRenderer.send('wt-start-torrenting', s.torrentKey, torrentID, path, s.fileModtimes, s.selections) } // @@ -818,6 +826,9 @@ function torrentMetadata (torrentKey, torrentInfo) { torrentSummary.path = torrentInfo.path torrentSummary.files = torrentInfo.files torrentSummary.magnetURI = torrentInfo.magnetURI + if (!torrentSummary.selections) { + torrentSummary.selections = torrentSummary.files.map((x) => true) + } update() // Save the .torrent file, if it hasn't been saved already @@ -1058,6 +1069,14 @@ function toggleSelectTorrent (infoHash) { update() } +function toggleTorrentFile (infoHash, index) { + var torrentSummary = getTorrentSummary(infoHash) + torrentSummary.selections[index] = !torrentSummary.selections[index] + + // Let the WebTorrent process know to start or stop fetching that file + ipcRenderer.send('wt-select-files', infoHash, torrentSummary.selections) +} + function openTorrentContextMenu (infoHash) { var torrentSummary = getTorrentSummary(infoHash) var menu = new electron.remote.Menu() diff --git a/renderer/views/torrent-list.js b/renderer/views/torrent-list.js index 615fc92f..4cfcff00 100644 --- a/renderer/views/torrent-list.js +++ b/renderer/views/torrent-list.js @@ -208,7 +208,8 @@ function TorrentList (state) { // Show a single torrentSummary file in the details view for a single torrent function renderFileRow (torrentSummary, file, index) { // First, find out how much of the file we've downloaded - var isDone = false + var isSelected = torrentSummary.selections[index] // Are we even torrenting it? + var isDone = false // Are we finished torrenting it? var progress = '' if (torrentSummary.progress && torrentSummary.progress.files) { var fileProg = torrentSummary.progress.files[index] @@ -217,26 +218,38 @@ function TorrentList (state) { } // Second, render the file as a table row + var isPlayable = TorrentPlayer.isPlayable(file) var infoHash = torrentSummary.infoHash var icon - var rowClass = '' var handleClick - if (TorrentPlayer.isPlayable(file)) { + if (isPlayable) { icon = 'play_arrow' /* playable? add option to play */ handleClick = dispatcher('play', infoHash, index) } else { icon = 'description' /* file icon, opens in OS default app */ - rowClass = isDone ? '' : 'disabled' handleClick = dispatcher('openFile', infoHash, index) } + var rowClass = 'clickable' + if (!isSelected) rowClass = 'disabled' // File deselected, not being torrented + if (!isDone && !isPlayable) rowClass = 'disabled' // Can't open yet, can't stream return hx` -