Polish the add plate widget

This commit is contained in:
Roland Geider
2025-05-23 13:39:53 +02:00
parent 5a8df8936e
commit 0d36fe4bc3
11 changed files with 220 additions and 239 deletions

View File

@@ -130,3 +130,5 @@ const LIBERAPAY_URL = 'https://liberapay.com/wger';
/// the milliseconds themselves can cause the application to crash since it runs /// the milliseconds themselves can cause the application to crash since it runs
/// out of memory... /// out of memory...
const double CHART_MILLISECOND_FACTOR = 100000.0; const double CHART_MILLISECOND_FACTOR = 100000.0;
enum WeightUnitEnum { kg, lb }

View File

@@ -19,13 +19,14 @@
/// Calculates the number of plates needed to reach a specific weight /// Calculates the number of plates needed to reach a specific weight
List<num> plateCalculator(num totalWeight, num barWeight, List<num> plates) { List<num> plateCalculator(num totalWeight, num barWeight, List<num> plates) {
final List<num> result = []; final List<num> result = [];
final sortedPlates = List.of(plates)..sort();
// Weight is less than the bar // Weight is less than the bar
if (totalWeight < barWeight) { if (totalWeight < barWeight) {
return []; return [];
} }
if (plates.isEmpty) { if (sortedPlates.isEmpty) {
return []; return [];
} }
@@ -33,12 +34,12 @@ List<num> plateCalculator(num totalWeight, num barWeight, List<num> plates) {
totalWeight = (totalWeight - barWeight) / 2; totalWeight = (totalWeight - barWeight) / 2;
// Weight can't be divided with the smallest plate // Weight can't be divided with the smallest plate
if (totalWeight % plates.first > 0) { if (totalWeight % sortedPlates.first > 0) {
return []; return [];
} }
// Iterate through the plates, beginning with the biggest ones // Iterate through the plates, beginning with the biggest ones
for (final plate in plates.reversed) { for (final plate in sortedPlates.reversed) {
while (totalWeight >= plate) { while (totalWeight >= plate) {
totalWeight -= plate; totalWeight -= plate;
result.add(plate); result.add(plate);

View File

@@ -90,20 +90,20 @@ void main() async {
await PreferenceHelper.instance.migrationSupportFunctionForSharedPreferences(); await PreferenceHelper.instance.migrationSupportFunctionForSharedPreferences();
// Catch errors from Flutter itself (widget build, layout, paint, etc.) // Catch errors from Flutter itself (widget build, layout, paint, etc.)
FlutterError.onError = (FlutterErrorDetails details) { // FlutterError.onError = (FlutterErrorDetails details) {
final stack = details.stack ?? StackTrace.empty; // final stack = details.stack ?? StackTrace.empty;
if (kDebugMode) { // if (kDebugMode) {
FlutterError.dumpErrorToConsole(details); // FlutterError.dumpErrorToConsole(details);
} // }
//
// Don't show the full error dialog for network image loading errors. // // Don't show the full error dialog for network image loading errors.
if (details.exception is NetworkImageLoadException) { // if (details.exception is NetworkImageLoadException) {
return; // return;
} // }
//
showGeneralErrorDialog(details.exception, stack); // // showGeneralErrorDialog(details.exception, stack);
// throw details.exception; // throw details.exception;
}; // };
// Catch errors that happen outside of the Flutter framework (e.g., in async operations) // Catch errors that happen outside of the Flutter framework (e.g., in async operations)
PlatformDispatcher.instance.onError = (error, stack) { PlatformDispatcher.instance.onError = (error, stack) {
@@ -114,8 +114,8 @@ void main() async {
if (error is WgerHttpException) { if (error is WgerHttpException) {
showHttpExceptionErrorDialog(error); showHttpExceptionErrorDialog(error);
} else { } else {
showGeneralErrorDialog(error, stack); // showGeneralErrorDialog(error, stack);
// throw error; throw error;
} }
// Return true to indicate that the error has been handled. // Return true to indicate that the error has been handled.

View File

@@ -2,10 +2,14 @@ import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:logging/logging.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:wger/helpers/consts.dart';
import 'package:wger/helpers/gym_mode.dart'; import 'package:wger/helpers/gym_mode.dart';
import 'package:wger/helpers/shared_preferences.dart';
const DEFAULT_KG_PLATES = [2.5, 5, 10, 15, 20, 25]; const DEFAULT_KG_PLATES = [2.5, 5, 10, 15, 20, 25];
const DEFAULT_LB_PLATES = [2.5, 5, 10, 25, 35, 45];
const PREFS_KEY_PLATES = 'selectedPlates'; const PREFS_KEY_PLATES = 'selectedPlates';
@@ -14,6 +18,12 @@ final plateWeightsProvider = StateNotifierProvider<PlateWeightsNotifier, PlateWe
}); });
class PlateWeightsState { class PlateWeightsState {
final _logger = Logger('PlateWeightsState');
final barWeightKg = 20;
final barWeightLb = 45;
// https://en.wikipedia.org/wiki/Barbell#Bumper_plates
final Map<double, Color> plateColorMapKg = { final Map<double, Color> plateColorMapKg = {
25: Colors.red, 25: Colors.red,
20: Colors.blue, 20: Colors.blue,
@@ -33,26 +43,29 @@ class PlateWeightsState {
25: Colors.green, 25: Colors.green,
10: Colors.white, 10: Colors.white,
5: Colors.blue, 5: Colors.blue,
2.5: Colors.green,
1.25: Colors.white, 1.25: Colors.white,
}; };
final bool isMetric; final bool isMetric;
final num totalWeight; final num totalWeight;
final num barWeight;
final List<num> selectedPlates; final List<num> selectedPlates;
final List<num> kgWeights = const [0.5, 1, 1.25, 2, 2.5, 5, 10, 15, 20, 25]; final List<num> availablePlatesKg = const [0.5, 1, 1.25, 2, 2.5, 5, 10, 15, 20, 25];
final List<num> lbsWeights = const [2.5, 5, 10, 25, 35, 45]; final List<num> availablePlatesLb = const [2.5, 5, 10, 25, 35, 45];
PlateWeightsState({ PlateWeightsState({
this.isMetric = true, this.isMetric = true,
this.totalWeight = 0, this.totalWeight = 0,
this.barWeight = 20,
List<num>? selectedPlates, List<num>? selectedPlates,
}) : selectedPlates = selectedPlates ?? [...DEFAULT_KG_PLATES]; }) : selectedPlates = selectedPlates ?? [...DEFAULT_KG_PLATES];
num get totalWeightInKg => isMetric ? totalWeight : totalWeight / 2.205; num get barWeight {
return isMetric ? barWeightKg : barWeightLb;
}
num get barWeightInKg => isMetric ? barWeight : barWeight / 2.205; List<num> get availablePlates {
return isMetric ? availablePlatesKg : availablePlatesLb;
}
List<num> get platesList { List<num> get platesList {
return plateCalculator(totalWeight, barWeight, selectedPlates); return plateCalculator(totalWeight, barWeight, selectedPlates);
@@ -63,8 +76,7 @@ class PlateWeightsState {
} }
Map<num, int> get calculatePlates { Map<num, int> get calculatePlates {
List<num> sortedPlates = List.from(selectedPlates)..sort(); return groupPlates(plateCalculator(totalWeight, barWeight, selectedPlates));
return groupPlates(plateCalculator(totalWeight, barWeight, sortedPlates));
} }
Color getColor(num plate) { Color getColor(num plate) {
@@ -74,91 +86,87 @@ class PlateWeightsState {
return plateColorMapLb[plate.toDouble()] ?? Colors.grey; return plateColorMapLb[plate.toDouble()] ?? Colors.grey;
} }
Map<String, dynamic> toJson() {
return {'isMetric': isMetric, 'selectedPlates': selectedPlates};
}
PlateWeightsState copyWith({ PlateWeightsState copyWith({
bool? isMetric, bool? isMetric,
num? totalWeight, num? totalWeight,
num? barWeight,
List<num>? selectedPlates, List<num>? selectedPlates,
}) { }) {
return PlateWeightsState( return PlateWeightsState(
isMetric: isMetric ?? this.isMetric, isMetric: isMetric ?? this.isMetric,
totalWeight: totalWeight ?? this.totalWeight, totalWeight: totalWeight ?? this.totalWeight,
barWeight: barWeight ?? this.barWeight,
selectedPlates: selectedPlates ?? this.selectedPlates, selectedPlates: selectedPlates ?? this.selectedPlates,
); );
} }
} }
class PlateWeightsNotifier extends StateNotifier<PlateWeightsState> { class PlateWeightsNotifier extends StateNotifier<PlateWeightsState> {
PlateWeightsNotifier() : super(PlateWeightsState()) { final _logger = Logger('PlateWeightsNotifier');
_readPlates();
late SharedPreferencesAsync prefs;
PlateWeightsNotifier({SharedPreferencesAsync? prefs}) : super(PlateWeightsState()) {
this.prefs = prefs ?? PreferenceHelper.asyncPref;
_readDataFromSharedPrefs();
} }
Future<void> _saveIntoSharedPrefs() async { Future<void> saveToSharedPrefs() async {
final pref = await SharedPreferences.getInstance(); await prefs.setString(PREFS_KEY_PLATES, jsonEncode(state.toJson()));
pref.setString(PREFS_KEY_PLATES, jsonEncode(state.selectedPlates));
} }
Future<void> _readPlates() async { Future<void> _readDataFromSharedPrefs() async {
final pref = await SharedPreferences.getInstance(); final prefsData = await prefs.getString(PREFS_KEY_PLATES);
final platePrefData = pref.getString(PREFS_KEY_PLATES);
if (platePrefData != null) { if (prefsData != null) {
try { try {
final plateData = json.decode(platePrefData); final plateData = json.decode(prefsData);
if (plateData is List) { state = state.copyWith(
state = state.copyWith(selectedPlates: plateData.cast<num>()); isMetric: plateData['isMetric'] ?? true,
} else { selectedPlates: plateData['selectedPlates'].cast<num>() ?? [...DEFAULT_KG_PLATES],
throw const FormatException('Not a List'); );
}
} catch (e) { } catch (e) {
state = state.copyWith(selectedPlates: []); _logger.fine('Error decoding plate data from SharedPreferences: $e');
} }
} }
} }
Future<void> toggleSelection(num x) async { Future<void> toggleSelection(num x) async {
final newSelectedPlates = List<num>.from(state.selectedPlates); final newSelectedPlates = List.of(state.selectedPlates);
if (newSelectedPlates.contains(x)) { if (newSelectedPlates.contains(x)) {
newSelectedPlates.remove(x); newSelectedPlates.remove(x);
} else { } else {
newSelectedPlates.add(x); newSelectedPlates.add(x);
} }
state = state.copyWith(selectedPlates: newSelectedPlates); state = state.copyWith(selectedPlates: newSelectedPlates);
await _saveIntoSharedPrefs(); await saveToSharedPrefs();
} }
void unitChange() { void unitChange({WeightUnitEnum? unit}) {
if (state.isMetric == false) { final WeightUnitEnum changeTo =
unit ?? (state.isMetric ? WeightUnitEnum.lb : WeightUnitEnum.kg);
if (changeTo == WeightUnitEnum.kg && !state.isMetric) {
state = state.copyWith( state = state.copyWith(
isMetric: true, isMetric: true,
totalWeight: state.totalWeightInKg, totalWeight: 0,
barWeight: state.barWeightInKg, selectedPlates: [...DEFAULT_KG_PLATES],
); );
} else { }
if (changeTo == WeightUnitEnum.lb && state.isMetric) {
state = state.copyWith( state = state.copyWith(
isMetric: false, isMetric: false,
totalWeight: state.totalWeightInKg * 2.205, totalWeight: 0,
barWeight: state.barWeightInKg * 2.205, selectedPlates: [...DEFAULT_LB_PLATES],
); );
} }
} }
void clear() async {
state = state.copyWith(selectedPlates: []);
await _saveIntoSharedPrefs();
}
void setWeight(num x) { void setWeight(num x) {
_logger.fine('Setting weight to $x');
state = state.copyWith(totalWeight: x); state = state.copyWith(totalWeight: x);
} }
void resetPlates() async {
state = state.copyWith(selectedPlates: [...DEFAULT_KG_PLATES]);
await _saveIntoSharedPrefs();
}
void selectAllPlates() async {
state = state.copyWith(selectedPlates: [...state.kgWeights]);
await _saveIntoSharedPrefs();
}
} }

View File

@@ -46,13 +46,12 @@ class UserProvider with ChangeNotifier {
} }
// change the unit of plates // change the unit of plates
void unitChange() { void changeUnit({changeTo = 'kg'}) {
if (profile?.weightUnitStr == 'kg') { if (changeTo == 'kg') {
profile?.weightUnitStr = 'lb'; profile?.weightUnitStr = 'lb';
} else { } else {
profile?.weightUnitStr = 'kg'; profile?.weightUnitStr = 'kg';
} }
ChangeNotifier();
} }
// Load theme mode from SharedPreferences // Load theme mode from SharedPreferences

View File

@@ -1,8 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:provider/provider.dart' as provider; import 'package:provider/provider.dart' as provider;
import 'package:wger/helpers/consts.dart';
import 'package:wger/l10n/generated/app_localizations.dart';
import 'package:wger/providers/plate_weights.dart'; import 'package:wger/providers/plate_weights.dart';
import 'package:wger/providers/user.dart'; import 'package:wger/providers/user.dart';
import 'package:wger/widgets/routines/plate_calculator.dart';
class AddPlateWeights extends ConsumerStatefulWidget { class AddPlateWeights extends ConsumerStatefulWidget {
const AddPlateWeights({super.key}); const AddPlateWeights({super.key});
@@ -13,8 +16,7 @@ class AddPlateWeights extends ConsumerStatefulWidget {
class _AddPlateWeightsState extends ConsumerState<AddPlateWeights> class _AddPlateWeightsState extends ConsumerState<AddPlateWeights>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
late AnimationController _controller; final _unitController = TextEditingController();
late Animation<Offset> _animation;
@override @override
void initState() { void initState() {
@@ -22,151 +24,79 @@ class _AddPlateWeightsState extends ConsumerState<AddPlateWeights>
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
ref.read(plateWeightsProvider.notifier); ref.read(plateWeightsProvider.notifier);
}); });
_controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 1),
);
_animation = Tween<Offset>(
begin: const Offset(-1.0, 0.0),
end: Offset.zero,
).animate(CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut,
));
_controller.forward();
} }
@override @override
void dispose() { void dispose() {
_controller.dispose(); _unitController.dispose();
super.dispose(); super.dispose();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final i18n = AppLocalizations.of(context);
final plateWeightsState = ref.watch(plateWeightsProvider); final plateWeightsState = ref.watch(plateWeightsProvider);
final plateWeightsNotifier = ref.read(plateWeightsProvider.notifier); final plateWeightsNotifier = ref.read(plateWeightsProvider.notifier);
final userProviderInstance = provider.Provider.of<UserProvider>(context); final userProvider = provider.Provider.of<UserProvider>(context);
final userProfile = userProviderInstance.profile;
return Scaffold( return Scaffold(
appBar: AppBar(title: const Text('Select Available Plates')), appBar: AppBar(title: const Text('Select Available Plates')),
body: Column( body: Column(
mainAxisSize: MainAxisSize.max,
children: [ children: [
Row( Padding(
mainAxisAlignment: MainAxisAlignment.center, padding: const EdgeInsets.all(10),
children: [ child: DropdownMenu<WeightUnitEnum>(
const Text('Preferred Unit'), width: double.infinity,
DropdownButton<String>( initialSelection: plateWeightsState.isMetric ? WeightUnitEnum.kg : WeightUnitEnum.lb,
value: (userProfile?.isMetric ?? true) ? 'kg' : 'lbs', controller: _unitController,
onChanged: (String? newValue) { requestFocusOnTap: true,
if (newValue == null) return; label: Text(i18n.unit),
final selectedUnitIsMetric = (newValue == 'kg'); onSelected: (WeightUnitEnum? unit) {
if (selectedUnitIsMetric != (userProfile?.isMetric ?? true)) { if (unit == null) {
plateWeightsNotifier.unitChange(); return;
provider.Provider.of<UserProvider>(context, listen: false).unitChange(); }
_controller.reset(); plateWeightsNotifier.unitChange(unit: unit);
_controller.forward(); // userProvider.changeUnit(changeTo: unit.name);
} // userProvider.saveProfile();
}, },
items: ['kg', 'lbs'].map((unit) { dropdownMenuEntries: WeightUnitEnum.values.map((unit) {
return DropdownMenuItem<String>( return DropdownMenuEntry<WeightUnitEnum>(
value: unit, value: unit,
child: Text(unit), label: unit == WeightUnitEnum.kg ? i18n.kg : i18n.lb,
);
}).toList(),
),
),
LayoutBuilder(
builder: (context, constraints) {
const double widthThreshold = 450.0;
final int crossAxisCount = constraints.maxWidth > widthThreshold ? 10 : 5;
return GridView.count(
crossAxisCount: crossAxisCount,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
children: plateWeightsState.availablePlates.map((number) {
final bool isSelected = plateWeightsState.selectedPlates.contains(number);
return GestureDetector(
onTap: () => plateWeightsNotifier.toggleSelection(number),
child: PlateWeight(
value: number,
isSelected: isSelected,
color: plateWeightsState.getColor(number),
),
); );
}).toList(), }).toList(),
), );
], },
), ),
Wrap( FilledButton(
alignment: WrapAlignment.center, onPressed: () {
runAlignment: WrapAlignment.center, plateWeightsNotifier.saveToSharedPrefs();
crossAxisAlignment: WrapCrossAlignment.center, Navigator.pop(context);
children: (userProfile == null || userProfile.isMetric) },
? plateWeightsState.kgWeights.map((number) { child: Text(i18n.save),
return SlideTransition(
position: _animation,
child: GestureDetector(
onTap: () => plateWeightsNotifier.toggleSelection(number),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 50,
width: 50,
alignment: Alignment.center,
margin: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: plateWeightsState.selectedPlates.contains(number)
? plateWeightsState.getColor(number)
: const Color.fromARGB(255, 97, 105, 101),
shape: BoxShape.circle,
border: Border.all(color: Colors.black, width: 2),
),
child: Text(
number.toString(),
textAlign: TextAlign.center,
style: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
),
),
),
);
}).toList()
: plateWeightsState.lbsWeights.map((number) {
return SlideTransition(
position: _animation,
child: GestureDetector(
onTap: () => plateWeightsNotifier.toggleSelection(number),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
margin: const EdgeInsets.all(8),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: plateWeightsState.selectedPlates.contains(number)
? const Color.fromARGB(255, 82, 226, 236)
: const Color.fromARGB(255, 97, 105, 101),
borderRadius: BorderRadius.circular(10),
),
child: Text(
'$number lbs',
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
),
),
);
}).toList(),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text('Done'),
),
ElevatedButton(
onPressed: () {
plateWeightsNotifier.selectAllPlates();
},
child: const Text('Select all'),
),
ElevatedButton(
onPressed: () {
plateWeightsNotifier.resetPlates();
},
child: const Text('Reset'),
),
],
), ),
], ],
), ),

View File

@@ -36,6 +36,7 @@ import 'package:wger/widgets/routines/forms/reps_unit.dart';
import 'package:wger/widgets/routines/forms/rir.dart'; import 'package:wger/widgets/routines/forms/rir.dart';
import 'package:wger/widgets/routines/forms/weight_unit.dart'; import 'package:wger/widgets/routines/forms/weight_unit.dart';
import 'package:wger/widgets/routines/gym_mode/navigation.dart'; import 'package:wger/widgets/routines/gym_mode/navigation.dart';
import 'package:wger/widgets/routines/plate_calculator.dart';
class LogPage extends ConsumerStatefulWidget { class LogPage extends ConsumerStatefulWidget {
final PageController _controller; final PageController _controller;
@@ -379,21 +380,26 @@ class _LogPageState extends ConsumerState<LogPage> {
Widget getPlates() { Widget getPlates() {
final plateWeightsState = ref.watch(plateWeightsProvider); final plateWeightsState = ref.watch(plateWeightsProvider);
return Column( return Column(
children: [ children: [
Text( Row(
AppLocalizations.of(context).plateCalculator, mainAxisAlignment: MainAxisAlignment.center,
style: Theme.of(context).textTheme.titleLarge, children: [
), Text(
IconButton( AppLocalizations.of(context).plateCalculator,
onPressed: () { style: Theme.of(context).textTheme.titleLarge,
Navigator.of(context) ),
.push(MaterialPageRoute(builder: (context) => const AddPlateWeights())); IconButton(
}, onPressed: () {
icon: const Icon(Icons.settings), Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => const AddPlateWeights()));
},
icon: const Icon(Icons.settings),
),
],
), ),
SizedBox( SizedBox(
height: 35,
child: plateWeightsState.hasPlates child: plateWeightsState.hasPlates
? Row( ? Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
@@ -403,28 +409,12 @@ class _LogPageState extends ConsumerState<LogPage> {
children: [ children: [
Text(entry.value.toString()), Text(entry.value.toString()),
const Text('×'), const Text('×'),
Container( PlateWeight(
decoration: BoxDecoration( value: entry.key,
color: ref.read(plateWeightsProvider).getColor(entry.key), size: 37,
shape: BoxShape.circle, padding: 2,
border: Border.all(color: Colors.black, width: 1), margin: 0,
), color: ref.read(plateWeightsProvider).getColor(entry.key),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 3),
child: SizedBox(
height: 35,
width: 35,
child: Align(
alignment: Alignment.center,
child: Text(
entry.key.toString(),
style: const TextStyle(
fontWeight: FontWeight.bold,
),
),
),
),
),
), ),
const SizedBox(width: 10), const SizedBox(width: 10),
], ],

View File

@@ -0,0 +1,48 @@
import 'package:flutter/material.dart';
class PlateWeight extends StatelessWidget {
final num value;
final Color color;
final bool isSelected;
final double size;
final double padding;
final double margin;
const PlateWeight({
super.key,
required this.value,
required this.color,
this.isSelected = true,
this.size = 50,
this.padding = 8,
this.margin = 3,
});
@override
Widget build(BuildContext context) {
return SizedBox(
height: size,
width: size,
child: Padding(
padding: EdgeInsets.all(padding),
child: Container(
alignment: Alignment.center,
margin: EdgeInsets.all(margin),
decoration: BoxDecoration(
color: isSelected ? color : Colors.black12,
shape: BoxShape.circle,
border: Border.all(color: Colors.black, width: isSelected ? 1 : 0),
),
child: Text(
value.toString(),
textAlign: TextAlign.center,
style: TextStyle(
color: isSelected ? Colors.black : Colors.black87,
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
),
),
),
),
);
}
}

View File

@@ -1181,10 +1181,11 @@ class MockUserProvider extends _i1.Mock implements _i22.UserProvider {
); );
@override @override
void unitChange() => super.noSuchMethod( void changeUnit({dynamic changeTo = 'kg'}) => super.noSuchMethod(
Invocation.method( Invocation.method(
#unitChange, #changeUnit,
[], [],
{#changeTo: changeTo},
), ),
returnValueForMissingStub: null, returnValueForMissingStub: null,
); );

View File

@@ -593,10 +593,11 @@ class MockUserProvider extends _i1.Mock implements _i17.UserProvider {
); );
@override @override
void unitChange() => super.noSuchMethod( void changeUnit({dynamic changeTo = 'kg'}) => super.noSuchMethod(
Invocation.method( Invocation.method(
#unitChange, #changeUnit,
[], [],
{#changeTo: changeTo},
), ),
returnValueForMissingStub: null, returnValueForMissingStub: null,
); );

View File

@@ -340,10 +340,11 @@ class MockUserProvider extends _i1.Mock implements _i13.UserProvider {
); );
@override @override
void unitChange() => super.noSuchMethod( void changeUnit({dynamic changeTo = 'kg'}) => super.noSuchMethod(
Invocation.method( Invocation.method(
#unitChange, #changeUnit,
[], [],
{#changeTo: changeTo},
), ),
returnValueForMissingStub: null, returnValueForMissingStub: null,
); );