From 6c9b742bdf47c54c5eb70b3835441ecb8395e83c Mon Sep 17 00:00:00 2001 From: mathiskirchner Date: Mon, 24 Nov 2025 20:59:23 +0100 Subject: [PATCH] Refactor CreateGroupView to use SelectPlayerWidget --- .../views/main_menu/create_group_view.dart | 290 +----------------- 1 file changed, 16 insertions(+), 274 deletions(-) diff --git a/lib/presentation/views/main_menu/create_group_view.dart b/lib/presentation/views/main_menu/create_group_view.dart index c01250b..1153fc0 100644 --- a/lib/presentation/views/main_menu/create_group_view.dart +++ b/lib/presentation/views/main_menu/create_group_view.dart @@ -5,13 +5,9 @@ import 'package:game_tracker/data/db/database.dart'; import 'package:game_tracker/data/dto/group.dart'; import 'package:game_tracker/data/dto/player.dart'; import 'package:game_tracker/presentation/widgets/buttons/custom_width_button.dart'; -import 'package:game_tracker/presentation/widgets/custom_search_bar.dart'; +import 'package:game_tracker/presentation/widgets/select_player_widget.dart'; import 'package:game_tracker/presentation/widgets/text_input_field.dart'; -import 'package:game_tracker/presentation/widgets/tiles/text_icon_list_tile.dart'; -import 'package:game_tracker/presentation/widgets/tiles/text_icon_tile.dart'; -import 'package:game_tracker/presentation/widgets/top_centered_message.dart'; import 'package:provider/provider.dart'; -import 'package:skeletonizer/skeletonizer.dart'; class CreateGroupView extends StatefulWidget { const CreateGroupView({super.key}); @@ -21,29 +17,21 @@ class CreateGroupView extends StatefulWidget { } class _CreateGroupViewState extends State { - List selectedPlayers = []; - List suggestedPlayers = []; - List allPlayers = []; - late final AppDatabase db; - late Future> _allPlayersFuture; - late final List skeletonData = List.filled( - 7, - Player(name: 'Player 0'), - ); final _groupNameController = TextEditingController(); final _searchBarController = TextEditingController(); + late final AppDatabase db; + List selectedPlayers = []; @override void initState() { super.initState(); db = Provider.of(context, listen: false); - _searchBarController.addListener(() { - setState(() {}); - }); _groupNameController.addListener(() { setState(() {}); }); - loadPlayerList(); + _searchBarController.addListener(() { + setState(() {}); + }); } @override @@ -53,21 +41,6 @@ class _CreateGroupViewState extends State { super.dispose(); } - void loadPlayerList() { - _allPlayersFuture = Future.delayed( - const Duration(milliseconds: 250), - () => db.playerDao.getAllPlayers(), - ); - suggestedPlayers = skeletonData; - _allPlayersFuture.then((loadedPlayers) { - setState(() { - loadedPlayers.sort((a, b) => a.name.compareTo(b.name)); - allPlayers = [...loadedPlayers]; - suggestedPlayers = [...loadedPlayers]; - }); - }); - } - @override Widget build(BuildContext context) { return Scaffold( @@ -96,204 +69,16 @@ class _CreateGroupViewState extends State { ), ), Expanded( - child: Container( - margin: const EdgeInsets.symmetric( - horizontal: 12, - vertical: 10, - ), - padding: const EdgeInsets.symmetric( - vertical: 10, - horizontal: 10, - ), - decoration: BoxDecoration( - color: CustomTheme.boxColor, - border: Border.all(color: CustomTheme.boxBorder), - borderRadius: BorderRadius.circular(12), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - CustomSearchBar( - controller: _searchBarController, - constraints: const BoxConstraints( - maxHeight: 45, - minHeight: 45, - ), - hintText: 'Search for players', - trailingButtonShown: true, - trailingButtonicon: Icons.add_circle, - trailingButtonEnabled: _searchBarController.text - .trim() - .isNotEmpty, - onTrailingButtonPressed: () async { - addNewPlayerFromSearch(context: context); - }, - onChanged: (value) { - setState(() { - if (value.isEmpty) { - suggestedPlayers = allPlayers.where((player) { - return !selectedPlayers.contains(player); - }).toList(); - } else { - suggestedPlayers = allPlayers.where((player) { - final bool nameMatches = player.name - .toLowerCase() - .contains(value.toLowerCase()); - final bool isNotSelected = !selectedPlayers - .contains(player); - return nameMatches && isNotSelected; - }).toList(); - } - }); - }, - ), - const SizedBox(height: 10), - Text( - 'Ausgewählte Spieler: (${selectedPlayers.length})', - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - ), - ), - const SizedBox(height: 10), - Wrap( - alignment: WrapAlignment.start, - crossAxisAlignment: WrapCrossAlignment.start, - spacing: 8.0, - runSpacing: 8.0, - children: [ - for (var player in selectedPlayers) - TextIconTile( - text: player.name, - onIconTap: () { - setState(() { - final currentSearch = _searchBarController.text - .toLowerCase(); - selectedPlayers.remove(player); - if (currentSearch.isEmpty || - player.name.toLowerCase().contains( - currentSearch, - )) { - suggestedPlayers.add(player); - suggestedPlayers.sort( - (a, b) => a.name.compareTo(b.name), - ); - } - }); - }, - ), - ], - ), - const SizedBox(height: 10), - const Text( - 'Alle Spieler:', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - ), - ), - const SizedBox(height: 10), - FutureBuilder( - future: _allPlayersFuture, - builder: - ( - BuildContext context, - AsyncSnapshot> snapshot, - ) { - if (snapshot.hasError) { - return const Center( - child: TopCenteredMessage( - icon: Icons.report, - title: 'Error', - message: 'Player data couldn\'t\nbe loaded.', - ), - ); - } - bool doneLoading = - snapshot.connectionState == - ConnectionState.done; - bool snapshotDataEmpty = - !snapshot.hasData || snapshot.data!.isEmpty; - if (doneLoading && - (snapshotDataEmpty && allPlayers.isEmpty)) { - return const Center( - child: TopCenteredMessage( - icon: Icons.info, - title: 'Info', - message: 'No players created yet.', - ), - ); - } - final bool isLoading = - snapshot.connectionState == - ConnectionState.waiting; - return Expanded( - child: Skeletonizer( - effect: PulseEffect( - from: Colors.grey[800]!, - to: Colors.grey[600]!, - duration: const Duration(milliseconds: 800), - ), - enabled: isLoading, - enableSwitchAnimation: true, - switchAnimationConfig: - const SwitchAnimationConfig( - duration: Duration(milliseconds: 200), - switchInCurve: Curves.linear, - switchOutCurve: Curves.linear, - transitionBuilder: AnimatedSwitcher - .defaultTransitionBuilder, - layoutBuilder: - AnimatedSwitcher.defaultLayoutBuilder, - ), - child: Visibility( - visible: - (suggestedPlayers.isEmpty && - allPlayers.isNotEmpty), - replacement: ListView.builder( - itemCount: suggestedPlayers.length, - itemBuilder: - (BuildContext context, int index) { - return TextIconListTile( - text: suggestedPlayers[index].name, - onPressed: () { - setState(() { - if (!selectedPlayers.contains( - suggestedPlayers[index], - )) { - selectedPlayers.add( - suggestedPlayers[index], - ); - selectedPlayers.sort( - (a, b) => a.name.compareTo( - b.name, - ), - ); - suggestedPlayers.remove( - suggestedPlayers[index], - ); - } - }); - }, - ); - }, - ), - child: TopCenteredMessage( - icon: Icons.info, - title: 'Info', - message: - (selectedPlayers.length == - allPlayers.length) - ? 'No more players to add.' - : 'No players found with that name.', - ), - ), - ), - ); - }, - ), - ], - ), + child: SelectPlayerWidget( + groupNameController: _groupNameController, + searchBarController: _searchBarController, + selectedPlayers: selectedPlayers, + onChanged: (value) { + setState(() { + selectedPlayers = [...value]; + }); + print(selectedPlayers); + }, ), ), CustomWidthButton( @@ -338,47 +123,4 @@ class _CreateGroupViewState extends State { ), ); } - - /// Adds a new player to the database from the search bar input. - /// Shows a snackbar indicating success or failure. - /// [context] - BuildContext to show the snackbar. - void addNewPlayerFromSearch({required BuildContext context}) async { - String playerName = _searchBarController.text.trim(); - Player createdPlayer = Player(name: playerName); - bool success = await db.playerDao.addPlayer(player: createdPlayer); - if (!context.mounted) return; - if (success) { - selectedPlayers.add(createdPlayer); - allPlayers.add(createdPlayer); - setState(() { - _searchBarController.clear(); - suggestedPlayers = allPlayers.where((player) { - return !selectedPlayers.contains(player); - }).toList(); - }); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - backgroundColor: CustomTheme.boxColor, - content: Center( - child: Text( - 'Successfully added player $playerName.', - style: const TextStyle(color: Colors.white), - ), - ), - ), - ); - } else { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - backgroundColor: CustomTheme.boxColor, - content: Center( - child: Text( - 'Could not add player $playerName.', - style: const TextStyle(color: Colors.white), - ), - ), - ), - ); - } - } }