Commit ae2812a0 authored by Mahmoud Aglan's avatar Mahmoud Aglan

fix: repair game board layout, coordinates, and Arabic UX

- Remove duplicate static coord elements from game.php (board.js creates them dynamically)
- Force LTR direction on game-layout and board to prevent RTL interference
- Fix piece font-size for proper unicode rendering
- Translate all game UI text to Arabic (status, result, stats)
- Sync move list and status to both desktop and mobile panels
- Improve board colors and spacing
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent d5658b63
...@@ -35,19 +35,6 @@ $extraCss = '/public/css/chessboard.css'; ...@@ -35,19 +35,6 @@ $extraCss = '/public/css/chessboard.css';
<!-- Board --> <!-- Board -->
<div class="board-wrapper"> <div class="board-wrapper">
<div class="board" id="board"></div> <div class="board" id="board"></div>
<!-- Coordinate labels -->
<div class="board-coords-file" id="coords-file">
<span>a</span><span>b</span><span>c</span><span>d</span>
<span>e</span><span>f</span><span>g</span><span>h</span>
</div>
<div class="board-coords-rank" id="coords-rank">
<span>8</span><span>7</span><span>6</span><span>5</span>
<span>4</span><span>3</span><span>2</span><span>1</span>
</div>
<!-- Arrow overlay -->
<div class="board-arrows" id="board-arrows">
<svg viewBox="0 0 800 800" preserveAspectRatio="xMidYMid meet"></svg>
</div>
</div> </div>
</div> </div>
......
This diff is collapsed.
...@@ -424,57 +424,61 @@ const Game = { ...@@ -424,57 +424,61 @@ const Game = {
// --- Pro Move List --- // --- Pro Move List ---
updateMoveList() { updateMoveList() {
const list = document.getElementById('move-list'); const lists = [document.getElementById('move-list'), document.getElementById('move-list-mobile')].filter(Boolean);
if (!list) return; if (lists.length === 0) return;
list.innerHTML = '';
const history = this.chess.history(); const history = this.chess.history();
for (let i = 0; i < history.length; i += 2) { lists.forEach(list => {
const pair = document.createElement('div'); list.innerHTML = '';
pair.className = 'move-pair';
for (let i = 0; i < history.length; i += 2) {
const num = document.createElement('span'); const pair = document.createElement('div');
num.className = 'move-number'; pair.className = 'move-pair';
num.textContent = (Math.floor(i / 2) + 1) + '.';
pair.appendChild(num); const num = document.createElement('span');
num.className = 'move-number';
const white = document.createElement('span'); num.textContent = (Math.floor(i / 2) + 1) + '.';
white.className = 'move' + (i === this.currentMoveIndex ? ' current' : ''); pair.appendChild(num);
white.textContent = history[i];
white.dataset.moveIndex = i; const moveIdx = i;
white.onclick = () => this.jumpToMove(i); const white = document.createElement('span');
pair.appendChild(white); white.className = 'move' + (i === this.currentMoveIndex ? ' current' : '');
white.textContent = history[i];
if (history[i + 1]) { white.dataset.moveIndex = i;
const black = document.createElement('span'); white.onclick = () => this.jumpToMove(moveIdx);
black.className = 'move' + (i + 1 === this.currentMoveIndex ? ' current' : ''); pair.appendChild(white);
black.textContent = history[i + 1];
black.dataset.moveIndex = i + 1; if (history[i + 1]) {
black.onclick = () => this.jumpToMove(i + 1); const moveIdx2 = i + 1;
pair.appendChild(black); const black = document.createElement('span');
} black.className = 'move' + (i + 1 === this.currentMoveIndex ? ' current' : '');
black.textContent = history[i + 1];
black.dataset.moveIndex = i + 1;
black.onclick = () => this.jumpToMove(moveIdx2);
pair.appendChild(black);
}
list.appendChild(pair); list.appendChild(pair);
} }
// Auto-scroll list.scrollTop = list.scrollHeight;
list.scrollTop = list.scrollHeight; });
// Show opening name
this.updateOpeningName(history); this.updateOpeningName(history);
}, },
updateOpeningName(history) { updateOpeningName(history) {
const openingEl = document.getElementById('opening-name'); const els = [
if (!openingEl) return; document.getElementById('opening-display'),
document.getElementById('opening-display-mobile')
].filter(Boolean);
if (history.length === 0) { if (history.length === 0) {
openingEl.textContent = ''; els.forEach(el => el.style.display = 'none');
return; return;
} }
// Try progressively shorter sequences to find opening
let opening = ''; let opening = '';
const maxCheck = Math.min(history.length, 12); const maxCheck = Math.min(history.length, 12);
for (let len = maxCheck; len >= 1; len--) { for (let len = maxCheck; len >= 1; len--) {
...@@ -485,7 +489,15 @@ const Game = { ...@@ -485,7 +489,15 @@ const Game = {
} }
} }
openingEl.textContent = opening; els.forEach(el => {
if (opening) {
el.style.display = 'flex';
const nameEl = el.querySelector('.opening-name');
if (nameEl) nameEl.textContent = opening;
} else {
el.style.display = 'none';
}
});
}, },
jumpToMove(index) { jumpToMove(index) {
...@@ -505,20 +517,25 @@ const Game = { ...@@ -505,20 +517,25 @@ const Game = {
// --- Game Status --- // --- Game Status ---
updateStatus() { updateStatus() {
const status = document.getElementById('game-status'); const status = document.getElementById('game-status');
if (!status) return; const statusMobile = document.getElementById('game-status-mobile');
if (!status && !statusMobile) return;
let text = '';
if (this.chess.in_checkmate()) { if (this.chess.in_checkmate()) {
const winner = this.chess.turn() === 'w' ? 'b' : 'w'; const winner = this.chess.turn() === 'w' ? 'b' : 'w';
status.textContent = winner === this.playerColor ? 'Checkmate - You win!' : 'Checkmate - You lose'; text = winner === this.playerColor ? 'كش مات - فزت!' : 'كش مات - خسرت';
} else if (this.chess.in_check()) { } else if (this.chess.in_check()) {
status.textContent = 'Check!'; text = 'كش!';
} else if (this.chess.in_draw()) { } else if (this.chess.in_draw()) {
status.textContent = 'Draw'; text = 'تعادل';
} else if (this.chess.in_stalemate()) { } else if (this.chess.in_stalemate()) {
status.textContent = 'Stalemate'; text = 'جمود - تعادل';
} else { } else {
status.textContent = this.chess.turn() === this.playerColor ? 'Your turn' : 'Opponent thinking...'; text = this.chess.turn() === this.playerColor ? 'دورك' : 'يفكر...';
} }
if (status) status.textContent = text;
if (statusMobile) statusMobile.textContent = text;
}, },
showThinking(show) { showThinking(show) {
...@@ -536,26 +553,26 @@ const Game = { ...@@ -536,26 +553,26 @@ const Game = {
let title, subtitle; let title, subtitle;
if (reason === 'timeout') { if (reason === 'timeout') {
title = winner === this.playerColor ? 'Win on time!' : 'Lost on time'; title = winner === this.playerColor ? 'فزت بالوقت!' : 'خسرت بالوقت';
subtitle = 'Time ran out'; subtitle = 'انتهى الوقت';
} else if (this.chess.in_checkmate()) { } else if (this.chess.in_checkmate()) {
const w = this.chess.turn() === 'w' ? 'b' : 'w'; const w = this.chess.turn() === 'w' ? 'b' : 'w';
title = w === this.playerColor ? 'You win!' : 'You lose'; title = w === this.playerColor ? 'فزت!' : 'خسرت';
subtitle = 'Checkmate'; subtitle = 'كش مات';
} else if (this.chess.in_stalemate()) { } else if (this.chess.in_stalemate()) {
title = 'Draw'; title = 'تعادل';
subtitle = 'Stalemate'; subtitle = 'جمود';
} else if (this.chess.in_draw()) { } else if (this.chess.in_draw()) {
title = 'Draw'; title = 'تعادل';
subtitle = 'Insufficient material'; subtitle = 'قطع غير كافية';
} else if (reason === 'resign') { } else if (reason === 'resign') {
title = winner === this.playerColor ? 'You win!' : 'You lose'; title = winner === this.playerColor ? 'فزت!' : 'خسرت';
subtitle = 'Resignation'; subtitle = 'استسلام';
} else if (reason === 'draw') { } else if (reason === 'draw') {
title = 'Draw'; title = 'تعادل';
subtitle = 'By agreement'; subtitle = 'باتفاق';
} else { } else {
title = 'Game over'; title = 'انتهت المباراة';
subtitle = ''; subtitle = '';
} }
...@@ -591,13 +608,13 @@ const Game = { ...@@ -591,13 +608,13 @@ const Game = {
overlay.innerHTML = '<div class="game-result-title">' + title + '</div>' + overlay.innerHTML = '<div class="game-result-title">' + title + '</div>' +
'<div class="game-result-subtitle">' + subtitle + '</div>' + '<div class="game-result-subtitle">' + subtitle + '</div>' +
'<div class="game-result-stats">' + '<div class="game-result-stats">' +
'<div class="stat-row"><span>Moves</span><span>' + totalMoves + '</span></div>' + '<div class="stat-row"><span>النقلات</span><span>' + totalMoves + '</span></div>' +
'<div class="stat-row"><span>Avg move time</span><span>' + avgMoveTime + 's</span></div>' + '<div class="stat-row"><span>متوسط وقت النقلة</span><span>' + avgMoveTime + 's</span></div>' +
'<div class="stat-row"><span>Time used</span><span>' + totalTimeUsed + 's</span></div>' + '<div class="stat-row"><span>اجمالي الوقت</span><span>' + totalTimeUsed + 's</span></div>' +
'</div>' + '</div>' +
'<div class="game-controls" style="margin-top:16px;">' + '<div class="game-controls" style="margin-top:16px;">' +
'<button class="btn btn-cyan" id="btn-rematch-result">Rematch</button>' + '<button class="btn btn-cyan" id="btn-rematch-result">اعادة</button>' +
'<button class="btn btn-ghost" onclick="window.location.href=\'/play\'">Back</button>' + '<button class="btn btn-ghost" onclick="window.location.href=\'/play\'">رجوع</button>' +
'</div>'; '</div>';
wrapper.appendChild(overlay); wrapper.appendChild(overlay);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment