diff --git a/app/src/main/java/com/plainstudio/stackcasino/MainActivity.kt b/app/src/main/java/com/plainstudio/stackcasino/MainActivity.kt index 3c853a3..4765559 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/MainActivity.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/MainActivity.kt @@ -18,6 +18,12 @@ import com.plainstudio.stackcasino.feature.splash.SplashViewModel import com.plainstudio.stackcasino.ui.theme.StackcasinoTheme import dagger.hilt.android.AndroidEntryPoint +/** + * Single-activity host. Installs the AndroidX system splash, keeps it on + * screen while [SplashViewModel] resolves the start destination from the + * cached auth state, then hands off to [StackApp] once the decision is + * ready. + */ @AndroidEntryPoint class MainActivity : ComponentActivity() { private val splashViewModel: SplashViewModel by viewModels() diff --git a/app/src/main/java/com/plainstudio/stackcasino/StackCasinoApp.kt b/app/src/main/java/com/plainstudio/stackcasino/StackCasinoApp.kt index a6a56c1..ee0d589 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/StackCasinoApp.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/StackCasinoApp.kt @@ -3,5 +3,10 @@ package com.plainstudio.stackcasino import android.app.Application import dagger.hilt.android.HiltAndroidApp +/** + * Application entry point. Annotated with [HiltAndroidApp] so Hilt + * generates the application-level dependency container that every + * other component (activities, ViewModels, modules) is built on top of. + */ @HiltAndroidApp class StackCasinoApp : Application() diff --git a/app/src/main/java/com/plainstudio/stackcasino/data/auth/LastSignInHint.kt b/app/src/main/java/com/plainstudio/stackcasino/data/auth/LastSignInHint.kt index 5221c32..6e5727d 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/data/auth/LastSignInHint.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/data/auth/LastSignInHint.kt @@ -24,12 +24,14 @@ class LastSignInHint ) { private val prefs = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE) + /** The cosmetic last-sign-in details rendered on the returning-user card. */ data class Hint( val displayName: String, val email: String, val photoUrl: String?, ) + /** Reads the stored hint, or null when no complete hint was persisted. */ fun read(): Hint? { val displayName = prefs.getString(KEY_DISPLAY_NAME, null) ?: return null val email = prefs.getString(KEY_EMAIL, null) ?: return null @@ -37,6 +39,7 @@ class LastSignInHint return Hint(displayName, email, photoUrl) } + /** Persists [hint] so the returning-user card survives sign-out. */ fun write(hint: Hint) { prefs.edit { putString(KEY_DISPLAY_NAME, hint.displayName) @@ -45,6 +48,7 @@ class LastSignInHint } } + /** Wipes the stored hint (for example after an explicit account switch). */ fun clear() { prefs.edit { clear() } } diff --git a/app/src/main/java/com/plainstudio/stackcasino/data/local/GameRoundDao.kt b/app/src/main/java/com/plainstudio/stackcasino/data/local/GameRoundDao.kt index e9a811e..944c541 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/data/local/GameRoundDao.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/data/local/GameRoundDao.kt @@ -9,12 +9,15 @@ import kotlinx.coroutines.flow.Flow /** Room access for the settled game-round ledger. */ @Dao interface GameRoundDao { + /** Observes every settled round, newest first, for the History feed. */ @Query("SELECT * FROM game_round ORDER BY timestamp DESC") fun observeRounds(): Flow> + /** Reads a single round by id for the round-detail / verification screen. */ @Query("SELECT * FROM game_round WHERE id = :id") suspend fun getRound(id: String): GameRoundEntity? + /** Inserts a settled round, replacing any existing row with the same id. */ @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertRound(round: GameRoundEntity) } diff --git a/app/src/main/java/com/plainstudio/stackcasino/data/local/NotificationDao.kt b/app/src/main/java/com/plainstudio/stackcasino/data/local/NotificationDao.kt index e2299ab..c02c9a3 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/data/local/NotificationDao.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/data/local/NotificationDao.kt @@ -12,9 +12,11 @@ interface NotificationDao { @Query("SELECT * FROM notification ORDER BY createdAt DESC") fun observeAll(): Flow> + /** Observes the unread count that drives the lobby bell badge. */ @Query("SELECT COUNT(*) FROM notification WHERE isRead = 0") fun observeUnreadCount(): Flow + /** Total row count; used to decide whether the inbox needs seeding. */ @Query("SELECT COUNT(*) FROM notification") suspend fun count(): Int @@ -23,9 +25,11 @@ interface NotificationDao { @Insert suspend fun insertAll(items: List): List + /** Marks the row with [id] read; returns the number of rows updated. */ @Query("UPDATE notification SET isRead = 1 WHERE id = :id") suspend fun markRead(id: String): Int + /** Marks every unread row read; returns the number of rows updated. */ @Query("UPDATE notification SET isRead = 1 WHERE isRead = 0") suspend fun markAllRead(): Int } diff --git a/app/src/main/java/com/plainstudio/stackcasino/data/local/StackDatabase.kt b/app/src/main/java/com/plainstudio/stackcasino/data/local/StackDatabase.kt index a7f1739..31a9725 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/data/local/StackDatabase.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/data/local/StackDatabase.kt @@ -22,14 +22,19 @@ import androidx.room.RoomDatabase exportSchema = true, ) abstract class StackDatabase : RoomDatabase() { + /** DAO for the local app-settings row. */ abstract fun appSettingsDao(): AppSettingsDao + /** DAO for the notification inbox. */ abstract fun notificationDao(): NotificationDao + /** DAO for the cached news feed. */ abstract fun newsArticleDao(): NewsArticleDao + /** DAO for the wallet snapshot and its transaction ledger. */ abstract fun walletDao(): WalletDao + /** DAO for the settled game-round ledger. */ abstract fun gameRoundDao(): GameRoundDao companion object { diff --git a/app/src/main/java/com/plainstudio/stackcasino/data/local/WalletDao.kt b/app/src/main/java/com/plainstudio/stackcasino/data/local/WalletDao.kt index c71e801..7955a98 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/data/local/WalletDao.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/data/local/WalletDao.kt @@ -10,24 +10,31 @@ import kotlinx.coroutines.flow.Flow /** Room access for the wallet snapshot and its transaction ledger. */ @Dao interface WalletDao { + /** Observes the singleton wallet row; emits null until it is seeded. */ @Query("SELECT * FROM wallet WHERE id = 0") fun observeWallet(): Flow + /** Reads the singleton wallet row once, or null when it has not been seeded. */ @Query("SELECT * FROM wallet WHERE id = 0") suspend fun getWallet(): WalletEntity? + /** Inserts or updates the singleton wallet row, returning its row id. */ @Upsert suspend fun upsertWallet(wallet: WalletEntity): Long + /** Observes the full transaction ledger, newest first. */ @Query("SELECT * FROM wallet_transaction ORDER BY timestamp DESC") fun observeTransactions(): Flow> + /** Counts the ledger rows; used to decide whether seeding is needed. */ @Query("SELECT COUNT(*) FROM wallet_transaction") suspend fun transactionCount(): Int + /** Inserts a batch of ledger rows, replacing any with matching ids. */ @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertTransactions(items: List): List + /** Inserts a single ledger row, replacing any with the same id. */ @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertTransaction(item: WalletTransactionEntity): Long } diff --git a/app/src/main/java/com/plainstudio/stackcasino/data/local/WalletEntity.kt b/app/src/main/java/com/plainstudio/stackcasino/data/local/WalletEntity.kt index aefee54..c9d582f 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/data/local/WalletEntity.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/data/local/WalletEntity.kt @@ -20,6 +20,7 @@ data class WalletEntity( val updatedAt: Long, ) { companion object { + /** The wallet row is a singleton; its primary key is always this. */ const val SINGLETON_ID = 0 } } diff --git a/app/src/main/java/com/plainstudio/stackcasino/data/news/NewsApiService.kt b/app/src/main/java/com/plainstudio/stackcasino/data/news/NewsApiService.kt index c7f8300..3374549 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/data/news/NewsApiService.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/data/news/NewsApiService.kt @@ -15,6 +15,7 @@ import retrofit2.http.Query * round-trips. */ interface NewsApiService { + /** Fetches articles matching [query] from the "/everything" endpoint. */ @GET("everything") suspend fun fetchEverything( @Query("q") query: String, @@ -28,6 +29,10 @@ interface NewsApiService { } } +/** + * Top-level NewsAPI response. [status] is "ok" on success; [code] and + * [message] carry the error detail when it is "error". + */ @JsonClass(generateAdapter = true) data class NewsApiResponseDto( val status: String, @@ -37,6 +42,7 @@ data class NewsApiResponseDto( val message: String? = null, ) +/** A single article in the NewsAPI response; most fields are nullable upstream. */ @JsonClass(generateAdapter = true) data class NewsApiArticleDto( val source: NewsApiSourceDto, @@ -47,6 +53,7 @@ data class NewsApiArticleDto( val publishedAt: String?, ) +/** The publisher block nested in each NewsAPI article. */ @JsonClass(generateAdapter = true) data class NewsApiSourceDto( val id: String?, diff --git a/app/src/main/java/com/plainstudio/stackcasino/data/wallet/WalletRemoteDataSource.kt b/app/src/main/java/com/plainstudio/stackcasino/data/wallet/WalletRemoteDataSource.kt index 1bfb1b3..9d623bf 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/data/wallet/WalletRemoteDataSource.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/data/wallet/WalletRemoteDataSource.kt @@ -28,6 +28,7 @@ class WalletRemoteDataSource constructor( private val firestore: FirebaseFirestore, ) { + /** Reads `wallets/{uid}`, returning null when the document is absent. */ suspend fun fetchWallet(uid: String): Wallet? { val doc = firestore @@ -44,6 +45,7 @@ class WalletRemoteDataSource ) } + /** Reads the user's `transactions` documents into ledger entries. */ suspend fun fetchTransactions(uid: String): List { val snapshot = firestore @@ -65,6 +67,10 @@ class WalletRemoteDataSource } } + /** + * Writes a `pending` withdrawal document (the client half of EP-05); + * the Cloud Function later signs and confirms it on-chain. + */ suspend fun createPendingWithdrawal( uid: String, id: String, diff --git a/app/src/main/java/com/plainstudio/stackcasino/di/AppModule.kt b/app/src/main/java/com/plainstudio/stackcasino/di/AppModule.kt index 2293634..4e34a0f 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/di/AppModule.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/di/AppModule.kt @@ -53,6 +53,12 @@ object AppModule { @Singleton fun provideIdGenerator(): IdGenerator = UuidIdGenerator() + /** + * Application-lifetime [CoroutineScope] for fire-and-forget work. A + * [SupervisorJob] keeps one failing child from cancelling its + * siblings, and [Dispatchers.IO] suits the best-effort remote writes + * this scope is meant for. + */ @Provides @Singleton @AppScope diff --git a/app/src/main/java/com/plainstudio/stackcasino/domain/assistant/AssistantRepository.kt b/app/src/main/java/com/plainstudio/stackcasino/domain/assistant/AssistantRepository.kt index ede8968..f770863 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/domain/assistant/AssistantRepository.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/domain/assistant/AssistantRepository.kt @@ -10,6 +10,7 @@ data class ChatTurn( val text: String, ) +/** Who authored a [ChatTurn]: the player ([User]) or the assistant ([Nep]). */ enum class Role { User, Nep } /** diff --git a/app/src/main/java/com/plainstudio/stackcasino/domain/game/BlackjackMath.kt b/app/src/main/java/com/plainstudio/stackcasino/domain/game/BlackjackMath.kt index d3bdd7b..78912dd 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/domain/game/BlackjackMath.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/domain/game/BlackjackMath.kt @@ -41,6 +41,7 @@ object BlackjackMath { return sum } + /** Whether the hand busts: its best total exceeds 21. */ fun isBust(cards: List): Boolean = total(cards) > BLACKJACK /** A natural: exactly two cards totalling 21. */ diff --git a/app/src/main/java/com/plainstudio/stackcasino/domain/wallet/Wallet.kt b/app/src/main/java/com/plainstudio/stackcasino/domain/wallet/Wallet.kt index c19b255..b8a3ed6 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/domain/wallet/Wallet.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/domain/wallet/Wallet.kt @@ -8,8 +8,10 @@ data class Wallet( val currencyCode: String, ) +/** Direction of a wallet transaction: funds in ([Deposit]) or out ([Withdraw]). */ enum class WalletTxType { Deposit, Withdraw } +/** Lifecycle state of a wallet transaction in the ledger. */ enum class WalletTxStatus { Confirmed, Pending, Failed } /** A single ledger entry in the wallet transaction history. */ diff --git a/app/src/main/java/com/plainstudio/stackcasino/domain/wallet/WalletRepository.kt b/app/src/main/java/com/plainstudio/stackcasino/domain/wallet/WalletRepository.kt index e46c377..9d8cdcf 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/domain/wallet/WalletRepository.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/domain/wallet/WalletRepository.kt @@ -9,8 +9,10 @@ import kotlinx.coroutines.flow.Flow * (validate + record a pending transaction, locking the funds). */ interface WalletRepository { + /** Cold stream of the wallet balances and deposit address. */ val wallet: Flow + /** Cold stream of the wallet transaction history, newest first. */ val transactions: Flow> /** Seeds the wallet + sample ledger on first run if empty. Idempotent. */ diff --git a/app/src/main/java/com/plainstudio/stackcasino/feature/assistant/AssistantUiState.kt b/app/src/main/java/com/plainstudio/stackcasino/feature/assistant/AssistantUiState.kt index 086852e..265b4fc 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/feature/assistant/AssistantUiState.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/feature/assistant/AssistantUiState.kt @@ -40,4 +40,5 @@ data class ChatMessage( val isError: Boolean = false, ) +/** Who authored a [ChatMessage]: the player or the Nep assistant. */ enum class Author { User, Nep } diff --git a/app/src/main/java/com/plainstudio/stackcasino/feature/assistant/AssistantViewModel.kt b/app/src/main/java/com/plainstudio/stackcasino/feature/assistant/AssistantViewModel.kt index 6294f2c..e088c05 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/feature/assistant/AssistantViewModel.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/feature/assistant/AssistantViewModel.kt @@ -42,6 +42,10 @@ class AssistantViewModel private val _uiState = MutableStateFlow(AssistantUiState.Welcome) val uiState: StateFlow = _uiState.asStateFlow() + /** + * Appends the user turn, shows the typing indicator, and asks the + * repository for Nep's reply. Blank or over-budget text is ignored. + */ fun sendMessage(text: String) { val trimmed = text.trim() if (trimmed.isEmpty() || trimmed.length > MAX_USER_MESSAGE_LENGTH) return @@ -84,6 +88,7 @@ class AssistantViewModel } } + /** Resets the chat back to the welcome state. */ fun clear() { _uiState.value = AssistantUiState.Welcome } diff --git a/app/src/main/java/com/plainstudio/stackcasino/feature/auth/LoginViewModel.kt b/app/src/main/java/com/plainstudio/stackcasino/feature/auth/LoginViewModel.kt index aff0693..2f26703 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/feature/auth/LoginViewModel.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/feature/auth/LoginViewModel.kt @@ -46,6 +46,10 @@ class LoginViewModel ) val events: SharedFlow = _events.asSharedFlow() + /** + * Launches the Credential Manager sign-in flow. No-ops while a + * sign-in is already in flight so a double tap can't fire twice. + */ fun signIn(activity: Activity) { if (_uiState.value is LoginUiState.Loading) return _uiState.value = LoginUiState.Loading @@ -64,6 +68,7 @@ class LoginViewModel signIn(activity) } + /** Dismisses the error banner, returning to the resting state. */ fun dismissError() { if (_uiState.value is LoginUiState.Error) { _uiState.value = deriveRestingState() diff --git a/app/src/main/java/com/plainstudio/stackcasino/feature/blackjack/BlackjackViewModel.kt b/app/src/main/java/com/plainstudio/stackcasino/feature/blackjack/BlackjackViewModel.kt index eab24e6..f04b7c0 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/feature/blackjack/BlackjackViewModel.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/feature/blackjack/BlackjackViewModel.kt @@ -197,6 +197,7 @@ class BlackjackViewModel gameRepository.settleBlackjack(settled, effectiveStake, payout, playerTotal, dealerTotal, label) } + /** Resolves a finished hand to its (payout, result label) pair. */ private fun outcome( playerBust: Boolean, playerTotal: Int, diff --git a/app/src/main/java/com/plainstudio/stackcasino/feature/history/HistoryUiState.kt b/app/src/main/java/com/plainstudio/stackcasino/feature/history/HistoryUiState.kt index 28bfc33..137771a 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/feature/history/HistoryUiState.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/feature/history/HistoryUiState.kt @@ -17,6 +17,10 @@ data class HistoryData( val rounds: List, ) +/** + * Pre-formatted aggregates for the summary strip. [netLabel] is already + * sign-prefixed ("+$412.30" / "-$50.00") so the screen renders it as-is. + */ data class HistorySummary( val totalRounds: Int, val winRatePercent: Int, diff --git a/app/src/main/java/com/plainstudio/stackcasino/feature/lobby/LobbyUiState.kt b/app/src/main/java/com/plainstudio/stackcasino/feature/lobby/LobbyUiState.kt index 778ec39..e444cb6 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/feature/lobby/LobbyUiState.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/feature/lobby/LobbyUiState.kt @@ -45,6 +45,10 @@ data class LobbyData( val recentActivity: List, ) +/** + * Header identity block. [greeting] is the time-of-day salutation + * ("Good Evening") rendered above the display name. + */ data class UserSummary( val displayName: String, val greeting: String, @@ -65,6 +69,7 @@ data class BalanceSummary( val lockedSubtitle: String, ) +/** Current-session tallies shown under the balance hero (rounds, wins, losses). */ data class SessionStats( val rounds: Int, val wins: Int, diff --git a/app/src/main/java/com/plainstudio/stackcasino/feature/lobby/LobbyViewModel.kt b/app/src/main/java/com/plainstudio/stackcasino/feature/lobby/LobbyViewModel.kt index cb8f1ba..3a37f82 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/feature/lobby/LobbyViewModel.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/feature/lobby/LobbyViewModel.kt @@ -24,6 +24,7 @@ class LobbyViewModel constructor( gameRepository: GameRepository, ) : ViewModel() { + /** The user's most recently played game, or null when none has been played yet. */ val lastPlayedGame: StateFlow = gameRepository.rounds .map { rounds -> rounds.firstOrNull()?.game } diff --git a/app/src/main/java/com/plainstudio/stackcasino/feature/news/NewsDetailViewModel.kt b/app/src/main/java/com/plainstudio/stackcasino/feature/news/NewsDetailViewModel.kt index 271a219..0acb45f 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/feature/news/NewsDetailViewModel.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/feature/news/NewsDetailViewModel.kt @@ -54,6 +54,13 @@ class NewsDetailViewModel } } +/** + * Render state for the news detail screen. + * + * * [Loading] -> the cached lookup has not emitted yet. + * * [NotFound] -> no article matches the requested id in the cache. + * * [Loaded] -> the cached [NewsArticle] is ready to render. + */ sealed interface NewsDetailUiState { data object Loading : NewsDetailUiState diff --git a/app/src/main/java/com/plainstudio/stackcasino/feature/notifications/NotificationsViewModel.kt b/app/src/main/java/com/plainstudio/stackcasino/feature/notifications/NotificationsViewModel.kt index 2c3f3bf..bb5c943 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/feature/notifications/NotificationsViewModel.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/feature/notifications/NotificationsViewModel.kt @@ -41,10 +41,12 @@ class NotificationsViewModel viewModelScope.launch { repository.ensureSeeded() } } + /** Marks the notification with [id] as read. */ fun markRead(id: String) { viewModelScope.launch { repository.markRead(id) } } + /** Marks every notification in the inbox as read. */ fun markAllRead() { viewModelScope.launch { repository.markAllRead() } } diff --git a/app/src/main/java/com/plainstudio/stackcasino/feature/profile/ProfilePreviewData.kt b/app/src/main/java/com/plainstudio/stackcasino/feature/profile/ProfilePreviewData.kt index 365c6ee..a90edcf 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/feature/profile/ProfilePreviewData.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/feature/profile/ProfilePreviewData.kt @@ -13,6 +13,7 @@ import com.plainstudio.stackcasino.util.initialsOf internal const val MEMBER_SINCE_PLACEHOLDER = "Member since Apr 2026" internal const val APP_VERSION_LABEL = "Stack · Plain Studio · v0.1.0" +/** Placeholder all-time P&L summary mirroring the mockup numbers. */ internal fun placeholderPnl(): ProfilePnl = ProfilePnl( netLabel = "-$3,529.50", @@ -24,6 +25,7 @@ internal fun placeholderPnl(): ProfilePnl = wonFraction = 0.717f, ) +/** Placeholder per-game activity rows mirroring the mockup breakdown. */ internal fun placeholderGameActivity(): List = listOf( GameActivityRow( @@ -68,6 +70,7 @@ internal fun placeholderGameActivity(): List = ), ) +/** Full profile seed combining a sample identity with the placeholder stats. */ internal fun previewProfileData(): ProfileData = ProfileData( identity = diff --git a/app/src/main/java/com/plainstudio/stackcasino/feature/profile/ProfileScreen.kt b/app/src/main/java/com/plainstudio/stackcasino/feature/profile/ProfileScreen.kt index ba0e657..a604879 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/feature/profile/ProfileScreen.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/feature/profile/ProfileScreen.kt @@ -84,6 +84,12 @@ fun ProfileScreen( } } +/** + * Stateless profile scaffold: renders the header plus the body for the + * current [state] (success, loading or error). Hoisted out of + * [ProfileScreen] so the @Preview composables can drive it with fixed + * state. + */ @Composable internal fun ProfileScreenContent( state: ProfileUiState, diff --git a/app/src/main/java/com/plainstudio/stackcasino/feature/rounddetail/RoundDetailData.kt b/app/src/main/java/com/plainstudio/stackcasino/feature/rounddetail/RoundDetailData.kt index 5416ceb..e50221f 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/feature/rounddetail/RoundDetailData.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/feature/rounddetail/RoundDetailData.kt @@ -34,6 +34,7 @@ data class RoundStat( val tone: StatTone, ) +/** Color treatment applied to a [RoundStat] value. */ enum class StatTone { Neutral, Accent, Danger } /** @@ -53,6 +54,7 @@ data class TimelineEvent( val tone: TimelineTone, ) +/** Color treatment applied to a [TimelineEvent] node. */ enum class TimelineTone { Neutral, Ok, Danger } /** @@ -68,6 +70,7 @@ data class ProvablyFair( val derivation: String, ) +/** A labeled provably-fair input and its full (untruncated) value. */ data class SeedValue( val label: String, val value: String, diff --git a/app/src/main/java/com/plainstudio/stackcasino/feature/wallet/WalletUiState.kt b/app/src/main/java/com/plainstudio/stackcasino/feature/wallet/WalletUiState.kt index 55df08f..4209e69 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/feature/wallet/WalletUiState.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/feature/wallet/WalletUiState.kt @@ -55,6 +55,7 @@ data class WalletTransaction( val currencyCode: String, ) +/** Direction of a ledger entry: money in ([Deposit]) or out ([Withdraw]). */ enum class TransactionType { Deposit, Withdraw } /** diff --git a/app/src/main/java/com/plainstudio/stackcasino/ui/components/EmptyState.kt b/app/src/main/java/com/plainstudio/stackcasino/ui/components/EmptyState.kt index d1707eb..cbaead3 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/ui/components/EmptyState.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/ui/components/EmptyState.kt @@ -98,7 +98,9 @@ fun EmptyState( } } +/** Ready-made icon slots for [EmptyState]. */ object EmptyStateDefaults { + /** Generic history glyph for screens without a context-specific icon. */ @Composable fun PlaceholderIcon() { Icon( diff --git a/app/src/main/java/com/plainstudio/stackcasino/ui/components/ErrorState.kt b/app/src/main/java/com/plainstudio/stackcasino/ui/components/ErrorState.kt index 6ed9c55..ce0dc33 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/ui/components/ErrorState.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/ui/components/ErrorState.kt @@ -175,7 +175,9 @@ private fun FooterRow(text: String) { } } +/** Ready-made icon slots for [ErrorState]. */ object ErrorStateDefaults { + /** Danger-tinted offline glyph for connectivity and sync failures. */ @Composable fun OfflineIcon() { Icon( diff --git a/app/src/main/java/com/plainstudio/stackcasino/ui/components/FilterChipRow.kt b/app/src/main/java/com/plainstudio/stackcasino/ui/components/FilterChipRow.kt index db6ccd8..d6cfd7a 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/ui/components/FilterChipRow.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/ui/components/FilterChipRow.kt @@ -86,6 +86,10 @@ fun FilterChipRow( } } +/** + * One chip in a [FilterChipRow]: the [key] selected when tapped and the + * [label] shown on the chip. + */ data class FilterChip( val key: T, val label: String, diff --git a/app/src/main/java/com/plainstudio/stackcasino/ui/components/StackCard.kt b/app/src/main/java/com/plainstudio/stackcasino/ui/components/StackCard.kt index 475e2fe..7030fb6 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/ui/components/StackCard.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/ui/components/StackCard.kt @@ -77,6 +77,7 @@ fun StackCard( } } +/** Default content padding and left-accent width for [StackCard]. */ object StackCardDefaults { val contentPadding: PaddingValues = PaddingValues(16.dp) val accentWidth = 3.dp diff --git a/app/src/main/java/com/plainstudio/stackcasino/ui/theme/Theme.kt b/app/src/main/java/com/plainstudio/stackcasino/ui/theme/Theme.kt index 49502ac..6d07762 100644 --- a/app/src/main/java/com/plainstudio/stackcasino/ui/theme/Theme.kt +++ b/app/src/main/java/com/plainstudio/stackcasino/ui/theme/Theme.kt @@ -31,6 +31,11 @@ internal val DarkColorScheme = onError = Color.White, ) +/** + * App theme wrapper. Applies the dark-only [DarkColorScheme] and the + * brand [Typography] to [content]. Wrap every screen (and preview) in + * this so Material 3 resolves the correct colors and type scale. + */ @Composable fun StackcasinoTheme(content: @Composable () -> Unit) { MaterialTheme(