More changes to uploads:
- Have got upload images appearing in the post list - Allowed for deleting uploads - Allowed for seeing the upload progress - Fixed the setting of upload properties like the MIME type - Removed the stripe exif logic with just re-encoding PNGs and JPEGs by loading them and saving them
This commit is contained in:
parent
d0cebe6564
commit
199ff9feb9
21 changed files with 471 additions and 65 deletions
|
|
@ -4,6 +4,8 @@ import {showToast} from "../services/toast";
|
|||
export default class ShowUploadController extends Controller {
|
||||
static values = {
|
||||
copySnippet: String,
|
||||
siteId: Number,
|
||||
uploadId: Number,
|
||||
};
|
||||
|
||||
async copy(ev) {
|
||||
|
|
@ -16,4 +18,24 @@ export default class ShowUploadController extends Controller {
|
|||
body: "Copied to clipboard.",
|
||||
});
|
||||
}
|
||||
|
||||
async delete(ev) {
|
||||
ev.preventDefault();
|
||||
if (!confirm("Are you sure you want to delete this upload?")) {
|
||||
return;
|
||||
}
|
||||
await this._doDelete();
|
||||
window.location = `/sites/${this.siteIdValue}/uploads/`;
|
||||
}
|
||||
|
||||
async _doDelete() {
|
||||
const url = `/sites/${this.siteIdValue}/uploads/${this.uploadIdValue}`
|
||||
|
||||
await fetch(url, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,12 @@
|
|||
import { Controller } from "@hotwired/stimulus"
|
||||
|
||||
export default class UploadController extends Controller {
|
||||
static targets = [
|
||||
'uploadBtn',
|
||||
'progressbar',
|
||||
'progressbarProgress',
|
||||
];
|
||||
|
||||
static values = {
|
||||
siteId: Number,
|
||||
};
|
||||
|
|
@ -30,13 +36,17 @@ export default class UploadController extends Controller {
|
|||
}
|
||||
|
||||
async _doUploads(files) {
|
||||
for (let file of files) {
|
||||
await this._doUpload(file);
|
||||
this.uploadBtnTarget.disabled = true;
|
||||
this._showUploadProgressBar();
|
||||
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
await this._doUpload(files[i], i, files.length);
|
||||
}
|
||||
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
async _doUpload(file) {
|
||||
async _doUpload(file, thisFileIndex, nFiles) {
|
||||
console.log(`Uploading ${file.name}: new pending`);
|
||||
|
||||
// Prepare upload of file supplying size and mime-type
|
||||
|
|
@ -60,12 +70,11 @@ export default class UploadController extends Controller {
|
|||
let chunk = file.slice(offset, offset + chunkSize);
|
||||
|
||||
console.log(`Uploading ${file.name}: uploading part`);
|
||||
await fetch(`/sites/${this.siteIdValue}/uploads/pending/${newPending.guid}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/octet-stream'
|
||||
},
|
||||
body: chunk
|
||||
await this._uploadChunk(`/sites/${this.siteIdValue}/uploads/pending/${newPending.guid}`, chunk, {
|
||||
chunkOffset: offset,
|
||||
totalSize: file.size,
|
||||
thisFileIndex,
|
||||
nFiles,
|
||||
});
|
||||
|
||||
offset += chunkSize;
|
||||
|
|
@ -88,6 +97,44 @@ export default class UploadController extends Controller {
|
|||
});
|
||||
}
|
||||
|
||||
_uploadChunk(url, chunk, progressInfo) {
|
||||
let { chunkOffset, totalSize, thisFileIndex, nFiles } = progressInfo;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.upload.addEventListener('progress', (e) => {
|
||||
if (e.lengthComputable) {
|
||||
const bytesUploaded = chunkOffset + e.loaded;
|
||||
const fractionalCompleteOfThisFile = +bytesUploaded / +totalSize;
|
||||
const percentComplete = (thisFileIndex + fractionalCompleteOfThisFile) * 100 / nFiles;
|
||||
console.log(`Uploading ${chunk.name}: ${percentComplete.toFixed(2)}%`);
|
||||
this.progressbarProgressTarget.style.width = `${percentComplete}%`;
|
||||
}
|
||||
});
|
||||
|
||||
xhr.addEventListener('load', () => {
|
||||
if (xhr.status >= 200 && xhr.status < 300) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(new Error(`Upload failed with status ${xhr.status}`));
|
||||
}
|
||||
});
|
||||
|
||||
xhr.addEventListener('error', () => reject(new Error('Upload failed')));
|
||||
xhr.addEventListener('abort', () => reject(new Error('Upload aborted')));
|
||||
|
||||
xhr.open('POST', url);
|
||||
xhr.setRequestHeader('Content-Type', 'application/octet-stream');
|
||||
xhr.send(chunk);
|
||||
});
|
||||
}
|
||||
|
||||
_showUploadProgressBar() {
|
||||
this.progressbarTarget.classList.remove('d-none');
|
||||
this.progressbarProgressTarget.style.width = '0%';
|
||||
}
|
||||
|
||||
async _calculateSHA256(file) {
|
||||
const arrayBuffer = await file.arrayBuffer();
|
||||
const hashBuffer = await crypto.subtle.digest('SHA-256', arrayBuffer);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue