bep40 commited on
Commit
2aaf385
·
verified ·
1 Parent(s): 689f9b9

Fix: highlight fullheight TikTok layout, prevent slide deletion after load"

Browse files
Files changed (1) hide show
  1. patch_extra.py +40 -46
patch_extra.py CHANGED
@@ -1,7 +1,6 @@
1
- """Extra CSS/JS fixes injected AFTER main PATCH_INJECT."""
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
- /* LIVESCORE COMPREHENSIVE CSS */
15
- /* Covers: fixtures, live, results, BXH, */
16
- /* match overlay (commentary, stats) */
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,.ls-content .fixture-item:hover{background:#1a2a1f}
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,.ls-content .result a{color:#fff;text-decoration:none;font-weight:800;font-size:12px}
44
- .ls-content .status span,.ls-content .match-score span,.ls-content .score span{display:block}
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,.ls-content table .club img,.mo-body table .team-name img,.mo-body table .club-name img{width:16px;height:16px;object-fit:contain}
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;padding-top:2px}
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,.mo-body .progress-bar{height:6px;background:#333;border-radius:3px;overflow:hidden;flex:2}
88
- .mo-body .stat-bar-fill,.mo-body .progress-fill{height:100%;background:#2d8659;border-radius:3px}
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
- // Kill old renderers that create duplicate Short AI slides
104
- window.renderAIShortHome=function(){};
105
  window.renderAIShorts7=function(){};
106
  window.renderTopicWallE=function(){};
107
  window.renderAiShorts=function(){};
108
- setInterval(function(){document.querySelectorAll('#ai-short-home,.ai-short-home,[id*="ai-shorts-patched"]').forEach(function(el){el.remove()});},2000);
109
- // Progress toast for short creation
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
- if(!r.ok||j.error)throw new Error(j.error||'Lỗi');
119
- showShortProgress('✅ Đã tạo Short AI!');
120
- setTimeout(hideShortProgress,3000);
121
  if(typeof renderShortAISlide==='function')renderShortAISlide();
122
- }catch(e){
123
- showShortProgress(' Lỗi: '+e.message);
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>