Spaces:
Sleeping
Sleeping
| // === HOMEPAGE LIVE MODE === | |
| // ALL sections show ● LIVE badge and auto-refresh without page reload | |
| // Livescore: 60s, Featured: 60s, Shorts: 5min, Hashtag: 3min, Highlights: 5min | |
| let _liveInterval = null; | |
| let _liveTick = 0; | |
| function startHomepageLive() { | |
| if (_liveInterval) clearInterval(_liveInterval); | |
| // Add LIVE badges to all section headers | |
| setTimeout(addLiveBadges, 2000); | |
| _liveInterval = setInterval(async () => { | |
| if (!document.getElementById('view-home')?.classList.contains('active')) return; | |
| _liveTick++; | |
| // === Livescore: every 60s === | |
| const lsTab = document.querySelector('.ls-tab.active'); | |
| if (lsTab && lsTab.dataset.tab) loadLivescore(lsTab.dataset.tab); | |
| // === Featured match: every 60s === | |
| try { | |
| const f = await fetch('/api/livescore/featured').then(r => r.json()).catch(() => null); | |
| if (f && f.home) { | |
| const el = document.querySelector('.featured-match'); | |
| if (el) { | |
| const sc = f.status === 'live' ? '' : 'upcoming'; | |
| const st = f.status === 'live' ? `🔴 ${f.minute || 'LIVE'}` : `⏰ ${f.time}`; | |
| el.innerHTML = `<div class="fm-league">${f.league}</div><div class="fm-teams"><div class="fm-team"><img src="${f.home_logo}" onerror="this.style.display='none'"><span>${f.home}</span></div><div class="fm-score">${f.score || 'VS'}</div><div class="fm-team"><img src="${f.away_logo}" onerror="this.style.display='none'"><span>${f.away}</span></div></div><div class="fm-status ${sc}">${st}</div>`; | |
| } | |
| } | |
| } catch(e) {} | |
| // === Hashtag: every 3 min (tick 3) === | |
| if (_liveTick % 3 === 0) { | |
| refreshHashtag(); | |
| } | |
| // === Hot topics: every 5 min (tick 5) === | |
| if (_liveTick % 5 === 0) { | |
| loadHotTopics(); | |
| } | |
| // Pulse LIVE badges | |
| pulseLiveBadges(); | |
| }, 60000); // 60s base | |
| } | |
| function addLiveBadges() { | |
| // Add ● LIVE to section headers that don't have it yet | |
| document.querySelectorAll('.ls-header h3, .slider-header .slider-label').forEach(el => { | |
| if (!el.querySelector('.live-dot')) { | |
| const dot = document.createElement('span'); | |
| dot.className = 'live-dot'; | |
| dot.style.cssText = 'font-size:8px;color:#e74c3c;margin-left:6px;animation:wc-pulse 1.5s infinite'; | |
| dot.textContent = '● LIVE'; | |
| el.appendChild(dot); | |
| } | |
| }); | |
| } | |
| function pulseLiveBadges() { | |
| // Quick visual pulse to show data is fresh | |
| document.querySelectorAll('.live-dot').forEach(d => { | |
| d.style.opacity = '1'; | |
| setTimeout(() => { d.style.opacity = '0.4'; }, 500); | |
| setTimeout(() => { d.style.opacity = '1'; }, 1000); | |
| }); | |
| } | |
| function refreshHashtag() { | |
| // Re-search current hashtag topic for fresh results | |
| if (typeof _htTopic !== 'undefined' && _htTopic) { | |
| const box = document.getElementById('hashtag-box'); | |
| if (box && box.innerHTML.length > 50) { | |
| // Silently refresh (don't show loading spinner) | |
| fetch(`/api/hashtag/sources?topic=${encodeURIComponent(_htTopic)}&page=0`) | |
| .then(r => r.json()) | |
| .then(j => { | |
| const sources = j.sources || []; | |
| if (!sources.length) return; | |
| const list = document.getElementById('ht-list'); | |
| if (!list) return; | |
| // Update content | |
| let h = ''; | |
| sources.forEach((s, i) => { | |
| h += `<div class="hashtag-src-item" onclick="readArticle('${esc(s.url)}')"><div class="hashtag-src-img" id="ht-img-${i}"></div><div class="hashtag-src-text"><div class="hashtag-src-title">${esc(s.title)}</div><div class="hashtag-src-via">${esc(s.via || '')}</div></div></div>`; | |
| }); | |
| list.innerHTML = h; | |
| // Load images | |
| sources.forEach((s, i) => { | |
| if (!s.url) return; | |
| fetch('/api/article?url=' + encodeURIComponent(s.url)).then(r => r.json()).then(d => { | |
| if (d && (d.og_image || d.img)) { | |
| const el = document.getElementById('ht-img-' + i); | |
| if (el) el.innerHTML = `<img src="${esc(d.og_image || d.img)}" onerror="this.style.display='none'">`; | |
| } | |
| }).catch(() => {}); | |
| }); | |
| }).catch(() => {}); | |
| } | |
| } | |
| } | |
| setTimeout(startHomepageLive, 6000); | |