883 lines
33 KiB
Dart
883 lines
33 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:aitrainer_app/library/custom_icon_icons.dart';
|
|
import 'package:aitrainer_app/model/cache.dart';
|
|
import 'package:aitrainer_app/util/trans.dart';
|
|
import 'package:aitrainer_app/widgets/menu_image.dart';
|
|
import 'package:aitrainer_app/widgets/time_picker.dart';
|
|
import 'package:aitrainer_app/widgets/tutorial_widget.dart';
|
|
import 'package:badges/badges.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/scheduler.dart';
|
|
import 'package:google_fonts/google_fonts.dart';
|
|
import 'package:keyboard_actions/keyboard_actions.dart';
|
|
import 'package:stop_watch_timer/stop_watch_timer.dart';
|
|
import 'package:wakelock/wakelock.dart';
|
|
import 'dialog_html.dart';
|
|
|
|
class ExerciseSaveStream {
|
|
static final ExerciseSaveStream _singleton = ExerciseSaveStream._internal();
|
|
final StreamController<bool> streamController = StreamController<bool>.broadcast();
|
|
int repeats = 0;
|
|
double weight = 0;
|
|
|
|
Stream get stream => streamController.stream;
|
|
StreamController getStreamController() => streamController;
|
|
|
|
factory ExerciseSaveStream() => _singleton;
|
|
|
|
ExerciseSaveStream._internal();
|
|
|
|
void dispose() {
|
|
streamController.close();
|
|
}
|
|
}
|
|
|
|
enum Explanations { intro, introBold, explanationWeight, explanationRepeats, explanationButton, explanationButtonExt }
|
|
|
|
extension ExplanationsExt on Explanations {
|
|
String toStr() => this.toString().split(".").last;
|
|
bool equalsTo(Explanations type) => this.toString() == type.toString();
|
|
bool equalsStringTo(String type) => this.toStr() == type;
|
|
}
|
|
|
|
class ExplanationExt {
|
|
final ActivityDone tip;
|
|
final String? unitQuantityUnit;
|
|
final double? weight;
|
|
final int? repeats;
|
|
ExplanationExt({
|
|
required this.tip,
|
|
this.unitQuantityUnit,
|
|
required this.weight,
|
|
required this.repeats,
|
|
});
|
|
|
|
String getExplanation(Explanations explanation) {
|
|
String expl = "";
|
|
if (this.tip.equalsTo(ActivityDone.exerciseSaveTestTip)) {
|
|
if (explanation.equalsTo(Explanations.intro)) {
|
|
expl = "Please take a middle weight which you are able to do 8-20 times with.";
|
|
} else if (explanation.equalsTo(Explanations.introBold)) {
|
|
expl = "Execute your MAXIMUM repeats with it!";
|
|
} else if (explanation.equalsTo(Explanations.explanationWeight)) {
|
|
expl = "Type here your selected weight,";
|
|
} else if (explanation.equalsTo(Explanations.explanationRepeats)) {
|
|
expl = "then here, how many times could you repeat it!";
|
|
} else if (explanation.equalsTo(Explanations.explanationButton)) {
|
|
expl = "After you done, click to the OK button!";
|
|
} else if (explanation.equalsTo(Explanations.explanationButtonExt)) {
|
|
expl = "";
|
|
}
|
|
} else if (this.tip.equalsTo(ActivityDone.exerciseSaveTrainingTip)) {
|
|
if (unitQuantityUnit != null) {
|
|
if (weight == -1) {
|
|
if (explanation.equalsTo(Explanations.intro)) {
|
|
expl = "Please take a middle weight which you are able to do 8-20 times with.";
|
|
} else if (explanation.equalsTo(Explanations.introBold)) {
|
|
expl = "Execute your MAXIMUM repeats with it!";
|
|
}
|
|
} else if (repeats == 99) {
|
|
if (explanation.equalsTo(Explanations.intro)) {
|
|
expl = "It is time to exhaust your muscles";
|
|
}
|
|
} else {
|
|
if (explanation.equalsTo(Explanations.intro)) {
|
|
expl = "For your optimal development we calculated a suitable weight and repeats";
|
|
} else if (explanation.equalsTo(Explanations.introBold)) {
|
|
expl = "You can change the weight, if you could not set it in the training room";
|
|
}
|
|
}
|
|
if (explanation.equalsTo(Explanations.explanationButtonExt)) {
|
|
if (repeats != 99) {
|
|
expl = "If you could do less, then modify and click to OK";
|
|
}
|
|
} else if (explanation.equalsTo(Explanations.explanationWeight)) {
|
|
if (weight == -1 || weight == -2) {
|
|
expl = "Type here your selected weight,";
|
|
} else {
|
|
expl = "Here is your tailored weight,";
|
|
}
|
|
} else if (explanation.equalsTo(Explanations.explanationRepeats)) {
|
|
if (repeats == 99) {
|
|
expl = "and execute it with maximum repeats!";
|
|
} else {
|
|
expl = "and executed with this number of repeats!";
|
|
}
|
|
}
|
|
} else {
|
|
if (repeats == 99) {
|
|
if (explanation.equalsTo(Explanations.intro)) {
|
|
expl = "Please repeat as much times as you can! MAXIMIZE it!";
|
|
}
|
|
} else {
|
|
if (explanation.equalsTo(Explanations.intro)) {
|
|
expl = "Please try to execute this exercise with exact repeats what is suggested";
|
|
}
|
|
}
|
|
}
|
|
if (explanation.equalsTo(Explanations.explanationButton)) {
|
|
expl = "After you done, click to the OK button!";
|
|
}
|
|
} else if (this.tip.equalsTo(ActivityDone.exerciseSaveTestsetTip)) {}
|
|
|
|
return expl;
|
|
}
|
|
}
|
|
|
|
// ignore: must_be_immutable
|
|
class ExerciseSave extends StatefulWidget {
|
|
final ValueChanged<double> onQuantityChanged;
|
|
final ValueChanged<double>? onUnitQuantityChanged;
|
|
final VoidCallback? onUnitQuantityChangeUp;
|
|
final VoidCallback? onUnitQuantityChangeDown;
|
|
final VoidCallback? onSubmit;
|
|
final bool hasUnitQuantity;
|
|
final String? unitQuantityUnit;
|
|
final String unit;
|
|
final String exerciseName;
|
|
final String exerciseDescription;
|
|
final int exerciseTypeId;
|
|
final double? weight;
|
|
final int? repeats;
|
|
final int? set;
|
|
final int? exerciseNr;
|
|
final int? originalQuantity;
|
|
final MenuImage menuImage;
|
|
final ActivityDone? tip;
|
|
|
|
ExerciseSave(
|
|
{required this.onQuantityChanged,
|
|
this.onUnitQuantityChanged,
|
|
this.onUnitQuantityChangeUp,
|
|
this.onUnitQuantityChangeDown,
|
|
this.onSubmit,
|
|
required this.hasUnitQuantity,
|
|
this.unitQuantityUnit,
|
|
required this.unit,
|
|
required this.exerciseName,
|
|
required this.exerciseDescription,
|
|
required this.exerciseTypeId,
|
|
this.weight,
|
|
this.repeats,
|
|
this.set,
|
|
this.exerciseNr,
|
|
this.originalQuantity,
|
|
required this.menuImage,
|
|
this.tip});
|
|
@override
|
|
_ExerciseSaveState createState() => _ExerciseSaveState();
|
|
}
|
|
|
|
class _ExerciseSaveState extends State<ExerciseSave> with Trans {
|
|
final FocusNode _nodeText1 = FocusNode();
|
|
final FocusNode _nodeText2 = FocusNode();
|
|
final _controller1 = TextEditingController();
|
|
final _controller2 = TextEditingController();
|
|
final StopWatchTimer stopWatchTimer = StopWatchTimer(
|
|
isLapHours: false,
|
|
);
|
|
final Stream stream = ExerciseSaveStream().stream;
|
|
late StreamSubscription<dynamic> subscription;
|
|
bool changable = false;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
setContext(context);
|
|
return getExerciseWidget();
|
|
}
|
|
|
|
@override
|
|
initState() {
|
|
super.initState();
|
|
_nodeText1.addListener(() {
|
|
if (_nodeText1.hasFocus) {
|
|
_controller1.selection = TextSelection(baseOffset: 0, extentOffset: _controller1.text.length);
|
|
}
|
|
});
|
|
_nodeText2.addListener(() {
|
|
if (_nodeText2.hasFocus) {
|
|
_controller2.selection = TextSelection(baseOffset: 0, extentOffset: _controller2.text.length);
|
|
}
|
|
});
|
|
if (widget.unit == "second") {
|
|
stopWatchTimer.rawTime.listen((value) => {
|
|
if (value > 0)
|
|
{
|
|
widget.onQuantityChanged((value / 1000)),
|
|
}
|
|
});
|
|
}
|
|
|
|
SchedulerBinding.instance!.addPostFrameCallback((_) {
|
|
subscription = stream.listen((event) {
|
|
//_controller1.text = ExerciseSaveStream().weight.toStringAsFixed(0);
|
|
_controller2.text = ExerciseSaveStream().repeats.toStringAsFixed(0);
|
|
});
|
|
print("ExerciseSave weight ${widget.weight}");
|
|
_controller1.text = widget.weight == null || widget.weight == -1
|
|
? "TEST"
|
|
: widget.weight! % widget.weight!.round() == 0
|
|
? widget.weight!.toStringAsFixed(0)
|
|
: widget.weight!.toStringAsFixed(1);
|
|
_controller2.text = widget.repeats == null
|
|
? "TEST"
|
|
: widget.repeats! == 99
|
|
? "MAX"
|
|
: widget.weight == -1 || widget.weight == -2
|
|
? "TEST"
|
|
: widget.repeats!.toStringAsFixed(0);
|
|
changable = (_controller2.text != "TEST" && _controller1.text != "TEST");
|
|
if (widget.unitQuantityUnit != null && widget.tip != null && Cache().isActivityDone(widget.tip!) == false) {
|
|
Timer(
|
|
Duration(milliseconds: 2000),
|
|
() => {
|
|
TutorialWidget().explanation(
|
|
context,
|
|
ExplanationWidget(
|
|
unitQuantityUnit: widget.unitQuantityUnit,
|
|
unit: widget.unit,
|
|
tip: widget.tip,
|
|
weight: widget.weight,
|
|
repeats: widget.repeats,
|
|
)),
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
@override
|
|
dispose() {
|
|
_controller1.dispose();
|
|
stopWatchTimer.dispose();
|
|
|
|
subscription.cancel();
|
|
|
|
super.dispose();
|
|
}
|
|
|
|
void isChangable() {
|
|
changable = !(widget.weight == -1 || widget.weight == -2 || widget.weight == null);
|
|
}
|
|
|
|
KeyboardActionsConfig _buildConfig(BuildContext context) {
|
|
return KeyboardActionsConfig(
|
|
keyboardActionsPlatform: KeyboardActionsPlatform.ALL,
|
|
keyboardBarColor: Colors.grey[200],
|
|
keyboardSeparatorColor: Colors.black26,
|
|
nextFocus: true,
|
|
actions: [
|
|
KeyboardActionsItem(focusNode: _nodeText2, toolbarButtons: [
|
|
(node) {
|
|
return GestureDetector(
|
|
onTap: () => node.unfocus(),
|
|
child: Container(
|
|
padding: EdgeInsets.all(8.0),
|
|
color: Colors.orange[500],
|
|
child: Text(
|
|
t("Done"),
|
|
style: TextStyle(color: Colors.white),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
]),
|
|
KeyboardActionsItem(
|
|
focusNode: _nodeText1,
|
|
toolbarButtons: [
|
|
//button 2
|
|
(node) {
|
|
return GestureDetector(
|
|
onTap: () => node.unfocus(),
|
|
child: Container(
|
|
color: Colors.orange,
|
|
padding: EdgeInsets.all(8.0),
|
|
child: Text(
|
|
t("Done"),
|
|
style: TextStyle(color: Colors.white),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
],
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
String getTimeGoal(int? originalQuantity) {
|
|
if (originalQuantity == null) {
|
|
return "";
|
|
} else if (originalQuantity == -1) {
|
|
return t("Goal") + ": Max";
|
|
} else {
|
|
int mins = (originalQuantity / 60).floor();
|
|
int secs = originalQuantity % 60;
|
|
String seconds = "";
|
|
if (secs > 0) {
|
|
seconds = secs.toStringAsFixed(0) + " " + t("secs");
|
|
}
|
|
return t("Goal") + ": " + mins.toStringAsFixed(0) + " " + t("mins") + " " + seconds;
|
|
}
|
|
}
|
|
|
|
Widget getExerciseWidget() {
|
|
ExplanationExt expl = ExplanationExt(
|
|
tip: widget.tip!,
|
|
weight: widget.weight,
|
|
repeats: widget.repeats,
|
|
unitQuantityUnit: widget.unitQuantityUnit,
|
|
);
|
|
|
|
return KeyboardActions(
|
|
config: _buildConfig(context),
|
|
child: Container(
|
|
child: SingleChildScrollView(
|
|
scrollDirection: Axis.vertical,
|
|
child: Column(mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[
|
|
Stack(alignment: Alignment.bottomLeft, children: [
|
|
Badge(
|
|
elevation: 0,
|
|
padding: EdgeInsets.all(0),
|
|
position: BadgePosition.topEnd(top: 5, end: 5),
|
|
animationDuration: Duration(milliseconds: 1500),
|
|
animationType: BadgeAnimationType.fade,
|
|
badgeColor: Colors.transparent,
|
|
showBadge: true,
|
|
badgeContent: IconButton(
|
|
iconSize: 30,
|
|
onPressed: () => showDialog(
|
|
context: context,
|
|
builder: (BuildContext context) {
|
|
return DialogHTML(title: widget.exerciseName, htmlData: '<p>' + widget.exerciseDescription + '</p>');
|
|
}),
|
|
icon: Icon(
|
|
CustomIcon.info_circle,
|
|
color: Colors.white,
|
|
)),
|
|
child: widget.menuImage,
|
|
),
|
|
Container(
|
|
padding: EdgeInsets.only(left: 10, bottom: 10, right: 10),
|
|
child: Text(
|
|
widget.exerciseName,
|
|
style: GoogleFonts.archivoBlack(
|
|
fontWeight: FontWeight.bold,
|
|
fontSize: 24,
|
|
color: Colors.white,
|
|
shadows: <Shadow>[
|
|
Shadow(
|
|
offset: Offset(5.0, 5.0),
|
|
blurRadius: 12.0,
|
|
color: Colors.black54,
|
|
),
|
|
Shadow(
|
|
offset: Offset(-3.0, 3.0),
|
|
blurRadius: 12.0,
|
|
color: Colors.black54,
|
|
),
|
|
],
|
|
),
|
|
overflow: TextOverflow.fade,
|
|
maxLines: 4,
|
|
softWrap: true,
|
|
))
|
|
]),
|
|
ListTile(
|
|
leading: IconButton(
|
|
iconSize: 30,
|
|
onPressed: () => {
|
|
if (widget.unitQuantityUnit != null)
|
|
{
|
|
TutorialWidget().explanation(
|
|
context,
|
|
ExplanationWidget(
|
|
unitQuantityUnit: widget.unitQuantityUnit,
|
|
unit: widget.unit,
|
|
tip: widget.tip,
|
|
weight: widget.weight,
|
|
repeats: widget.repeats,
|
|
))
|
|
}
|
|
},
|
|
icon: Icon(
|
|
CustomIcon.info_circle,
|
|
color: Colors.orange[100],
|
|
)),
|
|
subtitle: Text(
|
|
t(expl.getExplanation(Explanations.intro)),
|
|
style: GoogleFonts.inter(
|
|
fontSize: 14,
|
|
color: Colors.white,
|
|
fontWeight: FontWeight.bold,
|
|
shadows: <Shadow>[
|
|
Shadow(
|
|
offset: Offset(2.0, 2.0),
|
|
blurRadius: 6.0,
|
|
color: Colors.black54,
|
|
),
|
|
Shadow(
|
|
offset: Offset(-3.0, 3.0),
|
|
blurRadius: 12.0,
|
|
color: Colors.black54,
|
|
),
|
|
],
|
|
),
|
|
maxLines: 3,
|
|
textAlign: TextAlign.left,
|
|
overflow: TextOverflow.fade,
|
|
softWrap: true,
|
|
),
|
|
),
|
|
expl.getExplanation(Explanations.introBold).length > 0
|
|
? Text(
|
|
t(expl.getExplanation(Explanations.introBold)),
|
|
style: GoogleFonts.inter(
|
|
fontSize: 14,
|
|
color: Colors.orange,
|
|
fontWeight: FontWeight.bold,
|
|
shadows: <Shadow>[
|
|
Shadow(
|
|
offset: Offset(2.0, 2.0),
|
|
blurRadius: 6.0,
|
|
color: Colors.black54,
|
|
),
|
|
Shadow(
|
|
offset: Offset(-3.0, 3.0),
|
|
blurRadius: 12.0,
|
|
color: Colors.black54,
|
|
),
|
|
],
|
|
),
|
|
maxLines: 3,
|
|
textAlign: TextAlign.center,
|
|
overflow: TextOverflow.fade,
|
|
softWrap: true,
|
|
)
|
|
: Offstage(),
|
|
widget.unit == "second"
|
|
? Text(
|
|
getTimeGoal(widget.originalQuantity),
|
|
style: GoogleFonts.inter(
|
|
fontSize: 24,
|
|
color: Colors.yellow[400],
|
|
fontWeight: FontWeight.bold,
|
|
shadows: <Shadow>[
|
|
Shadow(
|
|
offset: Offset(2.0, 2.0),
|
|
blurRadius: 6.0,
|
|
color: Colors.black54,
|
|
),
|
|
Shadow(
|
|
offset: Offset(-3.0, 3.0),
|
|
blurRadius: 12.0,
|
|
color: Colors.black54,
|
|
),
|
|
],
|
|
),
|
|
textAlign: TextAlign.center,
|
|
)
|
|
: Offstage(),
|
|
columnQuantityUnit(),
|
|
columnQuantity(),
|
|
Divider(
|
|
color: Colors.transparent,
|
|
),
|
|
Text(
|
|
t(expl.getExplanation(Explanations.explanationButton)),
|
|
style: GoogleFonts.inter(
|
|
fontSize: 14,
|
|
color: Colors.white,
|
|
fontWeight: FontWeight.bold,
|
|
shadows: <Shadow>[
|
|
Shadow(
|
|
offset: Offset(2.0, 2.0),
|
|
blurRadius: 6.0,
|
|
color: Colors.black54,
|
|
),
|
|
Shadow(
|
|
offset: Offset(-3.0, 3.0),
|
|
blurRadius: 12.0,
|
|
color: Colors.black54,
|
|
),
|
|
],
|
|
),
|
|
maxLines: 3,
|
|
textAlign: TextAlign.center,
|
|
overflow: TextOverflow.fade,
|
|
softWrap: true,
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsets.only(left: 35, right: 35),
|
|
child: Text(
|
|
t(expl.getExplanation(Explanations.explanationButtonExt)),
|
|
style: GoogleFonts.inter(
|
|
fontSize: 14,
|
|
color: Colors.orange,
|
|
fontWeight: FontWeight.bold,
|
|
shadows: <Shadow>[
|
|
Shadow(
|
|
offset: Offset(2.0, 2.0),
|
|
blurRadius: 6.0,
|
|
color: Colors.black54,
|
|
),
|
|
Shadow(
|
|
offset: Offset(-3.0, 3.0),
|
|
blurRadius: 12.0,
|
|
color: Colors.black54,
|
|
),
|
|
],
|
|
),
|
|
maxLines: 3,
|
|
textAlign: TextAlign.center,
|
|
overflow: TextOverflow.fade,
|
|
softWrap: true,
|
|
)),
|
|
Divider(
|
|
color: Colors.transparent,
|
|
),
|
|
Divider(
|
|
color: Colors.transparent,
|
|
),
|
|
]),
|
|
)));
|
|
}
|
|
|
|
Widget columnQuantityUnit() {
|
|
//changable = (_controller2.text != "TEST" && _controller1.text != "TEST");
|
|
isChangable();
|
|
changable = false;
|
|
//print("PlusMinus: $changable - con2: ${_controller2.text} con1: ${_controller1.text}");
|
|
Widget row = Padding(padding: const EdgeInsets.only(top: 10, left: 55, right: 55), child: Column());
|
|
if (widget.hasUnitQuantity) {
|
|
row = Padding(
|
|
padding: const EdgeInsets.only(top: 10, left: 55, right: 55),
|
|
child: Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
|
|
Flexible(
|
|
child: TextFormField(
|
|
focusNode: _nodeText1,
|
|
controller: _controller1,
|
|
maxLength: 5,
|
|
decoration: InputDecoration(
|
|
contentPadding: EdgeInsets.only(left: 25, top: 5, bottom: 5),
|
|
labelText: t(widget.unitQuantityUnit!),
|
|
labelStyle: GoogleFonts.inter(fontSize: 20, color: Colors.yellow[50]),
|
|
fillColor: Colors.black38,
|
|
filled: true,
|
|
border: OutlineInputBorder(
|
|
gapPadding: 8.0,
|
|
borderRadius: BorderRadius.circular(12.0),
|
|
borderSide: BorderSide(color: Colors.white12, width: 0.4),
|
|
),
|
|
),
|
|
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
|
textInputAction: TextInputAction.done,
|
|
style: GoogleFonts.archivoBlack(fontSize: 75, color: Colors.yellow[300]),
|
|
onChanged: (value) {
|
|
if (value.isNotEmpty) {
|
|
value = value.replaceFirst(",", ".");
|
|
value = value.replaceAll(RegExp(r'[^0-9.]'), "");
|
|
widget.onUnitQuantityChanged!(double.parse(value));
|
|
}
|
|
})),
|
|
changable
|
|
? Column(children: [
|
|
IconButton(
|
|
onPressed: () => widget.onUnitQuantityChangeUp!(),
|
|
icon: Icon(CustomIcon.plus_circle, color: Colors.orange, size: 20),
|
|
),
|
|
IconButton(
|
|
onPressed: () => widget.onUnitQuantityChangeDown!(),
|
|
icon: Icon(CustomIcon.minus_circle, color: Colors.orange, size: 20),
|
|
),
|
|
])
|
|
: Offstage()
|
|
]));
|
|
}
|
|
return row;
|
|
}
|
|
|
|
Widget columnQuantity() {
|
|
if (widget.unit == "second") {
|
|
return Column(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
|
|
Padding(
|
|
padding: const EdgeInsets.only(top: 10, left: 55, right: 55),
|
|
child: StreamBuilder<int>(
|
|
stream: stopWatchTimer.rawTime,
|
|
initialData: stopWatchTimer.rawTime.value,
|
|
builder: (context, snap) {
|
|
final value = snap.data;
|
|
final displayTime = StopWatchTimer.getDisplayTime(value!, hours: false);
|
|
return Column(children: <Widget>[
|
|
Padding(
|
|
padding: const EdgeInsets.all(8),
|
|
child: Text(
|
|
displayTime,
|
|
style: const TextStyle(fontSize: 35, fontFamily: 'Helvetica', fontWeight: FontWeight.bold, color: Colors.white),
|
|
),
|
|
),
|
|
]);
|
|
})),
|
|
Padding(
|
|
padding: const EdgeInsets.only(top: 10, left: 25, right: 25),
|
|
child: Column(
|
|
children: <Widget>[
|
|
Padding(
|
|
padding: const EdgeInsets.only(bottom: 0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: <Widget>[
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 5),
|
|
child: IconButton(
|
|
padding: const EdgeInsets.all(2),
|
|
color: Colors.white70,
|
|
onPressed: () async {
|
|
stopWatchTimer.onExecute.add(StopWatchExecute.start);
|
|
Wakelock.enable(); // prevent sleep the phone
|
|
},
|
|
icon: Icon(CustomIcon.play_1),
|
|
iconSize: 40,
|
|
),
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 5),
|
|
child: IconButton(
|
|
padding: const EdgeInsets.all(2),
|
|
iconSize: 40,
|
|
color: Colors.white70,
|
|
onPressed: () async {
|
|
stopWatchTimer.onExecute.add(StopWatchExecute.stop);
|
|
Wakelock.disable();
|
|
},
|
|
icon: Icon(CustomIcon.stop),
|
|
),
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 5),
|
|
child: IconButton(
|
|
padding: const EdgeInsets.all(2),
|
|
iconSize: 40,
|
|
color: Colors.white70,
|
|
onPressed: () async {
|
|
stopWatchTimer.onExecute.add(StopWatchExecute.reset);
|
|
},
|
|
icon: Icon(CustomIcon.creative_commons_zero),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Divider(),
|
|
Divider(),
|
|
Text(t("Or type the time manually:"), style: GoogleFonts.inter(color: Colors.white)),
|
|
TimePickerWidget(
|
|
onChange: (value) => {
|
|
widget.onQuantityChanged(value),
|
|
},
|
|
)
|
|
]);
|
|
}
|
|
Widget row = Container(
|
|
padding: const EdgeInsets.only(top: 10, left: 55, right: 55),
|
|
child: Column(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
|
|
TextFormField(
|
|
focusNode: _nodeText2,
|
|
controller: _controller2,
|
|
decoration: InputDecoration(
|
|
contentPadding: EdgeInsets.only(left: 25, top: 5, bottom: 5),
|
|
labelText: t(widget.unit),
|
|
labelStyle: GoogleFonts.inter(fontSize: 20, color: Colors.orange[50], decorationColor: Colors.black12),
|
|
fillColor: Colors.black38,
|
|
filled: true,
|
|
border: OutlineInputBorder(
|
|
gapPadding: 8.0,
|
|
borderRadius: BorderRadius.circular(12.0),
|
|
borderSide: BorderSide(color: Colors.black26, width: 0.4),
|
|
),
|
|
),
|
|
keyboardType: TextInputType.number,
|
|
textInputAction: TextInputAction.next,
|
|
style: GoogleFonts.archivoBlack(fontSize: 75, color: Colors.orange[200]),
|
|
onChanged: (value) {
|
|
if (value.isNotEmpty) {
|
|
value = value.replaceFirst(",", ".");
|
|
value = value.replaceAll(RegExp(r'[^0-9.]'), "");
|
|
widget.onQuantityChanged(double.parse(value));
|
|
}
|
|
},
|
|
),
|
|
]));
|
|
|
|
return row;
|
|
}
|
|
}
|
|
|
|
class ExplanationWidget extends StatefulWidget {
|
|
final String? unitQuantityUnit;
|
|
final String unit;
|
|
final ActivityDone? tip;
|
|
final double? weight;
|
|
final int? repeats;
|
|
const ExplanationWidget({
|
|
Key? key,
|
|
this.unitQuantityUnit,
|
|
required this.unit,
|
|
this.tip,
|
|
this.weight,
|
|
this.repeats,
|
|
}) : super(key: key);
|
|
|
|
@override
|
|
_ExplanationWidgetState createState() => _ExplanationWidgetState();
|
|
}
|
|
|
|
class _ExplanationWidgetState extends State<ExplanationWidget> with Trans {
|
|
bool _selected = false;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
ExplanationExt expl = ExplanationExt(
|
|
tip: widget.tip!,
|
|
weight: widget.weight,
|
|
repeats: widget.repeats,
|
|
unitQuantityUnit: widget.unitQuantityUnit,
|
|
);
|
|
setContext(context);
|
|
return Material(
|
|
color: Colors.transparent,
|
|
child: Column(
|
|
children: [
|
|
Theme(
|
|
data: ThemeData(unselectedWidgetColor: Colors.white38),
|
|
child: CheckboxListTile(
|
|
value: _selected,
|
|
onChanged: (bool? checked) {
|
|
setState(() {
|
|
_selected = checked!;
|
|
});
|
|
},
|
|
checkColor: Colors.white,
|
|
activeColor: Colors.orange[600],
|
|
controlAffinity: ListTileControlAffinity.leading,
|
|
title: Text(
|
|
t("Show this tip no more"),
|
|
style: GoogleFonts.inter(color: Colors.grey),
|
|
))),
|
|
Padding(
|
|
padding: const EdgeInsets.only(top: 10, left: 10, right: 10),
|
|
child: Text(t(expl.getExplanation(Explanations.intro)),
|
|
maxLines: 5,
|
|
textAlign: TextAlign.center,
|
|
style: GoogleFonts.inter(
|
|
color: Colors.white,
|
|
fontWeight: FontWeight.bold,
|
|
fontSize: 16,
|
|
))),
|
|
Padding(
|
|
padding: const EdgeInsets.only(top: 10, left: 10, right: 10),
|
|
child: Text(t(expl.getExplanation(Explanations.introBold)),
|
|
maxLines: 5,
|
|
textAlign: TextAlign.center,
|
|
style: GoogleFonts.inter(
|
|
color: Colors.orange,
|
|
fontWeight: FontWeight.bold,
|
|
fontSize: 16,
|
|
))),
|
|
Stack(children: [
|
|
Padding(
|
|
padding: const EdgeInsets.only(top: 13, left: 18, right: 18),
|
|
child: Column(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
|
|
TextFormField(
|
|
decoration: InputDecoration(
|
|
contentPadding: EdgeInsets.only(left: 25, top: 5, bottom: 5),
|
|
labelText: t(widget.unitQuantityUnit!),
|
|
labelStyle: GoogleFonts.inter(fontSize: 20, color: Colors.yellow[50]),
|
|
fillColor: Colors.black38,
|
|
filled: true,
|
|
border: OutlineInputBorder(
|
|
gapPadding: 8.0,
|
|
borderRadius: BorderRadius.circular(12.0),
|
|
borderSide: BorderSide(color: Colors.white12, width: 0.4),
|
|
),
|
|
),
|
|
initialValue: ".",
|
|
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
|
textInputAction: TextInputAction.done,
|
|
style: GoogleFonts.archivoBlack(fontSize: 80, color: Colors.transparent),
|
|
onChanged: (value) {}),
|
|
])),
|
|
Container(
|
|
padding: EdgeInsets.only(top: 35, left: 35, right: 35),
|
|
child: Text(
|
|
t(expl.getExplanation(Explanations.explanationWeight)),
|
|
style: GoogleFonts.archivoBlack(fontSize: 23, color: Colors.yellow[300]),
|
|
)),
|
|
]),
|
|
Stack(children: [
|
|
Padding(
|
|
padding: const EdgeInsets.only(top: 10, left: 15, right: 15),
|
|
child: Column(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
|
|
TextFormField(
|
|
decoration: InputDecoration(
|
|
contentPadding: EdgeInsets.only(left: 25, top: 5, bottom: 5),
|
|
labelText: t(widget.unit),
|
|
labelStyle: GoogleFonts.inter(fontSize: 20, color: Colors.yellow[50]),
|
|
fillColor: Colors.black38,
|
|
filled: true,
|
|
border: OutlineInputBorder(
|
|
gapPadding: 8.0,
|
|
borderRadius: BorderRadius.circular(12.0),
|
|
borderSide: BorderSide(color: Colors.white12, width: 0.4),
|
|
),
|
|
),
|
|
initialValue: ".",
|
|
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
|
textInputAction: TextInputAction.done,
|
|
style: GoogleFonts.archivoBlack(fontSize: 80, color: Colors.transparent),
|
|
onChanged: (value) {}),
|
|
])),
|
|
Container(
|
|
padding: EdgeInsets.only(top: 25, left: 35, right: 35),
|
|
child: Text(
|
|
t(expl.getExplanation(Explanations.explanationRepeats)),
|
|
style: GoogleFonts.archivoBlack(fontSize: 23, color: Colors.yellow[300]),
|
|
)),
|
|
]),
|
|
Padding(
|
|
padding: const EdgeInsets.only(top: 10, left: 5, right: 5),
|
|
child: Text(
|
|
t("Don't forget, the app can give you only the right values, if you execute the task regurarly and after the exact instructions."),
|
|
maxLines: 5,
|
|
textAlign: TextAlign.center,
|
|
style: GoogleFonts.inter(
|
|
color: Colors.white,
|
|
fontSize: 14,
|
|
))),
|
|
Divider(),
|
|
GestureDetector(
|
|
onTap: () => {
|
|
TutorialWidget().close(),
|
|
if (_selected && widget.tip != null)
|
|
{
|
|
Cache().setActivityDonePrefs(widget.tip!),
|
|
}
|
|
},
|
|
child: Stack(
|
|
alignment: Alignment.center,
|
|
children: [
|
|
Image.asset('asset/icon/gomb_orange_c.png', width: 100, height: 45),
|
|
Text(
|
|
t("Got It"),
|
|
style: TextStyle(fontSize: 20, color: Colors.white),
|
|
),
|
|
],
|
|
)),
|
|
],
|
|
));
|
|
}
|
|
}
|