Spaces:
Running
Running
FIX: restore wc2026_v2.js from commit 48e2e2a - was corrupted with orphaned code fragments
Browse files- static/wc2026_v2.js +111 -4
static/wc2026_v2.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
| 1 |
-
// === WORLD CUP 2026 - Highlights ===
|
| 2 |
let _wc2026Data=null;let _wcRefreshInterval=null;
|
|
|
|
| 3 |
const WC_TEAMS={'Mexico':'🇲🇽 Mexico','Colombia':'🇨🇴 Colombia','USA':'🇺🇸 Mỹ','United States':'🇺🇸 Mỹ','Brazil':'🇧🇷 Brazil','Argentina':'🇦🇷 Argentina','Germany':'🇩🇪 Đức','France':'🇫🇷 Pháp','Spain':'🇪🇸 Tây Ban Nha','England':'🏴 Anh','Portugal':'🇵🇹 Bồ Đào Nha','Netherlands':'🇳🇱 Hà Lan','Italy':'🇮🇹 Ý','Belgium':'🇧🇪 Bỉ','Croatia':'🇭🇷 Croatia','Uruguay':'🇺🇾 Uruguay','Japan':'🇯🇵 Nhật Bản','South Korea':'🇰🇷 Hàn Quốc','Korea Republic':'🇰🇷 Hàn Quốc','Australia':'🇦🇺 Úc','Saudi Arabia':'🇸🇦 Ả Rập Xê Út','Iran':'🇮🇷 Iran','Qatar':'🇶🇦 Qatar','Canada':'🇨🇦 Canada','Morocco':'🇲🇦 Morocco','Senegal':'🇸🇳 Senegal','Ecuador':'🇪🇨 Ecuador','Serbia':'🇷🇸 Serbia','Switzerland':'🇨🇭 Thụy Sĩ','Denmark':'🇩🇰 Đan Mạch','Poland':'🇵🇱 Ba Lan','Turkey':'🇹🇷 Thổ Nhĩ Kỳ','Türkiye':'🇹🇷 Thổ Nhĩ Kỳ','Ukraine':'🇺🇦 Ukraine','Egypt':'🇪🇬 Ai Cập','Nigeria':'🇳🇬 Nigeria','Cameroon':'🇨🇲 Cameroon','Ghana':'🇬🇭 Ghana','Tunisia':'🇹🇳 Tunisia','Algeria':'🇩🇿 Algeria','South Africa':'🇿🇦 Nam Phi','Indonesia':'🇮🇩 Indonesia','Vietnam':'🇻🇳 Việt Nam','China PR':'🇨🇳 Trung Quốc','New Zealand':'🇳🇿 New Zealand','Panama':'🇵🇦 Panama','Costa Rica':'🇨🇷 Costa Rica','Jamaica':'🇯🇲 Jamaica','Honduras':'🇭🇳 Honduras','Paraguay':'🇵🇾 Paraguay','Bolivia':'🇧🇴 Bolivia','Chile':'🇨🇱 Chile','Peru':'🇵🇪 Peru','Venezuela':'🇻🇪 Venezuela','Norway':'🇳🇴 Na Uy','Sweden':'🇸🇪 Thụy Điển','Austria':'🇦🇹 Áo','Scotland':'🏴 Scotland','Wales':'🏴 Xứ Wales','Ireland':'🇮🇪 Ireland','Romania':'🇷🇴 Romania','Hungary':'🇭🇺 Hungary','Greece':'🇬🇷 Hy Lạp','Uzbekistan':'🇺🇿 Uzbekistan','Iraq':'🇮🇶 Iraq','TBD':'🏳️ TBD'};
|
| 4 |
function _t(n){return WC_TEAMS[n]||WC_TEAMS[(n||'').trim()]||'🏴 '+n;}
|
| 5 |
|
|
@@ -29,7 +30,18 @@ const WC_CSS=`<style>
|
|
| 29 |
.wc-bxh th{background:#0b1a2a!important;color:#6a9fca!important;padding:5px 3px!important;font-size:9px!important;text-align:center!important}
|
| 30 |
.wc-bxh td{padding:4px 3px!important;border-bottom:1px solid #0d1a2a!important;font-size:10px!important;color:#ddd!important}
|
| 31 |
/* WC Shorts slider */
|
| 32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
</style>`;
|
| 34 |
|
| 35 |
function switchWCTab(tab){
|
|
@@ -138,7 +150,102 @@ async function renderWCHighlights(el){
|
|
| 138 |
}
|
| 139 |
}
|
| 140 |
|
| 141 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 142 |
|
| 143 |
// Scroll-based activation with snap
|
| 144 |
let scrollTimer;
|
|
@@ -207,4 +314,4 @@ function startWCLiveRefresh(){
|
|
| 207 |
}catch(e){}
|
| 208 |
},90000);
|
| 209 |
}
|
| 210 |
-
setTimeout(startWCLiveRefresh,5000);
|
|
|
|
| 1 |
+
// === WORLD CUP 2026 - Highlights + Shorts ===
|
| 2 |
let _wc2026Data=null;let _wcRefreshInterval=null;
|
| 3 |
+
let _wcShortsData=[]; // YouTube shorts: VTV Nam Bộ + WC moments
|
| 4 |
const WC_TEAMS={'Mexico':'🇲🇽 Mexico','Colombia':'🇨🇴 Colombia','USA':'🇺🇸 Mỹ','United States':'🇺🇸 Mỹ','Brazil':'🇧🇷 Brazil','Argentina':'🇦🇷 Argentina','Germany':'🇩🇪 Đức','France':'🇫🇷 Pháp','Spain':'🇪🇸 Tây Ban Nha','England':'🏴 Anh','Portugal':'🇵🇹 Bồ Đào Nha','Netherlands':'🇳🇱 Hà Lan','Italy':'🇮🇹 Ý','Belgium':'🇧🇪 Bỉ','Croatia':'🇭🇷 Croatia','Uruguay':'🇺🇾 Uruguay','Japan':'🇯🇵 Nhật Bản','South Korea':'🇰🇷 Hàn Quốc','Korea Republic':'🇰🇷 Hàn Quốc','Australia':'🇦🇺 Úc','Saudi Arabia':'🇸🇦 Ả Rập Xê Út','Iran':'🇮🇷 Iran','Qatar':'🇶🇦 Qatar','Canada':'🇨🇦 Canada','Morocco':'🇲🇦 Morocco','Senegal':'🇸🇳 Senegal','Ecuador':'🇪🇨 Ecuador','Serbia':'🇷🇸 Serbia','Switzerland':'🇨🇭 Thụy Sĩ','Denmark':'🇩🇰 Đan Mạch','Poland':'🇵🇱 Ba Lan','Turkey':'🇹🇷 Thổ Nhĩ Kỳ','Türkiye':'🇹🇷 Thổ Nhĩ Kỳ','Ukraine':'🇺🇦 Ukraine','Egypt':'🇪🇬 Ai Cập','Nigeria':'🇳🇬 Nigeria','Cameroon':'🇨🇲 Cameroon','Ghana':'🇬🇭 Ghana','Tunisia':'🇹🇳 Tunisia','Algeria':'🇩🇿 Algeria','South Africa':'🇿🇦 Nam Phi','Indonesia':'🇮🇩 Indonesia','Vietnam':'🇻🇳 Việt Nam','China PR':'🇨🇳 Trung Quốc','New Zealand':'🇳🇿 New Zealand','Panama':'🇵🇦 Panama','Costa Rica':'🇨🇷 Costa Rica','Jamaica':'🇯🇲 Jamaica','Honduras':'🇭🇳 Honduras','Paraguay':'🇵🇾 Paraguay','Bolivia':'🇧🇴 Bolivia','Chile':'🇨🇱 Chile','Peru':'🇵🇪 Peru','Venezuela':'🇻🇪 Venezuela','Norway':'🇳🇴 Na Uy','Sweden':'🇸🇪 Thụy Điển','Austria':'🇦🇹 Áo','Scotland':'🏴 Scotland','Wales':'🏴 Xứ Wales','Ireland':'🇮🇪 Ireland','Romania':'🇷🇴 Romania','Hungary':'🇭🇺 Hungary','Greece':'🇬🇷 Hy Lạp','Uzbekistan':'🇺🇿 Uzbekistan','Iraq':'🇮🇶 Iraq','TBD':'🏳️ TBD'};
|
| 5 |
function _t(n){return WC_TEAMS[n]||WC_TEAMS[(n||'').trim()]||'🏴 '+n;}
|
| 6 |
|
|
|
|
| 30 |
.wc-bxh th{background:#0b1a2a!important;color:#6a9fca!important;padding:5px 3px!important;font-size:9px!important;text-align:center!important}
|
| 31 |
.wc-bxh td{padding:4px 3px!important;border-bottom:1px solid #0d1a2a!important;font-size:10px!important;color:#ddd!important}
|
| 32 |
/* WC Shorts slider */
|
| 33 |
+
.wc-shorts-slider{margin:8px 0}
|
| 34 |
+
.wc-shorts-track{display:flex;overflow-x:auto;gap:8px;padding:4px 0 10px;scrollbar-width:none}
|
| 35 |
+
.wc-shorts-track::-webkit-scrollbar{display:none}
|
| 36 |
+
.wc-shorts-item{flex:0 0 130px;cursor:pointer;border-radius:8px;overflow:hidden;background:#0a1520;border:1px solid #1a3a5a;transition:border-color .2s}
|
| 37 |
+
.wc-shorts-item:hover{border-color:#f0c040}
|
| 38 |
+
.wc-shorts-thumb{position:relative;width:100%;aspect-ratio:9/16;background:#1a2a3a;overflow:hidden}
|
| 39 |
+
.wc-shorts-thumb img{width:100%;height:100%;object-fit:cover}
|
| 40 |
+
.wc-shorts-thumb .card-play{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:32px;height:32px;border-radius:50%;background:rgba(0,0,0,.55);display:flex;align-items:center;justify-content:center;color:#fff;font-size:14px}
|
| 41 |
+
.wc-shorts-info{padding:4px 6px}
|
| 42 |
+
.wc-shorts-badge{font-size:8px;font-weight:700;padding:1px 4px;border-radius:3px;display:inline-block;margin-bottom:2px}
|
| 43 |
+
.wc-shorts-title{font-size:10px;color:#ccc;line-height:1.2;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
|
| 44 |
+
.wc-shorts-viewall{flex:0 0 100px;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#0b2e4a,#1a3a5a);border-radius:8px;cursor:pointer;border:1px dashed #2a5a8a;color:#8ab4d8;font-size:11px;font-weight:700;text-align:center;padding:8px}
|
| 45 |
</style>`;
|
| 46 |
|
| 47 |
function switchWCTab(tab){
|
|
|
|
| 150 |
}
|
| 151 |
}
|
| 152 |
|
| 153 |
+
// === WC SHORTS SLIDE — shown inside WC section ===
|
| 154 |
+
function renderWCShortsSlide(container){
|
| 155 |
+
if(!_wcShortsData || !_wcShortsData.length) return;
|
| 156 |
+
const wrap = document.createElement('div');
|
| 157 |
+
wrap.className = 'slider-wrap wc-shorts-slider';
|
| 158 |
+
let h = '<div class="slider-header"><span class="slider-label">📱 Shorts World Cup</span><span style="font-size:10px;color:#8ab4d8;cursor:pointer" onclick="openWCShortsFeed(0)">Xem tất cả →</span></div>';
|
| 159 |
+
h += '<div class="wc-shorts-track">';
|
| 160 |
+
_wcShortsData.slice(0,10).forEach((s,i)=>{
|
| 161 |
+
const badge = s.channel==='vtvnambo' ? 'VTV Nam Bộ' : '⚽ WC';
|
| 162 |
+
const badgeColor = s.channel==='vtvnambo' ? '#0b6bcb' : '#f26522';
|
| 163 |
+
h += `<div class="wc-shorts-item" onclick="openWCShortsFeed(${i})">`;
|
| 164 |
+
h += `<div class="wc-shorts-thumb">${s.img?`<img src="${esc(s.img)}" loading="lazy" onerror="this.style.display='none'">`:''}<div class="card-play">▶</div></div>`;
|
| 165 |
+
h += `<div class="wc-shorts-info"><span class="wc-shorts-badge" style="background:${badgeColor};color:#fff">${badge}</span><div class="wc-shorts-title">${esc(s.title)}</div></div>`;
|
| 166 |
+
h += '</div>';
|
| 167 |
+
});
|
| 168 |
+
// "View all" card
|
| 169 |
+
h += `<div class="wc-shorts-viewall" onclick="openWCShortsFeed(0)">📱 Xem tất cả<br><small style="font-size:9px;color:#6a9fca">${_wcShortsData.length} shorts</small></div>`;
|
| 170 |
+
h += '</div>';
|
| 171 |
+
wrap.innerHTML = h;
|
| 172 |
+
container.appendChild(wrap);
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
// === WC SHORTS TIKTOK FEED — full-screen vertical scroll, continuous autoplay ===
|
| 176 |
+
async function openWCShortsFeed(startIdx){
|
| 177 |
+
showView('view-tiktok');
|
| 178 |
+
const el = document.getElementById('view-tiktok');
|
| 179 |
+
el.innerHTML = '<div class="loading">Đang tải shorts...</div>';
|
| 180 |
+
|
| 181 |
+
// Fetch shorts if not loaded
|
| 182 |
+
if(!_wcShortsData || !_wcShortsData.length){
|
| 183 |
+
try{
|
| 184 |
+
const r = await fetch('/api/shorts?channel=vtvnambo&count=30');
|
| 185 |
+
_wcShortsData = await r.json() || [];
|
| 186 |
+
}catch(e){
|
| 187 |
+
_wcShortsData = [];
|
| 188 |
+
}
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
if(!_wcShortsData.length){
|
| 192 |
+
el.innerHTML = '<div class="loading">Chưa có shorts</div>';
|
| 193 |
+
return;
|
| 194 |
+
}
|
| 195 |
+
|
| 196 |
+
// Rotate so startIdx is first
|
| 197 |
+
const ordered = startIdx > 0 ? [..._wcShortsData.slice(startIdx), ..._wcShortsData.slice(0,startIdx)] : _wcShortsData;
|
| 198 |
+
|
| 199 |
+
let h = `<button class="back-btn" onclick="switchCat('home')">← World Cup Shorts</button>`;
|
| 200 |
+
h += '<div class="tiktok-container"><div class="tiktok-feed" id="wc-shorts-feed">';
|
| 201 |
+
|
| 202 |
+
ordered.forEach((s,i)=>{
|
| 203 |
+
const id = s.id || '';
|
| 204 |
+
const src = `https://www.youtube.com/embed/${id}?autoplay=0&rel=0&playsinline=1&mute=1`;
|
| 205 |
+
const vtag = `<iframe data-yt-src="${src}" allowfullscreen allow="accelerometer;autoplay;clipboard-write;encrypted-media;gyroscope;picture-in-picture"></iframe>`;
|
| 206 |
+
const badge = s.channel==='vtvnambo' ? 'VTV Nam Bộ' : '⚽ WC';
|
| 207 |
+
const badgeClass = s.channel==='vtvnambo' ? 'badge-wc' : 'badge-fpt';
|
| 208 |
+
const videoId = 'wcshort-' + id;
|
| 209 |
+
h += buildTikTokSlide({vtag,title:s.title,badge,badgeClass,videoId,idx:i,total:ordered.length,shareUrl:'https://youtube.com/shorts/'+id});
|
| 210 |
+
});
|
| 211 |
+
|
| 212 |
+
h += '</div></div>';
|
| 213 |
+
el.innerHTML = h;
|
| 214 |
+
|
| 215 |
+
// Init continuous autoplay feed
|
| 216 |
+
initWCShortsFeed();
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
function initWCShortsFeed(){
|
| 220 |
+
const feed = document.getElementById('wc-shorts-feed');
|
| 221 |
+
if(!feed) return;
|
| 222 |
+
const slides = feed.querySelectorAll('.tiktok-slide');
|
| 223 |
+
let cur = -1;
|
| 224 |
+
let isManualScroll = false;
|
| 225 |
+
let manualTimer = null;
|
| 226 |
+
|
| 227 |
+
function activate(i){
|
| 228 |
+
if(i === cur) return;
|
| 229 |
+
slides.forEach((sl,idx)=>{
|
| 230 |
+
const fr = sl.querySelector('iframe');
|
| 231 |
+
if(idx === i){
|
| 232 |
+
// Load and play
|
| 233 |
+
if(fr && !fr.src && fr.dataset.ytSrc) fr.src = fr.dataset.ytSrc;
|
| 234 |
+
// For continuous feel: set autoplay=1 on activate
|
| 235 |
+
if(fr && fr.src && !fr.src.includes('autoplay=1')){
|
| 236 |
+
fr.src = fr.src.replace('autoplay=0','autoplay=1');
|
| 237 |
+
}
|
| 238 |
+
const vid = sl.dataset.vid;
|
| 239 |
+
if(vid && !sl._viewed){ sl._viewed = true; doInteract(vid,'view'); }
|
| 240 |
+
} else {
|
| 241 |
+
// Pause: reload with autoplay=0 to stop
|
| 242 |
+
if(fr && fr.src){
|
| 243 |
+
fr.src = fr.src.replace('autoplay=1','autoplay=0');
|
| 244 |
+
}
|
| 245 |
+
}
|
| 246 |
+
});
|
| 247 |
+
cur = i;
|
| 248 |
+
}
|
| 249 |
|
| 250 |
// Scroll-based activation with snap
|
| 251 |
let scrollTimer;
|
|
|
|
| 314 |
}catch(e){}
|
| 315 |
},90000);
|
| 316 |
}
|
| 317 |
+
setTimeout(startWCLiveRefresh,5000);
|