Beta-Version 0.5.3 (#136)
* Updated createGameView ListBuilder * Added ReorderableListView * Increment build no * Fixed bug with wrong medal icon * change not equal to greater than * Updated bool var * Fixed deletion error * Small translation improvements * Implemented first version of point overview * Visual improvements on table * Added details and sum row * Updated strings * Implemented new strings * Refactoring * Updated graph displayment * Moved new views to statistics section * Added seperator in main menu * Renaming * Updated sign * Updated colors & class name * Removed empty line * Updated round index * Updated types * Added new kamikaze button and bundles navigation functionality * Updated lock icon * Updated button position and design * Removed title row and changed segmendetControl Padding * Refactored logic and added comments * Updated comment * Chaned icon * Added comment * Removed print * Updated colors * Changed var name * Removed unused strings * Added gameMode * Changed creation variable * Updated mode selection * Updated strings * Changed mode order * Implemented default mode selection * Updated initState * Removed print * Removed print * Removed comments * Updated config service * Changed create game view * Changed icon * Updated strings * Updated config * Updated mode selection logic * Deleted getter * Removed not used code * Implemented reset logic for default game mode * Updated to 0.5.0 * Hotfix: Pixel Overflow * Changed the overall return type for gamemodes * Updated documentation * Fixed merge issues * Added Custom button * Updated strings * Updated buttons, implemented animatedOpacity * Keyboard still doesnt works * Fixed keyboard behaviour * Changed keyboard height * Added method getGameSessionById() * Updated gameSession class * id gets added to gameSession class at creation * Cleaned up file * Added docs and dependency * Removed toString * Implemented null safety * Added named parameter * Replaced button with custom button * Updated key * Updated addGameSessionMethod * Update README.md * Added Strings for popup * Implemented popup & confetti * Extracted code to method _playFinishAnimation() * Replaced tenary operator with Visibility Widget * Replaced tenary operator with Visibility Widget * Used variable again * Added delays in constants.dart * Removed confetti button * Updated strings * Removed print * Added dispose for confettiController * Implemented missing constant in code * Updated gameSession logic so more than one player can be winner * Updated strings * Updated winner popup * game names now can have up to 20 chars * Updated strings * Added sized box for visual enhancement * Centered the add player button and made it wider * New created player textfields get automatically focused * Added focus nodes for autofocus and navigation between textfields * Updated version number * Updated game title textfield with focus node and textaction * Added focusnodes to dispose * Update README.md * Fixed bug with no popup shown * Fixed bug with out of range error * Updated listener notification
This commit is contained in:
@@ -1,11 +1,16 @@
|
||||
import 'package:cabo_counter/core/constants.dart';
|
||||
import 'package:cabo_counter/core/custom_theme.dart';
|
||||
import 'package:cabo_counter/data/game_manager.dart';
|
||||
import 'package:cabo_counter/data/game_session.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/mode_selection_view.dart';
|
||||
import 'package:cabo_counter/presentation/widgets/custom_button.dart';
|
||||
import 'package:cabo_counter/services/config_service.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
enum CreateStatus {
|
||||
noGameTitle,
|
||||
@@ -16,15 +21,15 @@ enum CreateStatus {
|
||||
}
|
||||
|
||||
class CreateGameView extends StatefulWidget {
|
||||
final GameMode gameMode;
|
||||
final String? gameTitle;
|
||||
final bool? isPointsLimitEnabled;
|
||||
final List<String>? players;
|
||||
|
||||
const CreateGameView({
|
||||
super.key,
|
||||
this.gameTitle,
|
||||
this.isPointsLimitEnabled,
|
||||
this.players,
|
||||
required this.gameMode,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -33,29 +38,39 @@ class CreateGameView extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _CreateGameViewState extends State<CreateGameView> {
|
||||
final TextEditingController _gameTitleTextController =
|
||||
TextEditingController();
|
||||
|
||||
/// List of text controllers for player names.
|
||||
final List<TextEditingController> _playerNameTextControllers = [
|
||||
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.
|
||||
final int maxPlayers = 5;
|
||||
|
||||
/// Variable to store whether the points limit feature is enabled.
|
||||
bool? _isPointsLimitEnabled;
|
||||
/// Factor to adjust the view length when the keyboard is visible.
|
||||
final double keyboardHeightAdjustmentFactor = 0.75;
|
||||
|
||||
/// Variable to hold the selected game mode.
|
||||
late GameMode gameMode;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
_isPointsLimitEnabled = widget.isPointsLimitEnabled;
|
||||
gameMode = widget.gameMode;
|
||||
|
||||
_gameTitleTextController.text = widget.gameTitle ?? '';
|
||||
|
||||
if (widget.players != null) {
|
||||
_playerNameTextControllers.clear();
|
||||
for (var player in widget.players!) {
|
||||
_playerNameTextControllers.add(TextEditingController(text: player));
|
||||
_playerNameFocusNodes.add(FocusNode());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,124 +78,100 @@ class _CreateGameViewState extends State<CreateGameView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
navigationBar: CupertinoNavigationBar(
|
||||
previousPageTitle: AppLocalizations.of(context).overview,
|
||||
middle: Text(AppLocalizations.of(context).new_game),
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(10, 10, 0, 0),
|
||||
child: Text(
|
||||
AppLocalizations.of(context).game,
|
||||
style: CustomTheme.rowTitle,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(15, 10, 10, 0),
|
||||
child: CupertinoTextField(
|
||||
decoration: const BoxDecoration(),
|
||||
maxLength: 16,
|
||||
prefix: Text(AppLocalizations.of(context).name),
|
||||
textAlign: TextAlign.right,
|
||||
placeholder: AppLocalizations.of(context).game_title,
|
||||
controller: _gameTitleTextController,
|
||||
),
|
||||
),
|
||||
// Spielmodus-Auswahl mit Chevron
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(15, 10, 10, 0),
|
||||
child: CupertinoTextField(
|
||||
decoration: const BoxDecoration(),
|
||||
readOnly: true,
|
||||
prefix: Text(AppLocalizations.of(context).mode),
|
||||
suffix: Row(
|
||||
children: [
|
||||
Text(
|
||||
_isPointsLimitEnabled == null
|
||||
? AppLocalizations.of(context).select_mode
|
||||
: (_isPointsLimitEnabled!
|
||||
? '${ConfigService.pointLimit} ${AppLocalizations.of(context).points}'
|
||||
: AppLocalizations.of(context).unlimited),
|
||||
),
|
||||
const SizedBox(width: 3),
|
||||
const CupertinoListTileChevron(),
|
||||
],
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(10, 10, 0, 0),
|
||||
child: Text(
|
||||
AppLocalizations.of(context).game,
|
||||
style: CustomTheme.rowTitle,
|
||||
),
|
||||
onTap: () async {
|
||||
final selectedMode = await Navigator.push(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (context) => ModeSelectionMenu(
|
||||
pointLimit: ConfigService.pointLimit,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if (selectedMode != null) {
|
||||
setState(() {
|
||||
_isPointsLimitEnabled = selectedMode;
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(10, 10, 0, 0),
|
||||
child: Text(
|
||||
AppLocalizations.of(context).players,
|
||||
style: CustomTheme.rowTitle,
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(15, 10, 10, 0),
|
||||
child: CupertinoTextField(
|
||||
decoration: const BoxDecoration(),
|
||||
maxLength: 20,
|
||||
prefix: Text(AppLocalizations.of(context).name),
|
||||
textAlign: TextAlign.right,
|
||||
placeholder: AppLocalizations.of(context).game_title,
|
||||
controller: _gameTitleTextController,
|
||||
onSubmitted: (_) {
|
||||
_playerNameFocusNodes.isNotEmpty
|
||||
? _playerNameFocusNodes[0].requestFocus()
|
||||
: FocusScope.of(context).unfocus();
|
||||
},
|
||||
textInputAction: _playerNameFocusNodes.isNotEmpty
|
||||
? TextInputAction.next
|
||||
: TextInputAction.done,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: _playerNameTextControllers.length +
|
||||
1, // +1 für den + Button
|
||||
itemBuilder: (context, index) {
|
||||
if (index == _playerNameTextControllers.length) {
|
||||
// + Button als letztes Element
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: CupertinoButton(
|
||||
padding: EdgeInsets.zero,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(
|
||||
CupertinoIcons.add_circled,
|
||||
color: CupertinoColors.activeGreen,
|
||||
size: 25,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
AppLocalizations.of(context).add_player,
|
||||
style: const TextStyle(
|
||||
color: CupertinoColors.activeGreen,
|
||||
),
|
||||
),
|
||||
],
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(15, 10, 10, 0),
|
||||
child: CupertinoTextField(
|
||||
decoration: const BoxDecoration(),
|
||||
readOnly: true,
|
||||
prefix: Text(AppLocalizations.of(context).mode),
|
||||
suffix: Row(
|
||||
children: [
|
||||
_getDisplayedGameMode(),
|
||||
const SizedBox(width: 3),
|
||||
const CupertinoListTileChevron(),
|
||||
],
|
||||
),
|
||||
onTap: () async {
|
||||
final selectedMode = await Navigator.push(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (context) => ModeSelectionMenu(
|
||||
pointLimit: ConfigService.getPointLimit(),
|
||||
showDeselection: false,
|
||||
),
|
||||
onPressed: () {
|
||||
if (_playerNameTextControllers.length < maxPlayers) {
|
||||
setState(() {
|
||||
_playerNameTextControllers
|
||||
.add(TextEditingController());
|
||||
});
|
||||
} else {
|
||||
showFeedbackDialog(CreateStatus.maxPlayers);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
} else {
|
||||
// Spieler-Einträge
|
||||
|
||||
setState(() {
|
||||
gameMode = selectedMode ?? gameMode;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(10, 10, 0, 0),
|
||||
child: Text(
|
||||
AppLocalizations.of(context).players,
|
||||
style: CustomTheme.rowTitle,
|
||||
),
|
||||
),
|
||||
ReorderableListView.builder(
|
||||
shrinkWrap: true,
|
||||
physics: const BouncingScrollPhysics(),
|
||||
padding: const EdgeInsets.all(8),
|
||||
itemCount: _playerNameTextControllers.length,
|
||||
onReorder: (oldIndex, newIndex) {
|
||||
setState(() {
|
||||
if (oldIndex < _playerNameTextControllers.length &&
|
||||
newIndex <= _playerNameTextControllers.length) {
|
||||
if (newIndex > oldIndex) newIndex--;
|
||||
final item =
|
||||
_playerNameTextControllers.removeAt(oldIndex);
|
||||
_playerNameTextControllers.insert(newIndex, item);
|
||||
}
|
||||
});
|
||||
},
|
||||
itemBuilder: (context, index) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8.0, horizontal: 5),
|
||||
key: ValueKey(index),
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
CupertinoButton(
|
||||
@@ -200,82 +191,187 @@ class _CreateGameViewState extends State<CreateGameView> {
|
||||
Expanded(
|
||||
child: CupertinoTextField(
|
||||
controller: _playerNameTextControllers[index],
|
||||
focusNode: _playerNameFocusNodes[index],
|
||||
maxLength: 12,
|
||||
placeholder:
|
||||
'${AppLocalizations.of(context).player} ${index + 1}',
|
||||
padding: const EdgeInsets.all(12),
|
||||
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(
|
||||
opacity: _playerNameTextControllers.length > 1
|
||||
? 1.0
|
||||
: 0.0,
|
||||
duration: const Duration(
|
||||
milliseconds: Constants.fadeInDuration),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 8.0),
|
||||
child: ReorderableDragStartListener(
|
||||
index: index,
|
||||
child: const Icon(
|
||||
CupertinoIcons.line_horizontal_3,
|
||||
color: CupertinoColors.systemGrey,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
Center(
|
||||
child: CupertinoButton(
|
||||
padding: EdgeInsets.zero,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
}),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(8, 0, 8, 50),
|
||||
child: Stack(
|
||||
children: [
|
||||
Text(
|
||||
AppLocalizations.of(context).create_game,
|
||||
style: const TextStyle(
|
||||
color: CupertinoColors.activeGreen,
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
CupertinoButton(
|
||||
padding: EdgeInsets.zero,
|
||||
onPressed: null,
|
||||
child: Icon(
|
||||
CupertinoIcons.plus_circle_fill,
|
||||
color: CustomTheme.primaryColor,
|
||||
size: 25,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
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);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
onPressed: () async {
|
||||
if (_gameTitleTextController.text == '') {
|
||||
showFeedbackDialog(CreateStatus.noGameTitle);
|
||||
return;
|
||||
}
|
||||
if (_isPointsLimitEnabled == null) {
|
||||
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);
|
||||
}
|
||||
GameSession gameSession = GameSession(
|
||||
createdAt: DateTime.now(),
|
||||
gameTitle: _gameTitleTextController.text,
|
||||
players: players,
|
||||
pointLimit: ConfigService.pointLimit,
|
||||
caboPenalty: ConfigService.caboPenalty,
|
||||
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)));
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
))));
|
||||
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();
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
KeyboardVisibilityBuilder(builder: (context, visible) {
|
||||
if (visible) {
|
||||
return SizedBox(
|
||||
height: MediaQuery.of(context).viewInsets.bottom *
|
||||
keyboardHeightAdjustmentFactor,
|
||||
);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
})
|
||||
],
|
||||
),
|
||||
)));
|
||||
}
|
||||
|
||||
/// Returns a widget that displays the currently selected game mode in the View.
|
||||
Text _getDisplayedGameMode() {
|
||||
if (gameMode == GameMode.none) {
|
||||
return Text(AppLocalizations.of(context).no_mode_selected);
|
||||
} else if (gameMode == GameMode.pointLimit) {
|
||||
return Text(
|
||||
'${ConfigService.getPointLimit()} ${AppLocalizations.of(context).points}',
|
||||
style: TextStyle(color: CustomTheme.primaryColor));
|
||||
} else {
|
||||
return Text(AppLocalizations.of(context).unlimited,
|
||||
style: TextStyle(color: CustomTheme.primaryColor));
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks all game attributes before creating a new game.
|
||||
/// If any attribute is invalid, it shows a feedback dialog.
|
||||
/// If all attributes are valid, it calls the `_createGame` method.
|
||||
void _checkAllGameAttributes() {
|
||||
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;
|
||||
}
|
||||
|
||||
_createGame();
|
||||
}
|
||||
|
||||
/// Checks if every player has a name.
|
||||
/// Returns true if all players have a name, false otherwise.
|
||||
bool _everyPlayerHasAName() {
|
||||
for (var controller in _playerNameTextControllers) {
|
||||
if (controller.text == '') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Displays a feedback dialog based on the [CreateStatus].
|
||||
void showFeedbackDialog(CreateStatus status) {
|
||||
void _showFeedbackDialog(CreateStatus status) {
|
||||
final (title, message) = _getDialogContent(status);
|
||||
|
||||
showCupertinoDialog(
|
||||
@@ -326,15 +422,36 @@ class _CreateGameViewState extends State<CreateGameView> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if every player has a name.
|
||||
/// Returns true if all players have a name, false otherwise.
|
||||
bool everyPlayerHasAName() {
|
||||
/// Creates a new gameSession and navigates to the active game view.
|
||||
/// This method creates a new gameSession object with the provided attributes in the text fields.
|
||||
/// It then adds the game session to the game manager and navigates to the active game view.
|
||||
void _createGame() {
|
||||
var uuid = const Uuid();
|
||||
final String id = uuid.v1();
|
||||
|
||||
List<String> players = [];
|
||||
for (var controller in _playerNameTextControllers) {
|
||||
if (controller.text == '') {
|
||||
return false;
|
||||
}
|
||||
players.add(controller.text);
|
||||
}
|
||||
return true;
|
||||
|
||||
bool isPointsLimitEnabled = gameMode == GameMode.pointLimit;
|
||||
|
||||
GameSession gameSession = GameSession(
|
||||
id: id,
|
||||
createdAt: DateTime.now(),
|
||||
gameTitle: _gameTitleTextController.text,
|
||||
players: players,
|
||||
pointLimit: ConfigService.getPointLimit(),
|
||||
caboPenalty: ConfigService.getCaboPenalty(),
|
||||
isPointsLimitEnabled: isPointsLimitEnabled,
|
||||
);
|
||||
gameManager.addGameSession(gameSession);
|
||||
final session = gameManager.getGameSessionById(id) ?? gameSession;
|
||||
|
||||
Navigator.pushReplacement(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (context) => ActiveGameView(gameSession: session)));
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -343,6 +460,9 @@ class _CreateGameViewState extends State<CreateGameView> {
|
||||
for (var controller in _playerNameTextControllers) {
|
||||
controller.dispose();
|
||||
}
|
||||
for (var focusnode in _playerNameFocusNodes) {
|
||||
focusnode.dispose();
|
||||
}
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user