mirror of
https://github.com/wger-project/flutter.git
synced 2026-02-18 00:17:48 +01:00
Move common logic to SessionForm
Refactor and polish a bit the form in the log overview.
This commit is contained in:
@@ -33,6 +33,9 @@ class WorkoutSession {
|
||||
@JsonKey(required: true, name: 'routine')
|
||||
late int routineId;
|
||||
|
||||
@JsonKey(required: true, name: 'day')
|
||||
int? dayId;
|
||||
|
||||
@JsonKey(required: true, toJson: dateToYYYYMMDD)
|
||||
late DateTime date;
|
||||
|
||||
@@ -53,6 +56,7 @@ class WorkoutSession {
|
||||
|
||||
WorkoutSession({
|
||||
this.id,
|
||||
this.dayId,
|
||||
required this.routineId,
|
||||
this.impression = 2,
|
||||
this.notes = '',
|
||||
|
||||
@@ -9,10 +9,11 @@ part of 'session.dart';
|
||||
WorkoutSession _$WorkoutSessionFromJson(Map<String, dynamic> json) {
|
||||
$checkKeys(
|
||||
json,
|
||||
requiredKeys: const ['id', 'routine', 'date', 'impression', 'time_start', 'time_end'],
|
||||
requiredKeys: const ['id', 'routine', 'day', 'date', 'impression', 'time_start', 'time_end'],
|
||||
);
|
||||
return WorkoutSession(
|
||||
id: (json['id'] as num?)?.toInt(),
|
||||
dayId: (json['day'] as num?)?.toInt(),
|
||||
routineId: (json['routine'] as num).toInt(),
|
||||
impression: json['impression'] == null ? 2 : int.parse(json['impression'] as String),
|
||||
notes: json['notes'] as String? ?? '',
|
||||
@@ -29,6 +30,7 @@ WorkoutSession _$WorkoutSessionFromJson(Map<String, dynamic> json) {
|
||||
Map<String, dynamic> _$WorkoutSessionToJson(WorkoutSession instance) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'routine': instance.routineId,
|
||||
'day': instance.dayId,
|
||||
'date': dateToYYYYMMDD(instance.date),
|
||||
'impression': numToString(instance.impression),
|
||||
'notes': instance.notes,
|
||||
|
||||
240
lib/widgets/routines/forms/session.dart
Normal file
240
lib/widgets/routines/forms/session.dart
Normal file
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* This file is part of wger Workout Manager <https://github.com/wger-project>.
|
||||
* Copyright (C) 2020, 2021 wger Team
|
||||
*
|
||||
* wger Workout Manager is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wger Workout Manager is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'package:clock/clock.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:wger/exceptions/http_exception.dart';
|
||||
import 'package:wger/helpers/consts.dart';
|
||||
import 'package:wger/helpers/json.dart';
|
||||
import 'package:wger/helpers/ui.dart';
|
||||
import 'package:wger/l10n/generated/app_localizations.dart';
|
||||
import 'package:wger/models/workouts/session.dart';
|
||||
import 'package:wger/providers/routines.dart';
|
||||
|
||||
class SessionForm extends StatefulWidget {
|
||||
final WorkoutSession _session;
|
||||
final int _routineId;
|
||||
final Function()? _onSaved;
|
||||
|
||||
static const SLIDER_START = -0.5;
|
||||
|
||||
SessionForm(this._routineId, {Function()? onSaved, WorkoutSession? session, int? dayId})
|
||||
: _onSaved = onSaved,
|
||||
_session = session ??
|
||||
WorkoutSession(
|
||||
routineId: _routineId,
|
||||
dayId: dayId,
|
||||
impression: DEFAULT_IMPRESSION,
|
||||
date: clock.now(),
|
||||
timeEnd: TimeOfDay.now(),
|
||||
timeStart: TimeOfDay.now(),
|
||||
);
|
||||
|
||||
@override
|
||||
_SessionFormState createState() => _SessionFormState();
|
||||
}
|
||||
|
||||
class _SessionFormState extends State<SessionForm> {
|
||||
final _form = GlobalKey<FormState>();
|
||||
|
||||
final impressionController = TextEditingController();
|
||||
final notesController = TextEditingController();
|
||||
final timeStartController = TextEditingController();
|
||||
final timeEndController = TextEditingController();
|
||||
|
||||
/// Selected impression: bad, neutral, good
|
||||
var selectedImpression = [false, false, false];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
timeStartController.text = timeToString(widget._session.timeStart) ?? '';
|
||||
timeEndController.text = timeToString(widget._session.timeEnd) ?? '';
|
||||
notesController.text = widget._session.notes;
|
||||
|
||||
selectedImpression[widget._session.impression - 1] = true;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
impressionController.dispose();
|
||||
notesController.dispose();
|
||||
timeStartController.dispose();
|
||||
timeEndController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final routinesProvider = context.read<RoutinesProvider>();
|
||||
|
||||
return Form(
|
||||
key: _form,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
ToggleButtons(
|
||||
renderBorder: false,
|
||||
onPressed: (int index) {
|
||||
setState(() {
|
||||
for (int buttonIndex = 0; buttonIndex < selectedImpression.length; buttonIndex++) {
|
||||
widget._session.impression = index + 1;
|
||||
|
||||
if (buttonIndex == index) {
|
||||
selectedImpression[buttonIndex] = true;
|
||||
} else {
|
||||
selectedImpression[buttonIndex] = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
isSelected: selectedImpression,
|
||||
children: const [
|
||||
Icon(Icons.sentiment_very_dissatisfied),
|
||||
Icon(Icons.sentiment_neutral),
|
||||
Icon(Icons.sentiment_very_satisfied),
|
||||
],
|
||||
),
|
||||
TextFormField(
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context).notes,
|
||||
),
|
||||
maxLines: 3,
|
||||
controller: notesController,
|
||||
keyboardType: TextInputType.multiline,
|
||||
onFieldSubmitted: (_) {},
|
||||
onSaved: (newValue) {
|
||||
widget._session.notes = newValue!;
|
||||
},
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Flexible(
|
||||
child: TextFormField(
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context).timeStart,
|
||||
errorMaxLines: 2,
|
||||
),
|
||||
controller: timeStartController,
|
||||
onFieldSubmitted: (_) {},
|
||||
onTap: () async {
|
||||
// Stop keyboard from appearing
|
||||
FocusScope.of(context).requestFocus(FocusNode());
|
||||
|
||||
// Open time picker
|
||||
final pickedTime = await showTimePicker(
|
||||
context: context,
|
||||
initialTime: widget._session.timeStart ?? TimeOfDay.now(),
|
||||
);
|
||||
|
||||
if (pickedTime != null) {
|
||||
timeStartController.text = timeToString(pickedTime)!;
|
||||
widget._session.timeStart = pickedTime;
|
||||
}
|
||||
},
|
||||
onSaved: (newValue) {
|
||||
if (newValue != null && newValue.isNotEmpty) {
|
||||
widget._session.timeStart = stringToTime(newValue);
|
||||
}
|
||||
},
|
||||
validator: (_) {
|
||||
if (timeStartController.text.isEmpty && timeEndController.text.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
final TimeOfDay startTime = stringToTime(timeStartController.text);
|
||||
final TimeOfDay endTime = stringToTime(timeEndController.text);
|
||||
if (startTime.isAfter(endTime)) {
|
||||
return AppLocalizations.of(context).timeStartAhead;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Flexible(
|
||||
child: TextFormField(
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context).timeEnd,
|
||||
),
|
||||
controller: timeEndController,
|
||||
onFieldSubmitted: (_) {},
|
||||
onTap: () async {
|
||||
// Stop keyboard from appearing
|
||||
FocusScope.of(context).requestFocus(FocusNode());
|
||||
|
||||
// Open time picker
|
||||
final pickedTime = await showTimePicker(
|
||||
context: context,
|
||||
initialTime: widget._session.timeEnd ?? TimeOfDay.now(),
|
||||
);
|
||||
|
||||
if (pickedTime != null) {
|
||||
timeEndController.text = timeToString(pickedTime)!;
|
||||
widget._session.timeEnd = pickedTime;
|
||||
}
|
||||
},
|
||||
onSaved: (newValue) {
|
||||
if (newValue != null && newValue.isNotEmpty) {
|
||||
widget._session.timeEnd = stringToTime(newValue);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
ElevatedButton(
|
||||
key: const ValueKey('save-button'),
|
||||
child: Text(AppLocalizations.of(context).save),
|
||||
onPressed: () async {
|
||||
// Validate and save the current values to the weightEntry
|
||||
final isValid = _form.currentState!.validate();
|
||||
if (!isValid) {
|
||||
return;
|
||||
}
|
||||
_form.currentState!.save();
|
||||
|
||||
// Save the entry on the server
|
||||
try {
|
||||
if (widget._session.id == null) {
|
||||
await routinesProvider.addSession(widget._session, widget._routineId);
|
||||
} else {
|
||||
await routinesProvider.editSession(widget._session);
|
||||
}
|
||||
|
||||
if (context.mounted && widget._onSaved != null) {
|
||||
widget._onSaved!();
|
||||
}
|
||||
} on WgerHttpException catch (error) {
|
||||
if (context.mounted) {
|
||||
showHttpExceptionErrorDialog(error, context);
|
||||
}
|
||||
} catch (error) {
|
||||
if (context.mounted) {
|
||||
showErrorDialog(error, context);
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -194,6 +194,7 @@ class _GymModeState extends ConsumerState<GymMode> {
|
||||
_controller,
|
||||
ref.read(gymStateProvider).startTime,
|
||||
_exercisePages,
|
||||
dayId: widget._dayDataGym.day!.id!,
|
||||
),
|
||||
];
|
||||
|
||||
|
||||
@@ -17,240 +17,59 @@
|
||||
*/
|
||||
import 'package:clock/clock.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart' as provider;
|
||||
import 'package:wger/exceptions/http_exception.dart';
|
||||
import 'package:wger/helpers/consts.dart';
|
||||
import 'package:wger/helpers/json.dart';
|
||||
import 'package:wger/helpers/misc.dart';
|
||||
import 'package:wger/helpers/ui.dart';
|
||||
import 'package:wger/l10n/generated/app_localizations.dart';
|
||||
import 'package:wger/models/exercises/exercise.dart';
|
||||
import 'package:wger/models/workouts/routine.dart';
|
||||
import 'package:wger/models/workouts/session.dart';
|
||||
import 'package:wger/providers/routines.dart';
|
||||
import 'package:wger/widgets/routines/forms/session.dart';
|
||||
import 'package:wger/widgets/routines/gym_mode/navigation.dart';
|
||||
|
||||
class SessionPage extends StatefulWidget {
|
||||
class SessionPage extends StatelessWidget {
|
||||
final Routine _routine;
|
||||
late WorkoutSession _session;
|
||||
final WorkoutSession _session;
|
||||
final PageController _controller;
|
||||
final Map<Exercise, int> _exercisePages;
|
||||
final TimeOfDay _start;
|
||||
|
||||
SessionPage(
|
||||
this._routine,
|
||||
this._controller,
|
||||
this._start,
|
||||
this._exercisePages,
|
||||
) {
|
||||
_session = _routine.sessions.map((sessionApi) => sessionApi.session).firstWhere(
|
||||
(session) => session.date.isSameDayAs(clock.now()),
|
||||
orElse: () => WorkoutSession(
|
||||
routineId: _routine.id!,
|
||||
impression: DEFAULT_IMPRESSION,
|
||||
date: clock.now(),
|
||||
timeEnd: TimeOfDay.now(),
|
||||
timeStart: _start,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
_SessionPageState createState() => _SessionPageState();
|
||||
}
|
||||
|
||||
class _SessionPageState extends State<SessionPage> {
|
||||
final _form = GlobalKey<FormState>();
|
||||
final impressionController = TextEditingController();
|
||||
final notesController = TextEditingController();
|
||||
final timeStartController = TextEditingController();
|
||||
final timeEndController = TextEditingController();
|
||||
|
||||
/// Selected impression: bad, neutral, good
|
||||
var selectedImpression = [false, false, false];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
timeStartController.text = timeToString(widget._session.timeStart ?? widget._start)!;
|
||||
timeEndController.text = timeToString(widget._session.timeEnd ?? TimeOfDay.now())!;
|
||||
notesController.text = widget._session.notes;
|
||||
|
||||
selectedImpression[widget._session.impression - 1] = true;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
impressionController.dispose();
|
||||
notesController.dispose();
|
||||
timeStartController.dispose();
|
||||
timeEndController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
TimeOfDay start,
|
||||
this._exercisePages, {
|
||||
int? dayId,
|
||||
}) : _session = _routine.sessions.map((sessionApi) => sessionApi.session).firstWhere(
|
||||
(session) => session.date.isSameDayAs(clock.now()),
|
||||
orElse: () => WorkoutSession(
|
||||
dayId: dayId,
|
||||
routineId: _routine.id!,
|
||||
impression: DEFAULT_IMPRESSION,
|
||||
date: clock.now(),
|
||||
timeEnd: TimeOfDay.now(),
|
||||
timeStart: start,
|
||||
),
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final routinesProvider = context.read<RoutinesProvider>();
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
NavigationHeader(
|
||||
AppLocalizations.of(context).workoutSession,
|
||||
widget._controller,
|
||||
exercisePages: widget._exercisePages,
|
||||
_controller,
|
||||
exercisePages: _exercisePages,
|
||||
),
|
||||
const Divider(),
|
||||
Expanded(child: Container()),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||
child: Form(
|
||||
key: _form,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
ToggleButtons(
|
||||
renderBorder: false,
|
||||
onPressed: (int index) {
|
||||
setState(() {
|
||||
for (int buttonIndex = 0;
|
||||
buttonIndex < selectedImpression.length;
|
||||
buttonIndex++) {
|
||||
widget._session.impression = index + 1;
|
||||
|
||||
if (buttonIndex == index) {
|
||||
selectedImpression[buttonIndex] = true;
|
||||
} else {
|
||||
selectedImpression[buttonIndex] = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
isSelected: selectedImpression,
|
||||
children: const [
|
||||
Icon(Icons.sentiment_very_dissatisfied),
|
||||
Icon(Icons.sentiment_neutral),
|
||||
Icon(Icons.sentiment_very_satisfied),
|
||||
],
|
||||
),
|
||||
TextFormField(
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context).notes,
|
||||
),
|
||||
maxLines: 3,
|
||||
controller: notesController,
|
||||
keyboardType: TextInputType.multiline,
|
||||
onFieldSubmitted: (_) {},
|
||||
onSaved: (newValue) {
|
||||
widget._session.notes = newValue!;
|
||||
},
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Flexible(
|
||||
child: TextFormField(
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context).timeStart,
|
||||
errorMaxLines: 2,
|
||||
),
|
||||
controller: timeStartController,
|
||||
onFieldSubmitted: (_) {},
|
||||
onTap: () async {
|
||||
// Stop keyboard from appearing
|
||||
FocusScope.of(context).requestFocus(FocusNode());
|
||||
|
||||
// Open time picker
|
||||
final pickedTime = await showTimePicker(
|
||||
context: context,
|
||||
initialTime: widget._session.timeStart ?? TimeOfDay.now(),
|
||||
);
|
||||
|
||||
if (pickedTime != null) {
|
||||
timeStartController.text = timeToString(pickedTime)!;
|
||||
widget._session.timeStart = pickedTime;
|
||||
}
|
||||
},
|
||||
onSaved: (newValue) {
|
||||
widget._session.timeStart = stringToTime(newValue);
|
||||
},
|
||||
validator: (_) {
|
||||
final TimeOfDay startTime = stringToTime(timeStartController.text);
|
||||
final TimeOfDay endTime = stringToTime(timeEndController.text);
|
||||
if (startTime.isAfter(endTime)) {
|
||||
return AppLocalizations.of(context).timeStartAhead;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Flexible(
|
||||
child: TextFormField(
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context).timeEnd,
|
||||
),
|
||||
controller: timeEndController,
|
||||
onFieldSubmitted: (_) {},
|
||||
onTap: () async {
|
||||
// Stop keyboard from appearing
|
||||
FocusScope.of(context).requestFocus(FocusNode());
|
||||
|
||||
// Open time picker
|
||||
final pickedTime = await showTimePicker(
|
||||
context: context,
|
||||
initialTime: widget._session.timeEnd ?? TimeOfDay.now(),
|
||||
);
|
||||
|
||||
if (pickedTime != null) {
|
||||
timeEndController.text = timeToString(pickedTime)!;
|
||||
widget._session.timeEnd = pickedTime;
|
||||
}
|
||||
},
|
||||
onSaved: (newValue) {
|
||||
widget._session.timeEnd = stringToTime(newValue);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
ElevatedButton(
|
||||
key: const ValueKey('save-button'),
|
||||
child: Text(AppLocalizations.of(context).save),
|
||||
onPressed: () async {
|
||||
// Validate and save the current values to the weightEntry
|
||||
final isValid = _form.currentState!.validate();
|
||||
if (!isValid) {
|
||||
return;
|
||||
}
|
||||
_form.currentState!.save();
|
||||
|
||||
// Save the entry on the server
|
||||
try {
|
||||
if (widget._session.id == null) {
|
||||
await routinesProvider.addSession(widget._session, widget._routine.id!);
|
||||
} else {
|
||||
await routinesProvider.editSession(widget._session);
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
} on WgerHttpException catch (error) {
|
||||
if (mounted) {
|
||||
showHttpExceptionErrorDialog(error, context);
|
||||
}
|
||||
} catch (error) {
|
||||
if (mounted) {
|
||||
showErrorDialog(error, context);
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
child: SessionForm(
|
||||
_routine.id!,
|
||||
onSaved: () => Navigator.of(context).pop(),
|
||||
session: _session,
|
||||
),
|
||||
),
|
||||
NavigationFooter(widget._controller, 1, showNext: false),
|
||||
NavigationFooter(_controller, 1, showNext: false),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -18,73 +18,87 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:wger/helpers/colors.dart';
|
||||
import 'package:wger/helpers/json.dart';
|
||||
import 'package:wger/helpers/misc.dart';
|
||||
import 'package:wger/helpers/ui.dart';
|
||||
import 'package:wger/l10n/generated/app_localizations.dart';
|
||||
import 'package:wger/models/workouts/log.dart';
|
||||
import 'package:wger/models/workouts/routine.dart';
|
||||
import 'package:wger/models/workouts/session.dart';
|
||||
import 'package:wger/providers/routines.dart';
|
||||
import 'package:wger/widgets/measurements/charts.dart';
|
||||
import 'package:wger/widgets/routines/charts.dart';
|
||||
import 'package:wger/widgets/routines/forms/session.dart';
|
||||
|
||||
class SessionInfo extends StatelessWidget {
|
||||
class SessionInfo extends StatefulWidget {
|
||||
final WorkoutSession _session;
|
||||
|
||||
const SessionInfo(this._session);
|
||||
|
||||
@override
|
||||
State<SessionInfo> createState() => _SessionInfoState();
|
||||
}
|
||||
|
||||
class _SessionInfoState extends State<SessionInfo> {
|
||||
bool editMode = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final i18n = AppLocalizations.of(context);
|
||||
|
||||
return GestureDetector(
|
||||
onTap: (){
|
||||
final routinesProvider = context.read<RoutinesProvider>();
|
||||
showEditSessionDialog(context, _session, routinesProvider);
|
||||
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
ListTile(
|
||||
title: Text(
|
||||
i18n.workoutSession,
|
||||
style: Theme.of(context).textTheme.headlineSmall,
|
||||
),
|
||||
Text(
|
||||
DateFormat.yMd(Localizations.localeOf(context).languageCode).format(_session.date),
|
||||
style: Theme.of(context).textTheme.headlineSmall,
|
||||
subtitle: Text(
|
||||
DateFormat.yMd(Localizations.localeOf(context).languageCode)
|
||||
.format(widget._session.date),
|
||||
),
|
||||
const SizedBox(height: 8.0),
|
||||
_buildInfoRow(
|
||||
context,
|
||||
i18n.timeStart,
|
||||
_session.timeStart != null
|
||||
? MaterialLocalizations.of(context).formatTimeOfDay(_session.timeStart!)
|
||||
: '-/-',
|
||||
onTap: () => setState(() => editMode = !editMode),
|
||||
trailing: Icon(editMode ? Icons.edit_off : Icons.edit),
|
||||
contentPadding: EdgeInsets.zero,
|
||||
),
|
||||
if (editMode)
|
||||
SessionForm(
|
||||
widget._session.routineId,
|
||||
onSaved: () => setState(() => editMode = false),
|
||||
session: widget._session,
|
||||
)
|
||||
else
|
||||
Column(
|
||||
children: [
|
||||
_buildInfoRow(
|
||||
context,
|
||||
i18n.timeStart,
|
||||
widget._session.timeStart != null
|
||||
? MaterialLocalizations.of(context)
|
||||
.formatTimeOfDay(widget._session.timeStart!)
|
||||
: '-/-',
|
||||
),
|
||||
_buildInfoRow(
|
||||
context,
|
||||
i18n.timeEnd,
|
||||
widget._session.timeEnd != null
|
||||
? MaterialLocalizations.of(context).formatTimeOfDay(widget._session.timeEnd!)
|
||||
: '-/-',
|
||||
),
|
||||
_buildInfoRow(
|
||||
context,
|
||||
i18n.impression,
|
||||
widget._session.impressionAsString,
|
||||
),
|
||||
_buildInfoRow(
|
||||
context,
|
||||
i18n.notes,
|
||||
widget._session.notes.isNotEmpty ? widget._session.notes : '-/-',
|
||||
),
|
||||
],
|
||||
),
|
||||
_buildInfoRow(
|
||||
context,
|
||||
i18n.timeEnd,
|
||||
_session.timeEnd != null
|
||||
? MaterialLocalizations.of(context).formatTimeOfDay(_session.timeEnd!)
|
||||
: '-/-',
|
||||
),
|
||||
_buildInfoRow(
|
||||
context,
|
||||
i18n.impression,
|
||||
_session.impressionAsString,
|
||||
),
|
||||
_buildInfoRow(
|
||||
context,
|
||||
i18n.notes,
|
||||
_session.notes.isNotEmpty ? _session.notes : '-/-',
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -99,12 +113,7 @@ class SessionInfo extends StatelessWidget {
|
||||
'$label: ',
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
value,
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
),
|
||||
Expanded(child: Text(value)),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -207,114 +216,3 @@ class DayLogWidget extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
void showEditSessionDialog(BuildContext context, WorkoutSession session, RoutinesProvider routinesProvider) {
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
final notesController = TextEditingController(text: session.notes);
|
||||
final timeStartController = TextEditingController(text: timeToString(session.timeStart ?? TimeOfDay.now())!);
|
||||
final timeEndController = TextEditingController(text: timeToString(session.timeEnd ?? TimeOfDay.now())!);
|
||||
List<bool> selectedImpression = [false, false, false];
|
||||
selectedImpression[session.impression - 1] = true;
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (ctx) {
|
||||
return AlertDialog(
|
||||
title: Text('Edit Session (${session.date.toLocal().toString().split(' ')[0]})'),
|
||||
content: Form(
|
||||
key: _formKey,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ToggleButtons(
|
||||
renderBorder: false,
|
||||
isSelected: selectedImpression,
|
||||
onPressed: (index) {
|
||||
for (int i = 0; i < selectedImpression.length; i++) {
|
||||
selectedImpression[i] = (i == index);
|
||||
}
|
||||
session.impression = index + 1;
|
||||
},
|
||||
children: const [
|
||||
Icon(Icons.sentiment_very_dissatisfied),
|
||||
Icon(Icons.sentiment_neutral),
|
||||
Icon(Icons.sentiment_very_satisfied),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
TextFormField(
|
||||
decoration: const InputDecoration(labelText: 'Notes'),
|
||||
controller: notesController,
|
||||
maxLines: 3,
|
||||
onSaved: (value) => session.notes = value ?? '',
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
TextFormField(
|
||||
decoration: const InputDecoration(labelText: 'Start Time'),
|
||||
controller: timeStartController,
|
||||
onTap: () async {
|
||||
FocusScope.of(ctx).requestFocus(FocusNode());
|
||||
final picked = await showTimePicker(
|
||||
context: ctx,
|
||||
initialTime: session.timeStart ?? TimeOfDay.now(),
|
||||
);
|
||||
if (picked != null) {
|
||||
timeStartController.text = timeToString(picked)!;
|
||||
session.timeStart = picked;
|
||||
}
|
||||
},
|
||||
validator: (_) {
|
||||
final start = stringToTime(timeStartController.text);
|
||||
final end = stringToTime(timeEndController.text);
|
||||
if (start.isAfter(end)) {
|
||||
return 'Start time cannot be after end time.';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
onSaved: (val) => session.timeStart = stringToTime(val),
|
||||
),
|
||||
TextFormField(
|
||||
decoration: const InputDecoration(labelText: 'End Time'),
|
||||
controller: timeEndController,
|
||||
onTap: () async {
|
||||
FocusScope.of(ctx).requestFocus(FocusNode());
|
||||
final picked = await showTimePicker(
|
||||
context: ctx,
|
||||
initialTime: session.timeEnd ?? TimeOfDay.now(),
|
||||
);
|
||||
if (picked != null) {
|
||||
timeEndController.text = timeToString(picked)!;
|
||||
session.timeEnd = picked;
|
||||
}
|
||||
},
|
||||
onSaved: (val) => session.timeEnd = stringToTime(val),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(ctx).pop(),
|
||||
child: const Text('Cancel'),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
if (_formKey.currentState?.validate() ?? false) {
|
||||
_formKey.currentState?.save();
|
||||
|
||||
try {
|
||||
await routinesProvider.editSession(session);
|
||||
Navigator.of(ctx).pop();
|
||||
} catch (e) {
|
||||
showErrorDialog(e, context);
|
||||
}
|
||||
}
|
||||
},
|
||||
child: const Text('Save'),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
130
test/workout/forms/session_form_test.dart
Normal file
130
test/workout/forms/session_form_test.dart
Normal file
@@ -0,0 +1,130 @@
|
||||
// test/widgets/routines/forms/session_form_test.dart
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:wger/l10n/generated/app_localizations.dart';
|
||||
import 'package:wger/models/workouts/session.dart';
|
||||
import 'package:wger/providers/routines.dart';
|
||||
import 'package:wger/widgets/routines/forms/session.dart';
|
||||
|
||||
import 'session_form_test.mocks.dart';
|
||||
|
||||
@GenerateMocks([RoutinesProvider])
|
||||
void main() {
|
||||
late MockRoutinesProvider mockRoutinesProvider;
|
||||
|
||||
setUp(() {
|
||||
mockRoutinesProvider = MockRoutinesProvider();
|
||||
});
|
||||
|
||||
Future<void> pumpSessionForm(
|
||||
WidgetTester tester, {
|
||||
WorkoutSession? session,
|
||||
int routineId = 1,
|
||||
Function()? onSaved,
|
||||
}) async {
|
||||
await tester.pumpWidget(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider<RoutinesProvider>.value(
|
||||
value: mockRoutinesProvider,
|
||||
),
|
||||
],
|
||||
child: MaterialApp(
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
home: Scaffold(
|
||||
body: SessionForm(
|
||||
routineId,
|
||||
session: session,
|
||||
onSaved: onSaved,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
group('SessionForm', () {
|
||||
testWidgets('renders correctly for an existing session', (WidgetTester tester) async {
|
||||
//Arrange
|
||||
final existingSession = WorkoutSession(
|
||||
id: 1,
|
||||
routineId: 1,
|
||||
notes: 'Existing notes',
|
||||
impression: 1,
|
||||
date: DateTime.now(),
|
||||
timeStart: const TimeOfDay(hour: 10, minute: 0),
|
||||
timeEnd: const TimeOfDay(hour: 11, minute: 0),
|
||||
);
|
||||
|
||||
//Act
|
||||
await pumpSessionForm(tester, session: existingSession);
|
||||
|
||||
//Assert
|
||||
expect(find.widgetWithText(TextFormField, 'Existing notes'), findsOneWidget);
|
||||
final toggleButtons = tester.widget<ToggleButtons>(find.byType(ToggleButtons));
|
||||
expect(toggleButtons.isSelected, [true, false, false]); // Bad impression
|
||||
expect(find.widgetWithText(TextFormField, '10:00'), findsOneWidget);
|
||||
expect(find.widgetWithText(TextFormField, '11:00'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('saves a new session', (WidgetTester tester) async {
|
||||
// Arrange
|
||||
bool onSavedCalled = false;
|
||||
await pumpSessionForm(tester, onSaved: () => onSavedCalled = true);
|
||||
|
||||
when(mockRoutinesProvider.addSession(any, any)).thenAnswer(
|
||||
(_) async => WorkoutSession(id: 1, routineId: 1, date: DateTime.now()),
|
||||
);
|
||||
|
||||
// Act
|
||||
await tester.enterText(find.widgetWithText(TextFormField, 'Notes'), 'New session notes');
|
||||
await tester.tap(find.byKey(const ValueKey('save-button')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Assert
|
||||
verify(mockRoutinesProvider.addSession(any, 1)).called(1);
|
||||
expect(onSavedCalled, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('saves an existing session', (WidgetTester tester) async {
|
||||
// Arrange
|
||||
bool onSavedCalled = false;
|
||||
final existingSession = WorkoutSession(
|
||||
id: 1,
|
||||
routineId: 1,
|
||||
notes: 'Old notes',
|
||||
impression: 2,
|
||||
date: DateTime.now(),
|
||||
);
|
||||
when(mockRoutinesProvider.editSession(any)).thenAnswer(
|
||||
(_) async => WorkoutSession(
|
||||
id: 1,
|
||||
routineId: 1,
|
||||
date: DateTime.now(),
|
||||
),
|
||||
);
|
||||
|
||||
// Act
|
||||
await pumpSessionForm(
|
||||
tester,
|
||||
session: existingSession,
|
||||
onSaved: () => onSavedCalled = true,
|
||||
);
|
||||
await tester.enterText(find.widgetWithText(TextFormField, 'Old notes'), 'Updated notes');
|
||||
await tester.tap(find.byKey(const ValueKey('save-button')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Assert
|
||||
final captured =
|
||||
verify(mockRoutinesProvider.editSession(captureAny)).captured.single as WorkoutSession;
|
||||
expect(captured.notes, 'Updated notes');
|
||||
expect(onSavedCalled, isTrue);
|
||||
});
|
||||
});
|
||||
}
|
||||
827
test/workout/forms/session_form_test.mocks.dart
Normal file
827
test/workout/forms/session_form_test.mocks.dart
Normal file
@@ -0,0 +1,827 @@
|
||||
// Mocks generated by Mockito 5.4.6 from annotations
|
||||
// in wger/test/workout/forms/session_form_test.dart.
|
||||
// Do not manually edit this file.
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'dart:async' as _i13;
|
||||
import 'dart:ui' as _i16;
|
||||
|
||||
import 'package:mockito/mockito.dart' as _i1;
|
||||
import 'package:mockito/src/dummies.dart' as _i15;
|
||||
import 'package:wger/models/workouts/base_config.dart' as _i9;
|
||||
import 'package:wger/models/workouts/day.dart' as _i6;
|
||||
import 'package:wger/models/workouts/day_data.dart' as _i14;
|
||||
import 'package:wger/models/workouts/log.dart' as _i11;
|
||||
import 'package:wger/models/workouts/repetition_unit.dart' as _i4;
|
||||
import 'package:wger/models/workouts/routine.dart' as _i5;
|
||||
import 'package:wger/models/workouts/session.dart' as _i10;
|
||||
import 'package:wger/models/workouts/slot.dart' as _i7;
|
||||
import 'package:wger/models/workouts/slot_entry.dart' as _i8;
|
||||
import 'package:wger/models/workouts/weight_unit.dart' as _i3;
|
||||
import 'package:wger/providers/base_provider.dart' as _i2;
|
||||
import 'package:wger/providers/routines.dart' as _i12;
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: avoid_redundant_argument_values
|
||||
// ignore_for_file: avoid_setters_without_getters
|
||||
// ignore_for_file: comment_references
|
||||
// ignore_for_file: deprecated_member_use
|
||||
// ignore_for_file: deprecated_member_use_from_same_package
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: invalid_use_of_visible_for_testing_member
|
||||
// ignore_for_file: must_be_immutable
|
||||
// ignore_for_file: prefer_const_constructors
|
||||
// ignore_for_file: unnecessary_parenthesis
|
||||
// ignore_for_file: camel_case_types
|
||||
// ignore_for_file: subtype_of_sealed_class
|
||||
|
||||
class _FakeWgerBaseProvider_0 extends _i1.SmartFake implements _i2.WgerBaseProvider {
|
||||
_FakeWgerBaseProvider_0(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
class _FakeWeightUnit_1 extends _i1.SmartFake implements _i3.WeightUnit {
|
||||
_FakeWeightUnit_1(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
class _FakeRepetitionUnit_2 extends _i1.SmartFake implements _i4.RepetitionUnit {
|
||||
_FakeRepetitionUnit_2(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
class _FakeRoutine_3 extends _i1.SmartFake implements _i5.Routine {
|
||||
_FakeRoutine_3(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
class _FakeDay_4 extends _i1.SmartFake implements _i6.Day {
|
||||
_FakeDay_4(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
class _FakeSlot_5 extends _i1.SmartFake implements _i7.Slot {
|
||||
_FakeSlot_5(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
class _FakeSlotEntry_6 extends _i1.SmartFake implements _i8.SlotEntry {
|
||||
_FakeSlotEntry_6(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
class _FakeBaseConfig_7 extends _i1.SmartFake implements _i9.BaseConfig {
|
||||
_FakeBaseConfig_7(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
class _FakeWorkoutSession_8 extends _i1.SmartFake implements _i10.WorkoutSession {
|
||||
_FakeWorkoutSession_8(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
class _FakeLog_9 extends _i1.SmartFake implements _i11.Log {
|
||||
_FakeLog_9(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
/// A class which mocks [RoutinesProvider].
|
||||
///
|
||||
/// See the documentation for Mockito's code generation for more information.
|
||||
class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
|
||||
MockRoutinesProvider() {
|
||||
_i1.throwOnMissingStub(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_i2.WgerBaseProvider get baseProvider => (super.noSuchMethod(
|
||||
Invocation.getter(#baseProvider),
|
||||
returnValue: _FakeWgerBaseProvider_0(
|
||||
this,
|
||||
Invocation.getter(#baseProvider),
|
||||
),
|
||||
) as _i2.WgerBaseProvider);
|
||||
|
||||
@override
|
||||
List<_i5.Routine> get items => (super.noSuchMethod(
|
||||
Invocation.getter(#items),
|
||||
returnValue: <_i5.Routine>[],
|
||||
) as List<_i5.Routine>);
|
||||
|
||||
@override
|
||||
List<_i3.WeightUnit> get weightUnits => (super.noSuchMethod(
|
||||
Invocation.getter(#weightUnits),
|
||||
returnValue: <_i3.WeightUnit>[],
|
||||
) as List<_i3.WeightUnit>);
|
||||
|
||||
@override
|
||||
_i3.WeightUnit get defaultWeightUnit => (super.noSuchMethod(
|
||||
Invocation.getter(#defaultWeightUnit),
|
||||
returnValue: _FakeWeightUnit_1(
|
||||
this,
|
||||
Invocation.getter(#defaultWeightUnit),
|
||||
),
|
||||
) as _i3.WeightUnit);
|
||||
|
||||
@override
|
||||
List<_i4.RepetitionUnit> get repetitionUnits => (super.noSuchMethod(
|
||||
Invocation.getter(#repetitionUnits),
|
||||
returnValue: <_i4.RepetitionUnit>[],
|
||||
) as List<_i4.RepetitionUnit>);
|
||||
|
||||
@override
|
||||
_i4.RepetitionUnit get defaultRepetitionUnit => (super.noSuchMethod(
|
||||
Invocation.getter(#defaultRepetitionUnit),
|
||||
returnValue: _FakeRepetitionUnit_2(
|
||||
this,
|
||||
Invocation.getter(#defaultRepetitionUnit),
|
||||
),
|
||||
) as _i4.RepetitionUnit);
|
||||
|
||||
@override
|
||||
set activeRoutine(_i5.Routine? _activeRoutine) => super.noSuchMethod(
|
||||
Invocation.setter(
|
||||
#activeRoutine,
|
||||
_activeRoutine,
|
||||
),
|
||||
returnValueForMissingStub: null,
|
||||
);
|
||||
|
||||
@override
|
||||
set weightUnits(List<_i3.WeightUnit>? weightUnits) => super.noSuchMethod(
|
||||
Invocation.setter(
|
||||
#weightUnits,
|
||||
weightUnits,
|
||||
),
|
||||
returnValueForMissingStub: null,
|
||||
);
|
||||
|
||||
@override
|
||||
set repetitionUnits(List<_i4.RepetitionUnit>? repetitionUnits) => super.noSuchMethod(
|
||||
Invocation.setter(
|
||||
#repetitionUnits,
|
||||
repetitionUnits,
|
||||
),
|
||||
returnValueForMissingStub: null,
|
||||
);
|
||||
|
||||
@override
|
||||
bool get hasListeners => (super.noSuchMethod(
|
||||
Invocation.getter(#hasListeners),
|
||||
returnValue: false,
|
||||
) as bool);
|
||||
|
||||
@override
|
||||
void clear() => super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#clear,
|
||||
[],
|
||||
),
|
||||
returnValueForMissingStub: null,
|
||||
);
|
||||
|
||||
@override
|
||||
_i3.WeightUnit findWeightUnitById(int? id) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#findWeightUnitById,
|
||||
[id],
|
||||
),
|
||||
returnValue: _FakeWeightUnit_1(
|
||||
this,
|
||||
Invocation.method(
|
||||
#findWeightUnitById,
|
||||
[id],
|
||||
),
|
||||
),
|
||||
) as _i3.WeightUnit);
|
||||
|
||||
@override
|
||||
_i4.RepetitionUnit findRepetitionUnitById(int? id) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#findRepetitionUnitById,
|
||||
[id],
|
||||
),
|
||||
returnValue: _FakeRepetitionUnit_2(
|
||||
this,
|
||||
Invocation.method(
|
||||
#findRepetitionUnitById,
|
||||
[id],
|
||||
),
|
||||
),
|
||||
) as _i4.RepetitionUnit);
|
||||
|
||||
@override
|
||||
List<_i5.Routine> getPlans() => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getPlans,
|
||||
[],
|
||||
),
|
||||
returnValue: <_i5.Routine>[],
|
||||
) as List<_i5.Routine>);
|
||||
|
||||
@override
|
||||
_i5.Routine findById(int? id) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#findById,
|
||||
[id],
|
||||
),
|
||||
returnValue: _FakeRoutine_3(
|
||||
this,
|
||||
Invocation.method(
|
||||
#findById,
|
||||
[id],
|
||||
),
|
||||
),
|
||||
) as _i5.Routine);
|
||||
|
||||
@override
|
||||
int findIndexById(int? id) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#findIndexById,
|
||||
[id],
|
||||
),
|
||||
returnValue: 0,
|
||||
) as int);
|
||||
|
||||
@override
|
||||
void setActiveRoutine() => super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#setActiveRoutine,
|
||||
[],
|
||||
),
|
||||
returnValueForMissingStub: null,
|
||||
);
|
||||
|
||||
@override
|
||||
_i13.Future<void> fetchAndSetAllRoutinesFull() => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#fetchAndSetAllRoutinesFull,
|
||||
[],
|
||||
),
|
||||
returnValue: _i13.Future<void>.value(),
|
||||
returnValueForMissingStub: _i13.Future<void>.value(),
|
||||
) as _i13.Future<void>);
|
||||
|
||||
@override
|
||||
_i13.Future<void> fetchAndSetAllRoutinesSparse() => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#fetchAndSetAllRoutinesSparse,
|
||||
[],
|
||||
),
|
||||
returnValue: _i13.Future<void>.value(),
|
||||
returnValueForMissingStub: _i13.Future<void>.value(),
|
||||
) as _i13.Future<void>);
|
||||
|
||||
@override
|
||||
_i13.Future<void> setExercisesAndUnits(List<_i14.DayData>? entries) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#setExercisesAndUnits,
|
||||
[entries],
|
||||
),
|
||||
returnValue: _i13.Future<void>.value(),
|
||||
returnValueForMissingStub: _i13.Future<void>.value(),
|
||||
) as _i13.Future<void>);
|
||||
|
||||
@override
|
||||
_i13.Future<_i5.Routine> fetchAndSetRoutineSparse(int? planId) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#fetchAndSetRoutineSparse,
|
||||
[planId],
|
||||
),
|
||||
returnValue: _i13.Future<_i5.Routine>.value(_FakeRoutine_3(
|
||||
this,
|
||||
Invocation.method(
|
||||
#fetchAndSetRoutineSparse,
|
||||
[planId],
|
||||
),
|
||||
)),
|
||||
) as _i13.Future<_i5.Routine>);
|
||||
|
||||
@override
|
||||
_i13.Future<_i5.Routine> fetchAndSetRoutineFull(int? routineId) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#fetchAndSetRoutineFull,
|
||||
[routineId],
|
||||
),
|
||||
returnValue: _i13.Future<_i5.Routine>.value(_FakeRoutine_3(
|
||||
this,
|
||||
Invocation.method(
|
||||
#fetchAndSetRoutineFull,
|
||||
[routineId],
|
||||
),
|
||||
)),
|
||||
) as _i13.Future<_i5.Routine>);
|
||||
|
||||
@override
|
||||
_i13.Future<_i5.Routine> addRoutine(_i5.Routine? routine) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#addRoutine,
|
||||
[routine],
|
||||
),
|
||||
returnValue: _i13.Future<_i5.Routine>.value(_FakeRoutine_3(
|
||||
this,
|
||||
Invocation.method(
|
||||
#addRoutine,
|
||||
[routine],
|
||||
),
|
||||
)),
|
||||
) as _i13.Future<_i5.Routine>);
|
||||
|
||||
@override
|
||||
_i13.Future<void> editRoutine(_i5.Routine? routine) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#editRoutine,
|
||||
[routine],
|
||||
),
|
||||
returnValue: _i13.Future<void>.value(),
|
||||
returnValueForMissingStub: _i13.Future<void>.value(),
|
||||
) as _i13.Future<void>);
|
||||
|
||||
@override
|
||||
_i13.Future<void> deleteRoutine(int? id) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#deleteRoutine,
|
||||
[id],
|
||||
),
|
||||
returnValue: _i13.Future<void>.value(),
|
||||
returnValueForMissingStub: _i13.Future<void>.value(),
|
||||
) as _i13.Future<void>);
|
||||
|
||||
@override
|
||||
_i13.Future<void> fetchAndSetRepetitionUnits() => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#fetchAndSetRepetitionUnits,
|
||||
[],
|
||||
),
|
||||
returnValue: _i13.Future<void>.value(),
|
||||
returnValueForMissingStub: _i13.Future<void>.value(),
|
||||
) as _i13.Future<void>);
|
||||
|
||||
@override
|
||||
_i13.Future<void> fetchAndSetWeightUnits() => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#fetchAndSetWeightUnits,
|
||||
[],
|
||||
),
|
||||
returnValue: _i13.Future<void>.value(),
|
||||
returnValueForMissingStub: _i13.Future<void>.value(),
|
||||
) as _i13.Future<void>);
|
||||
|
||||
@override
|
||||
_i13.Future<void> fetchAndSetUnits() => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#fetchAndSetUnits,
|
||||
[],
|
||||
),
|
||||
returnValue: _i13.Future<void>.value(),
|
||||
returnValueForMissingStub: _i13.Future<void>.value(),
|
||||
) as _i13.Future<void>);
|
||||
|
||||
@override
|
||||
_i13.Future<_i6.Day> addDay(_i6.Day? day) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#addDay,
|
||||
[day],
|
||||
),
|
||||
returnValue: _i13.Future<_i6.Day>.value(_FakeDay_4(
|
||||
this,
|
||||
Invocation.method(
|
||||
#addDay,
|
||||
[day],
|
||||
),
|
||||
)),
|
||||
) as _i13.Future<_i6.Day>);
|
||||
|
||||
@override
|
||||
_i13.Future<void> editDay(_i6.Day? day) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#editDay,
|
||||
[day],
|
||||
),
|
||||
returnValue: _i13.Future<void>.value(),
|
||||
returnValueForMissingStub: _i13.Future<void>.value(),
|
||||
) as _i13.Future<void>);
|
||||
|
||||
@override
|
||||
_i13.Future<void> editDays(List<_i6.Day>? days) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#editDays,
|
||||
[days],
|
||||
),
|
||||
returnValue: _i13.Future<void>.value(),
|
||||
returnValueForMissingStub: _i13.Future<void>.value(),
|
||||
) as _i13.Future<void>);
|
||||
|
||||
@override
|
||||
_i13.Future<void> deleteDay(int? dayId) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#deleteDay,
|
||||
[dayId],
|
||||
),
|
||||
returnValue: _i13.Future<void>.value(),
|
||||
returnValueForMissingStub: _i13.Future<void>.value(),
|
||||
) as _i13.Future<void>);
|
||||
|
||||
@override
|
||||
_i13.Future<_i7.Slot> addSlot(
|
||||
_i7.Slot? slot,
|
||||
int? routineId,
|
||||
) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#addSlot,
|
||||
[
|
||||
slot,
|
||||
routineId,
|
||||
],
|
||||
),
|
||||
returnValue: _i13.Future<_i7.Slot>.value(_FakeSlot_5(
|
||||
this,
|
||||
Invocation.method(
|
||||
#addSlot,
|
||||
[
|
||||
slot,
|
||||
routineId,
|
||||
],
|
||||
),
|
||||
)),
|
||||
) as _i13.Future<_i7.Slot>);
|
||||
|
||||
@override
|
||||
_i13.Future<void> deleteSlot(
|
||||
int? slotId,
|
||||
int? routineId,
|
||||
) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#deleteSlot,
|
||||
[
|
||||
slotId,
|
||||
routineId,
|
||||
],
|
||||
),
|
||||
returnValue: _i13.Future<void>.value(),
|
||||
returnValueForMissingStub: _i13.Future<void>.value(),
|
||||
) as _i13.Future<void>);
|
||||
|
||||
@override
|
||||
_i13.Future<void> editSlot(
|
||||
_i7.Slot? slot,
|
||||
int? routineId,
|
||||
) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#editSlot,
|
||||
[
|
||||
slot,
|
||||
routineId,
|
||||
],
|
||||
),
|
||||
returnValue: _i13.Future<void>.value(),
|
||||
returnValueForMissingStub: _i13.Future<void>.value(),
|
||||
) as _i13.Future<void>);
|
||||
|
||||
@override
|
||||
_i13.Future<void> editSlots(
|
||||
List<_i7.Slot>? slots,
|
||||
int? routineId,
|
||||
) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#editSlots,
|
||||
[
|
||||
slots,
|
||||
routineId,
|
||||
],
|
||||
),
|
||||
returnValue: _i13.Future<void>.value(),
|
||||
returnValueForMissingStub: _i13.Future<void>.value(),
|
||||
) as _i13.Future<void>);
|
||||
|
||||
@override
|
||||
_i13.Future<_i8.SlotEntry> addSlotEntry(
|
||||
_i8.SlotEntry? entry,
|
||||
int? routineId,
|
||||
) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#addSlotEntry,
|
||||
[
|
||||
entry,
|
||||
routineId,
|
||||
],
|
||||
),
|
||||
returnValue: _i13.Future<_i8.SlotEntry>.value(_FakeSlotEntry_6(
|
||||
this,
|
||||
Invocation.method(
|
||||
#addSlotEntry,
|
||||
[
|
||||
entry,
|
||||
routineId,
|
||||
],
|
||||
),
|
||||
)),
|
||||
) as _i13.Future<_i8.SlotEntry>);
|
||||
|
||||
@override
|
||||
_i13.Future<void> deleteSlotEntry(
|
||||
int? id,
|
||||
int? routineId,
|
||||
) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#deleteSlotEntry,
|
||||
[
|
||||
id,
|
||||
routineId,
|
||||
],
|
||||
),
|
||||
returnValue: _i13.Future<void>.value(),
|
||||
returnValueForMissingStub: _i13.Future<void>.value(),
|
||||
) as _i13.Future<void>);
|
||||
|
||||
@override
|
||||
_i13.Future<void> editSlotEntry(
|
||||
_i8.SlotEntry? entry,
|
||||
int? routineId,
|
||||
) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#editSlotEntry,
|
||||
[
|
||||
entry,
|
||||
routineId,
|
||||
],
|
||||
),
|
||||
returnValue: _i13.Future<void>.value(),
|
||||
returnValueForMissingStub: _i13.Future<void>.value(),
|
||||
) as _i13.Future<void>);
|
||||
|
||||
@override
|
||||
String getConfigUrl(_i8.ConfigType? type) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getConfigUrl,
|
||||
[type],
|
||||
),
|
||||
returnValue: _i15.dummyValue<String>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getConfigUrl,
|
||||
[type],
|
||||
),
|
||||
),
|
||||
) as String);
|
||||
|
||||
@override
|
||||
_i13.Future<_i9.BaseConfig> editConfig(
|
||||
_i9.BaseConfig? config,
|
||||
_i8.ConfigType? type,
|
||||
) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#editConfig,
|
||||
[
|
||||
config,
|
||||
type,
|
||||
],
|
||||
),
|
||||
returnValue: _i13.Future<_i9.BaseConfig>.value(_FakeBaseConfig_7(
|
||||
this,
|
||||
Invocation.method(
|
||||
#editConfig,
|
||||
[
|
||||
config,
|
||||
type,
|
||||
],
|
||||
),
|
||||
)),
|
||||
) as _i13.Future<_i9.BaseConfig>);
|
||||
|
||||
@override
|
||||
_i13.Future<_i9.BaseConfig> addConfig(
|
||||
_i9.BaseConfig? config,
|
||||
_i8.ConfigType? type,
|
||||
) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#addConfig,
|
||||
[
|
||||
config,
|
||||
type,
|
||||
],
|
||||
),
|
||||
returnValue: _i13.Future<_i9.BaseConfig>.value(_FakeBaseConfig_7(
|
||||
this,
|
||||
Invocation.method(
|
||||
#addConfig,
|
||||
[
|
||||
config,
|
||||
type,
|
||||
],
|
||||
),
|
||||
)),
|
||||
) as _i13.Future<_i9.BaseConfig>);
|
||||
|
||||
@override
|
||||
_i13.Future<void> deleteConfig(
|
||||
int? id,
|
||||
_i8.ConfigType? type,
|
||||
) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#deleteConfig,
|
||||
[
|
||||
id,
|
||||
type,
|
||||
],
|
||||
),
|
||||
returnValue: _i13.Future<void>.value(),
|
||||
returnValueForMissingStub: _i13.Future<void>.value(),
|
||||
) as _i13.Future<void>);
|
||||
|
||||
@override
|
||||
_i13.Future<void> handleConfig(
|
||||
_i8.SlotEntry? entry,
|
||||
String? input,
|
||||
_i8.ConfigType? type,
|
||||
) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#handleConfig,
|
||||
[
|
||||
entry,
|
||||
input,
|
||||
type,
|
||||
],
|
||||
),
|
||||
returnValue: _i13.Future<void>.value(),
|
||||
returnValueForMissingStub: _i13.Future<void>.value(),
|
||||
) as _i13.Future<void>);
|
||||
|
||||
@override
|
||||
_i13.Future<List<_i10.WorkoutSession>> fetchSessionData() => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#fetchSessionData,
|
||||
[],
|
||||
),
|
||||
returnValue: _i13.Future<List<_i10.WorkoutSession>>.value(<_i10.WorkoutSession>[]),
|
||||
) as _i13.Future<List<_i10.WorkoutSession>>);
|
||||
|
||||
@override
|
||||
_i13.Future<_i10.WorkoutSession> addSession(
|
||||
_i10.WorkoutSession? session,
|
||||
int? routineId,
|
||||
) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#addSession,
|
||||
[
|
||||
session,
|
||||
routineId,
|
||||
],
|
||||
),
|
||||
returnValue: _i13.Future<_i10.WorkoutSession>.value(_FakeWorkoutSession_8(
|
||||
this,
|
||||
Invocation.method(
|
||||
#addSession,
|
||||
[
|
||||
session,
|
||||
routineId,
|
||||
],
|
||||
),
|
||||
)),
|
||||
) as _i13.Future<_i10.WorkoutSession>);
|
||||
|
||||
@override
|
||||
_i13.Future<_i10.WorkoutSession> editSession(_i10.WorkoutSession? session) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#editSession,
|
||||
[session],
|
||||
),
|
||||
returnValue: _i13.Future<_i10.WorkoutSession>.value(_FakeWorkoutSession_8(
|
||||
this,
|
||||
Invocation.method(
|
||||
#editSession,
|
||||
[session],
|
||||
),
|
||||
)),
|
||||
) as _i13.Future<_i10.WorkoutSession>);
|
||||
|
||||
@override
|
||||
_i13.Future<_i11.Log> addLog(_i11.Log? log) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#addLog,
|
||||
[log],
|
||||
),
|
||||
returnValue: _i13.Future<_i11.Log>.value(_FakeLog_9(
|
||||
this,
|
||||
Invocation.method(
|
||||
#addLog,
|
||||
[log],
|
||||
),
|
||||
)),
|
||||
) as _i13.Future<_i11.Log>);
|
||||
|
||||
@override
|
||||
_i13.Future<void> deleteLog(
|
||||
int? logId,
|
||||
int? routineId,
|
||||
) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#deleteLog,
|
||||
[
|
||||
logId,
|
||||
routineId,
|
||||
],
|
||||
),
|
||||
returnValue: _i13.Future<void>.value(),
|
||||
returnValueForMissingStub: _i13.Future<void>.value(),
|
||||
) as _i13.Future<void>);
|
||||
|
||||
@override
|
||||
void addListener(_i16.VoidCallback? listener) => super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#addListener,
|
||||
[listener],
|
||||
),
|
||||
returnValueForMissingStub: null,
|
||||
);
|
||||
|
||||
@override
|
||||
void removeListener(_i16.VoidCallback? listener) => super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#removeListener,
|
||||
[listener],
|
||||
),
|
||||
returnValueForMissingStub: null,
|
||||
);
|
||||
|
||||
@override
|
||||
void dispose() => super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#dispose,
|
||||
[],
|
||||
),
|
||||
returnValueForMissingStub: null,
|
||||
);
|
||||
|
||||
@override
|
||||
void notifyListeners() => super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#notifyListeners,
|
||||
[],
|
||||
),
|
||||
returnValueForMissingStub: null,
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user