Fix all ESLint errors across project
This commit is contained in:
@@ -3,3 +3,5 @@
|
|||||||
- Nach jeder Änderung am Proxy (server.py) oder an den Requests (app.js) muss der Proxy neu gestartet werden: erst alten Prozess killen (`Get-Process -Name python | Stop-Process -Force`), dann unsichtbar starten.
|
- Nach jeder Änderung am Proxy (server.py) oder an den Requests (app.js) muss der Proxy neu gestartet werden: erst alten Prozess killen (`Get-Process -Name python | Stop-Process -Force`), dann unsichtbar starten.
|
||||||
- Commits und Push erfolgen nur durch expliziten Befehl des Nutzers.
|
- Commits und Push erfolgen nur durch expliziten Befehl des Nutzers.
|
||||||
- Der Server (server.py) wird immer unsichtbar gestartet: `Start-Process -NoNewWindow -FilePath "python" -ArgumentList "server.py"`
|
- Der Server (server.py) wird immer unsichtbar gestartet: `Start-Process -NoNewWindow -FilePath "python" -ArgumentList "server.py"`
|
||||||
|
- **LESS-Workflow**: CSS-Quelldatei ist `style.less`. Bei Serverstart wird automatisch `style.css` via `node build-less.js` kompiliert. Bei manuellen Änderungen an `style.less`: `node build-less.js` ausführen, dann Server neustarten.
|
||||||
|
- `style.css` ist auto-generiert – keine manuellen Änderungen dort vornehmen.
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Live-Überwachung von Lara Kiesewetters Partien bei der **ODJM (Offene Deutsche
|
|||||||
|
|
||||||
## Projektstruktur
|
## Projektstruktur
|
||||||
|
|
||||||
```
|
```text
|
||||||
├── app.js # Hauptlogik (Brett, UI, Auto-Refresh)
|
├── app.js # Hauptlogik (Brett, UI, Auto-Refresh)
|
||||||
├── index.html # HTML-Grundgerüst
|
├── index.html # HTML-Grundgerüst
|
||||||
├── style.css # Dark-Theme-Styling
|
├── style.css # Dark-Theme-Styling
|
||||||
@@ -42,7 +42,7 @@ Live-Überwachung von Lara Kiesewetters Partien bei der **ODJM (Offene Deutsche
|
|||||||
Der Server läuft auf `http://localhost:8111`.
|
Der Server läuft auf `http://localhost:8111`.
|
||||||
|
|
||||||
2. **Öffne die App im Browser:**
|
2. **Öffne die App im Browser:**
|
||||||
```
|
```text
|
||||||
http://localhost:8111
|
http://localhost:8111
|
||||||
```
|
```
|
||||||
(Der Server serviert auch die statischen Dateien.)
|
(Der Server serviert auch die statischen Dateien.)
|
||||||
|
|||||||
33
app.js
33
app.js
@@ -3,14 +3,12 @@
|
|||||||
* Haupt-Application
|
* Haupt-Application
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const PLAYER_NAME = 'Kiesewetter, Lara';
|
/* global $, parsePGN, filterLaraGames, getLiveGame, getLatestGame, Chess, Chessboard */
|
||||||
|
|
||||||
let board = null;
|
let board = null;
|
||||||
let chess = null;
|
let chess = null;
|
||||||
let currentGame = null;
|
let currentGame = null;
|
||||||
let allLaraGames = [];
|
let allLaraGames = [];
|
||||||
let serverLastFetch = null;
|
|
||||||
let laraColor = null;
|
|
||||||
let currentMoveIndex = -1;
|
let currentMoveIndex = -1;
|
||||||
let userSelectedGame = false;
|
let userSelectedGame = false;
|
||||||
let userScrolledMoves = false;
|
let userScrolledMoves = false;
|
||||||
@@ -89,14 +87,13 @@ function updateBoard() {
|
|||||||
// Spiegele das Brett, wenn Lara Schwarz hat
|
// Spiegele das Brett, wenn Lara Schwarz hat
|
||||||
const laraIsBlack = currentGame.black.toLowerCase().includes('kiesewetter');
|
const laraIsBlack = currentGame.black.toLowerCase().includes('kiesewetter');
|
||||||
const orientation = laraIsBlack ? 'black' : 'white';
|
const orientation = laraIsBlack ? 'black' : 'white';
|
||||||
laraColor = laraIsBlack ? 'b' : 'w';
|
|
||||||
|
|
||||||
// Führe alle Züge aus
|
// Führe alle Züge aus
|
||||||
const nonResultMoves = currentGame.moves.filter(m => !m.isResult);
|
const nonResultMoves = currentGame.moves.filter(m => !m.isResult);
|
||||||
for (const move of nonResultMoves) {
|
for (const move of nonResultMoves) {
|
||||||
try {
|
try {
|
||||||
chess.move(move.san);
|
chess.move(move.san);
|
||||||
} catch (e) {
|
} catch {
|
||||||
// Ignoriere ungültige Züge
|
// Ignoriere ungültige Züge
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,7 +105,7 @@ function updateBoard() {
|
|||||||
for (let i = 0; i <= currentMoveIndex && i < nonResultMoves.length; i++) {
|
for (let i = 0; i <= currentMoveIndex && i < nonResultMoves.length; i++) {
|
||||||
try {
|
try {
|
||||||
chess.move(nonResultMoves[i].san);
|
chess.move(nonResultMoves[i].san);
|
||||||
} catch (e) {
|
} catch {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,7 +150,7 @@ function goToMove(index) {
|
|||||||
for (let i = 0; i <= index; i++) {
|
for (let i = 0; i <= index; i++) {
|
||||||
try {
|
try {
|
||||||
chess.move(nonResultMoves[i].san);
|
chess.move(nonResultMoves[i].san);
|
||||||
} catch (err) {
|
} catch {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -265,21 +262,19 @@ function highlightActivePlayer() {
|
|||||||
* Highlight den letzten Zug auf dem Brett
|
* Highlight den letzten Zug auf dem Brett
|
||||||
*/
|
*/
|
||||||
function highlightLastMove() {
|
function highlightLastMove() {
|
||||||
if (!board || !chess) return;
|
if (!board || !chess || !currentGame) return;
|
||||||
|
|
||||||
|
$('#board [data-square]').removeClass('last-move-highlight');
|
||||||
|
|
||||||
const nonResultMoves = currentGame.moves.filter(m => !m.isResult);
|
const nonResultMoves = currentGame.moves.filter(m => !m.isResult);
|
||||||
|
|
||||||
if (currentMoveIndex >= 0 && currentMoveIndex < nonResultMoves.length) {
|
if (currentMoveIndex >= 0 && currentMoveIndex < nonResultMoves.length) {
|
||||||
const lastMove = nonResultMoves[currentMoveIndex];
|
|
||||||
|
|
||||||
// Parse die SAN-Züge, um Start- und Zielfelder zu finden
|
|
||||||
const moves = chess.history({ verbose: true });
|
const moves = chess.history({ verbose: true });
|
||||||
if (moves.length > 0) {
|
if (moves.length > 0) {
|
||||||
const lastMoveData = moves[moves.length - 1];
|
const lastMoveData = moves[moves.length - 1];
|
||||||
board.highlightSquare(lastMoveData.from, lastMoveData.to);
|
$(`#board [data-square="${lastMoveData.from}"]`).addClass('last-move-highlight');
|
||||||
|
$(`#board [data-square="${lastMoveData.to}"]`).addClass('last-move-highlight');
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
board.clearHighlights();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -501,12 +496,11 @@ async function updateStandings() {
|
|||||||
<span class="standings-value">${data.losses}</span>
|
<span class="standings-value">${data.losses}</span>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
serverLastFetch = Date.now();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
document.getElementById('standings-content').innerHTML = '<div class="standings-loading">Daten nicht verfügbar</div>';
|
document.getElementById('standings-content').innerHTML = '<div class="standings-loading">Daten nicht verfügbar</div>';
|
||||||
} catch (err) {
|
} catch {
|
||||||
document.getElementById('standings-content').innerHTML = '<div class="standings-loading">Daten nicht verfügbar</div>';
|
document.getElementById('standings-content').innerHTML = '<div class="standings-loading">Daten nicht verfügbar</div>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -564,11 +558,6 @@ function showLoading(show) {
|
|||||||
document.getElementById('loading-overlay').style.display = show ? 'flex' : 'none';
|
document.getElementById('loading-overlay').style.display = show ? 'flex' : 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
function showError(msg) {
|
|
||||||
document.getElementById('error-message').textContent = msg;
|
|
||||||
document.getElementById('error-overlay').style.display = 'flex';
|
|
||||||
}
|
|
||||||
|
|
||||||
function hideError() {
|
function hideError() {
|
||||||
document.getElementById('error-overlay').style.display = 'none';
|
document.getElementById('error-overlay').style.display = 'none';
|
||||||
}
|
}
|
||||||
@@ -609,8 +598,6 @@ document.getElementById('copy-pgn-btn').addEventListener('click', async () => {
|
|||||||
document.addEventListener('keydown', (e) => {
|
document.addEventListener('keydown', (e) => {
|
||||||
if (!currentGame) return;
|
if (!currentGame) return;
|
||||||
|
|
||||||
const nonResultMoves = currentGame.moves.filter(m => !m.isResult);
|
|
||||||
|
|
||||||
if (e.key === 'ArrowLeft') {
|
if (e.key === 'ArrowLeft') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
goToMove(currentMoveIndex - 1);
|
goToMove(currentMoveIndex - 1);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* global require, __dirname, process */
|
||||||
const less = require('less');
|
const less = require('less');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { defineConfig } from "eslint/config";
|
|||||||
|
|
||||||
export default defineConfig([
|
export default defineConfig([
|
||||||
{ files: ["**/*.{js,mjs,cjs}"], plugins: { js }, extends: ["js/recommended"], languageOptions: { globals: globals.browser } },
|
{ files: ["**/*.{js,mjs,cjs}"], plugins: { js }, extends: ["js/recommended"], languageOptions: { globals: globals.browser } },
|
||||||
{ files: ["**/*.json"], plugins: { json }, language: "json/json", extends: ["json/recommended"] },
|
{ files: ["**/*.json"], ignores: ["package-lock.json"], plugins: { json }, language: "json/json", extends: ["json/recommended"] },
|
||||||
{ files: ["**/*.md"], plugins: { markdown }, language: "markdown/commonmark", extends: ["markdown/recommended"] },
|
{ files: ["**/*.md"], plugins: { markdown }, language: "markdown/commonmark", extends: ["markdown/recommended"] },
|
||||||
{ files: ["**/*.css"], plugins: { css }, language: "css/css", extends: ["css/recommended"] },
|
{ files: ["**/*.css"], plugins: { css }, language: "css/css", extends: ["css/recommended"], rules: { "css/use-baseline": "off" } },
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -130,3 +130,8 @@ function getLatestGame(laraGames) {
|
|||||||
});
|
});
|
||||||
return sorted[0];
|
return sorted[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.parsePGN = parsePGN;
|
||||||
|
window.filterLaraGames = filterLaraGames;
|
||||||
|
window.getLiveGame = getLiveGame;
|
||||||
|
window.getLatestGame = getLatestGame;
|
||||||
|
|||||||
@@ -130,6 +130,9 @@ header h1 {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
}
|
}
|
||||||
|
#board [data-square].last-move-highlight {
|
||||||
|
box-shadow: inset 0 0 3px 3px rgba(255, 200, 0, 0.7);
|
||||||
|
}
|
||||||
#pgn-panel {
|
#pgn-panel {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
@@ -172,6 +175,7 @@ header h1 {
|
|||||||
padding: 8px;
|
padding: 8px;
|
||||||
background: rgba(0, 0, 0, 0.4);
|
background: rgba(0, 0, 0, 0.4);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
|
-webkit-user-select: text;
|
||||||
user-select: text;
|
user-select: text;
|
||||||
}
|
}
|
||||||
/* Info Section */
|
/* Info Section */
|
||||||
|
|||||||
@@ -157,6 +157,10 @@ header {
|
|||||||
#board {
|
#board {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
|
|
||||||
|
[data-square].last-move-highlight {
|
||||||
|
box-shadow: inset 0 0 3px 3px rgba(255, 200, 0, 0.7);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pgn-panel {
|
#pgn-panel {
|
||||||
@@ -205,6 +209,7 @@ header {
|
|||||||
padding: 8px;
|
padding: 8px;
|
||||||
background: @bg-darker;
|
background: @bg-darker;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
|
-webkit-user-select: text;
|
||||||
user-select: text;
|
user-select: text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user