Searching...
'; const items = await fetchFeedBatch(); const loadingEl = container.querySelector('.feed-loading'); if (loadingEl) loadingEl.remove(); await renderHome({ items }, false); showTab('home'); document.getElementById('searchInput').value = q; } // ==================== LOGIN MODAL ==================== function openLoginModal() { document.getElementById('modalOverlay').classList.remove('hidden'); document.getElementById('modalEmail').value = ''; document.getElementById('modalPassword').value = ''; document.getElementById('modalName').value = ''; document.getElementById('modalColor').value = '#cc0000'; document.getElementById('emailError').classList.remove('show'); document.getElementById('passError').classList.remove('show'); document.getElementById('modalEmail').classList.remove('error'); document.getElementById('modalPassword').classList.remove('error'); document.getElementById('nameGroup').style.display = 'none'; document.getElementById('colorGroup').style.display = 'none'; document.getElementById('switchMode').style.display = 'block'; document.getElementById('switchMode').textContent = 'Create account'; document.getElementById('modalTitle').textContent = 'Sign in'; document.getElementById('modalSubtitle').textContent = 'to continue to YouTubePC'; document.getElementById('modalSave').textContent = 'Sign In'; state.isSignUp = false; } function validateEmail(email) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); } function handleLogin() { const email = document.getElementById('modalEmail').value.trim(); const password = document.getElementById('modalPassword').value.trim(); const name = document.getElementById('modalName').value.trim(); const color = document.getElementById('modalColor').value; let valid = true; if (!email || !validateEmail(email)) { document.getElementById('emailError').classList.add('show'); document.getElementById('modalEmail').classList.add('error'); valid = false; } else { document.getElementById('emailError').classList.remove('show'); document.getElementById('modalEmail').classList.remove('error'); } if (!password || password.length < 6) { document.getElementById('passError').classList.add('show'); document.getElementById('modalPassword').classList.add('error'); valid = false; } else { document.getElementById('passError').classList.remove('show'); document.getElementById('modalPassword').classList.remove('error'); } if (!valid) return; // Save user state.user = { email: email, name: name || email.split('@')[0], color: color, password: password }; saveUser(); document.getElementById('modalOverlay').classList.add('hidden'); updateUI(); openInterestModal(); } function handleSignUp() { const email = document.getElementById('modalEmail').value.trim(); const password = document.getElementById('modalPassword').value.trim(); const name = document.getElementById('modalName').value.trim(); const color = document.getElementById('modalColor').value; let valid = true; if (!email || !validateEmail(email)) { document.getElementById('emailError').classList.add('show'); document.getElementById('modalEmail').classList.add('error'); valid = false; } else { document.getElementById('emailError').classList.remove('show'); document.getElementById('modalEmail').classList.remove('error'); } if (!password || password.length < 6) { document.getElementById('passError').classList.add('show'); document.getElementById('modalPassword').classList.add('error'); valid = false; } else { document.getElementById('passError').classList.remove('show'); document.getElementById('modalPassword').classList.remove('error'); } if (!valid) return; // Save user state.user = { email: email, name: name || email.split('@')[0], color: color, password: password }; saveUser(); document.getElementById('modalOverlay').classList.add('hidden'); updateUI(); openInterestModal(); } // ==================== UI ==================== function updateUI() { const signin = document.getElementById('signinBtn'); const avatar = document.getElementById('avatarBtn'); if (state.user) { signin.style.display = 'none'; avatar.style.display = 'flex'; document.getElementById('avatarText').textContent = state.user.name[0].toUpperCase(); avatar.style.background = state.user.color; } else { signin.style.display = 'flex'; avatar.style.display = 'none'; } if (state.settings.theme === 'light') { document.body.classList.add('light'); } else { document.body.classList.remove('light'); } } // ==================== EVENTS ==================== document.addEventListener('DOMContentLoaded', () => { // Bottom Navigation document.querySelectorAll('.bottom-btn').forEach(el => { el.onclick = () => { const tab = el.dataset.tab; if (tab === 'home') { if (state.query) performSearch(state.query); else buildHomeFeed(); } else if (tab === 'shorts') renderShorts(); else if (tab === 'trending') renderTrending(); else if (tab === 'watchlater') renderWatchLater(); else if (tab === 'history') renderHistory(); else if (tab === 'settings') renderSettings(); showTab(tab); }; }); // Logo document.getElementById('logoLink').onclick = (e) => { e.preventDefault(); state.query = ''; document.getElementById('searchInput').value = ''; buildHomeFeed(); showTab('home'); }; // Search document.getElementById('searchBtn').onclick = () => { const q = document.getElementById('searchInput').value.trim(); if (q) performSearch(q); }; document.getElementById('searchInput').onkeyup = (e) => { if (e.key === 'Enter') { const q = document.getElementById('searchInput').value.trim(); if (q) performSearch(q); } }; // Hamburger - toggle ads document.getElementById('hamburger').onclick = () => { document.querySelectorAll('.ad-left, .ad-right').forEach(el => { el.style.display = el.style.display === 'none' ? '' : 'none'; }); }; // Sign in - Real Gmail style document.getElementById('signinBtn').onclick = openLoginModal; document.getElementById('modalClose').onclick = () => { document.getElementById('modalOverlay').classList.add('hidden'); }; document.getElementById('modalSave').onclick = () => { if (state.isSignUp) { handleSignUp(); } else { handleLogin(); } }; // Switch between Sign In and Sign Up document.getElementById('switchMode').onclick = function() { state.isSignUp = !state.isSignUp; if (state.isSignUp) { this.textContent = 'Sign in instead'; document.getElementById('modalTitle').textContent = 'Create account'; document.getElementById('modalSubtitle').textContent = 'to continue to YouTubePC'; document.getElementById('modalSave').textContent = 'Sign Up'; document.getElementById('nameGroup').style.display = 'block'; document.getElementById('colorGroup').style.display = 'flex'; } else { this.textContent = 'Create account'; document.getElementById('modalTitle').textContent = 'Sign in'; document.getElementById('modalSubtitle').textContent = 'to continue to YouTubePC'; document.getElementById('modalSave').textContent = 'Sign In'; document.getElementById('nameGroup').style.display = 'none'; document.getElementById('colorGroup').style.display = 'none'; } }; // Enter key on modal document.getElementById('modalPassword').onkeyup = (e) => { if (e.key === 'Enter') { if (state.isSignUp) { handleSignUp(); } else { handleLogin(); } } }; // Avatar document.getElementById('avatarBtn').onclick = (e) => { document.getElementById('avatarDropdown').classList.toggle('show'); e.stopPropagation(); }; document.onclick = () => { document.getElementById('avatarDropdown').classList.remove('show'); }; document.querySelectorAll('#avatarDropdown .item').forEach(el => { el.onclick = () => { const action = el.dataset.action; if (action === 'history') renderHistory(); else if (action === 'watchlater') renderWatchLater(); else if (action === 'settings') renderSettings(); else if (action === 'signout') { state.user = null; saveUser(); updateUI(); buildHomeFeed(); } document.getElementById('avatarDropdown').classList.remove('show'); }; }); // Notification document.getElementById('notifBtn').onclick = () => { alert('No new notifications'); }; // Fullscreen document.addEventListener('fullscreenchange', () => { state.fullscreen = !!document.fullscreenElement; toggleAds(state.fullscreen); }); // Mini player document.getElementById('miniClose').onclick = closeMini; // Voice initVoice(); // Load YouTube API const script = document.createElement('script'); script.src = 'https://www.youtube.com/iframe_api'; document.head.appendChild(script); // Infinite scroll - automatically loads more of the home feed as user scrolls down document.getElementById('contentArea').addEventListener('scroll', () => { if (state.currentTab !== 'home') return; const el = document.getElementById('contentArea'); if (el.scrollTop + el.clientHeight >= el.scrollHeight - 600) { loadMoreFeed(); } }); // Initial load - launch ads play first (if configured), then the app loads updateUI(); playLaunchAds(() => { buildHomeFeed(); showTab('home'); }); }); window.onYouTubeIframeAPIReady = function() { console.log('YouTube API ready'); }; console.log('YouTubePC - Real Gmail login, bottom navigation, working buttons');