fixing upload
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -36,15 +36,16 @@
|
||||
<div class="form-section">
|
||||
<label>Video File <span class="required">*</span></label>
|
||||
<div class="drop-zone" id="drop-zone">
|
||||
<input type="file" id="file-input" name="file" accept="video/mp4,video/webm" required>
|
||||
<div class="drop-zone-prompt">
|
||||
<input type="file" id="file-input" name="file" accept="video/mp4,video/webm" style="display: none;">
|
||||
<label for="file-input" class="drop-zone-prompt"
|
||||
style="cursor: pointer; display: block; width: 100%; height: 100%;">
|
||||
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
|
||||
<polyline points="17 8 12 3 7 8"></polyline>
|
||||
<line x1="12" y1="3" x2="12" y2="15"></line>
|
||||
</svg>
|
||||
<p>Drop your mp4 or webm here<br>or click to browse</p>
|
||||
</div>
|
||||
</label>
|
||||
<div class="file-preview" id="file-preview" style="display: none;">
|
||||
<span class="file-name" id="file-name"></span>
|
||||
<span class="file-size" id="file-size"></span>
|
||||
@@ -104,9 +105,7 @@
|
||||
|
||||
<style>
|
||||
.upload-container {
|
||||
max-width: 700px;
|
||||
margin: 2rem auto;
|
||||
padding: 2rem;
|
||||
margin: 0px 25px 0px 25px
|
||||
}
|
||||
|
||||
.upload-container h2 {
|
||||
|
||||
Reference in New Issue
Block a user