4 Commits

Author SHA1 Message Date
195ebf569a Added icon as parameter for custom search bar
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Successful in 2m5s
2025-11-20 22:17:20 +01:00
eb7b247cae Fixed error adding player with empty name 2025-11-20 22:11:23 +01:00
01fede2951 Added Visibility Widget 2025-11-20 22:09:08 +01:00
b67f321276 Added name parameters and function doc 2025-11-20 22:05:44 +01:00
2 changed files with 63 additions and 52 deletions

View File

@@ -118,15 +118,16 @@ class _CreateGroupViewState extends State<CreateGroupView> {
), ),
hintText: 'Search for players', hintText: 'Search for players',
trailingButtonShown: true, trailingButtonShown: true,
trailingButtonicon: Icons.add_circle,
trailingButtonEnabled: _searchBarController.text trailingButtonEnabled: _searchBarController.text
.trim() .trim()
.isNotEmpty, .isNotEmpty,
onTrailingButtonPressed: () async { onTrailingButtonPressed: () async {
addNewPlayerFromSearch( addNewPlayerFromSearch(
context, context: context,
_searchBarController, searchBarController: _searchBarController,
db, db: db,
loadPlayerList, loadPlayerList: loadPlayerList,
); );
}, },
onChanged: (value) { onChanged: (value) {
@@ -246,46 +247,48 @@ class _CreateGroupViewState extends State<CreateGroupView> {
layoutBuilder: layoutBuilder:
AnimatedSwitcher.defaultLayoutBuilder, AnimatedSwitcher.defaultLayoutBuilder,
), ),
child: child: Visibility(
(suggestedPlayers.isEmpty && visible:
allPlayers.isNotEmpty) (suggestedPlayers.isEmpty &&
? TopCenteredMessage( allPlayers.isNotEmpty),
icon: Icons.info, replacement: ListView.builder(
title: 'Info', itemCount: suggestedPlayers.length,
message: itemBuilder:
(selectedPlayers.length == (BuildContext context, int index) {
allPlayers.length) return TextIconListTile(
? 'No more players to add.' text: suggestedPlayers[index].name,
: 'No players found with that name.', onPressed: () {
) setState(() {
: ListView.builder( if (!selectedPlayers.contains(
itemCount: suggestedPlayers.length, suggestedPlayers[index],
itemBuilder: )) {
(BuildContext context, int index) { selectedPlayers.add(
return TextIconListTile( suggestedPlayers[index],
text: suggestedPlayers[index] );
.name, selectedPlayers.sort(
onPressed: () { (a, b) => a.name.compareTo(
setState(() { b.name,
if (!selectedPlayers.contains( ),
suggestedPlayers[index], );
)) { suggestedPlayers.remove(
selectedPlayers.add( suggestedPlayers[index],
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.',
),
),
), ),
); );
}, },
@@ -338,12 +341,18 @@ class _CreateGroupViewState extends State<CreateGroupView> {
} }
} }
void addNewPlayerFromSearch( /// Adds a new player to the database from the search bar input.
context, /// Shows a snackbar indicating success or failure.
searchBarController, /// [context] - BuildContext to show the snackbar.
db, /// [searchBarController] - TextEditingController of the search bar.
loadPlayerList, /// [db] - AppDatabase instance to interact with the database.
) async { /// [loadPlayerList] - Function to reload the player list after adding.
void addNewPlayerFromSearch({
required BuildContext context,
required TextEditingController searchBarController,
required AppDatabase db,
required Function loadPlayerList,
}) async {
String playerName = searchBarController.text.trim(); String playerName = searchBarController.text.trim();
bool success = await db.playerDao.addPlayer(player: Player(name: playerName)); bool success = await db.playerDao.addPlayer(player: Player(name: playerName));
if (!context.mounted) return; if (!context.mounted) return;

View File

@@ -6,15 +6,17 @@ class CustomSearchBar extends StatelessWidget {
final String hintText; final String hintText;
final ValueChanged<String>? onChanged; final ValueChanged<String>? onChanged;
final BoxConstraints? constraints; final BoxConstraints? constraints;
final bool trailingButtonEnabled;
final bool trailingButtonShown; final bool trailingButtonShown;
final bool trailingButtonEnabled;
final VoidCallback? onTrailingButtonPressed; final VoidCallback? onTrailingButtonPressed;
final IconData trailingButtonicon;
const CustomSearchBar({ const CustomSearchBar({
super.key, super.key,
required this.controller, required this.controller,
required this.hintText, required this.hintText,
this.trailingButtonShown = false, this.trailingButtonShown = false,
this.trailingButtonicon = Icons.clear,
this.trailingButtonEnabled = true, this.trailingButtonEnabled = true,
this.onTrailingButtonPressed, this.onTrailingButtonPressed,
this.onChanged, this.onChanged,
@@ -35,9 +37,9 @@ class CustomSearchBar extends StatelessWidget {
Visibility( Visibility(
visible: trailingButtonShown, visible: trailingButtonShown,
child: GestureDetector( child: GestureDetector(
onTap: onTrailingButtonPressed, onTap: trailingButtonEnabled ? onTrailingButtonPressed : null,
child: Icon( child: Icon(
Icons.add_circle, trailingButtonicon,
color: trailingButtonEnabled color: trailingButtonEnabled
? null ? null
: Colors.grey.withValues(alpha: 0.2), : Colors.grey.withValues(alpha: 0.2),