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

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.plainstudio.stackcasino.R
import com.plainstudio.stackcasino.ui.components.HairlineDivider
import com.plainstudio.stackcasino.ui.components.PulsingDot
import com.plainstudio.stackcasino.ui.theme.AccentViolet
import com.plainstudio.stackcasino.ui.theme.SemanticOk
Expand Down Expand Up @@ -177,7 +178,7 @@ private fun AssistantHeader(
onClick = onClear,
)
}
Divider()
HairlineDivider()
}

@Composable
Expand Down Expand Up @@ -236,7 +237,7 @@ private fun AssistantInputBar(
.navigationBarsPadding()
.padding(InputBarOuterPadding),
) {
Divider()
HairlineDivider()
Spacer(modifier = Modifier.height(InputBarTopGap))
Row(
modifier = Modifier.fillMaxWidth(),
Expand Down Expand Up @@ -345,17 +346,6 @@ private fun InputBarFooter(charCount: Int) {
}
}

@Composable
internal fun Divider() {
Box(
modifier =
Modifier
.fillMaxWidth()
.height(1.dp)
.background(SurfaceOutline),
)
}

// ---------------------------------------------------------------------------
// Tokens shared across the assistant files.
// ---------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ import com.plainstudio.stackcasino.domain.assistant.ChatTurn
import com.plainstudio.stackcasino.domain.assistant.Role
import com.plainstudio.stackcasino.util.IdGenerator
import com.plainstudio.stackcasino.util.TimeProvider
import com.plainstudio.stackcasino.util.TimestampFormat
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import java.text.SimpleDateFormat
import java.util.Locale
import javax.inject.Inject

/**
Expand Down Expand Up @@ -118,14 +117,13 @@ class AssistantViewModel
copy(messages = messages + message)
}

private fun nowLabel(): String = TIMESTAMP_FORMAT.format(timeProvider.now())
private fun nowLabel(): String = TimestampFormat.timeOfDay(timeProvider.now().time)

// Per-message handle so the LazyColumn key never collides on
// repeated identical questions sent inside the same minute.
private fun newId(): String = idGenerator.newId()

companion object {
const val MAX_USER_MESSAGE_LENGTH = 300
private val TIMESTAMP_FORMAT = SimpleDateFormat("h:mm a", Locale.US)
}
}
Original file line number Diff line number Diff line change
@@ -1,105 +1,20 @@
package com.plainstudio.stackcasino.feature.blackjack

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.plainstudio.stackcasino.ui.theme.AccentViolet
import com.plainstudio.stackcasino.ui.theme.SurfaceOutline
import com.plainstudio.stackcasino.ui.theme.SurfaceRaised
import com.plainstudio.stackcasino.ui.theme.TextHigh
import com.plainstudio.stackcasino.ui.theme.TextLow
import com.plainstudio.stackcasino.ui.theme.TextMedium
import com.plainstudio.stackcasino.ui.components.RulesSheet

/**
* Blackjack rules sheet reached from the header, styled after the
* mockup's legal sheets: a tracked label, a bold title and a meta line
* over the numbered rule sections.
* Blackjack rules sheet reached from the header. Thin wrapper over the
* shared [RulesSheet]; only the title, meta line and rule data differ.
*/
@OptIn(ExperimentalMaterial3Api::class)
@Composable
internal fun BlackjackRulesSheet(onDismiss: () -> Unit) {
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
ModalBottomSheet(
onDismissRequest = onDismiss,
sheetState = sheetState,
containerColor = SurfaceRaised,
contentColor = TextHigh,
) {
Column(modifier = Modifier.fillMaxWidth().verticalScroll(rememberScrollState())) {
Column(
modifier = Modifier.fillMaxWidth().padding(start = SheetPadding, end = SheetPadding, bottom = 16.dp),
) {
Text(
text = "How to Play",
color = AccentViolet,
fontSize = LabelFontSize,
letterSpacing = TrackedLetterSpacing,
)
Spacer(modifier = Modifier.height(2.dp))
Text(text = "Blackjack Rules", color = TextHigh, fontSize = 20.sp, fontWeight = FontWeight.Bold)
Spacer(modifier = Modifier.height(4.dp))
Text(
text = "Classic · Dealer stands on 17 · RTP 99.5%",
color = TextLow,
fontSize = MetaFontSize,
letterSpacing = TrackedLetterSpacing,
style = TabularNums,
)
}
Divider()
Column(
modifier = Modifier.fillMaxWidth().padding(SheetPadding),
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
RULES.forEach { (label, body) -> RuleSection(label = label, body = body) }
Spacer(modifier = Modifier.height(4.dp))
Divider()
Text(
text = "End of rules · Must be 18+ to play",
color = TextLow,
fontSize = MetaFontSize,
letterSpacing = TrackedLetterSpacing,
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth().padding(top = 12.dp, bottom = 24.dp),
)
}
}
}
}

@Composable
private fun RuleSection(
label: String,
body: String,
) {
Column(modifier = Modifier.fillMaxWidth()) {
Text(text = label, color = AccentViolet, fontSize = LabelFontSize, letterSpacing = TrackedLetterSpacing)
Spacer(modifier = Modifier.height(4.dp))
Text(text = body, color = TextMedium, fontSize = 13.sp, lineHeight = 22.sp)
}
}

@Composable
private fun Divider() {
Box(modifier = Modifier.fillMaxWidth().height(1.dp).background(SurfaceOutline))
RulesSheet(
title = "Blackjack Rules",
meta = "Classic · Dealer stands on 17 · RTP 99.5%",
rules = RULES,
onDismiss = onDismiss,
)
}

private val RULES =
Expand All @@ -122,9 +37,3 @@ private val RULES =
"Card order is derived from HMAC-SHA256(server_seed, client_seed:nonce). The shuffle is revealed after " +
"each round.",
)

private val TabularNums = TextStyle(fontFeatureSettings = "tnum")
private val SheetPadding = 20.dp
private val LabelFontSize = 10.sp
private val MetaFontSize = 9.sp
private val TrackedLetterSpacing = 1.2.sp
Loading
Loading