feat: improve batch ID handling for file and folder uploads

- Update server-side upload initialization to always refresh batch activity timestamp
- Enhance client-side file grouping to consistently track batch IDs for files and folders
- Modify drop and file selection handlers to generate batch IDs for all upload scenarios
- Ensure batch ID is preserved and used consistently across file upload groups
This commit is contained in:
Greirson Lee-Thorp
2025-02-03 17:37:33 -08:00
parent 79f6c53871
commit bcc555939b
2 changed files with 26 additions and 8 deletions

View File

@@ -216,10 +216,16 @@
name: folderName,
isFolder: true,
totalSize: 0,
files: []
files: [],
// Use the first file's batch ID or generate a new one
batchId: file.batchId
});
}
const group = groups.get(folderName);
// If group doesn't have a batch ID yet, use the file's batch ID
if (!group.batchId) {
group.batchId = file.batchId;
}
group.files.push(file);
group.totalSize += file.size;
} else {
@@ -228,7 +234,8 @@
name: file.name,
isFolder: false,
totalSize: file.size,
files: [file]
files: [file],
batchId: file.batchId
});
}
});
@@ -245,7 +252,7 @@
if (entry.isFile) {
const file = await new Promise((resolve) => entry.file(resolve));
file.relativePath = path;
file.batchId = batchId;
file.batchId = batchId; // Use the same batch ID for all files in this drop
fileEntries.push(file);
} else if (entry.isDirectory) {
const reader = entry.createReader();
@@ -304,20 +311,29 @@
function handleDrop(e) {
const items = e.dataTransfer.items;
if (items && items[0].webkitGetAsEntry) {
// Handle folder/file drop using DataTransferItemList
getAllFileEntries(items).then(newFiles => {
files = newFiles;
updateFileList();
});
} else {
// Handle single file drop
const batchId = generateBatchId();
files = [...e.dataTransfer.files];
files.forEach(file => {
file.relativePath = ''; // No relative path for dropped files
file.batchId = batchId;
});
updateFileList();
}
}
function handleFiles(e) {
const batchId = generateBatchId();
files = [...e.target.files];
files.forEach(file => {
file.relativePath = ''; // No relative path for individual files
file.batchId = batchId;
});
updateFileList();
}
@@ -367,13 +383,15 @@
document.getElementById('uploadProgress').innerHTML = '';
const groupedItems = groupFilesByFolder(files);
const batchId = generateBatchId(); // Generate a single batch ID for all files
const results = await Promise.all(
groupedItems.map(async item => {
let success = true;
// Use the group's batch ID for all files in the group
const groupBatchId = item.batchId || generateBatchId();
for (const file of item.files) {
const uploader = new FileUploader(file, batchId);
// Always use the group's batch ID
const uploader = new FileUploader(file, groupBatchId);
if (!await uploader.start()) {
success = false;
}

View File

@@ -315,6 +315,9 @@ app.post('/upload/init', async (req, res) => {
return res.status(400).json({ error: 'Invalid batch ID format' });
}
// Always update batch activity timestamp for any upload
batchActivity.set(batchId, Date.now());
const safeFilename = path.normalize(filename).replace(/^(\.\.(\/|\\|$))+/, '');
// Check file size limit
@@ -360,9 +363,6 @@ app.post('/upload/init', async (req, res) => {
}
folderMappings.set(`${originalFolderName}-${batchId}`, newFolderName);
// Update batch activity timestamp instead of setting a timeout
batchActivity.set(batchId, Date.now());
}
// Replace the original folder path with the mapped one and keep original file name