I have developed a plugin to upload multiple files to the Bubble server. It works great on other devices except for iOS and MacOS. It works on Chrome but not on Safari. The issue that I think it is having is due to the WebKit engine Apple uses for its browsers.
Here is the code for the action that is responsible for uploading file to bubble:
function(instance, properties, context) {
if (instance.data.nomes.length > 0) {
const extensoes = instance.data.extensoes;
const nomes = instance.data.nomes;
const totalFiles = instance.data.nomes.length;
let uploadedFiles = [];
let totalBytes = 0;
let uploadedBytes = 0;
// Calculate total bytes for all files
instance.data.size.forEach((fileSize) => {
totalBytes += fileSize;
});
// Function to update progress
function updateProgress(bytesUploaded) {
uploadedBytes += bytesUploaded;
const progress = (uploadedBytes / totalBytes) * 100;
console.log("Update Progress");
instance.publishState('progress', progress.toFixed(2));
}
// Function to upload a single file with granular progress updates
function uploadFile(index) {
return new Promise((resolve, reject) => {
// Offload base64 to Blob conversion to avoid blocking the main thread
setTimeout(() => {
const name = nomes[index].split('.').slice(0, -1).join('.');
const extension = extensoes[index];
const fileName = `${name}.${extension}`;
// Convert Blob to byte array (no base64)
instance.data.blob[index].arrayBuffer().then(arrayBuffer => {
const byteArray = new Uint8Array(arrayBuffer);
console.log(byteArray); // Logs the byte array
const blob = new Blob([byteArray], { type: 'application/octet-stream' });
const file = new File([blob], fileName);
const fileSize = instance.data.size[index]; // Get the size for the specific file
let uploadedForThisFile = 0; // Bytes uploaded for this file
// Check if file can be uploaded
if (!instance.canUploadFile(file)) {
reject(new Error("File cannot be uploaded. Check the size or other constraints."));
return;
}
// Start file upload using instance.uploadFile
instance.uploadFile(
file,
function (err, url) {
if (err) {
reject(err);
return;
}
if (url) {
updateProgress(fileSize - uploadedForThisFile);
uploadedFiles.push(url);
resolve();
}
},
properties.attachTo, // Optional parameter for attaching to a thing
function (progress) {
const progressIncrement = progress * fileSize - uploadedForThisFile;
if (progressIncrement > 0) {
updateProgress(progressIncrement);
uploadedForThisFile += progressIncrement;
}
}
);
}).catch(err => {
console.error('Error converting Blob to ArrayBuffer:', err);
reject(err);
});
}, 0); // Delay conversion to prevent blocking the UI
});
}
// Upload all files sequentially
async function uploadAllFiles() {
try {
for (let i = 0; i < totalFiles; i++) {
await uploadFile(i); // Wait for each file to complete
}
// All files uploaded
instance.publishState('bubble', uploadedFiles);
instance.triggerEvent('saved'); // Trigger save event
} catch (err) {
console.error("File upload error:", err);
}
}
// Start uploading
uploadAllFiles();
} else {
console.warn("No files to upload.");
}
}
Just want to specify that I am using blobs for getting the metadata of the file and in this code I am converting them to file object because the uploadfile function accepts file objects.
Would be great if I could get any help on this issue.
Thanks in advance.