Commit bc27e3c6 authored by Mahmoud Aglan's avatar Mahmoud Aglan

fix: chess unmount cleanup, notification click routing, remove dead disconnect calls

Phase 1.13: add unmountGame export for chess — stops clock, destroys board,
nulls gameState on scene exit.

Phase 5.1: notification items now navigate to relevant section on click
(friends, play, tournaments, achievements based on type).

Phase 6.6: remove remaining stopDisconnectWatch calls from domino/ludo
since disconnect detection is now fully handled by match-session.js.
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 927372c0
import * as scene from '../../core/scene.js';
import { mountGame } from './scenes/game.js';
import { mountGame, unmountGame } from './scenes/game.js';
import { mountResult } from './scenes/result.js';
import { mountAnalysis } from './scenes/analysis.js';
import { mountHistory } from './scenes/history.js';
import { mountReview } from './scenes/review.js';
import { mountSpectate } from './scenes/spectate.js';
scene.register('chess-game', mountGame);
scene.register('chess-game', mountGame, unmountGame);
scene.register('chess-result', mountResult);
scene.register('chess-analysis', mountAnalysis);
scene.register('chess-history', mountHistory);
......
......@@ -996,3 +996,8 @@ function reportTournamentResult(result) {
}).catch(e => console.warn('[tournament] report error:', e));
}
export function unmountGame() {
if (clock) { clock.stop(); clock = null; }
if (board) { board.destroy?.(); board = null; }
gameState = null;
}
......@@ -1009,7 +1009,7 @@ function endMatch(el, result, reason) {
state.gameOver = true;
liveSession?.cleanup?.();
mp.stopDisconnectWatch?.();
if (result === 'win') {
audio.play('win', 'reward');
......@@ -1307,7 +1307,7 @@ export function unmountGame() {
if (botTimeout) { clearTimeout(botTimeout); botTimeout = null; }
if (autoPassTimeout) { clearTimeout(autoPassTimeout); autoPassTimeout = null; }
liveSession?.cleanup?.();
mp.stopDisconnectWatch?.();
board?.destroy();
hand?.destroy();
drag?.destroy();
......
......@@ -1384,7 +1384,7 @@ async function handleExit(el) {
if (game.mode === 'live' && matchId) {
net.post('ludo-match.php', { action: 'leave', match_id: matchId, player_index: myPlayerIndex }).catch(() => {});
mp.stopDisconnectWatch();
stopLudoPolling();
if (heartbeatTimer) { clearInterval(heartbeatTimer); heartbeatTimer = null; }
localStorage.removeItem('el3ab_active_match');
......
import * as net from '../../../core/net.js';
import * as store from '../../../core/store.js';
import * as scene from '../../../core/scene.js';
import * as bus from '../../../core/bus.js';
import { t } from '../../../core/i18n.js';
export async function mountNotifications(el) {
......@@ -45,6 +47,24 @@ function renderNotifications(el, notifications) {
notifications.forEach(n => n.is_read = true);
renderNotifications(el, notifications);
});
list.querySelectorAll('.notif-item').forEach(item => {
item.addEventListener('click', () => {
const id = item.dataset.id;
const notif = notifications.find(n => n.id === id);
if (!notif) return;
const type = notif.type || notif.notification_type || '';
if (type === 'friend_request' || type === 'friend_accept') {
bus.emit('navigate', { world: 'social', scene: 'friends' });
} else if (type === 'match_invite' || type === 'challenge') {
bus.emit('navigate', { world: 'play' });
} else if (type === 'tournament') {
bus.emit('navigate', { world: 'tournaments' });
} else if (type === 'achievement') {
scene.push('achievements');
}
});
});
}
function timeAgo(date) {
......
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