Tus10.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import Plugin from './Plugin'
  2. import tus from 'tus-js-client'
  3. /**
  4. * Tus resumable file uploader
  5. *
  6. */
  7. export default class Tus10 extends Plugin {
  8. constructor (core, opts) {
  9. super(core, opts)
  10. this.type = 'uploader'
  11. // set default options
  12. const defaultOptions = {}
  13. // merge default options with the ones set by user
  14. this.opts = Object.assign({}, defaultOptions, opts)
  15. }
  16. /**
  17. * Create a new Tus upload
  18. *
  19. * @param {object} file for use with upload
  20. * @param {integer} current file in a queue
  21. * @param {integer} total number of files in a queue
  22. * @returns {Promise}
  23. */
  24. upload (file, current, total) {
  25. this.core.log(`uploading ${current} of ${total}`)
  26. // Create a new tus upload
  27. return new Promise((resolve, reject) => {
  28. const upload = new tus.Upload(file.data, {
  29. // TODO merge this.opts or this.opts.tus here
  30. resume: false,
  31. endpoint: this.opts.endpoint,
  32. onError: (error) => {
  33. reject('Failed because: ' + error)
  34. },
  35. onProgress: (bytesUploaded, bytesTotal) => {
  36. let percentage = (bytesUploaded / bytesTotal * 100).toFixed(2)
  37. percentage = Math.round(percentage)
  38. // Dispatch progress event
  39. this.core.emitter.emit('upload-progress', {
  40. uploader: this,
  41. id: file.id,
  42. percentage: percentage
  43. })
  44. },
  45. onSuccess: () => {
  46. file.uploadURL = upload.url
  47. this.core.emitter.emit('upload-success', file)
  48. this.core.log(`Download ${upload.file.name} from ${upload.url}`)
  49. resolve(upload)
  50. }
  51. })
  52. upload.start()
  53. })
  54. }
  55. install () {
  56. this.core.emitter.on('next', () => {
  57. this.core.log('Tus is uploading..')
  58. const files = this.core.state.files
  59. const filesForUpload = {}
  60. Object.keys(files).forEach((file) => {
  61. if (files[file].progress === 0) {
  62. filesForUpload[file] = files[file]
  63. }
  64. })
  65. const uploaders = []
  66. Object.keys(filesForUpload).forEach((fileID, i) => {
  67. const file = filesForUpload[fileID]
  68. const current = parseInt(i, 10) + 1
  69. const total = Object.keys(filesForUpload).length
  70. uploaders.push(this.upload(file, current, total))
  71. })
  72. Promise.all(uploaders).then((result) => {
  73. this.core.log('Tus has finished uploading!')
  74. })
  75. })
  76. }
  77. /**
  78. * Add files to an array of `upload()` calles, passing the current and total file count numbers
  79. *
  80. * @param {Array | Object} results
  81. * @returns {Promise} of parallel uploads `Promise.all(uploaders)`
  82. */
  83. run (results) {
  84. this.core.log({
  85. class: this.constructor.name,
  86. method: 'run',
  87. results: results
  88. })
  89. const files = results
  90. // var uploaded = [];
  91. const uploaders = []
  92. for (let i in files) {
  93. const file = files[i]
  94. const current = parseInt(i, 10) + 1
  95. const total = files.length
  96. uploaders.push(this.upload(file, current, total))
  97. }
  98. return Promise.all(uploaders).then(() => {
  99. return {
  100. uploadedCount: files.length
  101. }
  102. })
  103. }
  104. }