-
Notifications
You must be signed in to change notification settings - Fork 975
Support .torrent files in Torrent Viewer #7351
Conversation
app/filtering.js
Outdated
@@ -303,7 +303,7 @@ function registerForHeadersReceived (session, partition) { | |||
continue | |||
} | |||
if (results.responseHeaders) { | |||
cb({responseHeaders: results.responseHeaders}) | |||
cb({ responseHeaders: results.responseHeaders, statusLine: results.statusLine }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this cover |
@luixxiul I've never seen a .magnet file before. That's a first for me. They're non-standard and it looks like they're only used by the Vuze torrent client. We could support them, but I think that the libreoffice team was probably expecting users to open the .magnet file and paste the link into a torrent app. |
100d6d3
to
7ae3d03
Compare
This PR is ready for review! I have no idea who should review it, so I added a bunch of potential reviewers. Looking forward to finally landing this! |
<link rel="localization" href="locales/{locale}/app.properties"> | ||
</head> | ||
<body> | ||
<div id="appContainer" /> | ||
<script src='gen/webtorrentPage.entry.js'></script> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This let's us use the DOM node #appContainer
right away, without waiting for DOM ready.
* are read. | ||
* @return {boolean} True if the resource is a torrent file. | ||
*/ | ||
function isTorrentFile (details) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This .torrent file detection is pretty conservative. It looks for a torrent mimetype, and only uses the ".torrent" extension to indicate a torrent if the server sets the 'content-type' to 'application/octet-stream'.
@@ -0,0 +1,35 @@ | |||
const React = require('react') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pulled this into its own component
|
||
let content | ||
if (torrent.serverURL == null) { | ||
if (!file || !serverUrl) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix race condition where media is briefly added to <iframe>. If there is no file object yet, but there is a serverUrl, then an iframe is added to the page, instead of a "Loading..." message.
return <a href={magnetURL}>{file.name}</a> | ||
const suffix = /^https?:/.test(torrentId) | ||
? '#ix=' + ix | ||
: '&ix=' + ix |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For http torrent links, we use a hash symbol instead of a query param to indicate the file that is selected, since we don't want to add random query params to the URL, which could cause the server to 404 if it doesn't like it.
For magnet links, adding a query param is acceptable since unknown keys are ignored by all torrent clients.
l10nId='copyMagnetLink' | ||
className='whiteButton copyMagnetLink' | ||
onClick={() => dispatch('copyMagnetLink')} | ||
/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Magnet links get a "Copy Magnet Link" button, instead of "Save Torrent File" which made no sense.
store.torrentIdProtocol = parsedUrl.protocol | ||
|
||
// `ix` param can be set by query param or hash, e.g. ?ix=1 or #ix=1 | ||
if (parsedUrl.protocol === 'http:' || parsedUrl.protocol === 'https:') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is where you can see how torrent links and magnet links are handled differently.
// Clean up the client. Note: Since this does IPC, it's not guaranteed to send | ||
// before the page is closed. But that's okay; webtorrent-remote expects regular | ||
// heartbeats and assumes clients are dead after 30s without one. So basically, | ||
// this is an optimization to destroy the client sooner. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a much more descriptive comment here. We're not relying on this IPC succeeding before the page is unloaded. (It only succeeds like 50% of the time.)
// update() call that happens on a 1 second interval. | ||
torrent.on('infohash', update) | ||
torrent.on('metadata', update) | ||
torrent.on('done', update) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These handlers make the UI snappier
@@ -123,7 +124,7 @@ | |||
"tracking-protection": "1.1.x", | |||
"underscore": "1.8.3", | |||
"url-loader": "^0.5.7", | |||
"webtorrent-remote": "^1.0.0" | |||
"webtorrent-remote": "^2.0.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lots of fixes went into the next version of webtorrent-remote
to support this PR
@@ -87,6 +87,7 @@ | |||
"ad-block": "^2.0.0", | |||
"aphrodite": "^1.0.0", | |||
"async": "^2.0.1", | |||
"clipboard-copy": "^1.0.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Published this to npm since it's reuseable and useful in other contexts. It's simpler than the other copy-to-clipboard solutions out there. Unfortunately, this is not just a simple one-liner.
If there is no file object yet, but there is a serverUrl, then an iframe is added to the page, instead of a "Loading..." message
(All the previous changes assume this version)
Always show torrent title -- even if internationalization code runs after it's set.
bd2d0c9
to
9c44d03
Compare
@bsclifton Rebased, and ready for review! |
This is beautiful beyond words. Why does the save down-arrow icon link to localhost? What is the expected behavior? (currently does nothing) What do I do if I want to start a new torrent? Other than these questions ^ it looks great. Well done @feross! |
Thanks :)
We serve the files in the torrent from a local HTTP server. That way when the browser makes a request for a specific file (or a part of a file, in the case of streaming) the torrent engine knows to prioritize downloading that part of the torrent first. It's unfortunate that we're exposing localhost in the link, but I think it's acceptable. The expected behavior is that clicking it will trigger a file download for just that one file. In some cases, I notice a long delay before that dialog shows up. It's unclear why that's happening. I can look into it for a future PR.
Per-file info is doable. What do you mean by controls to stop/start on contents?
The torrent viewer works just like the PDF viewer that's also built into Brave. You start a new torrent by navigating to a magnet link or torrent file URL. |
I think its start/stop/exclude buttons for individual downloads. As there is no option to exclude specific files form the list. This is (not sure if it still there) a feature in utorrent where you can pause/cancel/exclude specific files even after torrent download is started. That would be a nice addition to the existing feature |
@feross I think there are a few things which probably should be managed before we push this out the door.
For future consideration:
I'm sure I'm missing some obvious things here, but as a first push, this is great. If we get the first two issues resolved, this is good to go. Tested on OS X and Windows. Linux test underway. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alexwykoff has done a comprehensive review; I reviewed the code and also tried the PR- works great 😄 Will go ahead and merge and we can address any opens items with a follow up issue
@alexwykoff I opened an issue for your request:
Your other suggestions are interesting. My thoughts are inline.
Useful, but definitely a power user feature. We already support this feature in WebTorrent Desktop, though I believe that are some bugs in the implementation right now and extra files end up getting downloaded. FWIW, files are already prioritized based on need. So, media that is being consumed via the built-in video player, or that is being downloaded via the 'save file' button will be prioritized before the rest of the files in the torrent. So the primary benefit of this feature would be saving bandwidth/disk space by not downloading files you know you don't need.
Does an average user know what a seed ratio is? WebTorrent Desktop doesn't even include a seed ratio and it hasn't generated too many complaints.
Definitely useful in some situations, but would this be a client-wide cap? Does that mean we need a page for configuring the torrent viewer extension?
Does the PDF viewer support creating PDF files? I think this is out of scope.
I know that most existing torrent apps show all the torrents in one big table. But I like the current model where torrents are treated just like any other webpage. One torrent per tab. Thanks for the review and for landing this, @alexwykoff @bsclifton! |
Test Plan
Also, confirm that magnet links continue to work:
Description
Behold,
.torrent
file support!Fixes: #6671
Fixes: #7772
git rebase -i
to squash commits (if needed).