This commit is contained in:
retoor 2025-11-09 00:52:26 +01:00
parent c6fb77c89d
commit 9e9907bc00
2 changed files with 166 additions and 0 deletions

View File

@ -0,0 +1,116 @@
export function showUploadModal() {
document.getElementById('upload-modal').style.display = 'block';
// Clear previous selections and progress
document.getElementById('selected-files-preview').innerHTML = '';
document.getElementById('upload-progress-container').innerHTML = '';
document.getElementById('file-input-multiple').value = ''; // Clear selected files
document.getElementById('start-upload-btn').disabled = true;
}
document.addEventListener('DOMContentLoaded', () => {
const fileInput = document.getElementById('file-input-multiple');
const selectedFilesPreview = document.getElementById('selected-files-preview');
const startUploadBtn = document.getElementById('start-upload-btn');
const uploadProgressContainer = document.getElementById('upload-progress-container');
let filesToUpload = [];
fileInput.addEventListener('change', (event) => {
filesToUpload = Array.from(event.target.files);
selectedFilesPreview.innerHTML = ''; // Clear previous previews
uploadProgressContainer.innerHTML = ''; // Clear previous progress bars
if (filesToUpload.length > 0) {
startUploadBtn.disabled = false;
filesToUpload.forEach(file => {
const fileEntry = document.createElement('div');
fileEntry.className = 'file-entry';
fileEntry.innerHTML = `
<span class="file-name">${file.name}</span>
<span class="file-size">(${(file.size / 1024 / 1024).toFixed(2)} MB)</span>
<div class="thumbnail-preview"></div>
`;
selectedFilesPreview.appendChild(fileEntry);
// Display thumbnail for image files
if (file.type.startsWith('image/')) {
const reader = new FileReader();
reader.onload = (e) => {
const img = document.createElement('img');
img.src = e.target.result;
fileEntry.querySelector('.thumbnail-preview').appendChild(img);
};
reader.readAsDataURL(file);
}
});
} else {
startUploadBtn.disabled = true;
}
});
startUploadBtn.addEventListener('click', () => {
if (filesToUpload.length > 0) {
uploadFiles(filesToUpload);
}
});
async function uploadFiles(files) {
startUploadBtn.disabled = true; // Disable button during upload
uploadProgressContainer.innerHTML = ''; // Clear previous progress
const currentPath = new URLSearchParams(window.location.search).get('path') || '';
for (const file of files) {
const formData = new FormData();
formData.append('file', file);
const progressBarContainer = document.createElement('div');
progressBarContainer.className = 'progress-bar-container';
progressBarContainer.innerHTML = `
<div class="file-name">${file.name}</div>
<div class="progress-bar-wrapper">
<div class="progress-bar" id="progress-${file.name.replace(/\./g, '-')}" style="width: 0%;"></div>
</div>
<div class="progress-text" id="progress-text-${file.name.replace(/\./g, '-')}" >0%</div>
`;
uploadProgressContainer.appendChild(progressBarContainer);
const xhr = new XMLHttpRequest();
xhr.open('POST', `/files/upload?current_path=${encodeURIComponent(currentPath)}`, true);
xhr.upload.addEventListener('progress', (event) => {
if (event.lengthComputable) {
const percent = (event.loaded / event.total) * 100;
document.getElementById(`progress-${file.name.replace(/\./g, '-')}`).style.width = `${percent}%`;
document.getElementById(`progress-text-${file.name.replace(/\./g, '-')}`).textContent = `${Math.round(percent)}%`;
}
});
xhr.addEventListener('load', () => {
if (xhr.status === 200) {
console.log(`File ${file.name} uploaded successfully.`);
// Update progress to 100% on completion
document.getElementById(`progress-${file.name.replace(/\./g, '-')}`).style.width = `100%`;
document.getElementById(`progress-text-${file.name.replace(/\./g, '-')}`).textContent = `100% (Done)`;
} else {
console.error(`Error uploading ${file.name}: ${xhr.statusText}`);
document.getElementById(`progress-text-${file.name.replace(/\./g, '-')}`).textContent = `Failed (${xhr.status})`;
document.getElementById(`progress-${file.name.replace(/\./g, '-')}`).style.backgroundColor = `red`;
}
});
xhr.addEventListener('error', () => {
console.error(`Network error uploading ${file.name}.`);
document.getElementById(`progress-text-${file.name.replace(/\./g, '-')}`).textContent = `Network Error`;
document.getElementById(`progress-${file.name.replace(/\./g, '-')}`).style.backgroundColor = `red`;
});
xhr.send(formData);
}
// After all files are sent, refresh the page to show new files
// A small delay to allow server to process and update file list
setTimeout(() => {
window.location.reload();
}, 1000);
}
});

50
retoors/views/upload.py Normal file
View File

@ -0,0 +1,50 @@
from aiohttp import web
import aiohttp_jinja2
from aiohttp.web_response import json_response
from ..helpers.auth import login_required
class UploadView(web.View):
@login_required
async def post(self):
user_email = self.request["user"]["email"]
file_service = self.request.app["file_service"]
# Get current path from query parameter or form data
current_path = self.request.query.get("current_path", "")
try:
reader = await self.request.multipart()
files_uploaded = []
errors = []
while True:
field = await reader.next()
if field is None:
break
# Check if the field is a file input
if field.name == "file": # Assuming the input field name is 'file'
filename = field.filename
if not filename:
errors.append("Filename is required for one of the files.")
continue
content = await field.read()
# Construct the full file path relative to the user's base directory
full_file_path_for_service = f"{current_path}/{filename}" if current_path else filename
success = await file_service.upload_file(user_email, full_file_path_for_service, content)
if success:
files_uploaded.append(filename)
else:
errors.append(f"Failed to upload file '{filename}'")
if errors:
return json_response({"status": "error", "message": "Some files failed to upload", "details": errors}, status=500)
elif files_uploaded:
return json_response({"status": "success", "message": f"Successfully uploaded {len(files_uploaded)} files", "files": files_uploaded})
else:
return json_response({"status": "error", "message": "No files were uploaded"}, status=400)
except Exception as e:
return json_response({"status": "error", "message": f"Upload error: {str(e)}"}, status=500)