Spaces:
Runtime error
Runtime error
css-only: video 3:4 ratio for all TikTok feeds + shorts thumbnail 3:4
Browse files- app_wrapper.py +15 -13
app_wrapper.py
CHANGED
|
@@ -8,14 +8,18 @@ import app
|
|
| 8 |
|
| 9 |
# ββ CSS Patches ββ
|
| 10 |
SHORTS_EXTRA_CSS = """
|
| 11 |
-
/*
|
| 12 |
-
.
|
| 13 |
/* TikTok feed fullwidth */
|
| 14 |
.tiktok-fullscreen-container{width:100%!important;max-width:100%!important;border-radius:0!important}
|
| 15 |
-
/*
|
| 16 |
-
.tiktok-fullscreen-container.
|
| 17 |
.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)}
|
| 18 |
.tiktok-fullheight-btn.active{background:rgba(92,184,122,.5)}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
"""
|
| 20 |
|
| 21 |
FULLWIDTH_CSS = """
|
|
@@ -43,7 +47,7 @@ div[class*="svelte"]{padding-left:0!important;padding-right:0!important}
|
|
| 43 |
|
| 44 |
if "vslide-shorts-item" not in app.CSS:
|
| 45 |
app.CSS += SHORTS_CSS
|
| 46 |
-
if "
|
| 47 |
app.CSS += SHORTS_EXTRA_CSS
|
| 48 |
if "FULLWIDTH: kill all Gradio padding" not in app.CSS:
|
| 49 |
app.CSS += FULLWIDTH_CSS
|
|
@@ -92,11 +96,11 @@ def _patched_render_homepage(articles, *args, **kwargs):
|
|
| 92 |
return html
|
| 93 |
app.render_homepage_html = _patched_render_homepage
|
| 94 |
|
| 95 |
-
# ββ Patch render_video_page_html:
|
| 96 |
_orig_render_video_page = app.render_video_page_html
|
| 97 |
def _patched_render_video_page():
|
| 98 |
html = _orig_render_video_page()
|
| 99 |
-
toggle_btn = '<button class="tiktok-fullheight-btn" onclick="event.stopPropagation();var c=this.closest(\'.tiktok-fullscreen-container\');c.classList.toggle(\'
|
| 100 |
html = html.replace('<div class="tiktok-unmute-hint"', toggle_btn + '<div class="tiktok-unmute-hint"')
|
| 101 |
return html
|
| 102 |
app.render_video_page_html = _patched_render_video_page
|
|
@@ -214,9 +218,8 @@ def _build_tiktok_html(videos, current_url, source_label):
|
|
| 214 |
else:
|
| 215 |
vtag = f'<video class="tiktok-video" playsinline preload="metadata"{poster_attr} muted loop><source src="{app.safe_url(vsrc)}" type="video/mp4"></video>'
|
| 216 |
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
fullheight_btn = '<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>'
|
| 220 |
|
| 221 |
slides.append(f'''<div class="tiktok-slide" data-index="{vi}" data-aid="{aid}">
|
| 222 |
{vtag}
|
|
@@ -232,7 +235,7 @@ def _build_tiktok_html(videos, current_url, source_label):
|
|
| 232 |
<button class="tiktok-action-btn" onclick="{share_js}">\U0001f4e4 Chia s\u1ebb</button>
|
| 233 |
</div>
|
| 234 |
</div>
|
| 235 |
-
{
|
| 236 |
<div class="tiktok-unmute-hint" onclick="window.bdpTikTokUnmute(this)">\U0001f507 B\u1eadt ti\u1ebfng</div>
|
| 237 |
<span class="tiktok-counter">{vi+1}/{len(ordered)}</span>
|
| 238 |
</div>''')
|
|
@@ -251,8 +254,7 @@ def _build_tiktok_html(videos, current_url, source_label):
|
|
| 251 |
grid_html = f'''<div class="bdp-wrap"><div class="bdp-topbar"><span>\U0001f3ac Video</span><span>{len(ordered)} video</span></div>
|
| 252 |
<div class="bdp-grid">{''.join(list_cards)}</div></div>'''
|
| 253 |
|
| 254 |
-
|
| 255 |
-
return f'''<div class="tiktok-fullscreen-container {mode_class}" id="tiktok-fullscreen-feed">
|
| 256 |
<div class="tiktok-fullscreen-feed">{''.join(slides)}</div>
|
| 257 |
</div>
|
| 258 |
{grid_html}'''
|
|
|
|
| 8 |
|
| 9 |
# ββ CSS Patches ββ
|
| 10 |
SHORTS_EXTRA_CSS = """
|
| 11 |
+
/* ALL TikTok feeds: video 3:4 crop center */
|
| 12 |
+
.tiktok-fullscreen-container .tiktok-video{object-fit:cover!important}
|
| 13 |
/* TikTok feed fullwidth */
|
| 14 |
.tiktok-fullscreen-container{width:100%!important;max-width:100%!important;border-radius:0!important}
|
| 15 |
+
/* Contain toggle: show full video */
|
| 16 |
+
.tiktok-fullscreen-container.contain-mode .tiktok-video{object-fit:contain!important}
|
| 17 |
.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)}
|
| 18 |
.tiktok-fullheight-btn.active{background:rgba(92,184,122,.5)}
|
| 19 |
+
/* Shorts thumbnail override to 3:4 */
|
| 20 |
+
.vslide-shorts-thumb{aspect-ratio:3/4!important}
|
| 21 |
+
.vslide-shorts-item{flex:0 0 120px!important}
|
| 22 |
+
@media(min-width:768px){.vslide-shorts-item{flex:0 0 140px!important}}
|
| 23 |
"""
|
| 24 |
|
| 25 |
FULLWIDTH_CSS = """
|
|
|
|
| 47 |
|
| 48 |
if "vslide-shorts-item" not in app.CSS:
|
| 49 |
app.CSS += SHORTS_CSS
|
| 50 |
+
if "3:4 crop center" not in app.CSS:
|
| 51 |
app.CSS += SHORTS_EXTRA_CSS
|
| 52 |
if "FULLWIDTH: kill all Gradio padding" not in app.CSS:
|
| 53 |
app.CSS += FULLWIDTH_CSS
|
|
|
|
| 96 |
return html
|
| 97 |
app.render_homepage_html = _patched_render_homepage
|
| 98 |
|
| 99 |
+
# ββ Patch render_video_page_html: contain toggle button ββ
|
| 100 |
_orig_render_video_page = app.render_video_page_html
|
| 101 |
def _patched_render_video_page():
|
| 102 |
html = _orig_render_video_page()
|
| 103 |
+
toggle_btn = '<button class="tiktok-fullheight-btn" onclick="event.stopPropagation();var c=this.closest(\'.tiktok-fullscreen-container\');c.classList.toggle(\'contain-mode\');var on=c.classList.contains(\'contain-mode\');c.querySelectorAll(\'.tiktok-fullheight-btn\').forEach(function(b){b.classList.toggle(\'active\',on);b.textContent=on?\'\\u2922 3:4\':\'\\u2B07 Contain\';});">\u2B07 Contain</button>'
|
| 104 |
html = html.replace('<div class="tiktok-unmute-hint"', toggle_btn + '<div class="tiktok-unmute-hint"')
|
| 105 |
return html
|
| 106 |
app.render_video_page_html = _patched_render_video_page
|
|
|
|
| 218 |
else:
|
| 219 |
vtag = f'<video class="tiktok-video" playsinline preload="metadata"{poster_attr} muted loop><source src="{app.safe_url(vsrc)}" type="video/mp4"></video>'
|
| 220 |
|
| 221 |
+
# Contain toggle button for all feeds
|
| 222 |
+
contain_btn = '<button class="tiktok-fullheight-btn" onclick="event.stopPropagation();var c=this.closest(\'.tiktok-fullscreen-container\');c.classList.toggle(\'contain-mode\');var on=c.classList.contains(\'contain-mode\');c.querySelectorAll(\'.tiktok-fullheight-btn\').forEach(function(b){b.classList.toggle(\'active\',on);b.textContent=on?\'\\u2922 3:4\':\'\\u2B07 Contain\';});">\u2B07 Contain</button>'
|
|
|
|
| 223 |
|
| 224 |
slides.append(f'''<div class="tiktok-slide" data-index="{vi}" data-aid="{aid}">
|
| 225 |
{vtag}
|
|
|
|
| 235 |
<button class="tiktok-action-btn" onclick="{share_js}">\U0001f4e4 Chia s\u1ebb</button>
|
| 236 |
</div>
|
| 237 |
</div>
|
| 238 |
+
{contain_btn}
|
| 239 |
<div class="tiktok-unmute-hint" onclick="window.bdpTikTokUnmute(this)">\U0001f507 B\u1eadt ti\u1ebfng</div>
|
| 240 |
<span class="tiktok-counter">{vi+1}/{len(ordered)}</span>
|
| 241 |
</div>''')
|
|
|
|
| 254 |
grid_html = f'''<div class="bdp-wrap"><div class="bdp-topbar"><span>\U0001f3ac Video</span><span>{len(ordered)} video</span></div>
|
| 255 |
<div class="bdp-grid">{''.join(list_cards)}</div></div>'''
|
| 256 |
|
| 257 |
+
return f'''<div class="tiktok-fullscreen-container" id="tiktok-fullscreen-feed">
|
|
|
|
| 258 |
<div class="tiktok-fullscreen-feed">{''.join(slides)}</div>
|
| 259 |
</div>
|
| 260 |
{grid_html}'''
|