add player change callbacks and improve player detail view
This commit is contained in:
@@ -169,15 +169,18 @@ class PlayerDao extends DatabaseAccessor<AppDatabase> with _$PlayerDaoMixin {
|
|||||||
.map((row) => row.name)
|
.map((row) => row.name)
|
||||||
.getSingleOrNull() ??
|
.getSingleOrNull() ??
|
||||||
'';
|
'';
|
||||||
final previousNameCount = await getNameCount(name: previousPlayerName);
|
final previousNameCount = (await getNameCount(name: previousPlayerName))!;
|
||||||
|
print('previousNameCount: $previousNameCount');
|
||||||
|
|
||||||
|
// Update name count for the new name
|
||||||
|
final count = await calculateNameCount(name: name);
|
||||||
|
print('count: $count');
|
||||||
|
|
||||||
final rowsAffected =
|
final rowsAffected =
|
||||||
await (update(playerTable)..where((p) => p.id.equals(playerId))).write(
|
await (update(playerTable)..where((p) => p.id.equals(playerId))).write(
|
||||||
PlayerTableCompanion(name: Value(name)),
|
PlayerTableCompanion(name: Value(name)),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Update name count for the new name
|
|
||||||
final count = await calculateNameCount(name: name);
|
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
await (update(playerTable)..where((p) => p.name.equals(name))).write(
|
await (update(playerTable)..where((p) => p.name.equals(name))).write(
|
||||||
PlayerTableCompanion(nameCount: Value(count)),
|
PlayerTableCompanion(nameCount: Value(count)),
|
||||||
@@ -226,10 +229,10 @@ class PlayerDao extends DatabaseAccessor<AppDatabase> with _$PlayerDaoMixin {
|
|||||||
/* Name count management */
|
/* Name count management */
|
||||||
|
|
||||||
/// Retrieves the count of players with the given [name].
|
/// Retrieves the count of players with the given [name].
|
||||||
Future<int> getNameCount({required String name}) async {
|
Future<int?> getNameCount({required String name}) async {
|
||||||
final query = select(playerTable)..where((p) => p.name.equals(name));
|
final query = select(playerTable)..where((p) => p.name.equals(name));
|
||||||
final result = await query.get();
|
final result = await query.get();
|
||||||
return result.length;
|
return result.isEmpty ? null : result.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates the nameCount for the player with the given [playerId] to [nameCount].
|
/// Updates the nameCount for the player with the given [playerId] to [nameCount].
|
||||||
@@ -269,20 +272,19 @@ class PlayerDao extends DatabaseAccessor<AppDatabase> with _$PlayerDaoMixin {
|
|||||||
final count = await getNameCount(name: name);
|
final count = await getNameCount(name: name);
|
||||||
final int nameCount;
|
final int nameCount;
|
||||||
|
|
||||||
if (count == 1) {
|
if (count == null) {
|
||||||
|
// If no other players exist with the same name, set nameCount to 0
|
||||||
|
nameCount = 0;
|
||||||
|
} else if (count == 0) {
|
||||||
// If one other player exists with the same name, initialize the nameCount
|
// If one other player exists with the same name, initialize the nameCount
|
||||||
await initializeNameCount(name: name);
|
await initializeNameCount(name: name);
|
||||||
// And for the new player, set nameCount to 2
|
// And for the new player, set nameCount to 2
|
||||||
nameCount = 2;
|
nameCount = 2;
|
||||||
} else if (count > 1) {
|
} else {
|
||||||
// If more than one player exists with the same name, just increment
|
// If more than one player exists with the same name, just increment
|
||||||
// the nameCount for the new player
|
// the nameCount for the new player
|
||||||
nameCount = count + 1;
|
nameCount = count + 1;
|
||||||
} else {
|
|
||||||
// If no other players exist with the same name, set nameCount to 0
|
|
||||||
nameCount = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nameCount;
|
return nameCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ class _GroupViewState extends State<GroupView> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
return GroupTile(
|
return GroupTile(
|
||||||
|
onPlayerChanged: loadGroups,
|
||||||
group: groups[index],
|
group: groups[index],
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await Navigator.push(
|
await Navigator.push(
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ class _MatchViewState extends State<MatchView> {
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 12.0),
|
padding: const EdgeInsets.only(bottom: 12.0),
|
||||||
child: MatchTile(
|
child: MatchTile(
|
||||||
|
onPlayerEdited: loadMatches,
|
||||||
width: MediaQuery.sizeOf(context).width * 0.95,
|
width: MediaQuery.sizeOf(context).width * 0.95,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import 'package:tallee/presentation/widgets/buttons/main_menu_button.dart';
|
|||||||
import 'package:tallee/presentation/widgets/colored_icon_container.dart';
|
import 'package:tallee/presentation/widgets/colored_icon_container.dart';
|
||||||
import 'package:tallee/presentation/widgets/dialog/custom_alert_dialog.dart';
|
import 'package:tallee/presentation/widgets/dialog/custom_alert_dialog.dart';
|
||||||
import 'package:tallee/presentation/widgets/dialog/custom_dialog_action.dart';
|
import 'package:tallee/presentation/widgets/dialog/custom_dialog_action.dart';
|
||||||
|
import 'package:tallee/presentation/widgets/text_input/text_input_field.dart';
|
||||||
import 'package:tallee/presentation/widgets/tiles/info_tile.dart';
|
import 'package:tallee/presentation/widgets/tiles/info_tile.dart';
|
||||||
import 'package:tallee/presentation/widgets/tiles/text_icon_tile.dart';
|
import 'package:tallee/presentation/widgets/tiles/text_icon_tile.dart';
|
||||||
|
|
||||||
@@ -37,7 +38,8 @@ class PlayerDetailView extends StatefulWidget {
|
|||||||
|
|
||||||
class _PlayerDetailViewState extends State<PlayerDetailView> {
|
class _PlayerDetailViewState extends State<PlayerDetailView> {
|
||||||
late final AppDatabase db;
|
late final AppDatabase db;
|
||||||
|
late Player _player;
|
||||||
|
late String playerNameCount;
|
||||||
bool isLoading = true;
|
bool isLoading = true;
|
||||||
|
|
||||||
/// Total matches played by this player
|
/// Total matches played by this player
|
||||||
@@ -68,6 +70,7 @@ class _PlayerDetailViewState extends State<PlayerDetailView> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
_player = widget.player;
|
||||||
db = Provider.of<AppDatabase>(context, listen: false);
|
db = Provider.of<AppDatabase>(context, listen: false);
|
||||||
_loadData();
|
_loadData();
|
||||||
}
|
}
|
||||||
@@ -75,6 +78,7 @@ class _PlayerDetailViewState extends State<PlayerDetailView> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final loc = AppLocalizations.of(context);
|
final loc = AppLocalizations.of(context);
|
||||||
|
playerNameCount = getNameCountText(_player);
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
@@ -132,8 +136,11 @@ class _PlayerDetailViewState extends State<PlayerDetailView> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
Text(
|
Text(
|
||||||
widget.player.name + getNameCountText(widget.player),
|
_player.name,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 28,
|
fontSize: 28,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
@@ -141,9 +148,20 @@ class _PlayerDetailViewState extends State<PlayerDetailView> {
|
|||||||
),
|
),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
|
Text(
|
||||||
|
playerNameCount,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 28,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: CustomTheme.textColor.withAlpha(120),
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
const SizedBox(height: 5),
|
const SizedBox(height: 5),
|
||||||
Text(
|
Text(
|
||||||
'${loc.created_on} ${DateFormat.yMMMd(Localizations.localeOf(context).toString()).format(widget.player.createdAt)}',
|
'${loc.created_on} ${DateFormat.yMMMd(Localizations.localeOf(context).toString()).format(_player.createdAt)}',
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: CustomTheme.textColor,
|
color: CustomTheme.textColor,
|
||||||
@@ -152,8 +170,8 @@ class _PlayerDetailViewState extends State<PlayerDetailView> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
InfoTile(
|
InfoTile(
|
||||||
title: "Matches played in (${totalMatches})",
|
title: "Matches part of (${totalMatches})",
|
||||||
icon: Icons.people,
|
icon: Icons.sports_esports,
|
||||||
horizontalAlignment: CrossAxisAlignment.start,
|
horizontalAlignment: CrossAxisAlignment.start,
|
||||||
content: Wrap(
|
content: Wrap(
|
||||||
alignment: WrapAlignment.start,
|
alignment: WrapAlignment.start,
|
||||||
@@ -209,8 +227,48 @@ class _PlayerDetailViewState extends State<PlayerDetailView> {
|
|||||||
text: "Edit player",
|
text: "Edit player",
|
||||||
icon: Icons.edit,
|
icon: Icons.edit,
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
//TODO: update player name in popup
|
final controller = TextEditingController(text: _player.name);
|
||||||
widget.callback();
|
showDialog<bool>(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => CustomAlertDialog(
|
||||||
|
title: "Change Name",
|
||||||
|
content: TextInputField(
|
||||||
|
controller: controller,
|
||||||
|
hintText: 'Set a player name',
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
CustomDialogAction(
|
||||||
|
onPressed: () => Navigator.of(context).pop(true),
|
||||||
|
text: "Confirm",
|
||||||
|
),
|
||||||
|
CustomDialogAction(
|
||||||
|
onPressed: () => Navigator.of(context).pop(false),
|
||||||
|
buttonType: ButtonType.secondary,
|
||||||
|
text: loc.cancel,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
).then((confirmed) async {
|
||||||
|
if (confirmed! && context.mounted) {
|
||||||
|
if (controller.text != _player.name) {
|
||||||
|
await db.playerDao.updatePlayerName(
|
||||||
|
playerId: _player.id,
|
||||||
|
name: controller.text,
|
||||||
|
);
|
||||||
|
widget.callback.call();
|
||||||
|
setState(() {
|
||||||
|
_player = Player(
|
||||||
|
name: controller.text,
|
||||||
|
createdAt: _player.createdAt,
|
||||||
|
id: _player.id,
|
||||||
|
nameCount: _player.nameCount,
|
||||||
|
description: _player.description,
|
||||||
|
);
|
||||||
|
playerNameCount = getNameCountText(_player);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -224,17 +282,19 @@ class _PlayerDetailViewState extends State<PlayerDetailView> {
|
|||||||
Future<void> _loadData() async {
|
Future<void> _loadData() async {
|
||||||
isLoading = true;
|
isLoading = true;
|
||||||
final fetchedMatches = await db.matchDao.getMatchesByPlayer(
|
final fetchedMatches = await db.matchDao.getMatchesByPlayer(
|
||||||
playerId: widget.player.id,
|
playerId: _player.id,
|
||||||
);
|
);
|
||||||
final fetchedGroups = await db.groupDao.getGroupsByPlayer(
|
final fetchedGroups = await db.groupDao.getGroupsByPlayer(
|
||||||
playerId: widget.player.id,
|
playerId: _player.id,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!mounted) return;
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
playerMatches = fetchedMatches;
|
playerMatches = fetchedMatches;
|
||||||
totalMatches = fetchedMatches.length;
|
totalMatches = fetchedMatches.length;
|
||||||
matchesWon = fetchedMatches
|
matchesWon = fetchedMatches
|
||||||
.where((match) => match.mvp.any((mvp) => mvp.id == widget.player.id))
|
.where((match) => match.mvp.any((mvp) => mvp.id == _player.id))
|
||||||
.length;
|
.length;
|
||||||
playerGroups = fetchedGroups;
|
playerGroups = fetchedGroups;
|
||||||
totalGroups = fetchedGroups.length;
|
totalGroups = fetchedGroups.length;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ class GroupTile extends StatefulWidget {
|
|||||||
required this.group,
|
required this.group,
|
||||||
this.isHighlighted = false,
|
this.isHighlighted = false,
|
||||||
this.onTap,
|
this.onTap,
|
||||||
|
this.onPlayerChanged,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// The group data to be displayed.
|
/// The group data to be displayed.
|
||||||
@@ -28,6 +29,9 @@ class GroupTile extends StatefulWidget {
|
|||||||
/// Callback function to be executed when the tile is tapped.
|
/// Callback function to be executed when the tile is tapped.
|
||||||
final VoidCallback? onTap;
|
final VoidCallback? onTap;
|
||||||
|
|
||||||
|
/// Callback function to be executed when the players in the group are changed.
|
||||||
|
final VoidCallback? onPlayerChanged;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<GroupTile> createState() => _GroupTileState();
|
State<GroupTile> createState() => _GroupTileState();
|
||||||
}
|
}
|
||||||
@@ -101,7 +105,7 @@ class _GroupTileState extends State<GroupTile> {
|
|||||||
builder: (context) => PlayerDetailView(
|
builder: (context) => PlayerDetailView(
|
||||||
player: member,
|
player: member,
|
||||||
callback: () {
|
callback: () {
|
||||||
//TODO: implement callback
|
widget.onPlayerChanged?.call();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ class MatchTile extends StatefulWidget {
|
|||||||
required this.onTap,
|
required this.onTap,
|
||||||
this.width,
|
this.width,
|
||||||
this.compact = false,
|
this.compact = false,
|
||||||
|
this.onPlayerEdited,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// The match data to be displayed.
|
/// The match data to be displayed.
|
||||||
@@ -34,6 +35,9 @@ class MatchTile extends StatefulWidget {
|
|||||||
/// The callback invoked when the tile is tapped.
|
/// The callback invoked when the tile is tapped.
|
||||||
final VoidCallback onTap;
|
final VoidCallback onTap;
|
||||||
|
|
||||||
|
/// The callback invoked when the players are edited
|
||||||
|
final VoidCallback? onPlayerEdited;
|
||||||
|
|
||||||
/// Optional width for the tile.
|
/// Optional width for the tile.
|
||||||
final double? width;
|
final double? width;
|
||||||
|
|
||||||
@@ -233,7 +237,7 @@ class _MatchTileState extends State<MatchTile> {
|
|||||||
builder: (context) => PlayerDetailView(
|
builder: (context) => PlayerDetailView(
|
||||||
player: player,
|
player: player,
|
||||||
callback: () {
|
callback: () {
|
||||||
//TODO: implement callback
|
widget.onPlayerEdited?.call();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user