Skip to content

Commit

Permalink
feat: Bleeding Injury Duration (closes #58)
Browse files Browse the repository at this point in the history
  • Loading branch information
Gustl22 committed Oct 18, 2024
1 parent 6abdbdb commit 34a462d
Show file tree
Hide file tree
Showing 18 changed files with 260 additions and 101 deletions.
2 changes: 2 additions & 0 deletions wrestling_scoreboard_client/lib/l10n/app_de.arb
Original file line number Diff line number Diff line change
Expand Up @@ -223,12 +223,14 @@
"activityTimeAbbr": "AZ",
"injuryTime": "Verletzungszeit",
"injuryTimeShort": "VZ",
"bleedingInjuryTimeShort": "BZ",
"duration": "Dauer",
"durations": "Zeiten",
"periodDuration": "Dauer des Kampfabschnittes",
"breakDuration": "Dauer der Pause",
"activityDuration": "Dauer der Aktivitätszeit",
"injuryDuration": "Dauer der Verletzungszeit",
"bleedingInjuryDuration": "Dauer der Verletzungszeit mit Blut",
"periodCount": "Anzahl der Kampfabschnitte",

"referee": "Kampfrichter",
Expand Down
2 changes: 2 additions & 0 deletions wrestling_scoreboard_client/lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -226,12 +226,14 @@
"activityTimeAbbr": "AT",
"injuryTime": "injury time",
"injuryTimeShort": "IT",
"bleedingInjuryTimeShort": "BT",
"duration": "Duration",
"durations": "Durations",
"periodDuration": "Period duration",
"breakDuration": "Break duration",
"activityDuration": "Activity duration",
"injuryDuration": "Injury duration",
"bleedingInjuryDuration": "Bleeding injury duration",
"periodCount": "Number of periods",

"referee": "Referee",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import 'package:wrestling_scoreboard_common/common.dart';
extension BoutConfigLocalization on BoutConfig {
String localize(BuildContext context) {
final localizations = AppLocalizations.of(context)!;
return '# $id | ${localizations.periodCount}: $periodCount, ${localizations.periodDuration}: ${periodDuration.formatMinutesAndSeconds()}, ${localizations.injuryDuration}: ${injuryDuration.formatMinutesAndSeconds()}, ${localizations.activityDuration}: ${activityDuration.formatMinutesAndSeconds()}, ${localizations.breakDuration}: ${breakDuration.formatMinutesAndSeconds()}';
return '# $id | ${localizations.periodCount}: $periodCount, '
'${localizations.periodDuration}: ${periodDuration.formatMinutesAndSeconds()}, '
'${localizations.injuryDuration}: ${injuryDuration?.formatMinutesAndSeconds() ?? '-'}, '
'${localizations.activityDuration}: ${activityDuration?.formatMinutesAndSeconds() ?? '-'}, '
'${localizations.breakDuration}: ${breakDuration.formatMinutesAndSeconds()}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import 'package:wrestling_scoreboard_common/common.dart';
class ParticipantStateModel {
ParticipantState? pStatus;
ObservableStopwatch injuryStopwatch = ObservableStopwatch();
ObservableStopwatch bleedingInjuryStopwatch = ObservableStopwatch();
ObservableStopwatch? activityStopwatch;
bool isInjury = false;
bool isBleedingInjury = false;

ParticipantStateModel(this.pStatus);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import 'package:wrestling_scoreboard_common/common.dart';

class BoutActionControls extends StatelessWidget {
final BoutRole role;
final BoutConfig boutConfig;
final Function(BoutScreenActionIntent)? callback;

const BoutActionControls(this.role, this.callback, {super.key});
const BoutActionControls(this.role, this.boutConfig, this.callback, {super.key});

@override
Widget build(BuildContext context) {
Expand Down Expand Up @@ -54,17 +55,26 @@ class BoutActionControls extends StatelessWidget {
prepareCallback(const BoutScreenActionIntent.redDismissal(), const BoutScreenActionIntent.blueDismissal()),
color,
),
displayActionControl(
AppLocalizations.of(context)!.activityTimeAbbr, // AZ Activity Time, Aktivitätszeit
prepareCallback(
const BoutScreenActionIntent.redActivityTime(), const BoutScreenActionIntent.blueActivityTime()),
color,
),
displayActionControl(
AppLocalizations.of(context)!.injuryTimeShort, // VZ Injury Time, Verletzungszeit
prepareCallback(const BoutScreenActionIntent.redInjuryTime(), const BoutScreenActionIntent.blueInjuryTime()),
color,
),
if (boutConfig.activityDuration != null)
displayActionControl(
AppLocalizations.of(context)!.activityTimeAbbr, // AZ Activity Time, Aktivitätszeit
prepareCallback(
const BoutScreenActionIntent.redActivityTime(), const BoutScreenActionIntent.blueActivityTime()),
color,
),
if (boutConfig.injuryDuration != null)
displayActionControl(
AppLocalizations.of(context)!.injuryTimeShort, // VZ Injury Time, Verletzungszeit
prepareCallback(const BoutScreenActionIntent.redInjuryTime(), const BoutScreenActionIntent.blueInjuryTime()),
color,
),
if (boutConfig.bleedingInjuryDuration != null)
displayActionControl(
AppLocalizations.of(context)!.bleedingInjuryTimeShort, // BZ Bleeding Injury Time, Verletzungszeit Blut
prepareCallback(const BoutScreenActionIntent.redBleedingInjuryTime(),
const BoutScreenActionIntent.blueBleedingInjuryTime()),
color,
),
displayActionControl(
'⎌',
prepareCallback(const BoutScreenActionIntent.redUndo(), const BoutScreenActionIntent.blueUndo()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,26 +73,29 @@ class TeamMatchBoutDisplay extends StatelessWidget {
id: teamMatchBout.bout.id,
initialData: teamMatchBout.bout,
builder: (context, bout) {
return BoutScreen(
wrestlingEvent: match,
boutConfig: match.league?.division.boutConfig ?? TeamMatch.defaultBoutConfig,
// TODO: get from DB:
boutRules: TeamMatch.defaultBoutResultRules,
bouts: teamMatchBouts.map((e) => e.bout).toList(),
boutIndex: teamMatchBoutIndex,
bout: bout,
onPressBoutInfo: (BuildContext context) {
// FIXME: use `push` route, https://github.com/flutter/flutter/issues/140586
context.go(
'/${TeamMatchOverview.route}/${match.id}/${TeamMatchBoutOverview.route}/${teamMatchBout.id}');
},
navigateToBoutByIndex: (context, index) {
context.pop();
navigateToTeamMatchBoutScreen(context, match, teamMatchBouts[index]);
},
home: match.home.team,
guest: match.guest.team,
);
return ManyConsumer<BoutResultRule, BoutConfig>(
filterObject: teamMatchBout.teamMatch.league!.division.boutConfig,
builder: (BuildContext context, List<BoutResultRule> boutResultRules) {
return BoutScreen(
wrestlingEvent: match,
boutConfig: match.league?.division.boutConfig ?? TeamMatch.defaultBoutConfig,
boutRules: boutResultRules,
bouts: teamMatchBouts.map((e) => e.bout).toList(),
boutIndex: teamMatchBoutIndex,
bout: bout,
onPressBoutInfo: (BuildContext context) {
// FIXME: use `push` route, https://github.com/flutter/flutter/issues/140586
context.go(
'/${TeamMatchOverview.route}/${match.id}/${TeamMatchBoutOverview.route}/${teamMatchBout.id}');
},
navigateToBoutByIndex: (context, index) {
context.pop();
navigateToTeamMatchBoutScreen(context, match, teamMatchBouts[index]);
},
home: match.home.team,
guest: match.guest.team,
);
});
});
});
});
Expand Down Expand Up @@ -157,6 +160,8 @@ class BoutState extends ConsumerState<BoutScreen> {
period = (bout.duration.inSeconds ~/ boutConfig.periodDuration.inSeconds) + 1;
_r = ParticipantStateModel(bout.r);
_b = ParticipantStateModel(bout.b);

// Regular injury
_r.injuryStopwatch.limit = boutConfig.injuryDuration;
_r.injuryStopwatch.onEnd.stream.listen((event) {
setState(() {
Expand All @@ -172,6 +177,22 @@ class BoutState extends ConsumerState<BoutScreen> {
handleAction(const BoutScreenActionIntent.horn());
});

// Bleeding injury
_r.bleedingInjuryStopwatch.limit = boutConfig.bleedingInjuryDuration;
_r.bleedingInjuryStopwatch.onEnd.stream.listen((event) {
setState(() {
_r.isBleedingInjury = false;
});
handleAction(const BoutScreenActionIntent.horn());
});
_b.bleedingInjuryStopwatch.limit = boutConfig.bleedingInjuryDuration;
_b.bleedingInjuryStopwatch.onEnd.stream.listen((event) {
setState(() {
_b.isBleedingInjury = false;
});
handleAction(const BoutScreenActionIntent.horn());
});

stopwatch = _boutStopwatch = ObservableStopwatch(
limit: boutConfig.totalPeriodDuration,
);
Expand Down Expand Up @@ -374,6 +395,17 @@ class BoutState extends ConsumerState<BoutScreen> {
psm.injuryStopwatch.stop();
}
break;
case BoutScreenActions.redBleedingInjuryTime:
ParticipantStateModel psm = _r;
setState(() {
psm.isBleedingInjury = !psm.isBleedingInjury;
});
if (psm.isBleedingInjury) {
psm.bleedingInjuryStopwatch.start();
} else {
psm.bleedingInjuryStopwatch.stop();
}
break;
case BoutScreenActions.blueActivityTime:
ParticipantStateModel psm = _b;
psm.activityStopwatch?.dispose();
Expand Down Expand Up @@ -401,6 +433,17 @@ class BoutState extends ConsumerState<BoutScreen> {
psm.injuryStopwatch.stop();
}
break;
case BoutScreenActions.blueBleedingInjuryTime:
ParticipantStateModel psm = _b;
setState(() {
psm.isBleedingInjury = !psm.isBleedingInjury;
});
if (psm.isBleedingInjury) {
psm.bleedingInjuryStopwatch.start();
} else {
psm.bleedingInjuryStopwatch.stop();
}
break;
case BoutScreenActions.horn:
ref.read(bellPlayerNotifierProvider).then((player) async {
await player.stop();
Expand Down Expand Up @@ -516,7 +559,7 @@ class BoutState extends ConsumerState<BoutScreen> {
padding: bottomPadding,
children: [
displayTechnicalPoints(_r, BoutRole.red),
BoutActionControls(BoutRole.red, bout.r == null ? null : handleAction),
BoutActionControls(BoutRole.red, boutConfig, bout.r == null ? null : handleAction),
Expanded(
flex: 50,
child: Center(
Expand All @@ -528,7 +571,7 @@ class BoutState extends ConsumerState<BoutScreen> {
),
),
),
BoutActionControls(BoutRole.blue, bout.b == null ? null : handleAction),
BoutActionControls(BoutRole.blue, boutConfig, bout.b == null ? null : handleAction),
displayTechnicalPoints(_b, BoutRole.blue),
],
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ enum BoutScreenActions {
redDismissal,
redActivityTime,
redInjuryTime,
redBleedingInjuryTime,
redUndo,
blueOne,
blueTwo,
Expand All @@ -40,6 +41,7 @@ enum BoutScreenActions {
blueDismissal,
blueActivityTime,
blueInjuryTime,
blueBleedingInjuryTime,
blueUndo,
}

Expand Down Expand Up @@ -84,6 +86,8 @@ class BoutScreenActionIntent extends Intent {

const BoutScreenActionIntent.redInjuryTime() : type = BoutScreenActions.redInjuryTime;

const BoutScreenActionIntent.redBleedingInjuryTime() : type = BoutScreenActions.redBleedingInjuryTime;

const BoutScreenActionIntent.redUndo() : type = BoutScreenActions.redUndo;

const BoutScreenActionIntent.blueOne() : type = BoutScreenActions.blueOne;
Expand All @@ -106,6 +110,8 @@ class BoutScreenActionIntent extends Intent {

const BoutScreenActionIntent.blueInjuryTime() : type = BoutScreenActions.blueInjuryTime;

const BoutScreenActionIntent.blueBleedingInjuryTime() : type = BoutScreenActions.blueBleedingInjuryTime;

const BoutScreenActionIntent.blueUndo() : type = BoutScreenActions.blueUndo;
final BoutScreenActions type;

Expand Down Expand Up @@ -225,6 +231,9 @@ class BoutScreenActionIntent extends Intent {
case BoutScreenActions.redInjuryTime:
doAction(BoutScreenActions.redInjuryTime);
break;
case BoutScreenActions.redBleedingInjuryTime:
doAction(BoutScreenActions.redBleedingInjuryTime);
break;
case BoutScreenActions.redUndo:
if (bout.r != null) {
final actions = await getActions();
Expand Down Expand Up @@ -311,6 +320,9 @@ class BoutScreenActionIntent extends Intent {
case BoutScreenActions.blueInjuryTime:
doAction(BoutScreenActions.blueInjuryTime);
break;
case BoutScreenActions.blueBleedingInjuryTime:
doAction(BoutScreenActions.blueBleedingInjuryTime);
break;
case BoutScreenActions.undo:
final actions = await getActions();
if (actions.isNotEmpty) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class TechnicalPoints extends StatelessWidget {
},
),
),
if (pStatusModel.activityStopwatch != null)
if (pStatusModel.activityStopwatch != null && boutConfig.activityDuration != null)
Expanded(
flex: 30,
child: Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [
Expand All @@ -57,10 +57,10 @@ class TechnicalPoints extends StatelessWidget {
pStatusModel.activityStopwatch!,
white,
fontSize: timerFontSize,
maxDuration: boutConfig.activityDuration,
maxDuration: boutConfig.activityDuration!,
)
])),
if (pStatusModel.isInjury)
if (pStatusModel.isInjury && boutConfig.injuryDuration != null)
Expanded(
flex: 30,
child: Row(
Expand All @@ -71,7 +71,23 @@ class TechnicalPoints extends StatelessWidget {
pStatusModel.injuryStopwatch,
white,
fontSize: timerFontSize,
maxDuration: boutConfig.injuryDuration,
maxDuration: boutConfig.injuryDuration!,
)
],
),
),
if (pStatusModel.isBleedingInjury && boutConfig.bleedingInjuryDuration != null)
Expanded(
flex: 30,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ScaledText(AppLocalizations.of(context)!.bleedingInjuryTimeShort, fontSize: timerFontSize),
TimeDisplay(
pStatusModel.bleedingInjuryStopwatch,
white,
fontSize: timerFontSize,
maxDuration: boutConfig.bleedingInjuryDuration!,
)
],
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ abstract class BoutConfigEditState<T extends BoutConfigEdit> extends ConsumerSta
Duration? _breakDuration;
Duration? _activityDuration;
Duration? _injuryDuration;
Duration? _bleedingInjuryDuration;
int? _periodCount;

@override
Expand Down Expand Up @@ -63,7 +64,7 @@ abstract class BoutConfigEditState<T extends BoutConfigEdit> extends ConsumerSta
leading: const Icon(Icons.timelapse),
subtitle: Text(localizations.activityDuration),
title: DurationFormField(
initialValue: widget.boutConfig?.activityDuration ?? BoutConfig.defaultActivityDuration,
initialValue: widget.boutConfig?.activityDuration,
maxValue: const Duration(hours: 1),
onSaved: (Duration? value) {
_activityDuration = value;
Expand All @@ -74,13 +75,24 @@ abstract class BoutConfigEditState<T extends BoutConfigEdit> extends ConsumerSta
leading: const Icon(Icons.timelapse),
subtitle: Text(localizations.injuryDuration),
title: DurationFormField(
initialValue: widget.boutConfig?.injuryDuration ?? BoutConfig.defaultInjuryDuration,
initialValue: widget.boutConfig?.injuryDuration,
maxValue: const Duration(hours: 1),
onSaved: (Duration? value) {
_injuryDuration = value;
},
),
),
ListTile(
leading: const Icon(Icons.timelapse),
subtitle: Text(localizations.bleedingInjuryDuration),
title: DurationFormField(
initialValue: widget.boutConfig?.bleedingInjuryDuration,
maxValue: const Duration(hours: 1),
onSaved: (Duration? value) {
_bleedingInjuryDuration = value;
},
),
),
ListTile(
leading: const Icon(Icons.repeat),
title: TextFormField(
Expand Down Expand Up @@ -112,12 +124,13 @@ abstract class BoutConfigEditState<T extends BoutConfigEdit> extends ConsumerSta
Future<void> handleSubmit(NavigatorState navigator) async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
var boutConfig = BoutConfig(
BoutConfig boutConfig = BoutConfig(
id: widget.boutConfig?.id,
periodDuration: _periodDuration!,
breakDuration: _breakDuration!,
activityDuration: _activityDuration!,
injuryDuration: _injuryDuration!,
activityDuration: _activityDuration,
injuryDuration: _injuryDuration,
bleedingInjuryDuration: _bleedingInjuryDuration,
periodCount: _periodCount!,
);
boutConfig =
Expand Down
Loading

0 comments on commit 34a462d

Please sign in to comment.