1
0
forked from w0bm/f0bm

fixing upload

This commit is contained in:
x
2026-01-24 01:28:14 +01:00
parent c822a4f4e7
commit 43da214f73
2 changed files with 108 additions and 23 deletions

View File

@@ -5,6 +5,7 @@
const fileInput = document.getElementById('file-input');
const dropZone = document.getElementById('drop-zone');
const filePreview = document.getElementById('file-preview');
// Note: prompt is now a label, but accessible via class
const dropZonePrompt = dropZone.querySelector('.drop-zone-prompt');
const fileName = document.getElementById('file-name');
const fileSize = document.getElementById('file-size');
@@ -23,6 +24,43 @@
let tags = [];
let selectedFile = null;
// Flash Message Logic
const showFlash = (msg, type = 'success') => {
const existing = document.querySelector('.flash-message');
if (existing) existing.remove();
const flash = document.createElement('div');
flash.className = `flash-message ${type}`;
flash.textContent = msg;
Object.assign(flash.style, {
position: 'fixed',
top: '20px',
left: '50%',
transform: 'translateX(-50%)',
padding: '15px 30px',
borderRadius: '5px',
color: '#fff',
fontWeight: '600',
zIndex: '9999',
boxShadow: '0 4px 12px rgba(0,0,0,0.3)',
background: type === 'success' ? '#51cf66' : '#ff6b6b',
opacity: '0',
transition: 'opacity 0.3s'
});
document.body.appendChild(flash);
// Fade in
requestAnimationFrame(() => flash.style.opacity = '1');
// Remove after 5s
setTimeout(() => {
flash.style.opacity = '0';
setTimeout(() => flash.remove(), 300);
}, 5000);
};
const formatSize = (bytes) => {
const units = ['B', 'KB', 'MB', 'GB'];
let i = 0;
@@ -59,7 +97,11 @@
if (!file) return;
const validTypes = ['video/mp4', 'video/webm'];
if (!validTypes.includes(file.type)) {
// Check extensions as fallback
const ext = file.name.split('.').pop().toLowerCase();
const validExts = ['mp4', 'webm'];
if (!validTypes.includes(file.type) && !validExts.includes(ext)) {
statusDiv.textContent = 'Only mp4 and webm files are allowed';
statusDiv.className = 'upload-status error';
return;
@@ -72,9 +114,56 @@
filePreview.style.display = 'flex';
statusDiv.textContent = '';
statusDiv.className = 'upload-status';
// Video Preview
const itemPreview = filePreview.querySelector('.item-preview') || document.createElement('div');
itemPreview.className = 'item-preview';
itemPreview.style.marginRight = '15px';
// Clear previous
const existingVid = filePreview.querySelector('video');
if (existingVid) existingVid.remove();
const vid = document.createElement('video');
vid.src = URL.createObjectURL(file);
vid.controls = false;
vid.autoplay = true;
vid.muted = true;
vid.loop = true;
vid.style.maxHeight = '100px';
vid.style.maxWidth = '150px';
vid.style.borderRadius = '4px';
filePreview.prepend(vid);
updateSubmitButton();
};
const preventDefaults = (e) => {
e.preventDefault();
e.stopPropagation();
};
// Attach drag events only to dropZone now (Input is hidden)
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
dropZone.addEventListener(eventName, preventDefaults, false);
});
['dragenter', 'dragover'].forEach(eventName => {
dropZone.addEventListener(eventName, () => dropZone.classList.add('dragover'), false);
});
['dragleave', 'drop'].forEach(eventName => {
dropZone.addEventListener(eventName, () => dropZone.classList.remove('dragover'), false);
});
dropZone.addEventListener('drop', (e) => {
const dt = e.dataTransfer;
const files = dt.files;
handleFile(files[0]);
});
// Native change listener on hidden input
fileInput.addEventListener('change', (e) => handleFile(e.target.files[0]));
removeFile.addEventListener('click', (e) => {
@@ -84,24 +173,13 @@
fileInput.value = '';
dropZonePrompt.style.display = 'block';
filePreview.style.display = 'none';
// Clear preview video
const vid = filePreview.querySelector('video');
if (vid) vid.remove();
updateSubmitButton();
});
dropZone.addEventListener('dragover', (e) => {
e.preventDefault();
dropZone.classList.add('dragover');
});
dropZone.addEventListener('dragleave', () => {
dropZone.classList.remove('dragover');
});
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
dropZone.classList.remove('dragover');
handleFile(e.dataTransfer.files[0]);
});
const addTag = (tagName) => {
tagName = tagName.trim().toLowerCase();
if (!tagName || tags.includes(tagName)) return;
@@ -215,18 +293,24 @@
if (res.success) {
statusDiv.innerHTML = '✓ ' + res.msg;
statusDiv.className = 'upload-status success';
// Flash Message
showFlash(res.msg, 'success');
form.reset();
tags = [];
tagsList.innerHTML = '';
selectedFile = null;
dropZonePrompt.style.display = 'block';
dropZonePrompt.style.display = 'block'; // label is actually flex/block via CSS
filePreview.style.display = 'none';
const vid = filePreview.querySelector('video');
if (vid) vid.remove();
} else {
statusDiv.textContent = '✕ ' + res.msg;
statusDiv.className = 'upload-status error';
if (res.repost) {
statusDiv.innerHTML += ' <a href="/' + res.repost + '">View existing</a>';
}
showFlash('Upload failed: ' + res.msg, 'error');
}
submitBtn.querySelector('.btn-text').style.display = 'inline';
@@ -239,6 +323,7 @@
xhr.onerror = () => {
statusDiv.textContent = '✕ Upload failed. Please try again.';
statusDiv.className = 'upload-status error';
showFlash('Upload failed network error', 'error');
submitBtn.querySelector('.btn-text').style.display = 'inline';
submitBtn.querySelector('.btn-loading').style.display = 'none';
progressContainer.style.display = 'none';
@@ -252,6 +337,7 @@
console.error(err);
statusDiv.textContent = '✕ Upload failed: ' + err.message;
statusDiv.className = 'upload-status error';
showFlash('Upload failed: ' + err.message, 'error');
submitBtn.querySelector('.btn-text').style.display = 'inline';
submitBtn.querySelector('.btn-loading').style.display = 'none';
updateSubmitButton();