Merge pull request #130 from flixcoo/enhance/128-activegameview-enhancements

ActiveGameView enhancements
This commit is contained in:
2025-07-21 12:18:03 +02:00
committed by GitHub
6 changed files with 95 additions and 35 deletions

View File

@@ -97,7 +97,7 @@
}, },
"end_of_game_title": "End of Game", "end_of_game_title": "End of Game",
"end_of_game_message": "{names} won the game with {points} points. Congratulations!", "end_of_game_message": "{playerCount, plural, =1{{names} won the game with {points} points. Congratulations!} other{{names} won the game with {points} points. Congratulations to everyone!}}",
"@end_of_game_message": { "@end_of_game_message": {
"placeholders": { "placeholders": {
"playerCount": { "playerCount": {

View File

@@ -210,7 +210,14 @@ class AppLocalizationsEn extends AppLocalizations {
@override @override
String end_of_game_message(int playerCount, String names, int points) { String end_of_game_message(int playerCount, String names, int points) {
return '$names won the game with $points points. Congratulations!'; String _temp0 = intl.Intl.pluralLogic(
playerCount,
locale: localeName,
other:
'$names won the game with $points points. Congratulations to everyone!',
one: '$names won the game with $points points. Congratulations!',
);
return '$_temp0';
} }
@override @override

View File

@@ -49,7 +49,10 @@ class _ActiveGameViewState extends State<ActiveGameView> {
gameSession.playerScores, sortedPlayerIndices); gameSession.playerScores, sortedPlayerIndices);
return CupertinoPageScaffold( return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar( navigationBar: CupertinoNavigationBar(
middle: Text(gameSession.gameTitle), middle: Text(
gameSession.gameTitle,
overflow: TextOverflow.ellipsis,
),
), ),
child: SafeArea( child: SafeArea(
child: SingleChildScrollView( child: SingleChildScrollView(

View File

@@ -38,11 +38,16 @@ class CreateGameView extends StatefulWidget {
} }
class _CreateGameViewState extends State<CreateGameView> { class _CreateGameViewState extends State<CreateGameView> {
final TextEditingController _gameTitleTextController =
TextEditingController();
/// List of text controllers for player names.
final List<TextEditingController> _playerNameTextControllers = [ final List<TextEditingController> _playerNameTextControllers = [
TextEditingController() TextEditingController()
]; ];
final TextEditingController _gameTitleTextController =
TextEditingController(); /// List of focus nodes for player name text fields.
final List<FocusNode> _playerNameFocusNodes = [FocusNode()];
/// Maximum number of players allowed in the game. /// Maximum number of players allowed in the game.
final int maxPlayers = 5; final int maxPlayers = 5;
@@ -94,11 +99,19 @@ class _CreateGameViewState extends State<CreateGameView> {
padding: const EdgeInsets.fromLTRB(15, 10, 10, 0), padding: const EdgeInsets.fromLTRB(15, 10, 10, 0),
child: CupertinoTextField( child: CupertinoTextField(
decoration: const BoxDecoration(), decoration: const BoxDecoration(),
maxLength: 16, maxLength: 20,
prefix: Text(AppLocalizations.of(context).name), prefix: Text(AppLocalizations.of(context).name),
textAlign: TextAlign.right, textAlign: TextAlign.right,
placeholder: AppLocalizations.of(context).game_title, placeholder: AppLocalizations.of(context).game_title,
controller: _gameTitleTextController, controller: _gameTitleTextController,
onSubmitted: (_) {
_playerNameFocusNodes.isNotEmpty
? _playerNameFocusNodes[0].requestFocus()
: FocusScope.of(context).unfocus();
},
textInputAction: _playerNameFocusNodes.isNotEmpty
? TextInputAction.next
: TextInputAction.done,
), ),
), ),
Padding( Padding(
@@ -177,11 +190,24 @@ class _CreateGameViewState extends State<CreateGameView> {
Expanded( Expanded(
child: CupertinoTextField( child: CupertinoTextField(
controller: _playerNameTextControllers[index], controller: _playerNameTextControllers[index],
focusNode: _playerNameFocusNodes[index],
maxLength: 12, maxLength: 12,
placeholder: placeholder:
'${AppLocalizations.of(context).player} ${index + 1}', '${AppLocalizations.of(context).player} ${index + 1}',
padding: const EdgeInsets.all(12), padding: const EdgeInsets.all(12),
decoration: const BoxDecoration(), decoration: const BoxDecoration(),
textInputAction:
index + 1 < _playerNameTextControllers.length
? TextInputAction.next
: TextInputAction.done,
onSubmitted: (_) {
if (index + 1 < _playerNameFocusNodes.length) {
_playerNameFocusNodes[index + 1]
.requestFocus();
} else {
FocusScope.of(context).unfocus();
}
},
), ),
), ),
AnimatedOpacity( AnimatedOpacity(
@@ -207,38 +233,56 @@ class _CreateGameViewState extends State<CreateGameView> {
}), }),
Padding( Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 8, 50), padding: const EdgeInsets.fromLTRB(8, 0, 8, 50),
child: Center( child: Stack(
child: SizedBox( children: [
width: double.infinity, Row(
child: CupertinoButton( mainAxisAlignment: MainAxisAlignment.start,
padding: const EdgeInsets.symmetric(horizontal: 16), children: [
child: Row( CupertinoButton(
mainAxisAlignment: MainAxisAlignment.center, padding: EdgeInsets.zero,
children: [ onPressed: null,
Text( child: Icon(
AppLocalizations.of(context).add_player, CupertinoIcons.plus_circle_fill,
style: TextStyle(color: CustomTheme.primaryColor),
),
const SizedBox(width: 8),
Icon(
CupertinoIcons.add_circled_solid,
color: CustomTheme.primaryColor, color: CustomTheme.primaryColor,
size: 25, size: 25,
), ),
], ),
), ],
onPressed: () {
if (_playerNameTextControllers.length < maxPlayers) {
setState(() {
_playerNameTextControllers
.add(TextEditingController());
});
} else {
_showFeedbackDialog(CreateStatus.maxPlayers);
}
},
), ),
), Center(
child: CupertinoButton(
padding: const EdgeInsets.symmetric(horizontal: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
child: Center(
child: Text(
AppLocalizations.of(context).add_player,
style: TextStyle(
color: CustomTheme.primaryColor),
),
),
),
],
),
onPressed: () {
if (_playerNameTextControllers.length < maxPlayers) {
setState(() {
_playerNameTextControllers
.add(TextEditingController());
_playerNameFocusNodes.add(FocusNode());
});
WidgetsBinding.instance.addPostFrameCallback((_) {
_playerNameFocusNodes.last.requestFocus();
});
} else {
_showFeedbackDialog(CreateStatus.maxPlayers);
}
},
),
),
],
), ),
), ),
Padding( Padding(
@@ -415,6 +459,9 @@ class _CreateGameViewState extends State<CreateGameView> {
for (var controller in _playerNameTextControllers) { for (var controller in _playerNameTextControllers) {
controller.dispose(); controller.dispose();
} }
for (var focusnode in _playerNameFocusNodes) {
focusnode.dispose();
}
super.dispose(); super.dispose();
} }

View File

@@ -144,6 +144,9 @@ class _MainMenuViewState extends State<MainMenuView> {
)), )),
trailing: Row( trailing: Row(
children: [ children: [
const SizedBox(
width: 5,
),
Text('${session.roundNumber}'), Text('${session.roundNumber}'),
const SizedBox(width: 3), const SizedBox(width: 3),
const Icon(CupertinoIcons const Icon(CupertinoIcons

View File

@@ -2,7 +2,7 @@ name: cabo_counter
description: "Mobile app for the card game Cabo" description: "Mobile app for the card game Cabo"
publish_to: 'none' publish_to: 'none'
version: 0.5.2+581 version: 0.5.3+589
environment: environment:
sdk: ^3.5.4 sdk: ^3.5.4