bep40 commited on
Commit
35191dc
·
verified ·
1 Parent(s): c8e389b

fix: share reads ?open= param (no localStorage), readArticle always in-app, click outside closes comment

Browse files
Files changed (1) hide show
  1. 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
- const pending=localStorage.getItem('pending_article');
95
- if(pending){localStorage.removeItem('pending_article');let src='vne';if(pending.includes('bbc.com'))src='bbc';readArticle(pending,src);}
 
 
 
 
 
 
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){el.innerHTML=`<button class="back-btn" onclick="switchCat('home')">← Quay lại</button><div class="loading"><a href="${url}" target="_blank" style="color:#5cb87a">Mở link gốc</a></div>`;return;}
 
 
 
 
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>`;