Skip to content

Commit

Permalink
feat: generate score sheet pdf
Browse files Browse the repository at this point in the history
  • Loading branch information
Gustl22 committed Apr 2, 2023
1 parent b44cd85 commit 3f7ac05
Show file tree
Hide file tree
Showing 10 changed files with 573 additions and 15 deletions.
38 changes: 24 additions & 14 deletions wrestling_scoreboard_client/lib/ui/fight/fight_screen.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'dart:async';

import 'package:wrestling_scoreboard_common/common.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:printing/printing.dart';
import 'package:provider/provider.dart';
import 'package:wrestling_scoreboard_client/data/fight_role.dart';
import 'package:wrestling_scoreboard_client/data/wrestling_style.dart';
Expand All @@ -15,7 +15,9 @@ import 'package:wrestling_scoreboard_client/ui/models/participant_state_model.da
import 'package:wrestling_scoreboard_client/util/audio/audio.dart';
import 'package:wrestling_scoreboard_client/util/colors.dart';
import 'package:wrestling_scoreboard_client/util/network/data_provider.dart';
import 'package:wrestling_scoreboard_client/util/print/pdf/score_sheet.dart';
import 'package:wrestling_scoreboard_client/util/units.dart';
import 'package:wrestling_scoreboard_common/common.dart';

import '../components/fitted_text.dart';
import '../match/common_elements.dart';
Expand Down Expand Up @@ -53,7 +55,7 @@ class FightState extends State<FightScreen> {
late ObservableStopwatch _breakStopwatch;
late ParticipantStateModel _r;
late ParticipantStateModel _b;
late BoutConfig _boutConfig;
late BoutConfig boutConfig;
int period = 1;
late Function(FightScreenActionIntent) handleAction;

Expand All @@ -69,21 +71,21 @@ class FightState extends State<FightScreen> {
HornSound();
match = widget.match;
fights = widget.fights;
// TODO may overwrite in settings to be more flexible
_boutConfig = match.home.team.league?.boutConfig ?? BoutConfig();
// TODO: may overwrite in settings to be more flexible
boutConfig = match.home.team.league?.boutConfig ?? BoutConfig();
actions = widget.actions;
fightIndex = widget.fightIndex;
fight = widget.fights[fightIndex];
_r = ParticipantStateModel(fight.r);
_b = ParticipantStateModel(fight.b);
_r.injuryStopwatch.limit = _boutConfig.injuryDuration;
_r.injuryStopwatch.limit = boutConfig.injuryDuration;
_r.injuryStopwatch.onEnd.stream.listen((event) {
setState(() {
_r.isInjury = false;
});
handleAction(const FightScreenActionIntent.horn());
});
_b.injuryStopwatch.limit = _boutConfig.injuryDuration;
_b.injuryStopwatch.limit = boutConfig.injuryDuration;
_b.injuryStopwatch.onEnd.stream.listen((event) {
setState(() {
_b.isInjury = false;
Expand All @@ -92,7 +94,7 @@ class FightState extends State<FightScreen> {
});

stopwatch = _fightStopwatch = ObservableStopwatch(
limit: _boutConfig.periodDuration * _boutConfig.periodCount,
limit: boutConfig.periodDuration * boutConfig.periodCount,
);
_fightStopwatch.onStart.stream.listen((event) {
_r.activityStopwatch?.start();
Expand All @@ -114,7 +116,7 @@ class FightState extends State<FightScreen> {
if (stopwatch == _fightStopwatch) {
fight.duration = event;

if (fight.duration.compareTo(_boutConfig.periodDuration * period) >= 0) {
if (fight.duration.compareTo(boutConfig.periodDuration * period) >= 0) {
_fightStopwatch.stop();
if (_r.activityStopwatch != null) {
_r.activityStopwatch!.dispose();
Expand All @@ -125,14 +127,14 @@ class FightState extends State<FightScreen> {
_b.activityStopwatch = null;
}
handleAction(const FightScreenActionIntent.horn());
if (period < _boutConfig.periodCount) {
if (period < boutConfig.periodCount) {
setState(() {
stopwatch = _breakStopwatch;
});
_breakStopwatch.start();
period++;
}
} else if (fight.duration.inSeconds ~/ _boutConfig.periodDuration.inSeconds < (period - 1)) {
} else if (fight.duration.inSeconds ~/ boutConfig.periodDuration.inSeconds < (period - 1)) {
// Fix times below round time: e.g. if subtract time
period -= 1;
}
Expand All @@ -141,7 +143,7 @@ class FightState extends State<FightScreen> {
);
stopwatch.addDuration(fight.duration);
_breakStopwatch = ObservableStopwatch(
limit: _boutConfig.breakDuration,
limit: boutConfig.breakDuration,
);
_breakStopwatch.onEnd.stream.listen((event) {
if (stopwatch == _breakStopwatch) {
Expand Down Expand Up @@ -242,7 +244,7 @@ class FightState extends State<FightScreen> {
psm.activityStopwatch?.dispose();
setState(() {
psm.activityStopwatch =
psm.activityStopwatch == null ? ObservableStopwatch(limit: _boutConfig.activityDuration) : null;
psm.activityStopwatch == null ? ObservableStopwatch(limit: boutConfig.activityDuration) : null;
});
if (psm.activityStopwatch != null && _fightStopwatch.isRunning) psm.activityStopwatch!.start();
psm.activityStopwatch?.onEnd.stream.listen((event) {
Expand Down Expand Up @@ -270,7 +272,7 @@ class FightState extends State<FightScreen> {
psm.activityStopwatch?.dispose();
setState(() {
psm.activityStopwatch =
psm.activityStopwatch == null ? ObservableStopwatch(limit: _boutConfig.activityDuration) : null;
psm.activityStopwatch == null ? ObservableStopwatch(limit: boutConfig.activityDuration) : null;
});
if (psm.activityStopwatch != null && _fightStopwatch.isRunning) psm.activityStopwatch!.start();
psm.activityStopwatch?.onEnd.stream.listen((event) {
Expand Down Expand Up @@ -305,6 +307,7 @@ class FightState extends State<FightScreen> {

@override
Widget build(BuildContext context) {
final localizations = AppLocalizations.of(context)!;
double width = MediaQuery.of(context).size.width;
double padding = width / 100;
TextStyle fontStyleInfo = TextStyle(fontSize: width / 60);
Expand All @@ -325,13 +328,20 @@ class FightState extends State<FightScreen> {
doAction: doAction,
child: Scaffold(
bottomNavigationBar: BottomAppBar(
child: Row(children: [
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
Navigator.pop(context, false);
},
),
IconButton(
icon: const Icon(Icons.share),
onPressed: () async {
final bytes = await generateScoreSheet(this, localizations: localizations);
Printing.sharePdf(bytes: bytes);
},
),
]),
),
body: StreamProvider<List<FightAction>>(
Expand Down
6 changes: 5 additions & 1 deletion wrestling_scoreboard_client/lib/util/date_time.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import 'package:intl/intl.dart';

extension DateTimeFormatter on DateTime {
String toDateString(BuildContext context) {
return DateFormat.yMMMd(Localizations.localeOf(context).toLanguageTag()).format(this);
return toDateStringFromLocaleName(Localizations.localeOf(context).toLanguageTag());
}

String toDateStringFromLocaleName(String localeName) {
return DateFormat.yMMMd(localeName).format(this);
}

String toTimeString(BuildContext context) {
Expand Down
67 changes: 67 additions & 0 deletions wrestling_scoreboard_client/lib/util/print/pdf/components.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart';

Widget buildTextCell(
String title, {
double? height = 60,
double? width,
double? fontSize,
PdfColor borderColor = PdfColors.grey,
PdfColor textColor = PdfColors.black,
PdfColor? color,
EdgeInsets? margin,
Alignment alignment = Alignment.centerLeft,
}) {
return Container(
color: color,
margin: margin,
padding: const EdgeInsets.all(2),
alignment: alignment,
foregroundDecoration: BoxDecoration(
border: Border.all(
color: borderColor,
width: .5,
),
),
height: height,
width: width,
child: Text(title, style: TextStyle(fontSize: fontSize, color: textColor)));
}

Widget buildFormCell({
String? title,
String? content,
double height = 60,
double? width,
PdfColor borderColor = PdfColors.grey,
PdfColor? color,
PdfColor pencilColor = PdfColors.blue800,
}) {
return Container(
height: height,
width: width,
foregroundDecoration: BoxDecoration(
border: Border.all(
color: borderColor,
width: .5,
),
),
color: color,
child: Stack(
children: [
if (title != null)
Container(
alignment: Alignment.topLeft,
padding: const EdgeInsets.all(2),
child: Text(title.toUpperCase(), style: TextStyle(fontSize: 6, fontWeight: FontWeight.bold)),
),
if (content != null)
Expanded(
child: Container(
alignment: Alignment.center,
child: Text(content, style: TextStyle(fontSize: 12, color: pencilColor)),
)),
],
),
);
}
Loading

0 comments on commit 3f7ac05

Please sign in to comment.