Compare commits
5 Commits
f1028bd626
...
ace6303a62
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ace6303a62 | ||
|
|
34455378fc | ||
|
|
8cbd85dcce | ||
|
|
8e82c8ab2b | ||
|
|
6b17039918 |
@ -71,6 +71,28 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"%@: %@": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "%1$@: %2$@"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "%1$@: %2$@"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "%1$@ : %2$@"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"%lld": {
|
"%lld": {
|
||||||
"comment": "A label displaying the amount wagered in the current hand. The argument is the amount wagered in the current hand.",
|
"comment": "A label displaying the amount wagered in the current hand. The argument is the amount wagered in the current hand.",
|
||||||
"isCommentAutoGenerated": true,
|
"isCommentAutoGenerated": true,
|
||||||
@ -668,7 +690,26 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"21+3: Poker hand from your cards + dealer's upcard.": {
|
"21+3: Poker hand from your cards + dealer's upcard.": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "21+3: Poker hand from your cards + dealer's upcard."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "21+3: Mano de póquer con tus cartas + carta visible del crupier."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "21+3 : Main de poker avec vos cartes + carte visible du croupier."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"A 'soft' hand has an Ace counting as 11.": {
|
"A 'soft' hand has an Ace counting as 11.": {
|
||||||
"comment": "Explanation of how an Ace can be counted as either 1 or 11 in a hand.",
|
"comment": "Explanation of how an Ace can be counted as either 1 or 11 in a hand.",
|
||||||
@ -719,7 +760,26 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Aces can be high or low in straights (A-2-3 or Q-K-A).": {
|
"Aces can be high or low in straights (A-2-3 or Q-K-A).": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Aces can be high or low in straights (A-2-3 or Q-K-A)."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Los ases pueden ser altos o bajos en escaleras (A-2-3 o Q-K-A)."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Les as peuvent être hauts ou bas dans les suites (A-2-3 ou Q-K-A)."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Actions": {
|
"Actions": {
|
||||||
"localizations": {
|
"localizations": {
|
||||||
@ -1327,10 +1387,49 @@
|
|||||||
},
|
},
|
||||||
"Bet on your first two cards forming a pair": {
|
"Bet on your first two cards forming a pair": {
|
||||||
"comment": "Description of the Perfect Pairs side bet.",
|
"comment": "Description of the Perfect Pairs side bet.",
|
||||||
"isCommentAutoGenerated" : true
|
"isCommentAutoGenerated": true,
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Bet on your first two cards forming a pair"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Apuesta a que tus primeras dos cartas formen un par"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Pariez sur vos deux premières cartes formant une paire"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Bet on your first two cards forming a pair.": {
|
"Bet on your first two cards forming a pair.": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Bet on your first two cards forming a pair."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Apuesta a que tus primeras dos cartas formen un par."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Pariez sur vos deux premières cartes formant une paire."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Betting Hint": {
|
"Betting Hint": {
|
||||||
"comment": "A label describing the view that shows betting recommendations.",
|
"comment": "A label describing the view that shows betting recommendations.",
|
||||||
@ -1869,7 +1968,26 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Colored Pair (same color): 12:1": {
|
"Colored Pair (same color): 12:1": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Colored Pair (same color): 12:1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Par de color (mismo color): 12:1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Paire de couleur (même couleur) : 12:1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Common shoe game": {
|
"Common shoe game": {
|
||||||
"comment": "Description of a deck count option when the user selects 4 decks.",
|
"comment": "Description of a deck count option when the user selects 4 decks.",
|
||||||
@ -1989,7 +2107,27 @@
|
|||||||
},
|
},
|
||||||
"Current bet $%lld": {
|
"Current bet $%lld": {
|
||||||
"comment": "A hint that appears when a user taps on a side bet zone. The text varies depending on whether a bet is currently placed or not.",
|
"comment": "A hint that appears when a user taps on a side bet zone. The text varies depending on whether a bet is currently placed or not.",
|
||||||
"isCommentAutoGenerated" : true
|
"isCommentAutoGenerated": true,
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Current bet $%lld"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Apuesta actual $%lld"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Pari actuel %lld $"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Custom": {
|
"Custom": {
|
||||||
"localizations": {
|
"localizations": {
|
||||||
@ -2335,7 +2473,7 @@
|
|||||||
"localizations": {
|
"localizations": {
|
||||||
"en": {
|
"en": {
|
||||||
"stringUnit": {
|
"stringUnit": {
|
||||||
"state" : "new",
|
"state": "translated",
|
||||||
"value": "Dealer: %1$@. Value: %2$@"
|
"value": "Dealer: %1$@. Value: %2$@"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2779,7 +2917,50 @@
|
|||||||
},
|
},
|
||||||
"Double tap to place bet": {
|
"Double tap to place bet": {
|
||||||
"comment": "A hint text that describes the action to take to place a side bet.",
|
"comment": "A hint text that describes the action to take to place a side bet.",
|
||||||
"isCommentAutoGenerated" : true
|
"isCommentAutoGenerated": true,
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Double tap to place bet"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Toca dos veces para apostar"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Touchez deux fois pour parier"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Double, not Hit (TC %@)": {
|
||||||
|
"comment": "Short hint to double instead of hit based on true count.",
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Double, not Hit (TC %@)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Doblar, no Pedir (TC %@)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Doubler, pas Tirer (TC %@)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Enable 'Card Count' in Settings to practice.": {
|
"Enable 'Card Count' in Settings to practice.": {
|
||||||
"localizations": {
|
"localizations": {
|
||||||
@ -2804,7 +2985,26 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Enable in Settings to play side bets.": {
|
"Enable in Settings to play side bets.": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Enable in Settings to play side bets."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Habilita en Configuración para jugar apuestas laterales."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Activez dans les réglages pour jouer les paris latéraux."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Enable Side Bets": {
|
"Enable Side Bets": {
|
||||||
"localizations": {
|
"localizations": {
|
||||||
@ -2851,13 +3051,70 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Example: K♠ K♠ = Perfect Pair": {
|
"Example: K♠ K♠ = Perfect Pair": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Example: K♠ K♠ = Perfect Pair"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Ejemplo: K♠ K♠ = Par perfecto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Exemple : K♠ K♠ = Paire parfaite"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Example: K♠ K♣ = Colored Pair (both black)": {
|
"Example: K♠ K♣ = Colored Pair (both black)": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Example: K♠ K♣ = Colored Pair (both black)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Ejemplo: K♠ K♣ = Par de color (ambos negros)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Exemple : K♠ K♣ = Paire de couleur (tous deux noirs)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Example: K♠ K♥ = Mixed Pair (red/black)": {
|
"Example: K♠ K♥ = Mixed Pair (red/black)": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Example: K♠ K♥ = Mixed Pair (red/black)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Ejemplo: K♠ K♥ = Par mixto (rojo/negro)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Exemple : K♠ K♥ = Paire mixte (rouge/noir)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Fewer decks = easier to count accurately.": {
|
"Fewer decks = easier to count accurately.": {
|
||||||
"localizations": {
|
"localizations": {
|
||||||
@ -2928,10 +3185,48 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Flush (same suit): 5:1": {
|
"Flush (same suit): 5:1": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Flush (same suit): 5:1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Color (mismo palo): 5:1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Couleur (même couleur) : 5:1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Forms a poker hand: your 2 cards + dealer upcard.": {
|
"Forms a poker hand: your 2 cards + dealer upcard.": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Forms a poker hand: your 2 cards + dealer upcard."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Forma una mano de póquer: tus 2 cartas + carta visible del crupier."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Forme une main de poker : vos 2 cartes + carte visible du croupier."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"GAME STYLE": {
|
"GAME STYLE": {
|
||||||
"localizations": {
|
"localizations": {
|
||||||
@ -3251,6 +3546,29 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Hit, not Stand (TC %@)": {
|
||||||
|
"comment": "Short hint to hit instead of stand based on true count.",
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Hit, not Stand (TC %@)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Pedir, no Plantarse (TC %@)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Tirer, pas Rester (TC %@)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"Hit: Take another card": {
|
"Hit: Take another card": {
|
||||||
"comment": "Action available in Blackjack: Hit (take another card).",
|
"comment": "Action available in Blackjack: Hit (take another card).",
|
||||||
"isCommentAutoGenerated": true,
|
"isCommentAutoGenerated": true,
|
||||||
@ -4008,7 +4326,26 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Mixed Pair (diff. color): 6:1": {
|
"Mixed Pair (diff. color): 6:1": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Mixed Pair (diff. color): 6:1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Par mixto (diferente color): 6:1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Paire mixte (couleur différente) : 6:1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"More decks = harder to count cards.": {
|
"More decks = harder to count cards.": {
|
||||||
"localizations": {
|
"localizations": {
|
||||||
@ -4372,7 +4709,26 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Optional bets placed before the deal.": {
|
"Optional bets placed before the deal.": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Optional bets placed before the deal."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Apuestas opcionales colocadas antes del reparto."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Paris optionnels placés avant la distribution."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Other Game Icons": {
|
"Other Game Icons": {
|
||||||
"comment": "A label displayed above a section of the BrandingPreviewView that shows icons for other games.",
|
"comment": "A label displayed above a section of the BrandingPreviewView that shows icons for other games.",
|
||||||
@ -4515,7 +4871,26 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Perfect Pair (same suit): 25:1": {
|
"Perfect Pair (same suit): 25:1": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Perfect Pair (same suit): 25:1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Par perfecto (mismo palo): 25:1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Paire parfaite (même couleur) : 25:1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Perfect Pairs": {
|
"Perfect Pairs": {
|
||||||
"comment": "Name of the Perfect Pairs side bet type.",
|
"comment": "Name of the Perfect Pairs side bet type.",
|
||||||
@ -4542,10 +4917,48 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Perfect Pairs (25:1) and 21+3 (100:1)": {
|
"Perfect Pairs (25:1) and 21+3 (100:1)": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Perfect Pairs (25:1) and 21+3 (100:1)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Pares perfectos (25:1) y 21+3 (100:1)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Paires parfaites (25:1) et 21+3 (100:1)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Perfect Pairs: Bet on your first two cards being a pair.": {
|
"Perfect Pairs: Bet on your first two cards being a pair.": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Perfect Pairs: Bet on your first two cards being a pair."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Pares perfectos: Apuesta a que tus primeras dos cartas sean un par."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Paires parfaites : Pariez sur vos deux premières cartes formant une paire."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Play Again": {
|
"Play Again": {
|
||||||
"localizations": {
|
"localizations": {
|
||||||
@ -4575,7 +4988,7 @@
|
|||||||
"localizations": {
|
"localizations": {
|
||||||
"en": {
|
"en": {
|
||||||
"stringUnit": {
|
"stringUnit": {
|
||||||
"state" : "new",
|
"state": "translated",
|
||||||
"value": "Player hand: %1$@. Value: %2$@"
|
"value": "Player hand: %1$@. Value: %2$@"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -4617,7 +5030,27 @@
|
|||||||
},
|
},
|
||||||
"Poker hand from your first two cards + dealer's upcard": {
|
"Poker hand from your first two cards + dealer's upcard": {
|
||||||
"comment": "Description of the 21+3 side bet type.",
|
"comment": "Description of the 21+3 side bet type.",
|
||||||
"isCommentAutoGenerated" : true
|
"isCommentAutoGenerated": true,
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Poker hand from your first two cards + dealer's upcard"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Mano de póquer con tus primeras dos cartas + carta visible del crupier"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Main de poker avec vos deux premières cartes + carte visible du croupier"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Positive count = more high cards remain = player advantage.": {
|
"Positive count = more high cards remain = player advantage.": {
|
||||||
"localizations": {
|
"localizations": {
|
||||||
@ -5250,10 +5683,48 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"SIDE BETS": {
|
"SIDE BETS": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "SIDE BETS"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "APUESTAS LATERALES"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "PARIS LATÉRAUX"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Side bets have higher house edge than main game.": {
|
"Side bets have higher house edge than main game.": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Side bets have higher house edge than main game."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Las apuestas laterales tienen mayor ventaja de la casa que el juego principal."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Les paris latéraux ont un avantage de la maison plus élevé que le jeu principal."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Sign in to iCloud to sync progress": {
|
"Sign in to iCloud to sync progress": {
|
||||||
"localizations": {
|
"localizations": {
|
||||||
@ -5391,6 +5862,28 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Split up to 4 hands, but not aces.": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Split up to 4 hands, but not aces."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Divide hasta 4 manos, pero no ases."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Séparez jusqu'à 4 mains, mais pas les as."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"Split, not Stand (TC %@)": {
|
"Split, not Stand (TC %@)": {
|
||||||
"comment": "Short hint to split instead of stand based on true count.",
|
"comment": "Short hint to split instead of stand based on true count.",
|
||||||
"localizations": {
|
"localizations": {
|
||||||
@ -5414,121 +5907,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Stand, not Hit (TC %@)" : {
|
|
||||||
"comment" : "Short hint to stand instead of hit based on true count.",
|
|
||||||
"localizations" : {
|
|
||||||
"en" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Stand, not Hit (TC %@)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"es-MX" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Plantarse, no Pedir (TC %@)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fr-CA" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Rester, pas Tirer (TC %@)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Hit, not Stand (TC %@)" : {
|
|
||||||
"comment" : "Short hint to hit instead of stand based on true count.",
|
|
||||||
"localizations" : {
|
|
||||||
"en" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Hit, not Stand (TC %@)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"es-MX" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Pedir, no Plantarse (TC %@)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fr-CA" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Tirer, pas Rester (TC %@)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Double, not Hit (TC %@)" : {
|
|
||||||
"comment" : "Short hint to double instead of hit based on true count.",
|
|
||||||
"localizations" : {
|
|
||||||
"en" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Double, not Hit (TC %@)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"es-MX" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Doblar, no Pedir (TC %@)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fr-CA" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Doubler, pas Tirer (TC %@)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Split instead of Stand (TC %@, dealer very likely to bust)" : {
|
|
||||||
"comment" : "A hint to split a pair of 10s when the true count is high enough.",
|
|
||||||
"isCommentAutoGenerated" : true,
|
|
||||||
"localizations" : {
|
|
||||||
"en" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Split instead of Stand (TC %@, dealer very likely to bust)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"es-MX" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Dividir en vez de Plantarse (TC %@, el crupier probablemente se pase)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fr-CA" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Séparer au lieu de Rester (TC %@, le croupier va probablement sauter)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Split up to 4 hands, but not aces." : {
|
|
||||||
"localizations" : {
|
|
||||||
"en" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Split up to 4 hands, but not aces."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"es-MX" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Divide hasta 4 manos, pero no ases."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fr-CA" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Séparez jusqu'à 4 mains, mais pas les as."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Split: If you have two cards of the same value, split into two hands": {
|
"Split: If you have two cards of the same value, split into two hands": {
|
||||||
"comment": "Description of the 'Split' action in the game rules.",
|
"comment": "Description of the 'Split' action in the game rules.",
|
||||||
"isCommentAutoGenerated": true,
|
"isCommentAutoGenerated": true,
|
||||||
@ -5597,6 +5975,29 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Stand, not Hit (TC %@)": {
|
||||||
|
"comment": "Short hint to stand instead of hit based on true count.",
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Stand, not Hit (TC %@)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Plantarse, no Pedir (TC %@)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Rester, pas Tirer (TC %@)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"Stand: Keep your current hand": {
|
"Stand: Keep your current hand": {
|
||||||
"comment": "Action to keep your current hand in Blackjack.",
|
"comment": "Action to keep your current hand in Blackjack.",
|
||||||
"isCommentAutoGenerated": true,
|
"isCommentAutoGenerated": true,
|
||||||
@ -5736,7 +6137,26 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Straight (consecutive): 10:1": {
|
"Straight (consecutive): 10:1": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Straight (consecutive): 10:1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Escalera (consecutivas): 10:1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Suite (consécutives) : 10:1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Straight Flush": {
|
"Straight Flush": {
|
||||||
"comment": "Description of a 21+3 side bet outcome when the player has a straight flush.",
|
"comment": "Description of a 21+3 side bet outcome when the player has a straight flush.",
|
||||||
@ -5763,7 +6183,26 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Straight Flush: 40:1": {
|
"Straight Flush: 40:1": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Straight Flush: 40:1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Escalera de color: 40:1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Quinte flush : 40:1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Suited Trips": {
|
"Suited Trips": {
|
||||||
"comment": "Name of a 21+3 side bet outcome when the user has three cards of the same rank and suit.",
|
"comment": "Name of a 21+3 side bet outcome when the user has three cards of the same rank and suit.",
|
||||||
@ -5790,7 +6229,26 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Suited Trips (same rank & suit): 100:1": {
|
"Suited Trips (same rank & suit): 100:1": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Suited Trips (same rank & suit): 100:1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Trío del mismo palo (mismo rango y palo): 100:1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Brelan assorti (même rang et couleur) : 100:1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Surrender": {
|
"Surrender": {
|
||||||
"localizations": {
|
"localizations": {
|
||||||
@ -6109,7 +6567,26 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Three of a Kind: 30:1": {
|
"Three of a Kind: 30:1": {
|
||||||
|
"localizations": {
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Three of a Kind: 30:1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es-MX": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Trío: 30:1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr-CA": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Brelan : 30:1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Total Winnings": {
|
"Total Winnings": {
|
||||||
"localizations": {
|
"localizations": {
|
||||||
|
|||||||
@ -19,6 +19,16 @@ enum Design {
|
|||||||
/// Set to true to show layout debug borders on views
|
/// Set to true to show layout debug borders on views
|
||||||
static let showDebugBorders = false
|
static let showDebugBorders = false
|
||||||
|
|
||||||
|
/// Set to true to show debug log statements
|
||||||
|
static let showDebugLogs = false
|
||||||
|
|
||||||
|
/// Debug logger - only prints when showDebugLogs is true
|
||||||
|
static func debugLog(_ message: String) {
|
||||||
|
if showDebugLogs {
|
||||||
|
print(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Shared Constants (from CasinoKit)
|
// MARK: - Shared Constants (from CasinoKit)
|
||||||
|
|
||||||
typealias Spacing = CasinoDesign.Spacing
|
typealias Spacing = CasinoDesign.Spacing
|
||||||
@ -71,6 +81,33 @@ enum Design {
|
|||||||
|
|
||||||
// Table
|
// Table
|
||||||
static let tableHeight: CGFloat = 280
|
static let tableHeight: CGFloat = 280
|
||||||
|
|
||||||
|
// Result banner
|
||||||
|
static let resultRowAmountWidth: CGFloat = 70
|
||||||
|
static let resultRowResultWidth: CGFloat = 150
|
||||||
|
|
||||||
|
// Side bet zones
|
||||||
|
static let sideBetLabelFontSize: CGFloat = 13
|
||||||
|
static let sideBetPayoutFontSize: CGFloat = 11
|
||||||
|
|
||||||
|
// Side bet toast notifications
|
||||||
|
static let sideBetToastTitleFontSize: CGFloat = 11
|
||||||
|
static let sideBetToastResultFontSize: CGFloat = 12
|
||||||
|
static let sideBetToastAmountFontSize: CGFloat = 14
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Blackjack-Specific Delays
|
||||||
|
|
||||||
|
enum Delay {
|
||||||
|
/// Delay before playing game over sound
|
||||||
|
static let gameOverSound: Double = 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Blackjack-Specific Animation
|
||||||
|
|
||||||
|
enum AnimationExtra {
|
||||||
|
/// Bounce for side bet toast animations
|
||||||
|
static let toastBounce: Double = 0.4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -35,10 +35,8 @@ struct ActionButtonsView: View {
|
|||||||
EmptyView()
|
EmptyView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.animation(.spring(duration: Design.Animation.quick), value: state.currentPhase)
|
|
||||||
.animation(.easeInOut(duration: Design.Animation.standard), value: state.currentBet > 0)
|
|
||||||
}
|
}
|
||||||
.frame(minHeight: containerHeight)
|
.frame(height: containerHeight)
|
||||||
.padding(.horizontal, Design.Spacing.large)
|
.padding(.horizontal, Design.Spacing.large)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -130,20 +130,22 @@ struct GameTableView: View {
|
|||||||
)
|
)
|
||||||
.frame(maxWidth: maxContentWidth)
|
.frame(maxWidth: maxContentWidth)
|
||||||
|
|
||||||
// Chip selector - only shown during betting phase
|
// Chip selector - only shown during betting phase AND when result banner is NOT showing
|
||||||
if state.currentPhase == .betting {
|
if state.currentPhase == .betting && !state.showResultBanner {
|
||||||
Spacer()
|
|
||||||
.debugBorder(showDebugBorders, color: .yellow, label: "ChipSpacer")
|
|
||||||
|
|
||||||
ChipSelectorView(
|
ChipSelectorView(
|
||||||
selectedChip: $selectedChip,
|
selectedChip: $selectedChip,
|
||||||
balance: state.balance,
|
balance: state.balance,
|
||||||
currentBet: state.minBetForChipSelector, // Use min bet so chips stay enabled if any bet type can accept more
|
currentBet: state.minBetForChipSelector,
|
||||||
maxBet: state.settings.maxBet
|
maxBet: state.settings.maxBet
|
||||||
)
|
)
|
||||||
.frame(maxWidth: maxContentWidth)
|
.frame(maxWidth: maxContentWidth)
|
||||||
.transition(.opacity.combined(with: .move(edge: .bottom)))
|
|
||||||
.debugBorder(showDebugBorders, color: .pink, label: "ChipSelector")
|
.debugBorder(showDebugBorders, color: .pink, label: "ChipSelector")
|
||||||
|
.onAppear {
|
||||||
|
Design.debugLog("🎰 Chip selector APPEARED (banner showing: \(state.showResultBanner))")
|
||||||
|
}
|
||||||
|
.onDisappear {
|
||||||
|
Design.debugLog("🎰 Chip selector DISAPPEARED")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Action buttons - minimal spacing during player turn
|
// Action buttons - minimal spacing during player turn
|
||||||
@ -152,21 +154,33 @@ struct GameTableView: View {
|
|||||||
.padding(.bottom, Design.Spacing.small)
|
.padding(.bottom, Design.Spacing.small)
|
||||||
.debugBorder(showDebugBorders, color: .blue, label: "ActionBtns")
|
.debugBorder(showDebugBorders, color: .blue, label: "ActionBtns")
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity, alignment: .top)
|
||||||
|
.zIndex(1)
|
||||||
|
.onChange(of: state.currentPhase) { oldPhase, newPhase in
|
||||||
|
Design.debugLog("🔄 Phase changed: \(oldPhase) → \(newPhase)")
|
||||||
|
}
|
||||||
|
|
||||||
// Insurance popup overlay (covers entire screen)
|
// Insurance popup overlay (covers entire screen)
|
||||||
if state.currentPhase == .insurance {
|
if state.currentPhase == .insurance {
|
||||||
|
Color.clear
|
||||||
|
.overlay(alignment: .center) {
|
||||||
InsurancePopupView(
|
InsurancePopupView(
|
||||||
betAmount: state.currentBet / 2,
|
betAmount: state.currentBet / 2,
|
||||||
balance: state.balance,
|
balance: state.balance,
|
||||||
onTake: { Task { await state.takeInsurance() } },
|
onTake: { Task { await state.takeInsurance() } },
|
||||||
onDecline: { state.declineInsurance() }
|
onDecline: { state.declineInsurance() }
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
.ignoresSafeArea()
|
||||||
|
.allowsHitTesting(true)
|
||||||
.transition(.opacity.combined(with: .scale(scale: 0.9)))
|
.transition(.opacity.combined(with: .scale(scale: 0.9)))
|
||||||
|
.zIndex(100)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Result banner overlay
|
// Result banner overlay
|
||||||
if state.showResultBanner, let result = state.lastRoundResult {
|
if state.showResultBanner, let result = state.lastRoundResult {
|
||||||
|
Color.clear
|
||||||
|
.overlay(alignment: .center) {
|
||||||
ResultBannerView(
|
ResultBannerView(
|
||||||
result: result,
|
result: result,
|
||||||
currentBalance: state.balance,
|
currentBalance: state.balance,
|
||||||
@ -174,20 +188,43 @@ struct GameTableView: View {
|
|||||||
onNewRound: { state.newRound() },
|
onNewRound: { state.newRound() },
|
||||||
onPlayAgain: { state.resetGame() }
|
onPlayAgain: { state.resetGame() }
|
||||||
)
|
)
|
||||||
|
.onAppear {
|
||||||
|
Design.debugLog("🎯 RESULT BANNER APPEARED")
|
||||||
|
}
|
||||||
|
.onDisappear {
|
||||||
|
Design.debugLog("❌ RESULT BANNER DISAPPEARED")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.ignoresSafeArea()
|
||||||
|
.allowsHitTesting(true)
|
||||||
|
.zIndex(100)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Confetti for wins (matching Baccarat pattern)
|
// Confetti for wins (matching Baccarat pattern)
|
||||||
if state.showResultBanner && (state.lastRoundResult?.totalWinnings ?? 0) > 0 {
|
if state.showResultBanner && (state.lastRoundResult?.totalWinnings ?? 0) > 0 {
|
||||||
ConfettiView()
|
ConfettiView()
|
||||||
|
.zIndex(101)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Game over
|
// Game over
|
||||||
if state.isGameOver && !state.showResultBanner {
|
if state.isGameOver && !state.showResultBanner {
|
||||||
|
Color.clear
|
||||||
|
.overlay(alignment: .center) {
|
||||||
GameOverView(
|
GameOverView(
|
||||||
roundsPlayed: state.roundsPlayed,
|
roundsPlayed: state.roundsPlayed,
|
||||||
onPlayAgain: { state.resetGame() }
|
onPlayAgain: { state.resetGame() }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
.ignoresSafeArea()
|
||||||
|
.allowsHitTesting(true)
|
||||||
|
.zIndex(100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onChange(of: state.playerHands.count) { oldCount, newCount in
|
||||||
|
Design.debugLog("👥 Player hands count: \(oldCount) → \(newCount)")
|
||||||
|
}
|
||||||
|
.onChange(of: state.balance) { oldBalance, newBalance in
|
||||||
|
Design.debugLog("💰 Balance: \(oldBalance) → \(newBalance)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -54,7 +54,6 @@ struct ResultBannerView: View {
|
|||||||
ZStack {
|
ZStack {
|
||||||
// Full screen dark background
|
// Full screen dark background
|
||||||
Color.black.opacity(Design.Opacity.strong)
|
Color.black.opacity(Design.Opacity.strong)
|
||||||
.ignoresSafeArea()
|
|
||||||
|
|
||||||
// Content card
|
// Content card
|
||||||
VStack(spacing: Design.Spacing.xLarge) {
|
VStack(spacing: Design.Spacing.xLarge) {
|
||||||
@ -193,18 +192,18 @@ struct ResultBannerView: View {
|
|||||||
.shadow(color: mainResultColor.opacity(Design.Opacity.hint), radius: Design.Shadow.radiusXLarge)
|
.shadow(color: mainResultColor.opacity(Design.Opacity.hint), radius: Design.Shadow.radiusXLarge)
|
||||||
.frame(maxWidth: CasinoDesign.Size.maxModalWidth)
|
.frame(maxWidth: CasinoDesign.Size.maxModalWidth)
|
||||||
.padding(.horizontal, Design.Spacing.large) // Prevent clipping on sides
|
.padding(.horizontal, Design.Spacing.large) // Prevent clipping on sides
|
||||||
.scaleEffect(showContent ? 1.0 : 0.8)
|
.scaleEffect(showContent ? Design.Scale.normal : Design.Scale.slightShrink)
|
||||||
.opacity(showContent ? 1.0 : 0)
|
.opacity(showContent ? 1.0 : 0)
|
||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
withAnimation(.spring(duration: Design.Animation.springDuration, bounce: 0.3)) {
|
withAnimation(.spring(duration: Design.Animation.springDuration, bounce: Design.Animation.springBounce)) {
|
||||||
showContent = true
|
showContent = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Play game over sound if out of chips (after a delay so it doesn't overlap with result sound)
|
// Play game over sound if out of chips (after a delay so it doesn't overlap with result sound)
|
||||||
if isGameOver {
|
if isGameOver {
|
||||||
Task {
|
Task {
|
||||||
try? await Task.sleep(for: .seconds(1))
|
try? await Task.sleep(for: .seconds(Design.Delay.gameOverSound))
|
||||||
SoundManager.shared.play(.gameOver)
|
SoundManager.shared.play(.gameOver)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -222,6 +221,8 @@ struct ResultRow: View {
|
|||||||
let result: HandResult
|
let result: HandResult
|
||||||
var amount: Int? = nil
|
var amount: Int? = nil
|
||||||
|
|
||||||
|
private var showDebugBorders: Bool { Design.showDebugBorders }
|
||||||
|
|
||||||
private var amountText: String? {
|
private var amountText: String? {
|
||||||
guard let amount = amount else { return nil }
|
guard let amount = amount else { return nil }
|
||||||
if amount > 0 {
|
if amount > 0 {
|
||||||
@ -243,24 +244,31 @@ struct ResultRow: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
HStack {
|
HStack {
|
||||||
Text(label)
|
Text(label)
|
||||||
.font(.system(size: Design.BaseFontSize.body))
|
.font(.system(size: Design.BaseFontSize.medium))
|
||||||
.foregroundStyle(.white.opacity(Design.Opacity.strong))
|
.foregroundStyle(.white.opacity(Design.Opacity.strong))
|
||||||
|
.debugBorder(showDebugBorders, color: .blue, label: "Label")
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
.debugBorder(showDebugBorders, color: .yellow, label: "Spacer")
|
||||||
|
|
||||||
// Show amount if provided
|
// Show amount if provided
|
||||||
if let amountText = amountText {
|
if let amountText = amountText {
|
||||||
Text(amountText)
|
Text(amountText)
|
||||||
.font(.system(size: Design.BaseFontSize.body, weight: .semibold, design: .rounded))
|
.font(.system(size: Design.BaseFontSize.medium, weight: .semibold, design: .rounded))
|
||||||
.foregroundStyle(amountColor)
|
.foregroundStyle(amountColor)
|
||||||
.frame(width: 70, alignment: .trailing)
|
.frame(width: Design.Size.resultRowAmountWidth, alignment: .trailing)
|
||||||
|
.debugBorder(showDebugBorders, color: .green, label: "Amount")
|
||||||
}
|
}
|
||||||
|
|
||||||
Text(result.displayText)
|
Text(result.displayText)
|
||||||
.font(.system(size: Design.BaseFontSize.body, weight: .bold))
|
.font(.system(size: Design.BaseFontSize.large, weight: .bold))
|
||||||
.foregroundStyle(result.color)
|
.foregroundStyle(result.color)
|
||||||
.frame(width: 100, alignment: .trailing)
|
.frame(width: Design.Size.resultRowResultWidth, alignment: .trailing)
|
||||||
|
.lineLimit(1)
|
||||||
|
.minimumScaleFactor(Design.MinScaleFactor.comfortable)
|
||||||
|
.debugBorder(showDebugBorders, color: .red, label: "Result")
|
||||||
}
|
}
|
||||||
|
.debugBorder(showDebugBorders, color: .white, label: "ResultRow")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,6 +280,8 @@ struct SideBetResultRow: View {
|
|||||||
let isWin: Bool
|
let isWin: Bool
|
||||||
let amount: Int
|
let amount: Int
|
||||||
|
|
||||||
|
private var showDebugBorders: Bool { Design.showDebugBorders }
|
||||||
|
|
||||||
private var amountText: String {
|
private var amountText: String {
|
||||||
if amount > 0 {
|
if amount > 0 {
|
||||||
return "+$\(amount)"
|
return "+$\(amount)"
|
||||||
@ -295,23 +305,28 @@ struct SideBetResultRow: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
HStack {
|
HStack {
|
||||||
Text(label)
|
Text(label)
|
||||||
.font(.system(size: Design.BaseFontSize.body))
|
.font(.system(size: Design.BaseFontSize.medium))
|
||||||
.foregroundStyle(.white.opacity(Design.Opacity.strong))
|
.foregroundStyle(.white.opacity(Design.Opacity.strong))
|
||||||
|
.debugBorder(showDebugBorders, color: .blue, label: "Label")
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
.debugBorder(showDebugBorders, color: .yellow, label: "Spacer")
|
||||||
|
|
||||||
Text(amountText)
|
Text(amountText)
|
||||||
.font(.system(size: Design.BaseFontSize.body, weight: .semibold, design: .rounded))
|
.font(.system(size: Design.BaseFontSize.medium, weight: .semibold, design: .rounded))
|
||||||
.foregroundStyle(amountColor)
|
.foregroundStyle(amountColor)
|
||||||
.frame(width: 70, alignment: .trailing)
|
.frame(width: Design.Size.resultRowAmountWidth, alignment: .trailing)
|
||||||
|
.debugBorder(showDebugBorders, color: .green, label: "Amount")
|
||||||
|
|
||||||
Text(resultText)
|
Text(resultText)
|
||||||
.font(.system(size: Design.BaseFontSize.body, weight: .bold))
|
.font(.system(size: Design.BaseFontSize.large, weight: .bold))
|
||||||
.foregroundStyle(resultColor)
|
.foregroundStyle(resultColor)
|
||||||
.frame(width: 100, alignment: .trailing)
|
.frame(width: Design.Size.resultRowResultWidth, alignment: .trailing)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.minimumScaleFactor(Design.MinScaleFactor.comfortable)
|
.minimumScaleFactor(Design.MinScaleFactor.comfortable)
|
||||||
|
.debugBorder(showDebugBorders, color: .red, label: "Result")
|
||||||
}
|
}
|
||||||
|
.debugBorder(showDebugBorders, color: .white, label: "SideBetRow")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -31,9 +31,9 @@ struct PlayerHandsView: View {
|
|||||||
// Display hands in reverse order (right to left play order)
|
// Display hands in reverse order (right to left play order)
|
||||||
// Visual order: Hand 3, Hand 2, Hand 1 (left to right)
|
// Visual order: Hand 3, Hand 2, Hand 1 (left to right)
|
||||||
// Play order: Hand 1 played first (rightmost), then Hand 2, etc.
|
// Play order: Hand 1 played first (rightmost), then Hand 2, etc.
|
||||||
ForEach(hands.indices.reversed(), id: \.self) { index in
|
ForEach(Array(hands.enumerated()).reversed(), id: \.element.id) { index, hand in
|
||||||
PlayerHandView(
|
PlayerHandView(
|
||||||
hand: hands[index],
|
hand: hand,
|
||||||
isActive: index == activeHandIndex && isPlayerTurn,
|
isActive: index == activeHandIndex && isPlayerTurn,
|
||||||
showCardCount: showCardCount,
|
showCardCount: showCardCount,
|
||||||
// Hand numbers: rightmost (index 0) is Hand 1, played first
|
// Hand numbers: rightmost (index 0) is Hand 1, played first
|
||||||
@ -41,35 +41,39 @@ struct PlayerHandsView: View {
|
|||||||
cardWidth: cardWidth,
|
cardWidth: cardWidth,
|
||||||
cardSpacing: cardSpacing
|
cardSpacing: cardSpacing
|
||||||
)
|
)
|
||||||
.id(index)
|
.id(hand.id)
|
||||||
|
.transition(.scale.combined(with: .opacity))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.animation(.spring(duration: Design.Animation.springDuration), value: hands.count)
|
||||||
.padding(.horizontal, Design.Spacing.xxLarge) // More padding for scrolling
|
.padding(.horizontal, Design.Spacing.xxLarge) // More padding for scrolling
|
||||||
}
|
}
|
||||||
.scrollClipDisabled()
|
.scrollClipDisabled()
|
||||||
.scrollBounceBehavior(.always) // Always allow bouncing for better scroll feel
|
.scrollBounceBehavior(.always) // Always allow bouncing for better scroll feel
|
||||||
.defaultScrollAnchor(.center) // Center the content by default
|
.defaultScrollAnchor(.center) // Center the content by default
|
||||||
.onChange(of: activeHandIndex) { _, newIndex in
|
.onChange(of: activeHandIndex) { _, newIndex in
|
||||||
scrollToHand(proxy: proxy, index: newIndex)
|
scrollToActiveHand(proxy: proxy)
|
||||||
}
|
}
|
||||||
.onChange(of: totalCardCount) { _, _ in
|
.onChange(of: totalCardCount) { _, _ in
|
||||||
// Scroll to active hand when cards are added (hit)
|
// Scroll to active hand when cards are added (hit)
|
||||||
scrollToHand(proxy: proxy, index: activeHandIndex)
|
scrollToActiveHand(proxy: proxy)
|
||||||
}
|
}
|
||||||
.onChange(of: hands.count) { _, _ in
|
.onChange(of: hands.count) { _, _ in
|
||||||
// Scroll to active hand when split occurs
|
// Scroll to active hand when split occurs
|
||||||
scrollToHand(proxy: proxy, index: activeHandIndex)
|
scrollToActiveHand(proxy: proxy)
|
||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
scrollToHand(proxy: proxy, index: activeHandIndex)
|
scrollToActiveHand(proxy: proxy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func scrollToHand(proxy: ScrollViewProxy, index: Int) {
|
private func scrollToActiveHand(proxy: ScrollViewProxy) {
|
||||||
|
guard activeHandIndex < hands.count else { return }
|
||||||
|
let activeHandId = hands[activeHandIndex].id
|
||||||
withAnimation(.easeInOut(duration: Design.Animation.quick)) {
|
withAnimation(.easeInOut(duration: Design.Animation.quick)) {
|
||||||
proxy.scrollTo(index, anchor: .center)
|
proxy.scrollTo(activeHandId, anchor: .center)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,9 +18,9 @@ struct SideBetToastView: View {
|
|||||||
|
|
||||||
@State private var isShowing = false
|
@State private var isShowing = false
|
||||||
|
|
||||||
@ScaledMetric(relativeTo: .caption) private var titleFontSize: CGFloat = 10
|
@ScaledMetric(relativeTo: .caption) private var titleFontSize: CGFloat = Design.Size.sideBetToastTitleFontSize
|
||||||
@ScaledMetric(relativeTo: .caption2) private var resultFontSize: CGFloat = 11
|
@ScaledMetric(relativeTo: .callout) private var resultFontSize: CGFloat = Design.Size.sideBetToastResultFontSize
|
||||||
@ScaledMetric(relativeTo: .caption2) private var amountFontSize: CGFloat = 13
|
@ScaledMetric(relativeTo: .body) private var amountFontSize: CGFloat = Design.Size.sideBetToastAmountFontSize
|
||||||
|
|
||||||
private var backgroundColor: Color {
|
private var backgroundColor: Color {
|
||||||
isWin ? Color.green.opacity(Design.Opacity.heavy) : Color.red.opacity(Design.Opacity.heavy)
|
isWin ? Color.green.opacity(Design.Opacity.heavy) : Color.red.opacity(Design.Opacity.heavy)
|
||||||
@ -68,14 +68,14 @@ struct SideBetToastView: View {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
.shadow(color: borderColor.opacity(Design.Opacity.medium), radius: Design.Shadow.radiusMedium)
|
.shadow(color: borderColor.opacity(Design.Opacity.medium), radius: Design.Shadow.radiusMedium)
|
||||||
.scaleEffect(isShowing ? 1.0 : 0.5)
|
.scaleEffect(isShowing ? Design.Scale.normal : Design.Scale.shrunk)
|
||||||
.opacity(isShowing ? 1.0 : 0)
|
.opacity(isShowing ? 1.0 : 0)
|
||||||
.offset(x: isShowing ? 0 : (showOnLeft ? -Design.Spacing.toastSlide : Design.Spacing.toastSlide))
|
.offset(x: isShowing ? 0 : (showOnLeft ? -Design.Spacing.toastSlide : Design.Spacing.toastSlide))
|
||||||
.accessibilityElement(children: .combine)
|
.accessibilityElement(children: .combine)
|
||||||
.accessibilityLabel("\(title): \(result)")
|
.accessibilityLabel("\(title): \(result)")
|
||||||
.accessibilityValue(amountText)
|
.accessibilityValue(amountText)
|
||||||
.onAppear {
|
.onAppear {
|
||||||
withAnimation(.spring(duration: Design.Animation.springDuration, bounce: 0.4).delay(showOnLeft ? 0 : Design.Animation.staggerDelay1)) {
|
withAnimation(.spring(duration: Design.Animation.springDuration, bounce: Design.AnimationExtra.toastBounce).delay(showOnLeft ? 0 : Design.Animation.staggerDelay1)) {
|
||||||
isShowing = true
|
isShowing = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,8 +16,8 @@ struct SideBetZoneView: View {
|
|||||||
let isAtMax: Bool
|
let isAtMax: Bool
|
||||||
let onTap: () -> Void
|
let onTap: () -> Void
|
||||||
|
|
||||||
@ScaledMetric(relativeTo: .caption) private var labelFontSize: CGFloat = 11
|
@ScaledMetric(relativeTo: .callout) private var labelFontSize: CGFloat = Design.Size.sideBetLabelFontSize
|
||||||
@ScaledMetric(relativeTo: .caption2) private var payoutFontSize: CGFloat = 9
|
@ScaledMetric(relativeTo: .caption) private var payoutFontSize: CGFloat = Design.Size.sideBetPayoutFontSize
|
||||||
|
|
||||||
private var backgroundColor: Color {
|
private var backgroundColor: Color {
|
||||||
switch betType {
|
switch betType {
|
||||||
@ -49,7 +49,7 @@ struct SideBetZoneView: View {
|
|||||||
RoundedRectangle(cornerRadius: Design.CornerRadius.medium)
|
RoundedRectangle(cornerRadius: Design.CornerRadius.medium)
|
||||||
.strokeBorder(
|
.strokeBorder(
|
||||||
Color.white.opacity(Design.Opacity.hint),
|
Color.white.opacity(Design.Opacity.hint),
|
||||||
lineWidth: Design.LineWidth.thin
|
lineWidth: Design.LineWidth.medium
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
17
Blackjack/BlackjackTests/BlackjackTests.swift
Normal file
17
Blackjack/BlackjackTests/BlackjackTests.swift
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// BlackjackTests.swift
|
||||||
|
// BlackjackTests
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 12/17/25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Testing
|
||||||
|
@testable import Blackjack
|
||||||
|
|
||||||
|
struct BlackjackTests {
|
||||||
|
|
||||||
|
@Test func example() async throws {
|
||||||
|
// Write your test here and use APIs like `#expect(...)` to check expected conditions.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
41
Blackjack/BlackjackUITests/BlackjackUITests.swift
Normal file
41
Blackjack/BlackjackUITests/BlackjackUITests.swift
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
//
|
||||||
|
// BlackjackUITests.swift
|
||||||
|
// BlackjackUITests
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 12/17/25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
final class BlackjackUITests: XCTestCase {
|
||||||
|
|
||||||
|
override func setUpWithError() throws {
|
||||||
|
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||||
|
|
||||||
|
// In UI tests it is usually best to stop immediately when a failure occurs.
|
||||||
|
continueAfterFailure = false
|
||||||
|
|
||||||
|
// In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tearDownWithError() throws {
|
||||||
|
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
func testExample() throws {
|
||||||
|
// UI tests must launch the application that they test.
|
||||||
|
let app = XCUIApplication()
|
||||||
|
app.launch()
|
||||||
|
|
||||||
|
// Use XCTAssert and related functions to verify your tests produce the correct results.
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
func testLaunchPerformance() throws {
|
||||||
|
// This measures how long it takes to launch your application.
|
||||||
|
measure(metrics: [XCTApplicationLaunchMetric()]) {
|
||||||
|
XCUIApplication().launch()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
33
Blackjack/BlackjackUITests/BlackjackUITestsLaunchTests.swift
Normal file
33
Blackjack/BlackjackUITests/BlackjackUITestsLaunchTests.swift
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// BlackjackUITestsLaunchTests.swift
|
||||||
|
// BlackjackUITests
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 12/17/25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
final class BlackjackUITestsLaunchTests: XCTestCase {
|
||||||
|
|
||||||
|
override class var runsForEachTargetApplicationUIConfiguration: Bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
override func setUpWithError() throws {
|
||||||
|
continueAfterFailure = false
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
func testLaunch() throws {
|
||||||
|
let app = XCUIApplication()
|
||||||
|
app.launch()
|
||||||
|
|
||||||
|
// Insert steps here to perform after app launch but before taking a screenshot,
|
||||||
|
// such as logging into a test account or navigating somewhere in the app
|
||||||
|
|
||||||
|
let attachment = XCTAttachment(screenshot: app.screenshot())
|
||||||
|
attachment.name = "Launch Screen"
|
||||||
|
attachment.lifetime = .keepAlways
|
||||||
|
add(attachment)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user