Implemented new live edit mode

This commit is contained in:
2026-05-04 15:00:00 +02:00
parent a5f00f16ab
commit ea5577c288
3 changed files with 241 additions and 96 deletions

View File

@@ -8,8 +8,9 @@ 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/l10n/generated/app_localizations.dart'; import 'package:tallee/l10n/generated/app_localizations.dart';
import 'package:tallee/presentation/widgets/buttons/custom_width_button.dart'; import 'package:tallee/presentation/widgets/buttons/custom_width_button.dart';
import 'package:tallee/presentation/widgets/tiles/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/score_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';
class MatchResultView extends StatefulWidget { class MatchResultView extends StatefulWidget {
/// A view that allows selecting and saving the winner of a match /// A view that allows selecting and saving the winner of a match
@@ -30,6 +31,8 @@ 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;
/// List of all players who participated in the match /// List of all players who participated in the match
@@ -88,7 +91,16 @@ class _MatchResultViewState extends State<MatchResultView> {
return Scaffold( return Scaffold(
backgroundColor: CustomTheme.backgroundColor, backgroundColor: CustomTheme.backgroundColor,
appBar: AppBar( appBar: AppBar(
leading: IconButton( leading: isLiveEditMode
? IconButton(
icon: const Icon(Icons.arrow_back_ios),
onPressed: () {
setState(() {
isLiveEditMode = false;
});
},
)
: IconButton(
icon: const Icon(Icons.close), icon: const Icon(Icons.close),
onPressed: () { onPressed: () {
widget.onWinnerChanged?.call(); widget.onWinnerChanged?.call();
@@ -101,7 +113,22 @@ class _MatchResultViewState extends State<MatchResultView> {
child: Column( child: Column(
children: [ children: [
Expanded( Expanded(
child: Container( child: isLiveEditMode && rulesetSupportsScoreEntry()
? 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,
);
},
)
: Container(
margin: const EdgeInsets.symmetric( margin: const EdgeInsets.symmetric(
horizontal: 12, horizontal: 12,
vertical: 10, vertical: 10,
@@ -169,9 +196,12 @@ class _MatchResultViewState extends State<MatchResultView> {
controller: controller[index], controller: controller[index],
); );
}, },
separatorBuilder: (BuildContext context, int index) { separatorBuilder:
(BuildContext context, int index) {
return const Padding( return const Padding(
padding: EdgeInsets.symmetric(vertical: 8.0), padding: EdgeInsets.symmetric(
vertical: 8.0,
),
child: Divider(indent: 20), child: Divider(indent: 20),
); );
}, },
@@ -181,6 +211,22 @@ class _MatchResultViewState extends State<MatchResultView> {
), ),
), ),
), ),
if (!isLiveEditMode) ...[
if (rulesetSupportsScoreEntry())
// Button to switch to live edit mode
...[
CustomWidthButton(
text: 'Live-Edit Modus',
sizeRelativeToWidth: 0.95,
buttonType: ButtonType.secondary,
onPressed: () => setState(() {
isLiveEditMode = true;
}),
),
const SizedBox(height: 10),
],
// Save Changes Button
CustomWidthButton( CustomWidthButton(
text: loc.save_changes, text: loc.save_changes,
sizeRelativeToWidth: 0.95, sizeRelativeToWidth: 0.95,
@@ -198,6 +244,7 @@ class _MatchResultViewState extends State<MatchResultView> {
: null, : null,
), ),
], ],
],
), ),
), ),
); );

View File

@@ -0,0 +1,97 @@
import 'package:flutter/material.dart';
import 'package:flutter_numeric_text/flutter_numeric_text.dart';
import 'package:tallee/core/custom_theme.dart';
import 'package:tallee/presentation/widgets/buttons/main_menu_button.dart';
class LiveEditListTile extends StatefulWidget {
const LiveEditListTile({
super.key,
required this.title,
required this.value,
this.onChanged,
});
final String title;
final int value;
final void Function(int newValue)? onChanged;
@override
State<LiveEditListTile> createState() => _LiveEditListTileState();
}
class _LiveEditListTileState extends State<LiveEditListTile> {
int _score = 0;
final int maxScore = 9999;
final int minScore = -9999;
@override
void initState() {
_score = widget.value;
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 10),
margin: const EdgeInsets.symmetric(vertical: 12, horizontal: 8),
decoration: CustomTheme.standardBoxDecoration,
child: Column(
children: [
Text(
widget.title,
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
),
Padding(
padding: const EdgeInsets.only(left: 20, right: 20, bottom: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MainMenuButton(
onPressed: () => _score > minScore
? {
setState(() {
_score--;
if (widget.onChanged != null) {
widget.onChanged!(_score);
}
}),
}
: null,
icon: Icons.remove_rounded,
),
SizedBox(
width: 150,
child: NumericText(
_score.toString(),
maxLines: 1,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 48,
fontWeight: FontWeight.w600,
),
),
),
MainMenuButton(
onPressed: () => _score < maxScore
? {
setState(() {
_score++;
if (widget.onChanged != null) {
widget.onChanged!(_score);
}
}),
}
: null,
icon: Icons.add_rounded,
),
],
),
),
],
),
);
}
}

View File

@@ -17,6 +17,7 @@ dependencies:
sdk: flutter sdk: flutter
flutter_localizations: flutter_localizations:
sdk: flutter sdk: flutter
flutter_numeric_text: ^1.3.3
fluttericon: ^2.0.0 fluttericon: ^2.0.0
font_awesome_flutter: ^11.0.0 font_awesome_flutter: ^11.0.0
intl: any intl: any