Spaces:
Running
Running
revert: app_wrapper.py back to previous version (before comment/counter changes)
Browse files- app_wrapper.py +2 -103
app_wrapper.py
CHANGED
|
@@ -13,24 +13,6 @@ SHORTS_EXTRA_CSS = """
|
|
| 13 |
.tiktok-fullscreen-container.fullheight-mode .tiktok-video{object-fit:cover!important}
|
| 14 |
.tiktok-fullheight-btn{position:absolute;bottom:70px;right:12px;background:rgba(255,255,255,.15);color:#fff;border:none;padding:6px 12px;border-radius:16px;font-size:11px;cursor:pointer;z-index:8;backdrop-filter:blur(6px)}
|
| 15 |
.tiktok-fullheight-btn.active{background:rgba(92,184,122,.5)}
|
| 16 |
-
/* Right side action buttons */
|
| 17 |
-
.tiktok-right-actions{position:absolute;right:10px;bottom:140px;display:flex;flex-direction:column;align-items:center;gap:16px;z-index:8}
|
| 18 |
-
.tiktok-right-btn{background:none;border:none;color:#fff;font-size:22px;cursor:pointer;display:flex;flex-direction:column;align-items:center;gap:2px;filter:drop-shadow(0 1px 3px rgba(0,0,0,.6))}
|
| 19 |
-
.tiktok-right-btn span{font-size:10px;font-weight:600}
|
| 20 |
-
/* Comment panel */
|
| 21 |
-
.tiktok-cmt-panel{position:absolute;right:0;bottom:0;left:0;height:55%;background:rgba(17,17,17,.97);z-index:20;transform:translateY(100%);transition:transform .3s;border-radius:14px 14px 0 0;padding:12px;overflow-y:auto}
|
| 22 |
-
.tiktok-cmt-panel.open{transform:translateY(0)}
|
| 23 |
-
.tiktok-cmt-panel .cmt-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px}
|
| 24 |
-
.tiktok-cmt-panel .cmt-header h4{color:#fff;font-size:14px;margin:0}
|
| 25 |
-
.tiktok-cmt-panel .cmt-close{background:none;border:none;color:#aaa;font-size:20px;cursor:pointer}
|
| 26 |
-
.tiktok-cmt-panel .cmt-list{max-height:calc(100% - 100px);overflow-y:auto;margin-bottom:8px}
|
| 27 |
-
.tiktok-cmt-panel .cmt-item{background:#222;border-radius:8px;padding:8px 10px;margin-bottom:6px}
|
| 28 |
-
.tiktok-cmt-panel .cmt-item b{color:#5cb87a;font-size:12px}
|
| 29 |
-
.tiktok-cmt-panel .cmt-item p{color:#ccc;font-size:12px;margin:3px 0 0}
|
| 30 |
-
.tiktok-cmt-panel .cmt-item small{color:#666;font-size:10px}
|
| 31 |
-
.tiktok-cmt-panel .cmt-form{display:flex;gap:6px;align-items:center}
|
| 32 |
-
.tiktok-cmt-panel .cmt-input{flex:1;padding:8px;background:#222;border:1px solid #444;border-radius:8px;color:#eee;font-size:12px}
|
| 33 |
-
.tiktok-cmt-panel .cmt-send{background:#2d8659;color:#fff;border:none;padding:8px 14px;border-radius:8px;font-size:12px;cursor:pointer}
|
| 34 |
"""
|
| 35 |
FULLWIDTH_CSS = """
|
| 36 |
body,.gradio-container,.main,.contain{margin:0!important;padding:0!important;max-width:100%!important;width:100%!important}
|
|
@@ -134,99 +116,16 @@ def _btk(ordered,sl):
|
|
| 134 |
po=app.safe_url(v.get("poster",""));pa=f' poster="{po}"' if po else ""
|
| 135 |
vs=v["src"];aid=app.make_id(v["link"]);s=app.slug(v["title"])
|
| 136 |
orig_url=app.esc(v["link"])
|
| 137 |
-
|
| 138 |
-
share_js=f"event.stopPropagation();window.bdpShareOriginal('{app.esc(v['title'])}','{orig_url}');window.bdpIncCounter('{aid}','shares')"
|
| 139 |
-
# Comment toggle
|
| 140 |
-
cmt_js=f"event.stopPropagation();this.closest('.tiktok-slide').querySelector('.tiktok-cmt-panel').classList.toggle('open')"
|
| 141 |
-
# View counter increment on slide activation (done via data attribute)
|
| 142 |
vt=f'<video class="tiktok-video" playsinline preload="metadata"{pa} data-hls-src="{vs}" muted loop></video>' if v.get("vtype")=="hls" else f'<video class="tiktok-video" playsinline preload="metadata"{pa} muted loop><source src="{app.safe_url(vs)}" type="video/mp4"></video>'
|
| 143 |
fb='<button class="tiktok-fullheight-btn" onclick="event.stopPropagation();var c=this.closest(\'.tiktok-fullscreen-container\');c.classList.toggle(\'fullheight-mode\');var on=c.classList.contains(\'fullheight-mode\');c.querySelectorAll(\'.tiktok-fullheight-btn\').forEach(function(b){b.classList.toggle(\'active\',on);b.textContent=on?\'\\u2B07 Contain\':\'\\u2922 Fullheight\';});">\u2922 Fullheight</button>'
|
| 144 |
-
|
| 145 |
-
# Right side action buttons with counters
|
| 146 |
-
right_actions = f'''<div class="tiktok-right-actions">
|
| 147 |
-
<button class="tiktok-right-btn" onclick="event.stopPropagation();" data-views="{aid}">👁<span id="vc-{aid}">0</span></button>
|
| 148 |
-
<button class="tiktok-right-btn" onclick="{cmt_js}">💬<span id="cc-{aid}">0</span></button>
|
| 149 |
-
<button class="tiktok-right-btn" onclick="{share_js}">📤<span id="sc-{aid}">0</span></button>
|
| 150 |
-
</div>'''
|
| 151 |
-
|
| 152 |
-
# Comment panel
|
| 153 |
-
cmt_panel = f'''<div class="tiktok-cmt-panel" onclick="event.stopPropagation();">
|
| 154 |
-
<div class="cmt-header"><h4>\U0001f4ac B\u00ecnh lu\u1eadn</h4><button class="cmt-close" onclick="this.closest('.tiktok-cmt-panel').classList.remove('open')">\u2715</button></div>
|
| 155 |
-
<div class="cmt-list" id="tcl-{aid}"></div>
|
| 156 |
-
<div class="cmt-form">
|
| 157 |
-
<input class="cmt-input" id="tcn-{aid}" placeholder="T\u00ean..." maxlength="30">
|
| 158 |
-
<input class="cmt-input" id="tct-{aid}" placeholder="B\u00ecnh lu\u1eadn..." maxlength="200">
|
| 159 |
-
<button class="cmt-send" onclick="window.bdpTikTokCmt('{aid}')">G\u1eedi</button>
|
| 160 |
-
</div>
|
| 161 |
-
</div>'''
|
| 162 |
-
|
| 163 |
-
slides.append(f'<div class="tiktok-slide" data-index="{vi}" data-aid="{aid}">{vt}<div class="tiktok-pause-icon">\u25b6</div><div class="tiktok-seek-controls"><button class="tiktok-seek-btn" onclick="event.stopPropagation();window.bdpSeek(this,-10)">\u23ea 10s</button><button class="tiktok-seek-btn" onclick="event.stopPropagation();window.bdpSeek(this,10)">10s \u23e9</button></div><div class="tiktok-bottom"><span class="bdp-badge {badge}">{sl}</span><p class="tiktok-title">{v["title"]}</p></div>{right_actions}{fb}{cmt_panel}<div class="tiktok-unmute-hint" onclick="window.bdpTikTokUnmute(this)">\U0001f507 B\u1eadt ti\u1ebfng</div><span class="tiktok-counter">{vi+1}/{len(ordered)}</span></div>')
|
| 164 |
img=app.safe_url(v.get("img")or v.get("poster",""))
|
| 165 |
cards.append(f'<div class="bdp-card" onclick="window.bdpOpen(\'{app.esc(v["link"])}\',\'{aid}\',\'{s}\')"><div class="bdp-card-img"><img src="{img}" alt="" class="bdp-lazy-img"><div class="bdp-play-overlay">\u25b6</div></div><div class="bdp-card-body"><span class="bdp-badge {badge}">{sl}</span><h3 class="bdp-card-title">{v["title"]}</h3></div></div>')
|
| 166 |
grid=f'<div class="bdp-wrap"><div class="bdp-topbar"><span>\U0001f3ac Video</span><span>{len(ordered)} video</span></div><div class="bdp-grid">{"".join(cards)}</div></div>'
|
| 167 |
return f'<div class="tiktok-fullscreen-container" id="tiktok-fullscreen-feed"><div class="tiktok-fullscreen-feed">{"".join(slides)}</div></div>{grid}'
|
| 168 |
|
| 169 |
app.read_article=_pra
|
| 170 |
-
|
| 171 |
-
# ══ Patch JS: add counter + comment functions ══
|
| 172 |
-
_orig_js = app.JS_FUNC
|
| 173 |
-
if "bdpTikTokCmt" not in _orig_js:
|
| 174 |
-
_js = """
|
| 175 |
-
/* TikTok comment + counters */
|
| 176 |
-
window.bdpIncCounter=function(aid,type){
|
| 177 |
-
var k='bdp_'+type+'_'+aid;
|
| 178 |
-
var n=parseInt(localStorage.getItem(k)||'0')+1;
|
| 179 |
-
localStorage.setItem(k,n);
|
| 180 |
-
var el=document.getElementById((type==='shares'?'sc':type==='views'?'vc':'cc')+'-'+aid);
|
| 181 |
-
if(el)el.textContent=n;
|
| 182 |
-
};
|
| 183 |
-
window.bdpTikTokCmt=function(aid){
|
| 184 |
-
var n=document.getElementById('tcn-'+aid);
|
| 185 |
-
var t=document.getElementById('tct-'+aid);
|
| 186 |
-
if(!n||!t)return;
|
| 187 |
-
var nm=n.value.trim(),tx=t.value.trim();
|
| 188 |
-
if(!nm||!tx){window.bdpToast('Nh\\u1eadp t\\u00ean v\\u00e0 b\\u00ecnh lu\\u1eadn');return;}
|
| 189 |
-
var k='bdp_cmt_'+aid;
|
| 190 |
-
var c=JSON.parse(localStorage.getItem(k)||'[]');
|
| 191 |
-
c.push({name:nm,text:tx,date:new Date().toLocaleString('vi-VN')});
|
| 192 |
-
localStorage.setItem(k,JSON.stringify(c));
|
| 193 |
-
t.value='';
|
| 194 |
-
window.bdpIncCounter(aid,'comments');
|
| 195 |
-
window.bdpRenderTikTokCmt(aid);
|
| 196 |
-
window.bdpToast('\\u2705 \\u0110\\u00e3 g\\u1eedi!');
|
| 197 |
-
};
|
| 198 |
-
window.bdpRenderTikTokCmt=function(aid){
|
| 199 |
-
var l=document.getElementById('tcl-'+aid);if(!l)return;
|
| 200 |
-
var c=JSON.parse(localStorage.getItem('bdp_cmt_'+aid)||'[]');
|
| 201 |
-
if(!c.length){l.innerHTML='<p style="color:#666;font-size:11px;">Ch\\u01b0a c\\u00f3 b\\u00ecnh lu\\u1eadn</p>';return;}
|
| 202 |
-
var h='';for(var i=c.length-1;i>=0;i--){var x=c[i];h+='<div class="cmt-item"><b>'+x.name+'</b> <small>'+x.date+'</small><p>'+x.text.replace(/</g,'<')+'</p></div>';}
|
| 203 |
-
l.innerHTML=h;
|
| 204 |
-
};
|
| 205 |
-
/* Init counters on slide visible */
|
| 206 |
-
window.bdpInitCounters=function(){
|
| 207 |
-
document.querySelectorAll('.tiktok-slide[data-aid]').forEach(function(sl){
|
| 208 |
-
var aid=sl.getAttribute('data-aid');if(!aid||sl._cInit)return;sl._cInit=true;
|
| 209 |
-
var vc=parseInt(localStorage.getItem('bdp_views_'+aid)||'0');
|
| 210 |
-
var sc=parseInt(localStorage.getItem('bdp_shares_'+aid)||'0');
|
| 211 |
-
var cc=parseInt(localStorage.getItem('bdp_comments_'+aid)||'0');
|
| 212 |
-
var ve=document.getElementById('vc-'+aid);if(ve)ve.textContent=vc;
|
| 213 |
-
var se=document.getElementById('sc-'+aid);if(se)se.textContent=sc;
|
| 214 |
-
var ce=document.getElementById('cc-'+aid);if(ce)ce.textContent=cc;
|
| 215 |
-
window.bdpRenderTikTokCmt(aid);
|
| 216 |
-
});
|
| 217 |
-
};
|
| 218 |
-
setInterval(window.bdpInitCounters,1000);
|
| 219 |
-
/* Increment view when video plays */
|
| 220 |
-
var _origActivate=window._tikTokActivate;
|
| 221 |
-
"""
|
| 222 |
-
idx = _orig_js.rfind("var hh=window.location.hash")
|
| 223 |
-
if idx > 0:
|
| 224 |
-
app.JS_FUNC = _orig_js[:idx] + _js + "\n" + _orig_js[idx:]
|
| 225 |
-
else:
|
| 226 |
-
idx = _orig_js.rfind("}")
|
| 227 |
-
if idx > 0:
|
| 228 |
-
app.JS_FUNC = _orig_js[:idx] + _js + "\n" + _orig_js[idx:]
|
| 229 |
-
|
| 230 |
app.demo.css=app.CSS
|
| 231 |
demo=app.demo
|
| 232 |
if __name__=="__main__":demo.launch()
|
|
|
|
| 13 |
.tiktok-fullscreen-container.fullheight-mode .tiktok-video{object-fit:cover!important}
|
| 14 |
.tiktok-fullheight-btn{position:absolute;bottom:70px;right:12px;background:rgba(255,255,255,.15);color:#fff;border:none;padding:6px 12px;border-radius:16px;font-size:11px;cursor:pointer;z-index:8;backdrop-filter:blur(6px)}
|
| 15 |
.tiktok-fullheight-btn.active{background:rgba(92,184,122,.5)}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
"""
|
| 17 |
FULLWIDTH_CSS = """
|
| 18 |
body,.gradio-container,.main,.contain{margin:0!important;padding:0!important;max-width:100%!important;width:100%!important}
|
|
|
|
| 116 |
po=app.safe_url(v.get("poster",""));pa=f' poster="{po}"' if po else ""
|
| 117 |
vs=v["src"];aid=app.make_id(v["link"]);s=app.slug(v["title"])
|
| 118 |
orig_url=app.esc(v["link"])
|
| 119 |
+
sj=f"event.stopPropagation();window.bdpShareOriginal('{app.esc(v['title'])}','{orig_url}')"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
vt=f'<video class="tiktok-video" playsinline preload="metadata"{pa} data-hls-src="{vs}" muted loop></video>' if v.get("vtype")=="hls" else f'<video class="tiktok-video" playsinline preload="metadata"{pa} muted loop><source src="{app.safe_url(vs)}" type="video/mp4"></video>'
|
| 121 |
fb='<button class="tiktok-fullheight-btn" onclick="event.stopPropagation();var c=this.closest(\'.tiktok-fullscreen-container\');c.classList.toggle(\'fullheight-mode\');var on=c.classList.contains(\'fullheight-mode\');c.querySelectorAll(\'.tiktok-fullheight-btn\').forEach(function(b){b.classList.toggle(\'active\',on);b.textContent=on?\'\\u2B07 Contain\':\'\\u2922 Fullheight\';});">\u2922 Fullheight</button>'
|
| 122 |
+
slides.append(f'<div class="tiktok-slide" data-index="{vi}" data-aid="{aid}">{vt}<div class="tiktok-pause-icon">\u25b6</div><div class="tiktok-seek-controls"><button class="tiktok-seek-btn" onclick="event.stopPropagation();window.bdpSeek(this,-10)">\u23ea 10s</button><button class="tiktok-seek-btn" onclick="event.stopPropagation();window.bdpSeek(this,10)">10s \u23e9</button></div><div class="tiktok-bottom"><span class="bdp-badge {badge}">{sl}</span><p class="tiktok-title">{v["title"]}</p><div class="tiktok-actions"><button class="tiktok-action-btn" onclick="{sj}">\U0001f4e4 Chia s\u1ebb</button></div></div>{fb}<div class="tiktok-unmute-hint" onclick="window.bdpTikTokUnmute(this)">\U0001f507 B\u1eadt ti\u1ebfng</div><span class="tiktok-counter">{vi+1}/{len(ordered)}</span></div>')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 123 |
img=app.safe_url(v.get("img")or v.get("poster",""))
|
| 124 |
cards.append(f'<div class="bdp-card" onclick="window.bdpOpen(\'{app.esc(v["link"])}\',\'{aid}\',\'{s}\')"><div class="bdp-card-img"><img src="{img}" alt="" class="bdp-lazy-img"><div class="bdp-play-overlay">\u25b6</div></div><div class="bdp-card-body"><span class="bdp-badge {badge}">{sl}</span><h3 class="bdp-card-title">{v["title"]}</h3></div></div>')
|
| 125 |
grid=f'<div class="bdp-wrap"><div class="bdp-topbar"><span>\U0001f3ac Video</span><span>{len(ordered)} video</span></div><div class="bdp-grid">{"".join(cards)}</div></div>'
|
| 126 |
return f'<div class="tiktok-fullscreen-container" id="tiktok-fullscreen-feed"><div class="tiktok-fullscreen-feed">{"".join(slides)}</div></div>{grid}'
|
| 127 |
|
| 128 |
app.read_article=_pra
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
app.demo.css=app.CSS
|
| 130 |
demo=app.demo
|
| 131 |
if __name__=="__main__":demo.launch()
|