Spaces:
Running
Running
fix: share reads ?open= param (no localStorage), readArticle always in-app, click outside closes comment
Browse files- static/index.html +21 -4
static/index.html
CHANGED
|
@@ -84,6 +84,13 @@ function doShare(title,articleUrl,img){
|
|
| 84 |
else navigator.clipboard.writeText(shareUrl).then(()=>alert('Đã sao chép!')).catch(()=>{});
|
| 85 |
}
|
| 86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
async function init(){
|
| 88 |
_cats=await fetch('/api/categories').then(r=>r.json());
|
| 89 |
let bar='<div class="cat active" data-cat="home">🏠</div><div class="cat" data-cat="video">🎬 Video</div>';
|
|
@@ -91,8 +98,14 @@ async function init(){
|
|
| 91 |
document.getElementById('cat-bar').innerHTML=bar;
|
| 92 |
document.querySelectorAll('.cat').forEach(t=>{t.onclick=()=>switchCat(t.dataset.cat);});
|
| 93 |
await loadHome();
|
| 94 |
-
|
| 95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
}
|
| 97 |
function switchCat(id){document.querySelectorAll('.cat').forEach(x=>x.classList.remove('active'));document.querySelector(`[data-cat="${id}"]`)?.classList.add('active');document.querySelectorAll('.view').forEach(x=>x.classList.remove('active'));document.querySelectorAll('video').forEach(v=>v.pause());if(id==='home')document.getElementById('view-home').classList.add('active');else if(id==='video'){document.getElementById('view-video').classList.add('active');loadVideos();}else{document.getElementById('view-cat').classList.add('active');loadCat(id);}}
|
| 98 |
function showView(id){document.querySelectorAll('.view').forEach(x=>x.classList.remove('active'));document.getElementById(id).classList.add('active');}
|
|
@@ -108,12 +121,16 @@ async function loadHome(){
|
|
| 108 |
}
|
| 109 |
async function loadCat(id){const el=document.getElementById('view-cat');el.innerHTML='<div class="loading">Đang tải...</div>';const arts=await fetch('/api/category/'+id).then(r=>r.json());if(!arts.length){el.innerHTML='<div class="loading">Không có tin</div>';return;}let h='<div class="grid">';arts.forEach(a=>{const bg=a.source==='bbc'?'badge-bbc':a.source==='bdp'?'badge-bdp':'badge-vne';h+=`<div class="card" onclick="readArticle('${a.link.replace(/'/g,"\\'")}','${a.source}')"><div class="card-img">${a.img?`<img src="${a.img}">`:''}</div><div class="card-body"><span class="badge ${bg}">${a.source}</span><div class="card-title">${a.title}</div></div></div>`;});h+='</div>';el.innerHTML=h;}
|
| 110 |
|
|
|
|
| 111 |
async function readArticle(url,source){
|
| 112 |
-
if(source!=='vne'&&source!=='bbc'){window.open(url,'_blank');return;}
|
| 113 |
showView('view-article');const el=document.getElementById('view-article');el.innerHTML='<div class="loading">Đang tải...</div>';
|
| 114 |
const aid=hid(url);incV(aid);
|
| 115 |
const data=await fetch('/api/article?url='+encodeURIComponent(url)).then(r=>r.json());
|
| 116 |
-
if(!data||data.error){
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
const ogImg=data.og_image||'';
|
| 118 |
let h=`<button class="back-btn" onclick="switchCat('home')">← Quay lại</button><div class="article-view"><h1 class="article-title">${data.title}</h1>`;
|
| 119 |
if(data.summary)h+=`<div class="article-summary">${data.summary}</div>`;
|
|
|
|
| 84 |
else navigator.clipboard.writeText(shareUrl).then(()=>alert('Đã sao chép!')).catch(()=>{});
|
| 85 |
}
|
| 86 |
|
| 87 |
+
// ★ FIX: Click anywhere outside .cmt-panel closes it
|
| 88 |
+
document.addEventListener('click',function(e){
|
| 89 |
+
if(!e.target.closest('.cmt-panel')&&!e.target.closest('.tiktok-right-btn')){
|
| 90 |
+
document.querySelectorAll('.cmt-panel.open').forEach(p=>p.classList.remove('open'));
|
| 91 |
+
}
|
| 92 |
+
});
|
| 93 |
+
|
| 94 |
async function init(){
|
| 95 |
_cats=await fetch('/api/categories').then(r=>r.json());
|
| 96 |
let bar='<div class="cat active" data-cat="home">🏠</div><div class="cat" data-cat="video">🎬 Video</div>';
|
|
|
|
| 98 |
document.getElementById('cat-bar').innerHTML=bar;
|
| 99 |
document.querySelectorAll('.cat').forEach(t=>{t.onclick=()=>switchCat(t.dataset.cat);});
|
| 100 |
await loadHome();
|
| 101 |
+
// ★ FIX: Read ?open= query param (from /s share redirect) instead of localStorage
|
| 102 |
+
const params=new URLSearchParams(location.search);
|
| 103 |
+
const openUrl=params.get('open');
|
| 104 |
+
if(openUrl){
|
| 105 |
+
// Clean URL so user doesn't see ?open= in address bar
|
| 106 |
+
history.replaceState(null,'',location.pathname);
|
| 107 |
+
readArticle(openUrl,'vne');
|
| 108 |
+
}
|
| 109 |
}
|
| 110 |
function switchCat(id){document.querySelectorAll('.cat').forEach(x=>x.classList.remove('active'));document.querySelector(`[data-cat="${id}"]`)?.classList.add('active');document.querySelectorAll('.view').forEach(x=>x.classList.remove('active'));document.querySelectorAll('video').forEach(v=>v.pause());if(id==='home')document.getElementById('view-home').classList.add('active');else if(id==='video'){document.getElementById('view-video').classList.add('active');loadVideos();}else{document.getElementById('view-cat').classList.add('active');loadCat(id);}}
|
| 111 |
function showView(id){document.querySelectorAll('.view').forEach(x=>x.classList.remove('active'));document.getElementById(id).classList.add('active');}
|
|
|
|
| 121 |
}
|
| 122 |
async function loadCat(id){const el=document.getElementById('view-cat');el.innerHTML='<div class="loading">Đang tải...</div>';const arts=await fetch('/api/category/'+id).then(r=>r.json());if(!arts.length){el.innerHTML='<div class="loading">Không có tin</div>';return;}let h='<div class="grid">';arts.forEach(a=>{const bg=a.source==='bbc'?'badge-bbc':a.source==='bdp'?'badge-bdp':'badge-vne';h+=`<div class="card" onclick="readArticle('${a.link.replace(/'/g,"\\'")}','${a.source}')"><div class="card-img">${a.img?`<img src="${a.img}">`:''}</div><div class="card-body"><span class="badge ${bg}">${a.source}</span><div class="card-title">${a.title}</div></div></div>`;});h+='</div>';el.innerHTML=h;}
|
| 123 |
|
| 124 |
+
// ★ FIX: readArticle always opens in VNEWS reader. Never window.open externally.
|
| 125 |
async function readArticle(url,source){
|
|
|
|
| 126 |
showView('view-article');const el=document.getElementById('view-article');el.innerHTML='<div class="loading">Đang tải...</div>';
|
| 127 |
const aid=hid(url);incV(aid);
|
| 128 |
const data=await fetch('/api/article?url='+encodeURIComponent(url)).then(r=>r.json());
|
| 129 |
+
if(!data||data.error){
|
| 130 |
+
// API doesn't support this source → show article link inside VNEWS (not external redirect)
|
| 131 |
+
el.innerHTML=`<button class="back-btn" onclick="switchCat('home')">← Quay lại</button><div class="article-view" style="text-align:center;padding:60px 20px"><p style="color:#aaa;margin-bottom:12px">Bài viết này chưa hỗ trợ đọc trực tiếp</p><a href="${url}" target="_blank" style="color:#5cb87a;font-size:14px;text-decoration:underline">📰 Mở bài viết gốc</a></div>`;
|
| 132 |
+
return;
|
| 133 |
+
}
|
| 134 |
const ogImg=data.og_image||'';
|
| 135 |
let h=`<button class="back-btn" onclick="switchCat('home')">← Quay lại</button><div class="article-view"><h1 class="article-title">${data.title}</h1>`;
|
| 136 |
if(data.summary)h+=`<div class="article-summary">${data.summary}</div>`;
|