code review fixes:
Deduplicate chess notify() into shared notifyChessEvent() helper using BaseChessEvent Remove addCompletedGameDirectly, extend moveToCompleted with optional liveState param Hoist currentUser lookup to top of ChessLobbyContent, remove 4 duplicate remembers Add missing imports in desktop ChessScreen, replace all FQN usages with short names Remove redundant distinctBy in completed games UI (state already prevents duplicates)
This commit is contained in:
+28
-43
@@ -48,6 +48,7 @@ import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
|||||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||||
import com.vitorpamplona.quartz.nip59Giftwrap.seals.SealedRumorEvent
|
import com.vitorpamplona.quartz.nip59Giftwrap.seals.SealedRumorEvent
|
||||||
import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent
|
import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent
|
||||||
|
import com.vitorpamplona.quartz.nip64Chess.baseEvent.BaseChessEvent
|
||||||
import com.vitorpamplona.quartz.nip64Chess.challenge.accept.LiveChessGameAcceptEvent
|
import com.vitorpamplona.quartz.nip64Chess.challenge.accept.LiveChessGameAcceptEvent
|
||||||
import com.vitorpamplona.quartz.nip64Chess.move.LiveChessMoveEvent
|
import com.vitorpamplona.quartz.nip64Chess.move.LiveChessMoveEvent
|
||||||
import com.vitorpamplona.quartz.utils.Log
|
import com.vitorpamplona.quartz.utils.Log
|
||||||
@@ -107,12 +108,29 @@ class EventNotificationConsumer(
|
|||||||
Log.d(TAG, "Unwrapped consume ${innerEvent.javaClass.simpleName}")
|
Log.d(TAG, "Unwrapped consume ${innerEvent.javaClass.simpleName}")
|
||||||
|
|
||||||
when (innerEvent) {
|
when (innerEvent) {
|
||||||
is PrivateDmEvent -> notify(innerEvent, account)
|
is PrivateDmEvent -> {
|
||||||
is LnZapEvent -> notify(innerEvent, account)
|
notify(innerEvent, account)
|
||||||
is ChatMessageEvent -> notify(innerEvent, account)
|
}
|
||||||
is ChatMessageEncryptedFileHeaderEvent -> notify(innerEvent, account)
|
|
||||||
is LiveChessGameAcceptEvent -> notify(innerEvent, account)
|
is LnZapEvent -> {
|
||||||
is LiveChessMoveEvent -> notify(innerEvent, account)
|
notify(innerEvent, account)
|
||||||
|
}
|
||||||
|
|
||||||
|
is ChatMessageEvent -> {
|
||||||
|
notify(innerEvent, account)
|
||||||
|
}
|
||||||
|
|
||||||
|
is ChatMessageEncryptedFileHeaderEvent -> {
|
||||||
|
notify(innerEvent, account)
|
||||||
|
}
|
||||||
|
|
||||||
|
is LiveChessGameAcceptEvent -> {
|
||||||
|
notifyChessEvent(innerEvent, account, R.string.app_notification_chess_challenge_accepted)
|
||||||
|
}
|
||||||
|
|
||||||
|
is LiveChessMoveEvent -> {
|
||||||
|
notifyChessEvent(innerEvent, account, R.string.app_notification_chess_your_turn)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -486,11 +504,11 @@ class EventNotificationConsumer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun notify(
|
private suspend fun notifyChessEvent(
|
||||||
event: LiveChessGameAcceptEvent,
|
event: BaseChessEvent,
|
||||||
account: Account,
|
account: Account,
|
||||||
|
contentStringRes: Int,
|
||||||
) {
|
) {
|
||||||
Log.d(TAG, "New Chess Challenge Accept to Notify")
|
|
||||||
if (
|
if (
|
||||||
event.createdAt > TimeUtils.fifteenMinutesAgo() &&
|
event.createdAt > TimeUtils.fifteenMinutesAgo() &&
|
||||||
event.pubKey != account.signer.pubKey
|
event.pubKey != account.signer.pubKey
|
||||||
@@ -499,40 +517,7 @@ class EventNotificationConsumer(
|
|||||||
val user = author.toBestDisplayName()
|
val user = author.toBestDisplayName()
|
||||||
val userPicture = author.profilePicture()
|
val userPicture = author.profilePicture()
|
||||||
val title = stringRes(applicationContext, R.string.app_notification_chess_channel_name)
|
val title = stringRes(applicationContext, R.string.app_notification_chess_channel_name)
|
||||||
val content = stringRes(applicationContext, R.string.app_notification_chess_challenge_accepted, user)
|
val content = stringRes(applicationContext, contentStringRes, user)
|
||||||
val noteUri =
|
|
||||||
"notifications$ACCOUNT_QUERY_PARAM" +
|
|
||||||
account.signer.pubKey
|
|
||||||
.hexToByteArray()
|
|
||||||
.toNpub()
|
|
||||||
|
|
||||||
notificationManager()
|
|
||||||
.sendChessNotification(
|
|
||||||
event.id,
|
|
||||||
content,
|
|
||||||
title,
|
|
||||||
event.createdAt,
|
|
||||||
userPicture,
|
|
||||||
noteUri,
|
|
||||||
applicationContext,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun notify(
|
|
||||||
event: LiveChessMoveEvent,
|
|
||||||
account: Account,
|
|
||||||
) {
|
|
||||||
Log.d(TAG, "New Chess Move to Notify")
|
|
||||||
if (
|
|
||||||
event.createdAt > TimeUtils.fifteenMinutesAgo() &&
|
|
||||||
event.pubKey != account.signer.pubKey
|
|
||||||
) {
|
|
||||||
val author = LocalCache.getOrCreateUser(event.pubKey)
|
|
||||||
val user = author.toBestDisplayName()
|
|
||||||
val userPicture = author.profilePicture()
|
|
||||||
val title = stringRes(applicationContext, R.string.app_notification_chess_channel_name)
|
|
||||||
val content = stringRes(applicationContext, R.string.app_notification_chess_your_turn, user)
|
|
||||||
val noteUri =
|
val noteUri =
|
||||||
"notifications$ACCOUNT_QUERY_PARAM" +
|
"notifications$ACCOUNT_QUERY_PARAM" +
|
||||||
account.signer.pubKey
|
account.signer.pubKey
|
||||||
|
|||||||
+7
-22
@@ -298,6 +298,10 @@ fun ChessLobbyContent(
|
|||||||
val challenges by chessViewModel.challenges.collectAsState()
|
val challenges by chessViewModel.challenges.collectAsState()
|
||||||
val completedGames by chessViewModel.completedGames.collectAsState()
|
val completedGames by chessViewModel.completedGames.collectAsState()
|
||||||
val userPubkey = accountViewModel.account.userProfile().pubkeyHex
|
val userPubkey = accountViewModel.account.userProfile().pubkeyHex
|
||||||
|
val currentUser =
|
||||||
|
remember(userPubkey) {
|
||||||
|
accountViewModel.checkGetOrCreateUser(userPubkey)
|
||||||
|
}
|
||||||
|
|
||||||
val hasContent =
|
val hasContent =
|
||||||
activeGames.isNotEmpty() ||
|
activeGames.isNotEmpty() ||
|
||||||
@@ -368,10 +372,6 @@ fun ChessLobbyContent(
|
|||||||
accountViewModel.checkGetOrCreateUser(state.opponentPubkey)
|
accountViewModel.checkGetOrCreateUser(state.opponentPubkey)
|
||||||
}
|
}
|
||||||
val displayName = opponent?.toBestDisplayName() ?: state.opponentPubkey.take(8)
|
val displayName = opponent?.toBestDisplayName() ?: state.opponentPubkey.take(8)
|
||||||
val playerUser =
|
|
||||||
remember(state.playerPubkey) {
|
|
||||||
accountViewModel.checkGetOrCreateUser(state.playerPubkey)
|
|
||||||
}
|
|
||||||
ActiveGameCard(
|
ActiveGameCard(
|
||||||
gameId = gameId,
|
gameId = gameId,
|
||||||
opponentName = displayName,
|
opponentName = displayName,
|
||||||
@@ -381,7 +381,7 @@ fun ChessLobbyContent(
|
|||||||
OverlappingAvatars(
|
OverlappingAvatars(
|
||||||
avatar1Hex = state.playerPubkey,
|
avatar1Hex = state.playerPubkey,
|
||||||
avatar2Hex = state.opponentPubkey,
|
avatar2Hex = state.opponentPubkey,
|
||||||
avatar1Url = playerUser?.profilePicture(),
|
avatar1Url = currentUser?.profilePicture(),
|
||||||
avatar2Url = opponent?.profilePicture(),
|
avatar2Url = opponent?.profilePicture(),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@@ -410,10 +410,6 @@ fun ChessLobbyContent(
|
|||||||
val opponentName =
|
val opponentName =
|
||||||
opponentUser?.toBestDisplayName()
|
opponentUser?.toBestDisplayName()
|
||||||
?: challenge.opponentPubkey?.take(8)
|
?: challenge.opponentPubkey?.take(8)
|
||||||
val currentUser =
|
|
||||||
remember(userPubkey) {
|
|
||||||
accountViewModel.checkGetOrCreateUser(userPubkey)
|
|
||||||
}
|
|
||||||
OutgoingChallengeCard(
|
OutgoingChallengeCard(
|
||||||
opponentName = opponentName,
|
opponentName = opponentName,
|
||||||
userPlaysWhite = challenge.challengerColor == ChessColor.WHITE,
|
userPlaysWhite = challenge.challengerColor == ChessColor.WHITE,
|
||||||
@@ -477,10 +473,6 @@ fun ChessLobbyContent(
|
|||||||
?: accountViewModel.checkGetOrCreateUser(challenge.challengerPubkey)?.toBestDisplayName()
|
?: accountViewModel.checkGetOrCreateUser(challenge.challengerPubkey)?.toBestDisplayName()
|
||||||
?: challenge.challengerPubkey.take(8)
|
?: challenge.challengerPubkey.take(8)
|
||||||
}
|
}
|
||||||
val currentUser =
|
|
||||||
remember(userPubkey) {
|
|
||||||
accountViewModel.checkGetOrCreateUser(userPubkey)
|
|
||||||
}
|
|
||||||
ChallengeCard(
|
ChallengeCard(
|
||||||
challengerName = displayName,
|
challengerName = displayName,
|
||||||
challengerPlaysWhite = challenge.challengerColor == ChessColor.WHITE,
|
challengerPlaysWhite = challenge.challengerColor == ChessColor.WHITE,
|
||||||
@@ -518,10 +510,6 @@ fun ChessLobbyContent(
|
|||||||
?: accountViewModel.checkGetOrCreateUser(challenge.challengerPubkey)?.toBestDisplayName()
|
?: accountViewModel.checkGetOrCreateUser(challenge.challengerPubkey)?.toBestDisplayName()
|
||||||
?: challenge.challengerPubkey.take(8)
|
?: challenge.challengerPubkey.take(8)
|
||||||
}
|
}
|
||||||
val currentUser =
|
|
||||||
remember(userPubkey) {
|
|
||||||
accountViewModel.checkGetOrCreateUser(userPubkey)
|
|
||||||
}
|
|
||||||
ChallengeCard(
|
ChallengeCard(
|
||||||
challengerName = displayName,
|
challengerName = displayName,
|
||||||
challengerPlaysWhite = challenge.challengerColor == ChessColor.WHITE,
|
challengerPlaysWhite = challenge.challengerColor == ChessColor.WHITE,
|
||||||
@@ -576,7 +564,7 @@ fun ChessLobbyContent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
items(
|
items(
|
||||||
completedGames.distinctBy { it.gameId }.take(10),
|
completedGames.take(10),
|
||||||
key = { "completed-${it.gameId}-${it.completedAt}" },
|
key = { "completed-${it.gameId}-${it.completedAt}" },
|
||||||
) { game ->
|
) { game ->
|
||||||
val opponentPubkey =
|
val opponentPubkey =
|
||||||
@@ -601,10 +589,7 @@ fun ChessLobbyContent(
|
|||||||
OverlappingAvatars(
|
OverlappingAvatars(
|
||||||
avatar1Hex = userPubkey,
|
avatar1Hex = userPubkey,
|
||||||
avatar2Hex = opponentPubkey,
|
avatar2Hex = opponentPubkey,
|
||||||
avatar1Url =
|
avatar1Url = currentUser?.profilePicture(),
|
||||||
remember(userPubkey) {
|
|
||||||
accountViewModel.checkGetOrCreateUser(userPubkey)
|
|
||||||
}?.profilePicture(),
|
|
||||||
avatar2Url = opponentUser?.profilePicture(),
|
avatar2Url = opponentUser?.profilePicture(),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|||||||
+1
-2
@@ -778,8 +778,7 @@ class ChessLobbyLogic(
|
|||||||
// If the discovered game is already finished, send it straight to completed
|
// If the discovered game is already finished, send it straight to completed
|
||||||
val gameStatus = result.liveState.gameStatus.value
|
val gameStatus = result.liveState.gameStatus.value
|
||||||
if (gameStatus is GameStatus.Finished) {
|
if (gameStatus is GameStatus.Finished) {
|
||||||
// Use the direct helper to avoid the addActiveGame → moveToCompleted flicker
|
state.moveToCompleted(startEventId, gameStatus.result.notation, null, liveState = result.liveState)
|
||||||
state.addCompletedGameDirectly(startEventId, result.liveState, gameStatus.result.notation, null)
|
|
||||||
} else if (!result.liveState.isSpectator) {
|
} else if (!result.liveState.isSpectator) {
|
||||||
state.addActiveGame(startEventId, result.liveState)
|
state.addActiveGame(startEventId, result.liveState)
|
||||||
pollingDelegate.addGameId(startEventId)
|
pollingDelegate.addGameId(startEventId)
|
||||||
|
|||||||
+9
-58
@@ -394,31 +394,24 @@ class ChessLobbyState(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move a game from active/spectating to completed.
|
* Move a game to completed. Looks up the game from active/spectating maps,
|
||||||
* Display names are optional; UI can look them up later if needed.
|
* or uses the provided [liveState] if the game isn't in either map yet
|
||||||
|
* (e.g. a newly discovered game that is already finished).
|
||||||
*/
|
*/
|
||||||
fun moveToCompleted(
|
fun moveToCompleted(
|
||||||
gameId: String,
|
gameId: String,
|
||||||
result: String,
|
result: String,
|
||||||
termination: String?,
|
termination: String?,
|
||||||
|
liveState: LiveChessGameState? = null,
|
||||||
whiteDisplayName: String? = null,
|
whiteDisplayName: String? = null,
|
||||||
blackDisplayName: String? = null,
|
blackDisplayName: String? = null,
|
||||||
) {
|
) {
|
||||||
val existingState = _activeGames.value[gameId] ?: _spectatingGames.value[gameId]
|
val gameState = _activeGames.value[gameId] ?: _spectatingGames.value[gameId] ?: liveState ?: return
|
||||||
existingState?.let { gameState ->
|
|
||||||
// Derive white/black pubkeys from player color
|
|
||||||
val whitePubkey =
|
val whitePubkey =
|
||||||
if (gameState.playerColor == Color.WHITE) {
|
if (gameState.playerColor == Color.WHITE) gameState.playerPubkey else gameState.opponentPubkey
|
||||||
gameState.playerPubkey
|
|
||||||
} else {
|
|
||||||
gameState.opponentPubkey
|
|
||||||
}
|
|
||||||
val blackPubkey =
|
val blackPubkey =
|
||||||
if (gameState.playerColor == Color.BLACK) {
|
if (gameState.playerColor == Color.BLACK) gameState.playerPubkey else gameState.opponentPubkey
|
||||||
gameState.playerPubkey
|
|
||||||
} else {
|
|
||||||
gameState.opponentPubkey
|
|
||||||
}
|
|
||||||
|
|
||||||
val completed =
|
val completed =
|
||||||
CompletedGame(
|
CompletedGame(
|
||||||
@@ -436,12 +429,7 @@ class ChessLobbyState(
|
|||||||
)
|
)
|
||||||
|
|
||||||
_completedGames.update { current ->
|
_completedGames.update { current ->
|
||||||
// Avoid duplicates
|
if (current.any { it.gameId == gameId }) current else listOf(completed) + current
|
||||||
if (current.any { it.gameId == gameId }) {
|
|
||||||
current
|
|
||||||
} else {
|
|
||||||
listOf(completed) + current
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove from active/spectating
|
// Remove from active/spectating
|
||||||
@@ -453,43 +441,6 @@ class ChessLobbyState(
|
|||||||
_selectedGameId.value = null
|
_selectedGameId.value = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build and record a CompletedGame directly from a LiveChessGameState without requiring the
|
|
||||||
* game to be inserted into activeGames first. Use this when a newly discovered game is already
|
|
||||||
* finished so we avoid the intermediate addActiveGame → moveToCompleted flicker.
|
|
||||||
*/
|
|
||||||
fun addCompletedGameDirectly(
|
|
||||||
gameId: String,
|
|
||||||
liveState: LiveChessGameState,
|
|
||||||
result: String,
|
|
||||||
termination: String?,
|
|
||||||
) {
|
|
||||||
val whitePubkey =
|
|
||||||
if (liveState.playerColor == Color.WHITE) liveState.playerPubkey else liveState.opponentPubkey
|
|
||||||
val blackPubkey =
|
|
||||||
if (liveState.playerColor == Color.BLACK) liveState.playerPubkey else liveState.opponentPubkey
|
|
||||||
|
|
||||||
val completed =
|
|
||||||
CompletedGame(
|
|
||||||
gameId = gameId,
|
|
||||||
whitePubkey = whitePubkey,
|
|
||||||
whiteDisplayName = null,
|
|
||||||
blackPubkey = blackPubkey,
|
|
||||||
blackDisplayName = null,
|
|
||||||
result = result,
|
|
||||||
termination = termination,
|
|
||||||
moveCount = liveState.moveHistory.value.size,
|
|
||||||
completedAt =
|
|
||||||
com.vitorpamplona.quartz.utils.TimeUtils
|
|
||||||
.now(),
|
|
||||||
)
|
|
||||||
|
|
||||||
_completedGames.update { current ->
|
|
||||||
if (current.any { it.gameId == gameId }) current else listOf(completed) + current
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addSpectatingGame(
|
fun addSpectatingGame(
|
||||||
gameId: String,
|
gameId: String,
|
||||||
|
|||||||
+21
-14
@@ -43,7 +43,6 @@ import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
|||||||
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowLeft
|
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowLeft
|
||||||
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
|
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
|
||||||
import androidx.compose.material.icons.filled.Add
|
import androidx.compose.material.icons.filled.Add
|
||||||
import androidx.compose.material.icons.filled.ArrowBack
|
|
||||||
import androidx.compose.material.icons.filled.Refresh
|
import androidx.compose.material.icons.filled.Refresh
|
||||||
import androidx.compose.material.icons.filled.Visibility
|
import androidx.compose.material.icons.filled.Visibility
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
@@ -67,14 +66,22 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.min
|
import androidx.compose.ui.unit.min
|
||||||
|
import com.vitorpamplona.amethyst.commons.chess.ActiveGameCard
|
||||||
|
import com.vitorpamplona.amethyst.commons.chess.ChallengeCard
|
||||||
import com.vitorpamplona.amethyst.commons.chess.ChessBroadcastBanner
|
import com.vitorpamplona.amethyst.commons.chess.ChessBroadcastBanner
|
||||||
import com.vitorpamplona.amethyst.commons.chess.ChessChallenge
|
import com.vitorpamplona.amethyst.commons.chess.ChessChallenge
|
||||||
import com.vitorpamplona.amethyst.commons.chess.ChessConfig
|
import com.vitorpamplona.amethyst.commons.chess.ChessConfig
|
||||||
|
import com.vitorpamplona.amethyst.commons.chess.ChessPlayerVsHeader
|
||||||
import com.vitorpamplona.amethyst.commons.chess.ChessSyncBanner
|
import com.vitorpamplona.amethyst.commons.chess.ChessSyncBanner
|
||||||
import com.vitorpamplona.amethyst.commons.chess.CompletedGame
|
import com.vitorpamplona.amethyst.commons.chess.CompletedGame
|
||||||
|
import com.vitorpamplona.amethyst.commons.chess.CompletedGameCard
|
||||||
import com.vitorpamplona.amethyst.commons.chess.InteractiveChessBoard
|
import com.vitorpamplona.amethyst.commons.chess.InteractiveChessBoard
|
||||||
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.OverlappingAvatars
|
||||||
import com.vitorpamplona.amethyst.commons.chess.PublicGame
|
import com.vitorpamplona.amethyst.commons.chess.PublicGame
|
||||||
|
import com.vitorpamplona.amethyst.commons.chess.PublicGameCard
|
||||||
|
import com.vitorpamplona.amethyst.commons.chess.SpectatingGameCard
|
||||||
import com.vitorpamplona.amethyst.commons.data.UserMetadataCache
|
import com.vitorpamplona.amethyst.commons.data.UserMetadataCache
|
||||||
import com.vitorpamplona.amethyst.commons.ui.components.UserAvatar
|
import com.vitorpamplona.amethyst.commons.ui.components.UserAvatar
|
||||||
import com.vitorpamplona.amethyst.desktop.account.AccountState
|
import com.vitorpamplona.amethyst.desktop.account.AccountState
|
||||||
@@ -415,13 +422,13 @@ private fun ChessLobby(
|
|||||||
}
|
}
|
||||||
|
|
||||||
items(activeGames.entries.toList(), key = { "active-${it.key}" }) { (gameId, state) ->
|
items(activeGames.entries.toList(), key = { "active-${it.key}" }) { (gameId, state) ->
|
||||||
com.vitorpamplona.amethyst.commons.chess.ActiveGameCard(
|
ActiveGameCard(
|
||||||
gameId = gameId,
|
gameId = gameId,
|
||||||
opponentName = metadataCache.getDisplayName(state.opponentPubkey),
|
opponentName = metadataCache.getDisplayName(state.opponentPubkey),
|
||||||
isYourTurn = state.isPlayerTurn(),
|
isYourTurn = state.isPlayerTurn(),
|
||||||
onClick = { onSelectGame(gameId) },
|
onClick = { onSelectGame(gameId) },
|
||||||
avatar = {
|
avatar = {
|
||||||
com.vitorpamplona.amethyst.commons.chess.OverlappingAvatars(
|
OverlappingAvatars(
|
||||||
avatar1Hex = state.playerPubkey,
|
avatar1Hex = state.playerPubkey,
|
||||||
avatar2Hex = state.opponentPubkey,
|
avatar2Hex = state.opponentPubkey,
|
||||||
avatar1Url = metadataCache.getPictureUrl(state.playerPubkey),
|
avatar1Url = metadataCache.getPictureUrl(state.playerPubkey),
|
||||||
@@ -446,14 +453,14 @@ private fun ChessLobby(
|
|||||||
}
|
}
|
||||||
|
|
||||||
items(outgoingChallenges, key = { "outgoing-${it.eventId}" }) { challenge ->
|
items(outgoingChallenges, key = { "outgoing-${it.eventId}" }) { challenge ->
|
||||||
com.vitorpamplona.amethyst.commons.chess.OutgoingChallengeCard(
|
OutgoingChallengeCard(
|
||||||
opponentName = challenge.opponentPubkey?.let { metadataCache.getDisplayName(it) },
|
opponentName = challenge.opponentPubkey?.let { metadataCache.getDisplayName(it) },
|
||||||
userPlaysWhite = challenge.challengerColor == ChessColor.WHITE,
|
userPlaysWhite = challenge.challengerColor == ChessColor.WHITE,
|
||||||
onClick = { onOpenOwnChallenge(challenge) },
|
onClick = { onOpenOwnChallenge(challenge) },
|
||||||
avatar =
|
avatar =
|
||||||
challenge.opponentPubkey?.let { pubkey ->
|
challenge.opponentPubkey?.let { pubkey ->
|
||||||
{
|
{
|
||||||
com.vitorpamplona.amethyst.commons.chess.OverlappingAvatars(
|
OverlappingAvatars(
|
||||||
avatar1Hex = userPubkey,
|
avatar1Hex = userPubkey,
|
||||||
avatar2Hex = pubkey,
|
avatar2Hex = pubkey,
|
||||||
avatar1Url = metadataCache.getPictureUrl(userPubkey),
|
avatar1Url = metadataCache.getPictureUrl(userPubkey),
|
||||||
@@ -479,7 +486,7 @@ private fun ChessLobby(
|
|||||||
|
|
||||||
items(spectatingGames.entries.toList(), key = { "spectating-${it.key}" }) { (gameId, state) ->
|
items(spectatingGames.entries.toList(), key = { "spectating-${it.key}" }) { (gameId, state) ->
|
||||||
val moveCount by state.moveHistory.collectAsState()
|
val moveCount by state.moveHistory.collectAsState()
|
||||||
com.vitorpamplona.amethyst.commons.chess.SpectatingGameCard(
|
SpectatingGameCard(
|
||||||
moveCount = moveCount.size,
|
moveCount = moveCount.size,
|
||||||
onClick = { onSelectGame(gameId) },
|
onClick = { onSelectGame(gameId) },
|
||||||
)
|
)
|
||||||
@@ -500,13 +507,13 @@ private fun ChessLobby(
|
|||||||
}
|
}
|
||||||
|
|
||||||
items(incomingChallenges, key = { "incoming-${it.eventId}" }) { challenge ->
|
items(incomingChallenges, key = { "incoming-${it.eventId}" }) { challenge ->
|
||||||
com.vitorpamplona.amethyst.commons.chess.ChallengeCard(
|
ChallengeCard(
|
||||||
challengerName = challenge.challengerDisplayName ?: metadataCache.getDisplayName(challenge.challengerPubkey),
|
challengerName = challenge.challengerDisplayName ?: metadataCache.getDisplayName(challenge.challengerPubkey),
|
||||||
challengerPlaysWhite = challenge.challengerColor == ChessColor.WHITE,
|
challengerPlaysWhite = challenge.challengerColor == ChessColor.WHITE,
|
||||||
isIncoming = true,
|
isIncoming = true,
|
||||||
onAccept = { onAcceptChallenge(challenge) },
|
onAccept = { onAcceptChallenge(challenge) },
|
||||||
avatar = {
|
avatar = {
|
||||||
com.vitorpamplona.amethyst.commons.chess.OverlappingAvatars(
|
OverlappingAvatars(
|
||||||
avatar1Hex = challenge.challengerPubkey,
|
avatar1Hex = challenge.challengerPubkey,
|
||||||
avatar2Hex = userPubkey,
|
avatar2Hex = userPubkey,
|
||||||
avatar1Url = challenge.challengerAvatarUrl ?: metadataCache.getPictureUrl(challenge.challengerPubkey),
|
avatar1Url = challenge.challengerAvatarUrl ?: metadataCache.getPictureUrl(challenge.challengerPubkey),
|
||||||
@@ -531,13 +538,13 @@ private fun ChessLobby(
|
|||||||
}
|
}
|
||||||
|
|
||||||
items(openChallenges, key = { "open-${it.eventId}" }) { challenge ->
|
items(openChallenges, key = { "open-${it.eventId}" }) { challenge ->
|
||||||
com.vitorpamplona.amethyst.commons.chess.ChallengeCard(
|
ChallengeCard(
|
||||||
challengerName = challenge.challengerDisplayName ?: metadataCache.getDisplayName(challenge.challengerPubkey),
|
challengerName = challenge.challengerDisplayName ?: metadataCache.getDisplayName(challenge.challengerPubkey),
|
||||||
challengerPlaysWhite = challenge.challengerColor == ChessColor.WHITE,
|
challengerPlaysWhite = challenge.challengerColor == ChessColor.WHITE,
|
||||||
isIncoming = false,
|
isIncoming = false,
|
||||||
onAccept = { onAcceptChallenge(challenge) },
|
onAccept = { onAcceptChallenge(challenge) },
|
||||||
avatar = {
|
avatar = {
|
||||||
com.vitorpamplona.amethyst.commons.chess.OverlappingAvatars(
|
OverlappingAvatars(
|
||||||
avatar1Hex = challenge.challengerPubkey,
|
avatar1Hex = challenge.challengerPubkey,
|
||||||
avatar2Hex = userPubkey,
|
avatar2Hex = userPubkey,
|
||||||
avatar1Url = challenge.challengerAvatarUrl ?: metadataCache.getPictureUrl(challenge.challengerPubkey),
|
avatar1Url = challenge.challengerAvatarUrl ?: metadataCache.getPictureUrl(challenge.challengerPubkey),
|
||||||
@@ -561,7 +568,7 @@ private fun ChessLobby(
|
|||||||
}
|
}
|
||||||
|
|
||||||
items(publicGames, key = { "public-${it.gameId}" }) { game ->
|
items(publicGames, key = { "public-${it.gameId}" }) { game ->
|
||||||
com.vitorpamplona.amethyst.commons.chess.PublicGameCard(
|
PublicGameCard(
|
||||||
whiteName = game.whiteDisplayName ?: metadataCache.getDisplayName(game.whitePubkey),
|
whiteName = game.whiteDisplayName ?: metadataCache.getDisplayName(game.whitePubkey),
|
||||||
blackName = game.blackDisplayName ?: metadataCache.getDisplayName(game.blackPubkey),
|
blackName = game.blackDisplayName ?: metadataCache.getDisplayName(game.blackPubkey),
|
||||||
moveCount = game.moveCount,
|
moveCount = game.moveCount,
|
||||||
@@ -583,13 +590,13 @@ private fun ChessLobby(
|
|||||||
}
|
}
|
||||||
|
|
||||||
items(
|
items(
|
||||||
completedGames.distinctBy { it.gameId }.take(10),
|
completedGames.take(10),
|
||||||
key = { "completed-${it.gameId}-${it.completedAt}" },
|
key = { "completed-${it.gameId}-${it.completedAt}" },
|
||||||
) { game ->
|
) { game ->
|
||||||
// Derive opponent pubkey based on who the user is
|
// Derive opponent pubkey based on who the user is
|
||||||
val opponentPubkey =
|
val opponentPubkey =
|
||||||
if (game.whitePubkey == userPubkey) game.blackPubkey else game.whitePubkey
|
if (game.whitePubkey == userPubkey) game.blackPubkey else game.whitePubkey
|
||||||
com.vitorpamplona.amethyst.commons.chess.CompletedGameCard(
|
CompletedGameCard(
|
||||||
opponentName = game.blackDisplayName ?: game.whiteDisplayName ?: metadataCache.getDisplayName(opponentPubkey),
|
opponentName = game.blackDisplayName ?: game.whiteDisplayName ?: metadataCache.getDisplayName(opponentPubkey),
|
||||||
result = game.result,
|
result = game.result,
|
||||||
didUserWin = game.didUserWin(userPubkey),
|
didUserWin = game.didUserWin(userPubkey),
|
||||||
@@ -674,7 +681,7 @@ private fun DesktopChessGameLayout(
|
|||||||
) {
|
) {
|
||||||
// Player vs Player header above board
|
// Player vs Player header above board
|
||||||
if (whiteHex.isNotEmpty() || blackHex.isNotEmpty()) {
|
if (whiteHex.isNotEmpty() || blackHex.isNotEmpty()) {
|
||||||
com.vitorpamplona.amethyst.commons.chess.ChessPlayerVsHeader(
|
ChessPlayerVsHeader(
|
||||||
whiteName = whiteName,
|
whiteName = whiteName,
|
||||||
whiteHex = whiteHex,
|
whiteHex = whiteHex,
|
||||||
whiteAvatarUrl = whiteAvatarUrl,
|
whiteAvatarUrl = whiteAvatarUrl,
|
||||||
|
|||||||
Reference in New Issue
Block a user