WebTorrent Workshop

06 - Add the ability to share files

Add a form to the page which lets the user specify file to share with others. The user should be able to select files from their local filesystem using a standard “Browse for files…” upload dialog. Once they select some files, create a torrent and start seeding it using WebTorrent so that other users can download it if they know the correct magnet link to use.

The file transfer will take place over WebTorrent, which means that the data goes directly between users, without passing through a central server.

Tips

Let’s add a section to the page that shows a form:

<section>
  <h2>Start sharing</h2>
  <p>Drag-and-drop files to begin sharing.</p>
  <form>
    <label for='upload'>Or choose a file:</label>
    <input type='file' name='upload' id='upload' multiple />
  </form>
</section>

Let’s discuss a few things about this code.

Note: We’ll implement drag-and-drop in the next exercise so ignore the message in the HTML about using drag-and-drop for now!

The for='upload' attribute on the <label> element lets us tell the browser that this label describes the <input> element with name='upload'. This helps browser accessibility tools (like screen readers) to understand what the <input> field is for.

The id='upload' attribute on the <input> will help us easily find this element from our JavaScript code using the document.querySelector() function.

Notice how the <input> has a type='file' attribute so it renders as a file picker element. The multiple attribute tells the browser that the file picker should allow the user to select multiple files if they wish to do so.

One other neat trick. Notice how we don’t bother to include a submit button in this form. That’s because we’ll listen for the event that indicates the user has selected some files and immediately begin sharing them. This makes it a bit faster for the user to start sharing files!

Now let’s listen to the proper event. To do this we’ll use the upload-element library that saves us from writing a bunch of boilerplate code to listen to the proper event. You can import upload-element by adding this script tag to your HTML:

<script src='https://bundle.run/upload-element'></script>

This provides a uploadElement function on the global window object.

Now let’s register a function to run when the user selects files that they want to share. Add this to your init() function:

// Share files via upload input element
const upload = document.querySelector('#upload')
uploadElement(upload, (err, results) => {
  if (err) {
    logError(err)
    return
  }

  // For each result, get the File object
  const files = results.map(result => result.file)
  seedFiles(files)
})

If there was an error, we log it and return early from the function.

Otherwise, we map through the results and select the file property of each result. We store this array of File objects in a variable called files.

Finally, we call seedFiles() which will handle creating a torrent with these files inside, and sharing (i.e. seeding) these files with the WebTorrent network.

Let’s implement the seedFiles function now:

function seedFiles (files) {
  client.seed(files, handleTorrent)
  log(`Seeding new torrent with ${files.length} files!`)
}

We simply call WebTorrent’s client.seed function with the array of browser File objects to start sharing. This function creates a torrent from the given files and begins seeding it.

Finally, we call our handleTorrent function once this is finished, so the torrent contents display on the page just like when we called client.add before. This function is already implemented.

Verify

Try clicking the “Choose Files” or “Browse…” button (depends on the browser you’re using) to select some files to share.

You should see the message “Seeding new torrent with XX files!” where XX is the number of files that you selected. Finally, you should also see the file contents show up on the page, along with useful information like the new torrent’s magnet link.

Your page should look like this:

After sharing some files, open a duplicate CodePen tab and paste the magnet link in the download input and start downloading it. You should see the file get transferred from one browser tab to another!

Note: We’ll implement drag-and-drop in the next exercise so don’t worry if that doesn’t work right now!

If you are stuck, read the solution.

When you are ready, go to the next exercise.