Spaces:
Running
Running
Fix: highlight fullheight TikTok layout, prevent slide deletion after load"
Browse files- patch_extra.py +40 -46
patch_extra.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
| 1 |
-
"""Extra CSS/JS
|
| 2 |
EXTRA_FIX = r'''
|
| 3 |
<style>
|
| 4 |
-
/* Force correct position for Short AI interaction buttons */
|
| 5 |
.tiktok-slide{position:relative!important}
|
| 6 |
.tiktok-right{position:absolute!important;right:8px!important;bottom:100px!important;display:flex!important;flex-direction:column!important;align-items:center!important;gap:14px!important;z-index:5!important}
|
| 7 |
.tiktok-right-btn{display:flex!important;flex-direction:column!important;align-items:center!important;gap:2px!important;background:none!important;border:0!important;color:#fff!important;font-size:10px!important;cursor:pointer!important}
|
|
@@ -9,29 +8,22 @@ EXTRA_FIX = r'''
|
|
| 9 |
.tiktok-right-btn .count{font-size:10px!important;color:#ddd!important}
|
| 10 |
#short-progress-toast{position:fixed;bottom:70px;left:50%;transform:translateX(-50%);background:#2d8659;color:#fff;padding:10px 20px;border-radius:20px;font-size:12px;z-index:99998;box-shadow:0 4px 12px rgba(0,0,0,.4);display:none;white-space:nowrap}
|
| 11 |
#ai-short-home,.ai-short-home,.ai-short-card-final,[id*="ai-shorts-patched"]{display:none!important}
|
| 12 |
-
|
| 13 |
-
/
|
| 14 |
-
/
|
| 15 |
-
|
| 16 |
-
/*
|
| 17 |
-
/* ============================================ */
|
| 18 |
-
|
| 19 |
-
/* --- General ls-content --- */
|
| 20 |
.ls-content{max-height:480px;overflow-y:auto;padding:0 6px 8px;font-size:12px;color:#ddd}
|
| 21 |
.ls-content ul,.ls-content ol{list-style:none;padding:0;margin:0}
|
| 22 |
.ls-content li{padding:0;margin:0}
|
| 23 |
.ls-content a{color:#5cb87a;text-decoration:none}
|
| 24 |
.ls-content img{max-width:100%;vertical-align:middle}
|
| 25 |
-
|
| 26 |
-
/* --- League group headers --- */
|
| 27 |
.ls-content .matchs-league,.ls-content .league-group{list-style:none;padding:0;margin:0}
|
| 28 |
.ls-content .title-content,.ls-content .league-title,.ls-content .group-title,.ls-content .league-header{display:flex;gap:6px;align-items:center;background:#222;border-radius:4px;margin:4px 0;padding:5px 8px}
|
| 29 |
.ls-content .title-content img,.ls-content .league-title img,.ls-content .group-title img,.ls-content .league-header img{width:18px;height:18px;object-fit:contain}
|
| 30 |
.ls-content .title-content strong,.ls-content .league-title strong,.ls-content .league-title span,.ls-content .group-title strong,.ls-content .league-header strong,.ls-content .league-header span{font-size:11px;color:#ccc;font-weight:700}
|
| 31 |
-
|
| 32 |
-
/* --- Match items (fixtures/live/results) --- */
|
| 33 |
.ls-content .match-detail,.ls-content .match-item,.ls-content .fixture-item{padding:6px;border-bottom:1px solid #262626;cursor:pointer}
|
| 34 |
-
.ls-content .match-detail:hover,.ls-content .match-item:hover
|
| 35 |
.ls-content .match,.ls-content .match-row{display:flex;flex-wrap:wrap;align-items:center;gap:4px}
|
| 36 |
.ls-content .datetime,.ls-content .match-time,.ls-content .time,.ls-content .kick-off{width:100%;font-size:9px;color:#888}
|
| 37 |
.ls-content .teams,.ls-content .match-teams{display:flex;width:100%;align-items:center;gap:4px}
|
|
@@ -40,21 +32,19 @@ EXTRA_FIX = r'''
|
|
| 40 |
.ls-content .team .logo img,.ls-content .match-team .logo img,.ls-content .team-logo img{width:18px;height:18px;object-fit:contain}
|
| 41 |
.ls-content .home-team{justify-content:flex-end;text-align:right}
|
| 42 |
.ls-content .status,.ls-content .match-score,.ls-content .score,.ls-content .result{flex:0 0 54px;text-align:center}
|
| 43 |
-
.ls-content .status a,.ls-content .match-score a,.ls-content .score a
|
| 44 |
-
.ls-content .status span,.ls-content .match-score span
|
| 45 |
.ls-content .status .label,.ls-content .match-status,.ls-content .status-label{font-size:8px;color:#888;display:block}
|
| 46 |
.ls-content .status .label.live,.ls-content .match-status.live,.ls-content .live-label,.ls-content .is-live{color:#e74c3c;font-weight:700;animation:pulse-live 1.5s infinite}
|
| 47 |
@keyframes pulse-live{0%,100%{opacity:1}50%{opacity:.5}}
|
| 48 |
.ls-content .vs,.ls-content .score-vs{color:#fff;font-weight:800}
|
| 49 |
.ls-content .info,.ls-content .btns,.ls-content .match-info,.ls-content .extra-info{display:none}
|
| 50 |
-
|
| 51 |
-
/* --- BXH Tables (standings) --- */
|
| 52 |
.ls-content table,.mo-body table{width:100%;border-collapse:collapse;font-size:11px;color:#ccc}
|
| 53 |
.ls-content table th,.mo-body table th{background:#222;color:#999;padding:5px 4px;text-align:left;font-size:10px;border-bottom:1px solid #333;position:sticky;top:0;z-index:1}
|
| 54 |
.ls-content table td,.mo-body table td{padding:4px 3px;border-bottom:1px solid #1a1a1a}
|
| 55 |
.ls-content table tr:hover td,.mo-body table tr:hover td{background:#1a2a1f}
|
| 56 |
.ls-content table .team-name,.ls-content table .club-name,.ls-content table .club,.mo-body table .team-name,.mo-body table .club-name{display:flex;align-items:center;gap:4px;white-space:nowrap}
|
| 57 |
-
.ls-content table .team-name img,.ls-content table .club-name img,.
|
| 58 |
.ls-content table .highlight,.ls-content table .top,.ls-content table .ucl,.mo-body table .highlight{color:#5cb87a;font-weight:700}
|
| 59 |
.ls-content table .relegation,.ls-content table .bottom{color:#e74c3c}
|
| 60 |
.ls-content table .pos,.ls-content table .rank{width:20px;text-align:center;font-weight:700;color:#999}
|
|
@@ -63,14 +53,12 @@ EXTRA_FIX = r'''
|
|
| 63 |
.ls-content table .form .w,.ls-content table .recent .w{background:#2d8659;color:#fff}
|
| 64 |
.ls-content table .form .d,.ls-content table .recent .d{background:#f0c040;color:#111}
|
| 65 |
.ls-content table .form .l,.ls-content table .recent .l{background:#c0392b;color:#fff}
|
| 66 |
-
|
| 67 |
-
/* --- Match Overlay (commentary/diễn biến + stats) --- */
|
| 68 |
.mo-body{padding:8px;overflow-x:auto;font-size:12px;color:#ddd}
|
| 69 |
.mo-body ul,.mo-body ol{list-style:none;padding:0;margin:0}
|
| 70 |
.mo-body li{padding:5px 0;border-bottom:1px solid #222}
|
| 71 |
.mo-body .commentary-item,.mo-body .event-item,.mo-body .comment-row{display:flex;gap:8px;padding:6px 4px;border-bottom:1px solid #1f1f1f;align-items:flex-start}
|
| 72 |
.mo-body .commentary-item:hover,.mo-body .event-item:hover{background:#1a2a1f}
|
| 73 |
-
.mo-body .minute,.mo-body .event-time,.mo-body .time-col{flex:0 0 36px;font-size:10px;color:#5cb87a;font-weight:700;text-align:right
|
| 74 |
.mo-body .comment-text,.mo-body .event-text,.mo-body .description,.mo-body .text-col{flex:1;font-size:12px;line-height:1.45;color:#ccc}
|
| 75 |
.mo-body .event-icon,.mo-body .icon-col{flex:0 0 24px;text-align:center;font-size:14px}
|
| 76 |
.mo-body .goal,.mo-body .goal-event{color:#f0c040;font-weight:700}
|
|
@@ -78,35 +66,47 @@ EXTRA_FIX = r'''
|
|
| 78 |
.mo-body .yellow-card,.mo-body .yellow{color:#f0c040}
|
| 79 |
.mo-body .substitution,.mo-body .sub{color:#5cb87a}
|
| 80 |
.mo-body .halftime,.mo-body .period-break,.mo-body .half-time{background:#222;text-align:center;padding:8px;font-size:11px;color:#999;border-radius:4px;margin:8px 0}
|
| 81 |
-
|
| 82 |
-
/* --- Stats tab (player performance / match stats) --- */
|
| 83 |
.mo-body .stat-row,.mo-body .stats-item{display:flex;align-items:center;gap:8px;padding:6px 0;border-bottom:1px solid #1f1f1f}
|
| 84 |
.mo-body .stat-label,.mo-body .stat-name{flex:1;text-align:center;font-size:11px;color:#999}
|
| 85 |
.mo-body .stat-home,.mo-body .stat-val-home{flex:1;text-align:right;font-size:12px;font-weight:700;color:#eee}
|
| 86 |
.mo-body .stat-away,.mo-body .stat-val-away{flex:1;text-align:left;font-size:12px;font-weight:700;color:#eee}
|
| 87 |
-
.mo-body .stat-bar
|
| 88 |
-
.mo-body .stat-bar-fill
|
| 89 |
.mo-body .player-item,.mo-body .player-row{display:flex;gap:6px;padding:5px 4px;border-bottom:1px solid #1f1f1f;align-items:center}
|
| 90 |
.mo-body .player-item img,.mo-body .player-row img{width:28px;height:28px;border-radius:50%;object-fit:cover;background:#333}
|
| 91 |
.mo-body .player-name{font-size:11px;color:#eee;flex:1}
|
| 92 |
.mo-body .player-rating,.mo-body .player-score{font-size:12px;font-weight:800;color:#f0c040;padding:2px 6px;background:#222;border-radius:4px}
|
| 93 |
-
.mo-body .player-stats{font-size:10px;color:#888}
|
| 94 |
.mo-body .section-title,.mo-body .group-header{font-size:12px;font-weight:700;color:#5cb87a;padding:8px 0 4px;border-bottom:1px solid #333;margin-top:8px}
|
| 95 |
-
.mo-body .lineup,.mo-body .formation{padding:8px 0}
|
| 96 |
-
.mo-body .lineup .player,.mo-body .formation .player{display:inline-flex;align-items:center;gap:4px;background:#222;border-radius:12px;padding:3px 8px;margin:2px;font-size:10px;color:#ccc}
|
| 97 |
-
.mo-body .lineup .player img,.mo-body .formation .player img{width:16px;height:16px;border-radius:50%}
|
| 98 |
-
.mo-body .lineup .player .number,.mo-body .formation .player .number{color:#5cb87a;font-weight:700}
|
| 99 |
</style>
|
| 100 |
<div id="short-progress-toast"></div>
|
| 101 |
<script>
|
| 102 |
(function(){
|
| 103 |
-
//
|
| 104 |
-
|
| 105 |
window.renderAIShorts7=function(){};
|
| 106 |
window.renderTopicWallE=function(){};
|
| 107 |
window.renderAiShorts=function(){};
|
| 108 |
-
|
| 109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
window.showShortProgress=function(msg){var t=document.getElementById('short-progress-toast');if(t){t.textContent=msg;t.style.display='block';}};
|
| 111 |
window.hideShortProgress=function(){var t=document.getElementById('short-progress-toast');if(t)t.style.display='none';};
|
| 112 |
window.makeShortFromPost=async function(pid,btn){
|
|
@@ -114,17 +114,11 @@ window.makeShortFromPost=async function(pid,btn){
|
|
| 114 |
if(btn){btn.disabled=true;btn.textContent='Đang tạo...';}
|
| 115 |
try{
|
| 116 |
var r=await fetch('/api/ai/short/'+pid,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({voice:'nu',emotion:'neutral',speed:1.2})});
|
| 117 |
-
var j=await r.json();
|
| 118 |
-
|
| 119 |
-
showShortProgress('✅ Đã tạo Short AI!');
|
| 120 |
-
setTimeout(hideShortProgress,3000);
|
| 121 |
if(typeof renderShortAISlide==='function')renderShortAISlide();
|
| 122 |
-
}catch(e){
|
| 123 |
-
|
| 124 |
-
setTimeout(hideShortProgress,4000);
|
| 125 |
-
}finally{
|
| 126 |
-
if(btn){btn.disabled=false;btn.textContent='🎬 Tạo Short AI';}
|
| 127 |
-
}
|
| 128 |
};
|
| 129 |
})();
|
| 130 |
</script>
|
|
|
|
| 1 |
+
"""Extra CSS/JS: livescore, highlight TikTok layout, prevent slide deletion."""
|
| 2 |
EXTRA_FIX = r'''
|
| 3 |
<style>
|
|
|
|
| 4 |
.tiktok-slide{position:relative!important}
|
| 5 |
.tiktok-right{position:absolute!important;right:8px!important;bottom:100px!important;display:flex!important;flex-direction:column!important;align-items:center!important;gap:14px!important;z-index:5!important}
|
| 6 |
.tiktok-right-btn{display:flex!important;flex-direction:column!important;align-items:center!important;gap:2px!important;background:none!important;border:0!important;color:#fff!important;font-size:10px!important;cursor:pointer!important}
|
|
|
|
| 8 |
.tiktok-right-btn .count{font-size:10px!important;color:#ddd!important}
|
| 9 |
#short-progress-toast{position:fixed;bottom:70px;left:50%;transform:translateX(-50%);background:#2d8659;color:#fff;padding:10px 20px;border-radius:20px;font-size:12px;z-index:99998;box-shadow:0 4px 12px rgba(0,0,0,.4);display:none;white-space:nowrap}
|
| 10 |
#ai-short-home,.ai-short-home,.ai-short-card-final,[id*="ai-shorts-patched"]{display:none!important}
|
| 11 |
+
/* === HIGHLIGHT PLAYER: fullheight TikTok style === */
|
| 12 |
+
.vp-wrap{aspect-ratio:1/1!important;width:100%!important;max-height:100vh!important;background:#000!important}
|
| 13 |
+
.vp-wrap.wide{aspect-ratio:16/9!important}
|
| 14 |
+
.vp-wrap video,.vp-wrap iframe{width:100%!important;height:100%!important;object-fit:contain!important}
|
| 15 |
+
/* === LIVESCORE CSS === */
|
|
|
|
|
|
|
|
|
|
| 16 |
.ls-content{max-height:480px;overflow-y:auto;padding:0 6px 8px;font-size:12px;color:#ddd}
|
| 17 |
.ls-content ul,.ls-content ol{list-style:none;padding:0;margin:0}
|
| 18 |
.ls-content li{padding:0;margin:0}
|
| 19 |
.ls-content a{color:#5cb87a;text-decoration:none}
|
| 20 |
.ls-content img{max-width:100%;vertical-align:middle}
|
|
|
|
|
|
|
| 21 |
.ls-content .matchs-league,.ls-content .league-group{list-style:none;padding:0;margin:0}
|
| 22 |
.ls-content .title-content,.ls-content .league-title,.ls-content .group-title,.ls-content .league-header{display:flex;gap:6px;align-items:center;background:#222;border-radius:4px;margin:4px 0;padding:5px 8px}
|
| 23 |
.ls-content .title-content img,.ls-content .league-title img,.ls-content .group-title img,.ls-content .league-header img{width:18px;height:18px;object-fit:contain}
|
| 24 |
.ls-content .title-content strong,.ls-content .league-title strong,.ls-content .league-title span,.ls-content .group-title strong,.ls-content .league-header strong,.ls-content .league-header span{font-size:11px;color:#ccc;font-weight:700}
|
|
|
|
|
|
|
| 25 |
.ls-content .match-detail,.ls-content .match-item,.ls-content .fixture-item{padding:6px;border-bottom:1px solid #262626;cursor:pointer}
|
| 26 |
+
.ls-content .match-detail:hover,.ls-content .match-item:hover{background:#1a2a1f}
|
| 27 |
.ls-content .match,.ls-content .match-row{display:flex;flex-wrap:wrap;align-items:center;gap:4px}
|
| 28 |
.ls-content .datetime,.ls-content .match-time,.ls-content .time,.ls-content .kick-off{width:100%;font-size:9px;color:#888}
|
| 29 |
.ls-content .teams,.ls-content .match-teams{display:flex;width:100%;align-items:center;gap:4px}
|
|
|
|
| 32 |
.ls-content .team .logo img,.ls-content .match-team .logo img,.ls-content .team-logo img{width:18px;height:18px;object-fit:contain}
|
| 33 |
.ls-content .home-team{justify-content:flex-end;text-align:right}
|
| 34 |
.ls-content .status,.ls-content .match-score,.ls-content .score,.ls-content .result{flex:0 0 54px;text-align:center}
|
| 35 |
+
.ls-content .status a,.ls-content .match-score a,.ls-content .score a{color:#fff;text-decoration:none;font-weight:800;font-size:12px}
|
| 36 |
+
.ls-content .status span,.ls-content .match-score span{display:block}
|
| 37 |
.ls-content .status .label,.ls-content .match-status,.ls-content .status-label{font-size:8px;color:#888;display:block}
|
| 38 |
.ls-content .status .label.live,.ls-content .match-status.live,.ls-content .live-label,.ls-content .is-live{color:#e74c3c;font-weight:700;animation:pulse-live 1.5s infinite}
|
| 39 |
@keyframes pulse-live{0%,100%{opacity:1}50%{opacity:.5}}
|
| 40 |
.ls-content .vs,.ls-content .score-vs{color:#fff;font-weight:800}
|
| 41 |
.ls-content .info,.ls-content .btns,.ls-content .match-info,.ls-content .extra-info{display:none}
|
|
|
|
|
|
|
| 42 |
.ls-content table,.mo-body table{width:100%;border-collapse:collapse;font-size:11px;color:#ccc}
|
| 43 |
.ls-content table th,.mo-body table th{background:#222;color:#999;padding:5px 4px;text-align:left;font-size:10px;border-bottom:1px solid #333;position:sticky;top:0;z-index:1}
|
| 44 |
.ls-content table td,.mo-body table td{padding:4px 3px;border-bottom:1px solid #1a1a1a}
|
| 45 |
.ls-content table tr:hover td,.mo-body table tr:hover td{background:#1a2a1f}
|
| 46 |
.ls-content table .team-name,.ls-content table .club-name,.ls-content table .club,.mo-body table .team-name,.mo-body table .club-name{display:flex;align-items:center;gap:4px;white-space:nowrap}
|
| 47 |
+
.ls-content table .team-name img,.ls-content table .club-name img,.mo-body table .team-name img{width:16px;height:16px;object-fit:contain}
|
| 48 |
.ls-content table .highlight,.ls-content table .top,.ls-content table .ucl,.mo-body table .highlight{color:#5cb87a;font-weight:700}
|
| 49 |
.ls-content table .relegation,.ls-content table .bottom{color:#e74c3c}
|
| 50 |
.ls-content table .pos,.ls-content table .rank{width:20px;text-align:center;font-weight:700;color:#999}
|
|
|
|
| 53 |
.ls-content table .form .w,.ls-content table .recent .w{background:#2d8659;color:#fff}
|
| 54 |
.ls-content table .form .d,.ls-content table .recent .d{background:#f0c040;color:#111}
|
| 55 |
.ls-content table .form .l,.ls-content table .recent .l{background:#c0392b;color:#fff}
|
|
|
|
|
|
|
| 56 |
.mo-body{padding:8px;overflow-x:auto;font-size:12px;color:#ddd}
|
| 57 |
.mo-body ul,.mo-body ol{list-style:none;padding:0;margin:0}
|
| 58 |
.mo-body li{padding:5px 0;border-bottom:1px solid #222}
|
| 59 |
.mo-body .commentary-item,.mo-body .event-item,.mo-body .comment-row{display:flex;gap:8px;padding:6px 4px;border-bottom:1px solid #1f1f1f;align-items:flex-start}
|
| 60 |
.mo-body .commentary-item:hover,.mo-body .event-item:hover{background:#1a2a1f}
|
| 61 |
+
.mo-body .minute,.mo-body .event-time,.mo-body .time-col{flex:0 0 36px;font-size:10px;color:#5cb87a;font-weight:700;text-align:right}
|
| 62 |
.mo-body .comment-text,.mo-body .event-text,.mo-body .description,.mo-body .text-col{flex:1;font-size:12px;line-height:1.45;color:#ccc}
|
| 63 |
.mo-body .event-icon,.mo-body .icon-col{flex:0 0 24px;text-align:center;font-size:14px}
|
| 64 |
.mo-body .goal,.mo-body .goal-event{color:#f0c040;font-weight:700}
|
|
|
|
| 66 |
.mo-body .yellow-card,.mo-body .yellow{color:#f0c040}
|
| 67 |
.mo-body .substitution,.mo-body .sub{color:#5cb87a}
|
| 68 |
.mo-body .halftime,.mo-body .period-break,.mo-body .half-time{background:#222;text-align:center;padding:8px;font-size:11px;color:#999;border-radius:4px;margin:8px 0}
|
|
|
|
|
|
|
| 69 |
.mo-body .stat-row,.mo-body .stats-item{display:flex;align-items:center;gap:8px;padding:6px 0;border-bottom:1px solid #1f1f1f}
|
| 70 |
.mo-body .stat-label,.mo-body .stat-name{flex:1;text-align:center;font-size:11px;color:#999}
|
| 71 |
.mo-body .stat-home,.mo-body .stat-val-home{flex:1;text-align:right;font-size:12px;font-weight:700;color:#eee}
|
| 72 |
.mo-body .stat-away,.mo-body .stat-val-away{flex:1;text-align:left;font-size:12px;font-weight:700;color:#eee}
|
| 73 |
+
.mo-body .stat-bar{height:6px;background:#333;border-radius:3px;overflow:hidden;flex:2}
|
| 74 |
+
.mo-body .stat-bar-fill{height:100%;background:#2d8659;border-radius:3px}
|
| 75 |
.mo-body .player-item,.mo-body .player-row{display:flex;gap:6px;padding:5px 4px;border-bottom:1px solid #1f1f1f;align-items:center}
|
| 76 |
.mo-body .player-item img,.mo-body .player-row img{width:28px;height:28px;border-radius:50%;object-fit:cover;background:#333}
|
| 77 |
.mo-body .player-name{font-size:11px;color:#eee;flex:1}
|
| 78 |
.mo-body .player-rating,.mo-body .player-score{font-size:12px;font-weight:800;color:#f0c040;padding:2px 6px;background:#222;border-radius:4px}
|
|
|
|
| 79 |
.mo-body .section-title,.mo-body .group-header{font-size:12px;font-weight:700;color:#5cb87a;padding:8px 0 4px;border-bottom:1px solid #333;margin-top:8px}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
</style>
|
| 81 |
<div id="short-progress-toast"></div>
|
| 82 |
<script>
|
| 83 |
(function(){
|
| 84 |
+
// === PREVENT OLD JS FROM DESTROYING SLIDES ===
|
| 85 |
+
// Only kill renderers that create DUPLICATE slides, not our new ones
|
| 86 |
window.renderAIShorts7=function(){};
|
| 87 |
window.renderTopicWallE=function(){};
|
| 88 |
window.renderAiShorts=function(){};
|
| 89 |
+
// Override renderAIShortHome only if it's not ours
|
| 90 |
+
if(window.renderAIShortHome&&window.renderAIShortHome.toString().indexOf('short-ai-final-slide')===-1){
|
| 91 |
+
window.renderAIShortHome=function(){};
|
| 92 |
+
}
|
| 93 |
+
// Remove only old duplicate elements, NOT #short-ai-final-slide or [data-wall-live]
|
| 94 |
+
setInterval(function(){
|
| 95 |
+
document.querySelectorAll('#ai-short-home,.ai-short-home').forEach(function(el){
|
| 96 |
+
if(el.id!=='short-ai-final-slide')el.remove();
|
| 97 |
+
});
|
| 98 |
+
},3000);
|
| 99 |
+
// Prevent ensureNewsShortsHome from running repeatedly and wiping DOM
|
| 100 |
+
var _ensureRan=false;
|
| 101 |
+
var _origEnsure=window.ensureNewsShortsHome;
|
| 102 |
+
window.ensureNewsShortsHome=function(){if(_ensureRan)return;_ensureRan=true;if(_origEnsure)try{_origEnsure();}catch(e){}};
|
| 103 |
+
|
| 104 |
+
// === BLOCK /api/shorts?refresh=1 for first 8s (faster initial load) ===
|
| 105 |
+
var _origFetch=window.fetch,_allowRefresh=false;
|
| 106 |
+
window.fetch=function(url,opts){try{if(String(url).includes('/api/shorts?refresh=1')&&!_allowRefresh)url='/api/shorts';}catch(e){}return _origFetch.call(this,url,opts);};
|
| 107 |
+
setTimeout(function(){_allowRefresh=true;},8000);
|
| 108 |
+
|
| 109 |
+
// === PROGRESS TOAST ===
|
| 110 |
window.showShortProgress=function(msg){var t=document.getElementById('short-progress-toast');if(t){t.textContent=msg;t.style.display='block';}};
|
| 111 |
window.hideShortProgress=function(){var t=document.getElementById('short-progress-toast');if(t)t.style.display='none';};
|
| 112 |
window.makeShortFromPost=async function(pid,btn){
|
|
|
|
| 114 |
if(btn){btn.disabled=true;btn.textContent='Đang tạo...';}
|
| 115 |
try{
|
| 116 |
var r=await fetch('/api/ai/short/'+pid,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({voice:'nu',emotion:'neutral',speed:1.2})});
|
| 117 |
+
var j=await r.json();if(!r.ok||j.error)throw new Error(j.error||'Lỗi');
|
| 118 |
+
showShortProgress('✅ Đã tạo Short AI!');setTimeout(hideShortProgress,3000);
|
|
|
|
|
|
|
| 119 |
if(typeof renderShortAISlide==='function')renderShortAISlide();
|
| 120 |
+
}catch(e){showShortProgress('❌ '+e.message);setTimeout(hideShortProgress,4000);}
|
| 121 |
+
finally{if(btn){btn.disabled=false;btn.textContent='🎬 Tạo Short AI';}}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 122 |
};
|
| 123 |
})();
|
| 124 |
</script>
|