bep40 commited on
Commit
4cb3c62
·
verified ·
1 Parent(s): 71ffd13

Hashtag inline: show sources on homepage + rewrite button"

Browse files
Files changed (1) hide show
  1. hashtag_inline.py +87 -0
hashtag_inline.py ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Hashtag inline: click hashtag → show sources on homepage + rewrite button."""
2
+ HASHTAG_INLINE_INJECT = r'''
3
+ <style>
4
+ .hashtag-sources{margin:8px 4px;background:#141414;border:1px solid #2a2a2a;border-radius:10px;padding:10px;display:none}
5
+ .hashtag-sources.active{display:block}
6
+ .hashtag-sources h3{font-size:13px;color:#5cb87a;margin-bottom:8px}
7
+ .hashtag-source-item{display:flex;gap:8px;padding:8px;background:#1a1a1a;border-radius:8px;margin:6px 0;cursor:pointer}
8
+ .hashtag-source-item:active{opacity:.8}
9
+ .hashtag-source-item img{width:80px;height:50px;object-fit:cover;border-radius:6px;background:#333;flex-shrink:0}
10
+ .hashtag-source-item .info{flex:1;min-width:0}
11
+ .hashtag-source-item .title{font-size:12px;font-weight:700;color:#eee;line-height:1.3;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
12
+ .hashtag-source-item .desc{font-size:10px;color:#888;margin-top:2px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
13
+ .hashtag-source-item .via{font-size:9px;color:#5cb87a;margin-top:2px}
14
+ .hashtag-rewrite-btn{display:block;width:100%;margin-top:10px;background:#2d8659;border:0;color:#fff;border-radius:14px;padding:10px;font-size:12px;font-weight:700;cursor:pointer}
15
+ .hashtag-rewrite-btn:disabled{opacity:.5}
16
+ .hashtag-close{float:right;background:none;border:0;color:#999;font-size:18px;cursor:pointer}
17
+ </style>
18
+ <div id="hashtag-sources-panel" class="hashtag-sources"></div>
19
+ <script>
20
+ (function(){
21
+ function esc(s){return String(s||'').replace(/[&<>"']/g,function(m){return{'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[m]});}
22
+
23
+ // Override hashtag click: show sources inline on homepage
24
+ window.hashtagClick=async function(topic){
25
+ var panel=document.getElementById('hashtag-sources-panel');
26
+ if(!panel){panel=document.createElement('div');panel.id='hashtag-sources-panel';panel.className='hashtag-sources';var home=document.getElementById('view-home');if(home)home.insertBefore(panel,home.children[1]||null);}
27
+ panel.innerHTML='<button class="hashtag-close" onclick="closeHashtagPanel()">✕</button><h3>#'+esc(topic)+' — Đang tìm nguồn...</h3>';
28
+ panel.classList.add('active');
29
+ try{
30
+ var r=await fetch('/api/topic_sources?topic='+encodeURIComponent(topic));
31
+ var j=await r.json();
32
+ var sources=j.sources||[];
33
+ if(!sources.length){panel.innerHTML='<button class="hashtag-close" onclick="closeHashtagPanel()">✕</button><h3>#'+esc(topic)+'</h3><p style="color:#888;font-size:12px">Không tìm thấy nguồn cho chủ đề này.</p>';return;}
34
+ var h='<button class="hashtag-close" onclick="closeHashtagPanel()">✕</button>';
35
+ h+='<h3>#'+esc(topic)+' — '+sources.length+' nguồn</h3>';
36
+ sources.forEach(function(s){
37
+ h+='<div class="hashtag-source-item" onclick="if(typeof readArticle===\'function\')readArticle(\''+esc(s.url||'')+'\')">';
38
+ h+='<img src="/api/proxy/img?url='+encodeURIComponent(s.url||'')+'" onerror="this.style.display=\'none\'" loading="lazy">';
39
+ h+='<div class="info"><div class="title">'+esc(s.title||'')+'</div><div class="desc">'+esc((s.excerpt||s.snippet||'').slice(0,120))+'</div><div class="via">'+esc(s.via||'')+'</div></div>';
40
+ h+='</div>';
41
+ });
42
+ h+='<button class="hashtag-rewrite-btn" onclick="rewriteHashtagSources(\''+esc(topic)+'\',this)">🤖 Rewrite AI tổng hợp và đăng tường</button>';
43
+ panel.innerHTML=h;
44
+ // Try to load og:image for each source
45
+ sources.forEach(function(s,i){
46
+ if(!s.url)return;
47
+ fetch('/api/article?url='+encodeURIComponent(s.url)).then(function(r){return r.json()}).then(function(d){
48
+ if(d&&(d.og_image||d.img)){
49
+ var items=panel.querySelectorAll('.hashtag-source-item');
50
+ if(items[i]){var img=items[i].querySelector('img');if(img)img.src=d.og_image||d.img;}
51
+ }
52
+ }).catch(function(){});
53
+ });
54
+ }catch(e){panel.innerHTML='<button class="hashtag-close" onclick="closeHashtagPanel()">✕</button><h3>#'+esc(topic)+'</h3><p style="color:#f66;font-size:12px">Lỗi: '+esc(e.message)+'</p>';}
55
+ };
56
+
57
+ window.closeHashtagPanel=function(){
58
+ var panel=document.getElementById('hashtag-sources-panel');
59
+ if(panel)panel.classList.remove('active');
60
+ };
61
+
62
+ window.rewriteHashtagSources=async function(topic,btn){
63
+ btn.disabled=true;btn.textContent='Đang tổng hợp...';
64
+ try{
65
+ var r=await fetch('/api/topic_post',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({topic:topic})});
66
+ var j=await r.json();
67
+ if(!r.ok||j.error)throw new Error(j.error||'Lỗi');
68
+ btn.textContent='✅ Đã đăng tường AI!';
69
+ setTimeout(function(){closeHashtagPanel();},2000);
70
+ // Update wall
71
+ if(j.post&&typeof prependWallPost==='function')prependWallPost(j.post);
72
+ }catch(e){btn.textContent='❌ '+e.message;setTimeout(function(){btn.disabled=false;btn.textContent='🤖 Rewrite AI tổng hợp và đăng tường';},3000);}
73
+ };
74
+
75
+ // Patch existing hot-chip buttons to use hashtagClick instead of filling input
76
+ document.addEventListener('click',function(e){
77
+ var chip=e.target.closest('.hot-chip');
78
+ if(chip){
79
+ e.preventDefault();e.stopPropagation();
80
+ var topic=chip.textContent.replace(/^#/,'').trim()||chip.getAttribute('onclick')?.match(/value='([^']+)'/)?.[1]||'';
81
+ if(topic)hashtagClick(topic);
82
+ }
83
+ },true);
84
+
85
+ })();
86
+ </script>
87
+ '''