feat(chess): exit spectator mode with Leave Game button
Adds ability to leave a spectated game on both Android and Desktop: - Added stopSpectating() to ChessLobbyLogic (removes from state + stops polling) - Both ViewModels now delegate to logic.stopSpectating() instead of bypassing it - LiveChessGameScreen accepts onLeaveSpectating callback shown in spectator info area - Android: Leave Game button pops back stack and stops spectating - Desktop: Leave Game button clears selectedGameId (returns to lobby) and stops spectating Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+30
-8
@@ -281,6 +281,15 @@ fun ChessScreen(
|
||||
},
|
||||
onResign = { viewModel.resign(gameState.startEventId) },
|
||||
isSpectatorOverride = isSpectating,
|
||||
onLeaveSpectating =
|
||||
if (isSpectating) {
|
||||
{
|
||||
viewModel.stopSpectating(gameState.startEventId)
|
||||
viewModel.selectGame(null)
|
||||
}
|
||||
} else {
|
||||
null
|
||||
},
|
||||
compactMode = compactMode,
|
||||
whiteName = viewModel.userMetadataCache.getDisplayName(whitePubkey),
|
||||
whiteHex = whitePubkey,
|
||||
@@ -614,6 +623,7 @@ private fun DesktopChessGameLayout(
|
||||
onMoveMade: (from: String, to: String, san: String) -> Unit,
|
||||
onResign: () -> Unit,
|
||||
isSpectatorOverride: Boolean? = null,
|
||||
onLeaveSpectating: (() -> Unit)? = null,
|
||||
compactMode: Boolean = false,
|
||||
whiteName: String = "White",
|
||||
whiteHex: String = "",
|
||||
@@ -860,16 +870,28 @@ private fun DesktopChessGameLayout(
|
||||
containerColor = MaterialTheme.colorScheme.tertiaryContainer.copy(alpha = 0.5f),
|
||||
),
|
||||
) {
|
||||
Row(
|
||||
Column(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
Icon(Icons.Default.Visibility, contentDescription = null)
|
||||
Text(
|
||||
"Watching game - spectator mode",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
)
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
Icon(Icons.Default.Visibility, contentDescription = null)
|
||||
Text(
|
||||
"Watching game - spectator mode",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
)
|
||||
}
|
||||
onLeaveSpectating?.let { onLeave ->
|
||||
OutlinedButton(
|
||||
onClick = onLeave,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
Text("Leave Game")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -172,7 +172,7 @@ class DesktopChessViewModelNew(
|
||||
|
||||
fun loadGameAsSpectator(gameId: String) = logic.loadGameAsSpectator(gameId)
|
||||
|
||||
fun stopSpectating(gameId: String) = logic.state.removeSpectatingGame(gameId)
|
||||
fun stopSpectating(gameId: String) = logic.stopSpectating(gameId)
|
||||
|
||||
// ============================================
|
||||
// Utility
|
||||
|
||||
Reference in New Issue
Block a user