bep40 commited on
Commit
45f2f9e
·
verified ·
1 Parent(s): 7aa2274

FIX: restore wc2026_v2.js from commit 48e2e2a - was corrupted with orphaned code fragments

Browse files
Files changed (1) hide show
  1. 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
- // (WC Shorts removed per user request)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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);