diff --git a/app.js b/app.js index 21dabba..6258cbd 100644 --- a/app.js +++ b/app.js @@ -19,7 +19,7 @@ let roundPgns = {}; let pollId = 0; async function fetchRoundPGN(round) { - const res = await fetch(`https://www.deutsche-schachjugend.de/2026/odjm-d/partien/${round}.pgn`); + const res = await fetch(`https://www.deutsche-schachjugend.de/2026/odjm-d/partien/${round}.pgn?t=${Date.now()}`); if (!res.ok) return null; return await res.text(); } @@ -30,34 +30,19 @@ async function loadPGN(showOverlay = true) { hideError(); try { - if (!window.standingsLoaded) { - await updateStandings(); - window.standingsLoaded = true; - } + await updateStandings(); if (currentRound === 0) { if (showOverlay) showLoading(false); return; } - // Fehlende vergangene Runden einmalig nachladen - for (let r = 1; r < currentRound; r++) { - if (roundPgns[r] === undefined) { - const text = await fetchRoundPGN(r); - if (text !== null) roundPgns[r] = text; - } - } - - // Aktuelle Runde immer frisch holen - const pgnText = await fetchRoundPGN(currentRound); - if (currentPollId !== pollId) return; - if (pgnText !== null) roundPgns[currentRound] = pgnText; - - // Nächste Runde prüfen (sobald verfügbar, einmalig holen) - const nextRound = currentRound + 1; - if (roundPgns[nextRound] === undefined) { - const text = await fetchRoundPGN(nextRound).catch(() => null); - if (text) roundPgns[nextRound] = text; + // Alle Runden immer frisch von der DSJ laden (mit Cache-Busting) + const maxRound = currentRound + 1; + for (let r = 1; r <= maxRound; r++) { + const text = await fetchRoundPGN(r); + if (currentPollId !== pollId) return; + if (text !== null) roundPgns[r] = text; } // Alle PGNs kombinieren @@ -81,6 +66,7 @@ async function loadPGN(showOverlay = true) { updatePlayerInfo(); updateMovesList(); updateAllGamesList(); + updatePGNDisplay(); updateTimestamp(); showLoading(false); @@ -297,6 +283,48 @@ function highlightLastMove() { } } +/** + * Generiert PGN-Text aus einem Spiel-Objekt + */ +function generatePGN(game) { + if (!game) return ''; + + let pgn = ''; + if (game.event) pgn += `[Event "${game.event}"]\n`; + if (game.site) pgn += `[Site "${game.site}"]\n`; + if (game.date) pgn += `[Date "${game.date}"]\n`; + if (game.round) pgn += `[Round "${game.round}"]\n`; + if (game.white) pgn += `[White "${game.white}"]\n`; + if (game.black) pgn += `[Black "${game.black}"]\n`; + if (game.result) pgn += `[Result "${game.result}"]\n`; + if (game.whiteElo) pgn += `[WhiteElo "${game.whiteElo}"]\n`; + if (game.blackElo) pgn += `[BlackElo "${game.blackElo}"]\n`; + if (game.termination) pgn += `[Termination "${game.termination}"]\n`; + + pgn += '\n'; + + const nonResultMoves = game.moves.filter(m => !m.isResult); + for (let i = 0; i < nonResultMoves.length; i += 2) { + const moveNumber = Math.floor(i / 2) + 1; + pgn += `${moveNumber}. ${nonResultMoves[i].san}`; + if (i + 1 < nonResultMoves.length) { + pgn += ` ${nonResultMoves[i + 1].san} `; + } + } + + const resultMove = game.moves.find(m => m.isResult); + if (resultMove) { + pgn += ` ${resultMove.san}`; + } + + return pgn.trim(); +} + +function updatePGNDisplay() { + if (!currentGame) return; + document.getElementById('pgn-text').textContent = generatePGN(currentGame); +} + /** * Aktualisiert die Zugliste */ @@ -405,6 +433,7 @@ function updateAllGamesList() { updatePlayerInfo(); updateMovesList(); updateAllGamesList(); + updatePGNDisplay(); }); list.appendChild(entry); @@ -416,7 +445,7 @@ function updateAllGamesList() { */ async function updateStandings() { try { - const res = await fetch('https://www.deutsche-schachjugend.de/2026/odjm-d/tabelle/'); + 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(); @@ -552,6 +581,28 @@ document.getElementById('refresh-btn').addEventListener('click', () => { startAutoRefresh(); }); +/** + * PGN in Zwischenablage kopieren + */ +document.getElementById('copy-pgn-btn').addEventListener('click', async () => { + const text = document.getElementById('pgn-text').textContent; + if (!text) return; + try { + await navigator.clipboard.writeText(text); + const btn = document.getElementById('copy-pgn-btn'); + btn.textContent = '✅'; + setTimeout(() => { btn.textContent = '📋'; }, 1500); + } catch { + // Fallback + const ta = document.createElement('textarea'); + ta.value = text; + document.body.appendChild(ta); + ta.select(); + document.execCommand('copy'); + document.body.removeChild(ta); + } +}); + /** * Pfeiltasten-Navigation */ diff --git a/index.html b/index.html index bb57fed..bab365f 100644 --- a/index.html +++ b/index.html @@ -38,6 +38,13 @@