Have got uploads working
This commit is contained in:
parent
97112d99dd
commit
6b697e008f
20 changed files with 751 additions and 7 deletions
97
assets/js/controllers/upload.js
Normal file
97
assets/js/controllers/upload.js
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
import { Controller } from "@hotwired/stimulus"
|
||||
|
||||
export default class UploadController extends Controller {
|
||||
static values = {
|
||||
siteId: Number,
|
||||
};
|
||||
|
||||
upload(ev) {
|
||||
ev.preventDefault();
|
||||
|
||||
this._promptForUpload((files) => {
|
||||
this._doUploads(files);
|
||||
})
|
||||
}
|
||||
|
||||
_promptForUpload(onAccept) {
|
||||
const input = document.createElement('input');
|
||||
input.type = 'file';
|
||||
input.accept = 'image/*';
|
||||
input.multiple = true;
|
||||
|
||||
input.onchange = (e) => {
|
||||
const files = Array.from(e.target.files);
|
||||
if (files.length > 0) {
|
||||
onAccept(files);
|
||||
}
|
||||
};
|
||||
|
||||
input.click();
|
||||
}
|
||||
|
||||
async _doUploads(files) {
|
||||
for (let file of files) {
|
||||
await this._doUpload(file);
|
||||
}
|
||||
}
|
||||
|
||||
async _doUpload(file) {
|
||||
console.log(`Uploading ${file.name}: new pending`);
|
||||
|
||||
// Prepare upload of file supplying size and mime-type
|
||||
let newPending = await (await fetch(`/sites/${this.siteIdValue}/uploads/pending`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
size: file.size,
|
||||
mime: file.type,
|
||||
name: file.name,
|
||||
})
|
||||
})).json();
|
||||
|
||||
// Upload file in 2 MB blocks
|
||||
let offset = 0;
|
||||
let chunkSize = 2 * 1024 * 1024;
|
||||
while (offset < file.size) {
|
||||
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
|
||||
});
|
||||
|
||||
offset += chunkSize;
|
||||
}
|
||||
|
||||
// Calculate SHA256 hash
|
||||
const hash = await this._calculateSHA256(file);
|
||||
|
||||
// Finalise upload
|
||||
console.log(`Uploading ${file.name}: finalise`);
|
||||
await fetch(`/sites/${this.siteIdValue}/uploads/pending/${newPending.guid}/finalize`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
hash: hash
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
async _calculateSHA256(file) {
|
||||
const arrayBuffer = await file.arrayBuffer();
|
||||
const hashBuffer = await crypto.subtle.digest('SHA-256', arrayBuffer);
|
||||
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
||||
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
|
||||
return hashHex;
|
||||
}
|
||||
}
|
||||
|
|
@ -5,10 +5,12 @@ import PostlistController from "./controllers/postlist";
|
|||
import PosteditController from "./controllers/postedit";
|
||||
import LogoutController from "./controllers/logout";
|
||||
import FirstRunController from "./controllers/firstrun";
|
||||
import UploadController from "./controllers/upload";
|
||||
|
||||
window.Stimulus = Application.start()
|
||||
Stimulus.register("toast", ToastController);
|
||||
Stimulus.register("postlist", PostlistController);
|
||||
Stimulus.register("postedit", PosteditController);
|
||||
Stimulus.register("logout", LogoutController);
|
||||
Stimulus.register("first-run", FirstRunController);
|
||||
Stimulus.register("first-run", FirstRunController);
|
||||
Stimulus.register("upload", UploadController);
|
||||
Loading…
Add table
Add a link
Reference in a new issue