feat: Implemented LiveEditView
This commit is contained in:
@@ -0,0 +1,89 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:tallee/data/models/match.dart';
|
||||||
|
import 'package:tallee/data/models/player.dart';
|
||||||
|
import 'package:tallee/data/models/team.dart';
|
||||||
|
import 'package:tallee/presentation/widgets/buttons/haptic_icon_button.dart';
|
||||||
|
import 'package:tallee/presentation/widgets/tiles/match_result_view/live_edit_list_tile.dart';
|
||||||
|
|
||||||
|
class LiveEditView extends StatefulWidget {
|
||||||
|
const LiveEditView({super.key, required this.match});
|
||||||
|
final Match match;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<LiveEditView> createState() => _LiveEditViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _LiveEditViewState extends State<LiveEditView> {
|
||||||
|
List<Team> get allTeams =>
|
||||||
|
(widget.match.teams ?? [])..sort((a, b) => a.name.compareTo(b.name));
|
||||||
|
List<Player> get allPlayers =>
|
||||||
|
widget.match.players..sort((a, b) => a.name.compareTo(b.name));
|
||||||
|
List<int> scores = [];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
if (widget.match.isTeamMatch) {
|
||||||
|
scores = List.generate(
|
||||||
|
allTeams.length,
|
||||||
|
(index) => allTeams[index].score ?? 0,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
scores = List.generate(
|
||||||
|
allPlayers.length,
|
||||||
|
(index) => widget.match.scores[allPlayers[index].id]?.score ?? 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text(widget.match.name),
|
||||||
|
leading: HapticIconButton(
|
||||||
|
onPressed: () => Navigator.pop(context, scores),
|
||||||
|
icon: const Icon(Icons.close),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
Expanded(child: buildLiveEditWidget(widget.match.isTeamMatch)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildLiveEditWidget(bool isTeamMatch) {
|
||||||
|
if (isTeamMatch) {
|
||||||
|
return ListView.builder(
|
||||||
|
itemCount: allTeams.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return LiveEditListTile(
|
||||||
|
title: allTeams[index].name,
|
||||||
|
onChanged: (value) {
|
||||||
|
scores[index] = value;
|
||||||
|
},
|
||||||
|
value: scores[index],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return ListView.builder(
|
||||||
|
itemCount: allPlayers.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return LiveEditListTile(
|
||||||
|
title: allPlayers[index].name,
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
scores[index] = value;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
value: scores[index],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ import 'dart:math';
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:tallee/core/adaptive_page_route.dart';
|
||||||
import 'package:tallee/core/common.dart';
|
import 'package:tallee/core/common.dart';
|
||||||
import 'package:tallee/core/custom_theme.dart';
|
import 'package:tallee/core/custom_theme.dart';
|
||||||
import 'package:tallee/core/enums.dart';
|
import 'package:tallee/core/enums.dart';
|
||||||
@@ -11,11 +12,11 @@ import 'package:tallee/data/models/player.dart';
|
|||||||
import 'package:tallee/data/models/score_entry.dart';
|
import 'package:tallee/data/models/score_entry.dart';
|
||||||
import 'package:tallee/data/models/team.dart';
|
import 'package:tallee/data/models/team.dart';
|
||||||
import 'package:tallee/l10n/generated/app_localizations.dart';
|
import 'package:tallee/l10n/generated/app_localizations.dart';
|
||||||
|
import 'package:tallee/presentation/views/main_menu/match_view/create_match/match_result/live_edit_view.dart';
|
||||||
import 'package:tallee/presentation/widgets/buttons/animated_dialog_button.dart';
|
import 'package:tallee/presentation/widgets/buttons/animated_dialog_button.dart';
|
||||||
import 'package:tallee/presentation/widgets/buttons/haptic_icon_button.dart';
|
import 'package:tallee/presentation/widgets/buttons/haptic_icon_button.dart';
|
||||||
import 'package:tallee/presentation/widgets/tiles/match_result_view/custom_checkbox_list_tile.dart';
|
import 'package:tallee/presentation/widgets/tiles/match_result_view/custom_checkbox_list_tile.dart';
|
||||||
import 'package:tallee/presentation/widgets/tiles/match_result_view/custom_radio_list_tile.dart';
|
import 'package:tallee/presentation/widgets/tiles/match_result_view/custom_radio_list_tile.dart';
|
||||||
import 'package:tallee/presentation/widgets/tiles/match_result_view/live_edit_list_tile.dart';
|
|
||||||
import 'package:tallee/presentation/widgets/tiles/match_result_view/score_list_tile.dart';
|
import 'package:tallee/presentation/widgets/tiles/match_result_view/score_list_tile.dart';
|
||||||
import 'package:tallee/presentation/widgets/tiles/text_icon_list_tile.dart';
|
import 'package:tallee/presentation/widgets/tiles/text_icon_list_tile.dart';
|
||||||
|
|
||||||
@@ -38,8 +39,6 @@ class MatchResultView extends StatefulWidget {
|
|||||||
class _MatchResultViewState extends State<MatchResultView> {
|
class _MatchResultViewState extends State<MatchResultView> {
|
||||||
late final AppDatabase db;
|
late final AppDatabase db;
|
||||||
|
|
||||||
bool isLiveEditMode = false;
|
|
||||||
|
|
||||||
late final Ruleset ruleset;
|
late final Ruleset ruleset;
|
||||||
|
|
||||||
late final List<Player> allPlayers;
|
late final List<Player> allPlayers;
|
||||||
@@ -92,33 +91,20 @@ class _MatchResultViewState extends State<MatchResultView> {
|
|||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
automaticallyImplyLeading: true,
|
automaticallyImplyLeading: true,
|
||||||
leading: HapticIconButton(
|
leading: HapticIconButton(
|
||||||
icon: isLiveEditMode
|
icon: const Icon(Icons.close),
|
||||||
? const Icon(Icons.arrow_back_ios)
|
onPressed: () => {
|
||||||
: const Icon(Icons.close),
|
widget.onWinnerChanged?.call(),
|
||||||
onPressed: isLiveEditMode
|
Navigator.pop(context),
|
||||||
? () => setState(() {
|
},
|
||||||
isLiveEditMode = false;
|
|
||||||
})
|
|
||||||
: () => {widget.onWinnerChanged?.call(), Navigator.pop(context)},
|
|
||||||
),
|
),
|
||||||
title: Text(widget.match.name),
|
title: Text(widget.match.name),
|
||||||
),
|
),
|
||||||
body: Column(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: isLiveEditMode
|
child: Container(
|
||||||
// Live Edit Mode
|
margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
||||||
? buildLiveEditWidet(isTeamMatch)
|
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 10),
|
||||||
// Normal Container
|
|
||||||
: Container(
|
|
||||||
margin: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 12,
|
|
||||||
vertical: 10,
|
|
||||||
),
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
vertical: 10,
|
|
||||||
horizontal: 10,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: CustomTheme.boxColor,
|
color: CustomTheme.boxColor,
|
||||||
border: Border.all(color: CustomTheme.boxBorderColor),
|
border: Border.all(color: CustomTheme.boxBorderColor),
|
||||||
@@ -141,14 +127,10 @@ class _MatchResultViewState extends State<MatchResultView> {
|
|||||||
if (rulesetSupportsPlayerSelection())
|
if (rulesetSupportsPlayerSelection())
|
||||||
if (ruleset == Ruleset.multipleWinners)
|
if (ruleset == Ruleset.multipleWinners)
|
||||||
Expanded(
|
Expanded(
|
||||||
child: buildMultipleWinnerSelectionWidget(
|
child: buildMultipleWinnerSelectionWidget(isTeamMatch),
|
||||||
isTeamMatch,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
Expanded(
|
Expanded(child: buildPlayerSelectionWidget(isTeamMatch)),
|
||||||
child: buildPlayerSelectionWidget(isTeamMatch),
|
|
||||||
),
|
|
||||||
|
|
||||||
// Show score entry
|
// Show score entry
|
||||||
if (rulesetSupportsScoreEntry())
|
if (rulesetSupportsScoreEntry())
|
||||||
@@ -162,14 +144,13 @@ class _MatchResultViewState extends State<MatchResultView> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
if (!isLiveEditMode) ...[
|
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(12, 0, 12, 20),
|
padding: const EdgeInsets.fromLTRB(12, 0, 12, 20),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
|
// Live Edit Mode Button
|
||||||
if (rulesetSupportsScoreEntry()) ...[
|
if (rulesetSupportsScoreEntry()) ...[
|
||||||
// Button to switch to live edit mode
|
|
||||||
AnimatedDialogButton(
|
AnimatedDialogButton(
|
||||||
buttonConstraints: const BoxConstraints(
|
buttonConstraints: const BoxConstraints(
|
||||||
minWidth: double.infinity,
|
minWidth: double.infinity,
|
||||||
@@ -177,9 +158,23 @@ class _MatchResultViewState extends State<MatchResultView> {
|
|||||||
),
|
),
|
||||||
buttonText: loc.live_edit_mode,
|
buttonText: loc.live_edit_mode,
|
||||||
buttonType: ButtonType.secondary,
|
buttonType: ButtonType.secondary,
|
||||||
onPressed: () => setState(() {
|
onPressed: () =>
|
||||||
isLiveEditMode = !isLiveEditMode;
|
Navigator.push(
|
||||||
}),
|
context,
|
||||||
|
adaptivePageRoute(
|
||||||
|
fullscreenDialog: true,
|
||||||
|
builder: (context) =>
|
||||||
|
LiveEditView(match: widget.match),
|
||||||
|
),
|
||||||
|
).then(
|
||||||
|
(scores) => {
|
||||||
|
if (scores != null)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < scores.length; i++)
|
||||||
|
{controller[i].text = scores[i].toString()},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
||||||
@@ -207,7 +202,6 @@ class _MatchResultViewState extends State<MatchResultView> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -847,38 +841,4 @@ class _MatchResultViewState extends State<MatchResultView> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildLiveEditWidet(bool isTeamMatch) {
|
|
||||||
if (isTeamMatch) {
|
|
||||||
return ListView.builder(
|
|
||||||
itemCount: allTeams.length,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
return LiveEditListTile(
|
|
||||||
title: allTeams[index].name,
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {
|
|
||||||
controller[index].text = value.toString();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
value: int.tryParse(controller[index].text) ?? 0,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return ListView.builder(
|
|
||||||
itemCount: allPlayers.length,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
return LiveEditListTile(
|
|
||||||
title: allPlayers[index].name,
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {
|
|
||||||
controller[index].text = value.toString();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
value: int.tryParse(controller[index].text) ?? 0,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: tallee
|
name: tallee
|
||||||
description: "Tracking App for Card Games"
|
description: "Tracking App for Card Games"
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
version: 0.0.30+330
|
version: 0.0.30+331
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.8.1
|
sdk: ^3.8.1
|
||||||
|
|||||||
Reference in New Issue
Block a user