115 lines
2.8 KiB
JavaScript
115 lines
2.8 KiB
JavaScript
import call from './call';
|
|
|
|
export default class S3FileUploader {
|
|
constructor() {
|
|
this.listeners = {};
|
|
}
|
|
|
|
on(event, handler) {
|
|
this.listeners[event] = this.listeners[event] || [];
|
|
this.listeners[event].push(handler);
|
|
}
|
|
|
|
trigger(event, data) {
|
|
let handlers = this.listeners[event] || [];
|
|
handlers.forEach(handler => {
|
|
handler.call(this, data);
|
|
});
|
|
}
|
|
|
|
upload(file, options) {
|
|
return new Promise(async (resolve, reject) => {
|
|
async function getUploadLink() {
|
|
try {
|
|
let response = await fetch(
|
|
`/api/action/jcloud.api.site.get_upload_link?file=${file.name}`
|
|
);
|
|
let data = await response.json();
|
|
return data.message;
|
|
} catch (e) {
|
|
reject(e);
|
|
}
|
|
}
|
|
const upload_link = await getUploadLink();
|
|
const file_path = upload_link?.fields?.key;
|
|
|
|
if (!file_path) {
|
|
return;
|
|
}
|
|
|
|
let xhr = new XMLHttpRequest();
|
|
xhr.upload.addEventListener('loadstart', () => {
|
|
this.trigger('start');
|
|
});
|
|
xhr.upload.addEventListener('progress', e => {
|
|
if (e.lengthComputable) {
|
|
this.trigger('progress', {
|
|
uploaded: e.loaded,
|
|
total: e.total
|
|
});
|
|
}
|
|
});
|
|
xhr.upload.addEventListener('load', () => {
|
|
this.trigger('finish');
|
|
});
|
|
xhr.addEventListener('error', () => {
|
|
this.trigger('error');
|
|
reject();
|
|
});
|
|
xhr.onreadystatechange = () => {
|
|
if (xhr.readyState == XMLHttpRequest.DONE) {
|
|
let error;
|
|
if (xhr.status === 200 || xhr.status === 204) {
|
|
let r = null;
|
|
try {
|
|
r = JSON.parse(xhr.responseText);
|
|
} catch (e) {
|
|
r = xhr.responseText;
|
|
}
|
|
let out =
|
|
r.message ||
|
|
call('jcloud.api.site.uploaded_backup_info', {
|
|
file: file.name,
|
|
path: file_path,
|
|
type: file.type,
|
|
size: file.size
|
|
});
|
|
resolve(out || upload_link.fields.key);
|
|
} else {
|
|
// response from aws is in xml
|
|
let xmlDoc = new DOMParser().parseFromString(
|
|
xhr.responseText,
|
|
'text/xml'
|
|
);
|
|
let code =
|
|
xmlDoc.getElementsByTagName('Code')[0].childNodes[0].nodeValue;
|
|
let message =
|
|
xmlDoc.getElementsByTagName('Message')[0].childNodes[0].nodeValue;
|
|
console.error(`${code}: ${message}`);
|
|
error = xhr.responseText;
|
|
}
|
|
if (error && error.exc) {
|
|
console.error(JSON.parse(error.exc)[0]);
|
|
}
|
|
reject(error);
|
|
}
|
|
};
|
|
|
|
xhr.open('POST', upload_link.url, true);
|
|
xhr.setRequestHeader('Accept', 'application/json');
|
|
|
|
let form_data = new FormData();
|
|
for (let key in upload_link.fields) {
|
|
if (upload_link.fields.hasOwnProperty(key)) {
|
|
form_data.append(key, upload_link.fields[key]);
|
|
}
|
|
}
|
|
if (file) {
|
|
form_data.append('file', file, file.name);
|
|
}
|
|
|
|
xhr.send(form_data);
|
|
});
|
|
}
|
|
}
|