Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- Unified the recent win/loss indicator across the games. Coinflip, Mines,
Crash and Blackjack now share one `WinLossChip` / `RecentResultsStrip`
(the Coinflip lettered W / L / P style); Crash's plain colored squares and
Blackjack's solid chips now match. Roulette keeps its pocket-number strip.

### Added

- Real "Last Played" highlight on the lobby (cu-03): the new
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ import com.plainstudio.stackcasino.domain.game.BlackjackMath
import com.plainstudio.stackcasino.ui.components.GameActionButton
import com.plainstudio.stackcasino.ui.components.GameHeader
import com.plainstudio.stackcasino.ui.components.OutcomeTone
import com.plainstudio.stackcasino.ui.components.RecentResultsStrip
import com.plainstudio.stackcasino.ui.components.StatCell
import com.plainstudio.stackcasino.ui.theme.AccentViolet
import com.plainstudio.stackcasino.ui.theme.CenteredGlyph
import com.plainstudio.stackcasino.ui.theme.DISABLED_ALPHA
import com.plainstudio.stackcasino.ui.theme.MetaFontSize
import com.plainstudio.stackcasino.ui.theme.ScreenHorizontalPadding
Expand Down Expand Up @@ -88,7 +88,16 @@ fun BlackjackScreen(
onBack = onBack,
onOpenRules = { showRules = true },
)
RecentStrip(results = state.recentResults)
RecentResultsStrip(
results =
state.recentResults.map { result ->
when (result) {
BlackjackResult.Win -> OutcomeTone.Win
BlackjackResult.Loss -> OutcomeTone.Loss
BlackjackResult.Push -> OutcomeTone.Push
}
},
)
StatsStrip(state = state)
Table(state = state, modifier = Modifier.weight(1f))
BlackjackControls(
Expand All @@ -109,44 +118,6 @@ fun BlackjackScreen(
}
}

@Composable
private fun RecentStrip(results: List<BlackjackResult>) {
Column(
modifier = Modifier.fillMaxWidth().padding(horizontal = ScreenHorizontalPadding, vertical = 6.dp),
verticalArrangement = Arrangement.spacedBy(4.dp),
) {
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
Text(text = "Recent", color = TextLow, fontSize = TinyFontSize, letterSpacing = TrackedLetterSpacing)
Text(
text = if (results.isEmpty()) "no rounds yet" else "${results.size} rounds",
color = TextLow,
fontSize = TinyFontSize,
letterSpacing = TrackedLetterSpacing,
style = TabularNums,
)
}
Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) {
results.forEach { result -> HistoryChip(result = result) }
}
}
}

@Composable
private fun HistoryChip(result: BlackjackResult) {
val (label, color) =
when (result) {
BlackjackResult.Win -> "W" to SemanticOk
BlackjackResult.Loss -> "L" to SemanticDanger
BlackjackResult.Push -> "P" to TextMedium
}
Box(
modifier = Modifier.size(HistoryChipSize).background(color),
contentAlignment = Alignment.Center,
) {
Text(text = label, color = Color.White, fontSize = 10.sp, fontWeight = FontWeight.Bold, style = CenteredGlyph)
}
}

@Composable
private fun StatsStrip(state: BlackjackUiState) {
val profitColor = if (state.sessionProfitPositive) SemanticOk else SemanticDanger
Expand Down Expand Up @@ -482,7 +453,6 @@ private val BET_PRESETS = listOf(5, 10, 25, 100)
private val BetTextStyle = TextStyle(color = TextHigh, fontSize = 14.sp, fontFeatureSettings = "tnum")

private val ControlsVerticalPadding = 12.dp
private val HistoryChipSize = 20.dp
private val HandMinHeight = 72.dp
private val CardWidth = 44.dp
private val CardHeight = 62.dp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,11 @@ import androidx.compose.ui.unit.sp
import com.plainstudio.stackcasino.domain.game.CoinSide
import com.plainstudio.stackcasino.ui.components.GameActionButton
import com.plainstudio.stackcasino.ui.components.GameHeader
import com.plainstudio.stackcasino.ui.components.OutcomeTone
import com.plainstudio.stackcasino.ui.components.RecentResultsStrip
import com.plainstudio.stackcasino.ui.components.StatCell
import com.plainstudio.stackcasino.ui.theme.AccentViolet
import com.plainstudio.stackcasino.ui.theme.AccentVioletSoft
import com.plainstudio.stackcasino.ui.theme.CHIP_BORDER_ALPHA
import com.plainstudio.stackcasino.ui.theme.CHIP_TINT_ALPHA
import com.plainstudio.stackcasino.ui.theme.CenteredGlyph
import com.plainstudio.stackcasino.ui.theme.MetaFontSize
import com.plainstudio.stackcasino.ui.theme.ScreenHorizontalPadding
import com.plainstudio.stackcasino.ui.theme.SemanticDanger
Expand Down Expand Up @@ -92,7 +91,7 @@ fun CoinflipScreen(
onBack = onBack,
onOpenRules = { showRules = true },
)
RecentStrip(results = state.recentResults)
RecentResultsStrip(results = state.recentResults.map { if (it) OutcomeTone.Win else OutcomeTone.Loss })
StatsStrip(state = state)
CoinStage(modifier = Modifier.weight(1f), state = state)
CoinflipControls(
Expand All @@ -111,49 +110,6 @@ fun CoinflipScreen(
}
}

@Composable
private fun RecentStrip(results: List<Boolean>) {
Column(
modifier = Modifier.fillMaxWidth().padding(horizontal = ScreenHorizontalPadding, vertical = 6.dp),
verticalArrangement = Arrangement.spacedBy(6.dp),
) {
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
Text(text = "Recent", color = TextLow, fontSize = TinyFontSize, letterSpacing = TrackedLetterSpacing)
Text(
text = if (results.isEmpty()) "no rounds yet" else "${results.size} rounds",
color = TextLow,
fontSize = TinyFontSize,
letterSpacing = TrackedLetterSpacing,
style = TabularNums,
)
}
Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) {
results.forEach { won -> RecentChip(won = won) }
}
}
}

@Composable
private fun RecentChip(won: Boolean) {
val accent = if (won) SemanticOk else SemanticDanger
Box(
modifier =
Modifier
.size(RecentChipSize)
.background(accent.copy(alpha = CHIP_TINT_ALPHA))
.border(width = 1.dp, color = accent.copy(alpha = CHIP_BORDER_ALPHA)),
contentAlignment = Alignment.Center,
) {
Text(
text = if (won) "W" else "L",
color = accent,
fontSize = TinyFontSize,
fontWeight = FontWeight.Bold,
style = CenteredGlyph,
)
}
}

@Composable
private fun StatsStrip(state: CoinflipUiState) {
val profitColor = if (state.sessionProfitPositive) SemanticOk else SemanticDanger
Expand Down Expand Up @@ -414,7 +370,6 @@ private const val SHARE_MESSAGE =
private val BET_PRESETS = listOf(5, 10, 25, 100)

private val ControlsVerticalPadding = 12.dp
private val RecentChipSize = 20.dp
private val CoinSize = 180.dp
private val CoinLabelOffset = 60.dp

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.plainstudio.stackcasino.ui.components.GameActionButton
import com.plainstudio.stackcasino.ui.components.GameHeader
import com.plainstudio.stackcasino.ui.components.OutcomeTone
import com.plainstudio.stackcasino.ui.components.RecentResultsStrip
import com.plainstudio.stackcasino.ui.components.StatCell
import com.plainstudio.stackcasino.ui.components.gridBackground
import com.plainstudio.stackcasino.ui.theme.AccentViolet
Expand Down Expand Up @@ -94,7 +96,7 @@ fun CrashScreen(
onBack = onBack,
onOpenRules = { showRules = true },
)
RecentStrip(results = state.recentResults)
RecentResultsStrip(results = state.recentResults.map { if (it) OutcomeTone.Win else OutcomeTone.Loss })
StatsStrip(state = state, multiplier = multiplier)
CrashChart(state = state, multiplier = multiplier, modifier = Modifier.weight(1f))
CrashControls(
Expand All @@ -115,38 +117,6 @@ fun CrashScreen(
}
}

@Composable
private fun RecentStrip(results: List<Boolean>) {
Column(
modifier = Modifier.fillMaxWidth().padding(horizontal = ScreenHorizontalPadding, vertical = 6.dp),
verticalArrangement = Arrangement.spacedBy(6.dp),
) {
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
Text(text = "Recent", color = TextLow, fontSize = TinyFontSize, letterSpacing = TrackedLetterSpacing)
Text(
text = if (results.isEmpty()) "no rounds yet" else "${results.size} rounds",
color = TextLow,
fontSize = TinyFontSize,
letterSpacing = TrackedLetterSpacing,
style = TabularNums,
)
}
Row(horizontalArrangement = Arrangement.spacedBy(2.dp)) {
results.forEach { cashed -> RecentChip(cashed = cashed) }
}
}
}

@Composable
private fun RecentChip(cashed: Boolean) {
Box(
modifier =
Modifier
.size(RecentChipSize)
.background(if (cashed) SemanticOk else SemanticDanger),
)
}

@Composable
private fun StatsStrip(
state: CrashUiState,
Expand Down Expand Up @@ -446,7 +416,6 @@ private val HeroStyle =
)

private val ControlsVerticalPadding = 12.dp
private val RecentChipSize = 12.dp
private val AutoCashoutWidth = 84.dp

private val HeroFontSize = 56.sp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.plainstudio.stackcasino.ui.components.GameActionButton
import com.plainstudio.stackcasino.ui.components.GameHeader
import com.plainstudio.stackcasino.ui.components.OutcomeTone
import com.plainstudio.stackcasino.ui.components.RecentResultsStrip
import com.plainstudio.stackcasino.ui.components.StatCell
import com.plainstudio.stackcasino.ui.theme.AccentViolet
import com.plainstudio.stackcasino.ui.theme.CHIP_BORDER_ALPHA
import com.plainstudio.stackcasino.ui.theme.CHIP_TINT_ALPHA
import com.plainstudio.stackcasino.ui.theme.CenteredGlyph
import com.plainstudio.stackcasino.ui.theme.MetaFontSize
import com.plainstudio.stackcasino.ui.theme.ScreenHorizontalPadding
import com.plainstudio.stackcasino.ui.theme.SemanticDanger
Expand Down Expand Up @@ -86,7 +86,7 @@ fun MinesScreen(
onBack = onBack,
onOpenRules = { showRules = true },
)
RecentStrip(results = state.recentResults)
RecentResultsStrip(results = state.recentResults.map { if (it) OutcomeTone.Win else OutcomeTone.Loss })
StatsStrip(state = state)
MinesGrid(state = state, onRevealTile = onRevealTile, modifier = Modifier.weight(1f))
MinesControls(
Expand All @@ -105,49 +105,6 @@ fun MinesScreen(
}
}

@Composable
private fun RecentStrip(results: List<Boolean>) {
Column(
modifier = Modifier.fillMaxWidth().padding(horizontal = ScreenHorizontalPadding, vertical = 6.dp),
verticalArrangement = Arrangement.spacedBy(6.dp),
) {
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
Text(text = "Recent", color = TextLow, fontSize = TinyFontSize, letterSpacing = TrackedLetterSpacing)
Text(
text = if (results.isEmpty()) "no rounds yet" else "${results.size} rounds",
color = TextLow,
fontSize = TinyFontSize,
letterSpacing = TrackedLetterSpacing,
style = TabularNums,
)
}
Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) {
results.forEach { won -> RecentChip(won = won) }
}
}
}

@Composable
private fun RecentChip(won: Boolean) {
val accent = if (won) SemanticOk else SemanticDanger
Box(
modifier =
Modifier
.size(RecentChipSize)
.background(accent.copy(alpha = CHIP_TINT_ALPHA))
.border(width = 1.dp, color = accent.copy(alpha = CHIP_BORDER_ALPHA)),
contentAlignment = Alignment.Center,
) {
Text(
text = if (won) "W" else "L",
color = accent,
fontSize = TinyFontSize,
fontWeight = FontWeight.Bold,
style = CenteredGlyph,
)
}
}

@Composable
private fun StatsStrip(state: MinesUiState) {
val profitColor = if (state.sessionProfitPositive) SemanticOk else SemanticDanger
Expand Down Expand Up @@ -479,7 +436,6 @@ private const val RISK_MAX = 1.0f
private val RiskOrange = Color(0xFFF97316)
private val GridHorizontalPadding = 24.dp
private val ControlsVerticalPadding = 12.dp
private val RecentChipSize = 18.dp
private val GridGap = 6.dp
private val TileDotSize = 12.dp
private val ProgressBarHeight = 4.dp
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.plainstudio.stackcasino.ui.components

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.plainstudio.stackcasino.ui.theme.ScreenHorizontalPadding
import com.plainstudio.stackcasino.ui.theme.TabularNums
import com.plainstudio.stackcasino.ui.theme.TextLow
import com.plainstudio.stackcasino.ui.theme.TinyFontSize
import com.plainstudio.stackcasino.ui.theme.TrackedLetterSpacing

/**
* Recent-rounds strip shared by every game screen except Roulette: a
* "Recent" / round-count header over a row of [WinLossChip]s, in the
* Coinflip style.
*
* @param results most-recent-first round outcomes; when empty the header
* shows a "no rounds yet" hint and no chips are drawn.
*/
@Composable
fun RecentResultsStrip(
results: List<OutcomeTone>,
modifier: Modifier = Modifier,
) {
Column(
modifier = modifier.fillMaxWidth().padding(horizontal = ScreenHorizontalPadding, vertical = 6.dp),
verticalArrangement = Arrangement.spacedBy(6.dp),
) {
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
Text(text = "Recent", color = TextLow, fontSize = TinyFontSize, letterSpacing = TrackedLetterSpacing)
Text(
text = if (results.isEmpty()) "no rounds yet" else "${results.size} rounds",
color = TextLow,
fontSize = TinyFontSize,
letterSpacing = TrackedLetterSpacing,
style = TabularNums,
)
}
Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) {
results.forEach { tone -> WinLossChip(tone = tone) }
}
}
}
Loading
Loading