feat(chess): finished games section below active games in lobby
Adds a "Finished Games" section to the Android chess lobby screen, showing up to 10 completed games with opponent avatars, result (Won/Lost/Draw), and move count. The section only appears when completedGames is non-empty, matching the Desktop implementation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+52
-1
@@ -67,6 +67,7 @@ import com.vitorpamplona.amethyst.commons.chess.ActiveGameCard
|
|||||||
import com.vitorpamplona.amethyst.commons.chess.ChallengeCard
|
import com.vitorpamplona.amethyst.commons.chess.ChallengeCard
|
||||||
import com.vitorpamplona.amethyst.commons.chess.ChessChallenge
|
import com.vitorpamplona.amethyst.commons.chess.ChessChallenge
|
||||||
import com.vitorpamplona.amethyst.commons.chess.ChessSyncBanner
|
import com.vitorpamplona.amethyst.commons.chess.ChessSyncBanner
|
||||||
|
import com.vitorpamplona.amethyst.commons.chess.CompletedGameCard
|
||||||
import com.vitorpamplona.amethyst.commons.chess.NewChessGameDialog
|
import com.vitorpamplona.amethyst.commons.chess.NewChessGameDialog
|
||||||
import com.vitorpamplona.amethyst.commons.chess.OutgoingChallengeCard
|
import com.vitorpamplona.amethyst.commons.chess.OutgoingChallengeCard
|
||||||
import com.vitorpamplona.amethyst.commons.chess.OverlappingAvatars
|
import com.vitorpamplona.amethyst.commons.chess.OverlappingAvatars
|
||||||
@@ -295,13 +296,15 @@ fun ChessLobbyContent(
|
|||||||
val spectatingGames by chessViewModel.spectatingGames.collectAsState()
|
val spectatingGames by chessViewModel.spectatingGames.collectAsState()
|
||||||
val publicGames by chessViewModel.publicGames.collectAsState()
|
val publicGames by chessViewModel.publicGames.collectAsState()
|
||||||
val challenges by chessViewModel.challenges.collectAsState()
|
val challenges by chessViewModel.challenges.collectAsState()
|
||||||
|
val completedGames by chessViewModel.completedGames.collectAsState()
|
||||||
val userPubkey = accountViewModel.account.userProfile().pubkeyHex
|
val userPubkey = accountViewModel.account.userProfile().pubkeyHex
|
||||||
|
|
||||||
val hasContent =
|
val hasContent =
|
||||||
activeGames.isNotEmpty() ||
|
activeGames.isNotEmpty() ||
|
||||||
spectatingGames.isNotEmpty() ||
|
spectatingGames.isNotEmpty() ||
|
||||||
publicGames.isNotEmpty() ||
|
publicGames.isNotEmpty() ||
|
||||||
challenges.isNotEmpty()
|
challenges.isNotEmpty() ||
|
||||||
|
completedGames.isNotEmpty()
|
||||||
|
|
||||||
if (!hasContent) {
|
if (!hasContent) {
|
||||||
// Empty state - use LazyColumn so pull-to-refresh works
|
// Empty state - use LazyColumn so pull-to-refresh works
|
||||||
@@ -560,6 +563,54 @@ fun ChessLobbyContent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Finished games section
|
||||||
|
if (completedGames.isNotEmpty()) {
|
||||||
|
item {
|
||||||
|
Spacer(Modifier.height(16.dp))
|
||||||
|
Text(
|
||||||
|
"Finished Games",
|
||||||
|
style = MaterialTheme.typography.titleMedium,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
modifier = Modifier.padding(vertical = 8.dp),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
items(
|
||||||
|
completedGames.distinctBy { it.gameId }.take(10),
|
||||||
|
key = { "completed-${it.gameId}-${it.completedAt}" },
|
||||||
|
) { game ->
|
||||||
|
val opponentPubkey =
|
||||||
|
if (game.whitePubkey == userPubkey) game.blackPubkey else game.whitePubkey
|
||||||
|
val opponentUser =
|
||||||
|
remember(opponentPubkey) {
|
||||||
|
accountViewModel.checkGetOrCreateUser(opponentPubkey)
|
||||||
|
}
|
||||||
|
val opponentName =
|
||||||
|
opponentUser?.toBestDisplayName()
|
||||||
|
?: game.blackDisplayName
|
||||||
|
?: game.whiteDisplayName
|
||||||
|
?: opponentPubkey.take(8)
|
||||||
|
CompletedGameCard(
|
||||||
|
opponentName = opponentName,
|
||||||
|
result = game.result,
|
||||||
|
didUserWin = game.didUserWin(userPubkey),
|
||||||
|
isDraw = game.isDraw,
|
||||||
|
moveCount = game.moveCount,
|
||||||
|
avatar = {
|
||||||
|
OverlappingAvatars(
|
||||||
|
avatar1Hex = userPubkey,
|
||||||
|
avatar2Hex = opponentPubkey,
|
||||||
|
avatar1Url =
|
||||||
|
remember(userPubkey) {
|
||||||
|
accountViewModel.checkGetOrCreateUser(userPubkey)
|
||||||
|
}?.profilePicture(),
|
||||||
|
avatar2Url = opponentUser?.profilePicture(),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Bottom padding for FAB
|
// Bottom padding for FAB
|
||||||
item {
|
item {
|
||||||
Spacer(Modifier.height(80.dp))
|
Spacer(Modifier.height(80.dp))
|
||||||
|
|||||||
Reference in New Issue
Block a user