Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
This commit is contained in:
parent
43727534e6
commit
3be7fc5884
@ -394,6 +394,7 @@ final class GameState: CasinoGameState {
|
||||
self.engine = BaccaratEngine(deckCount: settings.deckCount.rawValue)
|
||||
self.balance = settings.startingBalance
|
||||
self.onboarding = OnboardingState(gameIdentifier: "baccarat")
|
||||
self.onboarding.registerHintKeys("bettingZone", "dealButton", "firstResult")
|
||||
self.persistence = CloudSyncManager<BaccaratGameData>()
|
||||
|
||||
// Sync sound settings with SoundManager
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -159,21 +159,17 @@ struct GameTableView: View {
|
||||
description: String(localized: "Change table limits and display options")
|
||||
)
|
||||
],
|
||||
onStartTutorial: {
|
||||
showWelcome = false
|
||||
state.onboarding.completeWelcome()
|
||||
checkOnboardingHints()
|
||||
},
|
||||
onStartPlaying: {
|
||||
// Mark all hints as shown FIRST so they don't appear
|
||||
state.onboarding.markHintShown("bettingZone")
|
||||
state.onboarding.markHintShown("dealButton")
|
||||
state.onboarding.markHintShown("firstResult")
|
||||
state.onboarding.completeWelcome()
|
||||
showWelcome = false
|
||||
}
|
||||
onboarding: state.onboarding,
|
||||
onDismiss: { showWelcome = false },
|
||||
onShowHints: checkOnboardingHints
|
||||
)
|
||||
}
|
||||
.onChange(of: showWelcome) { wasShowing, isShowing in
|
||||
// Handle swipe-down dismissal: treat as "Start Playing" (no tooltips)
|
||||
if wasShowing && !isShowing && !state.onboarding.hasCompletedWelcome {
|
||||
state.onboarding.skipOnboarding()
|
||||
}
|
||||
}
|
||||
.onChange(of: state.totalBetAmount) { _, newTotal in
|
||||
if newTotal > 0, state.onboarding.shouldShowHint("dealButton") {
|
||||
showDealHintWithDelay()
|
||||
|
||||
@ -349,6 +349,7 @@ final class GameState: CasinoGameState {
|
||||
self.balance = settings.startingBalance
|
||||
self.engine = BlackjackEngine(settings: settings)
|
||||
self.onboarding = OnboardingState(gameIdentifier: "blackjack")
|
||||
self.onboarding.registerHintKeys("bettingZone", "dealButton", "playerActions")
|
||||
self.persistence = CloudSyncManager<BlackjackGameData>()
|
||||
syncSoundSettings()
|
||||
loadSavedGame()
|
||||
|
||||
@ -876,7 +876,26 @@
|
||||
},
|
||||
"ALL TIME SUMMARY" : {
|
||||
"comment" : "Title for a section in the statistics sheet that provides a summary of the user's overall performance over all time.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "ALL TIME SUMMARY"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "RESUMEN HISTÓRICO"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "RÉSUMÉ GLOBAL"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Allow doubling on split hands" : {
|
||||
"localizations" : {
|
||||
@ -1133,7 +1152,26 @@
|
||||
},
|
||||
"BALANCE" : {
|
||||
"comment" : "Title of a section in the session detail view that shows the user's starting and ending balances.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "BALANCE"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "SALDO"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "SOLDE"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Basic Strategy" : {
|
||||
"localizations" : {
|
||||
@ -1180,7 +1218,27 @@
|
||||
}
|
||||
},
|
||||
"Beat the Dealer" : {
|
||||
|
||||
"comment" : "Welcome screen feature title for game objective.",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Beat the Dealer"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Vence al Crupier"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Battez le Croupier"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Beat the dealer by getting a hand value closer to 21 without going over." : {
|
||||
"comment" : "Text for the objective of the game.",
|
||||
@ -1674,7 +1732,27 @@
|
||||
}
|
||||
},
|
||||
"Built-in hints show optimal plays based on basic strategy" : {
|
||||
|
||||
"comment" : "Welcome screen feature description for strategy hints.",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Built-in hints show optimal plays based on basic strategy"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Las sugerencias integradas muestran las jugadas óptimas basadas en estrategia básica"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Les conseils intégrés montrent les jeux optimaux basés sur la stratégie de base"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"BUST" : {
|
||||
"localizations" : {
|
||||
@ -1876,7 +1954,26 @@
|
||||
},
|
||||
"CHIPS STATS" : {
|
||||
"comment" : "Title of a section in the Statistics Sheet that shows statistics related to the user's chips.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "CHIPS STATS"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "ESTADÍSTICAS DE FICHAS"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "STATISTIQUES DES JETONS"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Chips, cards, and results" : {
|
||||
"localizations" : {
|
||||
@ -2222,7 +2319,27 @@
|
||||
}
|
||||
},
|
||||
"Customize Rules" : {
|
||||
|
||||
"comment" : "Welcome screen feature title for customizing game rules.",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Customize Rules"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Personaliza las Reglas"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Personnalisez les Règles"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"DATA" : {
|
||||
"localizations" : {
|
||||
@ -2638,7 +2755,26 @@
|
||||
},
|
||||
"Delete" : {
|
||||
"comment" : "A button label that deletes a session.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Delete"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Eliminar"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Supprimer"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Delete Session?" : {
|
||||
|
||||
@ -3048,7 +3184,26 @@
|
||||
},
|
||||
"Doubles" : {
|
||||
"comment" : "Label for a stat item in the statistics UI that shows the number of times a hand was doubled down.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Doubles"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Doblados"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Doublés"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Enable 'Card Count' in Settings to practice." : {
|
||||
"localizations" : {
|
||||
@ -3118,11 +3273,49 @@
|
||||
},
|
||||
"End Session" : {
|
||||
"comment" : "The text for a button that ends the current game session.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "End Session"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Terminar Sesión"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Terminer la Session"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"End Session?" : {
|
||||
"comment" : "A confirmation dialog title that asks if the user wants to end their current session.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "End Session?"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "¿Terminar Sesión?"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Terminer la Session?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"European" : {
|
||||
"localizations" : {
|
||||
@ -3326,7 +3519,26 @@
|
||||
},
|
||||
"GAME STATS" : {
|
||||
"comment" : "Title for a section in the statistics sheet dedicated to blackjack-specific statistics.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "GAME STATS"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "ESTADÍSTICAS DEL JUEGO"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "STATISTIQUES DE JEU"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"GAME STYLE" : {
|
||||
"localizations" : {
|
||||
@ -3447,7 +3659,27 @@
|
||||
}
|
||||
},
|
||||
"Get closer to 21 than the dealer without going over" : {
|
||||
|
||||
"comment" : "Welcome screen feature description for game objective.",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Get closer to 21 than the dealer without going over"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Acércate más a 21 que el crupier sin pasarte"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Approchez-vous de 21 plus que le croupier sans dépasser"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"H17 rule, increases house edge" : {
|
||||
"localizations" : {
|
||||
@ -3495,11 +3727,49 @@
|
||||
},
|
||||
"Hands" : {
|
||||
"comment" : "Label for the number of blackjack hands played in a session.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Hands"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Manos"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Mains"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Hands played" : {
|
||||
"comment" : "A label describing the number of hands a player has played in a game.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Hands played"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Manos jugadas"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Mains jouées"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Haptic Feedback" : {
|
||||
"localizations" : {
|
||||
@ -3894,7 +4164,26 @@
|
||||
},
|
||||
"IN GAME STATS" : {
|
||||
"comment" : "Title of a section in the Statistics Sheet that shows in-game statistics.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "IN GAME STATS"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "ESTADÍSTICAS EN JUEGO"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "STATISTIQUES EN JEU"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Increase bets when the count is positive." : {
|
||||
"localizations" : {
|
||||
@ -4167,7 +4456,27 @@
|
||||
}
|
||||
},
|
||||
"Learn Strategy" : {
|
||||
|
||||
"comment" : "Welcome screen feature title for strategy hints.",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Learn Strategy"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Aprende Estrategia"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Apprenez la Stratégie"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"LEGAL" : {
|
||||
"localizations" : {
|
||||
@ -4238,7 +4547,26 @@
|
||||
},
|
||||
"Lost" : {
|
||||
"comment" : "Label for a game outcome circle indicating a loss.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Lost"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Perdido"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Perdu"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Lower house edge" : {
|
||||
"comment" : "Description of a deck count option when the user selects 2 decks.",
|
||||
@ -5088,7 +5416,26 @@
|
||||
},
|
||||
"PLAYER" : {
|
||||
"comment" : "Title to display for a player hand when the hand number is not available.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "PLAYER"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "JUGADOR"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "JOUEUR"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Player hand: %@. Value: %@" : {
|
||||
"comment" : "A user-readable string describing a player's blackjack hand, including the card values and any relevant game results. The argument is a comma-separated list of the card descriptions in the player's hand.",
|
||||
@ -5206,7 +5553,26 @@
|
||||
},
|
||||
"Push" : {
|
||||
"comment" : "Label for the \"Push\" outcome in the game stats section of the statistics sheet.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Push"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Empate"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Égalité"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"PUSH" : {
|
||||
"localizations" : {
|
||||
@ -5619,14 +5985,72 @@
|
||||
},
|
||||
"See detailed stats for each play session, just like at a real casino" : {
|
||||
"comment" : "Description of a feature in the welcome sheet that allows users to track their gaming sessions.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "See detailed stats for each play session, just like at a real casino"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Ve estadísticas detalladas de cada sesión de juego, como en un casino real"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Consultez les statistiques détaillées de chaque session de jeu, comme dans un vrai casino"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Select a chip and tap the bet area" : {
|
||||
|
||||
"comment" : "Onboarding hint for placing bets.",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Select a chip and tap the bet area"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Selecciona una ficha y toca el área de apuesta"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Sélectionnez un jeton et touchez la zone de mise"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"SESSION PERFORMANCE" : {
|
||||
"comment" : "Title of a section in the statistics sheet that shows performance metrics for individual sessions.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "SESSION PERFORMANCE"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "RENDIMIENTO DE SESIÓN"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "PERFORMANCE DE SESSION"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"SESSION SUMMARY" : {
|
||||
"extractionState" : "stale",
|
||||
@ -5653,7 +6077,26 @@
|
||||
},
|
||||
"Sessions" : {
|
||||
"comment" : "Label for the number of blackjack game sessions.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Sessions"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Sesiones"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Sessions"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Settings" : {
|
||||
"localizations" : {
|
||||
@ -5817,7 +6260,26 @@
|
||||
},
|
||||
"Show Hint" : {
|
||||
"comment" : "Label for a toolbar button that shows a hint.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Show Hint"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Mostrar Sugerencia"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Afficher le Conseil"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Show Hints" : {
|
||||
"localizations" : {
|
||||
@ -6139,7 +6601,26 @@
|
||||
},
|
||||
"Splits" : {
|
||||
"comment" : "Label for the number of split hands in the statistics UI.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Splits"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Divisiones"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Séparations"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Stand" : {
|
||||
"localizations" : {
|
||||
@ -6806,11 +7287,49 @@
|
||||
},
|
||||
"Time" : {
|
||||
"comment" : "Label for the duration of a blackjack game.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Time"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Tiempo"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Temps"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Total game time" : {
|
||||
"comment" : "Label for a stat row displaying the total game time.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Total game time"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Tiempo total de juego"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Temps de jeu total"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Total Winnings" : {
|
||||
"localizations" : {
|
||||
@ -6836,7 +7355,26 @@
|
||||
},
|
||||
"Track Sessions" : {
|
||||
"comment" : "Feature description in the welcome sheet for tracking detailed stats for each play session.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Track Sessions"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Seguimiento de Sesiones"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Suivez vos Sessions"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Traditional European casino style." : {
|
||||
"localizations" : {
|
||||
@ -6998,7 +7536,26 @@
|
||||
},
|
||||
"Vegas Strip, Atlantic City, European, or create your own" : {
|
||||
"comment" : "Feature description in the welcome sheet about customizing the game rules.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Vegas Strip, Atlantic City, European, or create your own"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Vegas Strip, Atlantic City, Europeo o crea el tuyo"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Vegas Strip, Atlantic City, Européen ou créez le vôtre"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Vibration on actions" : {
|
||||
"localizations" : {
|
||||
@ -7115,7 +7672,26 @@
|
||||
},
|
||||
"Won" : {
|
||||
"comment" : "Label for a game outcome circle that indicates a win.",
|
||||
"isCommentAutoGenerated" : true
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Won"
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Ganado"
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Gagné"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Worst" : {
|
||||
"extractionState" : "stale",
|
||||
@ -7164,13 +7740,24 @@
|
||||
},
|
||||
"You played %lld hands with a net result of %@. This session will be saved to your history." : {
|
||||
"comment" : "A message that appears when a user ends a game session. It includes the number of hands played and the net result of the session.",
|
||||
"isCommentAutoGenerated" : true,
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"state" : "translated",
|
||||
"value" : "You played %1$lld hands with a net result of %2$@. This session will be saved to your history."
|
||||
}
|
||||
},
|
||||
"es-MX" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Jugaste %1$lld manos con un resultado neto de %2$@. Esta sesión se guardará en tu historial."
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Vous avez joué %1$lld mains avec un résultat net de %2$@. Cette session sera sauvegardée dans votre historique."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -109,21 +109,17 @@ struct GameTableView: View {
|
||||
description: String(localized: "Vegas Strip, Atlantic City, European, or create your own")
|
||||
)
|
||||
],
|
||||
onStartTutorial: {
|
||||
showWelcome = false
|
||||
state.onboarding.completeWelcome()
|
||||
checkOnboardingHints()
|
||||
},
|
||||
onStartPlaying: {
|
||||
// Mark all hints as shown FIRST so they don't appear
|
||||
state.onboarding.markHintShown("bettingZone")
|
||||
state.onboarding.markHintShown("dealButton")
|
||||
state.onboarding.markHintShown("playerActions")
|
||||
state.onboarding.completeWelcome()
|
||||
showWelcome = false
|
||||
}
|
||||
onboarding: state.onboarding,
|
||||
onDismiss: { showWelcome = false },
|
||||
onShowHints: checkOnboardingHints
|
||||
)
|
||||
}
|
||||
.onChange(of: showWelcome) { wasShowing, isShowing in
|
||||
// Handle swipe-down dismissal: treat as "Start Playing" (no tooltips)
|
||||
if wasShowing && !isShowing && !state.onboarding.hasCompletedWelcome {
|
||||
state.onboarding.skipOnboarding()
|
||||
}
|
||||
}
|
||||
.onChange(of: state.currentBet) { _, newBet in
|
||||
if newBet > 0, state.onboarding.shouldShowHint("dealButton") {
|
||||
showDealHintWithDelay()
|
||||
|
||||
@ -26,6 +26,10 @@ public final class OnboardingState {
|
||||
/// Set of hint keys that have been shown to the user.
|
||||
public var hintsShown: Set<String> = []
|
||||
|
||||
/// Hint keys registered by the app for automatic skipping.
|
||||
/// When the user skips onboarding, all registered hints are marked as shown.
|
||||
private var registeredHintKeys: Set<String> = []
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
private let persistenceKey: String
|
||||
@ -35,6 +39,18 @@ public final class OnboardingState {
|
||||
load()
|
||||
}
|
||||
|
||||
/// Registers hint keys that should be marked as shown when skipping onboarding.
|
||||
/// Call this once during app setup with all hint keys used by the game.
|
||||
public func registerHintKeys(_ keys: Set<String>) {
|
||||
registeredHintKeys = keys
|
||||
}
|
||||
|
||||
/// Registers hint keys that should be marked as shown when skipping onboarding.
|
||||
/// Call this once during app setup with all hint keys used by the game.
|
||||
public func registerHintKeys(_ keys: String...) {
|
||||
registeredHintKeys = Set(keys)
|
||||
}
|
||||
|
||||
// MARK: - Hint Management
|
||||
|
||||
/// Marks a hint as shown and persists the state.
|
||||
@ -55,6 +71,18 @@ public final class OnboardingState {
|
||||
save()
|
||||
}
|
||||
|
||||
/// Skips onboarding entirely - marks all registered hints as shown and completes welcome.
|
||||
/// Use this when the user dismisses the welcome sheet without choosing tutorial mode
|
||||
/// (e.g., swiping down to dismiss, or tapping "Start Playing").
|
||||
public func skipOnboarding() {
|
||||
for key in registeredHintKeys {
|
||||
hintsShown.insert(key)
|
||||
}
|
||||
hasLaunchedBefore = true
|
||||
hasCompletedWelcome = true
|
||||
save()
|
||||
}
|
||||
|
||||
/// Enables tutorial mode (shows all hints again).
|
||||
public func startTutorialMode() {
|
||||
isTutorialMode = true
|
||||
|
||||
@ -21,6 +21,42 @@ public struct WelcomeSheet: View {
|
||||
@ScaledMetric(relativeTo: .body) private var iconSize: CGFloat = CasinoDesign.IconSize.large
|
||||
@ScaledMetric(relativeTo: .body) private var buttonPadding: CGFloat = CasinoDesign.Spacing.medium
|
||||
|
||||
/// Creates a welcome sheet with automatic onboarding state management.
|
||||
///
|
||||
/// This initializer handles the common pattern of:
|
||||
/// - "Show Me How" → completes welcome and triggers hint display
|
||||
/// - "Start Playing" → skips all hints and completes welcome
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - gameName: The name of the game to display
|
||||
/// - gameEmoji: An emoji representing the game
|
||||
/// - features: List of features to highlight
|
||||
/// - onboarding: The onboarding state to manage (must have hint keys registered)
|
||||
/// - onDismiss: Called after the sheet is dismissed
|
||||
/// - onShowHints: Called when user chooses "Show Me How" - use this to trigger tooltip display
|
||||
public init(
|
||||
gameName: String,
|
||||
gameEmoji: String = "🎰",
|
||||
features: [WelcomeFeature],
|
||||
onboarding: OnboardingState,
|
||||
onDismiss: @escaping () -> Void,
|
||||
onShowHints: @escaping () -> Void
|
||||
) {
|
||||
self.gameName = gameName
|
||||
self.gameEmoji = gameEmoji
|
||||
self.features = features
|
||||
self.onStartTutorial = {
|
||||
onboarding.completeWelcome()
|
||||
onDismiss()
|
||||
onShowHints()
|
||||
}
|
||||
self.onStartPlaying = {
|
||||
onboarding.skipOnboarding()
|
||||
onDismiss()
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a welcome sheet with custom callbacks for full control.
|
||||
public init(
|
||||
gameName: String,
|
||||
gameEmoji: String = "🎰",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user