Files
lara-schach-live/js/data.js

169 lines
6.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Lara Kiesewetter Live Schachturnier
* Data fetching, PGN loading, standings, auto-refresh
*/
/* global parsePGN, filterLaraGames, getLiveGame, getTodaysGames, getLatestGame */
async function fetchRoundPGN(round) {
const res = await fetch(`https://www.deutsche-schachjugend.de/2026/odjm-d/partien/${round}.pgn?t=${Date.now()}`);
if (!res.ok) return null;
const buf = await res.arrayBuffer();
let text = new TextDecoder('utf-8').decode(buf);
if (text.includes('\uFFFD')) {
text = new TextDecoder('iso-8859-1').decode(buf);
}
return text;
}
async function loadPGN(showOverlay = true) {
const currentPollId = pollId;
if (showOverlay) showLoading(true);
hideError();
try {
if (currentRound === 0) {
if (showOverlay) showLoading(false);
return;
}
const maxRound = currentRound + 1;
const isFirstLoad = Object.keys(roundPgns).length === 0;
const startRound = isFirstLoad ? 1 : currentRound;
for (let r = startRound; r <= maxRound; r++) {
const text = await fetchRoundPGN(r);
if (currentPollId !== pollId) return;
if (text !== null) roundPgns[r] = text;
}
const combinedPgn = Object.values(roundPgns).join('\n\n');
const allGames = parsePGN(combinedPgn);
allLaraGames = filterLaraGames(allGames);
if (allLaraGames.length === 0) {
return;
}
if (!userSelectedGame) {
const liveGame = getLiveGame(allLaraGames);
const todaysGames = getTodaysGames(allLaraGames);
currentGame = liveGame || (todaysGames.length > 0 ? getLatestGame(todaysGames) : getLatestGame(allLaraGames));
}
updateBoard();
updatePlayerInfo();
updateMovesList();
updateAllGamesList();
updatePGNDisplay();
updateTimestamp();
showLoading(false);
} catch (error) {
if (currentPollId !== pollId) return;
console.error('Fehler beim Laden:', error);
showLoading(false);
}
}
async function updateStandings() {
try {
const res = await fetch(`https://www.deutsche-schachjugend.de/2026/odjm-d/tabelle/?t=${Date.now()}`);
if (!res.ok) throw new Error('Fehler beim Laden');
const html = await res.text();
const roundMatch = html.match(/Tabellenstand\s+nach\s+der\s+(\d+)\.\s*Runde/);
if (roundMatch) {
currentRound = parseInt(roundMatch[1]);
}
const rows = html.matchAll(/<tr[^>]*>(.*?)<\/tr>/gs);
for (const row of rows) {
if (!row[1].includes('Lara Kiesewetter')) continue;
const cells = row[1].matchAll(/<td[^>]*>(.*?)<\/td>/gs);
const clean = [];
for (const cell of cells) {
clean.push(cell[1].replace(/<[^>]+>/g, '').trim());
}
if (clean.length >= 9) {
const data = {
rank: clean[0],
player: 'Lara Kiesewetter',
wins: clean[5],
draws: clean[6],
losses: clean[7],
points: clean[8],
round_info: roundMatch ? `nach der ${roundMatch[1]}. Runde` : '',
round: currentRound,
};
const container = document.getElementById('standings-content');
container.innerHTML = `
<div class="standings-rank">${data.rank}.</div>
<div class="standings-rank-label">Tabellenplatz</div>
<div class="standings-header">${data.round_info || 'nach Runde 1'}</div>
<div class="standings-row">
<span class="standings-label">Punkte</span>
<span class="standings-value">${data.points}</span>
</div>
<div class="standings-row">
<span class="standings-label">Siege</span>
<span class="standings-value">${data.wins}</span>
</div>
<div class="standings-row">
<span class="standings-label">Unentschieden</span>
<span class="standings-value">${data.draws}</span>
</div>
<div class="standings-row">
<span class="standings-label">Niederlagen</span>
<span class="standings-value">${data.losses}</span>
</div>
`;
return;
}
}
document.getElementById('standings-content').innerHTML = '<div class="standings-loading">Daten nicht verfügbar</div>';
} catch {
document.getElementById('standings-content').innerHTML = '<div class="standings-loading">Daten nicht verfügbar</div>';
}
}
function updateTimestamp() {
const time = new Date();
document.getElementById('last-update').textContent =
`Letztes Update: ${time.toLocaleTimeString('de-DE')}`;
}
function startAutoRefresh() {
clearInterval(pollInterval);
clearInterval(updateTimer);
clearInterval(standingsInterval);
const myId = ++pollId;
let lastUpdate = Date.now();
document.getElementById('refresh-timer').textContent = '0s';
document.getElementById('refresh-timer').style.color = '#4ade80';
loadPGN(true);
updateStandings();
pollInterval = setInterval(() => {
if (pollId !== myId) { clearInterval(pollInterval); clearInterval(updateTimer); clearInterval(standingsInterval); return; }
loadPGN(false);
lastUpdate = Date.now();
}, 15000);
updateTimer = setInterval(() => {
if (pollId !== myId) { clearInterval(pollInterval); clearInterval(updateTimer); clearInterval(standingsInterval); return; }
const elapsed = Date.now() - lastUpdate;
const remaining = Math.max(0, 15000 - elapsed);
const s = Math.floor(remaining / 1000);
document.getElementById('refresh-timer').textContent = `${s}s`;
}, 1000);
standingsInterval = setInterval(() => {
if (pollId !== myId) { clearInterval(pollInterval); clearInterval(updateTimer); clearInterval(standingsInterval); return; }
updateStandings();
}, 1800000);
}