From c78a90b6037086d3c25b0e4a4485860c66f4b828 Mon Sep 17 00:00:00 2001 From: Username1548 Date: Mon, 25 Nov 2024 16:01:02 +0700 Subject: [PATCH] create diet screen --- assets/icons/eatvio_logo.svg | 4 + assets/icons/paste2.svg | 12 + lib/core/const.dart | 4 + lib/core/locator_service.dart | 7 + lib/core/theme/theme_helper.dart | 4 + lib/core/widgets/custom_drop_down_button.dart | 41 + lib/core/widgets/custom_text_form_field.dart | 13 +- .../widgets/main_background_bouble.dart | 0 .../models/consultant_profile_model.g.dart | 48 +- .../create_diet/models/create_diet_model.dart | 8 +- .../models/create_diet_model.freezed.dart | 48 +- .../presentation/create_diet_screen.dart | 113 ++- .../presentation/cubit/create_diet_cubit.dart | 28 +- .../presentation/cubit/create_diet_state.dart | 4 +- .../cubit/create_diet_state.freezed.dart | 64 +- .../presentation/widgets/day_widget.dart | 178 +++++ .../widgets/duration_drop_down_widget.dart | 65 ++ .../widgets/image_picker_widget.dart | 122 +++ .../widgets/status_drop_down_widget.dart | 63 ++ .../widgets/type_choice_widget.dart | 100 +++ .../repositories/create_diet_repository.dart | 25 + .../services/create_diet_service.dart | 14 +- .../services/create_diet_service.g.dart | 64 ++ .../presentation/pages/about_diet_screen.dart | 2 +- .../presentation/widgets/more_options.dart | 2 +- .../presentation/widgets/type_badges.dart | 14 +- .../feed/models/diets_pagination_model.dart | 4 +- .../diets_pagination_model.freezed.dart | 80 +- .../feed/models/diets_pagination_model.g.dart | 8 +- .../bloc/diets_cubit/diets_cubit.dart | 127 +-- .../bloc/diets_cubit/diets_state.dart | 34 +- .../bloc/diets_cubit/diets_state.freezed.dart | 725 ++++++------------ .../feed/presentation/pages/feed_screen.dart | 62 +- .../widgets/choice_chip_widget.dart | 26 +- .../widgets/diet_filter_bottom_sheet.dart | 12 +- .../duration_choice_filter_widget.dart | 117 +-- .../widgets/sorting_drop_down_filter.dart | 66 +- .../widgets/type_choice_filter_widget.dart | 137 ++-- lib/generated/intl/messages_en.dart | 30 +- lib/generated/l10n.dart | 160 +++- lib/l10n/intl_en.arb | 24 +- pubspec.yaml | 1 + 42 files changed, 1742 insertions(+), 918 deletions(-) create mode 100644 assets/icons/eatvio_logo.svg create mode 100644 assets/icons/paste2.svg create mode 100644 lib/core/widgets/custom_drop_down_button.dart rename lib/{features/diets/presentation => core}/widgets/main_background_bouble.dart (100%) create mode 100644 lib/features/create_diet/presentation/widgets/day_widget.dart create mode 100644 lib/features/create_diet/presentation/widgets/duration_drop_down_widget.dart create mode 100644 lib/features/create_diet/presentation/widgets/image_picker_widget.dart create mode 100644 lib/features/create_diet/presentation/widgets/status_drop_down_widget.dart create mode 100644 lib/features/create_diet/presentation/widgets/type_choice_widget.dart create mode 100644 lib/features/create_diet/repositories/create_diet_repository.dart diff --git a/assets/icons/eatvio_logo.svg b/assets/icons/eatvio_logo.svg new file mode 100644 index 00000000..e6ed7018 --- /dev/null +++ b/assets/icons/eatvio_logo.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/icons/paste2.svg b/assets/icons/paste2.svg new file mode 100644 index 00000000..e4e5ac12 --- /dev/null +++ b/assets/icons/paste2.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/lib/core/const.dart b/lib/core/const.dart index 396c2dce..f7dba8dd 100644 --- a/lib/core/const.dart +++ b/lib/core/const.dart @@ -1 +1,5 @@ const String baseUrl = 'https://dev2.eatvio.com'; + +const List durationValues = [7, 14, 21]; + +const List typeValues = ['veg', 'light', 'carb', 'meat']; diff --git a/lib/core/locator_service.dart b/lib/core/locator_service.dart index 44378eb1..39d837db 100644 --- a/lib/core/locator_service.dart +++ b/lib/core/locator_service.dart @@ -1,5 +1,8 @@ import 'package:dio/dio.dart'; import 'package:eatvio_app/core/const.dart'; +import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_cubit.dart'; +import 'package:eatvio_app/features/create_diet/repositories/create_diet_repository.dart'; +import 'package:eatvio_app/features/create_diet/services/create_diet_service.dart'; import 'package:eatvio_app/features/diets/repositories/diet_repository.dart'; import 'package:eatvio_app/features/diets/services/diet_service.dart'; import 'package:eatvio_app/core/initialization_cubit/initialization_cubit.dart'; @@ -74,6 +77,8 @@ Future init() async { sl.registerFactory(() => DiaryCubit(diaryRepository: sl(), glossaryRepository: sl())); sl.registerFactory(() => AboutDietCubit(dietsRepository: sl())); sl.registerFactory(() => BlogPostCreateCubit(blogPostRepository: sl())); + sl.registerFactory(() => CreateDietCubit(createDietRepository: sl())); + // Repository sl.registerLazySingleton(() => ChatRepository(chatService: sl())); @@ -89,6 +94,7 @@ Future init() async { sl.registerLazySingleton(() => GlossaryRepository(glossaryService: sl())); sl.registerLazySingleton(() => DietRepository(dietsService: sl())); sl.registerLazySingleton(() => BlogPostRepository(blogPostService: sl())); + sl.registerLazySingleton(() => CreateDietRepository(createDietService: sl())); // Services sl.registerLazySingleton(() => ChatService(sl())); @@ -104,6 +110,7 @@ Future init() async { sl.registerLazySingleton(() => GlossaryService(sl())); sl.registerLazySingleton(() => DietService(sl())); sl.registerLazySingleton(() => BlogPostService(sl())); + sl.registerLazySingleton(() => CreateDietService(sl())); // External sl.registerLazySingleton( diff --git a/lib/core/theme/theme_helper.dart b/lib/core/theme/theme_helper.dart index 63675d02..77f7595e 100644 --- a/lib/core/theme/theme_helper.dart +++ b/lib/core/theme/theme_helper.dart @@ -178,6 +178,10 @@ class PrimaryColors { Color get transparentBlue => Color(0xFF2F80ED).withOpacity(0.1); Color get lightGray0 => Color(0xFFF6F6F6); + + Color get lightGray00 => Color(0xFFE9E9EA); + + Color get dottedBorder => Color(0xFFE6E6E6); } PrimaryColors get appTheme => ThemeHelper().themeColor(); diff --git a/lib/core/widgets/custom_drop_down_button.dart b/lib/core/widgets/custom_drop_down_button.dart new file mode 100644 index 00000000..843d6730 --- /dev/null +++ b/lib/core/widgets/custom_drop_down_button.dart @@ -0,0 +1,41 @@ +import 'package:eatvio_app/core/theme/theme_helper.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; + +class CustomDropDownButton extends StatelessWidget { + const CustomDropDownButton({ + super.key, + required this.items, + required this.onChanged, + this.value, + this.hint, + }); + final T? value; + final List> items; + final void Function(T?)? onChanged; + final Widget? hint; + @override + Widget build(BuildContext context) { + return DropdownButtonFormField( + hint: hint, + icon: SvgPicture.asset( + 'assets/icons/arrow_down2.svg', + width: 12, + height: 8, + ), + borderRadius: BorderRadius.circular(20), + dropdownColor: appTheme.lightGray0, + decoration: InputDecoration( + border: OutlineInputBorder( + borderRadius: const BorderRadius.all(Radius.circular(20)), + borderSide: BorderSide.none, + ), + fillColor: appTheme.lightGray0, + filled: true, + ), + value: value, + items: items, + onChanged: onChanged, + ); + } +} diff --git a/lib/core/widgets/custom_text_form_field.dart b/lib/core/widgets/custom_text_form_field.dart index 2ce5a525..17e961a2 100644 --- a/lib/core/widgets/custom_text_form_field.dart +++ b/lib/core/widgets/custom_text_form_field.dart @@ -13,7 +13,7 @@ class CustomTextFormField extends StatelessWidget { this.obscureText = false, this.textInputAction, this.textInputType, - this.maxLines, + this.maxLines = 1, this.hintText, this.hintStyle, this.prefix, @@ -35,6 +35,8 @@ class CustomTextFormField extends StatelessWidget { this.onEditingComplete, this.minLines = 1, this.maxLength, + this.expands = false, + this.textAlignVertical, super.key, }); @@ -49,7 +51,7 @@ class CustomTextFormField extends StatelessWidget { final TextInputAction? textInputAction; final TextInputType? textInputType; final int? maxLines; - final int minLines; + final int? minLines; final String? hintText; final TextStyle? hintStyle; final Widget? prefix; @@ -69,12 +71,15 @@ class CustomTextFormField extends StatelessWidget { final void Function(String?)? onSaved; final void Function(String)? onChanged; final int? maxLength; - + final bool expands; + final TextAlignVertical? textAlignVertical; @override Widget build(BuildContext context) { return Align( alignment: alignment ?? Alignment.center, child: TextFormField( + textAlignVertical: textAlignVertical, + expands: expands, minLines: minLines, maxLength: maxLength, onChanged: onChanged, @@ -88,7 +93,7 @@ class CustomTextFormField extends StatelessWidget { ), obscureText: obscureText!, textInputAction: textInputAction, - maxLines: maxLines ?? 1, + maxLines: maxLines, initialValue: initialValue, cursorColor: appTheme.blueA400, decoration: InputDecoration( diff --git a/lib/features/diets/presentation/widgets/main_background_bouble.dart b/lib/core/widgets/main_background_bouble.dart similarity index 100% rename from lib/features/diets/presentation/widgets/main_background_bouble.dart rename to lib/core/widgets/main_background_bouble.dart diff --git a/lib/features/consultant/become_consultant/models/consultant_profile_model.g.dart b/lib/features/consultant/become_consultant/models/consultant_profile_model.g.dart index e611c201..e66c2cee 100644 --- a/lib/features/consultant/become_consultant/models/consultant_profile_model.g.dart +++ b/lib/features/consultant/become_consultant/models/consultant_profile_model.g.dart @@ -23,21 +23,14 @@ _$ConsultantProfileModelImpl _$$ConsultantProfileModelImplFromJson( ); Map _$$ConsultantProfileModelImplToJson( - _$ConsultantProfileModelImpl instance) { - final val = {}; - - void writeNotNull(String key, dynamic value) { - if (value != null) { - val[key] = value; - } - } - - writeNotNull('has_medical_education', instance.hasMedicalEducation); - writeNotNull('social_links', instance.socialLinks); - writeNotNull('cert_photos', instance.photos); - writeNotNull('completed_courses', instance.certificates); - return val; -} + _$ConsultantProfileModelImpl instance) => + { + if (instance.hasMedicalEducation case final value?) + 'has_medical_education': value, + if (instance.socialLinks case final value?) 'social_links': value, + if (instance.photos case final value?) 'cert_photos': value, + if (instance.certificates case final value?) 'completed_courses': value, + }; _$SocialLinksModelImpl _$$SocialLinksModelImplFromJson( Map json) => @@ -50,22 +43,15 @@ _$SocialLinksModelImpl _$$SocialLinksModelImplFromJson( ); Map _$$SocialLinksModelImplToJson( - _$SocialLinksModelImpl instance) { - final val = {}; - - void writeNotNull(String key, dynamic value) { - if (value != null) { - val[key] = value; - } - } - - writeNotNull('vk_link', instance.vkLink); - writeNotNull('tg_link', instance.tgLink); - writeNotNull('fb_link', instance.fbLink); - writeNotNull('insta_link', instance.instaLink); - writeNotNull('personal_site_link', instance.personalSiteLink); - return val; -} + _$SocialLinksModelImpl instance) => + { + if (instance.vkLink case final value?) 'vk_link': value, + if (instance.tgLink case final value?) 'tg_link': value, + if (instance.fbLink case final value?) 'fb_link': value, + if (instance.instaLink case final value?) 'insta_link': value, + if (instance.personalSiteLink case final value?) + 'personal_site_link': value, + }; _$CertificatesModelImpl _$$CertificatesModelImplFromJson( Map json) => diff --git a/lib/features/create_diet/models/create_diet_model.dart b/lib/features/create_diet/models/create_diet_model.dart index 6517e784..35635552 100644 --- a/lib/features/create_diet/models/create_diet_model.dart +++ b/lib/features/create_diet/models/create_diet_model.dart @@ -1,7 +1,9 @@ import 'dart:io'; +import 'package:dio/dio.dart'; import 'package:eatvio_app/core/image_compressing/image_compress_utility.dart'; import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; +import 'package:flutter_image_compress/flutter_image_compress.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; part 'create_diet_model.freezed.dart'; @@ -15,8 +17,8 @@ class CreateDietModel with _$CreateDietModel{ String? details, String? state, int? duration, - List? type, - File? image, + required List type, + XFile? image, List>>? dailySchedule, }) = _CreateDietModel; @@ -26,7 +28,7 @@ class CreateDietModel with _$CreateDietModel{ 'state': state, 'type': type, 'details': details, - 'image': image != null ? await ImageCompressUtility.compressFile(image!) : null, + 'image': image != null ? await MultipartFile.fromFile((await ImageCompressUtility.compressFile(File(image!.path))).path, filename: image!.name) : null, }; Map toDailyScheduleCreationJson() => { diff --git a/lib/features/create_diet/models/create_diet_model.freezed.dart b/lib/features/create_diet/models/create_diet_model.freezed.dart index bc3eccbb..05001e64 100644 --- a/lib/features/create_diet/models/create_diet_model.freezed.dart +++ b/lib/features/create_diet/models/create_diet_model.freezed.dart @@ -20,8 +20,8 @@ mixin _$CreateDietModel { String? get details => throw _privateConstructorUsedError; String? get state => throw _privateConstructorUsedError; int? get duration => throw _privateConstructorUsedError; - List? get type => throw _privateConstructorUsedError; - File? get image => throw _privateConstructorUsedError; + List get type => throw _privateConstructorUsedError; + XFile? get image => throw _privateConstructorUsedError; List>>? get dailySchedule => throw _privateConstructorUsedError; @@ -43,8 +43,8 @@ abstract class $CreateDietModelCopyWith<$Res> { String? details, String? state, int? duration, - List? type, - File? image, + List type, + XFile? image, List>>? dailySchedule}); } @@ -67,7 +67,7 @@ class _$CreateDietModelCopyWithImpl<$Res, $Val extends CreateDietModel> Object? details = freezed, Object? state = freezed, Object? duration = freezed, - Object? type = freezed, + Object? type = null, Object? image = freezed, Object? dailySchedule = freezed, }) { @@ -88,14 +88,14 @@ class _$CreateDietModelCopyWithImpl<$Res, $Val extends CreateDietModel> ? _value.duration : duration // ignore: cast_nullable_to_non_nullable as int?, - type: freezed == type + type: null == type ? _value.type : type // ignore: cast_nullable_to_non_nullable - as List?, + as List, image: freezed == image ? _value.image : image // ignore: cast_nullable_to_non_nullable - as File?, + as XFile?, dailySchedule: freezed == dailySchedule ? _value.dailySchedule : dailySchedule // ignore: cast_nullable_to_non_nullable @@ -117,8 +117,8 @@ abstract class _$$CreateDietModelImplCopyWith<$Res> String? details, String? state, int? duration, - List? type, - File? image, + List type, + XFile? image, List>>? dailySchedule}); } @@ -139,7 +139,7 @@ class __$$CreateDietModelImplCopyWithImpl<$Res> Object? details = freezed, Object? state = freezed, Object? duration = freezed, - Object? type = freezed, + Object? type = null, Object? image = freezed, Object? dailySchedule = freezed, }) { @@ -160,14 +160,14 @@ class __$$CreateDietModelImplCopyWithImpl<$Res> ? _value.duration : duration // ignore: cast_nullable_to_non_nullable as int?, - type: freezed == type + type: null == type ? _value._type : type // ignore: cast_nullable_to_non_nullable - as List?, + as List, image: freezed == image ? _value.image : image // ignore: cast_nullable_to_non_nullable - as File?, + as XFile?, dailySchedule: freezed == dailySchedule ? _value._dailySchedule : dailySchedule // ignore: cast_nullable_to_non_nullable @@ -184,7 +184,7 @@ class _$CreateDietModelImpl extends _CreateDietModel { this.details, this.state, this.duration, - final List? type, + required final List type, this.image, final List>>? dailySchedule}) : _type = type, @@ -199,18 +199,16 @@ class _$CreateDietModelImpl extends _CreateDietModel { final String? state; @override final int? duration; - final List? _type; + final List _type; @override - List? get type { - final value = _type; - if (value == null) return null; + List get type { if (_type is EqualUnmodifiableListView) return _type; // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(value); + return EqualUnmodifiableListView(_type); } @override - final File? image; + final XFile? image; final List>>? _dailySchedule; @override List>>? get dailySchedule { @@ -269,8 +267,8 @@ abstract class _CreateDietModel extends CreateDietModel { final String? details, final String? state, final int? duration, - final List? type, - final File? image, + required final List type, + final XFile? image, final List>>? dailySchedule}) = _$CreateDietModelImpl; const _CreateDietModel._() : super._(); @@ -284,9 +282,9 @@ abstract class _CreateDietModel extends CreateDietModel { @override int? get duration; @override - List? get type; + List get type; @override - File? get image; + XFile? get image; @override List>>? get dailySchedule; diff --git a/lib/features/create_diet/presentation/create_diet_screen.dart b/lib/features/create_diet/presentation/create_diet_screen.dart index 81db4990..1b882176 100644 --- a/lib/features/create_diet/presentation/create_diet_screen.dart +++ b/lib/features/create_diet/presentation/create_diet_screen.dart @@ -1,4 +1,20 @@ -import 'package:flutter/widgets.dart'; +import 'package:eatvio_app/core/locator_service.dart'; +import 'package:eatvio_app/core/theme/custom_text_style.dart'; +import 'package:eatvio_app/core/theme/theme_helper.dart'; +import 'package:eatvio_app/core/utils/localization_utils.dart'; +import 'package:eatvio_app/core/widgets/custom_text_form_field.dart'; +import 'package:eatvio_app/core/widgets/main_background_bouble.dart'; +import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_cubit.dart'; +import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart'; +import 'package:eatvio_app/features/create_diet/presentation/widgets/day_widget.dart'; +import 'package:eatvio_app/features/create_diet/presentation/widgets/duration_drop_down_widget.dart'; +import 'package:eatvio_app/features/create_diet/presentation/widgets/image_picker_widget.dart'; +import 'package:eatvio_app/features/create_diet/presentation/widgets/status_drop_down_widget.dart'; +import 'package:eatvio_app/features/create_diet/presentation/widgets/type_choice_widget.dart'; +import 'package:eatvio_app/generated/l10n.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/flutter_svg.dart'; class CreateDietScreen extends StatelessWidget { static const name = 'createDietScreen'; @@ -7,6 +23,97 @@ class CreateDietScreen extends StatelessWidget { @override Widget build(BuildContext context) { - return const Placeholder(); + return BlocProvider( + create: (context) => sl(), + child: const CreateDietScreenContent(), + ); } -} \ No newline at end of file +} + +class CreateDietScreenContent extends StatelessWidget { + const CreateDietScreenContent({super.key}); + + @override + Widget build(BuildContext context) { + final s = S.of(context); + return Scaffold( + backgroundColor: appTheme.gray100, + appBar: AppBar( + centerTitle: true, + title: Text( + s.create_diet, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + softWrap: true, + style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black), + ), + ), + body: SingleChildScrollView( + child: Column( + children: [ + SizedBox(height: 8), + MainBackgroundBouble( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + children: [ + SizedBox(height: 16), + CustomTextFormField( + hintText: s.enter_diet_name, + onChanged: (value) { + context.read().setName(value); + }, + ), + SizedBox(height: 12), + SizedBox( + height: 132, + child: CustomTextFormField( + textAlignVertical: TextAlignVertical.top, + maxLines: null, + minLines: null, + expands: true, + hintText: s.enter_diet_description, + onChanged: (value) { + context.read().setDetails(value); + }, + ), + ), + SizedBox(height: 12), + DurationDropDownWidget(), + SizedBox(height: 12), + StatusDropDownWidget(), + SizedBox(height: 16), + TypeChoiceWidget(), + SizedBox(height: 16), + ImagePickerWidget(), + SizedBox(height: 16), + ], + ), + ), + SizedBox(height: 16), + BlocBuilder( + builder: (context, state) { + return MainBackgroundBouble( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: Center( + child: Text( + s.diet_plan + ' (${state.dietData.duration ?? 0} ' + getDayForm(state.dietData.duration ?? 0, s) + ')', + style: TextStyles.headingXLSemibold.copyWith( + color: appTheme.black, + ), + ), + ), + ), + ); + }, + ), + SizedBox(height: 8), + DayWidget( + index: 0, + ), + ], + ), + ), + ); + } +} diff --git a/lib/features/create_diet/presentation/cubit/create_diet_cubit.dart b/lib/features/create_diet/presentation/cubit/create_diet_cubit.dart index bc093d41..2e27e729 100644 --- a/lib/features/create_diet/presentation/cubit/create_diet_cubit.dart +++ b/lib/features/create_diet/presentation/cubit/create_diet_cubit.dart @@ -1,11 +1,14 @@ -import 'dart:io'; - +import 'package:eatvio_app/core/const.dart'; import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart'; +import 'package:eatvio_app/features/create_diet/repositories/create_diet_repository.dart'; import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_image_compress/flutter_image_compress.dart'; class CreateDietCubit extends Cubit { - CreateDietCubit() : super(CreateDietState.initial()); + final CreateDietRepository createDietRepository; + static const _dietStateValues = ['active', 'draft', 'personal']; + CreateDietCubit({required this.createDietRepository}) : super(CreateDietState.initial()); void setDetails(String text) { emit(state.copyWith(dietData: state.dietData.copyWith(details: text))); @@ -15,11 +18,18 @@ class CreateDietCubit extends Cubit { emit(state.copyWith(dietData: state.dietData.copyWith(name: name))); } - void setDuration(int duration) { - emit(state.copyWith(dietData: state.dietData.copyWith(duration: duration))); + void setDuration(int index) { + emit( + state.copyWith( + durationIndex: index, + dietData: state.dietData.copyWith( + duration: durationValues[index], + ), + ), + ); } - void setImage(File image) { + void setImage(XFile? image) { emit(state.copyWith(dietData: state.dietData.copyWith(image: image))); } @@ -27,11 +37,11 @@ class CreateDietCubit extends Cubit { emit(state.copyWith(dietData: state.dietData.copyWith(dailySchedule: dailySchedule))); } - void setDietState(String dietState) { - emit(state.copyWith(dietData: state.dietData.copyWith(state: dietState))); + void setDietState(int index) { + emit(state.copyWith(dietStateIndex: index, dietData: state.dietData.copyWith(state: _dietStateValues[index]))); } - void setDietType(List type) { + void setDietType(List type) { emit(state.copyWith(dietData: state.dietData.copyWith(type: type))); } } diff --git a/lib/features/create_diet/presentation/cubit/create_diet_state.dart b/lib/features/create_diet/presentation/cubit/create_diet_state.dart index 61ac70e9..8fdcaee6 100644 --- a/lib/features/create_diet/presentation/cubit/create_diet_state.dart +++ b/lib/features/create_diet/presentation/cubit/create_diet_state.dart @@ -9,7 +9,9 @@ class CreateDietState with _$CreateDietState { required bool isLoading, required String? errorMessage, required CreateDietModel dietData, + int? durationIndex, + int? dietStateIndex, }) = _CreateDietState; - factory CreateDietState.initial() => CreateDietState(isLoading: false, errorMessage: null, dietData: CreateDietModel()); + factory CreateDietState.initial() => CreateDietState(isLoading: false, errorMessage: null, dietData: CreateDietModel(type: [false, false, false, false])); } diff --git a/lib/features/create_diet/presentation/cubit/create_diet_state.freezed.dart b/lib/features/create_diet/presentation/cubit/create_diet_state.freezed.dart index 0a540986..8f6182d8 100644 --- a/lib/features/create_diet/presentation/cubit/create_diet_state.freezed.dart +++ b/lib/features/create_diet/presentation/cubit/create_diet_state.freezed.dart @@ -19,6 +19,8 @@ mixin _$CreateDietState { bool get isLoading => throw _privateConstructorUsedError; String? get errorMessage => throw _privateConstructorUsedError; CreateDietModel get dietData => throw _privateConstructorUsedError; + int? get durationIndex => throw _privateConstructorUsedError; + int? get dietStateIndex => throw _privateConstructorUsedError; /// Create a copy of CreateDietState /// with the given fields replaced by the non-null parameter values. @@ -33,7 +35,12 @@ abstract class $CreateDietStateCopyWith<$Res> { CreateDietState value, $Res Function(CreateDietState) then) = _$CreateDietStateCopyWithImpl<$Res, CreateDietState>; @useResult - $Res call({bool isLoading, String? errorMessage, CreateDietModel dietData}); + $Res call( + {bool isLoading, + String? errorMessage, + CreateDietModel dietData, + int? durationIndex, + int? dietStateIndex}); $CreateDietModelCopyWith<$Res> get dietData; } @@ -56,6 +63,8 @@ class _$CreateDietStateCopyWithImpl<$Res, $Val extends CreateDietState> Object? isLoading = null, Object? errorMessage = freezed, Object? dietData = null, + Object? durationIndex = freezed, + Object? dietStateIndex = freezed, }) { return _then(_value.copyWith( isLoading: null == isLoading @@ -70,6 +79,14 @@ class _$CreateDietStateCopyWithImpl<$Res, $Val extends CreateDietState> ? _value.dietData : dietData // ignore: cast_nullable_to_non_nullable as CreateDietModel, + durationIndex: freezed == durationIndex + ? _value.durationIndex + : durationIndex // ignore: cast_nullable_to_non_nullable + as int?, + dietStateIndex: freezed == dietStateIndex + ? _value.dietStateIndex + : dietStateIndex // ignore: cast_nullable_to_non_nullable + as int?, ) as $Val); } @@ -92,7 +109,12 @@ abstract class _$$CreateDietStateImplCopyWith<$Res> __$$CreateDietStateImplCopyWithImpl<$Res>; @override @useResult - $Res call({bool isLoading, String? errorMessage, CreateDietModel dietData}); + $Res call( + {bool isLoading, + String? errorMessage, + CreateDietModel dietData, + int? durationIndex, + int? dietStateIndex}); @override $CreateDietModelCopyWith<$Res> get dietData; @@ -114,6 +136,8 @@ class __$$CreateDietStateImplCopyWithImpl<$Res> Object? isLoading = null, Object? errorMessage = freezed, Object? dietData = null, + Object? durationIndex = freezed, + Object? dietStateIndex = freezed, }) { return _then(_$CreateDietStateImpl( isLoading: null == isLoading @@ -128,6 +152,14 @@ class __$$CreateDietStateImplCopyWithImpl<$Res> ? _value.dietData : dietData // ignore: cast_nullable_to_non_nullable as CreateDietModel, + durationIndex: freezed == durationIndex + ? _value.durationIndex + : durationIndex // ignore: cast_nullable_to_non_nullable + as int?, + dietStateIndex: freezed == dietStateIndex + ? _value.dietStateIndex + : dietStateIndex // ignore: cast_nullable_to_non_nullable + as int?, )); } } @@ -138,7 +170,9 @@ class _$CreateDietStateImpl implements _CreateDietState { const _$CreateDietStateImpl( {required this.isLoading, required this.errorMessage, - required this.dietData}); + required this.dietData, + this.durationIndex, + this.dietStateIndex}); @override final bool isLoading; @@ -146,10 +180,14 @@ class _$CreateDietStateImpl implements _CreateDietState { final String? errorMessage; @override final CreateDietModel dietData; + @override + final int? durationIndex; + @override + final int? dietStateIndex; @override String toString() { - return 'CreateDietState(isLoading: $isLoading, errorMessage: $errorMessage, dietData: $dietData)'; + return 'CreateDietState(isLoading: $isLoading, errorMessage: $errorMessage, dietData: $dietData, durationIndex: $durationIndex, dietStateIndex: $dietStateIndex)'; } @override @@ -162,12 +200,16 @@ class _$CreateDietStateImpl implements _CreateDietState { (identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage) && (identical(other.dietData, dietData) || - other.dietData == dietData)); + other.dietData == dietData) && + (identical(other.durationIndex, durationIndex) || + other.durationIndex == durationIndex) && + (identical(other.dietStateIndex, dietStateIndex) || + other.dietStateIndex == dietStateIndex)); } @override - int get hashCode => - Object.hash(runtimeType, isLoading, errorMessage, dietData); + int get hashCode => Object.hash(runtimeType, isLoading, errorMessage, + dietData, durationIndex, dietStateIndex); /// Create a copy of CreateDietState /// with the given fields replaced by the non-null parameter values. @@ -183,7 +225,9 @@ abstract class _CreateDietState implements CreateDietState { const factory _CreateDietState( {required final bool isLoading, required final String? errorMessage, - required final CreateDietModel dietData}) = _$CreateDietStateImpl; + required final CreateDietModel dietData, + final int? durationIndex, + final int? dietStateIndex}) = _$CreateDietStateImpl; @override bool get isLoading; @@ -191,6 +235,10 @@ abstract class _CreateDietState implements CreateDietState { String? get errorMessage; @override CreateDietModel get dietData; + @override + int? get durationIndex; + @override + int? get dietStateIndex; /// Create a copy of CreateDietState /// with the given fields replaced by the non-null parameter values. diff --git a/lib/features/create_diet/presentation/widgets/day_widget.dart b/lib/features/create_diet/presentation/widgets/day_widget.dart new file mode 100644 index 00000000..b249f81f --- /dev/null +++ b/lib/features/create_diet/presentation/widgets/day_widget.dart @@ -0,0 +1,178 @@ +import 'package:eatvio_app/core/theme/custom_text_style.dart'; +import 'package:eatvio_app/core/theme/theme_helper.dart'; +import 'package:eatvio_app/core/widgets/custom_divider.dart'; +import 'package:eatvio_app/core/widgets/custom_outlined_button.dart'; +import 'package:eatvio_app/core/widgets/main_background_bouble.dart'; +import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_cubit.dart'; +import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart'; +import 'package:eatvio_app/features/feed/presentation/widgets/choice_chip_widget.dart'; +import 'package:eatvio_app/generated/l10n.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/svg.dart'; + +class DayWidget extends StatefulWidget { + const DayWidget({ + super.key, + required this.index, + }); + final int index; + @override + State createState() => _DayWidgetState(); +} + +class _DayWidgetState extends State { + int _selectedDayIndex = 0; + final chipsLabelList = ['1', '2', '3', '4', '5']; + @override + Widget build(BuildContext context) { + final s = S.of(context); + return BlocBuilder( + builder: (context, state) { + return MainBackgroundBouble( + child: Padding( + padding: EdgeInsets.only( + left: 16, + right: 16, + top: 16, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Text( + s.day + ' ${widget.index + 1}', + style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black), + ), + Spacer(), + SvgPicture.asset( + 'assets/icons/copy2.svg', + width: 20, + height: 24, + colorFilter: ColorFilter.mode(appTheme.black, BlendMode.srcIn), + ), + ], + ), + SizedBox( + height: 12, + ), + CustomDivider(), + SizedBox( + height: 12, + ), + Text( + s.meal, + style: TextStyles.textMMedium.copyWith(color: appTheme.black), + ), + SizedBox(height: 16), + Row( + children: [ + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 6), + fontSize: TextStyles.textMMedium.fontSize, + fontWeight: TextStyles.textMMedium.fontWeight, + index: 0, + selectedChipIndex: _selectedDayIndex, + onSelected: (selectedValue) { + setState(() { + _selectedDayIndex = 0; + }); + }, + ), + Spacer(), + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 6), + fontSize: TextStyles.textMMedium.fontSize, + fontWeight: TextStyles.textMMedium.fontWeight, + index: 1, + selectedChipIndex: _selectedDayIndex, + onSelected: (selectedValue) { + setState(() { + _selectedDayIndex = 1; + }); + }, + ), + Spacer(), + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 6), + fontSize: TextStyles.textMMedium.fontSize, + fontWeight: TextStyles.textMMedium.fontWeight, + index: 2, + selectedChipIndex: _selectedDayIndex, + onSelected: (selectedValue) { + setState(() { + _selectedDayIndex = 2; + }); + }, + ), + Spacer(), + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 6), + fontSize: TextStyles.textMMedium.fontSize, + fontWeight: TextStyles.textMMedium.fontWeight, + index: 3, + selectedChipIndex: _selectedDayIndex, + onSelected: (selectedValue) { + setState(() { + _selectedDayIndex = 3; + }); + }, + ), + Spacer(), + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 6), + fontSize: TextStyles.textMMedium.fontSize, + fontWeight: TextStyles.textMMedium.fontWeight, + index: 4, + selectedChipIndex: _selectedDayIndex, + onSelected: (selectedValue) { + setState(() { + _selectedDayIndex = 4; + }); + }, + ), + ], + ), + SizedBox(height: 16), + Row( + children: [ + Container( + padding: EdgeInsets.symmetric(horizontal: 12, vertical: 14), + decoration: BoxDecoration(color: appTheme.gray50, borderRadius: BorderRadius.all(Radius.circular(12))), + child: SvgPicture.asset( + 'assets/icons/paste2.svg', + width: 28, + height: 24, + ), + ), + SizedBox(width: 8), + Expanded( + child: CustomOutlinedButton( + text: s.add, + height: 52, + buttonTextStyle: TextStyles.textMSemibold.copyWith( + color: appTheme.whiteA700, + ), + buttonStyle: ButtonStyle( + side: WidgetStatePropertyAll(BorderSide.none), + backgroundColor: WidgetStatePropertyAll(appTheme.blueA400), + ), + ), + ), + ], + ), + SizedBox(height: 20), + ], + ), + ), + ); + }, + ); + } +} diff --git a/lib/features/create_diet/presentation/widgets/duration_drop_down_widget.dart b/lib/features/create_diet/presentation/widgets/duration_drop_down_widget.dart new file mode 100644 index 00000000..c4b1ed31 --- /dev/null +++ b/lib/features/create_diet/presentation/widgets/duration_drop_down_widget.dart @@ -0,0 +1,65 @@ +import 'package:eatvio_app/core/const.dart'; +import 'package:eatvio_app/core/theme/custom_text_style.dart'; +import 'package:eatvio_app/core/theme/theme_helper.dart'; +import 'package:eatvio_app/core/utils/localization_utils.dart'; +import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_cubit.dart'; +import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart'; +import 'package:eatvio_app/core/widgets/custom_drop_down_button.dart'; +import 'package:eatvio_app/generated/l10n.dart'; +import 'package:flutter/material.dart'; +import 'package:collection/collection.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class DurationDropDownWidget extends StatefulWidget { + const DurationDropDownWidget({super.key}); + + @override + State createState() => _DurationDropDownWidgetState(); +} + +class _DurationDropDownWidgetState extends State { + final List durationDropDownTitles = []; + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + final s = S.of(context); + if (durationDropDownTitles.isEmpty) { + durationValues.forEach((element) { + durationDropDownTitles.add('$element ${getDayForm(element, s)}'); + }); + } + } + + @override + Widget build(BuildContext context) { + final s = S.of(context); + return BlocBuilder( + builder: (context, state) { + return CustomDropDownButton( + hint: Text( + s.choose_diet_duration, + style: TextStyles.textMMedium.copyWith(color: appTheme.black), + ), + onChanged: (value) { + if (value != null) { + context.read().setDuration(durationDropDownTitles.indexOf(value)); + } + }, + items: durationDropDownTitles + .mapIndexed( + (index, value) => DropdownMenuItem( + child: Text( + durationDropDownTitles[index], + style: TextStyles.textMMedium.copyWith(color: appTheme.black), + ), + value: durationDropDownTitles[index], + ), + ) + .toList(), + value: state.durationIndex == null ? null : durationDropDownTitles[state.durationIndex ?? 0], + ); + }, + ); + } +} diff --git a/lib/features/create_diet/presentation/widgets/image_picker_widget.dart b/lib/features/create_diet/presentation/widgets/image_picker_widget.dart new file mode 100644 index 00000000..e6bb9a82 --- /dev/null +++ b/lib/features/create_diet/presentation/widgets/image_picker_widget.dart @@ -0,0 +1,122 @@ +import 'dart:io'; + +import 'package:dotted_border/dotted_border.dart'; +import 'package:eatvio_app/core/theme/custom_text_style.dart'; +import 'package:eatvio_app/core/theme/theme_helper.dart'; +import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_cubit.dart'; +import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart'; +import 'package:eatvio_app/generated/l10n.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:image_picker/image_picker.dart'; + +class ImagePickerWidget extends StatefulWidget { + const ImagePickerWidget({super.key}); + + @override + State createState() => _ImagePickerWidgetState(); +} + +class _ImagePickerWidgetState extends State { + void _showImagePickerOptions(S s, CreateDietCubit cubit) { + showCupertinoModalPopup( + context: context, + builder: (context) => CupertinoActionSheet( + actions: [ + CupertinoActionSheetAction( + onPressed: () async { + final picker = ImagePicker(); + final image = await picker.pickImage(source: ImageSource.camera); + cubit.setImage(image); + Navigator.of(context).pop(); + }, + child: Row( + children: [ + Icon(Icons.photo_camera), + SizedBox(width: 8), + Text(s.photo), + ], + ), + ), + CupertinoActionSheetAction( + onPressed: () async { + final picker = ImagePicker(); + final image = await picker.pickImage(source: ImageSource.gallery); + cubit.setImage(image); + Navigator.of(context).pop(); + }, + child: Row( + children: [ + Icon(Icons.photo), + SizedBox(width: 8), + Text(s.gallery), + ], + ), + ), + ], + cancelButton: CupertinoActionSheetAction( + onPressed: () => Navigator.of(context).pop(), + isDestructiveAction: true, + child: const Text('Отмена'), + ), + ), + ); + } + + @override + Widget build(BuildContext context) { + final s = S.of(context); + return BlocBuilder( + builder: (context, state) { + return GestureDetector( + onTap: () { + _showImagePickerOptions(s, context.read()); + }, + child: Container( + height: 240, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: state.dietData.image != null ? DecorationImage(fit: BoxFit.cover, image: FileImage(File(state.dietData.image?.path ?? ''))) : null, + color: appTheme.gray50, + ), + width: MediaQuery.sizeOf(context).width, + padding: state.dietData.image != null ? null : EdgeInsets.all(8), + child: state.dietData.image != null + ? null + : Stack( + children: [ + DottedBorder( + stackFit: StackFit.expand, + dashPattern: [14, 14], + color: appTheme.dottedBorder, + borderType: BorderType.RRect, + radius: Radius.circular(12), + child: SizedBox.expand(), + ), + Center( + child: Column( + children: [ + SizedBox( + height: 48, + ), + SvgPicture.asset('assets/icons/eatvio_logo.svg'), + SizedBox( + height: 24, + ), + Text( + s.add_cover, + style: TextStyles.textMMedium.copyWith(color: appTheme.gray), + ), + ], + ), + ), + ], + ), + ), + ); + }, + ); + } +} diff --git a/lib/features/create_diet/presentation/widgets/status_drop_down_widget.dart b/lib/features/create_diet/presentation/widgets/status_drop_down_widget.dart new file mode 100644 index 00000000..999bda84 --- /dev/null +++ b/lib/features/create_diet/presentation/widgets/status_drop_down_widget.dart @@ -0,0 +1,63 @@ +import 'package:eatvio_app/core/theme/custom_text_style.dart'; +import 'package:eatvio_app/core/theme/theme_helper.dart'; +import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_cubit.dart'; +import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart'; +import 'package:eatvio_app/core/widgets/custom_drop_down_button.dart'; +import 'package:eatvio_app/generated/l10n.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:collection/collection.dart'; + +class StatusDropDownWidget extends StatefulWidget { + const StatusDropDownWidget({super.key}); + + @override + State createState() => _StatusDropDownWidgetState(); +} + +class _StatusDropDownWidgetState extends State { + final List dietStateTitles = []; + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + final s = S.of(context); + if (dietStateTitles.isEmpty) { + dietStateTitles.add(s.active_diet_state); + dietStateTitles.add(s.inactive_diet_state); + dietStateTitles.add(s.personal_diet_state); + } + } + + @override + Widget build(BuildContext context) { + final s = S.of(context); + return BlocBuilder( + builder: (context, state) { + return CustomDropDownButton( + hint: Text( + s.diet_state, + style: TextStyles.textMMedium.copyWith(color: appTheme.black), + ), + onChanged: (value) { + if (value != null) { + context.read().setDietState(dietStateTitles.indexOf(value)); + } + }, + items: dietStateTitles + .mapIndexed( + (index, value) => DropdownMenuItem( + child: Text( + dietStateTitles[index], + style: TextStyles.textMMedium.copyWith(color: appTheme.black), + ), + value: dietStateTitles[index], + ), + ) + .toList(), + value: state.dietStateIndex == null ? null : dietStateTitles[state.dietStateIndex ?? 0], + ); + }, + ); + } +} diff --git a/lib/features/create_diet/presentation/widgets/type_choice_widget.dart b/lib/features/create_diet/presentation/widgets/type_choice_widget.dart new file mode 100644 index 00000000..85b785e4 --- /dev/null +++ b/lib/features/create_diet/presentation/widgets/type_choice_widget.dart @@ -0,0 +1,100 @@ +import 'package:eatvio_app/core/theme/custom_text_style.dart'; +import 'package:eatvio_app/core/theme/theme_helper.dart'; +import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_cubit.dart'; +import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart'; +import 'package:eatvio_app/generated/l10n.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/svg.dart'; + +class TypeChoiceWidget extends StatefulWidget { + TypeChoiceWidget({super.key}); + + @override + State createState() => _TypeChoiceWidgetState(); +} + +class _TypeChoiceWidgetState extends State { + final List<(String, String)> choiceContent = []; + @override + void didChangeDependencies() { + super.didChangeDependencies(); + final s = S.of(context); + if (choiceContent.isEmpty) { + choiceContent.add( + ( + 'assets/icons/meat2.svg', + s.meat, + ), + ); + choiceContent.add( + ( + 'assets/icons/broccoli.svg', + s.vegan, + ), + ); + choiceContent.add( + ( + 'assets/icons/bread.svg', + s.carb_type, + ), + ); + choiceContent.add( + ( + 'assets/icons/cocktail.svg', + s.light_type, + ), + ); + } + } + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + return Row( + children: [ + ...List.generate(4, (index) { + return Expanded( + child: GestureDetector( + onTap: () { + final dietTypes = [...state.dietData.type]; + dietTypes[index] = !dietTypes[index]; + context.read().setDietType(dietTypes); + }, + child: Container( + margin: EdgeInsets.only(right: index == 3 ? 0 : 4), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: state.dietData.type[index] ? appTheme.cardBackground : appTheme.whiteA700, + border: Border.all( + width: 1, + color: state.dietData.type[index] ? appTheme.blueA400 : appTheme.lightGray00, + ), + ), + height: 80, + child: Column( + children: [ + SizedBox(height: 16), + SvgPicture.asset( + choiceContent[index].$1, + height: 30, + ), + SizedBox(height: 8), + Text( + choiceContent[index].$2, + overflow: TextOverflow.clip, + style: TextStyles.textXSSemibold.copyWith(color: appTheme.black), + ), + ], + ), + ), + ), + ); + }), + ], + ); + }, + ); + } +} diff --git a/lib/features/create_diet/repositories/create_diet_repository.dart b/lib/features/create_diet/repositories/create_diet_repository.dart new file mode 100644 index 00000000..4400d1c8 --- /dev/null +++ b/lib/features/create_diet/repositories/create_diet_repository.dart @@ -0,0 +1,25 @@ +import 'package:eatvio_app/features/create_diet/services/create_diet_service.dart'; +import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; + +class CreateDietRepository { + final CreateDietService createDietService; + CreateDietRepository({required this.createDietService}); + + Future createDiet({ + required Map model, + }) { + return createDietService.createDiet( + model: model, + ); + } + + Future createDietDailySchedule({ + required int id, + required Map model, + }) { + return createDietService.createDietDailySchedule( + id: id, + model: model, + ); + } +} diff --git a/lib/features/create_diet/services/create_diet_service.dart b/lib/features/create_diet/services/create_diet_service.dart index 93ec038d..03ab2a78 100644 --- a/lib/features/create_diet/services/create_diet_service.dart +++ b/lib/features/create_diet/services/create_diet_service.dart @@ -1,12 +1,22 @@ import 'package:dio/dio.dart'; +import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; import 'package:retrofit/retrofit.dart'; part 'create_diet_service.g.dart'; @RestApi() abstract class CreateDietService { - factory CreateDietService(Dio dio, {String baseUrl}) = _CreateDietService; + @POST('/api/diets/create') + @MultiPart() + Future createDiet({ + @Body() required Map model, + }); + + @POST('/api/diets/create/{id}/daily_schedule') + Future createDietDailySchedule({ + @Path() required int id, + @Body() required Map model, + }); } - \ No newline at end of file diff --git a/lib/features/create_diet/services/create_diet_service.g.dart b/lib/features/create_diet/services/create_diet_service.g.dart index a706620d..41ed51e7 100644 --- a/lib/features/create_diet/services/create_diet_service.g.dart +++ b/lib/features/create_diet/services/create_diet_service.g.dart @@ -21,6 +21,70 @@ class _CreateDietService implements CreateDietService { final ParseErrorLogger? errorLogger; + @override + Future createDiet({required Map model}) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + final _data = {}; + _data.addAll(model); + final _options = _setStreamType(Options( + method: 'POST', + headers: _headers, + extra: _extra, + contentType: 'multipart/form-data', + ) + .compose( + _dio.options, + '/api/diets/create', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + ))); + final _result = await _dio.fetch>(_options); + late Diet _value; + try { + _value = Diet.fromJson(_result.data!); + } on Object catch (e, s) { + errorLogger?.logError(e, s, _options); + rethrow; + } + return _value; + } + + @override + Future createDietDailySchedule({ + required int id, + required Map model, + }) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + final _data = {}; + _data.addAll(model); + final _options = _setStreamType(Options( + method: 'POST', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/api/diets/create/${id}/daily_schedule', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + ))); + await _dio.fetch(_options); + } + RequestOptions _setStreamType(RequestOptions requestOptions) { if (T != dynamic && !(requestOptions.responseType == ResponseType.bytes || diff --git a/lib/features/diets/presentation/pages/about_diet_screen.dart b/lib/features/diets/presentation/pages/about_diet_screen.dart index a229618d..ebceabdb 100644 --- a/lib/features/diets/presentation/pages/about_diet_screen.dart +++ b/lib/features/diets/presentation/pages/about_diet_screen.dart @@ -13,7 +13,7 @@ import 'package:eatvio_app/features/diets/presentation/widgets/author_card.dart' import 'package:eatvio_app/features/diets/presentation/widgets/cpfc_container.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/expandable_text.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/info_bouble.dart'; -import 'package:eatvio_app/features/diets/presentation/widgets/main_background_bouble.dart'; +import 'package:eatvio_app/core/widgets/main_background_bouble.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/more_options.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/start_diet_bottom_sheet.dart'; import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; diff --git a/lib/features/diets/presentation/widgets/more_options.dart b/lib/features/diets/presentation/widgets/more_options.dart index 862405f2..283e752e 100644 --- a/lib/features/diets/presentation/widgets/more_options.dart +++ b/lib/features/diets/presentation/widgets/more_options.dart @@ -1,7 +1,7 @@ import 'package:eatvio_app/core/const.dart'; import 'package:eatvio_app/core/utils/toasts.dart'; import 'package:eatvio_app/core/widgets/custom_divider.dart'; -import 'package:eatvio_app/features/diets/presentation/widgets/main_background_bouble.dart'; +import 'package:eatvio_app/core/widgets/main_background_bouble.dart'; import 'package:eatvio_app/generated/l10n.dart'; import 'package:eatvio_app/core/theme/custom_text_style.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; diff --git a/lib/features/diets/presentation/widgets/type_badges.dart b/lib/features/diets/presentation/widgets/type_badges.dart index b1d21fc4..2cf526c8 100644 --- a/lib/features/diets/presentation/widgets/type_badges.dart +++ b/lib/features/diets/presentation/widgets/type_badges.dart @@ -1,4 +1,4 @@ -import 'package:eatvio_app/features/diets/presentation/widgets/main_background_bouble.dart'; +import 'package:eatvio_app/core/widgets/main_background_bouble.dart'; import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; import 'package:eatvio_app/generated/l10n.dart'; import 'package:eatvio_app/core/theme/custom_text_style.dart'; @@ -23,15 +23,15 @@ class _TypeBadgesState extends State { Widget build(BuildContext context) { final s = S.of(context); final List<(String, Widget)> badgeSource = []; - if (widget.type.alko == true) { + if (widget.type.light == true) { badgeSource.add( ( 'assets/icons/cocktail.svg', _InfoOverlayEntry( onClose: closeOverlay, assetPath: 'assets/icons/cocktail.svg', - title: s.alko_type, - description: s.alko_type_desc, + title: s.light_type, + description: s.light_type_desc, ) ), ); @@ -49,15 +49,15 @@ class _TypeBadgesState extends State { ), ); } - if (widget.type.corb == true) { + if (widget.type.carb == true) { badgeSource.add( ( 'assets/icons/bread.svg', _InfoOverlayEntry( onClose: closeOverlay, assetPath: 'assets/icons/bread.svg', - title: s.corb_type, - description: s.corb_type_desc, + title: s.carb_type, + description: s.carb_type_desc, ) ), ); diff --git a/lib/features/feed/models/diets_pagination_model.dart b/lib/features/feed/models/diets_pagination_model.dart index 6fe4f677..7c59ec84 100644 --- a/lib/features/feed/models/diets_pagination_model.dart +++ b/lib/features/feed/models/diets_pagination_model.dart @@ -77,9 +77,9 @@ final portionValues = EnumValues({"grams": Portion.GRAMS, "milliliters": Portion @freezed class DietType with _$DietType { const factory DietType({ - @JsonKey(name: "alko") bool? alko, + @JsonKey(name: "light") bool? light, @JsonKey(name: "veg") bool? veg, - @JsonKey(name: "corb") bool? corb, + @JsonKey(name: "carb") bool? carb, @JsonKey(name: "meat") bool? meat, }) = _DietType; diff --git a/lib/features/feed/models/diets_pagination_model.freezed.dart b/lib/features/feed/models/diets_pagination_model.freezed.dart index 38789091..a209d2cc 100644 --- a/lib/features/feed/models/diets_pagination_model.freezed.dart +++ b/lib/features/feed/models/diets_pagination_model.freezed.dart @@ -1259,12 +1259,12 @@ DietType _$DietTypeFromJson(Map json) { /// @nodoc mixin _$DietType { - @JsonKey(name: "alko") - bool? get alko => throw _privateConstructorUsedError; + @JsonKey(name: "light") + bool? get light => throw _privateConstructorUsedError; @JsonKey(name: "veg") bool? get veg => throw _privateConstructorUsedError; - @JsonKey(name: "corb") - bool? get corb => throw _privateConstructorUsedError; + @JsonKey(name: "carb") + bool? get carb => throw _privateConstructorUsedError; @JsonKey(name: "meat") bool? get meat => throw _privateConstructorUsedError; @@ -1284,9 +1284,9 @@ abstract class $DietTypeCopyWith<$Res> { _$DietTypeCopyWithImpl<$Res, DietType>; @useResult $Res call( - {@JsonKey(name: "alko") bool? alko, + {@JsonKey(name: "light") bool? light, @JsonKey(name: "veg") bool? veg, - @JsonKey(name: "corb") bool? corb, + @JsonKey(name: "carb") bool? carb, @JsonKey(name: "meat") bool? meat}); } @@ -1305,23 +1305,23 @@ class _$DietTypeCopyWithImpl<$Res, $Val extends DietType> @pragma('vm:prefer-inline') @override $Res call({ - Object? alko = freezed, + Object? light = freezed, Object? veg = freezed, - Object? corb = freezed, + Object? carb = freezed, Object? meat = freezed, }) { return _then(_value.copyWith( - alko: freezed == alko - ? _value.alko - : alko // ignore: cast_nullable_to_non_nullable + light: freezed == light + ? _value.light + : light // ignore: cast_nullable_to_non_nullable as bool?, veg: freezed == veg ? _value.veg : veg // ignore: cast_nullable_to_non_nullable as bool?, - corb: freezed == corb - ? _value.corb - : corb // ignore: cast_nullable_to_non_nullable + carb: freezed == carb + ? _value.carb + : carb // ignore: cast_nullable_to_non_nullable as bool?, meat: freezed == meat ? _value.meat @@ -1340,9 +1340,9 @@ abstract class _$$DietTypeImplCopyWith<$Res> @override @useResult $Res call( - {@JsonKey(name: "alko") bool? alko, + {@JsonKey(name: "light") bool? light, @JsonKey(name: "veg") bool? veg, - @JsonKey(name: "corb") bool? corb, + @JsonKey(name: "carb") bool? carb, @JsonKey(name: "meat") bool? meat}); } @@ -1359,23 +1359,23 @@ class __$$DietTypeImplCopyWithImpl<$Res> @pragma('vm:prefer-inline') @override $Res call({ - Object? alko = freezed, + Object? light = freezed, Object? veg = freezed, - Object? corb = freezed, + Object? carb = freezed, Object? meat = freezed, }) { return _then(_$DietTypeImpl( - alko: freezed == alko - ? _value.alko - : alko // ignore: cast_nullable_to_non_nullable + light: freezed == light + ? _value.light + : light // ignore: cast_nullable_to_non_nullable as bool?, veg: freezed == veg ? _value.veg : veg // ignore: cast_nullable_to_non_nullable as bool?, - corb: freezed == corb - ? _value.corb - : corb // ignore: cast_nullable_to_non_nullable + carb: freezed == carb + ? _value.carb + : carb // ignore: cast_nullable_to_non_nullable as bool?, meat: freezed == meat ? _value.meat @@ -1389,30 +1389,30 @@ class __$$DietTypeImplCopyWithImpl<$Res> @JsonSerializable() class _$DietTypeImpl implements _DietType { const _$DietTypeImpl( - {@JsonKey(name: "alko") this.alko, + {@JsonKey(name: "light") this.light, @JsonKey(name: "veg") this.veg, - @JsonKey(name: "corb") this.corb, + @JsonKey(name: "carb") this.carb, @JsonKey(name: "meat") this.meat}); factory _$DietTypeImpl.fromJson(Map json) => _$$DietTypeImplFromJson(json); @override - @JsonKey(name: "alko") - final bool? alko; + @JsonKey(name: "light") + final bool? light; @override @JsonKey(name: "veg") final bool? veg; @override - @JsonKey(name: "corb") - final bool? corb; + @JsonKey(name: "carb") + final bool? carb; @override @JsonKey(name: "meat") final bool? meat; @override String toString() { - return 'DietType(alko: $alko, veg: $veg, corb: $corb, meat: $meat)'; + return 'DietType(light: $light, veg: $veg, carb: $carb, meat: $meat)'; } @override @@ -1420,15 +1420,15 @@ class _$DietTypeImpl implements _DietType { return identical(this, other) || (other.runtimeType == runtimeType && other is _$DietTypeImpl && - (identical(other.alko, alko) || other.alko == alko) && + (identical(other.light, light) || other.light == light) && (identical(other.veg, veg) || other.veg == veg) && - (identical(other.corb, corb) || other.corb == corb) && + (identical(other.carb, carb) || other.carb == carb) && (identical(other.meat, meat) || other.meat == meat)); } @JsonKey(includeFromJson: false, includeToJson: false) @override - int get hashCode => Object.hash(runtimeType, alko, veg, corb, meat); + int get hashCode => Object.hash(runtimeType, light, veg, carb, meat); /// Create a copy of DietType /// with the given fields replaced by the non-null parameter values. @@ -1448,23 +1448,23 @@ class _$DietTypeImpl implements _DietType { abstract class _DietType implements DietType { const factory _DietType( - {@JsonKey(name: "alko") final bool? alko, + {@JsonKey(name: "light") final bool? light, @JsonKey(name: "veg") final bool? veg, - @JsonKey(name: "corb") final bool? corb, + @JsonKey(name: "carb") final bool? carb, @JsonKey(name: "meat") final bool? meat}) = _$DietTypeImpl; factory _DietType.fromJson(Map json) = _$DietTypeImpl.fromJson; @override - @JsonKey(name: "alko") - bool? get alko; + @JsonKey(name: "light") + bool? get light; @override @JsonKey(name: "veg") bool? get veg; @override - @JsonKey(name: "corb") - bool? get corb; + @JsonKey(name: "carb") + bool? get carb; @override @JsonKey(name: "meat") bool? get meat; diff --git a/lib/features/feed/models/diets_pagination_model.g.dart b/lib/features/feed/models/diets_pagination_model.g.dart index 61060256..7d3c3de0 100644 --- a/lib/features/feed/models/diets_pagination_model.g.dart +++ b/lib/features/feed/models/diets_pagination_model.g.dart @@ -108,17 +108,17 @@ const _$PortionEnumMap = { _$DietTypeImpl _$$DietTypeImplFromJson(Map json) => _$DietTypeImpl( - alko: json['alko'] as bool?, + light: json['light'] as bool?, veg: json['veg'] as bool?, - corb: json['corb'] as bool?, + carb: json['carb'] as bool?, meat: json['meat'] as bool?, ); Map _$$DietTypeImplToJson(_$DietTypeImpl instance) => { - 'alko': instance.alko, + 'light': instance.light, 'veg': instance.veg, - 'corb': instance.corb, + 'carb': instance.carb, 'meat': instance.meat, }; diff --git a/lib/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart b/lib/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart index 27e97425..ef4ecb2d 100644 --- a/lib/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart +++ b/lib/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:developer'; import 'package:easy_debounce/easy_debounce.dart'; +import 'package:eatvio_app/core/const.dart'; import 'package:eatvio_app/features/diets/repositories/diet_repository.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_state.dart'; import 'package:eatvio_app/features/feed/repositories/feed_repository.dart'; @@ -14,16 +15,23 @@ class DietsCubit extends Cubit { late int lastPage; bool isLoading = false; String? _query; - String? _types; - int? _duration; - String? _sorting; + static const List _sortingValues = [ + null, + 'chosen_diets_count:desc', + 'created_at:desc', + 'created_at', + 'name', + 'name:desc', + ]; + static const List _durationValues = [null, ...durationValues]; + static const List _types = [null, ...typeValues]; late final StreamSubscription likesStateSubscription; late final StreamSubscription favoriteStateSubscription; late final StreamSubscription commentsStateSubscription; DietsCubit({ required this.feedRepository, required this.dietsRepository, - }) : super(const DietsState.loading()) { + }) : super(DietsState.initial()) { likesStateSubscription = dietsRepository.dietLikeState.listen((likesState) { _changeDietLikeState(likesState); }); @@ -43,35 +51,43 @@ class DietsCubit extends Cubit { super.close(); } + void changeTypeFilter(int index) { + emit(state.copyWith(filterState: state.filterState.copyWith(typeIndex: index), errorMessage: null)); + loadDiets(query: _query); + } + + void changeSortingType(int index) { + emit(state.copyWith(filterState: state.filterState.copyWith(sortingIndex: index), errorMessage: null)); + loadDiets(query: _query); + } + + void changeDurationFilter(int index) { + emit(state.copyWith(filterState: state.filterState.copyWith(durationIndex: index), errorMessage: null)); + loadDiets(query: _query); + } + loadDiets({ String? query, - String? types, - int? duration, - String? sorting, }) async { try { _query = query; - _types = types; - _duration = duration; - _sorting = sorting; + final type = _types[state.filterState.typeIndex]; + final duration = _durationValues[state.filterState.durationIndex]; + final sorting = _sortingValues[state.filterState.sortingIndex]; final dietsPagination = await feedRepository.getDiets( query: query, - types: types, + types: type, duration: duration, sorting: sorting, ); lastPage = dietsPagination.meta.lastPage; + emit( - DietsState.loaded( - dietsList: dietsPagination.data, - isLoading: isLoading, - ), + state.copyWith(dietsList: dietsPagination.data, isLoading: isLoading, errorMessage: null), ); } catch (e) { emit( - DietsState.error( - errorMessage: e.toString(), - ), + state.copyWith(errorMessage: e.toString()), ); } } @@ -80,7 +96,7 @@ class DietsCubit extends Cubit { if (currentPage < lastPage && !isLoading) { isLoading = true; - emit((state as DietsStateLoaded).copyWith(isLoading: isLoading)); + emit((state.copyWith(isLoading: isLoading, errorMessage: null))); try { if (currentPage < lastPage) { @@ -88,31 +104,30 @@ class DietsCubit extends Cubit { final dietPagination = await feedRepository.getDiets( page: currentPage, query: _query, - types: _types, - duration: _duration, - sorting: _sorting, + types: _types[state.filterState.typeIndex], + duration: _durationValues[state.filterState.durationIndex], + sorting: _sortingValues[state.filterState.sortingIndex], ); isLoading = false; emit( - DietsState.loaded( + state.copyWith( dietsList: [ - ...(state as DietsStateLoaded).dietsList, + ...state.dietsList, ...dietPagination.data, ], isLoading: isLoading, + errorMessage: null, ), ); } } catch (e) { - emit(DietsState.error(errorMessage: e.toString())); + emit(state.copyWith(errorMessage: e.toString())); } } } Future likeDiet(int id, int index) async { - if (state is! DietsStateLoaded) return; - - final currentDiets = (state as DietsStateLoaded).dietsList; + final currentDiets = state.dietsList; final dietsForModification = [...currentDiets]; final currentDiet = currentDiets[index]; if (currentDiet.wasLikedByMe) { @@ -121,11 +136,12 @@ class DietsCubit extends Cubit { wasLikedByMe: false, ); emit( - DietsState.loaded( + state.copyWith( dietsList: [ ...dietsForModification, ], isLoading: isLoading, + errorMessage: null, ), ); } else { @@ -134,11 +150,12 @@ class DietsCubit extends Cubit { wasLikedByMe: true, ); emit( - DietsState.loaded( + state.copyWith( dietsList: [ ...dietsForModification, ], isLoading: isLoading, + errorMessage: null, ), ); } @@ -154,17 +171,18 @@ class DietsCubit extends Cubit { ); dietsForModification[index] = actualDiet; emit( - DietsState.loaded( + state.copyWith( dietsList: [ ...dietsForModification, ], isLoading: isLoading, + errorMessage: null, ), ); } catch (e) { log(e.toString()); emit( - DietsState.loaded( + state.copyWith( dietsList: [ ...currentDiets, ], @@ -177,9 +195,7 @@ class DietsCubit extends Cubit { } void _changeDietLikeState(DietLikesState likesState) { - if (state is! DietsStateLoaded) return; - - final currentDiets = (state as DietsStateLoaded).dietsList; + final currentDiets = state.dietsList; final dietsForModification = [...currentDiets]; final currentDiet = currentDiets[likesState.index]; @@ -188,19 +204,18 @@ class DietsCubit extends Cubit { wasLikedByMe: likesState.wasLikedByMe, ); emit( - DietsState.loaded( + state.copyWith( dietsList: [ ...dietsForModification, ], isLoading: isLoading, + errorMessage: null, ), ); } void _changeDietFavoriteState(DietFavoriteState favoriteState) { - if (state is! DietsStateLoaded) return; - - final currentDiets = (state as DietsStateLoaded).dietsList; + final currentDiets = state.dietsList; final dietsForModification = [...currentDiets]; final currentDiet = currentDiets[favoriteState.index]; @@ -208,19 +223,18 @@ class DietsCubit extends Cubit { isFavorite: favoriteState.isFavorite, ); emit( - DietsState.loaded( + state.copyWith( dietsList: [ ...dietsForModification, ], isLoading: isLoading, + errorMessage: null, ), ); } void _changeDietCommentsState(DietCommentsState commentsState) { - if (state is! DietsStateLoaded) return; - - final currentDiets = (state as DietsStateLoaded).dietsList; + final currentDiets = state.dietsList; final dietsForModification = [...currentDiets]; final currentDiet = currentDiets[commentsState.index]; @@ -228,18 +242,18 @@ class DietsCubit extends Cubit { totalComments: commentsState.totalComments, ); emit( - DietsState.loaded( + state.copyWith( dietsList: [ ...dietsForModification, ], isLoading: isLoading, + errorMessage: null, ), ); } Future addDietToFavorite(int id, int index) async { - if (state is! DietsStateLoaded) return; - final currentDiets = (state as DietsStateLoaded).dietsList; + final currentDiets = state.dietsList; final dietsForModification = [...currentDiets]; final currentDiet = currentDiets[index]; @@ -247,11 +261,12 @@ class DietsCubit extends Cubit { isFavorite: true, ); emit( - DietsState.loaded( + state.copyWith( dietsList: [ ...dietsForModification, ], isLoading: isLoading, + errorMessage: null, ), ); EasyDebounce.debounce( @@ -262,21 +277,23 @@ class DietsCubit extends Cubit { final diet = await dietsRepository.addToFavorite(id); dietsForModification[index] = diet; emit( - DietsState.loaded( + state.copyWith( dietsList: [ ...dietsForModification, ], isLoading: isLoading, + errorMessage: null, ), ); } catch (e) { log(e.toString()); emit( - DietsState.loaded( + state.copyWith( dietsList: [ ...currentDiets, ], isLoading: isLoading, + errorMessage: null, ), ); } @@ -285,8 +302,7 @@ class DietsCubit extends Cubit { } Future removeDietFromFavorite(int id, int index) async { - if (state is! DietsStateLoaded) return; - final currentDiets = (state as DietsStateLoaded).dietsList; + final currentDiets = state.dietsList; final dietsForModification = [...currentDiets]; final currentDiet = currentDiets[index]; @@ -294,11 +310,12 @@ class DietsCubit extends Cubit { isFavorite: false, ); emit( - DietsState.loaded( + state.copyWith( dietsList: [ ...dietsForModification, ], isLoading: isLoading, + errorMessage: null, ), ); EasyDebounce.debounce( @@ -309,21 +326,23 @@ class DietsCubit extends Cubit { final diet = await dietsRepository.removeFromFavorite(id); dietsForModification[index] = diet; emit( - DietsState.loaded( + state.copyWith( dietsList: [ ...dietsForModification, ], isLoading: isLoading, + errorMessage: null, ), ); } catch (e) { log(e.toString()); emit( - DietsState.loaded( + state.copyWith( dietsList: [ ...currentDiets, ], isLoading: isLoading, + errorMessage: null, ), ); } diff --git a/lib/features/feed/presentation/bloc/diets_cubit/diets_state.dart b/lib/features/feed/presentation/bloc/diets_cubit/diets_state.dart index bc5bbba1..8f3888de 100644 --- a/lib/features/feed/presentation/bloc/diets_cubit/diets_state.dart +++ b/lib/features/feed/presentation/bloc/diets_cubit/diets_state.dart @@ -4,17 +4,31 @@ import 'package:freezed_annotation/freezed_annotation.dart'; part 'diets_state.freezed.dart'; @freezed -abstract class DietsState with _$DietsState { - const factory DietsState() = _DietsState; - - const factory DietsState.loading() = DietsStateLoading; - - const factory DietsState.loaded({ +class DietsState with _$DietsState { + const factory DietsState({ + required DietsFilterState filterState, required List dietsList, required bool isLoading, - }) = DietsStateLoaded; + required String? errorMessage, + }) = _DietsState; - const factory DietsState.error({ - required String errorMessage, - }) = DietsStateError; + factory DietsState.initial() => DietsState( + filterState: DietsFilterState( + durationIndex: 0, + sortingIndex: 0, + typeIndex: 0, + ), + dietsList: [], + isLoading: true, + errorMessage: null, + ); +} + +@freezed +class DietsFilterState with _$DietsFilterState { + const factory DietsFilterState({ + required int sortingIndex, + required int durationIndex, + required int typeIndex, + }) = _DietsFilterState; } diff --git a/lib/features/feed/presentation/bloc/diets_cubit/diets_state.freezed.dart b/lib/features/feed/presentation/bloc/diets_cubit/diets_state.freezed.dart index 8edde15b..aea14d0b 100644 --- a/lib/features/feed/presentation/bloc/diets_cubit/diets_state.freezed.dart +++ b/lib/features/feed/presentation/bloc/diets_cubit/diets_state.freezed.dart @@ -16,55 +16,15 @@ final _privateConstructorUsedError = UnsupportedError( /// @nodoc mixin _$DietsState { - @optionalTypeArgs - TResult when( - TResult Function() $default, { - required TResult Function() loading, - required TResult Function(List dietsList, bool isLoading) loaded, - required TResult Function(String errorMessage) error, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult? whenOrNull( - TResult? Function()? $default, { - TResult? Function()? loading, - TResult? Function(List dietsList, bool isLoading)? loaded, - TResult? Function(String errorMessage)? error, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeWhen( - TResult Function()? $default, { - TResult Function()? loading, - TResult Function(List dietsList, bool isLoading)? loaded, - TResult Function(String errorMessage)? error, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult map( - TResult Function(_DietsState value) $default, { - required TResult Function(DietsStateLoading value) loading, - required TResult Function(DietsStateLoaded value) loaded, - required TResult Function(DietsStateError value) error, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(_DietsState value)? $default, { - TResult? Function(DietsStateLoading value)? loading, - TResult? Function(DietsStateLoaded value)? loaded, - TResult? Function(DietsStateError value)? error, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeMap( - TResult Function(_DietsState value)? $default, { - TResult Function(DietsStateLoading value)? loading, - TResult Function(DietsStateLoaded value)? loaded, - TResult Function(DietsStateError value)? error, - required TResult orElse(), - }) => + DietsFilterState get filterState => throw _privateConstructorUsedError; + List get dietsList => throw _privateConstructorUsedError; + bool get isLoading => throw _privateConstructorUsedError; + String? get errorMessage => throw _privateConstructorUsedError; + + /// Create a copy of DietsState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $DietsStateCopyWith get copyWith => throw _privateConstructorUsedError; } @@ -73,6 +33,14 @@ abstract class $DietsStateCopyWith<$Res> { factory $DietsStateCopyWith( DietsState value, $Res Function(DietsState) then) = _$DietsStateCopyWithImpl<$Res, DietsState>; + @useResult + $Res call( + {DietsFilterState filterState, + List dietsList, + bool isLoading, + String? errorMessage}); + + $DietsFilterStateCopyWith<$Res> get filterState; } /// @nodoc @@ -87,13 +55,61 @@ class _$DietsStateCopyWithImpl<$Res, $Val extends DietsState> /// Create a copy of DietsState /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? filterState = null, + Object? dietsList = null, + Object? isLoading = null, + Object? errorMessage = freezed, + }) { + return _then(_value.copyWith( + filterState: null == filterState + ? _value.filterState + : filterState // ignore: cast_nullable_to_non_nullable + as DietsFilterState, + dietsList: null == dietsList + ? _value.dietsList + : dietsList // ignore: cast_nullable_to_non_nullable + as List, + isLoading: null == isLoading + ? _value.isLoading + : isLoading // ignore: cast_nullable_to_non_nullable + as bool, + errorMessage: freezed == errorMessage + ? _value.errorMessage + : errorMessage // ignore: cast_nullable_to_non_nullable + as String?, + ) as $Val); + } + + /// Create a copy of DietsState + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $DietsFilterStateCopyWith<$Res> get filterState { + return $DietsFilterStateCopyWith<$Res>(_value.filterState, (value) { + return _then(_value.copyWith(filterState: value) as $Val); + }); + } } /// @nodoc -abstract class _$$DietsStateImplCopyWith<$Res> { +abstract class _$$DietsStateImplCopyWith<$Res> + implements $DietsStateCopyWith<$Res> { factory _$$DietsStateImplCopyWith( _$DietsStateImpl value, $Res Function(_$DietsStateImpl) then) = __$$DietsStateImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {DietsFilterState filterState, + List dietsList, + bool isLoading, + String? errorMessage}); + + @override + $DietsFilterStateCopyWith<$Res> get filterState; } /// @nodoc @@ -106,249 +122,19 @@ class __$$DietsStateImplCopyWithImpl<$Res> /// Create a copy of DietsState /// with the given fields replaced by the non-null parameter values. -} - -/// @nodoc - -class _$DietsStateImpl implements _DietsState { - const _$DietsStateImpl(); - - @override - String toString() { - return 'DietsState()'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && other is _$DietsStateImpl); - } - - @override - int get hashCode => runtimeType.hashCode; - - @override - @optionalTypeArgs - TResult when( - TResult Function() $default, { - required TResult Function() loading, - required TResult Function(List dietsList, bool isLoading) loaded, - required TResult Function(String errorMessage) error, - }) { - return $default(); - } - - @override - @optionalTypeArgs - TResult? whenOrNull( - TResult? Function()? $default, { - TResult? Function()? loading, - TResult? Function(List dietsList, bool isLoading)? loaded, - TResult? Function(String errorMessage)? error, - }) { - return $default?.call(); - } - - @override - @optionalTypeArgs - TResult maybeWhen( - TResult Function()? $default, { - TResult Function()? loading, - TResult Function(List dietsList, bool isLoading)? loaded, - TResult Function(String errorMessage)? error, - required TResult orElse(), - }) { - if ($default != null) { - return $default(); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map( - TResult Function(_DietsState value) $default, { - required TResult Function(DietsStateLoading value) loading, - required TResult Function(DietsStateLoaded value) loaded, - required TResult Function(DietsStateError value) error, - }) { - return $default(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(_DietsState value)? $default, { - TResult? Function(DietsStateLoading value)? loading, - TResult? Function(DietsStateLoaded value)? loaded, - TResult? Function(DietsStateError value)? error, - }) { - return $default?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap( - TResult Function(_DietsState value)? $default, { - TResult Function(DietsStateLoading value)? loading, - TResult Function(DietsStateLoaded value)? loaded, - TResult Function(DietsStateError value)? error, - required TResult orElse(), - }) { - if ($default != null) { - return $default(this); - } - return orElse(); - } -} - -abstract class _DietsState implements DietsState { - const factory _DietsState() = _$DietsStateImpl; -} - -/// @nodoc -abstract class _$$DietsStateLoadingImplCopyWith<$Res> { - factory _$$DietsStateLoadingImplCopyWith(_$DietsStateLoadingImpl value, - $Res Function(_$DietsStateLoadingImpl) then) = - __$$DietsStateLoadingImplCopyWithImpl<$Res>; -} - -/// @nodoc -class __$$DietsStateLoadingImplCopyWithImpl<$Res> - extends _$DietsStateCopyWithImpl<$Res, _$DietsStateLoadingImpl> - implements _$$DietsStateLoadingImplCopyWith<$Res> { - __$$DietsStateLoadingImplCopyWithImpl(_$DietsStateLoadingImpl _value, - $Res Function(_$DietsStateLoadingImpl) _then) - : super(_value, _then); - - /// Create a copy of DietsState - /// with the given fields replaced by the non-null parameter values. -} - -/// @nodoc - -class _$DietsStateLoadingImpl implements DietsStateLoading { - const _$DietsStateLoadingImpl(); - - @override - String toString() { - return 'DietsState.loading()'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && other is _$DietsStateLoadingImpl); - } - - @override - int get hashCode => runtimeType.hashCode; - - @override - @optionalTypeArgs - TResult when( - TResult Function() $default, { - required TResult Function() loading, - required TResult Function(List dietsList, bool isLoading) loaded, - required TResult Function(String errorMessage) error, - }) { - return loading(); - } - - @override - @optionalTypeArgs - TResult? whenOrNull( - TResult? Function()? $default, { - TResult? Function()? loading, - TResult? Function(List dietsList, bool isLoading)? loaded, - TResult? Function(String errorMessage)? error, - }) { - return loading?.call(); - } - - @override - @optionalTypeArgs - TResult maybeWhen( - TResult Function()? $default, { - TResult Function()? loading, - TResult Function(List dietsList, bool isLoading)? loaded, - TResult Function(String errorMessage)? error, - required TResult orElse(), - }) { - if (loading != null) { - return loading(); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map( - TResult Function(_DietsState value) $default, { - required TResult Function(DietsStateLoading value) loading, - required TResult Function(DietsStateLoaded value) loaded, - required TResult Function(DietsStateError value) error, - }) { - return loading(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(_DietsState value)? $default, { - TResult? Function(DietsStateLoading value)? loading, - TResult? Function(DietsStateLoaded value)? loaded, - TResult? Function(DietsStateError value)? error, - }) { - return loading?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap( - TResult Function(_DietsState value)? $default, { - TResult Function(DietsStateLoading value)? loading, - TResult Function(DietsStateLoaded value)? loaded, - TResult Function(DietsStateError value)? error, - required TResult orElse(), - }) { - if (loading != null) { - return loading(this); - } - return orElse(); - } -} - -abstract class DietsStateLoading implements DietsState { - const factory DietsStateLoading() = _$DietsStateLoadingImpl; -} - -/// @nodoc -abstract class _$$DietsStateLoadedImplCopyWith<$Res> { - factory _$$DietsStateLoadedImplCopyWith(_$DietsStateLoadedImpl value, - $Res Function(_$DietsStateLoadedImpl) then) = - __$$DietsStateLoadedImplCopyWithImpl<$Res>; - @useResult - $Res call({List dietsList, bool isLoading}); -} - -/// @nodoc -class __$$DietsStateLoadedImplCopyWithImpl<$Res> - extends _$DietsStateCopyWithImpl<$Res, _$DietsStateLoadedImpl> - implements _$$DietsStateLoadedImplCopyWith<$Res> { - __$$DietsStateLoadedImplCopyWithImpl(_$DietsStateLoadedImpl _value, - $Res Function(_$DietsStateLoadedImpl) _then) - : super(_value, _then); - - /// Create a copy of DietsState - /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ + Object? filterState = null, Object? dietsList = null, Object? isLoading = null, + Object? errorMessage = freezed, }) { - return _then(_$DietsStateLoadedImpl( + return _then(_$DietsStateImpl( + filterState: null == filterState + ? _value.filterState + : filterState // ignore: cast_nullable_to_non_nullable + as DietsFilterState, dietsList: null == dietsList ? _value._dietsList : dietsList // ignore: cast_nullable_to_non_nullable @@ -357,17 +143,26 @@ class __$$DietsStateLoadedImplCopyWithImpl<$Res> ? _value.isLoading : isLoading // ignore: cast_nullable_to_non_nullable as bool, + errorMessage: freezed == errorMessage + ? _value.errorMessage + : errorMessage // ignore: cast_nullable_to_non_nullable + as String?, )); } } /// @nodoc -class _$DietsStateLoadedImpl implements DietsStateLoaded { - const _$DietsStateLoadedImpl( - {required final List dietsList, required this.isLoading}) +class _$DietsStateImpl implements _DietsState { + const _$DietsStateImpl( + {required this.filterState, + required final List dietsList, + required this.isLoading, + required this.errorMessage}) : _dietsList = dietsList; + @override + final DietsFilterState filterState; final List _dietsList; @override List get dietsList { @@ -378,277 +173,233 @@ class _$DietsStateLoadedImpl implements DietsStateLoaded { @override final bool isLoading; + @override + final String? errorMessage; @override String toString() { - return 'DietsState.loaded(dietsList: $dietsList, isLoading: $isLoading)'; + return 'DietsState(filterState: $filterState, dietsList: $dietsList, isLoading: $isLoading, errorMessage: $errorMessage)'; } @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$DietsStateLoadedImpl && + other is _$DietsStateImpl && + (identical(other.filterState, filterState) || + other.filterState == filterState) && const DeepCollectionEquality() .equals(other._dietsList, _dietsList) && (identical(other.isLoading, isLoading) || - other.isLoading == isLoading)); + other.isLoading == isLoading) && + (identical(other.errorMessage, errorMessage) || + other.errorMessage == errorMessage)); } @override - int get hashCode => Object.hash( - runtimeType, const DeepCollectionEquality().hash(_dietsList), isLoading); + int get hashCode => Object.hash(runtimeType, filterState, + const DeepCollectionEquality().hash(_dietsList), isLoading, errorMessage); /// Create a copy of DietsState /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') - _$$DietsStateLoadedImplCopyWith<_$DietsStateLoadedImpl> get copyWith => - __$$DietsStateLoadedImplCopyWithImpl<_$DietsStateLoadedImpl>( - this, _$identity); - - @override - @optionalTypeArgs - TResult when( - TResult Function() $default, { - required TResult Function() loading, - required TResult Function(List dietsList, bool isLoading) loaded, - required TResult Function(String errorMessage) error, - }) { - return loaded(dietsList, isLoading); - } - - @override - @optionalTypeArgs - TResult? whenOrNull( - TResult? Function()? $default, { - TResult? Function()? loading, - TResult? Function(List dietsList, bool isLoading)? loaded, - TResult? Function(String errorMessage)? error, - }) { - return loaded?.call(dietsList, isLoading); - } - - @override - @optionalTypeArgs - TResult maybeWhen( - TResult Function()? $default, { - TResult Function()? loading, - TResult Function(List dietsList, bool isLoading)? loaded, - TResult Function(String errorMessage)? error, - required TResult orElse(), - }) { - if (loaded != null) { - return loaded(dietsList, isLoading); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map( - TResult Function(_DietsState value) $default, { - required TResult Function(DietsStateLoading value) loading, - required TResult Function(DietsStateLoaded value) loaded, - required TResult Function(DietsStateError value) error, - }) { - return loaded(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(_DietsState value)? $default, { - TResult? Function(DietsStateLoading value)? loading, - TResult? Function(DietsStateLoaded value)? loaded, - TResult? Function(DietsStateError value)? error, - }) { - return loaded?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap( - TResult Function(_DietsState value)? $default, { - TResult Function(DietsStateLoading value)? loading, - TResult Function(DietsStateLoaded value)? loaded, - TResult Function(DietsStateError value)? error, - required TResult orElse(), - }) { - if (loaded != null) { - return loaded(this); - } - return orElse(); - } + _$$DietsStateImplCopyWith<_$DietsStateImpl> get copyWith => + __$$DietsStateImplCopyWithImpl<_$DietsStateImpl>(this, _$identity); } -abstract class DietsStateLoaded implements DietsState { - const factory DietsStateLoaded( - {required final List dietsList, - required final bool isLoading}) = _$DietsStateLoadedImpl; +abstract class _DietsState implements DietsState { + const factory _DietsState( + {required final DietsFilterState filterState, + required final List dietsList, + required final bool isLoading, + required final String? errorMessage}) = _$DietsStateImpl; + @override + DietsFilterState get filterState; + @override List get dietsList; + @override bool get isLoading; + @override + String? get errorMessage; /// Create a copy of DietsState /// with the given fields replaced by the non-null parameter values. + @override @JsonKey(includeFromJson: false, includeToJson: false) - _$$DietsStateLoadedImplCopyWith<_$DietsStateLoadedImpl> get copyWith => + _$$DietsStateImplCopyWith<_$DietsStateImpl> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$DietsStateErrorImplCopyWith<$Res> { - factory _$$DietsStateErrorImplCopyWith(_$DietsStateErrorImpl value, - $Res Function(_$DietsStateErrorImpl) then) = - __$$DietsStateErrorImplCopyWithImpl<$Res>; - @useResult - $Res call({String errorMessage}); +mixin _$DietsFilterState { + int get sortingIndex => throw _privateConstructorUsedError; + int get durationIndex => throw _privateConstructorUsedError; + int get typeIndex => throw _privateConstructorUsedError; + + /// Create a copy of DietsFilterState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $DietsFilterStateCopyWith get copyWith => + throw _privateConstructorUsedError; } /// @nodoc -class __$$DietsStateErrorImplCopyWithImpl<$Res> - extends _$DietsStateCopyWithImpl<$Res, _$DietsStateErrorImpl> - implements _$$DietsStateErrorImplCopyWith<$Res> { - __$$DietsStateErrorImplCopyWithImpl( - _$DietsStateErrorImpl _value, $Res Function(_$DietsStateErrorImpl) _then) - : super(_value, _then); +abstract class $DietsFilterStateCopyWith<$Res> { + factory $DietsFilterStateCopyWith( + DietsFilterState value, $Res Function(DietsFilterState) then) = + _$DietsFilterStateCopyWithImpl<$Res, DietsFilterState>; + @useResult + $Res call({int sortingIndex, int durationIndex, int typeIndex}); +} - /// Create a copy of DietsState +/// @nodoc +class _$DietsFilterStateCopyWithImpl<$Res, $Val extends DietsFilterState> + implements $DietsFilterStateCopyWith<$Res> { + _$DietsFilterStateCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of DietsFilterState /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ - Object? errorMessage = null, + Object? sortingIndex = null, + Object? durationIndex = null, + Object? typeIndex = null, }) { - return _then(_$DietsStateErrorImpl( - errorMessage: null == errorMessage - ? _value.errorMessage - : errorMessage // ignore: cast_nullable_to_non_nullable - as String, + return _then(_value.copyWith( + sortingIndex: null == sortingIndex + ? _value.sortingIndex + : sortingIndex // ignore: cast_nullable_to_non_nullable + as int, + durationIndex: null == durationIndex + ? _value.durationIndex + : durationIndex // ignore: cast_nullable_to_non_nullable + as int, + typeIndex: null == typeIndex + ? _value.typeIndex + : typeIndex // ignore: cast_nullable_to_non_nullable + as int, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$DietsFilterStateImplCopyWith<$Res> + implements $DietsFilterStateCopyWith<$Res> { + factory _$$DietsFilterStateImplCopyWith(_$DietsFilterStateImpl value, + $Res Function(_$DietsFilterStateImpl) then) = + __$$DietsFilterStateImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({int sortingIndex, int durationIndex, int typeIndex}); +} + +/// @nodoc +class __$$DietsFilterStateImplCopyWithImpl<$Res> + extends _$DietsFilterStateCopyWithImpl<$Res, _$DietsFilterStateImpl> + implements _$$DietsFilterStateImplCopyWith<$Res> { + __$$DietsFilterStateImplCopyWithImpl(_$DietsFilterStateImpl _value, + $Res Function(_$DietsFilterStateImpl) _then) + : super(_value, _then); + + /// Create a copy of DietsFilterState + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? sortingIndex = null, + Object? durationIndex = null, + Object? typeIndex = null, + }) { + return _then(_$DietsFilterStateImpl( + sortingIndex: null == sortingIndex + ? _value.sortingIndex + : sortingIndex // ignore: cast_nullable_to_non_nullable + as int, + durationIndex: null == durationIndex + ? _value.durationIndex + : durationIndex // ignore: cast_nullable_to_non_nullable + as int, + typeIndex: null == typeIndex + ? _value.typeIndex + : typeIndex // ignore: cast_nullable_to_non_nullable + as int, )); } } /// @nodoc -class _$DietsStateErrorImpl implements DietsStateError { - const _$DietsStateErrorImpl({required this.errorMessage}); +class _$DietsFilterStateImpl implements _DietsFilterState { + const _$DietsFilterStateImpl( + {required this.sortingIndex, + required this.durationIndex, + required this.typeIndex}); @override - final String errorMessage; + final int sortingIndex; + @override + final int durationIndex; + @override + final int typeIndex; @override String toString() { - return 'DietsState.error(errorMessage: $errorMessage)'; + return 'DietsFilterState(sortingIndex: $sortingIndex, durationIndex: $durationIndex, typeIndex: $typeIndex)'; } @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$DietsStateErrorImpl && - (identical(other.errorMessage, errorMessage) || - other.errorMessage == errorMessage)); + other is _$DietsFilterStateImpl && + (identical(other.sortingIndex, sortingIndex) || + other.sortingIndex == sortingIndex) && + (identical(other.durationIndex, durationIndex) || + other.durationIndex == durationIndex) && + (identical(other.typeIndex, typeIndex) || + other.typeIndex == typeIndex)); } @override - int get hashCode => Object.hash(runtimeType, errorMessage); + int get hashCode => + Object.hash(runtimeType, sortingIndex, durationIndex, typeIndex); - /// Create a copy of DietsState + /// Create a copy of DietsFilterState /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') - _$$DietsStateErrorImplCopyWith<_$DietsStateErrorImpl> get copyWith => - __$$DietsStateErrorImplCopyWithImpl<_$DietsStateErrorImpl>( + _$$DietsFilterStateImplCopyWith<_$DietsFilterStateImpl> get copyWith => + __$$DietsFilterStateImplCopyWithImpl<_$DietsFilterStateImpl>( this, _$identity); - - @override - @optionalTypeArgs - TResult when( - TResult Function() $default, { - required TResult Function() loading, - required TResult Function(List dietsList, bool isLoading) loaded, - required TResult Function(String errorMessage) error, - }) { - return error(errorMessage); - } - - @override - @optionalTypeArgs - TResult? whenOrNull( - TResult? Function()? $default, { - TResult? Function()? loading, - TResult? Function(List dietsList, bool isLoading)? loaded, - TResult? Function(String errorMessage)? error, - }) { - return error?.call(errorMessage); - } - - @override - @optionalTypeArgs - TResult maybeWhen( - TResult Function()? $default, { - TResult Function()? loading, - TResult Function(List dietsList, bool isLoading)? loaded, - TResult Function(String errorMessage)? error, - required TResult orElse(), - }) { - if (error != null) { - return error(errorMessage); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map( - TResult Function(_DietsState value) $default, { - required TResult Function(DietsStateLoading value) loading, - required TResult Function(DietsStateLoaded value) loaded, - required TResult Function(DietsStateError value) error, - }) { - return error(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(_DietsState value)? $default, { - TResult? Function(DietsStateLoading value)? loading, - TResult? Function(DietsStateLoaded value)? loaded, - TResult? Function(DietsStateError value)? error, - }) { - return error?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap( - TResult Function(_DietsState value)? $default, { - TResult Function(DietsStateLoading value)? loading, - TResult Function(DietsStateLoaded value)? loaded, - TResult Function(DietsStateError value)? error, - required TResult orElse(), - }) { - if (error != null) { - return error(this); - } - return orElse(); - } } -abstract class DietsStateError implements DietsState { - const factory DietsStateError({required final String errorMessage}) = - _$DietsStateErrorImpl; +abstract class _DietsFilterState implements DietsFilterState { + const factory _DietsFilterState( + {required final int sortingIndex, + required final int durationIndex, + required final int typeIndex}) = _$DietsFilterStateImpl; - String get errorMessage; + @override + int get sortingIndex; + @override + int get durationIndex; + @override + int get typeIndex; - /// Create a copy of DietsState + /// Create a copy of DietsFilterState /// with the given fields replaced by the non-null parameter values. + @override @JsonKey(includeFromJson: false, includeToJson: false) - _$$DietsStateErrorImplCopyWith<_$DietsStateErrorImpl> get copyWith => + _$$DietsFilterStateImplCopyWith<_$DietsFilterStateImpl> get copyWith => throw _privateConstructorUsedError; } diff --git a/lib/features/feed/presentation/pages/feed_screen.dart b/lib/features/feed/presentation/pages/feed_screen.dart index a02b931b..1510774c 100644 --- a/lib/features/feed/presentation/pages/feed_screen.dart +++ b/lib/features/feed/presentation/pages/feed_screen.dart @@ -1,4 +1,5 @@ import 'package:easy_debounce/easy_debounce.dart'; +import 'package:eatvio_app/features/create_diet/presentation/create_diet_screen.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_state.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart'; @@ -284,9 +285,33 @@ class _FeedScreenState extends State { onRefresh: () => dietsCubit.loadDiets(), child: BlocBuilder( builder: (BuildContext context, DietsState state) { - if (state is DietsStateLoaded) { + if (state.isLoading) { + return Scaffold( + backgroundColor: Colors.grey.shade200, + body: Center( + child: SizedBox( + height: 32, + width: 32, + child: RiveAnimation.asset( + 'assets/rive_animations/loading.riv', + ), + ), + ), + ); + } else if (state.errorMessage != null) { + return Scaffold( + backgroundColor: Colors.grey.shade200, + body: Padding( + padding: const EdgeInsets.all(16), + child: Center( + child: Text(state.errorMessage ?? ''), + ), + ), + ); + } else { return Stack( children: [ + SizedBox.expand(), ListView.separated( padding: EdgeInsets.symmetric(vertical: 8), shrinkWrap: true, @@ -303,34 +328,13 @@ class _FeedScreenState extends State { right: 0, bottom: 74, child: FilterBadge( - filterBottomSheet: DietFilterBottomSheet(), + filterBottomSheet: DietFilterBottomSheet( + dietsCubit: dietsCubit, + ), ), ), ], ); - } else if (state is DietsStateError) { - return Scaffold( - backgroundColor: Colors.grey.shade200, - body: Padding( - padding: const EdgeInsets.all(16), - child: Center( - child: Text(state.errorMessage), - ), - ), - ); - } else { - return Scaffold( - backgroundColor: Colors.grey.shade200, - body: Center( - child: SizedBox( - height: 32, - width: 32, - child: RiveAnimation.asset( - 'assets/rive_animations/loading.riv', - ), - ), - ), - ); } }, ), @@ -472,12 +476,12 @@ class _FeedScreenState extends State { _addItemButton() { return InkWell( onTap: () { - switch (_selectedChipIndex) { - case 1: - GoRouter.of(context).pushNamed('recipeCreateScreen'); + switch (_selectedChipIndex) { + case 2: + GoRouter.of(context).pushNamed(CreateDietScreen.name); break; default: - GoRouter.of(context).pushNamed('blogPostCreateScreen'); + GoRouter.of(context).pushNamed('blogPostCreateScreen'); } }, borderRadius: BorderRadius.circular(64), diff --git a/lib/features/feed/presentation/widgets/choice_chip_widget.dart b/lib/features/feed/presentation/widgets/choice_chip_widget.dart index d20a2dad..a2e7fc30 100644 --- a/lib/features/feed/presentation/widgets/choice_chip_widget.dart +++ b/lib/features/feed/presentation/widgets/choice_chip_widget.dart @@ -2,11 +2,27 @@ import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:flutter/material.dart'; class ChoiceChipWidget extends StatelessWidget { - const ChoiceChipWidget({super.key, required this.chipsLabelList, required this.index, required this.selectedChipIndex, required this.onSelected}); + const ChoiceChipWidget({ + super.key, + required this.chipsLabelList, + required this.index, + required this.selectedChipIndex, + required this.onSelected, + this.padding, + this.fontSize, + this.activeColor, + this.inactiveColor, + this.fontWeight, + }); final List chipsLabelList; final int index; final int selectedChipIndex; + final double? fontSize; + final Color? activeColor; + final Color? inactiveColor; + final FontWeight? fontWeight; final void Function(bool) onSelected; + final EdgeInsetsGeometry? padding; @override Widget build(BuildContext context) { return ChoiceChip( @@ -17,12 +33,12 @@ class ChoiceChipWidget extends StatelessWidget { shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + padding: padding ?? const EdgeInsets.symmetric(horizontal: 8, vertical: 4), label: Text(chipsLabelList[index]), labelStyle: TextStyle( - color: index == selectedChipIndex ? Colors.white : appTheme.gray600, - fontWeight: FontWeight.w500, - fontSize: 12, + color: index == selectedChipIndex ? activeColor ?? Colors.white : inactiveColor ?? appTheme.gray600, + fontWeight: fontWeight ?? FontWeight.w500, + fontSize: fontSize ?? 12, ), selected: selectedChipIndex == index, backgroundColor: appTheme.gray100, diff --git a/lib/features/feed/presentation/widgets/diet_filter_bottom_sheet.dart b/lib/features/feed/presentation/widgets/diet_filter_bottom_sheet.dart index 37d720d3..cdd87f8a 100644 --- a/lib/features/feed/presentation/widgets/diet_filter_bottom_sheet.dart +++ b/lib/features/feed/presentation/widgets/diet_filter_bottom_sheet.dart @@ -1,5 +1,7 @@ import 'package:eatvio_app/core/widgets/bottom_sheet_handler_bar.dart'; import 'package:eatvio_app/core/widgets/custom_divider.dart'; +import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart'; +import 'package:eatvio_app/features/feed/presentation/widgets/duration_choice_filter_widget.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/sorting_drop_down_filter.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/type_choice_filter_widget.dart'; import 'package:eatvio_app/generated/l10n.dart'; @@ -8,8 +10,8 @@ import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:flutter/material.dart'; class DietFilterBottomSheet extends StatelessWidget { - const DietFilterBottomSheet({super.key}); - + const DietFilterBottomSheet({super.key, required this.dietsCubit}); + final DietsCubit dietsCubit; @override Widget build(BuildContext context) { final s = S.of(context); @@ -29,7 +31,7 @@ class DietFilterBottomSheet extends StatelessWidget { style: TextStyles.textMSemibold.copyWith(color: appTheme.black), ), SizedBox(height: 12), - SortingDropDownFilter(), + SortingDropDownFilter(cubit: dietsCubit,), SizedBox( height: 16, ), @@ -44,7 +46,7 @@ class DietFilterBottomSheet extends StatelessWidget { SizedBox( height: 12, ), - TypeChoiceFilterWidget(), + TypeChoiceFilterWidget(cubit: dietsCubit,), SizedBox( height: 16, ), @@ -59,7 +61,7 @@ class DietFilterBottomSheet extends StatelessWidget { SizedBox( height: 12, ), - TypeChoiceFilterWidget(), + DurationChoiceFilterWidget(cubit: dietsCubit,), SizedBox( height: 24, ), diff --git a/lib/features/feed/presentation/widgets/duration_choice_filter_widget.dart b/lib/features/feed/presentation/widgets/duration_choice_filter_widget.dart index 7be17e8e..d3a5ec9b 100644 --- a/lib/features/feed/presentation/widgets/duration_choice_filter_widget.dart +++ b/lib/features/feed/presentation/widgets/duration_choice_filter_widget.dart @@ -1,84 +1,85 @@ +import 'package:eatvio_app/core/const.dart'; import 'package:eatvio_app/core/utils/localization_utils.dart'; +import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart'; +import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_state.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/choice_chip_widget.dart'; import 'package:eatvio_app/generated/l10n.dart'; import 'package:flutter/widgets.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; class DurationChoiceFilterWidget extends StatefulWidget { - const DurationChoiceFilterWidget({super.key}); - + const DurationChoiceFilterWidget({super.key, required this.cubit}); + final DietsCubit cubit; @override State createState() => _DurationChoiceFilterWidgetState(); } class _DurationChoiceFilterWidgetState extends State { final List chipsLabelList = []; - int selectedChipIndex = 0; + @override void didChangeDependencies() { final s = S.of(context); super.didChangeDependencies(); if (chipsLabelList.isEmpty) { chipsLabelList.add(s.all); - chipsLabelList.add('7 ${getDayForm(7, s)}'); - chipsLabelList.add('14 ${getDayForm(14, s)}'); - chipsLabelList.add('21 ${getDayForm(21, s)}'); + durationValues.forEach((element) { + chipsLabelList.add('${element} ${getDayForm(element, s)}'); + }); } } @override Widget build(BuildContext context) { - return Wrap( - children: [ - ChoiceChipWidget( - chipsLabelList: chipsLabelList, - index: 0, - selectedChipIndex: selectedChipIndex, - onSelected: (selectedValue) { - setState(() { - selectedChipIndex = 0; - }); - }, - ), - SizedBox( - width: 8, - ), - ChoiceChipWidget( - chipsLabelList: chipsLabelList, - index: 1, - selectedChipIndex: selectedChipIndex, - onSelected: (selectedValue) { - setState(() { - selectedChipIndex = 1; - }); - }, - ), - SizedBox( - width: 8, - ), - ChoiceChipWidget( - chipsLabelList: chipsLabelList, - index: 2, - selectedChipIndex: selectedChipIndex, - onSelected: (selectedValue) { - setState(() { - selectedChipIndex = 2; - }); - }, - ), - SizedBox( - width: 8, - ), - ChoiceChipWidget( - chipsLabelList: chipsLabelList, - index: 3, - selectedChipIndex: selectedChipIndex, - onSelected: (selectedValue) { - setState(() { - selectedChipIndex = 3; - }); - }, - ), - ], + return BlocBuilder( + bloc: widget.cubit, + builder: (context, state) { + return Wrap( + children: [ + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + index: 0, + selectedChipIndex: state.filterState.durationIndex, + onSelected: (selectedValue) { + widget.cubit.changeDurationFilter(0); + }, + ), + SizedBox( + width: 8, + ), + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + index: 1, + selectedChipIndex: state.filterState.durationIndex, + onSelected: (selectedValue) { + widget.cubit.changeDurationFilter(1); + }, + ), + SizedBox( + width: 8, + ), + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + index: 2, + selectedChipIndex: state.filterState.durationIndex, + onSelected: (selectedValue) { + widget.cubit.changeDurationFilter(2); + }, + ), + SizedBox( + width: 8, + ), + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + index: 3, + selectedChipIndex: state.filterState.durationIndex, + onSelected: (selectedValue) { + widget.cubit.changeDurationFilter(3); + }, + ), + ], + ); + }, ); } } diff --git a/lib/features/feed/presentation/widgets/sorting_drop_down_filter.dart b/lib/features/feed/presentation/widgets/sorting_drop_down_filter.dart index 9563130d..65f7cdc8 100644 --- a/lib/features/feed/presentation/widgets/sorting_drop_down_filter.dart +++ b/lib/features/feed/presentation/widgets/sorting_drop_down_filter.dart @@ -1,20 +1,22 @@ import 'package:eatvio_app/core/theme/custom_text_style.dart'; +import 'package:eatvio_app/core/widgets/custom_drop_down_button.dart'; +import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart'; +import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_state.dart'; import 'package:eatvio_app/generated/l10n.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:flutter/material.dart'; import 'package:collection/collection.dart'; -import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; class SortingDropDownFilter extends StatefulWidget { - const SortingDropDownFilter({super.key}); - + const SortingDropDownFilter({super.key, required this.cubit}); + final DietsCubit cubit; @override State createState() => _SortingDropDownFilterState(); } class _SortingDropDownFilterState extends State { final List sortingTypes = []; - int selectedIndex = 0; @override void didChangeDependencies() { super.didChangeDependencies(); @@ -30,40 +32,28 @@ class _SortingDropDownFilterState extends State { @override Widget build(BuildContext context) { - return DropdownButtonFormField( - icon: SvgPicture.asset( - 'assets/icons/arrow_down2.svg', - width: 12, - height: 8, - ), - borderRadius: BorderRadius.circular(20), - dropdownColor: appTheme.lightGray0, - decoration: InputDecoration( - border: OutlineInputBorder( - borderRadius: const BorderRadius.all(Radius.circular(20)), - borderSide: BorderSide.none, - ), - fillColor: appTheme.lightGray0, - filled: true, - ), - value: sortingTypes[selectedIndex], - items: sortingTypes - .mapIndexed( - (index, value) => DropdownMenuItem( - child: Text( - sortingTypes[index], - style: TextStyles.textMMedium.copyWith(color: appTheme.black), - ), - value: sortingTypes[index], - ), - ) - .toList(), - onChanged: (value) { - if (value != null) { - setState(() { - selectedIndex = sortingTypes.indexOf(value); - }); - } + return BlocBuilder( + bloc: widget.cubit, + builder: (context, state) { + return CustomDropDownButton( + items: sortingTypes + .mapIndexed( + (index, value) => DropdownMenuItem( + child: Text( + sortingTypes[index], + style: TextStyles.textMMedium.copyWith(color: appTheme.black), + ), + value: sortingTypes[index], + ), + ) + .toList(), + value: sortingTypes[state.filterState.sortingIndex], + onChanged: (value) { + if (value != null) { + widget.cubit.changeSortingType(sortingTypes.indexOf(value)); + } + }, + ); }, ); } diff --git a/lib/features/feed/presentation/widgets/type_choice_filter_widget.dart b/lib/features/feed/presentation/widgets/type_choice_filter_widget.dart index d7b57801..b4cd6bca 100644 --- a/lib/features/feed/presentation/widgets/type_choice_filter_widget.dart +++ b/lib/features/feed/presentation/widgets/type_choice_filter_widget.dart @@ -1,17 +1,19 @@ +import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart'; +import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_state.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/choice_chip_widget.dart'; import 'package:eatvio_app/generated/l10n.dart'; import 'package:flutter/widgets.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; class TypeChoiceFilterWidget extends StatefulWidget { - const TypeChoiceFilterWidget({super.key}); - + const TypeChoiceFilterWidget({super.key, required this.cubit}); + final DietsCubit cubit; @override State createState() => _TypeChoiceFilterWidgetState(); } class _TypeChoiceFilterWidgetState extends State { final List chipsLabelList = []; - int selectedChipIndex = 0; @override void didChangeDependencies() { final s = S.of(context); @@ -19,79 +21,74 @@ class _TypeChoiceFilterWidgetState extends State { if (chipsLabelList.isEmpty) { chipsLabelList.add(s.all); chipsLabelList.add(s.vegan_type); - chipsLabelList.add(s.alko_type); - chipsLabelList.add(s.corb_type); + chipsLabelList.add(s.light_type); + chipsLabelList.add(s.carb_type); chipsLabelList.add(s.meat_type); } } @override Widget build(BuildContext context) { - return Wrap( - children: [ - ChoiceChipWidget( - chipsLabelList: chipsLabelList, - index: 0, - selectedChipIndex: selectedChipIndex, - onSelected: (selectedValue) { - setState(() { - selectedChipIndex = 0; - }); - }, - ), - SizedBox( - width: 8, - ), - ChoiceChipWidget( - chipsLabelList: chipsLabelList, - index: 1, - selectedChipIndex: selectedChipIndex, - onSelected: (selectedValue) { - setState(() { - selectedChipIndex = 1; - }); - }, - ), - SizedBox( - width: 8, - ), - ChoiceChipWidget( - chipsLabelList: chipsLabelList, - index: 2, - selectedChipIndex: selectedChipIndex, - onSelected: (selectedValue) { - setState(() { - selectedChipIndex = 2; - }); - }, - ), - SizedBox( - width: 8, - ), - ChoiceChipWidget( - chipsLabelList: chipsLabelList, - index: 3, - selectedChipIndex: selectedChipIndex, - onSelected: (selectedValue) { - setState(() { - selectedChipIndex = 3; - }); - }, - ), - SizedBox( - width: 8, - ), - ChoiceChipWidget( - chipsLabelList: chipsLabelList, - index: 4, - selectedChipIndex: selectedChipIndex, - onSelected: (selectedValue) { - setState(() { - selectedChipIndex = 4; - }); - }, - ), - ], + return BlocBuilder( + bloc: widget.cubit, + builder: (context, state) { + return Wrap( + children: [ + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + index: 0, + selectedChipIndex: state.filterState.typeIndex, + onSelected: (selectedValue) { + widget.cubit.changeTypeFilter(0); + }, + ), + SizedBox( + width: 8, + ), + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + index: 1, + selectedChipIndex: state.filterState.typeIndex, + onSelected: (selectedValue) { + widget.cubit.changeTypeFilter(1); + }, + ), + SizedBox( + width: 8, + ), + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + index: 2, + selectedChipIndex: state.filterState.typeIndex, + onSelected: (selectedValue) { + widget.cubit.changeTypeFilter(2); + }, + ), + SizedBox( + width: 8, + ), + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + index: 3, + selectedChipIndex: state.filterState.typeIndex, + onSelected: (selectedValue) { + widget.cubit.changeTypeFilter(3); + }, + ), + SizedBox( + width: 8, + ), + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + index: 4, + selectedChipIndex: state.filterState.typeIndex, + onSelected: (selectedValue) { + widget.cubit.changeTypeFilter(4); + }, + ), + ], + ); + }, ); } } diff --git a/lib/generated/intl/messages_en.dart b/lib/generated/intl/messages_en.dart index ecffb344..879c1f0f 100644 --- a/lib/generated/intl/messages_en.dart +++ b/lib/generated/intl/messages_en.dart @@ -26,13 +26,13 @@ class MessageLookup extends MessageLookupByLibrary { "Russia": MessageLookupByLibrary.simpleMessage("Россия"), "about_diet": MessageLookupByLibrary.simpleMessage("Об этой диете"), "active": MessageLookupByLibrary.simpleMessage("Активен"), + "active_diet_state": MessageLookupByLibrary.simpleMessage("Активная"), + "add": MessageLookupByLibrary.simpleMessage("Добавить"), + "add_cover": MessageLookupByLibrary.simpleMessage("Добавьте обложку"), "add_measure": MessageLookupByLibrary.simpleMessage("Добавить замер"), "additional_information": MessageLookupByLibrary.simpleMessage("Дополнительная информация"), "admin": MessageLookupByLibrary.simpleMessage("Админ"), - "alko_type": MessageLookupByLibrary.simpleMessage("Алкоголь"), - "alko_type_desc": MessageLookupByLibrary.simpleMessage( - "С некоторыми видами диет можно употреблять алкоголь в умеренных количествах. Рекомендуется совмещать вместе с низкокалорийными закусками."), "all": MessageLookupByLibrary.simpleMessage("Все"), "allergies_presence": MessageLookupByLibrary.simpleMessage("Наличие аллергии"), @@ -47,11 +47,16 @@ class MessageLookup extends MessageLookupByLibrary { "bodymass_chart": MessageLookupByLibrary.simpleMessage("График ИМТ"), "by_default": MessageLookupByLibrary.simpleMessage("По умолчянию"), "calories": MessageLookupByLibrary.simpleMessage("Калории"), + "carb_type": MessageLookupByLibrary.simpleMessage("Мучное"), + "carb_type_desc": MessageLookupByLibrary.simpleMessage( + "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы."), "carbohydrates": MessageLookupByLibrary.simpleMessage("Углеводы"), "chat": MessageLookupByLibrary.simpleMessage("Чат"), "chest": MessageLookupByLibrary.simpleMessage("Грудь"), "chest_circumference": MessageLookupByLibrary.simpleMessage("Обхват груди"), + "choose_diet_duration": + MessageLookupByLibrary.simpleMessage("Выберите срок диеты"), "choose_start_diet_date": MessageLookupByLibrary.simpleMessage( "Выберите дату старты диеты. Она отобразиться у Вас в дневнике"), "circumference_empty": MessageLookupByLibrary.simpleMessage( @@ -70,16 +75,15 @@ class MessageLookup extends MessageLookupByLibrary { "continueButton": MessageLookupByLibrary.simpleMessage("Продолжить"), "continue_": MessageLookupByLibrary.simpleMessage("Продолжить"), "copy_link": MessageLookupByLibrary.simpleMessage("Скопировать ссылку"), - "corb_type": MessageLookupByLibrary.simpleMessage("Мучное"), - "corb_type_desc": MessageLookupByLibrary.simpleMessage( - "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы."), "country": MessageLookupByLibrary.simpleMessage("Страна"), + "create_diet": MessageLookupByLibrary.simpleMessage("Создание диеты"), "date_of_birth": MessageLookupByLibrary.simpleMessage("Дата рождения"), "day": MessageLookupByLibrary.simpleMessage("День"), "days": MessageLookupByLibrary.simpleMessage("дней"), "diary": MessageLookupByLibrary.simpleMessage("Дневник"), "diet_author": MessageLookupByLibrary.simpleMessage("Автор диеты"), "diet_plan": MessageLookupByLibrary.simpleMessage("План диеты"), + "diet_state": MessageLookupByLibrary.simpleMessage("Статус диеты"), "diet_time": MessageLookupByLibrary.simpleMessage("Время прохождения"), "diet_type": MessageLookupByLibrary.simpleMessage("Тип диеты"), "do_you_have_hypertension_tendency": @@ -98,6 +102,10 @@ class MessageLookup extends MessageLookupByLibrary { "Некорректный адрес электронной почты"), "enter_additional_information": MessageLookupByLibrary.simpleMessage( "Введите любую дополнительную информацию на своё усмотрение:"), + "enter_diet_description": + MessageLookupByLibrary.simpleMessage("Введите описание диеты"), + "enter_diet_name": + MessageLookupByLibrary.simpleMessage("Выведите название диеты"), "enter_information": MessageLookupByLibrary.simpleMessage("Введите информацию..."), "exit": MessageLookupByLibrary.simpleMessage("Выйти"), @@ -116,6 +124,7 @@ class MessageLookup extends MessageLookupByLibrary { "Имя обязательно для заполнения"), "first_name_short": MessageLookupByLibrary.simpleMessage( "В имени должен быть минимум 1 символ"), + "gallery": MessageLookupByLibrary.simpleMessage("Галерея"), "gr": MessageLookupByLibrary.simpleMessage("гр"), "grams": MessageLookupByLibrary.simpleMessage("гр"), "height_measurements": @@ -125,6 +134,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Обхват бедер"), "hips": MessageLookupByLibrary.simpleMessage("Бедра"), "in_progress": MessageLookupByLibrary.simpleMessage("В процессе"), + "inactive_diet_state": MessageLookupByLibrary.simpleMessage("Черновик"), "initial_measurements": MessageLookupByLibrary.simpleMessage("Первичные замеры"), "language": MessageLookupByLibrary.simpleMessage("Язык"), @@ -134,11 +144,15 @@ class MessageLookup extends MessageLookupByLibrary { "last_name_short": MessageLookupByLibrary.simpleMessage( "В фамилии должен быть минимум 6 символов"), "lbl_english": MessageLookupByLibrary.simpleMessage("English"), + "light_type": MessageLookupByLibrary.simpleMessage("Легкая"), + "light_type_desc": MessageLookupByLibrary.simpleMessage( + "С некоторыми видами диет можно употреблять алкоголь в умеренных количествах. Рекомендуется совмещать вместе с низкокалорийными закусками."), "link_was_copied": MessageLookupByLibrary.simpleMessage("Ссылка успешно скопирована"), "loading": MessageLookupByLibrary.simpleMessage("Загрузка..."), "male": MessageLookupByLibrary.simpleMessage("Мужской"), "meal": MessageLookupByLibrary.simpleMessage("Приём пищи"), + "meat": MessageLookupByLibrary.simpleMessage("Мясо"), "meat_type": MessageLookupByLibrary.simpleMessage("С мясом"), "meat_type_desc": MessageLookupByLibrary.simpleMessage( "Диета с мясом полезная и сбалансированная. Включает в себя нежирное мясо: курицу, индейку, кролика или говядину. В сочетании с овощами получаете все необходимые витамины и минералы. Не забывайте о порциях и старайтесь есть медленно, прислушиваясь к своему организму."), @@ -173,6 +187,9 @@ class MessageLookup extends MessageLookupByLibrary { "password_short": MessageLookupByLibrary.simpleMessage( "В пароле должно быть минимум 6 символов"), "pcs": MessageLookupByLibrary.simpleMessage("шт"), + "personal_diet_state": + MessageLookupByLibrary.simpleMessage("Персональная"), + "photo": MessageLookupByLibrary.simpleMessage("Фото"), "place_of_living": MessageLookupByLibrary.simpleMessage("Место проживания"), "plans_complete": @@ -202,6 +219,7 @@ class MessageLookup extends MessageLookupByLibrary { "user_registration": MessageLookupByLibrary.simpleMessage("Регистрация пользователя"), "username": MessageLookupByLibrary.simpleMessage("Имя пользователя"), + "vegan": MessageLookupByLibrary.simpleMessage("Веган."), "vegan_type": MessageLookupByLibrary.simpleMessage("Вегетарианская"), "vegan_type_desc": MessageLookupByLibrary.simpleMessage( "Диета основана на потреблении растительной пищи и отказе от продуктов животного происхождения. Такой тип питания может быть разнообразным и вкусным, а также полезным для здоровья."), diff --git a/lib/generated/l10n.dart b/lib/generated/l10n.dart index 125ec2f1..96da0e7e 100644 --- a/lib/generated/l10n.dart +++ b/lib/generated/l10n.dart @@ -1210,11 +1210,11 @@ class S { ); } - /// `Алкоголь` - String get alko_type { + /// `Легкая` + String get light_type { return Intl.message( - 'Алкоголь', - name: 'alko_type', + 'Легкая', + name: 'light_type', desc: '', args: [], ); @@ -1231,10 +1231,10 @@ class S { } /// `Мучное` - String get corb_type { + String get carb_type { return Intl.message( 'Мучное', - name: 'corb_type', + name: 'carb_type', desc: '', args: [], ); @@ -1251,20 +1251,20 @@ class S { } /// `С некоторыми видами диет можно употреблять алкоголь в умеренных количествах. Рекомендуется совмещать вместе с низкокалорийными закусками.` - String get alko_type_desc { + String get light_type_desc { return Intl.message( 'С некоторыми видами диет можно употреблять алкоголь в умеренных количествах. Рекомендуется совмещать вместе с низкокалорийными закусками.', - name: 'alko_type_desc', + name: 'light_type_desc', desc: '', args: [], ); } /// `Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы.` - String get corb_type_desc { + String get carb_type_desc { return Intl.message( 'Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы.', - name: 'corb_type_desc', + name: 'carb_type_desc', desc: '', args: [], ); @@ -1469,6 +1469,146 @@ class S { args: [], ); } + + /// `Создание диеты` + String get create_diet { + return Intl.message( + 'Создание диеты', + name: 'create_diet', + desc: '', + args: [], + ); + } + + /// `Выведите название диеты` + String get enter_diet_name { + return Intl.message( + 'Выведите название диеты', + name: 'enter_diet_name', + desc: '', + args: [], + ); + } + + /// `Введите описание диеты` + String get enter_diet_description { + return Intl.message( + 'Введите описание диеты', + name: 'enter_diet_description', + desc: '', + args: [], + ); + } + + /// `Выберите срок диеты` + String get choose_diet_duration { + return Intl.message( + 'Выберите срок диеты', + name: 'choose_diet_duration', + desc: '', + args: [], + ); + } + + /// `Статус диеты` + String get diet_state { + return Intl.message( + 'Статус диеты', + name: 'diet_state', + desc: '', + args: [], + ); + } + + /// `Активная` + String get active_diet_state { + return Intl.message( + 'Активная', + name: 'active_diet_state', + desc: '', + args: [], + ); + } + + /// `Черновик` + String get inactive_diet_state { + return Intl.message( + 'Черновик', + name: 'inactive_diet_state', + desc: '', + args: [], + ); + } + + /// `Персональная` + String get personal_diet_state { + return Intl.message( + 'Персональная', + name: 'personal_diet_state', + desc: '', + args: [], + ); + } + + /// `Мясо` + String get meat { + return Intl.message( + 'Мясо', + name: 'meat', + desc: '', + args: [], + ); + } + + /// `Веган.` + String get vegan { + return Intl.message( + 'Веган.', + name: 'vegan', + desc: '', + args: [], + ); + } + + /// `Фото` + String get photo { + return Intl.message( + 'Фото', + name: 'photo', + desc: '', + args: [], + ); + } + + /// `Галерея` + String get gallery { + return Intl.message( + 'Галерея', + name: 'gallery', + desc: '', + args: [], + ); + } + + /// `Добавьте обложку` + String get add_cover { + return Intl.message( + 'Добавьте обложку', + name: 'add_cover', + desc: '', + args: [], + ); + } + + /// `Добавить` + String get add { + return Intl.message( + 'Добавить', + name: 'add', + desc: '', + args: [], + ); + } } class AppLocalizationDelegate extends LocalizationsDelegate { diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index b29cc1c2..bd0fd888 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -115,12 +115,12 @@ "share": "Поделиться", "complain": "Пожаловаться", "vegan_type": "Вегетарианская", - "alko_type": "Алкоголь", + "light_type": "Легкая", "meat_type": "С мясом", - "corb_type": "Мучное", + "carb_type": "Мучное", "vegan_type_desc": "Диета основана на потреблении растительной пищи и отказе от продуктов животного происхождения. Такой тип питания может быть разнообразным и вкусным, а также полезным для здоровья.", - "alko_type_desc": "С некоторыми видами диет можно употреблять алкоголь в умеренных количествах. Рекомендуется совмещать вместе с низкокалорийными закусками.", - "corb_type_desc": "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы.", + "light_type_desc": "С некоторыми видами диет можно употреблять алкоголь в умеренных количествах. Рекомендуется совмещать вместе с низкокалорийными закусками.", + "carb_type_desc": "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы.", "meat_type_desc": "Диета с мясом полезная и сбалансированная. Включает в себя нежирное мясо: курицу, индейку, кролика или говядину. В сочетании с овощами получаете все необходимые витамины и минералы. Не забывайте о порциях и старайтесь есть медленно, прислушиваясь к своему организму.", "diet_plan": "План диеты", "calories": "Калории", @@ -140,5 +140,19 @@ "most_old": "Самые старые", "most_liked": "Больше всего лайкнутых", "most_copleted": "Больше всего пройденных", - "by_default": "По умолчянию" + "by_default": "По умолчянию", + "create_diet": "Создание диеты", + "enter_diet_name": "Выведите название диеты", + "enter_diet_description": "Введите описание диеты", + "choose_diet_duration": "Выберите срок диеты", + "diet_state": "Статус диеты", + "active_diet_state": "Активная", + "inactive_diet_state": "Черновик", + "personal_diet_state": "Персональная", + "meat": "Мясо", + "vegan": "Веган.", + "photo": "Фото", + "gallery": "Галерея", + "add_cover": "Добавьте обложку", + "add": "Добавить" } diff --git a/pubspec.yaml b/pubspec.yaml index 105c362a..baddffa8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -56,6 +56,7 @@ dependencies: flutter_rating_bar: ^4.0.1 flutter_image_compress: ^2.3.0 image: ^4.3.0 + dotted_border: ^2.1.0 dev_dependencies: build_runner: ^2.4.13