From 4d8f6464d76921ca123c45fd987912cba662bee1 Mon Sep 17 00:00:00 2001 From: Username1548 Date: Tue, 12 Nov 2024 19:05:30 +0700 Subject: [PATCH] trailing comma rule added --- analysis_options.yaml | 7 + .../initialization_cubit.dart | 4 +- lib/core/utils/toasts.dart | 2 +- lib/core/widgets/base_button.dart | 10 + lib/core/widgets/custom_divider.dart | 2 +- .../profile_avatar_cubit.dart | 2 +- .../presentation/pages/calendar_screen.dart | 4 +- .../bloc/chat_room_cubit/chat_room_cubit.dart | 6 +- .../chat_select_cubit/chat_select_cubit.dart | 2 +- .../presentation/bloc/about_diet_cubit.dart | 115 +++ .../presentation/bloc/about_diet_state.dart | 14 + .../bloc/about_diet_state.freezed.dart | 796 +++++++++++++++++ .../presentation/pages/about_diet_screen.dart | 799 ++++++++++-------- .../presentation/widgets/author_card.dart | 8 +- .../presentation/widgets/calendar_widget.dart | 90 ++ .../presentation/widgets/cpfc_container.dart | 4 +- .../presentation/widgets/info_bouble.dart | 2 +- .../widgets/main_background_bouble.dart | 4 +- .../presentation/widgets/more_options.dart | 9 +- .../widgets/start_diet_bottom_sheet.dart | 56 ++ .../presentation/widgets/type_badges.dart | 10 +- .../diets/repositories/diets_repository.dart | 48 ++ .../diets/services/diets_service.dart | 28 +- .../diets/services/diets_service.g.dart | 133 +++ .../feed/models/diets_pagination_model.dart | 2 + .../diets_pagination_model.freezed.dart | 64 +- .../feed/models/diets_pagination_model.g.dart | 4 + .../bloc/diets_cubit/diets_cubit.dart | 4 +- .../bloc/recipes_cubit/recipes_cubit.dart | 6 +- .../bloc/profile_cubit/profile_cubit.dart | 4 +- .../bloc/recipe_create_cubit.dart | 4 +- .../pages/recipe_create_screen.dart | 8 +- .../pages/recipe_edit_screen.dart | 10 +- .../pages/city_of_living_screen.dart | 11 +- .../bloc/settings_cubit/settings_cubit.dart | 2 +- lib/generated/intl/messages_all.dart | 2 +- lib/generated/intl/messages_en.dart | 55 +- lib/generated/l10n.dart | 24 +- lib/l10n/intl_en.arb | 4 +- lib/locator_service.dart | 9 +- .../bloc/subscribers_bloc.dart | 4 +- .../subscribers_screen.dart | 8 +- lib/theme/theme_helper.dart | 2 + 43 files changed, 1923 insertions(+), 459 deletions(-) create mode 100644 lib/core/widgets/base_button.dart create mode 100644 lib/features/diets/presentation/bloc/about_diet_cubit.dart create mode 100644 lib/features/diets/presentation/bloc/about_diet_state.dart create mode 100644 lib/features/diets/presentation/bloc/about_diet_state.freezed.dart create mode 100644 lib/features/diets/presentation/widgets/calendar_widget.dart create mode 100644 lib/features/diets/presentation/widgets/start_diet_bottom_sheet.dart create mode 100644 lib/features/diets/repositories/diets_repository.dart diff --git a/analysis_options.yaml b/analysis_options.yaml index 3d36fcec..e8fba18e 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,4 +1,11 @@ + +linter: + rules: + - require_trailing_commas + analyzer: + exclude: + - '**/*.g.dart' errors: invalid_annotation_target: ignore plugins: diff --git a/lib/core/initialization_cubit/initialization_cubit.dart b/lib/core/initialization_cubit/initialization_cubit.dart index da7588cd..93e02a47 100644 --- a/lib/core/initialization_cubit/initialization_cubit.dart +++ b/lib/core/initialization_cubit/initialization_cubit.dart @@ -89,11 +89,11 @@ class InitializationCubit extends Cubit { emit(InitializationState.success( client: client, - )); + ),); } catch (e) { emit(InitializationState.error( errorMessage: e.toString(), - )); + ),); rethrow; } } diff --git a/lib/core/utils/toasts.dart b/lib/core/utils/toasts.dart index c949af0d..18195ccd 100644 --- a/lib/core/utils/toasts.dart +++ b/lib/core/utils/toasts.dart @@ -11,5 +11,5 @@ void showInfoToast(String message) { timeInSecForIosWeb: _toastDuration, backgroundColor: appTheme.blueA400, textColor: appTheme.whiteA700, - fontSize: 16.0); + fontSize: 16.0,); } diff --git a/lib/core/widgets/base_button.dart b/lib/core/widgets/base_button.dart new file mode 100644 index 00000000..c632ff4d --- /dev/null +++ b/lib/core/widgets/base_button.dart @@ -0,0 +1,10 @@ +import 'package:flutter/material.dart'; + +class BaseButton extends StatelessWidget { + const BaseButton({super.key}); + + @override + Widget build(BuildContext context) { + return FilledButton(onPressed: () {}, child: Text('qweqwe')); + } +} diff --git a/lib/core/widgets/custom_divider.dart b/lib/core/widgets/custom_divider.dart index f6635d53..8262ee4a 100644 --- a/lib/core/widgets/custom_divider.dart +++ b/lib/core/widgets/custom_divider.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; class CustomDivider extends StatelessWidget { const CustomDivider({super.key}); - + @override Widget build(BuildContext context) { return Divider( diff --git a/lib/features/bottom_navigation_bar/presentation/bloc/profile_avatar_cubit/profile_avatar_cubit.dart b/lib/features/bottom_navigation_bar/presentation/bloc/profile_avatar_cubit/profile_avatar_cubit.dart index 629e3d26..2990a507 100644 --- a/lib/features/bottom_navigation_bar/presentation/bloc/profile_avatar_cubit/profile_avatar_cubit.dart +++ b/lib/features/bottom_navigation_bar/presentation/bloc/profile_avatar_cubit/profile_avatar_cubit.dart @@ -13,7 +13,7 @@ class ProfileAvatarCubit extends Cubit { try { emit(ProfileAvatarState.loaded( profile: await profileRepository.getMyProfile(), - )); + ),); } catch (e) { emit(ProfileAvatarState.error(errorMessage: e.toString())); } diff --git a/lib/features/calendar/presentation/pages/calendar_screen.dart b/lib/features/calendar/presentation/pages/calendar_screen.dart index cf9ca83e..329ad7ec 100644 --- a/lib/features/calendar/presentation/pages/calendar_screen.dart +++ b/lib/features/calendar/presentation/pages/calendar_screen.dart @@ -89,7 +89,7 @@ class CalendarScreen extends StatelessWidget { ), ), ), - ]); + ],); } _buildCalendarBody(BuildContext context, CalendarStateLoaded state) { @@ -225,7 +225,7 @@ class CalendarScreen extends StatelessWidget { style: CustomTextStyles.titleSmallBold, // Предполагается, что текст белый ), ), - ]), + ],), ], ), ), diff --git a/lib/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart b/lib/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart index ef4a3f3a..2ee24863 100644 --- a/lib/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart +++ b/lib/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart @@ -38,7 +38,7 @@ class ChatRoomCubit extends Cubit { chatMessages: (state as ChatRoomStateLoaded).chatMessages, isTyping: (state as ChatRoomStateLoaded).isTyping, isLoading: isLoading, - )); + ),); try { final chatMessages = await chatRepository.getChatMessages(chatId, currentPage + 1); @@ -49,7 +49,7 @@ class ChatRoomCubit extends Cubit { chatMessages: [...(state as ChatRoomStateLoaded).chatMessages, ...chatMessages.messagesList], isTyping: (state as ChatRoomStateLoaded).isTyping, isLoading: isLoading, - )); + ),); currentPage++; } catch (e) { @@ -72,7 +72,7 @@ class ChatRoomCubit extends Cubit { chatMessages: chatMessages.messagesList, isTyping: false, isLoading: isLoading, - )); + ),); } catch (e) { emit(ChatRoomState.error(errorMessage: 'Ошибка получеия данных')); } diff --git a/lib/features/chat/presentation/bloc/chat_select_cubit/chat_select_cubit.dart b/lib/features/chat/presentation/bloc/chat_select_cubit/chat_select_cubit.dart index 6c119f19..b190cb27 100644 --- a/lib/features/chat/presentation/bloc/chat_select_cubit/chat_select_cubit.dart +++ b/lib/features/chat/presentation/bloc/chat_select_cubit/chat_select_cubit.dart @@ -14,7 +14,7 @@ class ChatSelectCubit extends Cubit { try { emit(ChatSelectState.loaded( chatRooms: (await chatRepository.getChatRoomPreviews(query: query)), - )); + ),); } catch (e) { emit( ChatSelectState.error(errorMessage: e.toString()), diff --git a/lib/features/diets/presentation/bloc/about_diet_cubit.dart b/lib/features/diets/presentation/bloc/about_diet_cubit.dart new file mode 100644 index 00000000..830dd3a6 --- /dev/null +++ b/lib/features/diets/presentation/bloc/about_diet_cubit.dart @@ -0,0 +1,115 @@ +import 'dart:async'; +import 'dart:developer'; + +import 'package:easy_debounce/easy_debounce.dart'; +import 'package:eatvio_app/features/diets/presentation/bloc/about_diet_state.dart'; +import 'package:eatvio_app/features/diets/repositories/diets_repository.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class AboutDietCubit extends Cubit { + AboutDietCubit({required this.dietsRepository}) : super(AboutDietState.initial()); + final DietsRepository dietsRepository; + + Future getDiet(int id) async { + try { + final diet = await dietsRepository.getDiet(id); + emit(AboutDietState.loaded(diet)); + } catch (e) { + log(e.toString()); + } + } + + Future getDietWithLoading(int id) async{ + try { + emit(AboutDietState.loading()); + final diet = await dietsRepository.getDiet(id); + emit(AboutDietState.loaded(diet)); + } catch (e) { + log(e.toString()); + } + } + + Future likeDiet(int id) async { + if (state is! DietStateLoaded) return; + + final currentDiet = (state as DietStateLoaded).diet; + + if (currentDiet.wasLikedByMe) { + final updatedDiet = currentDiet.copyWith( + totalLikes: currentDiet.totalLikes - 1, + wasLikedByMe: false, + ); + emit(AboutDietState.loaded(updatedDiet)); + } else { + final updatedDiet = currentDiet.copyWith( + totalLikes: currentDiet.totalLikes + 1, + wasLikedByMe: true, + ); + emit(AboutDietState.loaded(updatedDiet)); + } + + EasyDebounce.debounce( + 'like_diet', + Duration(seconds: 1), + () async { + try { + await dietsRepository.likeDiet(id); + await getDiet(id); + } catch (e) { + log(e.toString()); + emit(AboutDietState.loaded(currentDiet)); + } + }, + ); + } + + Future addToFavorite(int id) async { + if (state is! DietStateLoaded) return; + + final currentDiet = (state as DietStateLoaded).diet; + + final updatedDiet = currentDiet.copyWith( + isFavorite: true, + ); + emit(AboutDietState.loaded(updatedDiet)); + + EasyDebounce.debounce( + 'add_diet_to_favorites', + Duration(seconds: 1), + () async { + try { + await dietsRepository.addToFavorite(id); + await getDiet(id); + } catch (e) { + log(e.toString()); + emit(AboutDietState.loaded(currentDiet)); + } + }, + ); + } + + Future removeFromFavorite(int id) async { + if (state is! DietStateLoaded) return; + + final currentDiet = (state as DietStateLoaded).diet; + + final updatedDiet = currentDiet.copyWith( + isFavorite: false, + ); + emit(AboutDietState.loaded(updatedDiet)); + + EasyDebounce.debounce( + 'remove_diet_from_favorites', + Duration(seconds: 1), + () async { + try { + await dietsRepository.removeFromFavorite(id); + await getDiet(id); + } catch (e) { + log(e.toString()); + emit(AboutDietState.loaded(currentDiet)); + } + }, + ); + } +} diff --git a/lib/features/diets/presentation/bloc/about_diet_state.dart b/lib/features/diets/presentation/bloc/about_diet_state.dart new file mode 100644 index 00000000..36a78a31 --- /dev/null +++ b/lib/features/diets/presentation/bloc/about_diet_state.dart @@ -0,0 +1,14 @@ +import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'about_diet_state.freezed.dart'; + +@freezed +class AboutDietState with _$AboutDietState { + const factory AboutDietState() = _AboutDietState; + + const factory AboutDietState.initial() = DietStateInitial; + const factory AboutDietState.loading() = DietStateLoading; + const factory AboutDietState.loaded(Diet diet) = DietStateLoaded; + const factory AboutDietState.error({required String message}) = DietStateError; +} diff --git a/lib/features/diets/presentation/bloc/about_diet_state.freezed.dart b/lib/features/diets/presentation/bloc/about_diet_state.freezed.dart new file mode 100644 index 00000000..ce2270dc --- /dev/null +++ b/lib/features/diets/presentation/bloc/about_diet_state.freezed.dart @@ -0,0 +1,796 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'about_diet_state.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); + +/// @nodoc +mixin _$AboutDietState { + @optionalTypeArgs + TResult when( + TResult Function() $default, { + required TResult Function() initial, + required TResult Function() loading, + required TResult Function(Diet diet) loaded, + required TResult Function(String message) error, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function()? $default, { + TResult? Function()? initial, + TResult? Function()? loading, + TResult? Function(Diet diet)? loaded, + TResult? Function(String message)? error, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeWhen( + TResult Function()? $default, { + TResult Function()? initial, + TResult Function()? loading, + TResult Function(Diet diet)? loaded, + TResult Function(String message)? error, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult map( + TResult Function(_AboutDietState value) $default, { + required TResult Function(DietStateInitial value) initial, + required TResult Function(DietStateLoading value) loading, + required TResult Function(DietStateLoaded value) loaded, + required TResult Function(DietStateError value) error, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_AboutDietState value)? $default, { + TResult? Function(DietStateInitial value)? initial, + TResult? Function(DietStateLoading value)? loading, + TResult? Function(DietStateLoaded value)? loaded, + TResult? Function(DietStateError value)? error, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeMap( + TResult Function(_AboutDietState value)? $default, { + TResult Function(DietStateInitial value)? initial, + TResult Function(DietStateLoading value)? loading, + TResult Function(DietStateLoaded value)? loaded, + TResult Function(DietStateError value)? error, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $AboutDietStateCopyWith<$Res> { + factory $AboutDietStateCopyWith( + AboutDietState value, $Res Function(AboutDietState) then) = + _$AboutDietStateCopyWithImpl<$Res, AboutDietState>; +} + +/// @nodoc +class _$AboutDietStateCopyWithImpl<$Res, $Val extends AboutDietState> + implements $AboutDietStateCopyWith<$Res> { + _$AboutDietStateCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of AboutDietState + /// with the given fields replaced by the non-null parameter values. +} + +/// @nodoc +abstract class _$$AboutDietStateImplCopyWith<$Res> { + factory _$$AboutDietStateImplCopyWith(_$AboutDietStateImpl value, + $Res Function(_$AboutDietStateImpl) then) = + __$$AboutDietStateImplCopyWithImpl<$Res>; +} + +/// @nodoc +class __$$AboutDietStateImplCopyWithImpl<$Res> + extends _$AboutDietStateCopyWithImpl<$Res, _$AboutDietStateImpl> + implements _$$AboutDietStateImplCopyWith<$Res> { + __$$AboutDietStateImplCopyWithImpl( + _$AboutDietStateImpl _value, $Res Function(_$AboutDietStateImpl) _then) + : super(_value, _then); + + /// Create a copy of AboutDietState + /// with the given fields replaced by the non-null parameter values. +} + +/// @nodoc + +class _$AboutDietStateImpl implements _AboutDietState { + const _$AboutDietStateImpl(); + + @override + String toString() { + return 'AboutDietState()'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && other is _$AboutDietStateImpl); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when( + TResult Function() $default, { + required TResult Function() initial, + required TResult Function() loading, + required TResult Function(Diet diet) loaded, + required TResult Function(String message) error, + }) { + return $default(); + } + + @override + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function()? $default, { + TResult? Function()? initial, + TResult? Function()? loading, + TResult? Function(Diet diet)? loaded, + TResult? Function(String message)? error, + }) { + return $default?.call(); + } + + @override + @optionalTypeArgs + TResult maybeWhen( + TResult Function()? $default, { + TResult Function()? initial, + TResult Function()? loading, + TResult Function(Diet diet)? loaded, + TResult Function(String message)? error, + required TResult orElse(), + }) { + if ($default != null) { + return $default(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map( + TResult Function(_AboutDietState value) $default, { + required TResult Function(DietStateInitial value) initial, + required TResult Function(DietStateLoading value) loading, + required TResult Function(DietStateLoaded value) loaded, + required TResult Function(DietStateError value) error, + }) { + return $default(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_AboutDietState value)? $default, { + TResult? Function(DietStateInitial value)? initial, + TResult? Function(DietStateLoading value)? loading, + TResult? Function(DietStateLoaded value)? loaded, + TResult? Function(DietStateError value)? error, + }) { + return $default?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap( + TResult Function(_AboutDietState value)? $default, { + TResult Function(DietStateInitial value)? initial, + TResult Function(DietStateLoading value)? loading, + TResult Function(DietStateLoaded value)? loaded, + TResult Function(DietStateError value)? error, + required TResult orElse(), + }) { + if ($default != null) { + return $default(this); + } + return orElse(); + } +} + +abstract class _AboutDietState implements AboutDietState { + const factory _AboutDietState() = _$AboutDietStateImpl; +} + +/// @nodoc +abstract class _$$DietStateInitialImplCopyWith<$Res> { + factory _$$DietStateInitialImplCopyWith(_$DietStateInitialImpl value, + $Res Function(_$DietStateInitialImpl) then) = + __$$DietStateInitialImplCopyWithImpl<$Res>; +} + +/// @nodoc +class __$$DietStateInitialImplCopyWithImpl<$Res> + extends _$AboutDietStateCopyWithImpl<$Res, _$DietStateInitialImpl> + implements _$$DietStateInitialImplCopyWith<$Res> { + __$$DietStateInitialImplCopyWithImpl(_$DietStateInitialImpl _value, + $Res Function(_$DietStateInitialImpl) _then) + : super(_value, _then); + + /// Create a copy of AboutDietState + /// with the given fields replaced by the non-null parameter values. +} + +/// @nodoc + +class _$DietStateInitialImpl implements DietStateInitial { + const _$DietStateInitialImpl(); + + @override + String toString() { + return 'AboutDietState.initial()'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && other is _$DietStateInitialImpl); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when( + TResult Function() $default, { + required TResult Function() initial, + required TResult Function() loading, + required TResult Function(Diet diet) loaded, + required TResult Function(String message) error, + }) { + return initial(); + } + + @override + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function()? $default, { + TResult? Function()? initial, + TResult? Function()? loading, + TResult? Function(Diet diet)? loaded, + TResult? Function(String message)? error, + }) { + return initial?.call(); + } + + @override + @optionalTypeArgs + TResult maybeWhen( + TResult Function()? $default, { + TResult Function()? initial, + TResult Function()? loading, + TResult Function(Diet diet)? loaded, + TResult Function(String message)? error, + required TResult orElse(), + }) { + if (initial != null) { + return initial(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map( + TResult Function(_AboutDietState value) $default, { + required TResult Function(DietStateInitial value) initial, + required TResult Function(DietStateLoading value) loading, + required TResult Function(DietStateLoaded value) loaded, + required TResult Function(DietStateError value) error, + }) { + return initial(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_AboutDietState value)? $default, { + TResult? Function(DietStateInitial value)? initial, + TResult? Function(DietStateLoading value)? loading, + TResult? Function(DietStateLoaded value)? loaded, + TResult? Function(DietStateError value)? error, + }) { + return initial?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap( + TResult Function(_AboutDietState value)? $default, { + TResult Function(DietStateInitial value)? initial, + TResult Function(DietStateLoading value)? loading, + TResult Function(DietStateLoaded value)? loaded, + TResult Function(DietStateError value)? error, + required TResult orElse(), + }) { + if (initial != null) { + return initial(this); + } + return orElse(); + } +} + +abstract class DietStateInitial implements AboutDietState { + const factory DietStateInitial() = _$DietStateInitialImpl; +} + +/// @nodoc +abstract class _$$DietStateLoadingImplCopyWith<$Res> { + factory _$$DietStateLoadingImplCopyWith(_$DietStateLoadingImpl value, + $Res Function(_$DietStateLoadingImpl) then) = + __$$DietStateLoadingImplCopyWithImpl<$Res>; +} + +/// @nodoc +class __$$DietStateLoadingImplCopyWithImpl<$Res> + extends _$AboutDietStateCopyWithImpl<$Res, _$DietStateLoadingImpl> + implements _$$DietStateLoadingImplCopyWith<$Res> { + __$$DietStateLoadingImplCopyWithImpl(_$DietStateLoadingImpl _value, + $Res Function(_$DietStateLoadingImpl) _then) + : super(_value, _then); + + /// Create a copy of AboutDietState + /// with the given fields replaced by the non-null parameter values. +} + +/// @nodoc + +class _$DietStateLoadingImpl implements DietStateLoading { + const _$DietStateLoadingImpl(); + + @override + String toString() { + return 'AboutDietState.loading()'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && other is _$DietStateLoadingImpl); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when( + TResult Function() $default, { + required TResult Function() initial, + required TResult Function() loading, + required TResult Function(Diet diet) loaded, + required TResult Function(String message) error, + }) { + return loading(); + } + + @override + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function()? $default, { + TResult? Function()? initial, + TResult? Function()? loading, + TResult? Function(Diet diet)? loaded, + TResult? Function(String message)? error, + }) { + return loading?.call(); + } + + @override + @optionalTypeArgs + TResult maybeWhen( + TResult Function()? $default, { + TResult Function()? initial, + TResult Function()? loading, + TResult Function(Diet diet)? loaded, + TResult Function(String message)? error, + required TResult orElse(), + }) { + if (loading != null) { + return loading(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map( + TResult Function(_AboutDietState value) $default, { + required TResult Function(DietStateInitial value) initial, + required TResult Function(DietStateLoading value) loading, + required TResult Function(DietStateLoaded value) loaded, + required TResult Function(DietStateError value) error, + }) { + return loading(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_AboutDietState value)? $default, { + TResult? Function(DietStateInitial value)? initial, + TResult? Function(DietStateLoading value)? loading, + TResult? Function(DietStateLoaded value)? loaded, + TResult? Function(DietStateError value)? error, + }) { + return loading?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap( + TResult Function(_AboutDietState value)? $default, { + TResult Function(DietStateInitial value)? initial, + TResult Function(DietStateLoading value)? loading, + TResult Function(DietStateLoaded value)? loaded, + TResult Function(DietStateError value)? error, + required TResult orElse(), + }) { + if (loading != null) { + return loading(this); + } + return orElse(); + } +} + +abstract class DietStateLoading implements AboutDietState { + const factory DietStateLoading() = _$DietStateLoadingImpl; +} + +/// @nodoc +abstract class _$$DietStateLoadedImplCopyWith<$Res> { + factory _$$DietStateLoadedImplCopyWith(_$DietStateLoadedImpl value, + $Res Function(_$DietStateLoadedImpl) then) = + __$$DietStateLoadedImplCopyWithImpl<$Res>; + @useResult + $Res call({Diet diet}); + + $DietCopyWith<$Res> get diet; +} + +/// @nodoc +class __$$DietStateLoadedImplCopyWithImpl<$Res> + extends _$AboutDietStateCopyWithImpl<$Res, _$DietStateLoadedImpl> + implements _$$DietStateLoadedImplCopyWith<$Res> { + __$$DietStateLoadedImplCopyWithImpl( + _$DietStateLoadedImpl _value, $Res Function(_$DietStateLoadedImpl) _then) + : super(_value, _then); + + /// Create a copy of AboutDietState + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? diet = null, + }) { + return _then(_$DietStateLoadedImpl( + null == diet + ? _value.diet + : diet // ignore: cast_nullable_to_non_nullable + as Diet, + )); + } + + /// Create a copy of AboutDietState + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $DietCopyWith<$Res> get diet { + return $DietCopyWith<$Res>(_value.diet, (value) { + return _then(_value.copyWith(diet: value)); + }); + } +} + +/// @nodoc + +class _$DietStateLoadedImpl implements DietStateLoaded { + const _$DietStateLoadedImpl(this.diet); + + @override + final Diet diet; + + @override + String toString() { + return 'AboutDietState.loaded(diet: $diet)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$DietStateLoadedImpl && + (identical(other.diet, diet) || other.diet == diet)); + } + + @override + int get hashCode => Object.hash(runtimeType, diet); + + /// Create a copy of AboutDietState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$DietStateLoadedImplCopyWith<_$DietStateLoadedImpl> get copyWith => + __$$DietStateLoadedImplCopyWithImpl<_$DietStateLoadedImpl>( + this, _$identity); + + @override + @optionalTypeArgs + TResult when( + TResult Function() $default, { + required TResult Function() initial, + required TResult Function() loading, + required TResult Function(Diet diet) loaded, + required TResult Function(String message) error, + }) { + return loaded(diet); + } + + @override + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function()? $default, { + TResult? Function()? initial, + TResult? Function()? loading, + TResult? Function(Diet diet)? loaded, + TResult? Function(String message)? error, + }) { + return loaded?.call(diet); + } + + @override + @optionalTypeArgs + TResult maybeWhen( + TResult Function()? $default, { + TResult Function()? initial, + TResult Function()? loading, + TResult Function(Diet diet)? loaded, + TResult Function(String message)? error, + required TResult orElse(), + }) { + if (loaded != null) { + return loaded(diet); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map( + TResult Function(_AboutDietState value) $default, { + required TResult Function(DietStateInitial value) initial, + required TResult Function(DietStateLoading value) loading, + required TResult Function(DietStateLoaded value) loaded, + required TResult Function(DietStateError value) error, + }) { + return loaded(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_AboutDietState value)? $default, { + TResult? Function(DietStateInitial value)? initial, + TResult? Function(DietStateLoading value)? loading, + TResult? Function(DietStateLoaded value)? loaded, + TResult? Function(DietStateError value)? error, + }) { + return loaded?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap( + TResult Function(_AboutDietState value)? $default, { + TResult Function(DietStateInitial value)? initial, + TResult Function(DietStateLoading value)? loading, + TResult Function(DietStateLoaded value)? loaded, + TResult Function(DietStateError value)? error, + required TResult orElse(), + }) { + if (loaded != null) { + return loaded(this); + } + return orElse(); + } +} + +abstract class DietStateLoaded implements AboutDietState { + const factory DietStateLoaded(final Diet diet) = _$DietStateLoadedImpl; + + Diet get diet; + + /// Create a copy of AboutDietState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + _$$DietStateLoadedImplCopyWith<_$DietStateLoadedImpl> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class _$$DietStateErrorImplCopyWith<$Res> { + factory _$$DietStateErrorImplCopyWith(_$DietStateErrorImpl value, + $Res Function(_$DietStateErrorImpl) then) = + __$$DietStateErrorImplCopyWithImpl<$Res>; + @useResult + $Res call({String message}); +} + +/// @nodoc +class __$$DietStateErrorImplCopyWithImpl<$Res> + extends _$AboutDietStateCopyWithImpl<$Res, _$DietStateErrorImpl> + implements _$$DietStateErrorImplCopyWith<$Res> { + __$$DietStateErrorImplCopyWithImpl( + _$DietStateErrorImpl _value, $Res Function(_$DietStateErrorImpl) _then) + : super(_value, _then); + + /// Create a copy of AboutDietState + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? message = null, + }) { + return _then(_$DietStateErrorImpl( + message: null == message + ? _value.message + : message // ignore: cast_nullable_to_non_nullable + as String, + )); + } +} + +/// @nodoc + +class _$DietStateErrorImpl implements DietStateError { + const _$DietStateErrorImpl({required this.message}); + + @override + final String message; + + @override + String toString() { + return 'AboutDietState.error(message: $message)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$DietStateErrorImpl && + (identical(other.message, message) || other.message == message)); + } + + @override + int get hashCode => Object.hash(runtimeType, message); + + /// Create a copy of AboutDietState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$DietStateErrorImplCopyWith<_$DietStateErrorImpl> get copyWith => + __$$DietStateErrorImplCopyWithImpl<_$DietStateErrorImpl>( + this, _$identity); + + @override + @optionalTypeArgs + TResult when( + TResult Function() $default, { + required TResult Function() initial, + required TResult Function() loading, + required TResult Function(Diet diet) loaded, + required TResult Function(String message) error, + }) { + return error(message); + } + + @override + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function()? $default, { + TResult? Function()? initial, + TResult? Function()? loading, + TResult? Function(Diet diet)? loaded, + TResult? Function(String message)? error, + }) { + return error?.call(message); + } + + @override + @optionalTypeArgs + TResult maybeWhen( + TResult Function()? $default, { + TResult Function()? initial, + TResult Function()? loading, + TResult Function(Diet diet)? loaded, + TResult Function(String message)? error, + required TResult orElse(), + }) { + if (error != null) { + return error(message); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map( + TResult Function(_AboutDietState value) $default, { + required TResult Function(DietStateInitial value) initial, + required TResult Function(DietStateLoading value) loading, + required TResult Function(DietStateLoaded value) loaded, + required TResult Function(DietStateError value) error, + }) { + return error(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_AboutDietState value)? $default, { + TResult? Function(DietStateInitial value)? initial, + TResult? Function(DietStateLoading value)? loading, + TResult? Function(DietStateLoaded value)? loaded, + TResult? Function(DietStateError value)? error, + }) { + return error?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap( + TResult Function(_AboutDietState value)? $default, { + TResult Function(DietStateInitial value)? initial, + TResult Function(DietStateLoading value)? loading, + TResult Function(DietStateLoaded value)? loaded, + TResult Function(DietStateError value)? error, + required TResult orElse(), + }) { + if (error != null) { + return error(this); + } + return orElse(); + } +} + +abstract class DietStateError implements AboutDietState { + const factory DietStateError({required final String message}) = + _$DietStateErrorImpl; + + String get message; + + /// Create a copy of AboutDietState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + _$$DietStateErrorImplCopyWith<_$DietStateErrorImpl> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/lib/features/diets/presentation/pages/about_diet_screen.dart b/lib/features/diets/presentation/pages/about_diet_screen.dart index f32d5bd9..db0bd378 100644 --- a/lib/features/diets/presentation/pages/about_diet_screen.dart +++ b/lib/features/diets/presentation/pages/about_diet_screen.dart @@ -5,12 +5,15 @@ import 'package:eatvio_app/core/const.dart'; import 'package:eatvio_app/core/utils/localization_utils.dart'; import 'package:eatvio_app/core/utils/string_extentions.dart'; import 'package:eatvio_app/core/widgets/custom_divider.dart'; +import 'package:eatvio_app/features/diets/presentation/bloc/about_diet_cubit.dart'; +import 'package:eatvio_app/features/diets/presentation/bloc/about_diet_state.dart'; 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/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/diets/presentation/widgets/type_badges.dart'; import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/comments_cubit/comments_cubit.dart'; @@ -39,6 +42,7 @@ class AboutDietScreen extends StatefulWidget { class _AboutDietScreenState extends State { final CommentsCubit commentsCubit = sl(); + final AboutDietCubit dietsCubit = sl(); int? replyId; final ScrollController scrollController = ScrollController(); final textEditingController = TextEditingController(); @@ -59,365 +63,451 @@ class _AboutDietScreenState extends State { @override Widget build(BuildContext context) { final s = S.of(context); - return BlocProvider( - create: (BuildContext context) => commentsCubit - ..getComments( - widget.diet.id.toString(), - CommentSourceType.diet, - true, - ), - child: BlocConsumer( - listener: (BuildContext context, CommentsState state) { - if (state is CommentsStateLoaded) { - setState(() { - replyId = state.replyId; - }); - } - }, - builder: (BuildContext context, CommentsState state) { - return Scaffold( - backgroundColor: appTheme.gray100, - resizeToAvoidBottomInset: true, - bottomSheet: Container( - padding: EdgeInsets.symmetric(vertical: 12) + (Platform.isIOS ? const EdgeInsets.only(bottom: 16) : EdgeInsets.zero), - decoration: BoxDecoration( - color: Colors.white, - border: Border( - top: BorderSide( - color: Colors.black.withOpacity(0.1), - ), - ), - ), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Row( - children: [ - Expanded( - child: SizedBox( - child: FloatingActionButton.extended( - heroTag: 'nextButtonRegistration', - highlightElevation: 0, - elevation: 0, - focusElevation: 0, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(16), - ), - backgroundColor: appTheme.greenA700, - onPressed: () {}, - label: Text( - s.startDiet, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: appTheme.whiteA700, - ), + return BlocProvider( + create: (context) => dietsCubit..getDietWithLoading(widget.diet.id), + child: BlocProvider( + create: (BuildContext context) => commentsCubit + ..getComments( + widget.diet.id.toString(), + CommentSourceType.diet, + true, + ), + child: BlocConsumer( + listener: (BuildContext context, CommentsState commentsState) { + if (commentsState is CommentsStateLoaded) { + setState(() { + replyId = commentsState.replyId; + }); + } + }, + builder: (BuildContext context, CommentsState state) { + return BlocBuilder( + builder: (context, dietState) { + return dietState is DietStateLoaded + ? Scaffold( + backgroundColor: appTheme.gray100, + resizeToAvoidBottomInset: true, + bottomSheet: Container( + padding: EdgeInsets.symmetric(vertical: 12) + (Platform.isIOS ? const EdgeInsets.only(bottom: 16) : EdgeInsets.zero), + decoration: BoxDecoration( + color: Colors.white, + border: Border( + top: BorderSide( + color: Colors.black.withOpacity(0.1), ), ), ), - ), - SizedBox(width: 8), - Container( - width: 52, - height: 52, - decoration: BoxDecoration(color: appTheme.gray50, shape: BoxShape.circle), - child: Icon( - Icons.bookmark_border_rounded, - color: appTheme.blueGray800, - size: 24, - ), - ) - ], - ), - SizedBox(height: 8), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - if (replyId != null) - GestureDetector( - onTap: () { - context.read().setReplyId(null); - setState(() { - replyId = null; - textEditingController.clear(); - }); - FocusManager.instance.primaryFocus?.unfocus(); - }, - child: Container( - decoration: BoxDecoration( - color: appTheme.blueA400, - shape: BoxShape.circle, - ), - height: 32, - width: 32, - child: Icon( - Icons.close_rounded, - size: 18, - color: Colors.white, - ), - ), - ), - if (replyId != null) SizedBox(width: 8), - Expanded( - child: SizedBox( - child: TextFormField( - onChanged: (_) { - setState(() {}); - }, - controller: textEditingController, - maxLines: 5, - minLines: 1, - keyboardType: TextInputType.multiline, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w400, - color: Colors.black, - height: 1, - ), - decoration: InputDecoration( - isDense: true, - contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), - hintText: s.comment.capitalize(), - hintStyle: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w400, - height: 1, - color: Color(0xFFAEAEB2), - ), - filled: true, - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(16), - borderSide: BorderSide( - color: Color(0xFFD1D1D6), - width: 1, - ), - ), - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(16), - borderSide: BorderSide( - color: Color(0xFFD1D1D6), - width: 1, - ), - ), - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(16), - borderSide: BorderSide( - color: Color(0xFFD1D1D6), - width: 1, - ), - ), - ), - ), - ), - ), - SizedBox(width: 8), - GestureDetector( - onTap: () { - if (textEditingController.text.length > 2) { - commentsCubit.sendComment( - id: widget.diet.id.toString(), - commentText: textEditingController.text, - parentCommentId: replyId, - commentSourceType: CommentSourceType.diet, - ); - context.read().setReplyId(null); - setState(() { - textEditingController.clear(); - replyId = null; - }); - FocusManager.instance.primaryFocus?.unfocus(); - } - }, - child: Container( - decoration: BoxDecoration( - color: textEditingController.text.length > 2 ? appTheme.blueA400 : appTheme.gray50, - shape: BoxShape.circle, - ), - height: 32, - width: 32, - child: Icon( - Icons.send_rounded, - size: 18, - color: textEditingController.text.length > 2 ? appTheme.whiteA700 : appTheme.blueGray800, - ), - ), - ), - ], - ), - ], - ), - ), - ), - appBar: AppBar( - centerTitle: true, - title: Text( - widget.diet.name, - maxLines: 2, - textAlign: TextAlign.center, - overflow: TextOverflow.ellipsis, - softWrap: true, - style: TextStyle( - color: Colors.black, - fontSize: 24, - fontWeight: FontWeight.w500, - height: 1, - ), - ), - actions: [ - PortalTarget( - visible: isMoreOptionsVisible, - portalFollower: MoreOptions(id: widget.diet.id), - anchor: Aligned( - shiftToWithinBound: AxisFlag(x: true, y: true), - follower: Alignment.topRight, - target: Alignment.bottomRight, - ), - child: IconButton( - onPressed: () { - setState(() { - isMoreOptionsVisible = !isMoreOptionsVisible; - }); - }, - icon: SvgPicture.asset( - 'assets/icons/more_button.svg', - width: 20, - height: 20, - )), - ), - ], - ), - body: SingleChildScrollView( - controller: scrollController, - padding: EdgeInsets.only(bottom: 160), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox(height: 8), - MainBackgroundBouble( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Stack(children: [ - CachedNetworkImage( - imageUrl: baseUrl + '/storage/' + widget.diet.image, - ), - Positioned( - child: Row( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + mainAxisSize: MainAxisSize.min, children: [ - InfoBouble(children: [ - - ], backgroundColor: appTheme.whiteA700,) + Row( + children: [ + Expanded( + child: SizedBox( + child: FloatingActionButton.extended( + heroTag: 'nextButtonRegistration', + highlightElevation: 0, + elevation: 0, + focusElevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + backgroundColor: appTheme.greenA700, + onPressed: () { + showModalBottomSheet(context: context, builder: (context) => StartDietBottomSheet()); + }, + label: Text( + s.startDiet, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: appTheme.whiteA700, + ), + ), + ), + ), + ), + SizedBox(width: 8), + GestureDetector( + onTap: () { + if (dietState.diet.isFavorite) { + dietsCubit.removeFromFavorite(widget.diet.id); + } else { + dietsCubit.addToFavorite(widget.diet.id); + } + }, + child: Container( + width: 52, + height: 52, + decoration: BoxDecoration(color: appTheme.gray50, shape: BoxShape.circle), + child: Icon( + dietState.diet.isFavorite ? Icons.bookmark : Icons.bookmark_border_rounded, + color: appTheme.blueGray800, + size: 24, + ), + ), + ), + ], + ), + SizedBox(height: 8), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (replyId != null) + GestureDetector( + onTap: () { + context.read().setReplyId(null); + setState(() { + replyId = null; + textEditingController.clear(); + }); + FocusManager.instance.primaryFocus?.unfocus(); + }, + child: Container( + decoration: BoxDecoration( + color: appTheme.blueA400, + shape: BoxShape.circle, + ), + height: 32, + width: 32, + child: Icon( + Icons.close_rounded, + size: 18, + color: Colors.white, + ), + ), + ), + if (replyId != null) SizedBox(width: 8), + Expanded( + child: SizedBox( + child: TextFormField( + onChanged: (_) { + setState(() {}); + }, + controller: textEditingController, + maxLines: 5, + minLines: 1, + keyboardType: TextInputType.multiline, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w400, + color: Colors.black, + height: 1, + ), + decoration: InputDecoration( + isDense: true, + contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), + hintText: s.comment.capitalize(), + hintStyle: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w400, + height: 1, + color: Color(0xFFAEAEB2), + ), + filled: true, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(16), + borderSide: BorderSide( + color: Color(0xFFD1D1D6), + width: 1, + ), + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(16), + borderSide: BorderSide( + color: Color(0xFFD1D1D6), + width: 1, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(16), + borderSide: BorderSide( + color: Color(0xFFD1D1D6), + width: 1, + ), + ), + ), + ), + ), + ), + SizedBox(width: 8), + GestureDetector( + onTap: () { + if (textEditingController.text.length > 2) { + commentsCubit.sendComment( + id: widget.diet.id.toString(), + commentText: textEditingController.text, + parentCommentId: replyId, + commentSourceType: CommentSourceType.diet, + ); + context.read().setReplyId(null); + setState(() { + textEditingController.clear(); + replyId = null; + }); + dietsCubit.getDiet(widget.diet.id); + FocusManager.instance.primaryFocus?.unfocus(); + } + }, + child: Container( + decoration: BoxDecoration( + color: textEditingController.text.length > 2 ? appTheme.blueA400 : appTheme.gray50, + shape: BoxShape.circle, + ), + height: 32, + width: 32, + child: Icon( + Icons.send_rounded, + size: 18, + color: textEditingController.text.length > 2 ? appTheme.whiteA700 : appTheme.blueGray800, + ), + ), + ), + ], + ), ], ), - ) - ]), - SizedBox(height: 16), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Text( - s.about_diet, - style: TextStyle(color: appTheme.blueGray800, fontSize: 20, fontWeight: FontWeight.w600), ), ), - SizedBox(height: 12), - SingleChildScrollView( - padding: const EdgeInsets.symmetric(horizontal: 16), - scrollDirection: Axis.horizontal, - child: Row( + appBar: AppBar( + centerTitle: true, + title: Text( + widget.diet.name, + maxLines: 2, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + softWrap: true, + style: TextStyle( + color: Colors.black, + fontSize: 24, + fontWeight: FontWeight.w500, + height: 1, + ), + ), + actions: [ + PortalTarget( + visible: isMoreOptionsVisible, + portalFollower: MoreOptions(id: widget.diet.id), + anchor: Aligned( + shiftToWithinBound: AxisFlag(x: true, y: true), + follower: Alignment.topRight, + target: Alignment.bottomRight, + ), + child: IconButton( + onPressed: () { + setState(() { + isMoreOptionsVisible = !isMoreOptionsVisible; + }); + }, + icon: SvgPicture.asset( + 'assets/icons/more_button.svg', + width: 20, + height: 20, + ),), + ), + ], + ), + body: SingleChildScrollView( + controller: scrollController, + padding: EdgeInsets.only(bottom: 160), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - InfoBouble( - children: [ - SvgPicture.asset( - 'assets/icons/time2.svg', - width: 13.3, - height: 13.3, - ), - SizedBox(width: 4), - Text(widget.diet.duration.toString() + ' ' + getDayForm(widget.diet.duration, s), - style: TextStyle(color: appTheme.blueGray800, fontSize: 12, fontWeight: FontWeight.w500)), - ], + SizedBox(height: 8), + MainBackgroundBouble( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Stack(children: [ + CachedNetworkImage( + imageUrl: baseUrl + '/storage/' + widget.diet.image, + ), + Positioned( + bottom: 16, + left: 0, + right: 0, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + InfoBouble( + children: [ + SvgPicture.asset('assets/icons/eye.svg', width: 18, height: 12), + SizedBox(width: 8), + Text( + dietState.diet.totalViews.toString(), + style: TextStyle(color: appTheme.blueGray800, fontSize: 12, fontWeight: FontWeight.w500), + ), + ], + backgroundColor: appTheme.whiteA700, + ), + SizedBox(width: 12), + GestureDetector( + onTap: () { + dietsCubit.likeDiet(widget.diet.id); + }, + child: InfoBouble( + children: [ + SvgPicture.asset( + 'assets/icons/heart.svg', + width: 14, + height: 12, + colorFilter: dietState.diet.wasLikedByMe ? ColorFilter.mode(appTheme.blueA400, BlendMode.srcIn) : null, + ), + SizedBox(width: 8), + Text( + dietState.diet.totalLikes.toString(), + style: TextStyle(color: appTheme.blueGray800, fontSize: 12, fontWeight: FontWeight.w500), + ), + ], + backgroundColor: appTheme.whiteA700, + ), + ), + SizedBox(width: 12), + InfoBouble( + children: [ + SvgPicture.asset('assets/icons/comment2.svg', width: 13, height: 12), + SizedBox(width: 8), + Text( + dietState.diet.totalComments.toString(), + style: TextStyle(color: appTheme.blueGray800, fontSize: 12, fontWeight: FontWeight.w500), + ), + ], + backgroundColor: appTheme.whiteA700, + ), + ], + ), + ), + ],), + SizedBox(height: 16), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Text( + s.about_diet, + style: TextStyle(color: appTheme.blueGray800, fontSize: 20, fontWeight: FontWeight.w600), + ), + ), + SizedBox(height: 12), + SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 16), + scrollDirection: Axis.horizontal, + child: Row( + children: [ + InfoBouble( + children: [ + SvgPicture.asset( + 'assets/icons/time2.svg', + width: 13.3, + height: 13.3, + ), + SizedBox(width: 4), + Text(widget.diet.duration.toString() + ' ' + getDayForm(widget.diet.duration, s), + style: TextStyle(color: appTheme.blueGray800, fontSize: 12, fontWeight: FontWeight.w500),), + ], + ), + SizedBox(width: 12), + InfoBouble( + children: [ + SvgPicture.asset( + 'assets/icons/people.svg', + width: 13.3, + height: 13.3, + ), + SizedBox(width: 4), + Text('80 человек прошли(статика, ещё нет бека)', + style: TextStyle(color: appTheme.blueGray800, fontSize: 12, fontWeight: FontWeight.w500),), + ], + ), + SizedBox(width: 12), + InfoBouble( + children: [ + TypeBadges(type: widget.diet.type), + ], + ), + ], + ), + ), + ExpandableText( + text: widget.diet.details, + ), + SizedBox(height: 20), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: AuthorCard( + author: widget.diet.author, + ), + ), + SizedBox(height: 16), + ], + ), ), - SizedBox(width: 12), - InfoBouble( - children: [ - SvgPicture.asset( - 'assets/icons/people.svg', - width: 13.3, - height: 13.3, + SizedBox(height: 16), + MainBackgroundBouble( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: Center( + child: Text( + s.diet_plan + '(${widget.diet.duration.toString()} ' + getDayForm(widget.diet.duration, s) + ')', + style: TextStyle( + color: appTheme.blueGray800, + fontSize: 20, + fontWeight: FontWeight.w600, + ), ), - SizedBox(width: 4), - Text('80 человек прошли(статика, ещё нет бека)', - style: TextStyle(color: appTheme.blueGray800, fontSize: 12, fontWeight: FontWeight.w500)), - ], + ), + ),), + SizedBox(height: 8), + ListView.builder( + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemBuilder: (context, index) { + return _dayOfPlan(widget.diet.dailySchedule[index], index, s); + }, + itemCount: widget.diet.dailySchedule.length, + ), + MainBackgroundBouble( + padding: EdgeInsets.symmetric(vertical: 16), + child: Column(children: [ + Container( + padding: EdgeInsets.symmetric(horizontal: 16), + alignment: Alignment.centerLeft, + child: Text( + dietState.diet.totalComments.toString() + ' ' + getCommentForm(widget.diet.totalComments, s), + style: TextStyle( + fontSize: 12, + color: appTheme.gray500, + fontWeight: FontWeight.w400, + ), + ), + ), + SizedBox(height: 16), + if (state is CommentsStateLoading) + Padding( + padding: const EdgeInsets.all(32), + child: SizedBox( + height: 32, + width: 32, + child: RiveAnimation.asset( + 'assets/rive_animations/loading.riv', + ), + ), + ), + if (state is CommentsStateLoaded) + CommentsWidget( + id: widget.diet.id.toString(), + commentSourceType: CommentSourceType.diet, + comment: state.comment, + replyId: replyId, + ), + ],), ), - SizedBox(width: 12), - InfoBouble( - children: [ - TypeBadges(type: widget.diet.type), - ], - ) ], ), ), - ExpandableText( - text: widget.diet.details, - ), - SizedBox(height: 20), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: AuthorCard( - author: widget.diet.author, - ), - ), - SizedBox(height: 16), - ], - ), - ), - SizedBox(height: 16), - MainBackgroundBouble( - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 16.0), - child: Center( - child: Text( - s.diet_plan + '(${widget.diet.duration.toString()} ' + getDayForm(widget.diet.duration, s) + ')', - style: TextStyle( - color: appTheme.blueGray800, - fontSize: 20, - fontWeight: FontWeight.w600, - ), - ), - ), - )), - SizedBox(height: 8), - ListView.builder( - physics: NeverScrollableScrollPhysics(), - shrinkWrap: true, - itemBuilder: (context, index) { - return _dayOfPlan(widget.diet.dailySchedule[index], index, s); - }, - itemCount: widget.diet.dailySchedule.length, - ), - MainBackgroundBouble( - padding: EdgeInsets.symmetric(vertical: 16), - child: Column(children: [ - Container( - padding: EdgeInsets.symmetric(horizontal: 16), - alignment: Alignment.centerLeft, - child: Text( - widget.diet.totalComments.toString() + ' ' + getCommentForm(widget.diet.totalComments, s), - style: TextStyle( - fontSize: 12, - color: appTheme.gray500, - fontWeight: FontWeight.w400, - ), - ), - ), - SizedBox(height: 16), - if (state is CommentsStateLoading) - Padding( - padding: const EdgeInsets.all(32), + ) + : Scaffold( + body: Center( child: SizedBox( height: 32, width: 32, @@ -426,20 +516,11 @@ class _AboutDietScreenState extends State { ), ), ), - if (state is CommentsStateLoaded) - CommentsWidget( - id: widget.diet.id.toString(), - commentSourceType: CommentSourceType.diet, - comment: state.comment, - replyId: replyId, - ), - ]), - ), - ], - ), - ), - ); - }, + ); + }, + ); + }, + ), ), ); } @@ -525,7 +606,7 @@ class _AboutDietScreenState extends State { ], ), ), - CpfcContainer(calories: 0, protein: 0, fat: 0, carbohydrates: 0) + CpfcContainer(calories: 0, protein: 0, fat: 0, carbohydrates: 0), ], ), ), diff --git a/lib/features/diets/presentation/widgets/author_card.dart b/lib/features/diets/presentation/widgets/author_card.dart index ee50ca05..d566dad5 100644 --- a/lib/features/diets/presentation/widgets/author_card.dart +++ b/lib/features/diets/presentation/widgets/author_card.dart @@ -70,10 +70,10 @@ class AuthorCard extends StatelessWidget { fontSize: 16, fontWeight: FontWeight.w500, ), - ) - ]) + ), + ],), ], - ) + ), ], ), ), @@ -99,7 +99,7 @@ class AuthorCard extends StatelessWidget { ), ), ), - ) + ), ], ), ); diff --git a/lib/features/diets/presentation/widgets/calendar_widget.dart b/lib/features/diets/presentation/widgets/calendar_widget.dart new file mode 100644 index 00000000..e2353b28 --- /dev/null +++ b/lib/features/diets/presentation/widgets/calendar_widget.dart @@ -0,0 +1,90 @@ +import 'package:eatvio_app/theme/theme_helper.dart'; +import 'package:flutter/material.dart'; +import 'package:table_calendar/table_calendar.dart'; + +class CalendarWidget extends StatefulWidget { + const CalendarWidget({super.key}); + + @override + State createState() => _CalendarWidgetState(); +} + +class _CalendarWidgetState extends State { + CalendarFormat _calendarFormat = CalendarFormat.month; + DateTime _focusedDay = DateTime.now(); + DateTime? _selectedDay = DateTime.now(); + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.only(top: 5), + child: TableCalendar( + firstDay: DateTime.utc(2010, 10, 16), + lastDay: DateTime.utc(2030, 3, 14), + locale: 'ru_RU', + startingDayOfWeek: StartingDayOfWeek.monday, + focusedDay: _focusedDay, + rangeStartDay: _selectedDay, + rangeEndDay: _selectedDay?.add(const Duration(days: 6)), + calendarFormat: _calendarFormat, + headerStyle: HeaderStyle( + titleCentered: true, + formatButtonVisible: false, + leftChevronVisible: false, + rightChevronVisible: false, + ), + rowHeight: 40, + selectedDayPredicate: (day) { + return isSameDay(_selectedDay, day); + }, + onDaySelected: (selectedDay, focusedDay) { + if (!isSameDay(_selectedDay, selectedDay)) { + setState(() { + _selectedDay = selectedDay; + _focusedDay = focusedDay; + }); + } + }, + onFormatChanged: (format) { + if (_calendarFormat != format) { + setState(() { + _calendarFormat = format; + }); + } + }, + onPageChanged: (focusedDay) { + _focusedDay = focusedDay; + }, + calendarStyle: CalendarStyle( + weekendDecoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.circle, + ), + defaultDecoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.circle, + ), + selectedDecoration: BoxDecoration( + color: appTheme.blueA400, + shape: BoxShape.circle, + ), + todayTextStyle: TextStyle( + color: Colors.black, + ), + todayDecoration: BoxDecoration( + border: Border.all( + color: appTheme.blueA400, + width: 2, + ), + color: Colors.white, + shape: BoxShape.circle, + ), + ), + ), + ), + ], + ); + } +} diff --git a/lib/features/diets/presentation/widgets/cpfc_container.dart b/lib/features/diets/presentation/widgets/cpfc_container.dart index f7428d46..e73cf57c 100644 --- a/lib/features/diets/presentation/widgets/cpfc_container.dart +++ b/lib/features/diets/presentation/widgets/cpfc_container.dart @@ -39,8 +39,8 @@ class CpfcContainer extends StatelessWidget { Text('$carbohydrates', style: TextStyle(color: appTheme.blueGray800, fontSize: 16, fontWeight: FontWeight.w600)), Text(s.carbohydrates, style: TextStyle(color: appTheme.blueGray800, fontSize: 12, fontWeight: FontWeight.w500)), ], - ) - ]), + ), + ],), ); } } diff --git a/lib/features/diets/presentation/widgets/info_bouble.dart b/lib/features/diets/presentation/widgets/info_bouble.dart index d37cbd92..870859dd 100644 --- a/lib/features/diets/presentation/widgets/info_bouble.dart +++ b/lib/features/diets/presentation/widgets/info_bouble.dart @@ -14,7 +14,7 @@ class InfoBouble extends StatelessWidget { color: backgroundColor ?? appTheme.gray50, borderRadius: BorderRadius.circular(radius), ), - child: Row(children: children), + child: Row(mainAxisSize: MainAxisSize.min, children: children), ); } } diff --git a/lib/features/diets/presentation/widgets/main_background_bouble.dart b/lib/features/diets/presentation/widgets/main_background_bouble.dart index 6b6ad9c5..8b94131e 100644 --- a/lib/features/diets/presentation/widgets/main_background_bouble.dart +++ b/lib/features/diets/presentation/widgets/main_background_bouble.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; class MainBackgroundBouble extends StatelessWidget { const MainBackgroundBouble( - {super.key, required this.child, this.width, this.padding, this.enableShadow = false}); + {super.key, required this.child, this.width, this.padding, this.enableShadow = false,}); final double? width; final Widget child; final bool enableShadow; @@ -21,7 +21,7 @@ class MainBackgroundBouble extends StatelessWidget { offset: Offset(0, 0), ), ] - : null), + : null,), child: ClipRRect( borderRadius: BorderRadius.circular(12), child: Container( diff --git a/lib/features/diets/presentation/widgets/more_options.dart b/lib/features/diets/presentation/widgets/more_options.dart index ca5033b8..639fe8d2 100644 --- a/lib/features/diets/presentation/widgets/more_options.dart +++ b/lib/features/diets/presentation/widgets/more_options.dart @@ -7,6 +7,7 @@ import 'package:eatvio_app/theme/theme_helper.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:go_router/go_router.dart'; import 'package:share_plus/share_plus.dart'; class MoreOptions extends StatelessWidget { @@ -72,7 +73,9 @@ class MoreOptions extends StatelessWidget { child: CustomDivider(), ), GestureDetector( - onTap: () {}, + onTap: () { + context.push('complainingScreen'); + }, child: Row( children: [ Text( @@ -87,10 +90,10 @@ class MoreOptions extends StatelessWidget { SvgPicture.asset('assets/icons/complain.svg', width: 16, height: 20), ], ), - ) + ), ], ), ), - width: 272); + width: 272,); } } diff --git a/lib/features/diets/presentation/widgets/start_diet_bottom_sheet.dart b/lib/features/diets/presentation/widgets/start_diet_bottom_sheet.dart new file mode 100644 index 00000000..94e18e89 --- /dev/null +++ b/lib/features/diets/presentation/widgets/start_diet_bottom_sheet.dart @@ -0,0 +1,56 @@ +import 'package:eatvio_app/features/diets/presentation/widgets/calendar_widget.dart'; +import 'package:eatvio_app/generated/l10n.dart'; +import 'package:eatvio_app/theme/theme_helper.dart'; +import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:flutter/material.dart'; + +class StartDietBottomSheet extends StatelessWidget { + const StartDietBottomSheet({super.key}); + + @override + Widget build(BuildContext context) { + final s = S.of(context); + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 5), + Container( + height: 4, + width: 40, + decoration: BoxDecoration(color: appTheme.lightGrey, borderRadius: BorderRadius.circular(20)), + ), + SizedBox(height: 22), + Text(s.startDiet, + style: TextStyle( + color: appTheme.blueGray800, + fontSize: 20, + fontWeight: FontWeight.w600, + ),), + SizedBox(height: 12), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 25.0), + child: Text(s.choose_start_diet_date, + textAlign: TextAlign.center, + style: TextStyle( + color: appTheme.blueGray800, + fontSize: 16, + fontWeight: FontWeight.w500, + ),), + ), + CalendarWidget(), + Padding( + padding: EdgeInsets.only(left: 16, right: 16, top: 20, bottom: 25), + child: CustomOutlinedButton( + height: 52, + text: s.continue_, + buttonStyle: ButtonStyle( + textStyle: WidgetStatePropertyAll(TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w600)), + backgroundColor: WidgetStatePropertyAll(appTheme.blueA400), + side: WidgetStatePropertyAll(BorderSide.none), + ), + ), + ), + ], + ); + } +} diff --git a/lib/features/diets/presentation/widgets/type_badges.dart b/lib/features/diets/presentation/widgets/type_badges.dart index 3e828f3d..204d8c30 100644 --- a/lib/features/diets/presentation/widgets/type_badges.dart +++ b/lib/features/diets/presentation/widgets/type_badges.dart @@ -29,7 +29,7 @@ class _TypeBadgesState extends State { title: s.alko_type, description: s.alko_type_desc, ) - )); + ),); } if (widget.type.veg == true) { badgeSource.add(( @@ -40,7 +40,7 @@ class _TypeBadgesState extends State { title: s.vegan_type, description: s.vegan_type_desc, ) - )); + ),); } if (widget.type.corb == true) { badgeSource.add(( @@ -51,7 +51,7 @@ class _TypeBadgesState extends State { title: s.corb_type, description: s.corb_type_desc, ) - )); + ),); } if (widget.type.meat == true) { badgeSource.add(( @@ -62,7 +62,7 @@ class _TypeBadgesState extends State { title: s.meat_type, description: s.meat_type_desc, ) - )); + ),); } return Row( children: List.generate( @@ -117,7 +117,7 @@ class _TypeBadgesState extends State { } class _InfoOverlayEntry extends StatelessWidget { - const _InfoOverlayEntry({super.key, required this.title, required this.description, required this.assetPath, required this.onClose}); + const _InfoOverlayEntry({required this.title, required this.description, required this.assetPath, required this.onClose}); final String title; final String description; final assetPath; diff --git a/lib/features/diets/repositories/diets_repository.dart b/lib/features/diets/repositories/diets_repository.dart new file mode 100644 index 00000000..3e826995 --- /dev/null +++ b/lib/features/diets/repositories/diets_repository.dart @@ -0,0 +1,48 @@ +import 'package:eatvio_app/features/diets/services/diets_service.dart'; +import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; + +class DietsRepository { + DietsRepository({required this.dietsService}); + final DietsService dietsService; + + Future likeDiet(int id) async { + try { + await dietsService.likeDiet(id: id); + } catch (e) { + rethrow; + } + } + + Future unlikeDiet(int id) async { + try { + await dietsService.unlikeDiet(id: id); + } catch (e) { + rethrow; + } + } + + Future getDiet(int id) async { + try { + final diet = await dietsService.getDiet(id: id); + return diet; + } catch (e) { + rethrow; + } + } + + Future addToFavorite(int id) async { + try { + await dietsService.addToFavorite(id: id); + } catch (e) { + rethrow; + } + } + + Future removeFromFavorite(int id) async { + try { + await dietsService.removeFromFavorite(id: id); + } catch (e) { + rethrow; + } + } +} diff --git a/lib/features/diets/services/diets_service.dart b/lib/features/diets/services/diets_service.dart index 9130f39c..d5236e3d 100644 --- a/lib/features/diets/services/diets_service.dart +++ b/lib/features/diets/services/diets_service.dart @@ -1,12 +1,36 @@ import 'package:dio/dio.dart'; +import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; import 'package:retrofit/retrofit.dart'; part 'diets_service.g.dart'; @RestApi() abstract class DietsService { - factory DietsService(Dio dio, {String baseUrl}) = _DietsService; + @POST('/api/diets/{id}/like') + Future likeDiet({ + @Path() required int id, + }); -} \ No newline at end of file + @POST('/api/diets/{id}/add_to_favorite') + Future addToFavorite({ + @Path() required int id, + }); + + @POST('/api/diets/{id}/remove_from_favorite') + Future removeFromFavorite({ + @Path() required int id, + }); + + @POST('/api/diets/{id}/unliked') + Future unlikeDiet({ + @Path() required int id, + }); + + @GET('/api/diets/show/{id}') + Future getDiet({ + @Path() required int id, + }); + +} diff --git a/lib/features/diets/services/diets_service.g.dart b/lib/features/diets/services/diets_service.g.dart index aeef4f7e..67718920 100644 --- a/lib/features/diets/services/diets_service.g.dart +++ b/lib/features/diets/services/diets_service.g.dart @@ -21,6 +21,139 @@ class _DietsService implements DietsService { final ParseErrorLogger? errorLogger; + @override + Future likeDiet({required int id}) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _options = _setStreamType(Options( + method: 'POST', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/api/diets/${id}/like', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + ))); + await _dio.fetch(_options); + } + + @override + Future addToFavorite({required int id}) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _options = _setStreamType(Options( + method: 'POST', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/api/diets/${id}/add_to_favorite', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + ))); + await _dio.fetch(_options); + } + + @override + Future removeFromFavorite({required int id}) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _options = _setStreamType(Options( + method: 'POST', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/api/diets/${id}/remove_from_favorite', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + ))); + await _dio.fetch(_options); + } + + @override + Future unlikeDiet({required int id}) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _options = _setStreamType(Options( + method: 'POST', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/api/diets/${id}/unliked', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + ))); + await _dio.fetch(_options); + } + + @override + Future getDiet({required int id}) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _options = _setStreamType(Options( + method: 'GET', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/api/diets/show/${id}', + 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; + } + RequestOptions _setStreamType(RequestOptions requestOptions) { if (T != dynamic && !(requestOptions.responseType == ResponseType.bytes || diff --git a/lib/features/feed/models/diets_pagination_model.dart b/lib/features/feed/models/diets_pagination_model.dart index dd7f4491..99f43194 100644 --- a/lib/features/feed/models/diets_pagination_model.dart +++ b/lib/features/feed/models/diets_pagination_model.dart @@ -31,6 +31,8 @@ class Diet with _$Diet { @JsonKey(name: "total_likes") required int totalLikes, @JsonKey(name: "total_views") required int totalViews, @JsonKey(name: "total_comments") required int totalComments, + @JsonKey(name: "was_liked_by_me") required bool wasLikedByMe, + @JsonKey(name: "is_favorite") required bool isFavorite, }) = _Diet; factory Diet.fromJson(Map json) => _$DietFromJson(json); diff --git a/lib/features/feed/models/diets_pagination_model.freezed.dart b/lib/features/feed/models/diets_pagination_model.freezed.dart index 15b651f3..0bbb9b25 100644 --- a/lib/features/feed/models/diets_pagination_model.freezed.dart +++ b/lib/features/feed/models/diets_pagination_model.freezed.dart @@ -284,6 +284,10 @@ mixin _$Diet { int get totalViews => throw _privateConstructorUsedError; @JsonKey(name: "total_comments") int get totalComments => throw _privateConstructorUsedError; + @JsonKey(name: "was_liked_by_me") + bool get wasLikedByMe => throw _privateConstructorUsedError; + @JsonKey(name: "is_favorite") + bool get isFavorite => throw _privateConstructorUsedError; /// Serializes this Diet to a JSON map. Map toJson() => throw _privateConstructorUsedError; @@ -312,7 +316,9 @@ abstract class $DietCopyWith<$Res> { @JsonKey(name: "author") Author author, @JsonKey(name: "total_likes") int totalLikes, @JsonKey(name: "total_views") int totalViews, - @JsonKey(name: "total_comments") int totalComments}); + @JsonKey(name: "total_comments") int totalComments, + @JsonKey(name: "was_liked_by_me") bool wasLikedByMe, + @JsonKey(name: "is_favorite") bool isFavorite}); $DietTypeCopyWith<$Res> get type; $AuthorCopyWith<$Res> get author; @@ -345,6 +351,8 @@ class _$DietCopyWithImpl<$Res, $Val extends Diet> Object? totalLikes = null, Object? totalViews = null, Object? totalComments = null, + Object? wasLikedByMe = null, + Object? isFavorite = null, }) { return _then(_value.copyWith( id: null == id @@ -395,6 +403,14 @@ class _$DietCopyWithImpl<$Res, $Val extends Diet> ? _value.totalComments : totalComments // ignore: cast_nullable_to_non_nullable as int, + wasLikedByMe: null == wasLikedByMe + ? _value.wasLikedByMe + : wasLikedByMe // ignore: cast_nullable_to_non_nullable + as bool, + isFavorite: null == isFavorite + ? _value.isFavorite + : isFavorite // ignore: cast_nullable_to_non_nullable + as bool, ) as $Val); } @@ -439,7 +455,9 @@ abstract class _$$DietImplCopyWith<$Res> implements $DietCopyWith<$Res> { @JsonKey(name: "author") Author author, @JsonKey(name: "total_likes") int totalLikes, @JsonKey(name: "total_views") int totalViews, - @JsonKey(name: "total_comments") int totalComments}); + @JsonKey(name: "total_comments") int totalComments, + @JsonKey(name: "was_liked_by_me") bool wasLikedByMe, + @JsonKey(name: "is_favorite") bool isFavorite}); @override $DietTypeCopyWith<$Res> get type; @@ -471,6 +489,8 @@ class __$$DietImplCopyWithImpl<$Res> Object? totalLikes = null, Object? totalViews = null, Object? totalComments = null, + Object? wasLikedByMe = null, + Object? isFavorite = null, }) { return _then(_$DietImpl( id: null == id @@ -521,6 +541,14 @@ class __$$DietImplCopyWithImpl<$Res> ? _value.totalComments : totalComments // ignore: cast_nullable_to_non_nullable as int, + wasLikedByMe: null == wasLikedByMe + ? _value.wasLikedByMe + : wasLikedByMe // ignore: cast_nullable_to_non_nullable + as bool, + isFavorite: null == isFavorite + ? _value.isFavorite + : isFavorite // ignore: cast_nullable_to_non_nullable + as bool, )); } } @@ -541,7 +569,9 @@ class _$DietImpl implements _Diet { @JsonKey(name: "author") required this.author, @JsonKey(name: "total_likes") required this.totalLikes, @JsonKey(name: "total_views") required this.totalViews, - @JsonKey(name: "total_comments") required this.totalComments}) + @JsonKey(name: "total_comments") required this.totalComments, + @JsonKey(name: "was_liked_by_me") required this.wasLikedByMe, + @JsonKey(name: "is_favorite") required this.isFavorite}) : _dailySchedule = dailySchedule; factory _$DietImpl.fromJson(Map json) => @@ -589,10 +619,16 @@ class _$DietImpl implements _Diet { @override @JsonKey(name: "total_comments") final int totalComments; + @override + @JsonKey(name: "was_liked_by_me") + final bool wasLikedByMe; + @override + @JsonKey(name: "is_favorite") + final bool isFavorite; @override String toString() { - return 'Diet(id: $id, name: $name, image: $image, duration: $duration, state: $state, type: $type, details: $details, dailySchedule: $dailySchedule, author: $author, totalLikes: $totalLikes, totalViews: $totalViews, totalComments: $totalComments)'; + return 'Diet(id: $id, name: $name, image: $image, duration: $duration, state: $state, type: $type, details: $details, dailySchedule: $dailySchedule, author: $author, totalLikes: $totalLikes, totalViews: $totalViews, totalComments: $totalComments, wasLikedByMe: $wasLikedByMe, isFavorite: $isFavorite)'; } @override @@ -616,7 +652,11 @@ class _$DietImpl implements _Diet { (identical(other.totalViews, totalViews) || other.totalViews == totalViews) && (identical(other.totalComments, totalComments) || - other.totalComments == totalComments)); + other.totalComments == totalComments) && + (identical(other.wasLikedByMe, wasLikedByMe) || + other.wasLikedByMe == wasLikedByMe) && + (identical(other.isFavorite, isFavorite) || + other.isFavorite == isFavorite)); } @JsonKey(includeFromJson: false, includeToJson: false) @@ -634,7 +674,9 @@ class _$DietImpl implements _Diet { author, totalLikes, totalViews, - totalComments); + totalComments, + wasLikedByMe, + isFavorite); /// Create a copy of Diet /// with the given fields replaced by the non-null parameter values. @@ -666,7 +708,9 @@ abstract class _Diet implements Diet { @JsonKey(name: "author") required final Author author, @JsonKey(name: "total_likes") required final int totalLikes, @JsonKey(name: "total_views") required final int totalViews, - @JsonKey(name: "total_comments") required final int totalComments}) = + @JsonKey(name: "total_comments") required final int totalComments, + @JsonKey(name: "was_liked_by_me") required final bool wasLikedByMe, + @JsonKey(name: "is_favorite") required final bool isFavorite}) = _$DietImpl; factory _Diet.fromJson(Map json) = _$DietImpl.fromJson; @@ -707,6 +751,12 @@ abstract class _Diet implements Diet { @override @JsonKey(name: "total_comments") int get totalComments; + @override + @JsonKey(name: "was_liked_by_me") + bool get wasLikedByMe; + @override + @JsonKey(name: "is_favorite") + bool get isFavorite; /// Create a copy of Diet /// with the given fields replaced by the non-null parameter values. diff --git a/lib/features/feed/models/diets_pagination_model.g.dart b/lib/features/feed/models/diets_pagination_model.g.dart index 7fcab8cd..c79e3a26 100644 --- a/lib/features/feed/models/diets_pagination_model.g.dart +++ b/lib/features/feed/models/diets_pagination_model.g.dart @@ -43,6 +43,8 @@ _$DietImpl _$$DietImplFromJson(Map json) => _$DietImpl( totalLikes: (json['total_likes'] as num).toInt(), totalViews: (json['total_views'] as num).toInt(), totalComments: (json['total_comments'] as num).toInt(), + wasLikedByMe: json['was_liked_by_me'] as bool, + isFavorite: json['is_favorite'] as bool, ); Map _$$DietImplToJson(_$DietImpl instance) => @@ -59,6 +61,8 @@ Map _$$DietImplToJson(_$DietImpl instance) => 'total_likes': instance.totalLikes, 'total_views': instance.totalViews, 'total_comments': instance.totalComments, + 'was_liked_by_me': instance.wasLikedByMe, + 'is_favorite': instance.isFavorite, }; _$AuthorImpl _$$AuthorImplFromJson(Map json) => _$AuthorImpl( 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 fa44eafb..ab9e4396 100644 --- a/lib/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart +++ b/lib/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart @@ -23,11 +23,11 @@ class DietsCubit extends Cubit { emit(DietsState.loaded( dietsList: dietsPagination.data, isLoading: isLoading, - )); + ),); } catch (e) { emit(DietsState.error( errorMessage: e.toString(), - )); + ),); } } diff --git a/lib/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart b/lib/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart index 93bcf399..5147445a 100644 --- a/lib/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart +++ b/lib/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart @@ -34,7 +34,7 @@ class RecipesCubit extends Cubit { selectedTags: _selectedTags, selectedTagsCounter: _selectedTags.length, isLoading: isLoading, - )); + ),); } catch (e) { emit(RecipesState.error(errorMessage: e.toString())); } @@ -61,7 +61,7 @@ class RecipesCubit extends Cubit { ...recipesList, ], isLoading: isLoading, - )); + ),); } } catch (e) { emit(RecipesState.error(errorMessage: e.toString())); @@ -74,6 +74,6 @@ class RecipesCubit extends Cubit { emit((state as RecipesStateLoaded).copyWith( selectedTags: _selectedTags, selectedTagsCounter: _selectedTags.length, - )); + ),); } } diff --git a/lib/features/profile/presentation/bloc/profile_cubit/profile_cubit.dart b/lib/features/profile/presentation/bloc/profile_cubit/profile_cubit.dart index 409225e1..bdd4e0f4 100644 --- a/lib/features/profile/presentation/bloc/profile_cubit/profile_cubit.dart +++ b/lib/features/profile/presentation/bloc/profile_cubit/profile_cubit.dart @@ -19,7 +19,7 @@ class ProfileCubit extends Cubit { profile: await profileRepository.getProfileBySlug(slug), profileDetails: await profileRepository.getMyProfileDetails(), blogPosts: await profileRepository.getBlogPostsByAuthorSlug(slug: slug), - )); + ),); } catch (e) { emit(ProfileState.error(errorMessage: e.toString())); } @@ -37,7 +37,7 @@ class ProfileCubit extends Cubit { blogPosts: await profileRepository.getBlogPostsByAuthorSlug(slug: profile.slug), weightPoints: await profileRepository.getWeight(period: period), circumferencePoints: await profileRepository.getCircumferences(period: period), - )); + ),); } catch (e) { emit(ProfileState.error(errorMessage: e.toString())); } diff --git a/lib/features/recipes/presentation/bloc/recipe_create_cubit.dart b/lib/features/recipes/presentation/bloc/recipe_create_cubit.dart index aad1afb4..dbd10b07 100644 --- a/lib/features/recipes/presentation/bloc/recipe_create_cubit.dart +++ b/lib/features/recipes/presentation/bloc/recipe_create_cubit.dart @@ -88,7 +88,7 @@ class RecipeCreateCubit extends Cubit { statuses: statuses, selectedType: selectedType, selectedCookingTime: selectedCookingTime, - selectedStatus: selectedStatus)); + selectedStatus: selectedStatus,),); } catch (e) { emit(RecipeCreateState.error(errorMessage: e.toString())); } @@ -136,7 +136,7 @@ class RecipeCreateCubit extends Cubit { statuses: statuses, selectedType: types[0], selectedCookingTime: cookingTimes[0], - selectedStatus: statuses[0])); + selectedStatus: statuses[0],),); } catch (e) { emit(RecipeCreateState.error(errorMessage: e.toString())); } diff --git a/lib/features/recipes/presentation/pages/recipe_create_screen.dart b/lib/features/recipes/presentation/pages/recipe_create_screen.dart index 2398edc9..669caca3 100644 --- a/lib/features/recipes/presentation/pages/recipe_create_screen.dart +++ b/lib/features/recipes/presentation/pages/recipe_create_screen.dart @@ -238,7 +238,7 @@ class RecipeCreateScreen extends StatelessWidget { inactiveTrackColor: Colors.grey.shade300, ), Text('шт'), - ]), + ],), SizedBox(height: 8), Container( height: 48, @@ -340,7 +340,7 @@ class RecipeCreateScreen extends StatelessWidget { ), ), ], - )), + ),), ], ), ), @@ -381,7 +381,7 @@ class RecipeCreateScreen extends StatelessWidget { ], ), ) - : Image.file(File(state.stepImages[stepNumber]!.path), height: 150, fit: BoxFit.cover)), + : Image.file(File(state.stepImages[stepNumber]!.path), height: 150, fit: BoxFit.cover),), SizedBox(height: 16), CustomTextFormField( hintText: 'Введите описание шага', @@ -495,7 +495,7 @@ class RecipeCreateScreen extends StatelessWidget { steps.add(step.Step( description: state.stepControllers[i].text, image: state.stepImages[i]?.path, - )); + ),); } } diff --git a/lib/features/recipes/presentation/pages/recipe_edit_screen.dart b/lib/features/recipes/presentation/pages/recipe_edit_screen.dart index d1f1c7fc..174c0e99 100644 --- a/lib/features/recipes/presentation/pages/recipe_edit_screen.dart +++ b/lib/features/recipes/presentation/pages/recipe_edit_screen.dart @@ -247,7 +247,7 @@ class RecipeEditScreen extends StatelessWidget { inactiveTrackColor: Colors.grey.shade300, ), Text('шт'), - ]), + ],), SizedBox(height: 8), Container( height: 48, @@ -267,7 +267,7 @@ class RecipeEditScreen extends StatelessWidget { onPressed: () => context.read().addIngredient(new Ingredient( name: state.productNameController.text, portion: state.ingredientController.text, - unit: state.ingredientAsItems ? 'pcs' : 'gr'))), + unit: state.ingredientAsItems ? 'pcs' : 'gr',),),), ), SizedBox(height: 24), Text('Описание рецепта'), @@ -345,7 +345,7 @@ class RecipeEditScreen extends StatelessWidget { ), ), ], - )), + ),), ], ), ), @@ -390,7 +390,7 @@ class RecipeEditScreen extends StatelessWidget { baseUrl + '/storage/' + state.stepImages[stepNumber]!.path, height: 150, fit: BoxFit.cover, - )), + ),), SizedBox(height: 16), CustomTextFormField( hintText: 'Введите описание шага', @@ -504,7 +504,7 @@ class RecipeEditScreen extends StatelessWidget { steps.add(step.Step( description: state.stepControllers[i].text, image: state.stepImages[i]?.path, - )); + ),); } } diff --git a/lib/features/registration/presentation/pages/city_of_living_screen.dart b/lib/features/registration/presentation/pages/city_of_living_screen.dart index f21f0659..bae25803 100644 --- a/lib/features/registration/presentation/pages/city_of_living_screen.dart +++ b/lib/features/registration/presentation/pages/city_of_living_screen.dart @@ -88,7 +88,7 @@ class _CityOfLivingScreenState extends State { textStyle: TextStyle( fontSize: 16, color: Colors.black, - )), + ),), itemBuilder: (BuildContext context, String item) { return Padding( padding: const EdgeInsets.all(8.0), @@ -111,8 +111,7 @@ class _CityOfLivingScreenState extends State { suggestionsCallback: (query) async { if (query.length >= 3) { final registrationCubit = context.read(); - final qwe = (await registrationCubit.getLocationsByQuery(query)); - return qwe; + return (await registrationCubit.getLocationsByQuery(query)); } return null; }, @@ -130,11 +129,9 @@ class _CityOfLivingScreenState extends State { if (locationData != null) { final List locations = await context .read() - .getLocationsByCoordinates( - locationData.latitude.toString(), locationData.longitude.toString()); + .getLocationsByCoordinates(locationData.latitude.toString(), locationData.longitude.toString()); final registrationCubit = context.read(); - registrationCubit - .updateSheet(registrationCubit.state.sheet.copyWith(location: locations.first)); + registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(location: locations.first)); setState(() { cityController.text = locations.first; suggestionsController.suggestions = locations; diff --git a/lib/features/settings/presentation/bloc/settings_cubit/settings_cubit.dart b/lib/features/settings/presentation/bloc/settings_cubit/settings_cubit.dart index 811a4bbf..f0a388a4 100644 --- a/lib/features/settings/presentation/bloc/settings_cubit/settings_cubit.dart +++ b/lib/features/settings/presentation/bloc/settings_cubit/settings_cubit.dart @@ -20,7 +20,7 @@ class SettingsCubit extends Cubit { profileSettings: await settingsRepository.getProfileSettings(), profileDetails: await profileRepository.getMyProfileDetails(), profile: await profileRepository.getMyProfile(), - )); + ),); } catch (e) { emit(SettingsState.error(errorMessage: e.toString())); } diff --git a/lib/generated/intl/messages_all.dart b/lib/generated/intl/messages_all.dart index 203415cc..b6510a8a 100644 --- a/lib/generated/intl/messages_all.dart +++ b/lib/generated/intl/messages_all.dart @@ -36,7 +36,7 @@ MessageLookupByLibrary? _findExact(String localeName) { Future initializeMessages(String localeName) { var availableLocale = Intl.verifiedLocale( localeName, (locale) => _deferredLibraries[locale] != null, - onFailure: (_) => null); + onFailure: (_) => null,); if (availableLocale == null) { return new SynchronousFuture(false); } diff --git a/lib/generated/intl/messages_en.dart b/lib/generated/intl/messages_en.dart index 99f95108..42f0d564 100644 --- a/lib/generated/intl/messages_en.dart +++ b/lib/generated/intl/messages_en.dart @@ -32,7 +32,7 @@ class MessageLookup extends MessageLookupByLibrary { "admin": MessageLookupByLibrary.simpleMessage("Админ"), "alko_type": MessageLookupByLibrary.simpleMessage("Алкоголь"), "alko_type_desc": MessageLookupByLibrary.simpleMessage( - "С некоторыми видами диет можно употреблять алкоголь в умеренных количествах. Рекомендуется совмещать вместе с низкокалорийными закусками."), + "С некоторыми видами диет можно употреблять алкоголь в умеренных количествах. Рекомендуется совмещать вместе с низкокалорийными закусками.",), "allergies_presence": MessageLookupByLibrary.simpleMessage("Наличие аллергии"), "another_form_of_comment": @@ -42,7 +42,7 @@ class MessageLookup extends MessageLookupByLibrary { "archived": MessageLookupByLibrary.simpleMessage("В архиве"), "authentificate": MessageLookupByLibrary.simpleMessage("Войти"), "average_pressure": MessageLookupByLibrary.simpleMessage( - "Средние показатели давления:"), + "Средние показатели давления:",), "bodymass_chart": MessageLookupByLibrary.simpleMessage("График ИМТ"), "calories": MessageLookupByLibrary.simpleMessage("Калории"), "carbohydrates": MessageLookupByLibrary.simpleMessage("Углеводы"), @@ -50,10 +50,12 @@ class MessageLookup extends MessageLookupByLibrary { "chest": MessageLookupByLibrary.simpleMessage("Грудь"), "chest_circumference": MessageLookupByLibrary.simpleMessage("Обхват груди"), + "choose_start_diet_date": MessageLookupByLibrary.simpleMessage( + "Выберите дату старты диеты. Она отобразиться у Вас в дневнике",), "circumference_empty": MessageLookupByLibrary.simpleMessage( - "Все замеры обязательны к заполнению"), + "Все замеры обязательны к заполнению",), "circumference_is_not_a_number": MessageLookupByLibrary.simpleMessage( - "Все замеры должны быть числами"), + "Все замеры должны быть числами",), "circumferences_chart": MessageLookupByLibrary.simpleMessage("График обхватов"), "city": MessageLookupByLibrary.simpleMessage("Город"), @@ -64,10 +66,11 @@ class MessageLookup extends MessageLookupByLibrary { "comments_plural": MessageLookupByLibrary.simpleMessage("комментариев"), "complain": MessageLookupByLibrary.simpleMessage("Пожаловаться"), "continueButton": MessageLookupByLibrary.simpleMessage("Продолжить"), + "continue_": MessageLookupByLibrary.simpleMessage("Продолжить"), "copy_link": MessageLookupByLibrary.simpleMessage("Скопировать ссылку"), "corb_type": MessageLookupByLibrary.simpleMessage("Мучное"), "corb_type_desc": MessageLookupByLibrary.simpleMessage( - "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы."), + "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы.",), "country": MessageLookupByLibrary.simpleMessage("Страна"), "date_of_birth": MessageLookupByLibrary.simpleMessage("Дата рождения"), "day": MessageLookupByLibrary.simpleMessage("День"), @@ -80,17 +83,17 @@ class MessageLookup extends MessageLookupByLibrary { "do_you_have_hypotension_tendency": MessageLookupByLibrary.simpleMessage("Есть ли у вас гипотония?"), "do_you_take_pills": MessageLookupByLibrary.simpleMessage( - "Принимаете ли вы лекарства или бады?"), + "Принимаете ли вы лекарства или бады?",), "down_pressure": MessageLookupByLibrary.simpleMessage("Нижние показатели давления:"), "draft": MessageLookupByLibrary.simpleMessage("Черновик"), "email": MessageLookupByLibrary.simpleMessage("Элетронная почта"), "email_empty": MessageLookupByLibrary.simpleMessage( - "Необходимо ввести адрес электронной почты"), + "Необходимо ввести адрес электронной почты",), "email_invalid": MessageLookupByLibrary.simpleMessage( - "Некорректный адрес электронной почты"), + "Некорректный адрес электронной почты",), "enter_additional_information": MessageLookupByLibrary.simpleMessage( - "Введите любую дополнительную информацию на своё усмотрение:"), + "Введите любую дополнительную информацию на своё усмотрение:",), "enter_information": MessageLookupByLibrary.simpleMessage("Введите информацию..."), "exit": MessageLookupByLibrary.simpleMessage("Выйти"), @@ -99,16 +102,16 @@ class MessageLookup extends MessageLookupByLibrary { "favorite_foods": MessageLookupByLibrary.simpleMessage("Любимые продукты"), "favorite_unfavorite_foods": MessageLookupByLibrary.simpleMessage( - "Ваши любимые/нелюбимые продукты питания?"), + "Ваши любимые/нелюбимые продукты питания?",), "female": MessageLookupByLibrary.simpleMessage("Женский"), "fill_in_information": MessageLookupByLibrary.simpleMessage("Заполните информацию:"), "finish": MessageLookupByLibrary.simpleMessage("Завершить"), "first_name": MessageLookupByLibrary.simpleMessage("Имя"), "first_name_empty": MessageLookupByLibrary.simpleMessage( - "Имя обязательно для заполнения"), + "Имя обязательно для заполнения",), "first_name_short": MessageLookupByLibrary.simpleMessage( - "В имени должен быть минимум 1 символ"), + "В имени должен быть минимум 1 символ",), "gr": MessageLookupByLibrary.simpleMessage("гр"), "grams": MessageLookupByLibrary.simpleMessage("гр"), "height_measurements": @@ -123,9 +126,9 @@ class MessageLookup extends MessageLookupByLibrary { "language": MessageLookupByLibrary.simpleMessage("Язык"), "last_name": MessageLookupByLibrary.simpleMessage("Фамилия"), "last_name_empty": MessageLookupByLibrary.simpleMessage( - "Фамилия обязательна для заполнения"), + "Фамилия обязательна для заполнения",), "last_name_short": MessageLookupByLibrary.simpleMessage( - "В фамилии должен быть минимум 6 символов"), + "В фамилии должен быть минимум 6 символов",), "lbl_english": MessageLookupByLibrary.simpleMessage("English"), "link_was_copied": MessageLookupByLibrary.simpleMessage("Ссылка успешно скопирована"), @@ -134,7 +137,7 @@ class MessageLookup extends MessageLookupByLibrary { "meal": MessageLookupByLibrary.simpleMessage("Приём пищи"), "meat_type": MessageLookupByLibrary.simpleMessage("С мясом"), "meat_type_desc": MessageLookupByLibrary.simpleMessage( - "Диета с мясом полезная и сбалансированная. Включает в себя нежирное мясо: курицу, индейку, кролика или говядину. В сочетании с овощами получаете все необходимые витамины и минералы. Не забывайте о порциях и старайтесь есть медленно, прислушиваясь к своему организму."), + "Диета с мясом полезная и сбалансированная. Включает в себя нежирное мясо: курицу, индейку, кролика или говядину. В сочетании с овощами получаете все необходимые витамины и минералы. Не забывайте о порциях и старайтесь есть медленно, прислушиваясь к своему организму.",), "milliliter": MessageLookupByLibrary.simpleMessage("мл"), "msg_network_err": MessageLookupByLibrary.simpleMessage("Сетевая ошибка!"), @@ -143,9 +146,9 @@ class MessageLookup extends MessageLookupByLibrary { "my_blog": MessageLookupByLibrary.simpleMessage("Мой блог"), "my_settings": MessageLookupByLibrary.simpleMessage("Мои настройки"), "name_empty": MessageLookupByLibrary.simpleMessage( - "Имя пользователя обязательно для заполнения"), + "Имя пользователя обязательно для заполнения",), "name_short": MessageLookupByLibrary.simpleMessage( - "В имени пользователя должно быть минимум 6 символов"), + "В имени пользователя должно быть минимум 6 символов",), "no": MessageLookupByLibrary.simpleMessage("Нет"), "no_account": MessageLookupByLibrary.simpleMessage("У меня нет аккаунта"), @@ -155,9 +158,9 @@ class MessageLookup extends MessageLookupByLibrary { "password_confirmation_mismatch": MessageLookupByLibrary.simpleMessage("Пароли не совпадают"), "password_empty": MessageLookupByLibrary.simpleMessage( - "Пароль обязателен для заполнения"), + "Пароль обязателен для заполнения",), "password_short": MessageLookupByLibrary.simpleMessage( - "В пароле должно быть минимум 6 символов"), + "В пароле должно быть минимум 6 символов",), "pcs": MessageLookupByLibrary.simpleMessage("шт"), "place_of_living": MessageLookupByLibrary.simpleMessage("Место проживания"), @@ -166,9 +169,9 @@ class MessageLookup extends MessageLookupByLibrary { "preferred_language": MessageLookupByLibrary.simpleMessage("Предпочитаемый язык общения"), "pressure_empty": MessageLookupByLibrary.simpleMessage( - "Все показатели давления обязательны к заполнению"), + "Все показатели давления обязательны к заполнению",), "pressure_is_not_a_number": MessageLookupByLibrary.simpleMessage( - "Все показатели давления должны быть числами"), + "Все показатели давления должны быть числами",), "profile": MessageLookupByLibrary.simpleMessage("Профиль"), "proteins": MessageLookupByLibrary.simpleMessage("Белки"), "save": MessageLookupByLibrary.simpleMessage("Сохранить"), @@ -177,11 +180,11 @@ class MessageLookup extends MessageLookupByLibrary { "skip": MessageLookupByLibrary.simpleMessage("Пропустить"), "startDiet": MessageLookupByLibrary.simpleMessage("Начать диету"), "tell_your_schedule": MessageLookupByLibrary.simpleMessage( - "Расскажите в свободной форме о том как просыпаетесь, когда едите, когда ложитесь спать:"), + "Расскажите в свободной форме о том как просыпаетесь, когда едите, когда ложитесь спать:",), "unfavorite_foods": MessageLookupByLibrary.simpleMessage("Нелюбимые продукты"), "up_pressure": MessageLookupByLibrary.simpleMessage( - "Верхние показатели давления:"), + "Верхние показатели давления:",), "user_authorization": MessageLookupByLibrary.simpleMessage("Аутентификация"), "user_registration": @@ -189,7 +192,7 @@ class MessageLookup extends MessageLookupByLibrary { "username": MessageLookupByLibrary.simpleMessage("Имя пользователя"), "vegan_type": MessageLookupByLibrary.simpleMessage("Вегетарианская"), "vegan_type_desc": MessageLookupByLibrary.simpleMessage( - "Диета основана на потреблении растительной пищи и отказе от продуктов животного происхождения. Такой тип питания может быть разнообразным и вкусным, а также полезным для здоровья."), + "Диета основана на потреблении растительной пищи и отказе от продуктов животного происхождения. Такой тип питания может быть разнообразным и вкусным, а также полезным для здоровья.",), "waist": MessageLookupByLibrary.simpleMessage("Талия"), "waist_circumference": MessageLookupByLibrary.simpleMessage("Обхват талии"), @@ -200,7 +203,7 @@ class MessageLookup extends MessageLookupByLibrary { "what_is_your_name": MessageLookupByLibrary.simpleMessage("Как вас зовут?"), "wrong_credentials": MessageLookupByLibrary.simpleMessage( - "Неверные данные пользователя"), + "Неверные данные пользователя",), "your_blood_pressure": MessageLookupByLibrary.simpleMessage("Ваше артериальное давление?"), "your_favorite_sports": @@ -208,6 +211,6 @@ class MessageLookup extends MessageLookupByLibrary { "your_gender": MessageLookupByLibrary.simpleMessage("Ваш пол?"), "your_height": MessageLookupByLibrary.simpleMessage("Ваш рост:"), "your_schedule": MessageLookupByLibrary.simpleMessage("Ваш режим дня?"), - "your_weight": MessageLookupByLibrary.simpleMessage("Ваш вес:") + "your_weight": MessageLookupByLibrary.simpleMessage("Ваш вес:"), }; } diff --git a/lib/generated/l10n.dart b/lib/generated/l10n.dart index 52cfc313..2cc942c5 100644 --- a/lib/generated/l10n.dart +++ b/lib/generated/l10n.dart @@ -19,7 +19,7 @@ class S { static S get current { assert(_current != null, - 'No instance of S was loaded. Try to initialize the S delegate before accessing S.current.'); + 'No instance of S was loaded. Try to initialize the S delegate before accessing S.current.',); return _current!; } @@ -42,7 +42,7 @@ class S { static S of(BuildContext context) { final instance = S.maybeOf(context); assert(instance != null, - 'No instance of S present in the widget tree. Did you add S.delegate in localizationsDelegates?'); + 'No instance of S present in the widget tree. Did you add S.delegate in localizationsDelegates?',); return instance!; } @@ -1349,6 +1349,26 @@ class S { args: [], ); } + + /// `Выберите дату старты диеты. Она отобразиться у Вас в дневнике` + String get choose_start_diet_date { + return Intl.message( + 'Выберите дату старты диеты. Она отобразиться у Вас в дневнике', + name: 'choose_start_diet_date', + desc: '', + args: [], + ); + } + + /// `Продолжить` + String get continue_ { + return Intl.message( + 'Продолжить', + name: 'continue_', + desc: '', + args: [], + ); + } } class AppLocalizationDelegate extends LocalizationsDelegate { diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index bb9f8e9d..0d0d086a 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -128,5 +128,7 @@ "fats": "Жиры", "carbohydrates": "Углеводы", "answer": "Ответить", - "link_was_copied": "Ссылка успешно скопирована" + "link_was_copied": "Ссылка успешно скопирована", + "choose_start_diet_date": "Выберите дату старты диеты. Она отобразиться у Вас в дневнике", + "continue_": "Продолжить" } diff --git a/lib/locator_service.dart b/lib/locator_service.dart index 43d3082d..c459e3fd 100644 --- a/lib/locator_service.dart +++ b/lib/locator_service.dart @@ -17,6 +17,9 @@ import 'package:eatvio_app/features/consultant/become_consultant/services/consul import 'package:eatvio_app/features/diary/presentation/bloc/diary_cubit.dart'; import 'package:eatvio_app/features/diary/repositories/diary_repository.dart'; import 'package:eatvio_app/features/diary/services/diary_service.dart'; +import 'package:eatvio_app/features/diets/presentation/bloc/about_diet_cubit.dart'; +import 'package:eatvio_app/features/diets/repositories/diets_repository.dart'; +import 'package:eatvio_app/features/diets/services/diets_service.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/comments_cubit/comments_cubit.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart'; @@ -66,6 +69,7 @@ Future init() async { sl.registerFactory(() => SettingsCubit(profileRepository: sl(), settingsRepository: sl())); sl.registerFactory(() => RegisterConsultantCubit(consultantRepository: sl())); sl.registerFactory(() => DiaryCubit(diaryRepository: sl(), glossaryRepository: sl())); + sl.registerFactory(() => AboutDietCubit(dietsRepository: sl())); // Repository sl.registerLazySingleton(() => ChatRepository(chatService: sl())); @@ -79,6 +83,7 @@ Future init() async { sl.registerLazySingleton(() => ConsultantRepository(consultantService: sl())); sl.registerLazySingleton(() => DiaryRepository(diaryService: sl())); sl.registerLazySingleton(() => GlossaryRepository(glossaryService: sl())); + sl.registerLazySingleton(() => DietsRepository(dietsService: sl())); // Services sl.registerLazySingleton(() => ChatService(sl())); @@ -92,7 +97,9 @@ Future init() async { sl.registerLazySingleton(() => ConsultantService(sl())); sl.registerLazySingleton(() => DiaryService(sl())); sl.registerLazySingleton(() => GlossaryService(sl())); - + sl.registerLazySingleton(() => DietsService(sl())); + + // External sl.registerLazySingleton( () => Dio( diff --git a/lib/old/users/subscribers_screen/bloc/subscribers_bloc.dart b/lib/old/users/subscribers_screen/bloc/subscribers_bloc.dart index aec562b0..ef52c077 100644 --- a/lib/old/users/subscribers_screen/bloc/subscribers_bloc.dart +++ b/lib/old/users/subscribers_screen/bloc/subscribers_bloc.dart @@ -44,11 +44,11 @@ class SubscribersBloc extends Bloc { emit((currentState).copyWith( subscribers: data, myProfileModelObj: currentState.myProfileModelObj, - )); + ),); } else { emit(SubscribersLoadedState( subscribers: data, - )); + ),); } } else { // Один или несколько ключевых полей отсутствуют, обрабатываем ошибку diff --git a/lib/old/users/subscribers_screen/subscribers_screen.dart b/lib/old/users/subscribers_screen/subscribers_screen.dart index adef5d67..efdc730c 100644 --- a/lib/old/users/subscribers_screen/subscribers_screen.dart +++ b/lib/old/users/subscribers_screen/subscribers_screen.dart @@ -20,7 +20,7 @@ class SubscribersScreen extends StatelessWidget { static Widget builder(BuildContext context) { return BlocProvider( create: (context) => SubscribersBloc(SubscribersState(myProfileModelObj: SubscribersModel()))..add(SubscribersInitialEvent()), - child: SubscribersScreen()); + child: SubscribersScreen(),); } Widget build(BuildContext context) { @@ -93,7 +93,7 @@ class SubscribersScreen extends StatelessWidget { Padding( padding: const EdgeInsets.only(right: 20.0), child: GestureDetector(child: Icon(Icons.create_outlined)), - ) + ), ], ), ), @@ -149,7 +149,7 @@ class SubscribersScreen extends StatelessWidget { ), ), ], - ) + ), ], ), ), @@ -212,6 +212,6 @@ class SubscribersScreen extends StatelessWidget { ), subtitle: Text(subscriber?['description'] ?? ''), trailing: GestureDetector(child: Icon(Icons.edit)), - )); + ),); } } diff --git a/lib/theme/theme_helper.dart b/lib/theme/theme_helper.dart index 0841f960..d0a8635e 100644 --- a/lib/theme/theme_helper.dart +++ b/lib/theme/theme_helper.dart @@ -170,6 +170,8 @@ class PrimaryColors { Color get dividerColor => Color(0xFFF1F2F6); Color get grey => Color(0xFF6D6F71); + + Color get lightGrey => Color(0xFFCECECE); } PrimaryColors get appTheme => ThemeHelper().themeColor();