Improved Jua uploader

This commit is contained in:
djmaze 2021-09-14 12:50:56 +02:00
parent 2cb73643ca
commit 9e28eb5fc7
5 changed files with 45 additions and 66 deletions

View file

@ -57,10 +57,7 @@ export class ThemesUserSettings {
if (this.background.uploaderButton() && this.capaUserBackground()) { if (this.background.uploaderButton() && this.capaUserBackground()) {
const oJua = new Jua({ const oJua = new Jua({
action: serverRequest('UploadBackground'), action: serverRequest('UploadBackground'),
name: 'uploader', limit: 1,
queueSize: 1,
multipleSizeLimit: 1,
disableMultiple: true,
clickElement: this.background.uploaderButton() clickElement: this.background.uploaderButton()
}); });

View file

@ -1096,9 +1096,6 @@ class ComposePopupView extends AbstractViewPopup {
attachmentSizeLimit = pInt(SettingsGet('AttachmentLimit')), attachmentSizeLimit = pInt(SettingsGet('AttachmentLimit')),
oJua = new Jua({ oJua = new Jua({
action: serverRequest('Upload'), action: serverRequest('Upload'),
name: 'uploader',
queueSize: 2,
multipleSizeLimit: 50,
clickElement: this.composeUploaderButton(), clickElement: this.composeUploaderButton(),
dragAndDropElement: this.composeUploaderDropPlace() dragAndDropElement: this.composeUploaderDropPlace()
}); });
@ -1176,23 +1173,24 @@ class ComposePopupView extends AbstractViewPopup {
}) })
.on('onComplete', (id, result, data) => { .on('onComplete', (id, result, data) => {
const attachment = this.getAttachmentById(id), const attachment = this.getAttachmentById(id),
errorCode = data && data.Result && data.Result.ErrorCode ? data.Result.ErrorCode : null, response = (data && data.Result) || {},
attachmentJson = result && data && data.Result && data.Result.Attachment ? data.Result.Attachment : null; errorCode = response.ErrorCode,
attachmentJson = result && response.Attachment;
let error = ''; let error = '';
if (null !== errorCode) { if (null != errorCode) {
error = getUploadErrorDescByCode(errorCode); error = getUploadErrorDescByCode(errorCode);
} else if (!attachmentJson) { } else if (!attachmentJson) {
error = i18n('UPLOAD/ERROR_UNKNOWN'); error = i18n('UPLOAD/ERROR_UNKNOWN');
} }
if (attachment) { if (attachment) {
if (error && error.length) { if (error) {
attachment attachment
.waiting(false) .waiting(false)
.uploading(false) .uploading(false)
.complete(true) .complete(true)
.error(error); .error(error + '\n' + response.ErrorMessage);
} else if (attachmentJson) { } else if (attachmentJson) {
attachment attachment
.waiting(false) .waiting(false)

View file

@ -472,10 +472,7 @@ class ContactsPopupView extends AbstractViewPopup {
if (this.importUploaderButton()) { if (this.importUploaderButton()) {
const j = new Jua({ const j = new Jua({
action: serverRequest('UploadContacts'), action: serverRequest('UploadContacts'),
name: 'uploader', limit: 1,
queueSize: 1,
multipleSizeLimit: 1,
disableMultiple: true,
disableDocumentDropPrevent: true, disableDocumentDropPrevent: true,
clickElement: this.importUploaderButton() clickElement: this.importUploaderButton()
}); });

View file

@ -720,8 +720,7 @@ export class MessageListMailBoxUserView extends AbstractViewRight {
const oJua = new Jua({ const oJua = new Jua({
action: serverRequest('Append'), action: serverRequest('Append'),
name: 'AppendFile', name: 'AppendFile',
queueSize: 1, limit: 1,
multipleSizeLimit: 1,
hidden: { hidden: {
Folder: () => FolderUserStore.currentFolderFullNameRaw() Folder: () => FolderUserStore.currentFolderFullNameRaw()
}, },

84
vendors/jua/jua.js vendored
View file

@ -1,7 +1,6 @@
/* RainLoop Webmail (c) RainLoop Team | MIT */ /* RainLoop Webmail (c) RainLoop Team | MIT */
(doc => { (doc => {
const const
iDefLimit = 20,
defined = v => undefined !== v, defined = v => undefined !== v,
/** /**
* @param {*} aItems * @param {*} aItems
@ -13,7 +12,6 @@
{ {
if (aItems && aItems.length) if (aItems && aItems.length)
{ {
iLimit = defined(iLimit) ? parseInt(iLimit || 0, 10) : iDefLimit;
let let
iInputLimit = iLimit, iInputLimit = iLimit,
oFile = null, oFile = null,
@ -53,15 +51,15 @@
sType = oFile.type || '' sType = oFile.type || ''
; ;
return (!sType && 0 == iSize) return (sType && iSize)
? null // Folder ? {
: { FileName: (oFile.name || '').replace(/^.*\/([^/]*)$/, '$1'),
'FileName': (oFile.name || '').replace(/^.*\/([^/]*)$/, '$1'), Size: iSize,
'Size': iSize, Type: sType,
'Type': sType, Folder: '',
'Folder': '', File : oFile
'File' : oFile }
}; : null; // Folder
}, },
eventContainsFiles = oEvent => eventContainsFiles = oEvent =>
@ -97,11 +95,11 @@
/** /**
* @constructor * @constructor
* @param {Object=} oOptions * @param {Object=} options
*/ */
class Jua class Jua
{ {
constructor(oOptions) constructor(options)
{ {
const self = this; const self = this;
@ -117,25 +115,17 @@
onLimitReached: null onLimitReached: null
}; };
oOptions = Object.assign({
action: '',
name: 'juaFile',
hidden: {},
disableMultiple: false,
queueSize: 10,
clickElement: null,
dragAndDropElement: null,
dragAndDropBodyElement: null,
disableDocumentDropPrevent: false,
multipleSizeLimit: iDefLimit
}, oOptions || {});
self.oXhrs = {}; self.oXhrs = {};
self.oUids = {}; self.oUids = {};
self.oOptions = oOptions; self.options = Object.assign({
self.oQueue = new Queue(oOptions.queueSize); action: '',
name: 'uploader',
hidden: {},
limit: 0
}, options || {});
self.oQueue = new Queue(1 == options.limit ? 1 : 2);
let el = oOptions.clickElement; let el = options.clickElement;
if (el) { if (el) {
el.style.position = 'relative'; el.style.position = 'relative';
el.style.overflow = 'hidden'; el.style.overflow = 'hidden';
@ -146,12 +136,12 @@
self.generateNewInput(el); self.generateNewInput(el);
} }
el = oOptions.dragAndDropElement; el = options.dragAndDropElement;
if (el) if (el)
{ {
let oBigDropZone = oOptions.dragAndDropBodyElement || doc; let oBigDropZone = options.dragAndDropBodyElement || doc;
if (!oOptions.disableDocumentDropPrevent) if (!options.disableDocumentDropPrevent)
{ {
doc.addEventListener('dragover', oEvent => { doc.addEventListener('dragover', oEvent => {
if (eventContainsFiles(oEvent)) if (eventContainsFiles(oEvent))
@ -246,7 +236,7 @@
self.docTimer.clear(); self.docTimer.clear();
} }
}, },
oOptions.multipleSizeLimit, self.options.limit,
self.getEvent('onLimitReached') self.getEvent('onLimitReached')
); );
} }
@ -273,10 +263,7 @@
*/ */
runEvent(sName, aArgs) runEvent(sName, aArgs)
{ {
if (this.oEvents[sName]) this.oEvents[sName] && this.oEvents[sName].apply(null, aArgs || []);
{
this.oEvents[sName].apply(null, aArgs || []);
}
} }
/** /**
@ -330,8 +317,8 @@
self = this, self = this,
oXhr = new XMLHttpRequest(), oXhr = new XMLHttpRequest(),
oFormData = new FormData(), oFormData = new FormData(),
sAction = this.oOptions.action, sAction = this.options.action,
aHidden = this.oOptions.hidden, aHidden = this.options.hidden,
fStartFunction = this.getEvent('onStart'), fStartFunction = this.getEvent('onStart'),
fProgressFunction = this.getEvent('onProgress') fProgressFunction = this.getEvent('onProgress')
; ;
@ -366,13 +353,13 @@
console.error(e); console.error(e);
} }
} }
this.getEvent('onComplete')(sUid, bResult, bResult ? oResult : null); this.getEvent('onComplete')(sUid, bResult, oResult);
} }
}; };
fStartFunction && fStartFunction(sUid); fStartFunction && fStartFunction(sUid);
oFormData.append(this.oOptions.name, oFileInfo['File']); oFormData.append(this.options.name, oFileInfo['File']);
Object.entries(aHidden).forEach(([key, value]) => Object.entries(aHidden).forEach(([key, value]) =>
oFormData.append(key, (typeof value === "function" ? value(oFileInfo) : value).toString()) oFormData.append(key, (typeof value === "function" ? value(oFileInfo) : value).toString())
); );
@ -395,13 +382,14 @@
if (oClickElement) if (oClickElement)
{ {
const self = this, const self = this,
limit = self.options.limit,
oInput = doc.createElement('input'), oInput = doc.createElement('input'),
onClick = ()=>oInput.click(); onClick = ()=>oInput.click();
oInput.type = 'file'; oInput.type = 'file';
oInput.tabIndex = -1; oInput.tabIndex = -1;
oInput.style.display = 'none'; oInput.style.display = 'none';
oInput.multiple = !self.oOptions.disableMultiple; oInput.multiple = 1 < limit;
oClickElement.addEventListener('click', onClick); oClickElement.addEventListener('click', onClick);
@ -416,16 +404,16 @@
}; };
if (oInput.files && oInput.files.length) { if (oInput.files && oInput.files.length) {
getDataFromFiles(oInput.files, fFileCallback, getDataFromFiles(oInput.files, fFileCallback,
self.oOptions.multipleSizeLimit, limit,
self.getEvent('onLimitReached') self.getEvent('onLimitReached')
); );
} else { } else {
fFileCallback({ fFileCallback({
'FileName': oInput.value.split('\\').pop().split('/').pop(), FileName: oInput.value.split(/\\\//).pop(),
'Size': null, Size: null,
'Type': null, Type: null,
'Folder': '', Folder: '',
'File' : null File : null
}); });
} }
}); });