tus / tus-js-client

A pure JavaScript client for the tus resumable upload protocol
https://tus.io/
MIT License
2.1k stars 315 forks source link

Is there a way to upload multiple files using tus-js-client #419

Closed c0d33py closed 10 months ago

c0d33py commented 2 years ago

Info: I want to upload multiple file using tus-js-client. I am facing some issue when i try to upload multiple files.

Issues:

const fileInput = document.querySelector('#js-file-input')
    const dataDiv = document.querySelector('#data-pre');
    const toggleBtn = document.querySelector('#toggle-btn')
    const progressBar = document.querySelector('.progress-bar')
    const textProgress = document.querySelector('#js-upload-text-progress')
    const uploadList = document.querySelector('#upload-list')

    function reset() {
      progressBar.style.width = `${0}%`
      textProgress.textContent = ""
    }
    /**
   * Turn a byte number into a human readable format.
   * Taken from https://stackoverflow.com/a/18650828
   */
    function formatBytes(bytes, decimals = 2) {
      if (bytes === 0) return '0 Bytes'

      const k = 1024
      const dm = decimals < 0 ? 0 : decimals
      const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
      const i = Math.floor(Math.log(bytes) / Math.log(k))
      return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]
    }

    fileInput.addEventListener('change', (e) => {
      const files = e.target.files;
      let convertedFiles = [];

      Object.keys(files).forEach(k => {
        convertedFiles = [
          ...convertedFiles,
          { id: URL.createObjectURL(files[k]), file: files[k] }
        ];
      });

      // setStagedFiles([...stagedFiles, ...convertedFiles]);

      convertedFiles.map(i => {
        const file = i.file;
        const chunkSize = parseInt(5242880, 10)

        let upload = new tus.Upload(file, {
          endpoint: "https://tusd.tusdemo.net/files/",
          // endpoint: "http://localhost:8000/tus/upload/",
          chunkSize,
          retryDelays: [0, 1000, 3000, 5000],
          metadata: {
            filename: file.name,
            filetype: file.type
          },
          onError: function (error) {
            console.log("Failed because: " + error);
          },
          onProgress: function (bytesUploaded, bytesTotal) {
            const percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2)
            progressBar.style.width = `${percentage}%`
            textProgress.textContent = `Uploaded ${formatBytes(bytesUploaded)} of ${formatBytes(bytesTotal)} (${percentage})`
            console.log(bytesUploaded, bytesTotal, percentage + "%");
          },
          onSuccess: function () {
            const anchor = document.createElement('a')
            anchor.textContent = `Download ${upload.file.name} (${upload.file.size} bytes)`
            anchor.href = upload.url
            anchor.className = 'btn btn-success'
            uploadList.appendChild(anchor)
            console.log("Download %s from %s", upload.file.name, upload.url);

            reset()
          }
        });

        toggleBtn.addEventListener('click', (e) => {
          upload.start()
        });

        dataDiv.innerHTML +=
          `
          <div class="file-data" key=${i.file.id}>
            <img alt="what" src=${i.id} width="150" />
            <div>name: ${i.file.name}</div>
            <div>type: ${i.file.type}</div>
            <div>size: ${i.file.size}</div>
          </div>
       `
      });
    });
Acconut commented 2 years ago

The progress bar is fluctuating

The onProgress callback reports the progress for each upload individually. You must manually combine these progress events to calculate the total progress over all uploaded files.

I want each file upload next file start after first file complete.

You can do this by only calling new tus.Upload(..) and upload.start() in the onSuccess callback of the previous upload.

In general, I recommend you to use Uppy (https://uppy.io/) which is built upon tus-js-client and supports tus uploads. It has much better support for handling multiple files, including calculating the combined upload progress and limiting the number of concurrent uploads.

c0d33py commented 2 years ago

Thanks for your reply!

Dear i am Django user so that's why i have installed (django-tus) which is working fine with tus-js-client.

i am also try with @uppy/tus. The @uppy/tus is working fine the files are uploaded successfully but in the trackback getting error

 File "/django/django-uppy/django_tus/views.py", line 81, in head
    tus_file = TusFile.get_tusfile_or_404(str(resource_id))
  File "/django/django-uppy/django_tus/tusfile.py", line 69, in get_tusfile_or_404
    raise TusResponse(status=404)
TypeError: exceptions must derive from BaseException

This issue also highlighted on Django-tus #24 but nobody respond yet.

Acconut commented 2 years ago

When exactly does this exception occur? During the actual upload or afterwards when you try to access the upload? Uppy directly uses tus-js-client, so if tus-js-client works, Uppy should also work without issues.

I have no experience with Django or the django-tus project, so I cannot help you much. But I would recommend you to comment on https://github.com/alican/django-tus/issues/24#issue-973376131 to see if you can get help.

Acconut commented 10 months ago

Closing this issue due to inactivity. Feel free to leave a comment if you want to continue the discussion :)