Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f98bcfd956 | |||
| 6d1e06dfd6 |
@@ -28,3 +28,8 @@
|
||||
### Bug Fixes
|
||||
|
||||
* NCWF-1 401 ([#5](https://git.janis-eccarius.de/NowChess/NowChess-Frontend/issues/5)) ([f8f93ef](https://git.janis-eccarius.de/NowChess/NowChess-Frontend/commit/f8f93efff48f1d7198023fed45b675c2e225df36))
|
||||
## [0.0.0](https://git.janis-eccarius.de/NowChess/NowChess-Frontend/compare/0.2.1...0.0.0) (2026-05-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* NCWF-1 401 ([#6](https://git.janis-eccarius.de/NowChess/NowChess-Frontend/issues/6)) ([6d1e06d](https://git.janis-eccarius.de/NowChess/NowChess-Frontend/commit/6d1e06dfd606b93d029e9c9b84eea6f8b3b6294e))
|
||||
|
||||
@@ -263,6 +263,14 @@
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (showChallengeDialog) {
|
||||
<div class="dialog-overlay" (click)="closeChallengeDialog()">
|
||||
<div class="dialog-card" (click)="$event.stopPropagation()">
|
||||
<app-challenge-create-dialog (closeChallengeDialog)="closeChallengeDialog()"></app-challenge-create-dialog>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (errorMessage) {
|
||||
<p class="error-banner">{{ errorMessage }}</p>
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ export class WelcomeComponent implements OnInit, OnDestroy {
|
||||
showOptionsDialog = false;
|
||||
showJoinDialog = false;
|
||||
showImportDialog = false;
|
||||
showChallengeDialog = false;
|
||||
|
||||
gameIdInput = '';
|
||||
importMode: ImportMode = 'fen';
|
||||
@@ -223,11 +224,21 @@ export class WelcomeComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
startOneVsOne(): void {
|
||||
if (!this.requireAuth(() => this.performStartOneVsOne())) {
|
||||
if (!this.requireAuth(() => this.openChallengeDialog())) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.performStartOneVsOne();
|
||||
this.openChallengeDialog();
|
||||
}
|
||||
|
||||
openChallengeDialog(): void {
|
||||
this.closeAllDialogs();
|
||||
this.showChallengeDialog = true;
|
||||
}
|
||||
|
||||
closeChallengeDialog(): void {
|
||||
this.showChallengeDialog = false;
|
||||
this.errorMessage = '';
|
||||
}
|
||||
|
||||
startVsBot(difficulty: Difficulty): void {
|
||||
@@ -352,28 +363,6 @@ export class WelcomeComponent implements OnInit, OnDestroy {
|
||||
action();
|
||||
}
|
||||
|
||||
private performStartOneVsOne(): void {
|
||||
if (this.creating) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.errorMessage = '';
|
||||
this.creating = true;
|
||||
|
||||
this.gameApi
|
||||
.createGame()
|
||||
.pipe(finalize(() => (this.creating = false)))
|
||||
.subscribe({
|
||||
next: (game) => {
|
||||
void this.router.navigate(['/game', game.gameId], {
|
||||
state: { theme: this.isSunsetMode ? 'light' : 'dark' }
|
||||
});
|
||||
},
|
||||
error: (error) => {
|
||||
this.errorMessage = getErrorMessage(error, 'Unable to create a game.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private performStartVsBot(difficulty: Difficulty): void {
|
||||
if (this.creating) {
|
||||
|
||||
@@ -10,6 +10,7 @@ export class GameStreamService {
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
private streamSubscription: Subscription | null = null;
|
||||
private pollSubscription: Subscription | null = null;
|
||||
private lastGameStateHash: string | null = null;
|
||||
|
||||
startStreaming(
|
||||
gameId: string,
|
||||
@@ -20,7 +21,10 @@ export class GameStreamService {
|
||||
.streamGame(gameId)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe({
|
||||
next: (event) => onEvent(event),
|
||||
next: (event) => {
|
||||
this.lastGameStateHash = JSON.stringify(event);
|
||||
onEvent(event);
|
||||
},
|
||||
error: () => {
|
||||
onStreamError();
|
||||
this.startPolling(gameId, onEvent);
|
||||
@@ -37,7 +41,7 @@ export class GameStreamService {
|
||||
return;
|
||||
}
|
||||
|
||||
this.pollSubscription = interval(1500)
|
||||
this.pollSubscription = interval(5000)
|
||||
.pipe(
|
||||
startWith(0),
|
||||
switchMap(() => this.gameApi.getGame(gameId)),
|
||||
@@ -45,11 +49,16 @@ export class GameStreamService {
|
||||
)
|
||||
.subscribe({
|
||||
next: (game) => {
|
||||
const event: GameStreamEvent = {
|
||||
type: 'gameFull',
|
||||
game
|
||||
};
|
||||
onEvent(event);
|
||||
// Only emit if game state changed to avoid unnecessary updates
|
||||
const stateHash = JSON.stringify(game.state);
|
||||
if (this.lastGameStateHash !== stateHash) {
|
||||
this.lastGameStateHash = stateHash;
|
||||
const event: GameStreamEvent = {
|
||||
type: 'gameFull',
|
||||
game
|
||||
};
|
||||
onEvent(event);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -59,5 +68,6 @@ export class GameStreamService {
|
||||
this.pollSubscription?.unsubscribe();
|
||||
this.streamSubscription = null;
|
||||
this.pollSubscription = null;
|
||||
this.lastGameStateHash = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,8 +84,19 @@ export class StreamHandlerService {
|
||||
}
|
||||
};
|
||||
|
||||
// Set timeout to fallback if WebSocket doesn't connect quickly
|
||||
const connectionTimeoutId = setTimeout(() => {
|
||||
if (!connected && !fallbackActive) {
|
||||
console.warn(`[StreamHandler] WebSocket timeout for ${gameId}, attempting NDJSON fallback`);
|
||||
ws.close();
|
||||
void startNdjsonFallback();
|
||||
}
|
||||
}, 3000);
|
||||
|
||||
ws.onopen = () => {
|
||||
connected = true;
|
||||
clearTimeout(connectionTimeoutId);
|
||||
console.log(`[StreamHandler] WebSocket connected for ${gameId}`);
|
||||
};
|
||||
|
||||
ws.onmessage = (message) => {
|
||||
@@ -97,19 +108,23 @@ export class StreamHandlerService {
|
||||
};
|
||||
|
||||
ws.onerror = (error) => {
|
||||
console.warn(`[StreamHandler] WebSocket error for ${gameId}, attempting NDJSON fallback:`, error);
|
||||
if (!connected) {
|
||||
console.warn(`[StreamHandler] WebSocket error for ${gameId}:`, error);
|
||||
clearTimeout(connectionTimeoutId);
|
||||
if (!connected && !fallbackActive) {
|
||||
void startNdjsonFallback();
|
||||
}
|
||||
};
|
||||
|
||||
ws.onclose = () => {
|
||||
clearTimeout(connectionTimeoutId);
|
||||
console.warn(`[StreamHandler] WebSocket closed for ${gameId}, connected=${connected}`);
|
||||
if (!connected) {
|
||||
if (connected) {
|
||||
// Connection was established but closed, stream is complete
|
||||
observer.complete();
|
||||
} else if (!fallbackActive) {
|
||||
// Connection never established, try fallback
|
||||
console.log(`[StreamHandler] Starting NDJSON fallback for ${gameId}`);
|
||||
void startNdjsonFallback();
|
||||
} else {
|
||||
observer.complete();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
MAJOR=0
|
||||
MINOR=2
|
||||
PATCH=1
|
||||
PATCH=2
|
||||
|
||||
Reference in New Issue
Block a user