Updated buttons, implemented animatedOpacity

This commit is contained in:
2025-07-20 17:51:30 +02:00
parent 5ebce36c12
commit a4693ccf39
4 changed files with 117 additions and 172 deletions

View File

@@ -365,7 +365,7 @@ abstract class AppLocalizations {
/// No description provided for @no_name_message. /// No description provided for @no_name_message.
/// ///
/// In de, this message translates to: /// In de, this message translates to:
/// **'Jeder Spieler muss einen Namen haben.'** /// **'Jede:r Spieler:in muss einen Namen haben.'**
String get no_name_message; String get no_name_message;
/// No description provided for @select_game_mode. /// No description provided for @select_game_mode.

View File

@@ -149,7 +149,7 @@ class AppLocalizationsDe extends AppLocalizations {
String get no_name_title => 'Kein Name'; String get no_name_title => 'Kein Name';
@override @override
String get no_name_message => 'Jeder Spieler muss einen Namen haben.'; String get no_name_message => 'Jede:r Spieler:in muss einen Namen haben.';
@override @override
String get select_game_mode => 'Spielmodus auswählen'; String get select_game_mode => 'Spielmodus auswählen';

View File

@@ -4,6 +4,7 @@ import 'package:cabo_counter/data/game_session.dart';
import 'package:cabo_counter/l10n/generated/app_localizations.dart'; import 'package:cabo_counter/l10n/generated/app_localizations.dart';
import 'package:cabo_counter/presentation/views/active_game_view.dart'; import 'package:cabo_counter/presentation/views/active_game_view.dart';
import 'package:cabo_counter/presentation/views/mode_selection_view.dart'; import 'package:cabo_counter/presentation/views/mode_selection_view.dart';
import 'package:cabo_counter/presentation/widgets/custom_button.dart';
import 'package:cabo_counter/services/config_service.dart'; import 'package:cabo_counter/services/config_service.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -136,185 +137,129 @@ class _CreateGameViewState extends State<CreateGameView> {
style: CustomTheme.rowTitle, style: CustomTheme.rowTitle,
), ),
), ),
Expanded( Flexible(
child: ReorderableListView.builder( child: ReorderableListView.builder(
physics: const NeverScrollableScrollPhysics(), shrinkWrap: true,
itemCount: _playerNameTextControllers.length + 2, physics: const BouncingScrollPhysics(),
onReorder: (oldIndex, newIndex) { padding: const EdgeInsets.all(8),
itemCount: _playerNameTextControllers.length,
onReorder: (oldIndex, newIndex) {
setState(() {
if (oldIndex < _playerNameTextControllers.length && if (oldIndex < _playerNameTextControllers.length &&
newIndex <= _playerNameTextControllers.length) { newIndex <= _playerNameTextControllers.length) {
setState(() { if (newIndex > oldIndex) newIndex--;
if (newIndex > oldIndex) newIndex--; final item =
final item = _playerNameTextControllers.removeAt(oldIndex);
_playerNameTextControllers.removeAt(oldIndex); _playerNameTextControllers.insert(newIndex, item);
_playerNameTextControllers.insert(newIndex, item);
});
} }
}, });
itemBuilder: (context, index) { },
// Create game button itemBuilder: (context, index) {
if (index == _playerNameTextControllers.length + 1) { return Padding(
return Container( key: ValueKey(
key: const ValueKey('create_game_button'), 'player_${_playerNameTextControllers[index].hashCode}'),
child: CupertinoButton( padding: const EdgeInsets.symmetric(vertical: 8.0),
padding: const EdgeInsets.fromLTRB(0, 50, 0, 0), child: Row(
child: Row( children: [
mainAxisAlignment: MainAxisAlignment.center, CupertinoButton(
children: [ padding: EdgeInsets.zero,
Container( child: const Icon(
decoration: BoxDecoration( CupertinoIcons.minus_circle_fill,
borderRadius: BorderRadius.circular(20), color: CupertinoColors.destructiveRed,
color: CustomTheme.primaryColor, size: 25,
),
padding: const EdgeInsets.symmetric(
horizontal: 15, vertical: 8),
child: Text(
AppLocalizations.of(context).create_game,
style: TextStyle(
color: CustomTheme.backgroundColor,
),
),
),
],
), ),
onPressed: () { onPressed: () {
_checkAllGameAttributes(); setState(() {
_playerNameTextControllers[index].dispose();
_playerNameTextControllers.removeAt(index);
});
}, },
), ),
); Expanded(
} child: CupertinoTextField(
// Add player button controller: _playerNameTextControllers[index],
if (index == _playerNameTextControllers.length) { maxLength: 12,
return Container( placeholder:
key: const ValueKey('add_player_button'), '${AppLocalizations.of(context).player} ${index + 1}',
child: Padding( padding: const EdgeInsets.all(12),
padding: const EdgeInsets.symmetric( decoration: const BoxDecoration(),
vertical: 4.0, horizontal: 10), ),
child: CupertinoButton(
padding: EdgeInsets.zero,
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Icon(
CupertinoIcons.add_circled_solid,
color: CustomTheme.primaryColor,
),
const SizedBox(width: 6),
Text(
AppLocalizations.of(context)
.add_player,
style: TextStyle(
color:
CustomTheme.primaryColor),
),
]),
onPressed: () {
if (_playerNameTextControllers.length <
maxPlayers) {
setState(() {
_playerNameTextControllers
.add(TextEditingController());
});
} else {
showFeedbackDialog(
CreateStatus.maxPlayers);
}
})));
} else {
// Player entries
return Padding(
key: ValueKey(_playerNameTextControllers[index]),
padding: const EdgeInsets.symmetric(
vertical: 8.0, horizontal: 5),
child: Row(
children: [
CupertinoButton(
padding: EdgeInsets.zero,
child: const Icon(
CupertinoIcons.minus_circle_fill,
color: CupertinoColors.destructiveRed,
size: 25,
),
onPressed: () {
setState(() {
_playerNameTextControllers[index].dispose();
_playerNameTextControllers.removeAt(index);
});
},
),
Expanded(
child: CupertinoTextField(
controller: _playerNameTextControllers[index],
maxLength: 12,
placeholder:
'${AppLocalizations.of(context).player} ${index + 1}',
padding: const EdgeInsets.all(12),
decoration: const BoxDecoration(),
),
),
],
), ),
); AnimatedOpacity(
} opacity: _playerNameTextControllers.length > 1
})), ? 1.0
Center( : 0.0,
child: CupertinoButton( duration: const Duration(milliseconds: 300),
padding: EdgeInsets.zero, child: Padding(
child: Row( padding: const EdgeInsets.only(right: 8.0),
mainAxisAlignment: MainAxisAlignment.center, child: ReorderableDragStartListener(
children: [ index: index,
Text( child: const Icon(
AppLocalizations.of(context).create_game, CupertinoIcons.line_horizontal_3,
style: const TextStyle( color: CupertinoColors.systemGrey,
color: CupertinoColors.activeGreen, ),
),
),
)
],
), ),
), );
], }),
),
Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 0, 50),
child: Center(
child: CupertinoButton(
padding: EdgeInsets.zero,
child: Row(
children: [
CupertinoButton(
padding: EdgeInsets.zero,
onPressed: null,
child: Icon(
CupertinoIcons.plus_circle_fill,
color: CustomTheme.primaryColor,
size: 25,
)),
Stack(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());
});
} else {
showFeedbackDialog(CreateStatus.maxPlayers);
}
},
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 50),
child: Center(
key: const ValueKey('create_game_button'),
child: CustomButton(
child: Text(
AppLocalizations.of(context).create_game,
style: TextStyle(
color: CustomTheme.primaryColor,
),
),
onPressed: () {
_checkAllGameAttributes();
},
), ),
onPressed: () async {
if (_gameTitleTextController.text == '') {
showFeedbackDialog(CreateStatus.noGameTitle);
return;
}
if (gameMode == GameMode.none) {
showFeedbackDialog(CreateStatus.noModeSelected);
return;
}
if (_playerNameTextControllers.length < 2) {
showFeedbackDialog(CreateStatus.minPlayers);
return;
}
if (!everyPlayerHasAName()) {
showFeedbackDialog(CreateStatus.noPlayerName);
return;
}
List<String> players = [];
for (var controller in _playerNameTextControllers) {
players.add(controller.text);
}
bool isPointsLimitEnabled = gameMode == GameMode.pointLimit;
GameSession gameSession = GameSession(
createdAt: DateTime.now(),
gameTitle: _gameTitleTextController.text,
players: players,
pointLimit: ConfigService.getPointLimit(),
caboPenalty: ConfigService.getCaboPenalty(),
isPointsLimitEnabled: isPointsLimitEnabled,
);
final index = await gameManager.addGameSession(gameSession);
final session = gameManager.gameList[index];
if (context.mounted) {
Navigator.pushReplacement(
context,
CupertinoPageRoute(
builder: (context) =>
ActiveGameView(gameSession: session)));
}
},
), ),
), ),
], ],

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.0+556 version: 0.5.0+558
environment: environment:
sdk: ^3.5.4 sdk: ^3.5.4