// Firebase Configuration const firebaseConfig = { apiKey: "YOUR_API_KEY", authDomain: "YOUR_PROJECT_ID.firebaseapp.com", databaseURL: "https://YOUR_PROJECT_ID-default-rtdb.firebaseio.com", projectId: "YOUR_PROJECT_ID", storageBucket: "YOUR_PROJECT_ID.appspot.com", messagingSenderId: "YOUR_SENDER_ID", appId: "YOUR_APP_ID" }; // Initialize Firebase firebase.initializeApp(firebaseConfig); const storage = firebase.storage(); const database = firebase.database(); // App State let selectedFile = null; // DOM Elements const app = document.getElementById('app'); const toast = document.getElementById('toast'); const progressModal = document.getElementById('progressModal'); const uploadProgress = document.getElementById('uploadProgress'); const progressText = document.getElementById('progressText'); // Hash Router const routes = { '/': renderUploadPage, '/files': renderFilesPage, '/file/:id': renderDownloadPage }; // Initialize App document.addEventListener('DOMContentLoaded', () => { handleRoute(); window.addEventListener('hashchange', handleRoute); document.getElementById('homeLink').addEventListener('click', () => { window.location.hash = '#/'; }); }); function handleRoute() { const hash = window.location.hash.slice(1) || '/'; const path = hash.split('?')[0]; document.querySelectorAll('.nav-link').forEach(link => { const route = link.dataset.route; link.classList.toggle('active', path === route); }); if (path.startsWith('/file/')) { const id = path.split('/')[2]; renderDownloadPage(id); } else if (routes[path]) { routes[path](); } else { routes['/'](); } } // Utility Functions function showToast(message, type = 'info') { toast.textContent = message; toast.className = `toast show ${type}`; setTimeout(() => { toast.classList.remove('show'); }, 3000); } function formatBytes(bytes) { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; } function generateShortId() { return Math.random().toString(36).substring(2, 8) + Math.random().toString(36).substring(2, 8); } // Render Upload Page function renderUploadPage() { const html = `
Drop files anywhere
or click to select
`; app.innerHTML = html; initializeUploadPage(); } function initializeUploadPage() { const dropZone = document.getElementById('dropZone'); const fileInput = document.getElementById('fileInput'); const selectFileBtn = document.getElementById('selectFileBtn'); const uploadBtn = document.getElementById('uploadBtn'); const selectedFileContainer = document.getElementById('selectedFileContainer'); const selectedFileName = document.getElementById('selectedFileName'); const selectedFileSize = document.getElementById('selectedFileSize'); dropZone.addEventListener('click', () => fileInput.click()); 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'); const file = e.dataTransfer.files[0]; if (file) handleFileSelect(file); }); fileInput.addEventListener('change', (e) => { const file = e.target.files[0]; if (file) handleFileSelect(file); }); selectFileBtn.addEventListener('click', () => fileInput.click()); uploadBtn.addEventListener('click', () => { if (!selectedFile) { showToast('Please select a file first', 'error'); return; } uploadFile(selectedFile); }); function handleFileSelect(file) { selectedFile = file; selectedFileName.textContent = file.name; selectedFileSize.textContent = formatBytes(file.size); selectedFileContainer.style.display = 'block'; } } // Upload File (No auth required) async function uploadFile(file) { const shortId = generateShortId(); const timestamp = Date.now(); const safeFileName = file.name.replace(/[^a-zA-Z0-9.-]/g, '_'); const storageRef = storage.ref(`uploads/${timestamp}_${safeFileName}`); const uploadTask = storageRef.put(file); progressModal.style.display = 'block'; uploadTask.on('state_changed', (snapshot) => { const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100; uploadProgress.style.width = progress + '%'; progressText.textContent = Math.round(progress) + '%'; }, (error) => { console.error('Upload error:', error); progressModal.style.display = 'none'; showToast('Upload failed. Please try again.', 'error'); }, async () => { try { const downloadURL = await uploadTask.snapshot.ref.getDownloadURL(); // Save file info to Realtime Database (no user data) const fileData = { id: shortId, name: file.name, size: file.size, type: file.type || 'application/octet-stream', url: downloadURL, shortId: shortId, timestamp: timestamp, downloads: 0, storagePath: `uploads/${timestamp}_${safeFileName}` }; await database.ref(`files/${shortId}`).set(fileData); // Also add to public file list for easy browsing await database.ref(`public-files/${shortId}`).set({ id: shortId, name: file.name, timestamp: timestamp }); progressModal.style.display = 'none'; uploadProgress.style.width = '0%'; const fileUrl = `${window.location.origin}${window.location.pathname}#/file/${shortId}`; showToast('File uploaded successfully!', 'success'); // Ask user if they want to copy link if (confirm('File uploaded! Copy link to clipboard?')) { navigator.clipboard.writeText(fileUrl); showToast('Link copied to clipboard!', 'success'); } // Reset UI selectedFile = null; document.getElementById('selectedFileContainer').style.display = 'none'; document.getElementById('fileInput').value = ''; } catch (error) { console.error('Database error:', error); progressModal.style.display = 'none'; showToast('Error saving file info', 'error'); } } ); } // Render Files Page (Public files - no auth needed) async function renderFilesPage() { app.innerHTML = '
Loading files...
'; try { // Get all public files const filesSnapshot = await database.ref('files').once('value'); const filesData = filesSnapshot.val() || {}; const files = Object.values(filesData) .sort((a, b) => b.timestamp - a.timestamp) .slice(0, 50); // Show only 50 most recent files if (files.length === 0) { app.innerHTML = `

Recent Files

No files uploaded yet

Upload your first file
`; return; } const filesHtml = `

Recent Files

${files.length} files
${files.map(file => `
${file.name}
Size ${formatBytes(file.size)}
Downloads ${file.downloads || 0}
Uploaded ${new Date(file.timestamp).toLocaleDateString()}
View
`).join('')}
`; app.innerHTML = filesHtml; } catch (error) { console.error('Error loading files:', error); app.innerHTML = `

Error loading files. Please try again.

`; } } // Copy link function (global) window.copyLink = async function(shortId) { const link = `${window.location.origin}${window.location.pathname}#/file/${shortId}`; try { await navigator.clipboard.writeText(link); showToast('Link copied to clipboard!', 'success'); } catch (err) { // Fallback for older browsers const textarea = document.createElement('textarea'); textarea.value = link; document.body.appendChild(textarea); textarea.select(); document.execCommand('copy'); document.body.removeChild(textarea); showToast('Link copied to clipboard!', 'success'); } }; // Render Download Page async function renderDownloadPage(fileId) { app.innerHTML = '
Loading file info...
'; try { const fileSnapshot = await database.ref(`files/${fileId}`).once('value'); const fileData = fileSnapshot.val(); if (!fileData) { app.innerHTML = `

File not found or has been removed

Go Home
`; return; } // Increment download count await database.ref(`files/${fileId}/downloads`).transaction(count => (count || 0) + 1); const html = `

${fileData.name}

Size ${formatBytes(fileData.size)}
Type ${fileData.type || 'Unknown'}
Uploaded ${new Date(fileData.timestamp).toLocaleString()}
Downloads ${(fileData.downloads || 0) + 1}
Download File
`; app.innerHTML = html; } catch (error) { console.error('Error loading file:', error); app.innerHTML = `

Error loading file. Please try again.

Go Home
`; } }