2020-03-30 15:34:56 +02:00
|
|
|
import Rails from '@rails/ujs';
|
|
|
|
import AutoUploadController from './auto-upload-controller.js';
|
2020-04-20 15:07:44 +02:00
|
|
|
import { fire } from '@utils';
|
2020-04-15 16:35:39 +02:00
|
|
|
import { FAILURE_CONNECTIVITY } from '../../shared/activestorage/file-upload-error';
|
2020-03-30 15:34:56 +02:00
|
|
|
|
2020-04-20 15:07:44 +02:00
|
|
|
//
|
|
|
|
// DEBUG
|
|
|
|
//
|
|
|
|
const originalImpl = FileReader.prototype.addEventListener;
|
|
|
|
|
2020-03-30 15:34:56 +02:00
|
|
|
// Manage multiple concurrent uploads.
|
|
|
|
//
|
|
|
|
// When the first upload starts, all the form "Submit" buttons are disabled.
|
|
|
|
// They are enabled again when the last upload ends.
|
|
|
|
export default class AutoUploadsControllers {
|
|
|
|
constructor() {
|
|
|
|
this.inFlightUploadsCount = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
async upload(input, file) {
|
|
|
|
let form = input.form;
|
|
|
|
this._incrementInFlightUploads(form);
|
|
|
|
|
|
|
|
try {
|
|
|
|
let controller = new AutoUploadController(input, file);
|
|
|
|
await controller.start();
|
2020-04-15 16:35:39 +02:00
|
|
|
} catch (error) {
|
|
|
|
// Report errors to Sentry (except connectivity issues)
|
|
|
|
if (error.failureReason != FAILURE_CONNECTIVITY) {
|
|
|
|
throw error;
|
|
|
|
}
|
2020-03-30 15:34:56 +02:00
|
|
|
} finally {
|
|
|
|
this._decrementInFlightUploads(form);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_incrementInFlightUploads(form) {
|
|
|
|
this.inFlightUploadsCount += 1;
|
|
|
|
|
|
|
|
if (form) {
|
|
|
|
form
|
|
|
|
.querySelectorAll('button[type=submit]')
|
|
|
|
.forEach(submitButton => Rails.disableElement(submitButton));
|
|
|
|
}
|
2020-04-20 15:07:44 +02:00
|
|
|
|
|
|
|
//
|
|
|
|
// DEBUG: hook into FileReader onload event
|
|
|
|
//
|
|
|
|
if (FileReader.prototype.addEventListener === originalImpl) {
|
|
|
|
FileReader.prototype.addEventListener = function() {
|
|
|
|
// When DirectUploads attempts to add an event listener for "error",
|
|
|
|
// also insert a custom event listener of our that will report errors to Sentry.
|
|
|
|
if (arguments[0] == 'error') {
|
|
|
|
let handler = event => {
|
|
|
|
let message = `FileReader ${event.target.error.name}: ${event.target.error.message}`;
|
|
|
|
fire(document, 'sentry:capture-exception', new Error(message));
|
|
|
|
};
|
|
|
|
originalImpl.apply(this, ['error', handler]);
|
|
|
|
}
|
|
|
|
// Add the originally requested event listener
|
|
|
|
return originalImpl.apply(this, arguments);
|
|
|
|
};
|
|
|
|
}
|
2020-03-30 15:34:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
_decrementInFlightUploads(form) {
|
|
|
|
if (this.inFlightUploadsCount > 0) {
|
|
|
|
this.inFlightUploadsCount -= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.inFlightUploadsCount == 0 && form) {
|
|
|
|
form
|
|
|
|
.querySelectorAll('button[type=submit]')
|
|
|
|
.forEach(submitButton => Rails.enableElement(submitButton));
|
|
|
|
}
|
2020-04-20 15:07:44 +02:00
|
|
|
|
|
|
|
//
|
|
|
|
// DEBUG: remove the FileReader hook we set before.
|
|
|
|
//
|
|
|
|
if (this.inFlightUploadsCount == 0) {
|
|
|
|
FileReader.prototype.addEventListener = originalImpl;
|
|
|
|
}
|
2020-03-30 15:34:56 +02:00
|
|
|
}
|
|
|
|
}
|