mirror of
https://github.com/Dvorinka/bizoni.git
synced 2026-06-03 18:22:57 +00:00
fix matches
This commit is contained in:
+104
-22
@@ -16,8 +16,8 @@
|
||||
const [d, t] = s.split(' ');
|
||||
const [day, month, year] = d.split('.').map(Number);
|
||||
const [hour, minute] = t.split(':').map(Number);
|
||||
const dt = new Date(Date.UTC(year, month-1, day, hour, minute));
|
||||
// adjust to Prague timezone visually
|
||||
// Interpret as local time (Europe/Prague). Using local constructor avoids UTC offset skew.
|
||||
const dt = new Date(year, month-1, day, hour, minute);
|
||||
return dt;
|
||||
}catch(e){ return null; }
|
||||
}
|
||||
@@ -34,9 +34,24 @@
|
||||
.facr-tab{ padding:6px 10px; margin:4px; border-radius:16px; border:1px solid #c42221; color:#c42221; background:#ffffff; font-weight:600; }
|
||||
.facr-tab.active{ background:#c42221; color:#ffffff; }
|
||||
.facr-tab:hover{ background:#c42221cc; color:#ffffff; }
|
||||
.facr-inline-status{ margin-left:8px; font-weight:700; font-size:14px; white-space:nowrap; color:inherit; display:inline-block; vertical-align:middle; }
|
||||
/* Default (desktop): show middle only */
|
||||
#facr-countdown{ display:none !important; }
|
||||
.facr-inline-status{ display:none !important; }
|
||||
.facr-mob-center-score{ display:none; font-weight:700; font-size:24px; line-height:1; }
|
||||
/* Mobile: keep only the bottom countdown by default */
|
||||
@media (max-width: 767px){
|
||||
#facr-mid{ display:none !important; }
|
||||
#facr-countdown{ display:block !important; }
|
||||
.facr-inline-status{ display:none !important; }
|
||||
.facr-mob-center-score{ display:inline-block !important; }
|
||||
/* If finished, hide the bottom countdown */
|
||||
.facr-finished #facr-countdown{ display:none !important; }
|
||||
}
|
||||
@media (max-width: 480px){
|
||||
#facr-mid{ font-size:28px !important; min-width:100px; }
|
||||
.facr-tab{ padding:4px 8px; font-size:14px; }
|
||||
.facr-inline-status{ font-size:12px; margin-left:6px; }
|
||||
.facr-nav{ padding:4px 8px; }
|
||||
}
|
||||
`;
|
||||
@@ -158,11 +173,27 @@
|
||||
return;
|
||||
}
|
||||
|
||||
// Prefer first future match; if none, show the latest recent within 3 days
|
||||
// Selection policy:
|
||||
// 1) If there is any finished match within the last 3 days across competitions,
|
||||
// show the latest such finished match (keep result visible for 3 days)
|
||||
// 2) Otherwise, show the first future match
|
||||
// 3) If none, show the latest overall (shouldn't happen as items filtered by 3d window per-comp)
|
||||
const now = new Date();
|
||||
let autoIdx = items.findIndex(it => it.dt >= now);
|
||||
if(autoIdx === -1) autoIdx = items.length - 1;
|
||||
const idx = Math.min(state.matchIndex || autoIdx, items.length-1);
|
||||
const threeDms = 3*24*60*60*1000;
|
||||
let latestRecentIdx = -1;
|
||||
let latestRecentTime = -Infinity;
|
||||
items.forEach((it, i) => {
|
||||
const dtms = it.dt.getTime();
|
||||
if(dtms <= now.getTime() && now.getTime() - dtms <= threeDms){
|
||||
if(dtms > latestRecentTime){ latestRecentTime = dtms; latestRecentIdx = i; }
|
||||
}
|
||||
});
|
||||
let preferredIdx = latestRecentIdx;
|
||||
if(preferredIdx === -1){
|
||||
preferredIdx = items.findIndex(it => it.dt >= now);
|
||||
if(preferredIdx === -1) preferredIdx = items.length - 1;
|
||||
}
|
||||
const idx = Math.min(state.matchIndex || preferredIdx, items.length-1);
|
||||
const { comp, match:m } = items[idx];
|
||||
const compName = truncate(escapeHTML(comp.name || comp.code || 'Soutěž'), 60);
|
||||
|
||||
@@ -179,26 +210,60 @@
|
||||
const isToday = matchDayCZ === todayCZ();
|
||||
const startDt = m.date_time ? parseCZDate(m.date_time) : null;
|
||||
const diffMsPre = startDt ? (startDt.getTime() - new Date().getTime()) : 0;
|
||||
const midText = (!isToday && diffMsPre > 0) ? `Za ${fmtCountdownLong(diffMsPre)}` : (m.score || '-');
|
||||
const midText = (diffMsPre > 0) ? `Za ${fmtCountdownLong(diffMsPre)}` : (m.score || '-');
|
||||
|
||||
// Determine status flags and parse score parts if any
|
||||
const now2_forTpl = new Date();
|
||||
const startMs_forTpl = m.date_time ? parseCZDate(m.date_time).getTime() : 0;
|
||||
const diff_forTpl = startMs_forTpl - now2_forTpl.getTime();
|
||||
const twoH_forTpl = 2*60*60*1000;
|
||||
const threeD_forTpl = 3*24*60*60*1000;
|
||||
const isFuture = diff_forTpl > 0;
|
||||
const isLive = Math.abs(diff_forTpl) <= twoH_forTpl;
|
||||
const isRecentFinished = (!isFuture && !isLive && -diff_forTpl < threeD_forTpl);
|
||||
const scoreStr = m.score || '';
|
||||
const s1 = scoreStr && scoreStr.includes(':') ? escapeHTML(scoreStr.split(':')[0]) : '';
|
||||
const s2 = scoreStr && scoreStr.includes(':') ? escapeHTML(scoreStr.split(':')[1]) : '';
|
||||
// Date/time formatting for display lines
|
||||
const dtForDisp = startDt || (m.date_time ? parseCZDate(m.date_time) : null);
|
||||
const dd = dtForDisp ? String(dtForDisp.getDate()).padStart(1,'') : '';
|
||||
const mm = dtForDisp ? String(dtForDisp.getMonth()+1).padStart(1,'') : '';
|
||||
const yyyy = dtForDisp ? dtForDisp.getFullYear() : '';
|
||||
const HH = dtForDisp ? String(dtForDisp.getHours()).padStart(2,'0') : '';
|
||||
const MM = dtForDisp ? String(dtForDisp.getMinutes()).padStart(2,'0') : '';
|
||||
const dateOnly = dtForDisp ? `${dd}. ${mm}. ${yyyy}` : '';
|
||||
const timeToken = (m.date_time || '').split(' ')[1] || '';
|
||||
const timeOnly = dtForDisp ? `${HH}:${MM}` : '';
|
||||
const timeDisplay = dtForDisp ? ((timeToken === '' || timeToken === '00:00') ? 'Bude upřesněno' : timeOnly) : '';
|
||||
const venue = m.venue || '';
|
||||
const wrapperExtraClass = (isRecentFinished && s1 && s2) ? ' facr-finished' : '';
|
||||
|
||||
const headerLabel = isLive ? 'Aktuální zápas' : (isFuture ? 'Nadcházející zápas' : (isRecentFinished ? 'Poslední zápas' : `Zápasy (${idx+1}/${items.length})`));
|
||||
|
||||
root.innerHTML = `
|
||||
<div class="lte-football-upcoming">
|
||||
<div class="lte-football-upcoming${wrapperExtraClass}">
|
||||
<div class="facr-comp-title lte-football-date" style="text-align:center; margin-bottom:6px;">${compName}</div>
|
||||
<div class="facr-upcoming-header">
|
||||
<button id="facr-prev" class="facr-nav">◀</button>
|
||||
<span class="lte-header lte-header-upcoming">Zápasy (${idx+1}/${items.length})</span>
|
||||
<span class="lte-header lte-header-upcoming">${headerLabel}</span>
|
||||
<button id="facr-next" class="facr-nav">▶</button>
|
||||
</div>
|
||||
<div class="lte-teams">
|
||||
<span class="lte-team-name lte-team-1 lte-header" title="${escapeHTML(m.home)}">
|
||||
<span class="lte-team-logo"><img decoding="async" src="${homeLogo}" alt="${escapeHTML(m.home)}"></span>${homeName}
|
||||
<span id="facr-inline-status" class="facr-inline-status" aria-live="polite"></span>
|
||||
${isRecentFinished && s1 ? `<span class="lte-team-count-mob">${s1}</span>` : ''}
|
||||
</span>
|
||||
<span class="lte-team-count">
|
||||
<span id="facr-mid" style="font-size:32px; line-height:1; font-weight:700; display:inline-block; min-width:120px; text-align:center;">${midText}</span>
|
||||
${isRecentFinished && s1 && s2 ? `<span class="facr-mob-center-score">${s1}<span>:</span>${s2}</span>` : ''}
|
||||
</span>
|
||||
<span class="lte-team-count"><span id="facr-mid" style="font-size:32px; line-height:1; font-weight:700; display:inline-block; min-width:120px; text-align:center;">${midText}</span></span>
|
||||
<span class="lte-team-name lte-team-2 lte-header" title="${escapeHTML(m.away)}">
|
||||
${awayName}<span class="lte-team-logo"><img decoding="async" src="${awayLogo}" alt="${escapeHTML(m.away)}"></span>
|
||||
${isRecentFinished && s2 ? `<span class=\"lte-team-count-mob\">${s2}</span>` : ''}${awayName}<span class="lte-team-logo"><img decoding="async" src="${awayLogo}" alt="${escapeHTML(m.away)}"></span>
|
||||
</span>
|
||||
</div>
|
||||
<span class="lte-football-date" style="text-align:center;" title="${escapeHTML(m.date_time + (m.venue?`, ${m.venue}`:''))}">${dateVenue}</span>
|
||||
<span class="lte-football-date" style="text-align:center;" title="${escapeHTML(m.date_time + (m.venue?`, ${m.venue}`:''))}">${escapeHTML(dateOnly + (venue?`, ${venue}`:''))}</span>
|
||||
${timeDisplay ? `<span class="lte-football-time" style="display:block; text-align:center;">${escapeHTML(timeDisplay)}</span>` : ''}
|
||||
<span id="facr-countdown" class="lte-football-date" style="display:block; text-align:center;"></span>
|
||||
<br>
|
||||
<a class="lte-football-date" target="_blank" href="${facrLink}" style="text-align:center; background-color:#c42221; color:#ffffff; opacity:1;">Detail na FACR</a>
|
||||
@@ -214,22 +279,25 @@
|
||||
|
||||
// setup countdown / status text
|
||||
const cd = document.getElementById('facr-countdown');
|
||||
if(cd){
|
||||
const inlineStatus = document.getElementById('facr-inline-status');
|
||||
if(cd || inlineStatus){
|
||||
const now2 = new Date();
|
||||
const startMs = m.date_time ? parseCZDate(m.date_time).getTime() : 0;
|
||||
const diff = startMs - now2.getTime();
|
||||
const twoH = 2*60*60*1000;
|
||||
const threeD = 3*24*60*60*1000;
|
||||
let text = '';
|
||||
if(diff > 0){
|
||||
// Always show a visible countdown, including on non-today future matches
|
||||
cd.textContent = `Začátek za ${fmtCountdown(diff)}`;
|
||||
text = `Začátek za ${fmtCountdown(diff)}`;
|
||||
}else if(Math.abs(diff) <= twoH){
|
||||
cd.textContent = 'Právě probíhá';
|
||||
text = 'Právě probíhá';
|
||||
}else if(-diff < threeD){
|
||||
cd.textContent = (m.score ? `Výsledek: ${m.score}` : 'Ukončeno');
|
||||
text = (m.score ? `Výsledek: ${m.score}` : 'Ukončeno');
|
||||
}else{
|
||||
cd.textContent = '';
|
||||
text = '';
|
||||
}
|
||||
if(cd) cd.textContent = text;
|
||||
if(inlineStatus) inlineStatus.textContent = text;
|
||||
}
|
||||
|
||||
// Live countdown in the middle area when future and not today
|
||||
@@ -240,17 +308,31 @@
|
||||
const now = Date.now();
|
||||
const diff = startTime - now;
|
||||
if(diff > 0){
|
||||
midEl.textContent = `Za ${fmtCountdownLong(diff)}`;
|
||||
const longTxt = `Za ${fmtCountdownLong(diff)}`;
|
||||
midEl.textContent = longTxt;
|
||||
const inlineEl = document.getElementById('facr-inline-status');
|
||||
if(inlineEl) inlineEl.textContent = `Začátek za ${fmtCountdown(diff)}`;
|
||||
const cdEl = document.getElementById('facr-countdown');
|
||||
if(cdEl) cdEl.textContent = `Začátek za ${fmtCountdown(diff)}`;
|
||||
}else{
|
||||
// switch to score at/after kickoff
|
||||
midEl.textContent = m.score || '-';
|
||||
const scoreTxt = m.score || '-';
|
||||
midEl.textContent = scoreTxt;
|
||||
const inlineEl = document.getElementById('facr-inline-status');
|
||||
if(inlineEl) inlineEl.textContent = (m.score ? `Výsledek: ${m.score}` : 'Ukončeno');
|
||||
const cdEl = document.getElementById('facr-countdown');
|
||||
if(cdEl) cdEl.textContent = (m.score ? `Výsledek: ${m.score}` : 'Ukončeno');
|
||||
if(state.upcomingTimerId){ clearInterval(state.upcomingTimerId); state.upcomingTimerId = null; }
|
||||
}
|
||||
}
|
||||
// Only run live countdown if the match is in the future and not today
|
||||
if(startTime > Date.now() && !isToday){
|
||||
// Run live countdown for any future match (including today)
|
||||
if(startTime > Date.now()){
|
||||
tick();
|
||||
state.upcomingTimerId = setInterval(tick, 1000);
|
||||
} else {
|
||||
// Ensure inline status reflects finished state on initial render
|
||||
const inlineEl = document.getElementById('facr-inline-status');
|
||||
if(inlineEl) inlineEl.textContent = (m.score ? `Výsledek: ${m.score}` : 'Ukončeno');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user