Skip to content

Commit

Permalink
feat: Disable impossible bout results (closes #97)
Browse files Browse the repository at this point in the history
  • Loading branch information
Gustl22 committed Dec 6, 2024
1 parent a15fd01 commit bc6a955
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -102,32 +102,48 @@ class BoutMainControlsState extends ConsumerState<BoutMainControls> {
displayDropDown(BoutRole role) {
ParticipantState? pStatus = role == BoutRole.red ? widget.boutState.bout.r : widget.boutState.bout.b;
ParticipantState? pStatusOpponent = role == BoutRole.blue ? widget.boutState.bout.r : widget.boutState.bout.b;
// Empty List, if pStatus is empty
final List<MapEntry<BoutResult, Widget>> boutResultOptions = [];
if (pStatus != null) {
final boutResultValues = List.of(BoutResult.values);
if (pStatusOpponent == null) {
// Cannot select this option, as there is no opponent
boutResultValues.remove(BoutResult.dsq2);
}
boutResultOptions.addAll(boutResultValues.map(
(BoutResult boutResult) => MapEntry(
boutResult,
Tooltip(
message: boutResult.description(context),
child: Text(boutResult.abbreviation(context)),
),
),
));
}

return ThemedContainer(
color: role == widget.boutState.bout.winnerRole ? role.color() : null,
child: ButtonTheme(
alignedDropdown: true,
child: ManyConsumer<BoutAction, Bout>(
filterObject: widget.boutState.bout,
builder: (context, actions) {
return SimpleDropdown<BoutResult>(
// Empty List, if pStatus is empty
final List<DropdownMenuItem<BoutResult>> boutResultOptions = [];
if (pStatus != null) {
final boutResultValues = List.of(BoutResult.values);
if (pStatusOpponent == null) {
// Cannot select this option, as there is no opponent
boutResultValues.remove(BoutResult.dsq2);
}
boutResultOptions.addAll(boutResultValues.map(
(BoutResult boutResult) {
final resultRule = BoutConfig.resultRule(
result: boutResult,
style: widget.boutState.bout.weightClass?.style ?? WrestlingStyle.free,
technicalPointsWinner: ParticipantState.getTechnicalPoints(actions, role),
technicalPointsLoser: ParticipantState.getTechnicalPoints(
actions, role == BoutRole.red ? BoutRole.blue : BoutRole.red),
rules: widget.boutState.boutRules,
);
final isEnabled = resultRule != null;
return DropdownMenuItem(
// Only allow to select option, if current state and resultRules allow it.
enabled: isEnabled,
value: boutResult,
child: Tooltip(
message: boutResult.description(context),
child: Text(boutResult.abbreviation(context),
style: isEnabled ? null : TextStyle(color: Theme.of(context).disabledColor)),
),
);
},
));
}

return CustomDropdown<BoutResult>(
isNullable: true,
selected: role == widget.boutState.bout.winnerRole || widget.boutState.bout.result == BoutResult.dsq2
? widget.boutState.bout.result
Expand Down
48 changes: 40 additions & 8 deletions wrestling_scoreboard_client/lib/view/widgets/dropdown.dart
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,46 @@ class SimpleDropdown<T> extends StatelessWidget {

@override
Widget build(BuildContext context) {
final items = options
.map<DropdownMenuItem<T>>(
(entry) => DropdownMenuItem<T>(
value: entry.key,
child: entry.value,
),
)
.toList();
return CustomDropdown<T>(
hint: hint,
isExpanded: isExpanded,
selected: selected,
onChange: onChange,
options: options.map<DropdownMenuItem<T>>(
(entry) => DropdownMenuItem<T>(
value: entry.key,
child: entry.value,
),
),
alignment: alignment,
isNullable: isNullable,
);
}
}

class CustomDropdown<T> extends StatelessWidget {
final Iterable<DropdownMenuItem<T>> options;
final T? selected;
final void Function(T? value) onChange;
final bool isExpanded;
final bool isNullable;
final String? hint;
final AlignmentGeometry alignment;

const CustomDropdown({
required this.options,
required this.selected,
required this.onChange,
this.isNullable = false,
this.isExpanded = true,
super.key,
this.hint,
this.alignment = AlignmentDirectional.centerStart,
});

@override
Widget build(BuildContext context) {
final items = options.toList();
if (isNullable) {
items.add(DropdownMenuItem<T>(
value: null,
Expand Down
4 changes: 4 additions & 0 deletions wrestling_scoreboard_common/lib/src/data/bout.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ class Bout with _$Bout implements DataObject, Organizational {
rules: rules,
);

if (resultRule == null) {
throw Exception('No bout result rule found for $result');
}

return copyWith(
r: r?.copyWith(
classificationPoints:
Expand Down
4 changes: 2 additions & 2 deletions wrestling_scoreboard_common/lib/src/data/bout_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class BoutConfig with _$BoutConfig implements DataObject {
return copyWith(id: id);
}

static BoutResultRule resultRule({
static BoutResultRule? resultRule({
required BoutResult result,
required WrestlingStyle style,
required int technicalPointsWinner,
Expand All @@ -87,7 +87,7 @@ class BoutConfig with _$BoutConfig implements DataObject {
return matchResult && matchStyle && matchDiff && matchPointsLoser && matchPointsWinner;
}).toList();
if (applyingRules.isEmpty) {
throw Exception('No bout result rule found for $result');
return null;
}
applyingRules.sort((a, b) {
var pDiff = (a.technicalPointsDifference ?? 0) - (b.technicalPointsDifference ?? 0);
Expand Down
Loading

0 comments on commit bc6a955

Please sign in to comment.