Spaces:
Running
Running
File size: 6,590 Bytes
340e1b6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | document.addEventListener('DOMContentLoaded', function() {
// DOM Elements
const videoUrlInput = document.getElementById('videoUrl');
const pasteBtn = document.getElementById('pasteBtn');
const downloadBtn = document.getElementById('downloadBtn');
const videoPreviewSection = document.getElementById('videoPreview');
const videoThumbnail = document.getElementById('videoThumbnail');
const videoTitle = document.getElementById('videoTitle');
const videoDuration = document.getElementById('videoDuration');
const qualitySelect = document.getElementById('qualitySelect');
const formatSelect = document.getElementById('formatSelect');
const downloadFinalBtn = document.getElementById('downloadFinalBtn');
const convertBtn = document.getElementById('convertBtn');
const recentDownloads = document.getElementById('recentDownloads');
// Event Listeners
pasteBtn.addEventListener('click', handlePaste);
downloadBtn.addEventListener('click', handleDownload);
downloadFinalBtn.addEventListener('click', handleFinalDownload);
convertBtn.addEventListener('click', handleConvertToMP3);
// Functions
function handlePaste() {
navigator.clipboard.readText()
.then(text => {
videoUrlInput.value = text;
})
.catch(err => {
console.error('Failed to read clipboard contents: ', err);
});
}
function handleDownload() {
const url = videoUrlInput.value.trim();
if (!url) {
showAlert('Please enter a valid video URL', 'error');
return;
}
// Show loading state
downloadBtn.disabled = true;
downloadBtn.innerHTML = '<span class="spinner inline-block w-5 h-5 border-2 border-white border-t-transparent rounded-full mr-2"></span> Analyzing...';
// Simulate API call (in a real app, this would be a fetch to your backend)
setTimeout(() => {
// Mock response
const mockResponse = {
success: true,
thumbnail: 'http://static.photos/technology/640x360/1',
title: 'Sample Video Title',
duration: '5:30',
availableQualities: ['360', '720', '1080']
};
if (mockResponse.success) {
// Populate video info
videoThumbnail.src = mockResponse.thumbnail;
videoTitle.textContent = mockResponse.title;
videoDuration.textContent = `Duration: ${mockResponse.duration}`;
// Show the preview section
videoPreviewSection.classList.remove('hidden');
// Scroll to preview
videoPreviewSection.scrollIntoView({ behavior: 'smooth' });
// Add to recent downloads (simplified)
addToRecentDownloads(mockResponse.title, url);
} else {
showAlert('Failed to analyze the video URL. Please check if it\'s valid and try again.', 'error');
}
// Reset button
downloadBtn.disabled = false;
downloadBtn.innerHTML = '<i data-feather="download"></i><span>Analyze & Download</span>';
feather.replace();
}, 1500);
}
function handleFinalDownload() {
const url = videoUrlInput.value.trim();
const quality = qualitySelect.value;
const format = formatSelect.value;
showAlert(`Preparing ${quality}p ${format.toUpperCase()} download...`, 'success');
// In a real app, this would redirect to your backend download endpoint
console.log(`Downloading: ${url} at ${quality}p as ${format}`);
}
function handleConvertToMP3() {
const url = videoUrlInput.value.trim();
showAlert('Converting to MP3...', 'success');
// In a real app, this would redirect to your backend conversion endpoint
console.log(`Converting to MP3: ${url}`);
}
function addToRecentDownloads(title, url) {
// Simplified - in a real app you would save this to localStorage or a database
const downloadItem = document.createElement('div');
downloadItem.className = 'flex items-center justify-between p-3 bg-gray-100 dark:bg-gray-700 rounded-lg';
downloadItem.innerHTML = `
<div class="flex items-center gap-3">
<div class="w-12 h-12 bg-gray-300 dark:bg-gray-600 rounded-lg overflow-hidden">
<img src="${videoThumbnail.src}" alt="${title}" class="w-full h-full object-cover">
</div>
<div>
<h4 class="font-medium text-gray-900 dark:text-white line-clamp-1">${title}</h4>
<p class="text-sm text-gray-500 dark:text-gray-400">${new Date().toLocaleDateString()}</p>
</div>
</div>
<button class="text-primary hover:text-primary/80 dark:text-secondary dark:hover:text-secondary/80 transition-colors">
<i data-feather="download"></i>
</button>
`;
// If it's the first item, remove the placeholder
if (recentDownloads.children.length === 1 && recentDownloads.children[0].classList.contains('text-center')) {
recentDownloads.innerHTML = '';
}
recentDownloads.prepend(downloadItem);
feather.replace();
}
function showAlert(message, type) {
const alert = document.createElement('div');
alert.className = `fixed top-4 right-4 px-6 py-3 rounded-lg shadow-lg text-white font-medium z-50 transition-all duration-300 transform translate-x-full ${type === 'error' ? 'bg-red-500' : 'bg-green-500'}`;
alert.textContent = message;
document.body.appendChild(alert);
setTimeout(() => {
alert.classList.remove('translate-x-full');
alert.classList.add('translate-x-0');
}, 10);
setTimeout(() => {
alert.classList.remove('translate-x-0');
alert.classList.add('translate-x-full');
setTimeout(() => {
alert.remove();
}, 300);
}, 3000);
}
// Initialize theme from localStorage
if (localStorage.getItem('theme') === 'dark' || (!localStorage.getItem('theme') && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark');
}
}); |