mirror of
https://github.com/wger-project/flutter.git
synced 2026-02-18 00:17:48 +01:00
Fixes for flutter typeahead 5.1.0
Also, add some models for the API response from the search
This commit is contained in:
@@ -15,7 +15,7 @@ import '../test_data/workouts.dart';
|
||||
|
||||
Widget createGymModeScreen({locale = 'en'}) {
|
||||
final key = GlobalKey<NavigatorState>();
|
||||
final bases = getTestExerciseBases();
|
||||
final bases = getTestExercises();
|
||||
final workout = getWorkout(exercises: getScreenshotExercises());
|
||||
|
||||
final mockExerciseProvider = MockExercisesProvider();
|
||||
|
||||
@@ -48,3 +48,44 @@ class ExerciseApiData with _$ExerciseApiData {
|
||||
|
||||
factory ExerciseApiData.fromJson(Map<String, dynamic> json) => _$ExerciseApiDataFromJson(json);
|
||||
}
|
||||
|
||||
/// Model for the search results returned from the /api/v2/exercise/search endpoint
|
||||
///
|
||||
@freezed
|
||||
class ExerciseSearchDetails with _$ExerciseSearchDetails {
|
||||
factory ExerciseSearchDetails({
|
||||
// ignore: invalid_annotation_target
|
||||
@JsonKey(name: 'id') required int translationId,
|
||||
// ignore: invalid_annotation_target
|
||||
@JsonKey(name: 'base_id') required int exerciseId,
|
||||
required String name,
|
||||
required String category,
|
||||
required String? image,
|
||||
// ignore: invalid_annotation_target
|
||||
@JsonKey(name: 'image_thumbnail') required String? imageThumbnail,
|
||||
}) = _ExerciseSearchDetails;
|
||||
|
||||
factory ExerciseSearchDetails.fromJson(Map<String, dynamic> json) =>
|
||||
_$ExerciseSearchDetailsFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ExerciseSearchEntry with _$ExerciseSearchEntry {
|
||||
factory ExerciseSearchEntry({
|
||||
required String value,
|
||||
required ExerciseSearchDetails data,
|
||||
}) = _ExerciseSearchEntry;
|
||||
|
||||
factory ExerciseSearchEntry.fromJson(Map<String, dynamic> json) =>
|
||||
_$ExerciseSearchEntryFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ExerciseApiSearch with _$ExerciseApiSearch {
|
||||
factory ExerciseApiSearch({
|
||||
required List<ExerciseSearchEntry> suggestions,
|
||||
}) = _ExerciseApiSearch;
|
||||
|
||||
factory ExerciseApiSearch.fromJson(Map<String, dynamic> json) =>
|
||||
_$ExerciseApiSearchFromJson(json);
|
||||
}
|
||||
|
||||
@@ -545,3 +545,567 @@ abstract class _ExerciseBaseData implements ExerciseApiData {
|
||||
_$$ExerciseBaseDataImplCopyWith<_$ExerciseBaseDataImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
ExerciseSearchDetails _$ExerciseSearchDetailsFromJson(Map<String, dynamic> json) {
|
||||
return _ExerciseSearchDetails.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$ExerciseSearchDetails {
|
||||
// ignore: invalid_annotation_target
|
||||
@JsonKey(name: 'id')
|
||||
int get translationId => throw _privateConstructorUsedError; // ignore: invalid_annotation_target
|
||||
@JsonKey(name: 'base_id')
|
||||
int get exerciseId => throw _privateConstructorUsedError;
|
||||
String get name => throw _privateConstructorUsedError;
|
||||
String get category => throw _privateConstructorUsedError;
|
||||
String? get image => throw _privateConstructorUsedError; // ignore: invalid_annotation_target
|
||||
@JsonKey(name: 'image_thumbnail')
|
||||
String? get imageThumbnail => throw _privateConstructorUsedError;
|
||||
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
@JsonKey(ignore: true)
|
||||
$ExerciseSearchDetailsCopyWith<ExerciseSearchDetails> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $ExerciseSearchDetailsCopyWith<$Res> {
|
||||
factory $ExerciseSearchDetailsCopyWith(
|
||||
ExerciseSearchDetails value, $Res Function(ExerciseSearchDetails) then) =
|
||||
_$ExerciseSearchDetailsCopyWithImpl<$Res, ExerciseSearchDetails>;
|
||||
@useResult
|
||||
$Res call(
|
||||
{@JsonKey(name: 'id') int translationId,
|
||||
@JsonKey(name: 'base_id') int exerciseId,
|
||||
String name,
|
||||
String category,
|
||||
String? image,
|
||||
@JsonKey(name: 'image_thumbnail') String? imageThumbnail});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$ExerciseSearchDetailsCopyWithImpl<$Res, $Val extends ExerciseSearchDetails>
|
||||
implements $ExerciseSearchDetailsCopyWith<$Res> {
|
||||
_$ExerciseSearchDetailsCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? translationId = null,
|
||||
Object? exerciseId = null,
|
||||
Object? name = null,
|
||||
Object? category = null,
|
||||
Object? image = freezed,
|
||||
Object? imageThumbnail = freezed,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
translationId: null == translationId
|
||||
? _value.translationId
|
||||
: translationId // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
exerciseId: null == exerciseId
|
||||
? _value.exerciseId
|
||||
: exerciseId // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
name: null == name
|
||||
? _value.name
|
||||
: name // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
category: null == category
|
||||
? _value.category
|
||||
: category // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
image: freezed == image
|
||||
? _value.image
|
||||
: image // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
imageThumbnail: freezed == imageThumbnail
|
||||
? _value.imageThumbnail
|
||||
: imageThumbnail // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$ExerciseSearchDetailsImplCopyWith<$Res>
|
||||
implements $ExerciseSearchDetailsCopyWith<$Res> {
|
||||
factory _$$ExerciseSearchDetailsImplCopyWith(
|
||||
_$ExerciseSearchDetailsImpl value, $Res Function(_$ExerciseSearchDetailsImpl) then) =
|
||||
__$$ExerciseSearchDetailsImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call(
|
||||
{@JsonKey(name: 'id') int translationId,
|
||||
@JsonKey(name: 'base_id') int exerciseId,
|
||||
String name,
|
||||
String category,
|
||||
String? image,
|
||||
@JsonKey(name: 'image_thumbnail') String? imageThumbnail});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$ExerciseSearchDetailsImplCopyWithImpl<$Res>
|
||||
extends _$ExerciseSearchDetailsCopyWithImpl<$Res, _$ExerciseSearchDetailsImpl>
|
||||
implements _$$ExerciseSearchDetailsImplCopyWith<$Res> {
|
||||
__$$ExerciseSearchDetailsImplCopyWithImpl(
|
||||
_$ExerciseSearchDetailsImpl _value, $Res Function(_$ExerciseSearchDetailsImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? translationId = null,
|
||||
Object? exerciseId = null,
|
||||
Object? name = null,
|
||||
Object? category = null,
|
||||
Object? image = freezed,
|
||||
Object? imageThumbnail = freezed,
|
||||
}) {
|
||||
return _then(_$ExerciseSearchDetailsImpl(
|
||||
translationId: null == translationId
|
||||
? _value.translationId
|
||||
: translationId // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
exerciseId: null == exerciseId
|
||||
? _value.exerciseId
|
||||
: exerciseId // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
name: null == name
|
||||
? _value.name
|
||||
: name // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
category: null == category
|
||||
? _value.category
|
||||
: category // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
image: freezed == image
|
||||
? _value.image
|
||||
: image // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
imageThumbnail: freezed == imageThumbnail
|
||||
? _value.imageThumbnail
|
||||
: imageThumbnail // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$ExerciseSearchDetailsImpl implements _ExerciseSearchDetails {
|
||||
_$ExerciseSearchDetailsImpl(
|
||||
{@JsonKey(name: 'id') required this.translationId,
|
||||
@JsonKey(name: 'base_id') required this.exerciseId,
|
||||
required this.name,
|
||||
required this.category,
|
||||
required this.image,
|
||||
@JsonKey(name: 'image_thumbnail') required this.imageThumbnail});
|
||||
|
||||
factory _$ExerciseSearchDetailsImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$ExerciseSearchDetailsImplFromJson(json);
|
||||
|
||||
// ignore: invalid_annotation_target
|
||||
@override
|
||||
@JsonKey(name: 'id')
|
||||
final int translationId;
|
||||
// ignore: invalid_annotation_target
|
||||
@override
|
||||
@JsonKey(name: 'base_id')
|
||||
final int exerciseId;
|
||||
@override
|
||||
final String name;
|
||||
@override
|
||||
final String category;
|
||||
@override
|
||||
final String? image;
|
||||
// ignore: invalid_annotation_target
|
||||
@override
|
||||
@JsonKey(name: 'image_thumbnail')
|
||||
final String? imageThumbnail;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ExerciseSearchDetails(translationId: $translationId, exerciseId: $exerciseId, name: $name, category: $category, image: $image, imageThumbnail: $imageThumbnail)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$ExerciseSearchDetailsImpl &&
|
||||
(identical(other.translationId, translationId) ||
|
||||
other.translationId == translationId) &&
|
||||
(identical(other.exerciseId, exerciseId) || other.exerciseId == exerciseId) &&
|
||||
(identical(other.name, name) || other.name == name) &&
|
||||
(identical(other.category, category) || other.category == category) &&
|
||||
(identical(other.image, image) || other.image == image) &&
|
||||
(identical(other.imageThumbnail, imageThumbnail) ||
|
||||
other.imageThumbnail == imageThumbnail));
|
||||
}
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
int get hashCode =>
|
||||
Object.hash(runtimeType, translationId, exerciseId, name, category, image, imageThumbnail);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$ExerciseSearchDetailsImplCopyWith<_$ExerciseSearchDetailsImpl> get copyWith =>
|
||||
__$$ExerciseSearchDetailsImplCopyWithImpl<_$ExerciseSearchDetailsImpl>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$ExerciseSearchDetailsImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _ExerciseSearchDetails implements ExerciseSearchDetails {
|
||||
factory _ExerciseSearchDetails(
|
||||
{@JsonKey(name: 'id') required final int translationId,
|
||||
@JsonKey(name: 'base_id') required final int exerciseId,
|
||||
required final String name,
|
||||
required final String category,
|
||||
required final String? image,
|
||||
@JsonKey(name: 'image_thumbnail') required final String? imageThumbnail}) =
|
||||
_$ExerciseSearchDetailsImpl;
|
||||
|
||||
factory _ExerciseSearchDetails.fromJson(Map<String, dynamic> json) =
|
||||
_$ExerciseSearchDetailsImpl.fromJson;
|
||||
|
||||
@override // ignore: invalid_annotation_target
|
||||
@JsonKey(name: 'id')
|
||||
int get translationId;
|
||||
@override // ignore: invalid_annotation_target
|
||||
@JsonKey(name: 'base_id')
|
||||
int get exerciseId;
|
||||
@override
|
||||
String get name;
|
||||
@override
|
||||
String get category;
|
||||
@override
|
||||
String? get image;
|
||||
@override // ignore: invalid_annotation_target
|
||||
@JsonKey(name: 'image_thumbnail')
|
||||
String? get imageThumbnail;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$$ExerciseSearchDetailsImplCopyWith<_$ExerciseSearchDetailsImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
ExerciseSearchEntry _$ExerciseSearchEntryFromJson(Map<String, dynamic> json) {
|
||||
return _ExerciseSearchEntry.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$ExerciseSearchEntry {
|
||||
String get value => throw _privateConstructorUsedError;
|
||||
ExerciseSearchDetails get data => throw _privateConstructorUsedError;
|
||||
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
@JsonKey(ignore: true)
|
||||
$ExerciseSearchEntryCopyWith<ExerciseSearchEntry> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $ExerciseSearchEntryCopyWith<$Res> {
|
||||
factory $ExerciseSearchEntryCopyWith(
|
||||
ExerciseSearchEntry value, $Res Function(ExerciseSearchEntry) then) =
|
||||
_$ExerciseSearchEntryCopyWithImpl<$Res, ExerciseSearchEntry>;
|
||||
@useResult
|
||||
$Res call({String value, ExerciseSearchDetails data});
|
||||
|
||||
$ExerciseSearchDetailsCopyWith<$Res> get data;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$ExerciseSearchEntryCopyWithImpl<$Res, $Val extends ExerciseSearchEntry>
|
||||
implements $ExerciseSearchEntryCopyWith<$Res> {
|
||||
_$ExerciseSearchEntryCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? value = null,
|
||||
Object? data = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
value: null == value
|
||||
? _value.value
|
||||
: value // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
data: null == data
|
||||
? _value.data
|
||||
: data // ignore: cast_nullable_to_non_nullable
|
||||
as ExerciseSearchDetails,
|
||||
) as $Val);
|
||||
}
|
||||
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$ExerciseSearchDetailsCopyWith<$Res> get data {
|
||||
return $ExerciseSearchDetailsCopyWith<$Res>(_value.data, (value) {
|
||||
return _then(_value.copyWith(data: value) as $Val);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$ExerciseSearchEntryImplCopyWith<$Res>
|
||||
implements $ExerciseSearchEntryCopyWith<$Res> {
|
||||
factory _$$ExerciseSearchEntryImplCopyWith(
|
||||
_$ExerciseSearchEntryImpl value, $Res Function(_$ExerciseSearchEntryImpl) then) =
|
||||
__$$ExerciseSearchEntryImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({String value, ExerciseSearchDetails data});
|
||||
|
||||
@override
|
||||
$ExerciseSearchDetailsCopyWith<$Res> get data;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$ExerciseSearchEntryImplCopyWithImpl<$Res>
|
||||
extends _$ExerciseSearchEntryCopyWithImpl<$Res, _$ExerciseSearchEntryImpl>
|
||||
implements _$$ExerciseSearchEntryImplCopyWith<$Res> {
|
||||
__$$ExerciseSearchEntryImplCopyWithImpl(
|
||||
_$ExerciseSearchEntryImpl _value, $Res Function(_$ExerciseSearchEntryImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? value = null,
|
||||
Object? data = null,
|
||||
}) {
|
||||
return _then(_$ExerciseSearchEntryImpl(
|
||||
value: null == value
|
||||
? _value.value
|
||||
: value // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
data: null == data
|
||||
? _value.data
|
||||
: data // ignore: cast_nullable_to_non_nullable
|
||||
as ExerciseSearchDetails,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$ExerciseSearchEntryImpl implements _ExerciseSearchEntry {
|
||||
_$ExerciseSearchEntryImpl({required this.value, required this.data});
|
||||
|
||||
factory _$ExerciseSearchEntryImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$ExerciseSearchEntryImplFromJson(json);
|
||||
|
||||
@override
|
||||
final String value;
|
||||
@override
|
||||
final ExerciseSearchDetails data;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ExerciseSearchEntry(value: $value, data: $data)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$ExerciseSearchEntryImpl &&
|
||||
(identical(other.value, value) || other.value == value) &&
|
||||
(identical(other.data, data) || other.data == data));
|
||||
}
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, value, data);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$ExerciseSearchEntryImplCopyWith<_$ExerciseSearchEntryImpl> get copyWith =>
|
||||
__$$ExerciseSearchEntryImplCopyWithImpl<_$ExerciseSearchEntryImpl>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$ExerciseSearchEntryImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _ExerciseSearchEntry implements ExerciseSearchEntry {
|
||||
factory _ExerciseSearchEntry(
|
||||
{required final String value,
|
||||
required final ExerciseSearchDetails data}) = _$ExerciseSearchEntryImpl;
|
||||
|
||||
factory _ExerciseSearchEntry.fromJson(Map<String, dynamic> json) =
|
||||
_$ExerciseSearchEntryImpl.fromJson;
|
||||
|
||||
@override
|
||||
String get value;
|
||||
@override
|
||||
ExerciseSearchDetails get data;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$$ExerciseSearchEntryImplCopyWith<_$ExerciseSearchEntryImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
ExerciseApiSearch _$ExerciseApiSearchFromJson(Map<String, dynamic> json) {
|
||||
return _ExerciseApiSearch.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$ExerciseApiSearch {
|
||||
List<ExerciseSearchEntry> get suggestions => throw _privateConstructorUsedError;
|
||||
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
@JsonKey(ignore: true)
|
||||
$ExerciseApiSearchCopyWith<ExerciseApiSearch> get copyWith => throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $ExerciseApiSearchCopyWith<$Res> {
|
||||
factory $ExerciseApiSearchCopyWith(
|
||||
ExerciseApiSearch value, $Res Function(ExerciseApiSearch) then) =
|
||||
_$ExerciseApiSearchCopyWithImpl<$Res, ExerciseApiSearch>;
|
||||
@useResult
|
||||
$Res call({List<ExerciseSearchEntry> suggestions});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$ExerciseApiSearchCopyWithImpl<$Res, $Val extends ExerciseApiSearch>
|
||||
implements $ExerciseApiSearchCopyWith<$Res> {
|
||||
_$ExerciseApiSearchCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? suggestions = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
suggestions: null == suggestions
|
||||
? _value.suggestions
|
||||
: suggestions // ignore: cast_nullable_to_non_nullable
|
||||
as List<ExerciseSearchEntry>,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$ExerciseApiSearchImplCopyWith<$Res> implements $ExerciseApiSearchCopyWith<$Res> {
|
||||
factory _$$ExerciseApiSearchImplCopyWith(
|
||||
_$ExerciseApiSearchImpl value, $Res Function(_$ExerciseApiSearchImpl) then) =
|
||||
__$$ExerciseApiSearchImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({List<ExerciseSearchEntry> suggestions});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$ExerciseApiSearchImplCopyWithImpl<$Res>
|
||||
extends _$ExerciseApiSearchCopyWithImpl<$Res, _$ExerciseApiSearchImpl>
|
||||
implements _$$ExerciseApiSearchImplCopyWith<$Res> {
|
||||
__$$ExerciseApiSearchImplCopyWithImpl(
|
||||
_$ExerciseApiSearchImpl _value, $Res Function(_$ExerciseApiSearchImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? suggestions = null,
|
||||
}) {
|
||||
return _then(_$ExerciseApiSearchImpl(
|
||||
suggestions: null == suggestions
|
||||
? _value._suggestions
|
||||
: suggestions // ignore: cast_nullable_to_non_nullable
|
||||
as List<ExerciseSearchEntry>,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$ExerciseApiSearchImpl implements _ExerciseApiSearch {
|
||||
_$ExerciseApiSearchImpl({required final List<ExerciseSearchEntry> suggestions})
|
||||
: _suggestions = suggestions;
|
||||
|
||||
factory _$ExerciseApiSearchImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$ExerciseApiSearchImplFromJson(json);
|
||||
|
||||
final List<ExerciseSearchEntry> _suggestions;
|
||||
@override
|
||||
List<ExerciseSearchEntry> get suggestions {
|
||||
if (_suggestions is EqualUnmodifiableListView) return _suggestions;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_suggestions);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ExerciseApiSearch(suggestions: $suggestions)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$ExerciseApiSearchImpl &&
|
||||
const DeepCollectionEquality().equals(other._suggestions, _suggestions));
|
||||
}
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, const DeepCollectionEquality().hash(_suggestions));
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$ExerciseApiSearchImplCopyWith<_$ExerciseApiSearchImpl> get copyWith =>
|
||||
__$$ExerciseApiSearchImplCopyWithImpl<_$ExerciseApiSearchImpl>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$ExerciseApiSearchImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _ExerciseApiSearch implements ExerciseApiSearch {
|
||||
factory _ExerciseApiSearch({required final List<ExerciseSearchEntry> suggestions}) =
|
||||
_$ExerciseApiSearchImpl;
|
||||
|
||||
factory _ExerciseApiSearch.fromJson(Map<String, dynamic> json) = _$ExerciseApiSearchImpl.fromJson;
|
||||
|
||||
@override
|
||||
List<ExerciseSearchEntry> get suggestions;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$$ExerciseApiSearchImplCopyWith<_$ExerciseApiSearchImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
@@ -56,3 +56,47 @@ Map<String, dynamic> _$$ExerciseBaseDataImplToJson(_$ExerciseBaseDataImpl instan
|
||||
'author_history': instance.authors,
|
||||
'total_authors_history': instance.authorsGlobal,
|
||||
};
|
||||
|
||||
_$ExerciseSearchDetailsImpl _$$ExerciseSearchDetailsImplFromJson(Map<String, dynamic> json) =>
|
||||
_$ExerciseSearchDetailsImpl(
|
||||
translationId: json['id'] as int,
|
||||
exerciseId: json['base_id'] as int,
|
||||
name: json['name'] as String,
|
||||
category: json['category'] as String,
|
||||
image: json['image'] as String?,
|
||||
imageThumbnail: json['image_thumbnail'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ExerciseSearchDetailsImplToJson(_$ExerciseSearchDetailsImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.translationId,
|
||||
'base_id': instance.exerciseId,
|
||||
'name': instance.name,
|
||||
'category': instance.category,
|
||||
'image': instance.image,
|
||||
'image_thumbnail': instance.imageThumbnail,
|
||||
};
|
||||
|
||||
_$ExerciseSearchEntryImpl _$$ExerciseSearchEntryImplFromJson(Map<String, dynamic> json) =>
|
||||
_$ExerciseSearchEntryImpl(
|
||||
value: json['value'] as String,
|
||||
data: ExerciseSearchDetails.fromJson(json['data'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ExerciseSearchEntryImplToJson(_$ExerciseSearchEntryImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'value': instance.value,
|
||||
'data': instance.data,
|
||||
};
|
||||
|
||||
_$ExerciseApiSearchImpl _$$ExerciseApiSearchImplFromJson(Map<String, dynamic> json) =>
|
||||
_$ExerciseApiSearchImpl(
|
||||
suggestions: (json['suggestions'] as List<dynamic>)
|
||||
.map((e) => ExerciseSearchEntry.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ExerciseApiSearchImplToJson(_$ExerciseApiSearchImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'suggestions': instance.suggestions,
|
||||
};
|
||||
|
||||
40
lib/models/exercises/ingredient_api.dart
Normal file
40
lib/models/exercises/ingredient_api.dart
Normal file
@@ -0,0 +1,40 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'ingredient_api.freezed.dart';
|
||||
part 'ingredient_api.g.dart';
|
||||
|
||||
/// Model for the search results returned from the /api/v2/ingredient/search endpoint
|
||||
@freezed
|
||||
class IngredientApiSearchDetails with _$IngredientApiSearchDetails {
|
||||
factory IngredientApiSearchDetails({
|
||||
required int id,
|
||||
required String name,
|
||||
required String? image,
|
||||
// ignore: invalid_annotation_target
|
||||
@JsonKey(name: 'image_thumbnail') required String? imageThumbnail,
|
||||
}) = _IngredientApiSearchDetails;
|
||||
|
||||
factory IngredientApiSearchDetails.fromJson(Map<String, dynamic> json) =>
|
||||
_$IngredientApiSearchDetailsFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class IngredientApiSearchEntry with _$IngredientApiSearchEntry {
|
||||
factory IngredientApiSearchEntry({
|
||||
required String value,
|
||||
required IngredientApiSearchDetails data,
|
||||
}) = _IngredientApiSearchEntry;
|
||||
|
||||
factory IngredientApiSearchEntry.fromJson(Map<String, dynamic> json) =>
|
||||
_$IngredientApiSearchEntryFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class IngredientApiSearch with _$IngredientApiSearch {
|
||||
factory IngredientApiSearch({
|
||||
required List<IngredientApiSearchEntry> suggestions,
|
||||
}) = _IngredientApiSearch;
|
||||
|
||||
factory IngredientApiSearch.fromJson(Map<String, dynamic> json) =>
|
||||
_$IngredientApiSearchFromJson(json);
|
||||
}
|
||||
533
lib/models/exercises/ingredient_api.freezed.dart
Normal file
533
lib/models/exercises/ingredient_api.freezed.dart
Normal file
@@ -0,0 +1,533 @@
|
||||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'ingredient_api.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
final _privateConstructorUsedError = UnsupportedError(
|
||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
|
||||
|
||||
IngredientApiSearchDetails _$IngredientApiSearchDetailsFromJson(Map<String, dynamic> json) {
|
||||
return _IngredientApiSearchDetails.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$IngredientApiSearchDetails {
|
||||
int get id => throw _privateConstructorUsedError;
|
||||
String get name => throw _privateConstructorUsedError;
|
||||
String? get image => throw _privateConstructorUsedError; // ignore: invalid_annotation_target
|
||||
@JsonKey(name: 'image_thumbnail')
|
||||
String? get imageThumbnail => throw _privateConstructorUsedError;
|
||||
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
@JsonKey(ignore: true)
|
||||
$IngredientApiSearchDetailsCopyWith<IngredientApiSearchDetails> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $IngredientApiSearchDetailsCopyWith<$Res> {
|
||||
factory $IngredientApiSearchDetailsCopyWith(
|
||||
IngredientApiSearchDetails value, $Res Function(IngredientApiSearchDetails) then) =
|
||||
_$IngredientApiSearchDetailsCopyWithImpl<$Res, IngredientApiSearchDetails>;
|
||||
@useResult
|
||||
$Res call(
|
||||
{int id,
|
||||
String name,
|
||||
String? image,
|
||||
@JsonKey(name: 'image_thumbnail') String? imageThumbnail});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$IngredientApiSearchDetailsCopyWithImpl<$Res, $Val extends IngredientApiSearchDetails>
|
||||
implements $IngredientApiSearchDetailsCopyWith<$Res> {
|
||||
_$IngredientApiSearchDetailsCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? id = null,
|
||||
Object? name = null,
|
||||
Object? image = freezed,
|
||||
Object? imageThumbnail = freezed,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
id: null == id
|
||||
? _value.id
|
||||
: id // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
name: null == name
|
||||
? _value.name
|
||||
: name // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
image: freezed == image
|
||||
? _value.image
|
||||
: image // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
imageThumbnail: freezed == imageThumbnail
|
||||
? _value.imageThumbnail
|
||||
: imageThumbnail // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$IngredientApiSearchDetailsImplCopyWith<$Res>
|
||||
implements $IngredientApiSearchDetailsCopyWith<$Res> {
|
||||
factory _$$IngredientApiSearchDetailsImplCopyWith(_$IngredientApiSearchDetailsImpl value,
|
||||
$Res Function(_$IngredientApiSearchDetailsImpl) then) =
|
||||
__$$IngredientApiSearchDetailsImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call(
|
||||
{int id,
|
||||
String name,
|
||||
String? image,
|
||||
@JsonKey(name: 'image_thumbnail') String? imageThumbnail});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$IngredientApiSearchDetailsImplCopyWithImpl<$Res>
|
||||
extends _$IngredientApiSearchDetailsCopyWithImpl<$Res, _$IngredientApiSearchDetailsImpl>
|
||||
implements _$$IngredientApiSearchDetailsImplCopyWith<$Res> {
|
||||
__$$IngredientApiSearchDetailsImplCopyWithImpl(_$IngredientApiSearchDetailsImpl _value,
|
||||
$Res Function(_$IngredientApiSearchDetailsImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? id = null,
|
||||
Object? name = null,
|
||||
Object? image = freezed,
|
||||
Object? imageThumbnail = freezed,
|
||||
}) {
|
||||
return _then(_$IngredientApiSearchDetailsImpl(
|
||||
id: null == id
|
||||
? _value.id
|
||||
: id // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
name: null == name
|
||||
? _value.name
|
||||
: name // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
image: freezed == image
|
||||
? _value.image
|
||||
: image // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
imageThumbnail: freezed == imageThumbnail
|
||||
? _value.imageThumbnail
|
||||
: imageThumbnail // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$IngredientApiSearchDetailsImpl implements _IngredientApiSearchDetails {
|
||||
_$IngredientApiSearchDetailsImpl(
|
||||
{required this.id,
|
||||
required this.name,
|
||||
required this.image,
|
||||
@JsonKey(name: 'image_thumbnail') required this.imageThumbnail});
|
||||
|
||||
factory _$IngredientApiSearchDetailsImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$IngredientApiSearchDetailsImplFromJson(json);
|
||||
|
||||
@override
|
||||
final int id;
|
||||
@override
|
||||
final String name;
|
||||
@override
|
||||
final String? image;
|
||||
// ignore: invalid_annotation_target
|
||||
@override
|
||||
@JsonKey(name: 'image_thumbnail')
|
||||
final String? imageThumbnail;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'IngredientApiSearchDetails(id: $id, name: $name, image: $image, imageThumbnail: $imageThumbnail)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$IngredientApiSearchDetailsImpl &&
|
||||
(identical(other.id, id) || other.id == id) &&
|
||||
(identical(other.name, name) || other.name == name) &&
|
||||
(identical(other.image, image) || other.image == image) &&
|
||||
(identical(other.imageThumbnail, imageThumbnail) ||
|
||||
other.imageThumbnail == imageThumbnail));
|
||||
}
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, id, name, image, imageThumbnail);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$IngredientApiSearchDetailsImplCopyWith<_$IngredientApiSearchDetailsImpl> get copyWith =>
|
||||
__$$IngredientApiSearchDetailsImplCopyWithImpl<_$IngredientApiSearchDetailsImpl>(
|
||||
this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$IngredientApiSearchDetailsImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _IngredientApiSearchDetails implements IngredientApiSearchDetails {
|
||||
factory _IngredientApiSearchDetails(
|
||||
{required final int id,
|
||||
required final String name,
|
||||
required final String? image,
|
||||
@JsonKey(name: 'image_thumbnail') required final String? imageThumbnail}) =
|
||||
_$IngredientApiSearchDetailsImpl;
|
||||
|
||||
factory _IngredientApiSearchDetails.fromJson(Map<String, dynamic> json) =
|
||||
_$IngredientApiSearchDetailsImpl.fromJson;
|
||||
|
||||
@override
|
||||
int get id;
|
||||
@override
|
||||
String get name;
|
||||
@override
|
||||
String? get image;
|
||||
@override // ignore: invalid_annotation_target
|
||||
@JsonKey(name: 'image_thumbnail')
|
||||
String? get imageThumbnail;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$$IngredientApiSearchDetailsImplCopyWith<_$IngredientApiSearchDetailsImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
IngredientApiSearchEntry _$IngredientApiSearchEntryFromJson(Map<String, dynamic> json) {
|
||||
return _IngredientApiSearchEntry.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$IngredientApiSearchEntry {
|
||||
String get value => throw _privateConstructorUsedError;
|
||||
IngredientApiSearchDetails get data => throw _privateConstructorUsedError;
|
||||
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
@JsonKey(ignore: true)
|
||||
$IngredientApiSearchEntryCopyWith<IngredientApiSearchEntry> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $IngredientApiSearchEntryCopyWith<$Res> {
|
||||
factory $IngredientApiSearchEntryCopyWith(
|
||||
IngredientApiSearchEntry value, $Res Function(IngredientApiSearchEntry) then) =
|
||||
_$IngredientApiSearchEntryCopyWithImpl<$Res, IngredientApiSearchEntry>;
|
||||
@useResult
|
||||
$Res call({String value, IngredientApiSearchDetails data});
|
||||
|
||||
$IngredientApiSearchDetailsCopyWith<$Res> get data;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$IngredientApiSearchEntryCopyWithImpl<$Res, $Val extends IngredientApiSearchEntry>
|
||||
implements $IngredientApiSearchEntryCopyWith<$Res> {
|
||||
_$IngredientApiSearchEntryCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? value = null,
|
||||
Object? data = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
value: null == value
|
||||
? _value.value
|
||||
: value // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
data: null == data
|
||||
? _value.data
|
||||
: data // ignore: cast_nullable_to_non_nullable
|
||||
as IngredientApiSearchDetails,
|
||||
) as $Val);
|
||||
}
|
||||
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$IngredientApiSearchDetailsCopyWith<$Res> get data {
|
||||
return $IngredientApiSearchDetailsCopyWith<$Res>(_value.data, (value) {
|
||||
return _then(_value.copyWith(data: value) as $Val);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$IngredientApiSearchEntryImplCopyWith<$Res>
|
||||
implements $IngredientApiSearchEntryCopyWith<$Res> {
|
||||
factory _$$IngredientApiSearchEntryImplCopyWith(_$IngredientApiSearchEntryImpl value,
|
||||
$Res Function(_$IngredientApiSearchEntryImpl) then) =
|
||||
__$$IngredientApiSearchEntryImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({String value, IngredientApiSearchDetails data});
|
||||
|
||||
@override
|
||||
$IngredientApiSearchDetailsCopyWith<$Res> get data;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$IngredientApiSearchEntryImplCopyWithImpl<$Res>
|
||||
extends _$IngredientApiSearchEntryCopyWithImpl<$Res, _$IngredientApiSearchEntryImpl>
|
||||
implements _$$IngredientApiSearchEntryImplCopyWith<$Res> {
|
||||
__$$IngredientApiSearchEntryImplCopyWithImpl(
|
||||
_$IngredientApiSearchEntryImpl _value, $Res Function(_$IngredientApiSearchEntryImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? value = null,
|
||||
Object? data = null,
|
||||
}) {
|
||||
return _then(_$IngredientApiSearchEntryImpl(
|
||||
value: null == value
|
||||
? _value.value
|
||||
: value // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
data: null == data
|
||||
? _value.data
|
||||
: data // ignore: cast_nullable_to_non_nullable
|
||||
as IngredientApiSearchDetails,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$IngredientApiSearchEntryImpl implements _IngredientApiSearchEntry {
|
||||
_$IngredientApiSearchEntryImpl({required this.value, required this.data});
|
||||
|
||||
factory _$IngredientApiSearchEntryImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$IngredientApiSearchEntryImplFromJson(json);
|
||||
|
||||
@override
|
||||
final String value;
|
||||
@override
|
||||
final IngredientApiSearchDetails data;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'IngredientApiSearchEntry(value: $value, data: $data)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$IngredientApiSearchEntryImpl &&
|
||||
(identical(other.value, value) || other.value == value) &&
|
||||
(identical(other.data, data) || other.data == data));
|
||||
}
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, value, data);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$IngredientApiSearchEntryImplCopyWith<_$IngredientApiSearchEntryImpl> get copyWith =>
|
||||
__$$IngredientApiSearchEntryImplCopyWithImpl<_$IngredientApiSearchEntryImpl>(
|
||||
this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$IngredientApiSearchEntryImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _IngredientApiSearchEntry implements IngredientApiSearchEntry {
|
||||
factory _IngredientApiSearchEntry(
|
||||
{required final String value,
|
||||
required final IngredientApiSearchDetails data}) = _$IngredientApiSearchEntryImpl;
|
||||
|
||||
factory _IngredientApiSearchEntry.fromJson(Map<String, dynamic> json) =
|
||||
_$IngredientApiSearchEntryImpl.fromJson;
|
||||
|
||||
@override
|
||||
String get value;
|
||||
@override
|
||||
IngredientApiSearchDetails get data;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$$IngredientApiSearchEntryImplCopyWith<_$IngredientApiSearchEntryImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
IngredientApiSearch _$IngredientApiSearchFromJson(Map<String, dynamic> json) {
|
||||
return _IngredientApiSearch.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$IngredientApiSearch {
|
||||
List<IngredientApiSearchEntry> get suggestions => throw _privateConstructorUsedError;
|
||||
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
@JsonKey(ignore: true)
|
||||
$IngredientApiSearchCopyWith<IngredientApiSearch> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $IngredientApiSearchCopyWith<$Res> {
|
||||
factory $IngredientApiSearchCopyWith(
|
||||
IngredientApiSearch value, $Res Function(IngredientApiSearch) then) =
|
||||
_$IngredientApiSearchCopyWithImpl<$Res, IngredientApiSearch>;
|
||||
@useResult
|
||||
$Res call({List<IngredientApiSearchEntry> suggestions});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$IngredientApiSearchCopyWithImpl<$Res, $Val extends IngredientApiSearch>
|
||||
implements $IngredientApiSearchCopyWith<$Res> {
|
||||
_$IngredientApiSearchCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? suggestions = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
suggestions: null == suggestions
|
||||
? _value.suggestions
|
||||
: suggestions // ignore: cast_nullable_to_non_nullable
|
||||
as List<IngredientApiSearchEntry>,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$IngredientApiSearchImplCopyWith<$Res>
|
||||
implements $IngredientApiSearchCopyWith<$Res> {
|
||||
factory _$$IngredientApiSearchImplCopyWith(
|
||||
_$IngredientApiSearchImpl value, $Res Function(_$IngredientApiSearchImpl) then) =
|
||||
__$$IngredientApiSearchImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({List<IngredientApiSearchEntry> suggestions});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$IngredientApiSearchImplCopyWithImpl<$Res>
|
||||
extends _$IngredientApiSearchCopyWithImpl<$Res, _$IngredientApiSearchImpl>
|
||||
implements _$$IngredientApiSearchImplCopyWith<$Res> {
|
||||
__$$IngredientApiSearchImplCopyWithImpl(
|
||||
_$IngredientApiSearchImpl _value, $Res Function(_$IngredientApiSearchImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? suggestions = null,
|
||||
}) {
|
||||
return _then(_$IngredientApiSearchImpl(
|
||||
suggestions: null == suggestions
|
||||
? _value._suggestions
|
||||
: suggestions // ignore: cast_nullable_to_non_nullable
|
||||
as List<IngredientApiSearchEntry>,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$IngredientApiSearchImpl implements _IngredientApiSearch {
|
||||
_$IngredientApiSearchImpl({required final List<IngredientApiSearchEntry> suggestions})
|
||||
: _suggestions = suggestions;
|
||||
|
||||
factory _$IngredientApiSearchImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$IngredientApiSearchImplFromJson(json);
|
||||
|
||||
final List<IngredientApiSearchEntry> _suggestions;
|
||||
@override
|
||||
List<IngredientApiSearchEntry> get suggestions {
|
||||
if (_suggestions is EqualUnmodifiableListView) return _suggestions;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_suggestions);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'IngredientApiSearch(suggestions: $suggestions)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$IngredientApiSearchImpl &&
|
||||
const DeepCollectionEquality().equals(other._suggestions, _suggestions));
|
||||
}
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, const DeepCollectionEquality().hash(_suggestions));
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$IngredientApiSearchImplCopyWith<_$IngredientApiSearchImpl> get copyWith =>
|
||||
__$$IngredientApiSearchImplCopyWithImpl<_$IngredientApiSearchImpl>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$IngredientApiSearchImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _IngredientApiSearch implements IngredientApiSearch {
|
||||
factory _IngredientApiSearch({required final List<IngredientApiSearchEntry> suggestions}) =
|
||||
_$IngredientApiSearchImpl;
|
||||
|
||||
factory _IngredientApiSearch.fromJson(Map<String, dynamic> json) =
|
||||
_$IngredientApiSearchImpl.fromJson;
|
||||
|
||||
@override
|
||||
List<IngredientApiSearchEntry> get suggestions;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$$IngredientApiSearchImplCopyWith<_$IngredientApiSearchImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
50
lib/models/exercises/ingredient_api.g.dart
Normal file
50
lib/models/exercises/ingredient_api.g.dart
Normal file
@@ -0,0 +1,50 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'ingredient_api.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_$IngredientApiSearchDetailsImpl _$$IngredientApiSearchDetailsImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$IngredientApiSearchDetailsImpl(
|
||||
id: json['id'] as int,
|
||||
name: json['name'] as String,
|
||||
image: json['image'] as String?,
|
||||
imageThumbnail: json['image_thumbnail'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$IngredientApiSearchDetailsImplToJson(
|
||||
_$IngredientApiSearchDetailsImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'name': instance.name,
|
||||
'image': instance.image,
|
||||
'image_thumbnail': instance.imageThumbnail,
|
||||
};
|
||||
|
||||
_$IngredientApiSearchEntryImpl _$$IngredientApiSearchEntryImplFromJson(Map<String, dynamic> json) =>
|
||||
_$IngredientApiSearchEntryImpl(
|
||||
value: json['value'] as String,
|
||||
data: IngredientApiSearchDetails.fromJson(json['data'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$IngredientApiSearchEntryImplToJson(
|
||||
_$IngredientApiSearchEntryImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'value': instance.value,
|
||||
'data': instance.data,
|
||||
};
|
||||
|
||||
_$IngredientApiSearchImpl _$$IngredientApiSearchImplFromJson(Map<String, dynamic> json) =>
|
||||
_$IngredientApiSearchImpl(
|
||||
suggestions: (json['suggestions'] as List<dynamic>)
|
||||
.map((e) => IngredientApiSearchEntry.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$IngredientApiSearchImplToJson(_$IngredientApiSearchImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'suggestions': instance.suggestions,
|
||||
};
|
||||
@@ -649,12 +649,9 @@ class ExercisesProvider with ChangeNotifier {
|
||||
),
|
||||
);
|
||||
|
||||
// Process the response
|
||||
return Future.wait(
|
||||
(result['suggestions'] as List).map<Future<Exercise>>(
|
||||
(entry) => fetchAndSetExercise(entry['data']['base_id']),
|
||||
),
|
||||
);
|
||||
// Load the ingredients
|
||||
final results = ExerciseApiSearch.fromJson(result);
|
||||
return Future.wait(results.suggestions.map((e) => fetchAndSetExercise(e.data.exerciseId)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:wger/exceptions/http_exception.dart';
|
||||
import 'package:wger/exceptions/no_such_entry_exception.dart';
|
||||
import 'package:wger/helpers/consts.dart';
|
||||
import 'package:wger/models/exercises/ingredient_api.dart';
|
||||
import 'package:wger/models/nutrition/image.dart';
|
||||
import 'package:wger/models/nutrition/ingredient.dart';
|
||||
import 'package:wger/models/nutrition/log.dart';
|
||||
@@ -331,7 +332,7 @@ class NutritionPlansProvider with ChangeNotifier {
|
||||
}
|
||||
|
||||
/// Searches for an ingredient
|
||||
Future<List> searchIngredient(
|
||||
Future<List<IngredientApiSearchEntry>> searchIngredient(
|
||||
String name, {
|
||||
String languageCode = 'en',
|
||||
bool searchEnglish = false,
|
||||
@@ -352,7 +353,7 @@ class NutritionPlansProvider with ChangeNotifier {
|
||||
);
|
||||
|
||||
// Process the response
|
||||
return response['suggestions'];
|
||||
return IngredientApiSearch.fromJson(response).suggestions;
|
||||
}
|
||||
|
||||
/// Searches for an ingredient with code
|
||||
|
||||
@@ -17,8 +17,7 @@
|
||||
*/
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
//import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart';
|
||||
import 'package:flutter/services.dart'; //import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:flutter_typeahead/flutter_typeahead.dart';
|
||||
import 'package:flutter_zxing/flutter_zxing.dart';
|
||||
@@ -27,6 +26,7 @@ import 'package:provider/provider.dart';
|
||||
import 'package:wger/helpers/consts.dart';
|
||||
import 'package:wger/helpers/platform.dart';
|
||||
import 'package:wger/helpers/ui.dart';
|
||||
import 'package:wger/models/exercises/ingredient_api.dart';
|
||||
import 'package:wger/providers/nutrition.dart';
|
||||
import 'package:wger/widgets/core/core.dart';
|
||||
|
||||
@@ -90,44 +90,56 @@ class _IngredientTypeaheadState extends State<IngredientTypeahead> {
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
TypeAheadFormField(
|
||||
textFieldConfiguration: TextFieldConfiguration(
|
||||
controller: widget._ingredientController,
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: const Icon(Icons.search),
|
||||
labelText: AppLocalizations.of(context).searchIngredient,
|
||||
suffixIcon: (widget.showScanner && !isDesktop) ? scanButton() : null,
|
||||
),
|
||||
),
|
||||
suggestionsCallback: (pattern) async {
|
||||
TypeAheadField<IngredientApiSearchEntry>(
|
||||
controller: widget._ingredientController,
|
||||
builder: (context, controller, focusNode) {
|
||||
return TextFormField(
|
||||
controller: controller,
|
||||
focusNode: focusNode,
|
||||
autofocus: true,
|
||||
validator: (value) {
|
||||
if (value!.isEmpty) {
|
||||
return AppLocalizations.of(context).selectIngredient;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: const Icon(Icons.search),
|
||||
labelText: AppLocalizations.of(context).searchIngredient,
|
||||
suffixIcon: (widget.showScanner && !isDesktop) ? scanButton() : null,
|
||||
),
|
||||
);
|
||||
},
|
||||
suggestionsCallback: (pattern) {
|
||||
if (pattern == '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Provider.of<NutritionPlansProvider>(context, listen: false).searchIngredient(
|
||||
pattern,
|
||||
languageCode: Localizations.localeOf(context).languageCode,
|
||||
searchEnglish: _searchEnglish,
|
||||
);
|
||||
},
|
||||
itemBuilder: (context, dynamic suggestion) {
|
||||
itemBuilder: (context, suggestion) {
|
||||
final url = context.read<NutritionPlansProvider>().baseProvider.auth.serverUrl;
|
||||
return ListTile(
|
||||
leading: suggestion['data']['image'] != null
|
||||
? CircleAvatar(backgroundImage: NetworkImage(url! + suggestion['data']['image']))
|
||||
leading: suggestion.data.image != null
|
||||
? CircleAvatar(backgroundImage: NetworkImage(url! + suggestion.data.image!))
|
||||
: const CircleIconAvatar(Icon(Icons.image, color: Colors.grey)),
|
||||
title: Text(suggestion['value']),
|
||||
subtitle: Text(suggestion['data']['id'].toString()),
|
||||
title: Text(suggestion.value),
|
||||
// subtitle: Text(suggestion.data.id.toString()),
|
||||
);
|
||||
},
|
||||
transitionBuilder: (context, suggestionsBox, controller) {
|
||||
return suggestionsBox;
|
||||
},
|
||||
onSuggestionSelected: (dynamic suggestion) {
|
||||
widget._ingredientIdController.text = suggestion['data']['id'].toString();
|
||||
widget._ingredientController.text = suggestion['value'];
|
||||
},
|
||||
validator: (value) {
|
||||
if (value!.isEmpty) {
|
||||
return AppLocalizations.of(context).selectIngredient;
|
||||
}
|
||||
return null;
|
||||
transitionBuilder: (context, animation, child) => FadeTransition(
|
||||
opacity: CurvedAnimation(parent: animation, curve: Curves.fastOutSlowIn),
|
||||
child: child,
|
||||
),
|
||||
onSelected: (suggestion) {
|
||||
//SuggestionsController.of(context).;
|
||||
|
||||
widget._ingredientIdController.text = suggestion.data.id.toString();
|
||||
widget._ingredientController.text = suggestion.value;
|
||||
},
|
||||
),
|
||||
if (Localizations.localeOf(context).languageCode != LANGUAGE_SHORT_ENGLISH)
|
||||
|
||||
@@ -363,106 +363,126 @@ class _SetFormWidgetState extends State<SetFormWidget> {
|
||||
Card(
|
||||
child: Column(
|
||||
children: [
|
||||
TypeAheadFormField<Exercise>(
|
||||
TypeAheadField<Exercise>(
|
||||
key: const Key('field-typeahead'),
|
||||
textFieldConfiguration: TextFieldConfiguration(
|
||||
controller: _exercisesController,
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context).searchExercise,
|
||||
prefixIcon: const Icon(Icons.search),
|
||||
suffixIcon: IconButton(
|
||||
icon: const Icon(Icons.help),
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(AppLocalizations.of(context).selectExercises),
|
||||
const SizedBox(height: 10),
|
||||
Text(AppLocalizations.of(context).sameRepetitions)
|
||||
decorationBuilder: (context, child) {
|
||||
return Material(
|
||||
type: MaterialType.card,
|
||||
elevation: 4,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
controller: _exercisesController,
|
||||
builder: (context, controller, focusNode) {
|
||||
return TextFormField(
|
||||
controller: controller,
|
||||
focusNode: focusNode,
|
||||
// autofocus: true,
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context).searchExercise,
|
||||
prefixIcon: const Icon(Icons.search),
|
||||
suffixIcon: IconButton(
|
||||
icon: const Icon(Icons.help),
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(AppLocalizations.of(context).selectExercises),
|
||||
const SizedBox(height: 10),
|
||||
Text(AppLocalizations.of(context).sameRepetitions)
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(
|
||||
MaterialLocalizations.of(context).closeButtonLabel),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(
|
||||
MaterialLocalizations.of(context).closeButtonLabel),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
errorMaxLines: 2,
|
||||
border: InputBorder.none,
|
||||
),
|
||||
errorMaxLines: 2,
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
validator: (value) {
|
||||
// At least one exercise must be selected
|
||||
if (widget._set.exerciseBasesIds.isEmpty) {
|
||||
return AppLocalizations.of(context).selectExercise;
|
||||
}
|
||||
|
||||
// At least one setting has to be filled in
|
||||
if (widget._set.settings
|
||||
.where((s) => s.weight == null && s.reps == null)
|
||||
.length ==
|
||||
widget._set.settings.length) {
|
||||
return AppLocalizations.of(context).enterRepetitionsOrWeight;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
);
|
||||
},
|
||||
suggestionsCallback: (pattern) {
|
||||
if (pattern == '') {
|
||||
return null;
|
||||
}
|
||||
return context.read<ExercisesProvider>().searchExercise(
|
||||
pattern,
|
||||
languageCode: Localizations.localeOf(context).languageCode,
|
||||
searchEnglish: _searchEnglish,
|
||||
);
|
||||
},
|
||||
itemBuilder: (BuildContext context, Exercise exerciseSuggestion) {
|
||||
return ListTile(
|
||||
leading: SizedBox(
|
||||
width: 45,
|
||||
child: ExerciseImageWidget(image: exerciseSuggestion.getMainImage),
|
||||
),
|
||||
title: Text(
|
||||
exerciseSuggestion
|
||||
.getExercise(Localizations.localeOf(context).languageCode)
|
||||
.name,
|
||||
),
|
||||
subtitle: Text(
|
||||
'${exerciseSuggestion.category!.name} / ${exerciseSuggestion.equipment.map((e) => e.name).join(', ')}',
|
||||
),
|
||||
);
|
||||
},
|
||||
noItemsFoundBuilder: (context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(AppLocalizations.of(context).noMatchingExerciseFound),
|
||||
TextButton(
|
||||
itemBuilder: (BuildContext context, Exercise exerciseSuggestion) =>
|
||||
ListTile(
|
||||
key: Key('exercise-${exerciseSuggestion.id}'),
|
||||
leading: SizedBox(
|
||||
width: 45,
|
||||
child: ExerciseImageWidget(image: exerciseSuggestion.getMainImage),
|
||||
),
|
||||
title: Text(
|
||||
exerciseSuggestion
|
||||
.getExercise(Localizations.localeOf(context).languageCode)
|
||||
.name,
|
||||
),
|
||||
subtitle: Text(
|
||||
'${exerciseSuggestion.category!.name} / ${exerciseSuggestion.equipment.map((e) => e.name).join(', ')}',
|
||||
),
|
||||
),
|
||||
emptyBuilder: (context) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ListTile(
|
||||
title: Text(AppLocalizations.of(context).noMatchingExerciseFound),
|
||||
),
|
||||
ListTile(
|
||||
title: OutlinedButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pushNamed(AddExerciseScreen.routeName);
|
||||
},
|
||||
child: Text(AppLocalizations.of(context).contributeExercise),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
transitionBuilder: (context, suggestionsBox, controller) {
|
||||
return suggestionsBox;
|
||||
},
|
||||
onSuggestionSelected: (Exercise exerciseSuggestion) {
|
||||
transitionBuilder: (context, animation, child) => FadeTransition(
|
||||
opacity: CurvedAnimation(parent: animation, curve: Curves.fastOutSlowIn),
|
||||
child: child,
|
||||
),
|
||||
onSelected: (Exercise exerciseSuggestion) {
|
||||
// SuggestionsController.of(context).select(exerciseSuggestion);
|
||||
|
||||
addExercise(exerciseSuggestion);
|
||||
_exercisesController.text = '';
|
||||
},
|
||||
validator: (value) {
|
||||
// At least one exercise must be selected
|
||||
if (widget._set.exerciseBasesIds.isEmpty) {
|
||||
return AppLocalizations.of(context).selectExercise;
|
||||
}
|
||||
|
||||
// At least one setting has to be filled in
|
||||
if (widget._set.settings
|
||||
.where((s) => s.weight == null && s.reps == null)
|
||||
.length ==
|
||||
widget._set.settings.length) {
|
||||
return AppLocalizations.of(context).enterRepetitionsOrWeight;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
if (Localizations.localeOf(context).languageCode != LANGUAGE_SHORT_ENGLISH)
|
||||
SwitchListTile(
|
||||
|
||||
@@ -226,7 +226,7 @@ packages:
|
||||
source: hosted
|
||||
version: "0.4.1"
|
||||
clock:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: clock
|
||||
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
|
||||
@@ -537,10 +537,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_typeahead
|
||||
sha256: ef2dd5a505d2d95a5b4c571c81ad2d6e7955f583dddec49064fec57acffd7a96
|
||||
sha256: e2070dea278f09ae30885872138ccae75292b33b7af2c241fec5ceafd980c374
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.2"
|
||||
version: "5.1.0"
|
||||
flutter_web_plugins:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
|
||||
@@ -38,7 +38,7 @@ dependencies:
|
||||
equatable: ^2.0.5
|
||||
flutter_calendar_carousel: ^2.4.1
|
||||
flutter_html: ^3.0.0-beta.2
|
||||
flutter_typeahead: ^5.0.2
|
||||
flutter_typeahead: ^5.1.0
|
||||
font_awesome_flutter: ^10.4.0
|
||||
http: ^1.2.0
|
||||
image_picker: ^1.0.6
|
||||
|
||||
@@ -93,9 +93,7 @@ void main() {
|
||||
body: anyNamed('body'),
|
||||
)).thenAnswer((_) => Future(() => Response(json.encode(responseLoginOk), 200)));
|
||||
|
||||
when(mockClient.get(
|
||||
any,
|
||||
)).thenAnswer((_) => Future(() => Response('"1.2.3.4"', 200)));
|
||||
when(mockClient.get(any)).thenAnswer((_) => Future(() => Response('"1.2.3.4"', 200)));
|
||||
|
||||
when(mockClient.post(
|
||||
tRegistration,
|
||||
|
||||
@@ -76,7 +76,7 @@ void main() {
|
||||
when(mockExerciseProvider.muscles).thenReturn(testMuscles);
|
||||
when(mockExerciseProvider.equipment).thenReturn(testEquipment);
|
||||
when(mockExerciseProvider.exerciseBasesByVariation).thenReturn({});
|
||||
when(mockExerciseProvider.exercises).thenReturn(getTestExerciseBases());
|
||||
when(mockExerciseProvider.exercises).thenReturn(getTestExercises());
|
||||
when(mockExerciseProvider.languages).thenReturn(testLanguages);
|
||||
|
||||
when(mockAddExerciseProvider.equipment).thenReturn([]);
|
||||
|
||||
@@ -50,7 +50,7 @@ void main() {
|
||||
mockBaseProvider,
|
||||
database: ExerciseDatabase.inMemory(NativeDatabase.memory()),
|
||||
);
|
||||
provider.exercises = getTestExerciseBases();
|
||||
provider.exercises = getTestExercises();
|
||||
provider.languages = [tLanguage1, tLanguage2, tLanguage3];
|
||||
|
||||
// Mock base info response
|
||||
|
||||
@@ -223,7 +223,7 @@ void main() {
|
||||
equipment: FilterCategory<Equipment>(title: 'Equipment', items: {}),
|
||||
);
|
||||
|
||||
provider.exercises = data.getTestExerciseBases();
|
||||
provider.exercises = data.getTestExercises();
|
||||
});
|
||||
|
||||
test('Nothing is selected with no search term', () async {
|
||||
@@ -238,7 +238,7 @@ void main() {
|
||||
|
||||
expect(
|
||||
provider.filteredExercises,
|
||||
data.getTestExerciseBases(),
|
||||
data.getTestExercises(),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -253,7 +253,7 @@ void main() {
|
||||
|
||||
// assert
|
||||
verifyNever(provider.baseProvider.fetch(tSearchByNameUri));
|
||||
expect(provider.filteredExercises, [data.getTestExerciseBases()[0]]);
|
||||
expect(provider.filteredExercises, [data.getTestExercises()[0]]);
|
||||
});
|
||||
|
||||
test('A muscle is selected with no search term. Should not find results', () async {
|
||||
@@ -281,7 +281,7 @@ void main() {
|
||||
|
||||
// assert
|
||||
verifyNever(provider.baseProvider.fetch(tSearchByNameUri));
|
||||
expect(provider.filteredExercises, [data.getTestExerciseBases()[0]]);
|
||||
expect(provider.filteredExercises, [data.getTestExercises()[0]]);
|
||||
});
|
||||
|
||||
test('An equipment is selected with no search term. Should not find results', () async {
|
||||
@@ -310,7 +310,7 @@ void main() {
|
||||
|
||||
// assert
|
||||
verifyNever(provider.baseProvider.fetch(tSearchByNameUri));
|
||||
expect(provider.filteredExercises, [data.getTestExerciseBases()[1]]);
|
||||
expect(provider.filteredExercises, [data.getTestExercises()[1]]);
|
||||
});
|
||||
|
||||
test('A muscle and equipment is selected but no match', () async {
|
||||
@@ -365,7 +365,7 @@ void main() {
|
||||
verify(provider.baseProvider.fetch(tSearchByNameUri)).called(1);
|
||||
expect(
|
||||
provider.filteredExercises,
|
||||
[data.getTestExerciseBases()[0], data.getTestExerciseBases()[1]],
|
||||
[data.getTestExercises()[0], data.getTestExercises()[1]],
|
||||
);
|
||||
});
|
||||
test('Should find items from selection but should filter them by search term', () async {
|
||||
|
||||
@@ -38,7 +38,7 @@ void main() {
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
navigatorKey: GlobalKey<NavigatorState>(),
|
||||
home: Scaffold(
|
||||
body: ExerciseDetail(getTestExerciseBases()[0]),
|
||||
body: ExerciseDetail(getTestExercises()[0]),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -14,7 +14,7 @@ void main() {
|
||||
group('Model tests', () {
|
||||
test('test getExercise', () async {
|
||||
// arrange and act
|
||||
final base = getTestExerciseBases()[1];
|
||||
final base = getTestExercises()[1];
|
||||
|
||||
// assert
|
||||
expect(base.getExercise('en').id, 5);
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'dart:async' as _i8;
|
||||
import 'dart:ui' as _i9;
|
||||
import 'dart:ui' as _i10;
|
||||
|
||||
import 'package:mockito/mockito.dart' as _i1;
|
||||
import 'package:wger/models/exercises/ingredient_api.dart' as _i9;
|
||||
import 'package:wger/models/nutrition/ingredient.dart' as _i6;
|
||||
import 'package:wger/models/nutrition/meal.dart' as _i4;
|
||||
import 'package:wger/models/nutrition/meal_item.dart' as _i5;
|
||||
@@ -341,7 +342,7 @@ class MockNutritionPlansProvider extends _i1.Mock implements _i7.NutritionPlansP
|
||||
) as _i8.Future<void>);
|
||||
|
||||
@override
|
||||
_i8.Future<List<dynamic>> searchIngredient(
|
||||
_i8.Future<List<_i9.IngredientApiSearchEntry>> searchIngredient(
|
||||
String? name, {
|
||||
String? languageCode = r'en',
|
||||
bool? searchEnglish = false,
|
||||
@@ -355,8 +356,9 @@ class MockNutritionPlansProvider extends _i1.Mock implements _i7.NutritionPlansP
|
||||
#searchEnglish: searchEnglish,
|
||||
},
|
||||
),
|
||||
returnValue: _i8.Future<List<dynamic>>.value(<dynamic>[]),
|
||||
) as _i8.Future<List<dynamic>>);
|
||||
returnValue:
|
||||
_i8.Future<List<_i9.IngredientApiSearchEntry>>.value(<_i9.IngredientApiSearchEntry>[]),
|
||||
) as _i8.Future<List<_i9.IngredientApiSearchEntry>>);
|
||||
|
||||
@override
|
||||
_i8.Future<_i6.Ingredient?> searchIngredientWithCode(String? code) => (super.noSuchMethod(
|
||||
@@ -424,7 +426,7 @@ class MockNutritionPlansProvider extends _i1.Mock implements _i7.NutritionPlansP
|
||||
) as _i8.Future<void>);
|
||||
|
||||
@override
|
||||
void addListener(_i9.VoidCallback? listener) => super.noSuchMethod(
|
||||
void addListener(_i10.VoidCallback? listener) => super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#addListener,
|
||||
[listener],
|
||||
@@ -433,7 +435,7 @@ class MockNutritionPlansProvider extends _i1.Mock implements _i7.NutritionPlansP
|
||||
);
|
||||
|
||||
@override
|
||||
void removeListener(_i9.VoidCallback? listener) => super.noSuchMethod(
|
||||
void removeListener(_i10.VoidCallback? listener) => super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#removeListener,
|
||||
[listener],
|
||||
|
||||
@@ -9,6 +9,7 @@ import 'package:http/http.dart' as http;
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:wger/helpers/consts.dart';
|
||||
import 'package:wger/models/exercises/ingredient_api.dart';
|
||||
import 'package:wger/models/nutrition/ingredient.dart';
|
||||
import 'package:wger/models/nutrition/meal.dart';
|
||||
import 'package:wger/models/nutrition/meal_item.dart';
|
||||
@@ -76,8 +77,13 @@ void main() {
|
||||
when(mockNutrition.searchIngredientWithCode('123')).thenAnswer((_) => Future.value(ingredient));
|
||||
when(mockNutrition.searchIngredientWithCode('')).thenAnswer((_) => Future.value(null));
|
||||
when(mockNutrition.searchIngredientWithCode('222')).thenAnswer((_) => Future.value(null));
|
||||
when(mockNutrition.searchIngredient(any)).thenAnswer((_) =>
|
||||
Future.value(json.decode(fixture('nutrition/ingredient_suggestions')) as List<dynamic>));
|
||||
when(mockNutrition.searchIngredient(any,
|
||||
languageCode: anyNamed('languageCode'), searchEnglish: anyNamed('searchEnglish')))
|
||||
.thenAnswer(
|
||||
(_) => Future.value(
|
||||
IngredientApiSearch.fromJson(json.decode(fixture('nutrition/ingredient_suggestions')))
|
||||
.suggestions),
|
||||
);
|
||||
|
||||
when(mockNutrition.addMealItem(any, meal1)).thenAnswer((_) => Future.value(mealItem));
|
||||
});
|
||||
@@ -109,8 +115,8 @@ void main() {
|
||||
await tester.pumpWidget(createMealItemFormScreen(meal1, '', true));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(TypeAheadFormField), findsOneWidget);
|
||||
expect(find.byType(TextFormField), findsOneWidget);
|
||||
expect(find.byType(TypeAheadField<IngredientApiSearchEntry>), findsOneWidget);
|
||||
expect(find.byType(TextFormField), findsWidgets);
|
||||
expect(find.byKey(const Key('scan-button')), findsOneWidget);
|
||||
expect(find.byKey(const Key(SUBMIT_BUTTON_KEY_NAME)), findsOneWidget);
|
||||
|
||||
@@ -248,6 +254,8 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('save ingredient without weight', (WidgetTester tester) async {
|
||||
await tester.binding.setSurfaceSize(const Size(1080, 1920));
|
||||
tester.view.devicePixelRatio = 1.0;
|
||||
await tester.pumpWidget(createMealItemFormScreen(meal1, '123', true));
|
||||
|
||||
await tester.tap(find.byKey(const Key('scan-button')));
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'dart:async' as _i8;
|
||||
import 'dart:ui' as _i9;
|
||||
import 'dart:ui' as _i10;
|
||||
|
||||
import 'package:mockito/mockito.dart' as _i1;
|
||||
import 'package:wger/models/exercises/ingredient_api.dart' as _i9;
|
||||
import 'package:wger/models/nutrition/ingredient.dart' as _i6;
|
||||
import 'package:wger/models/nutrition/meal.dart' as _i4;
|
||||
import 'package:wger/models/nutrition/meal_item.dart' as _i5;
|
||||
@@ -341,7 +342,7 @@ class MockNutritionPlansProvider extends _i1.Mock implements _i7.NutritionPlansP
|
||||
) as _i8.Future<void>);
|
||||
|
||||
@override
|
||||
_i8.Future<List<dynamic>> searchIngredient(
|
||||
_i8.Future<List<_i9.IngredientApiSearchEntry>> searchIngredient(
|
||||
String? name, {
|
||||
String? languageCode = r'en',
|
||||
bool? searchEnglish = false,
|
||||
@@ -355,8 +356,9 @@ class MockNutritionPlansProvider extends _i1.Mock implements _i7.NutritionPlansP
|
||||
#searchEnglish: searchEnglish,
|
||||
},
|
||||
),
|
||||
returnValue: _i8.Future<List<dynamic>>.value(<dynamic>[]),
|
||||
) as _i8.Future<List<dynamic>>);
|
||||
returnValue:
|
||||
_i8.Future<List<_i9.IngredientApiSearchEntry>>.value(<_i9.IngredientApiSearchEntry>[]),
|
||||
) as _i8.Future<List<_i9.IngredientApiSearchEntry>>);
|
||||
|
||||
@override
|
||||
_i8.Future<_i6.Ingredient?> searchIngredientWithCode(String? code) => (super.noSuchMethod(
|
||||
@@ -424,7 +426,7 @@ class MockNutritionPlansProvider extends _i1.Mock implements _i7.NutritionPlansP
|
||||
) as _i8.Future<void>);
|
||||
|
||||
@override
|
||||
void addListener(_i9.VoidCallback? listener) => super.noSuchMethod(
|
||||
void addListener(_i10.VoidCallback? listener) => super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#addListener,
|
||||
[listener],
|
||||
@@ -433,7 +435,7 @@ class MockNutritionPlansProvider extends _i1.Mock implements _i7.NutritionPlansP
|
||||
);
|
||||
|
||||
@override
|
||||
void removeListener(_i9.VoidCallback? listener) => super.noSuchMethod(
|
||||
void removeListener(_i10.VoidCallback? listener) => super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#removeListener,
|
||||
[listener],
|
||||
|
||||
@@ -41,7 +41,7 @@ void main() {
|
||||
|
||||
final mockExerciseProvider = MockExercisesProvider();
|
||||
final workoutPlan = getWorkout();
|
||||
final bases = getTestExerciseBases();
|
||||
final bases = getTestExercises();
|
||||
|
||||
Widget createHomeScreen({locale = 'en'}) {
|
||||
return ChangeNotifierProvider<WorkoutPlansProvider>(
|
||||
|
||||
@@ -27,16 +27,16 @@ void main() {
|
||||
final workout = getWorkout();
|
||||
|
||||
expect(workout.logs.length, 3);
|
||||
final logExercise1 = workout.filterLogsByExerciseBase(getTestExerciseBases()[0]);
|
||||
final logExercise1 = workout.filterLogsByExerciseBase(getTestExercises()[0]);
|
||||
expect(logExercise1.length, 2);
|
||||
expect(logExercise1[0].id, 1);
|
||||
expect(logExercise1[1].id, 2);
|
||||
|
||||
final logExercise2 = workout.filterLogsByExerciseBase(getTestExerciseBases()[1]);
|
||||
final logExercise2 = workout.filterLogsByExerciseBase(getTestExercises()[1]);
|
||||
expect(logExercise2.length, 1);
|
||||
expect(logExercise2[0].id, 3);
|
||||
|
||||
expect(workout.filterLogsByExerciseBase(getTestExerciseBases()[2]).length, 0);
|
||||
expect(workout.filterLogsByExerciseBase(getTestExercises()[2]).length, 0);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import 'package:wger/providers/exercises.dart';
|
||||
import 'package:wger/providers/workout_plans.dart';
|
||||
import 'package:wger/widgets/workouts/forms.dart';
|
||||
|
||||
import '../../test_data/exercises.dart';
|
||||
import '../../test_data/workouts.dart';
|
||||
import 'workout_set_form_test.mocks.dart';
|
||||
|
||||
@@ -84,6 +85,13 @@ void main() {
|
||||
when(mockWorkoutPlans.addSet(any)).thenAnswer((_) => Future.value(Set.empty()));
|
||||
when(mockWorkoutPlans.addSetting(any)).thenAnswer((_) => Future.value(Setting.empty()));
|
||||
when(mockWorkoutPlans.fetchSmartText(any, any)).thenAnswer((_) => Future.value('2 x 10'));
|
||||
when(mockExerciseProvider.searchExercise(
|
||||
any,
|
||||
languageCode: anyNamed('languageCode'),
|
||||
searchEnglish: anyNamed('searchEnglish'),
|
||||
)).thenAnswer(
|
||||
(_) => Future.value([getTestExercises().first]),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
await tester.pumpAndSettle();
|
||||
@@ -91,6 +99,7 @@ void main() {
|
||||
await tester.enterText(find.byKey(const Key('field-typeahead')), 'exercise');
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
//await tester.tap(find.byKey(const Key('exercise-1')));
|
||||
await tester.tap(find.byKey(const Key(SUBMIT_BUTTON_KEY_NAME)));
|
||||
|
||||
//verify(mockWorkoutPlans.addSet(any));
|
||||
|
||||
@@ -203,7 +203,7 @@ final sideRaisesEn = Translation(
|
||||
language: tLanguage2,
|
||||
);
|
||||
|
||||
List<Exercise> getTestExerciseBases() {
|
||||
List<Exercise> getTestExercises() {
|
||||
benchPress.translations = [benchPressEn, benchPressDe];
|
||||
crunches.translations = [crunchesEn, crunchesDe, crunchesFr];
|
||||
deadLift.translations = [deadLiftEn];
|
||||
|
||||
@@ -210,8 +210,7 @@ final benchPressDE = Translation(
|
||||
uuid: '198dcb2e-e35f-4b69-ae8b-e1124d438eae',
|
||||
created: DateTime(2021, 1, 15),
|
||||
name: 'Bankdrücken LH',
|
||||
description:
|
||||
'''
|
||||
description: '''
|
||||
<p>Lege dich auf die Bank, die Stange direkt über die Augen, die Knie etwas angewinkelt und die Füße fest auf dem Boden. Greife die Stange breit und lasse sie langsam und kontrolliert runter, dabei sollte die Stange kurz auf Brustwarzenhöhe den Körper berühren. Dann das Gewicht wieder hochdrücken bis die Arme durchgestreckt sind.</p>
|
||||
<p>Bei hohem Gewicht, empfielt sich natürlich einen <em>Spotter</em> zu haben, der einen hilft falls man die Stange nicht alleine hochdrücken kann.</p>
|
||||
<p>Mit der Breite des Griffs kann außerdem kontrolliert werden, welcher Bereich der Brust stärker belastet wird:</p>
|
||||
@@ -228,8 +227,7 @@ final benchPressEN = Translation(
|
||||
uuid: '5da6340b-22ec-4c1b-a443-eef2f59f92f0',
|
||||
created: DateTime(2021, 1, 15),
|
||||
name: 'Bench Press',
|
||||
description:
|
||||
'''
|
||||
description: '''
|
||||
<p>Lay down on a bench, the bar should be directly above your eyes, the knees are somewhat angled and the feet are firmly on the floor. Concentrate, breath deeply and grab the bar more than shoulder wide. Bring it slowly down till it briefly touches your chest at the height of your nipples. Push the bar up.</p>
|
||||
<p>If you train with a high weight it is advisable to have a <em>spotter</em> that can help you up if you can't lift the weight on your own.</p>
|
||||
<p>With the width of the grip you can also control which part of the chest is trained more:</p>
|
||||
@@ -258,8 +256,7 @@ final deadLiftEN = Translation(
|
||||
uuid: '22cca8fc-cfaf-4941-b0f7-faf9f2937c52',
|
||||
created: DateTime(2021, 1, 15),
|
||||
name: 'Deadlifts',
|
||||
description:
|
||||
'''
|
||||
description: '''
|
||||
<p>Stand firmly, with your feet slightly more than shoulder wide apart. Stand directly behind the bar where it should barely touch your shin, your feet pointing a bit out. Bend down with a straight back, the knees also pointing somewhat out. Grab the bar with a shoulder wide grip, one underhand, one reverse grip.</p>
|
||||
<p>Pull the weight up. At the highest point make a slight hollow back and pull the bar back. Hold 1 or 2 seconds that position. Go down, making sure the back is not bent. Once down you can either go back again as soon as the weights touch the floor, or make a pause, depending on the weight.</p>''',
|
||||
exerciseId: 184,
|
||||
@@ -271,8 +268,7 @@ final deadLiftDE = Translation(
|
||||
uuid: '521a5e4f-6f35-43e5-9d1c-6e75c4956e96',
|
||||
created: DateTime(2021, 1, 15),
|
||||
name: 'Kreuzheben',
|
||||
description:
|
||||
'''
|
||||
description: '''
|
||||
<p>Stelle dich mit etwas mehr als schulterbreitem Stand vor der Stange, die Füße zeigen leicht nach außen, die Stange ist direkt darüber und sehr nahe am Schienbein. Beuge die Knie (zeigen ebenfalls etwas nach außen) und neige den Oberkörper (bleibt während der ganzen Übung gerade). Greife die Stange schulterbreit mit einem Unter- und einem Obergriff.</p>
|
||||
<p>Ziehe nun die Stange nach oben. An der höchsten Stelle mache ein leichtes Hohlkreuz und drücke die Schultern nach hinten. Gehe wieder runter, wobei du darauf achtest, dass der Rücken gerade bleibt und sich nicht krümmt. Du kannst unten angekommen eine kleine Pause einlegen oder sofort weitermachen.</p>''',
|
||||
exerciseId: 184,
|
||||
@@ -284,8 +280,7 @@ final deadLiftPT = Translation(
|
||||
uuid: 'e570cd82-5a8f-4768-a2f3-8d60bad5c6e8',
|
||||
created: DateTime(2021, 1, 15),
|
||||
name: 'Levantamento terra',
|
||||
description:
|
||||
'''
|
||||
description: '''
|
||||
Fique firme, com os pés ligeiramente mais afastados do que os ombros. Fique diretamente atrás da barra, onde ela mal deve tocar sua canela, com os pés apontando um pouco para fora. Curve-se com as costas retas, os joelhos também apontando um pouco para fora. Agarre a barra com uma pegada na largura dos ombros, uma pegada por baixo e uma pegada reversa.
|
||||
|
||||
Puxe o peso para cima. No ponto mais alto, faça uma leve depressão para trás e puxe a barra para trás. Segure 1 ou 2 segundos nessa posição. Desça, certificando-se de que as costas não estão dobradas. Depois de descer, você pode voltar assim que os pesos tocarem o chão ou fazer uma pausa, dependendo do peso.''',
|
||||
@@ -378,8 +373,7 @@ final crunchesDE = Translation(
|
||||
uuid: '0e10ac9b-ed1d-42c9-b8cc-123c22ccc5d5',
|
||||
created: DateTime(2021, 1, 15),
|
||||
name: 'Crunches',
|
||||
description:
|
||||
'''
|
||||
description: '''
|
||||
<p>Lege dich auf eine Matte mit angewinkelten Beinen. Die Füße werden irgendwie festgehalten (Partner, Lanhghantel, o.Ä.) und die Hände werden hinter dem Nacken verschränkt. Aus dieser Position führe den Oberkörper so weit nach oben, bis Kopf oder Ellenbogen die angewinkelten Beine berühren.</p>
|
||||
<p>Es ist wichtig, dass dieser Vorgang mit einer rollenden Bewegung durchgeführt wird: die Wirbelsäule sollte sich Wirbel für Wirbel von der Matte lösen. Ein Hohlkreuz ist stets zu vermeiden.</p>''',
|
||||
exerciseId: 167,
|
||||
@@ -506,8 +500,7 @@ final curlsEN = Translation(
|
||||
uuid: '48a59aa8-4568-409c-8afe-f8cb99c558ea',
|
||||
created: DateTime(2021, 1, 15),
|
||||
name: 'Biceps Curls With Dumbbell',
|
||||
description:
|
||||
'''
|
||||
description: '''
|
||||
<p>Hold two barbells, the arms are streched, the hands are on your side, the palms face inwards. Bend the arms and bring the weight with a fast movement up. At the same time, rotate your arms by 90 degrees at the very beginning of the movement. At the highest point, rotate a little the weights further outwards. Without a pause, bring them down, slowly.</p>
|
||||
<p>Don't allow your body to swing during the exercise, all work is done by the biceps, which are the only mucles that should move (pay attention to the elbows).</p>''',
|
||||
exerciseId: 92,
|
||||
@@ -519,8 +512,7 @@ final curlsDE = Translation(
|
||||
uuid: '8cbbffcc-1989-43de-9200-03869480398c',
|
||||
created: DateTime(2021, 1, 15),
|
||||
name: 'Bizeps KH-Curls',
|
||||
description:
|
||||
'''
|
||||
description: '''
|
||||
<p>Halte zwei Kurzhantel mit ausgestreckten Armen neben dem Körper, die Handflächen zeigen nach innen. Beuge die Arme und brige die Hanteln mit einer schnellen Bewegung nach oben wobei sie gleichzeitig um 90 Grad gedreht werden. Am höchsten Punkt kann man die Hanteln ganz leicht weiter nach außen drehen. Ohne Pause wird das Gewicht nun kontrolliert nach unten gebracht. Beachte, dass die Bewegung nach oben schneller ist als nach unten.</p>
|
||||
<p>Während des Bewegungablaufs darf der Körper nicht mitschwingen. Die Ellenbogen bleiben dabei immer an der Stelle.</p>''',
|
||||
exerciseId: 92,
|
||||
|
||||
@@ -34,7 +34,7 @@ const RepetitionUnit repetitionUnit1 = RepetitionUnit(id: 1, name: 'Repetitions'
|
||||
const RepetitionUnit repetitionUnit2 = RepetitionUnit(id: 2, name: 'Hours');
|
||||
|
||||
WorkoutPlan getWorkout({List<Exercise>? exercises}) {
|
||||
final testBases = exercises ?? getTestExerciseBases();
|
||||
final testBases = exercises ?? getTestExercises();
|
||||
|
||||
final log1 = Log.empty()
|
||||
..id = 1
|
||||
|
||||
Reference in New Issue
Block a user