From 937d7cded544f3f2ead26df651dfc2776f3a5a36 Mon Sep 17 00:00:00 2001 From: Username1548 Date: Thu, 14 Nov 2024 17:29:19 +0700 Subject: [PATCH 1/5] fixed layout of diets feed and added text styles --- assets/icons/eye2.svg | 4 + assets/icons/filter2.svg | 3 + assets/icons/repost.svg | 3 + lib/app_router.dart | 11 +- .../diet/repositories/diet_repository.dart | 105 +++ .../data/diet/services/diet_service.dart} | 12 +- .../data/diet/services/diet_service.g.dart} | 31 +- lib/core/widgets/bookmark_button.dart | 44 + lib/core/widgets/diet_info_row.dart | 66 ++ lib/core/widgets/feed_icon_button.dart | 51 ++ .../chat/presentation/pages/chat_screen.dart | 2 +- .../presentation/bloc/about_diet_cubit.dart | 34 +- .../presentation/pages/about_diet_screen.dart | 783 ++++++++---------- .../presentation/widgets/author_card.dart | 39 +- .../presentation/widgets/calendar_widget.dart | 36 +- .../presentation/widgets/cpfc_container.dart | 56 +- .../presentation/widgets/expandable_text.dart | 3 +- .../presentation/widgets/more_options.dart | 138 ++- .../widgets/start_diet_bottom_sheet.dart | 49 +- .../presentation/widgets/type_badges.dart | 126 +-- .../diets/repositories/diets_repository.dart | 48 -- .../feed/models/diets_pagination_model.dart | 2 + .../bloc/diets_cubit/diets_cubit.dart | 240 +++++- .../feed/presentation/pages/feed_screen.dart | 32 +- .../widgets/blog_post_widget.dart | 43 +- .../presentation/widgets/comments_widget.dart | 8 +- .../presentation/widgets/diets_widget.dart | 281 +++---- .../presentation/widgets/filter_widget.dart | 24 + .../feed/repositories/feed_repository.dart | 1 + lib/features/feed/services/feed_service.dart | 3 +- lib/generated/intl/messages_all.dart | 2 +- lib/generated/intl/messages_en.dart | 54 +- lib/generated/l10n.dart | 4 +- lib/locator_service.dart | 13 +- lib/theme/app_decoration.dart | 4 +- lib/theme/custom_text_style.dart | 68 +- lib/theme/theme_helper.dart | 10 +- 37 files changed, 1451 insertions(+), 982 deletions(-) create mode 100644 assets/icons/eye2.svg create mode 100644 assets/icons/filter2.svg create mode 100644 assets/icons/repost.svg create mode 100644 lib/core/data/diet/repositories/diet_repository.dart rename lib/{features/diets/services/diets_service.dart => core/data/diet/services/diet_service.dart} (72%) rename lib/{features/diets/services/diets_service.g.dart => core/data/diet/services/diet_service.g.dart} (84%) create mode 100644 lib/core/widgets/bookmark_button.dart create mode 100644 lib/core/widgets/diet_info_row.dart create mode 100644 lib/core/widgets/feed_icon_button.dart delete mode 100644 lib/features/diets/repositories/diets_repository.dart create mode 100644 lib/features/feed/presentation/widgets/filter_widget.dart diff --git a/assets/icons/eye2.svg b/assets/icons/eye2.svg new file mode 100644 index 00000000..84676c48 --- /dev/null +++ b/assets/icons/eye2.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/icons/filter2.svg b/assets/icons/filter2.svg new file mode 100644 index 00000000..ed90bc9d --- /dev/null +++ b/assets/icons/filter2.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/repost.svg b/assets/icons/repost.svg new file mode 100644 index 00000000..05517e80 --- /dev/null +++ b/assets/icons/repost.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/app_router.dart b/lib/app_router.dart index 6b8edb3c..91ab37fd 100644 --- a/lib/app_router.dart +++ b/lib/app_router.dart @@ -147,9 +147,14 @@ class AppRouter { GoRoute( path: '/about-diet-screen', name: 'aboutDietScreen', - builder: (context, state) => AboutDietScreen( - diet: state.extra as Diet, - ), + builder: (context, state) { + final data = state.extra as Map; + return AboutDietScreen( + diet: data['diet'] as Diet, + index: data['index'] as int, + navigateToComments: data['navigateToComments'] as bool, + ); + }, ), GoRoute( path: '/blog-post-create-screen', diff --git a/lib/core/data/diet/repositories/diet_repository.dart b/lib/core/data/diet/repositories/diet_repository.dart new file mode 100644 index 00000000..5e78ae33 --- /dev/null +++ b/lib/core/data/diet/repositories/diet_repository.dart @@ -0,0 +1,105 @@ +import 'dart:async'; + +import 'package:eatvio_app/core/data/diet/services/diet_service.dart'; +import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; +import 'package:equatable/equatable.dart'; + +class DietRepository { + DietRepository({required this.dietsService}); + final DietService dietsService; + + final _dietLikeStateStreamController = StreamController.broadcast(); + final _dietFavoriteStateStreamController = StreamController.broadcast(); + final _dietCommentsStateStreamController = StreamController.broadcast(); + Stream get dietLikeState => _dietLikeStateStreamController.stream; + Stream get dietFavoriteState => _dietFavoriteStateStreamController.stream; + Stream get dietCommentsState => _dietCommentsStateStreamController.stream; + + Future likeDiet(int id) async { + try { + await dietsService.likeDiet(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; + } + } + + void emitLikesStateToFeed(DietLikesState state) => _dietLikeStateStreamController.add(state); + void emitFavoriteStateToFeed(DietFavoriteState state) => _dietFavoriteStateStreamController.add(state); + void emitCommentsStateToFeed(DietCommentsState state) => _dietCommentsStateStreamController.add(state); +} + +class DietLikesState extends Equatable { + final bool wasLikedByMe; + final int totalLikes; + final int index; + + DietLikesState({ + required this.wasLikedByMe, + required this.totalLikes, + required this.index, + }); + + @override + List get props => [ + wasLikedByMe, + totalLikes, + index, + ]; +} + +class DietFavoriteState extends Equatable { + final bool isFavorite; + final int index; + + DietFavoriteState({ + required this.isFavorite, + required this.index, + }); + + @override + List get props => [ + isFavorite, + index, + ]; +} + +class DietCommentsState extends Equatable { + final int index; + final int totalComments; + + DietCommentsState({ + required this.index, + required this.totalComments, + }); + + @override + List get props => [ + index, + totalComments, + ]; +} \ No newline at end of file diff --git a/lib/features/diets/services/diets_service.dart b/lib/core/data/diet/services/diet_service.dart similarity index 72% rename from lib/features/diets/services/diets_service.dart rename to lib/core/data/diet/services/diet_service.dart index d5236e3d..fec1966c 100644 --- a/lib/features/diets/services/diets_service.dart +++ b/lib/core/data/diet/services/diet_service.dart @@ -2,11 +2,11 @@ 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'; +part 'diet_service.g.dart'; @RestApi() -abstract class DietsService { - factory DietsService(Dio dio, {String baseUrl}) = _DietsService; +abstract class DietService { + factory DietService(Dio dio, {String baseUrl}) = _DietService; @POST('/api/diets/{id}/like') Future likeDiet({ @@ -23,14 +23,8 @@ abstract class DietsService { @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/core/data/diet/services/diet_service.g.dart similarity index 84% rename from lib/features/diets/services/diets_service.g.dart rename to lib/core/data/diet/services/diet_service.g.dart index 67718920..db4a1f56 100644 --- a/lib/features/diets/services/diets_service.g.dart +++ b/lib/core/data/diet/services/diet_service.g.dart @@ -1,6 +1,6 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'diets_service.dart'; +part of 'diet_service.dart'; // ************************************************************************** // RetrofitGenerator @@ -8,8 +8,8 @@ part of 'diets_service.dart'; // ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations -class _DietsService implements DietsService { - _DietsService( +class _DietService implements DietService { + _DietService( this._dio, { this.baseUrl, this.errorLogger, @@ -96,31 +96,6 @@ class _DietsService implements DietsService { 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 = {}; diff --git a/lib/core/widgets/bookmark_button.dart b/lib/core/widgets/bookmark_button.dart new file mode 100644 index 00000000..b8d767ac --- /dev/null +++ b/lib/core/widgets/bookmark_button.dart @@ -0,0 +1,44 @@ +import 'package:eatvio_app/theme/theme_helper.dart'; +import 'package:flutter/material.dart'; + +class BookmarkButton extends StatelessWidget { + const BookmarkButton({ + super.key, + required this.onTap, + required this.color, + required this.isFavorite, + required this.width, + required this.height, + required this.size, + this.shape, + this.borderRadius, + }); + final void Function() onTap; + final Color color; + final BoxShape? shape; + final bool isFavorite; + final BorderRadiusGeometry? borderRadius; + final double width; + final double height; + final double size; + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap, + child: Container( + width: width, + height: height, + decoration: BoxDecoration( + color: color, + shape: shape ?? BoxShape.rectangle, + borderRadius: borderRadius, + ), + child: Icon( + isFavorite ? Icons.bookmark : Icons.bookmark_border_rounded, + color: appTheme.black, + size: size, + ), + ), + ); + } +} diff --git a/lib/core/widgets/diet_info_row.dart b/lib/core/widgets/diet_info_row.dart new file mode 100644 index 00000000..bf365a5d --- /dev/null +++ b/lib/core/widgets/diet_info_row.dart @@ -0,0 +1,66 @@ +import 'package:eatvio_app/core/utils/localization_utils.dart'; +import 'package:eatvio_app/features/diets/presentation/widgets/info_bouble.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/generated/l10n.dart'; +import 'package:eatvio_app/theme/custom_text_style.dart'; +import 'package:eatvio_app/theme/theme_helper.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; + +class DietInfoRow extends StatelessWidget { + const DietInfoRow({super.key, required this.diet, this.itemsBackgroundColor, this.disableDescriptionOfTypes = false}); + final Color? itemsBackgroundColor; + final Diet diet; + final bool disableDescriptionOfTypes; + @override + Widget build(BuildContext context) { + final s = S.of(context); + return SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 16), + scrollDirection: Axis.horizontal, + child: Row( + children: [ + InfoBouble( + backgroundColor: itemsBackgroundColor, + children: [ + SvgPicture.asset( + 'assets/icons/time2.svg', + width: 13.3, + height: 13.3, + ), + SizedBox(width: 4), + Text( + diet.duration.toString() + ' ' + getDayForm(diet.duration, s), + style: TextStyles.textXSSemibold.copyWith(color: appTheme.black), + ), + ], + ), + SizedBox(width: 12), + InfoBouble( + backgroundColor: itemsBackgroundColor, + children: [ + SvgPicture.asset( + 'assets/icons/people.svg', + width: 13.3, + height: 13.3, + ), + SizedBox(width: 4), + Text( + '80 человек прошли', + style: TextStyles.textXSSemibold.copyWith(color: appTheme.black), + ), + ], + ), + SizedBox(width: 12), + InfoBouble( + backgroundColor: itemsBackgroundColor, + children: [ + TypeBadges(type: diet.type, disableDescriptionOfTypes: disableDescriptionOfTypes), + ], + ), + ], + ), + ); + } +} diff --git a/lib/core/widgets/feed_icon_button.dart b/lib/core/widgets/feed_icon_button.dart new file mode 100644 index 00000000..e3744f9c --- /dev/null +++ b/lib/core/widgets/feed_icon_button.dart @@ -0,0 +1,51 @@ +import 'package:eatvio_app/theme/custom_text_style.dart'; +import 'package:eatvio_app/theme/theme_helper.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; + +class FeedIconButton extends StatelessWidget { + const FeedIconButton({super.key, this.icon, this.svgIcon, this.text, this.onTap, this.iconColor, this.backgroundColor, this.textColor}); + final IconData? icon; + final SvgPicture? svgIcon; + final String? text; + final Function()? onTap; + final Color? iconColor; + final Color? backgroundColor; + final Color? textColor; + @override + Widget build(BuildContext context) { + return InkWell( + onTap: onTap ?? () {}, + borderRadius: BorderRadius.circular(16), + child: Container( + padding: EdgeInsets.symmetric(horizontal: 12, vertical: 4), + decoration: BoxDecoration( + color: backgroundColor ?? appTheme.gray100, + borderRadius: BorderRadius.circular(16), + ), + height: 32, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (svgIcon != null) svgIcon!, + if (icon != null) + Icon( + icon, + size: 16, + color: iconColor ?? appTheme.gray600, + ), + if (text != null) ...[ + SizedBox(width: 8), + Text( + text!, + style: TextStyles.textSMedium.copyWith( + color: textColor ?? appTheme.gray600, + ), + ), + ], + ], + ), + ), + ); + } +} diff --git a/lib/features/chat/presentation/pages/chat_screen.dart b/lib/features/chat/presentation/pages/chat_screen.dart index ee50e04d..65dfd03d 100644 --- a/lib/features/chat/presentation/pages/chat_screen.dart +++ b/lib/features/chat/presentation/pages/chat_screen.dart @@ -119,7 +119,7 @@ class _ChatScreenState extends State { Text( state.chatRoom.users['to_chat_user']!.name, style: CustomTextStyles.titleSmallBold.copyWith( - color: PrimaryColors().blueGray800, + color: PrimaryColors().black, ), ), AnimatedCrossFade( diff --git a/lib/features/diets/presentation/bloc/about_diet_cubit.dart b/lib/features/diets/presentation/bloc/about_diet_cubit.dart index 830dd3a6..498f15ea 100644 --- a/lib/features/diets/presentation/bloc/about_diet_cubit.dart +++ b/lib/features/diets/presentation/bloc/about_diet_cubit.dart @@ -2,24 +2,27 @@ import 'dart:async'; import 'dart:developer'; import 'package:easy_debounce/easy_debounce.dart'; +import 'package:eatvio_app/core/data/diet/repositories/diet_repository.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; + final DietRepository dietsRepository; - Future getDiet(int id) async { + Future getDiet(int id, {int? index}) async { try { final diet = await dietsRepository.getDiet(id); + if (index != null) { + dietsRepository.emitCommentsStateToFeed(DietCommentsState(index: index, totalComments: diet.totalComments)); + } emit(AboutDietState.loaded(diet)); } catch (e) { log(e.toString()); } } - Future getDietWithLoading(int id) async{ + Future getDietWithLoading(int id) async { try { emit(AboutDietState.loading()); final diet = await dietsRepository.getDiet(id); @@ -29,7 +32,7 @@ class AboutDietCubit extends Cubit { } } - Future likeDiet(int id) async { + Future likeDiet(int id, int dietIndexInFeed) async { if (state is! DietStateLoaded) return; final currentDiet = (state as DietStateLoaded).diet; @@ -39,12 +42,15 @@ class AboutDietCubit extends Cubit { totalLikes: currentDiet.totalLikes - 1, wasLikedByMe: false, ); + dietsRepository.emitLikesStateToFeed(DietLikesState(wasLikedByMe: updatedDiet.wasLikedByMe, totalLikes: updatedDiet.totalLikes, index: dietIndexInFeed)); emit(AboutDietState.loaded(updatedDiet)); } else { final updatedDiet = currentDiet.copyWith( totalLikes: currentDiet.totalLikes + 1, wasLikedByMe: true, ); + + dietsRepository.emitLikesStateToFeed(DietLikesState(wasLikedByMe: updatedDiet.wasLikedByMe, totalLikes: updatedDiet.totalLikes, index: dietIndexInFeed)); emit(AboutDietState.loaded(updatedDiet)); } @@ -57,13 +63,15 @@ class AboutDietCubit extends Cubit { await getDiet(id); } catch (e) { log(e.toString()); + dietsRepository + .emitLikesStateToFeed(DietLikesState(wasLikedByMe: currentDiet.wasLikedByMe, totalLikes: currentDiet.totalLikes, index: dietIndexInFeed)); emit(AboutDietState.loaded(currentDiet)); } }, ); } - Future addToFavorite(int id) async { + Future addToFavorite(int id, int dietIndexInFeed) async { if (state is! DietStateLoaded) return; final currentDiet = (state as DietStateLoaded).diet; @@ -71,6 +79,7 @@ class AboutDietCubit extends Cubit { final updatedDiet = currentDiet.copyWith( isFavorite: true, ); + dietsRepository.emitFavoriteStateToFeed(DietFavoriteState(isFavorite: updatedDiet.isFavorite, index: dietIndexInFeed)); emit(AboutDietState.loaded(updatedDiet)); EasyDebounce.debounce( @@ -79,16 +88,19 @@ class AboutDietCubit extends Cubit { () async { try { await dietsRepository.addToFavorite(id); - await getDiet(id); + Future.delayed(const Duration(seconds: 1), () async { + await getDiet(id); + }); } catch (e) { log(e.toString()); + dietsRepository.emitFavoriteStateToFeed(DietFavoriteState(isFavorite: currentDiet.isFavorite, index: dietIndexInFeed)); emit(AboutDietState.loaded(currentDiet)); } }, ); } - Future removeFromFavorite(int id) async { + Future removeFromFavorite(int id, int dietIndexInFeed) async { if (state is! DietStateLoaded) return; final currentDiet = (state as DietStateLoaded).diet; @@ -96,6 +108,7 @@ class AboutDietCubit extends Cubit { final updatedDiet = currentDiet.copyWith( isFavorite: false, ); + dietsRepository.emitFavoriteStateToFeed(DietFavoriteState(isFavorite: updatedDiet.isFavorite, index: dietIndexInFeed)); emit(AboutDietState.loaded(updatedDiet)); EasyDebounce.debounce( @@ -104,9 +117,12 @@ class AboutDietCubit extends Cubit { () async { try { await dietsRepository.removeFromFavorite(id); - await getDiet(id); + Future.delayed(const Duration(seconds: 1), () async { + await getDiet(id); + }); } catch (e) { log(e.toString()); + dietsRepository.emitFavoriteStateToFeed(DietFavoriteState(isFavorite: currentDiet.isFavorite, index: dietIndexInFeed)); emit(AboutDietState.loaded(currentDiet)); } }, diff --git a/lib/features/diets/presentation/pages/about_diet_screen.dart b/lib/features/diets/presentation/pages/about_diet_screen.dart index db0bd378..8173f15a 100644 --- a/lib/features/diets/presentation/pages/about_diet_screen.dart +++ b/lib/features/diets/presentation/pages/about_diet_screen.dart @@ -4,7 +4,9 @@ import 'package:cached_network_image/cached_network_image.dart'; 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/bookmark_button.dart'; import 'package:eatvio_app/core/widgets/custom_divider.dart'; +import 'package:eatvio_app/core/widgets/diet_info_row.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'; @@ -14,13 +16,13 @@ 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'; import 'package:eatvio_app/features/feed/presentation/bloc/comments_cubit/comments_state.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/comments_widget.dart'; import 'package:eatvio_app/generated/l10n.dart'; import 'package:eatvio_app/locator_service.dart'; +import 'package:eatvio_app/theme/custom_text_style.dart'; import 'package:eatvio_app/theme/theme_helper.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -30,9 +32,11 @@ import 'package:rive/rive.dart' hide LinearGradient; class AboutDietScreen extends StatefulWidget { final Diet diet; + final int index; + final bool navigateToComments; late final List selectedIndexes; - AboutDietScreen({super.key, required this.diet}) { + AboutDietScreen({super.key, required this.diet, required this.index, required this.navigateToComments}) { selectedIndexes = List.generate(diet.dailySchedule.length, (_) => 0); } @@ -47,7 +51,7 @@ class _AboutDietScreenState extends State { final ScrollController scrollController = ScrollController(); final textEditingController = TextEditingController(); bool isMoreOptionsVisible = false; - + bool _jumped = false; @override void initState() { super.initState(); @@ -60,6 +64,13 @@ class _AboutDietScreenState extends State { }); } + void _scrollToBottom() { + _jumped = true; + scrollController.jumpTo( + scrollController.position.maxScrollExtent, + ); + } + @override Widget build(BuildContext context) { final s = S.of(context); @@ -83,440 +94,389 @@ class _AboutDietScreenState extends State { 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), - ), - ), + if (dietState is DietStateLoaded) { + Future.delayed(Duration(milliseconds: 500), () { + if (widget.navigateToComments && !_jumped) { + _scrollToBottom(); + } + }); + 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, + ), + ), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( 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: () { - showModalBottomSheet(context: context, builder: (context) => StartDietBottomSheet()); - }, - label: Text( - s.startDiet, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: appTheme.whiteA700, - ), - ), - ), + Expanded( + child: SizedBox( + child: FloatingActionButton.extended( + heroTag: 'nextButtonRegistration', + highlightElevation: 0, + elevation: 0, + focusElevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), ), - ), - SizedBox(width: 8), - GestureDetector( - onTap: () { - if (dietState.diet.isFavorite) { - dietsCubit.removeFromFavorite(widget.diet.id); - } else { - dietsCubit.addToFavorite(widget.diet.id); - } + backgroundColor: appTheme.greenA700, + onPressed: () { + showModalBottomSheet(context: context, builder: (context) => StartDietBottomSheet()); }, - 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, - ), + label: Text( + s.startDiet, + style: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700), ), ), - ], + ), ), - 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(width: 8), + BookmarkButton( + isFavorite: dietState.diet.isFavorite, + onTap: () { + if (dietState.diet.isFavorite) { + dietsCubit.removeFromFavorite(widget.diet.id, widget.index); + } else { + dietsCubit.addToFavorite(widget.diet.id, widget.index); + } + }, + width: 52, + height: 52, + size: 24, + shape: BoxShape.circle, + color: appTheme.gray50, ), ], ), - ), - ), - 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; - }); + 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: TextStyles.textMMedium.copyWith(color: appTheme.black), + decoration: InputDecoration( + isDense: true, + contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), + hintText: s.comment.capitalize(), + hintStyle: TextStyles.textMMedium.copyWith(color: appTheme.lightGray600), + 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; + }); + Future.delayed(Duration(milliseconds: 500), () { + dietsCubit.getDiet(widget.diet.id, index: widget.index); + }); + FocusManager.instance.primaryFocus?.unfocus(); + } }, - icon: SvgPicture.asset( - 'assets/icons/more_button.svg', - width: 20, - height: 20, - ),), + 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.black, + ), + ), + ), + ], ), ], ), - body: SingleChildScrollView( - controller: scrollController, - padding: EdgeInsets.only(bottom: 160), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox(height: 8), - MainBackgroundBouble( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + ), + ), + appBar: AppBar( + centerTitle: true, + title: Text( + widget.diet.name, + maxLines: 2, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + softWrap: true, + style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black), + ), + 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: [ - 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), - ), + CachedNetworkImage( + imageUrl: baseUrl + '/storage/' + widget.diet.image, ), - SizedBox(height: 12), - SingleChildScrollView( - padding: const EdgeInsets.symmetric(horizontal: 16), - scrollDirection: Axis.horizontal, + Positioned( + bottom: 16, + left: 0, + right: 0, child: Row( + mainAxisAlignment: MainAxisAlignment.center, children: [ InfoBouble( children: [ - SvgPicture.asset( - 'assets/icons/time2.svg', - width: 13.3, - height: 13.3, + SvgPicture.asset('assets/icons/eye.svg', width: 18, height: 12), + SizedBox(width: 8), + Text( + dietState.diet.totalViews.toString(), + style: TextStyles.textXSSemibold.copyWith(color: appTheme.black), ), - SizedBox(width: 4), - Text(widget.diet.duration.toString() + ' ' + getDayForm(widget.diet.duration, s), - style: TextStyle(color: appTheme.blueGray800, fontSize: 12, fontWeight: FontWeight.w500),), ], + backgroundColor: appTheme.whiteA700, + ), + SizedBox(width: 12), + GestureDetector( + onTap: () { + dietsCubit.likeDiet(widget.diet.id, widget.index); + }, + 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: TextStyles.textXSSemibold.copyWith(color: appTheme.black), + ), + ], + backgroundColor: appTheme.whiteA700, + ), ), SizedBox(width: 12), InfoBouble( children: [ - SvgPicture.asset( - 'assets/icons/people.svg', - width: 13.3, - height: 13.3, + SvgPicture.asset('assets/icons/comment2.svg', width: 13, height: 12), + SizedBox(width: 8), + Text( + dietState.diet.totalComments.toString(), + style: TextStyles.textXSSemibold.copyWith(color: appTheme.black), ), - 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), ], + backgroundColor: appTheme.whiteA700, ), ], ), ), - 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( + SizedBox(height: 16), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), child: Text( - s.diet_plan + '(${widget.diet.duration.toString()} ' + getDayForm(widget.diet.duration, s) + ')', - style: TextStyle( - color: appTheme.blueGray800, - fontSize: 20, - fontWeight: FontWeight.w600, + s.about_diet, + style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black), + ), + ), + SizedBox(height: 12), + DietInfoRow(diet: widget.diet), + 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: TextStyles.headingXLSemibold.copyWith( + color: appTheme.black, + ), + ), + ), + ), + ), + 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: TextStyles.textMMedium.copyWith( + color: appTheme.gray500, ), ), ), - ),), - 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', ), ), ), - 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, - ), - ],), - ), - ], - ), - ), - ) - : Scaffold( - body: Center( - 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, + ), + ], ), ), - ), - ); + ], + ), + ), + ); + } + return Scaffold( + body: Center( + child: SizedBox( + height: 32, + width: 32, + child: RiveAnimation.asset( + 'assets/rive_animations/loading.riv', + ), + ), + ), + ); }, ); }, @@ -537,10 +497,8 @@ class _AboutDietScreenState extends State { ), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), label: Text((index + 1).toString()), - labelStyle: TextStyle( + labelStyle: TextStyles.textXSSemibold.copyWith( color: index == widget.selectedIndexes[dayNumber] ? Colors.white : appTheme.gray600, - fontWeight: FontWeight.w500, - fontSize: 12, ), selected: widget.selectedIndexes[dayNumber] == index, backgroundColor: appTheme.gray100, @@ -567,10 +525,8 @@ class _AboutDietScreenState extends State { children: [ Text( s.day + ' ' + (dayNumber + 1).toString(), - style: TextStyle( - color: appTheme.blueGray800, - fontSize: 20, - fontWeight: FontWeight.w600, + style: TextStyles.headingXLSemibold.copyWith( + color: appTheme.black, ), ), Padding( @@ -579,10 +535,8 @@ class _AboutDietScreenState extends State { ), Text( s.meal, - style: TextStyle( - color: appTheme.blueGray800, - fontSize: 16, - fontWeight: FontWeight.w500, + style: TextStyles.textMMedium.copyWith( + color: appTheme.black, ), ), Row( @@ -618,21 +572,20 @@ class _AboutDietScreenState extends State { padding: const EdgeInsets.only(bottom: 12), child: Row( children: [ - Text( - daily.name, - style: TextStyle( - color: appTheme.blueGray800, - fontSize: 16, - fontWeight: FontWeight.w500, + SizedBox( + width: MediaQuery.sizeOf(context).width * 0.6, + child: Text( + daily.name, + style: TextStyles.textMMedium.copyWith( + color: appTheme.black, + ), ), ), Spacer(), Text( daily.quantity.toString() + ' ' + getLocalizedMeasurementUnits(s, daily.portion), - style: TextStyle( - color: appTheme.blueGray800, - fontSize: 16, - fontWeight: FontWeight.w600, + style: TextStyles.textMSemibold.copyWith( + color: appTheme.black, ), ), ], diff --git a/lib/features/diets/presentation/widgets/author_card.dart b/lib/features/diets/presentation/widgets/author_card.dart index d566dad5..c277ef30 100644 --- a/lib/features/diets/presentation/widgets/author_card.dart +++ b/lib/features/diets/presentation/widgets/author_card.dart @@ -1,6 +1,7 @@ import 'package:eatvio_app/features/diets/presentation/widgets/info_bouble.dart'; import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; import 'package:eatvio_app/generated/l10n.dart'; +import 'package:eatvio_app/theme/custom_text_style.dart'; import 'package:eatvio_app/theme/theme_helper.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; @@ -36,18 +37,14 @@ class AuthorCard extends StatelessWidget { ), subtitle: Text( author.authorName, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w600, - color: appTheme.blueGray800, + style: TextStyles.textLSemibold.copyWith( + color: appTheme.black, ), ), title: Text( s.diet_author, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - color: Color(0xFF6D6F71), + style: TextStyles.textSSemibold.copyWith( + color: appTheme.gray, ), ), ), @@ -55,23 +52,23 @@ class AuthorCard extends StatelessWidget { children: [ Text( 'Конслуьтант', - style: TextStyle( - color: appTheme.blueGray800, - fontSize: 16, - fontWeight: FontWeight.w500, + style: TextStyles.textMMedium.copyWith( + color: appTheme.black, ), ), SizedBox(width: 10), - InfoBouble(radius: 12, backgroundColor: appTheme.whiteA700, children: [ - Text( - '128-й в рейтинге', - style: TextStyle( - color: appTheme.blueA400, - fontSize: 16, - fontWeight: FontWeight.w500, + InfoBouble( + radius: 12, + backgroundColor: appTheme.whiteA700, + children: [ + Text( + '128-й в рейтинге', + style: TextStyles.textMMediumAuto.copyWith( + color: appTheme.blueA400, + ), ), - ), - ],), + ], + ), ], ), ], diff --git a/lib/features/diets/presentation/widgets/calendar_widget.dart b/lib/features/diets/presentation/widgets/calendar_widget.dart index e2353b28..4c156035 100644 --- a/lib/features/diets/presentation/widgets/calendar_widget.dart +++ b/lib/features/diets/presentation/widgets/calendar_widget.dart @@ -1,5 +1,7 @@ +import 'package:eatvio_app/core/utils/string_extentions.dart'; import 'package:eatvio_app/theme/theme_helper.dart'; import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; import 'package:table_calendar/table_calendar.dart'; class CalendarWidget extends StatefulWidget { @@ -10,7 +12,7 @@ class CalendarWidget extends StatefulWidget { } class _CalendarWidgetState extends State { - CalendarFormat _calendarFormat = CalendarFormat.month; + CalendarFormat _calendarFormat = CalendarFormat.week; DateTime _focusedDay = DateTime.now(); DateTime? _selectedDay = DateTime.now(); @override @@ -26,16 +28,25 @@ class _CalendarWidgetState extends State { locale: 'ru_RU', startingDayOfWeek: StartingDayOfWeek.monday, focusedDay: _focusedDay, - rangeStartDay: _selectedDay, - rangeEndDay: _selectedDay?.add(const Duration(days: 6)), calendarFormat: _calendarFormat, + calendarBuilders: CalendarBuilders( + headerTitleBuilder: (context, day) { + final dateFormatter = DateFormat('MMMM', 'ru_RU'); + return Center( + child: Text( + '${dateFormatter.format(day).capitalize()}', + style: TextStyle(color: appTheme.black, fontSize: 16, fontWeight: FontWeight.w400), + ), + ); + }, + ), headerStyle: HeaderStyle( titleCentered: true, formatButtonVisible: false, leftChevronVisible: false, rightChevronVisible: false, ), - rowHeight: 40, + rowHeight: 64, selectedDayPredicate: (day) { return isSameDay(_selectedDay, day); }, @@ -58,27 +69,36 @@ class _CalendarWidgetState extends State { _focusedDay = focusedDay; }, calendarStyle: CalendarStyle( + weekendTextStyle: TextStyle( + color: appTheme.gray, + ), + defaultTextStyle: TextStyle( + color: appTheme.gray, + ), weekendDecoration: BoxDecoration( - color: Colors.white, + color: appTheme.dividerColor, shape: BoxShape.circle, ), defaultDecoration: BoxDecoration( - color: Colors.white, + color: appTheme.dividerColor, shape: BoxShape.circle, ), + selectedTextStyle: TextStyle( + color: appTheme.whiteA700, + ), selectedDecoration: BoxDecoration( color: appTheme.blueA400, shape: BoxShape.circle, ), todayTextStyle: TextStyle( - color: Colors.black, + color: appTheme.gray, ), todayDecoration: BoxDecoration( border: Border.all( color: appTheme.blueA400, width: 2, ), - color: Colors.white, + color: appTheme.dividerColor, shape: BoxShape.circle, ), ), diff --git a/lib/features/diets/presentation/widgets/cpfc_container.dart b/lib/features/diets/presentation/widgets/cpfc_container.dart index e73cf57c..bd211b21 100644 --- a/lib/features/diets/presentation/widgets/cpfc_container.dart +++ b/lib/features/diets/presentation/widgets/cpfc_container.dart @@ -1,4 +1,5 @@ import 'package:eatvio_app/generated/l10n.dart'; +import 'package:eatvio_app/theme/custom_text_style.dart'; import 'package:eatvio_app/theme/theme_helper.dart'; import 'package:flutter/material.dart'; @@ -15,32 +16,35 @@ class CpfcContainer extends StatelessWidget { return Container( color: appTheme.cardBackground, padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12), - child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Column( - children: [ - Text('$calories', style: TextStyle(color: appTheme.blueGray800, fontSize: 16, fontWeight: FontWeight.w600)), - Text(s.calories, style: TextStyle(color: appTheme.blueGray800, fontSize: 12, fontWeight: FontWeight.w500)), - ], - ), - Column( - children: [ - Text('$protein', style: TextStyle(color: appTheme.blueGray800, fontSize: 16, fontWeight: FontWeight.w600)), - Text(s.proteins, style: TextStyle(color: appTheme.blueGray800, fontSize: 12, fontWeight: FontWeight.w500)), - ], - ), - Column( - children: [ - Text('$fat', style: TextStyle(color: appTheme.blueGray800, fontSize: 16, fontWeight: FontWeight.w600)), - Text(s.fats, style: TextStyle(color: appTheme.blueGray800, fontSize: 12, fontWeight: FontWeight.w500)), - ], - ), - Column( - children: [ - 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)), - ], - ), - ],), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + children: [ + Text('$calories', style: TextStyles.textMSemibold.copyWith(color: appTheme.black)), + Text(s.calories, style: TextStyles.textXSSemibold.copyWith(color: appTheme.black)), + ], + ), + Column( + children: [ + Text('$protein', style: TextStyles.textMSemibold.copyWith(color: appTheme.black)), + Text(s.proteins, style: TextStyles.textXSSemibold.copyWith(color: appTheme.black)), + ], + ), + Column( + children: [ + Text('$fat', style: TextStyles.textMSemibold.copyWith(color: appTheme.black)), + Text(s.fats, style: TextStyles.textXSSemibold.copyWith(color: appTheme.black)), + ], + ), + Column( + children: [ + Text('$carbohydrates', style: TextStyles.textMSemibold.copyWith(color: appTheme.black)), + Text(s.carbohydrates, style: TextStyles.textXSSemibold.copyWith(color: appTheme.black)), + ], + ), + ], + ), ); } } diff --git a/lib/features/diets/presentation/widgets/expandable_text.dart b/lib/features/diets/presentation/widgets/expandable_text.dart index a035c287..80ecb6a3 100644 --- a/lib/features/diets/presentation/widgets/expandable_text.dart +++ b/lib/features/diets/presentation/widgets/expandable_text.dart @@ -1,6 +1,7 @@ import 'dart:math' as math; import 'package:eatvio_app/generated/l10n.dart'; +import 'package:eatvio_app/theme/custom_text_style.dart'; import 'package:eatvio_app/theme/theme_helper.dart'; import 'package:flutter/material.dart'; import 'package:flutter_html/flutter_html.dart'; @@ -74,7 +75,7 @@ class _ExpandableTextState extends State { children: [ Text( isExpanded ? s.hide : s.expand, - style: TextStyle(color: appTheme.blueA400, fontSize: 16, fontWeight: FontWeight.w500), + style: TextStyles.textMMedium.copyWith(color: appTheme.blueA400), ), Transform.rotate(angle: isExpanded ? math.pi : 0, child: SvgPicture.asset('assets/icons/arrow_down.svg', width: 12, height: 12)), ], diff --git a/lib/features/diets/presentation/widgets/more_options.dart b/lib/features/diets/presentation/widgets/more_options.dart index 639fe8d2..675ecd7e 100644 --- a/lib/features/diets/presentation/widgets/more_options.dart +++ b/lib/features/diets/presentation/widgets/more_options.dart @@ -3,6 +3,7 @@ import 'package:eatvio_app/core/utils/toasts.dart'; import 'package:eatvio_app/core/widgets/custom_divider.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/main_background_bouble.dart'; import 'package:eatvio_app/generated/l10n.dart'; +import 'package:eatvio_app/theme/custom_text_style.dart'; import 'package:eatvio_app/theme/theme_helper.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -17,83 +18,80 @@ class MoreOptions extends StatelessWidget { Widget build(BuildContext context) { final s = S.of(context); return MainBackgroundBouble( - enableShadow: true, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - GestureDetector( - onTap: () { - Clipboard.setData(ClipboardData(text: baseUrl + '/ru/diet/' + id.toString())); - showInfoToast(s.link_was_copied); - }, - child: Row( - children: [ - Text( - s.copy_link, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: appTheme.blueGray800, - ), + enableShadow: true, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + GestureDetector( + onTap: () { + Clipboard.setData(ClipboardData(text: baseUrl + '/ru/diet/' + id.toString())); + showInfoToast(s.link_was_copied); + }, + child: Row( + children: [ + Text( + s.copy_link, + style: TextStyles.textMMedium.copyWith( + + color: appTheme.black, ), - Spacer(), - SvgPicture.asset('assets/icons/copy2.svg', width: 16, height: 20), - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 12.0), - child: CustomDivider(), - ), - GestureDetector( - onTap: () => Share.shareUri( - Uri.parse( - baseUrl + '/ru/diet/' + id.toString(), ), + Spacer(), + SvgPicture.asset('assets/icons/copy2.svg', width: 16, height: 20), + ], + ), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 12.0), + child: CustomDivider(), + ), + GestureDetector( + onTap: () => Share.shareUri( + Uri.parse( + baseUrl + '/ru/diet/' + id.toString(), ), - child: Row( - children: [ - Text( - s.share, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: appTheme.blueGray800, - ), + ), + child: Row( + children: [ + Text( + s.share, + style: TextStyles.textMMedium.copyWith( + + color: appTheme.black, ), - Spacer(), - SvgPicture.asset('assets/icons/share2.svg', width: 16, height: 20), - ], - ), + ), + Spacer(), + SvgPicture.asset('assets/icons/share2.svg', width: 16, height: 20), + ], ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 12.0), - child: CustomDivider(), - ), - GestureDetector( - onTap: () { - context.push('complainingScreen'); - }, - child: Row( - children: [ - Text( - s.complain, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: appTheme.blueGray800, - ), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 12.0), + child: CustomDivider(), + ), + GestureDetector( + onTap: () { + context.push('complainingScreen'); + }, + child: Row( + children: [ + Text( + s.complain, + style: TextStyles.textMMedium.copyWith( + color: appTheme.black, ), - Spacer(), - SvgPicture.asset('assets/icons/complain.svg', width: 16, height: 20), - ], - ), + ), + Spacer(), + 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 index 94e18e89..100c706d 100644 --- a/lib/features/diets/presentation/widgets/start_diet_bottom_sheet.dart +++ b/lib/features/diets/presentation/widgets/start_diet_bottom_sheet.dart @@ -1,5 +1,7 @@ +import 'package:eatvio_app/core/widgets/custom_divider.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/calendar_widget.dart'; import 'package:eatvio_app/generated/l10n.dart'; +import 'package:eatvio_app/theme/custom_text_style.dart'; import 'package:eatvio_app/theme/theme_helper.dart'; import 'package:eatvio_app/widgets/custom_outlined_button.dart'; import 'package:flutter/material.dart'; @@ -13,38 +15,45 @@ class StartDietBottomSheet extends StatelessWidget { return Column( mainAxisSize: MainAxisSize.min, children: [ - SizedBox(height: 5), + SizedBox(height: 4), Container( height: 4, width: 40, - decoration: BoxDecoration(color: appTheme.lightGrey, borderRadius: BorderRadius.circular(20)), + decoration: BoxDecoration(color: appTheme.lightGray, borderRadius: BorderRadius.circular(20)), + ), + SizedBox(height: 12), + Text( + s.startDiet, + style: TextStyles.headingXLSemibold.copyWith( + color: appTheme.black, + ), ), - 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, - ),), + child: Text( + s.choose_start_diet_date, + textAlign: TextAlign.center, + style: TextStyles.textMMedium.copyWith( + color: appTheme.black, + ), + ), + ), + SizedBox(height: 12), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: CustomDivider(), ), CalendarWidget(), Padding( - padding: EdgeInsets.only(left: 16, right: 16, top: 20, bottom: 25), + padding: EdgeInsets.only(left: 16, right: 16, top: 16, bottom: 28), child: CustomOutlinedButton( - height: 52, - text: s.continue_, + height: 60, + text: s.startDiet, + buttonTextStyle: TextStyles.textLSemibold.copyWith( + color: appTheme.whiteA700, + ), 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 b72c85d4..6d7e2b73 100644 --- a/lib/features/diets/presentation/widgets/type_badges.dart +++ b/lib/features/diets/presentation/widgets/type_badges.dart @@ -1,16 +1,17 @@ import 'package:eatvio_app/features/diets/presentation/widgets/main_background_bouble.dart'; import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; import 'package:eatvio_app/generated/l10n.dart'; +import 'package:eatvio_app/theme/custom_text_style.dart'; import 'package:eatvio_app/theme/theme_helper.dart'; import 'package:flutter/material.dart'; import 'package:flutter_portal/flutter_portal.dart'; import 'package:flutter_svg/svg.dart'; class TypeBadges extends StatefulWidget { - const TypeBadges({super.key, required this.type}); + const TypeBadges({super.key, required this.type, required this.disableDescriptionOfTypes}); final DietType type; - + final bool disableDescriptionOfTypes; @override State createState() => _TypeBadgesState(); } @@ -23,48 +24,56 @@ class _TypeBadgesState extends State { final s = S.of(context); final List<(String, Widget)> badgeSource = []; if (widget.type.alko == true) { - badgeSource.add(( - 'assets/icons/cocktail.svg', - _InfoOverlayEntry( - onClose: closeOverlay, - assetPath: 'assets/icons/cocktail.svg', - title: s.alko_type, - description: s.alko_type_desc, - ) - ),); + badgeSource.add( + ( + 'assets/icons/cocktail.svg', + _InfoOverlayEntry( + onClose: closeOverlay, + assetPath: 'assets/icons/cocktail.svg', + title: s.alko_type, + description: s.alko_type_desc, + ) + ), + ); } if (widget.type.veg == true) { - badgeSource.add(( - 'assets/icons/broccoli.svg', - _InfoOverlayEntry( - onClose: closeOverlay, - assetPath: 'assets/icons/broccoli.svg', - title: s.vegan_type, - description: s.vegan_type_desc, - ) - ),); + badgeSource.add( + ( + 'assets/icons/broccoli.svg', + _InfoOverlayEntry( + onClose: closeOverlay, + assetPath: 'assets/icons/broccoli.svg', + title: s.vegan_type, + description: s.vegan_type_desc, + ) + ), + ); } if (widget.type.corb == true) { - badgeSource.add(( - 'assets/icons/bread.svg', - _InfoOverlayEntry( - onClose: closeOverlay, - assetPath: 'assets/icons/bread.svg', - title: s.corb_type, - description: s.corb_type_desc, - ) - ),); + badgeSource.add( + ( + 'assets/icons/bread.svg', + _InfoOverlayEntry( + onClose: closeOverlay, + assetPath: 'assets/icons/bread.svg', + title: s.corb_type, + description: s.corb_type_desc, + ) + ), + ); } if (widget.type.meat == true) { - badgeSource.add(( - 'assets/icons/meat2.svg', - _InfoOverlayEntry( - onClose: closeOverlay, - assetPath: 'assets/icons/meat2.svg', - title: s.meat_type, - description: s.meat_type_desc, - ) - ),); + badgeSource.add( + ( + 'assets/icons/meat2.svg', + _InfoOverlayEntry( + onClose: closeOverlay, + assetPath: 'assets/icons/meat2.svg', + title: s.meat_type, + description: s.meat_type_desc, + ) + ), + ); } return Row( children: List.generate( @@ -81,19 +90,21 @@ class _TypeBadgesState extends State { ), portalFollower: badgeSource[index].$2, child: GestureDetector( - onTap: () { - for (int stateIndex = 0; stateIndex < overlaysVisibilityState.length; stateIndex++) { - if (index != stateIndex) { - setState(() { - overlaysVisibilityState[stateIndex] = false; - }); - } else { - setState(() { - overlaysVisibilityState[stateIndex] = true; - }); - } - } - }, + onTap: widget.disableDescriptionOfTypes + ? null + : () { + for (int stateIndex = 0; stateIndex < overlaysVisibilityState.length; stateIndex++) { + if (index != stateIndex) { + setState(() { + overlaysVisibilityState[stateIndex] = false; + }); + } else { + setState(() { + overlaysVisibilityState[stateIndex] = true; + }); + } + } + }, child: Padding( padding: EdgeInsets.only(right: index != badgeSource.length - 1 ? 8.0 : 0), child: SvgPicture.asset( @@ -152,22 +163,19 @@ class _InfoOverlayEntry extends StatelessWidget { children: [ Text( title, - style: TextStyle( + style: TextStyles.textMMedium.copyWith( decoration: TextDecoration.none, - color: appTheme.blueGray800, - fontSize: 16, - fontWeight: FontWeight.w500, + color: appTheme.black, ), ), SizedBox(height: 4), Text( description, softWrap: true, - style: TextStyle( + style: TextStyles.textXSSemibold.copyWith( decoration: TextDecoration.none, - color: appTheme.blueGray800, - fontSize: 12, - fontWeight: FontWeight.w500, + color: appTheme.black, + ), ), ], diff --git a/lib/features/diets/repositories/diets_repository.dart b/lib/features/diets/repositories/diets_repository.dart deleted file mode 100644 index 3e826995..00000000 --- a/lib/features/diets/repositories/diets_repository.dart +++ /dev/null @@ -1,48 +0,0 @@ -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/feed/models/diets_pagination_model.dart b/lib/features/feed/models/diets_pagination_model.dart index 99f43194..c3be8c4f 100644 --- a/lib/features/feed/models/diets_pagination_model.dart +++ b/lib/features/feed/models/diets_pagination_model.dart @@ -1,3 +1,4 @@ +import 'package:eatvio_app/core/data/diet/repositories/diet_repository.dart'; import 'package:eatvio_app/core/models/pagination_model.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -36,6 +37,7 @@ class Diet with _$Diet { }) = _Diet; factory Diet.fromJson(Map json) => _$DietFromJson(json); + } @freezed 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 ab9e4396..476b1e97 100644 --- a/lib/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart +++ b/lib/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart @@ -1,15 +1,44 @@ +import 'dart:async'; +import 'dart:developer'; + +import 'package:easy_debounce/easy_debounce.dart'; +import 'package:eatvio_app/core/data/diet/repositories/diet_repository.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_state.dart'; import 'package:eatvio_app/features/feed/repositories/feed_repository.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class DietsCubit extends Cubit { final FeedRepository feedRepository; + final DietRepository dietsRepository; int currentPage = 1; late int lastPage; bool isLoading = false; String? _query; + late final StreamSubscription likesStateSubscription; + late final StreamSubscription favoriteStateSubscription; + late final StreamSubscription commentsStateSubscription; + DietsCubit({ + required this.feedRepository, + required this.dietsRepository, + }) : super(const DietsState.loading()) { + likesStateSubscription = dietsRepository.dietLikeState.listen((likesState) { + _changeDietLikeState(likesState); + }); + favoriteStateSubscription = dietsRepository.dietFavoriteState.listen((favoriteState) { + _changeDietFavoriteState(favoriteState); + }); + commentsStateSubscription = dietsRepository.dietCommentsState.listen((commentsState) { + _changeDietCommentsState(commentsState); + }); + } - DietsCubit({required this.feedRepository}) : super(const DietsState.loading()); + @override + Future close() async { + likesStateSubscription.cancel(); + favoriteStateSubscription.cancel(); + commentsStateSubscription.cancel(); + super.close(); + } loadDiets({ String? query, @@ -20,14 +49,18 @@ class DietsCubit extends Cubit { query: query, ); lastPage = dietsPagination.meta.lastPage; - emit(DietsState.loaded( - dietsList: dietsPagination.data, - isLoading: isLoading, - ),); + emit( + DietsState.loaded( + dietsList: dietsPagination.data, + isLoading: isLoading, + ), + ); } catch (e) { - emit(DietsState.error( - errorMessage: e.toString(), - ),); + emit( + DietsState.error( + errorMessage: e.toString(), + ), + ); } } @@ -60,4 +93,195 @@ class DietsCubit extends Cubit { } } } + + Future likeDiet(int id, int index) async { + if (state is! DietsStateLoaded) return; + + final currentDiets = (state as DietsStateLoaded).dietsList; + final dietsForModification = [...currentDiets]; + final currentDiet = currentDiets[index]; + if (currentDiet.wasLikedByMe) { + dietsForModification[index] = currentDiet.copyWith( + totalLikes: currentDiet.totalLikes - 1, + wasLikedByMe: false, + ); + emit( + DietsState.loaded( + dietsList: [ + ...dietsForModification, + ], + isLoading: isLoading, + ), + ); + } else { + dietsForModification[index] = currentDiet.copyWith( + totalLikes: currentDiet.totalLikes + 1, + wasLikedByMe: true, + ); + emit( + DietsState.loaded( + dietsList: [ + ...dietsForModification, + ], + isLoading: isLoading, + ), + ); + } + EasyDebounce.debounce( + 'like_diet', + Duration(milliseconds: 200), + () async { + try { + await dietsRepository.likeDiet(id); + } catch (e) { + log(e.toString()); + emit( + DietsState.loaded( + dietsList: [ + ...currentDiets, + ], + isLoading: isLoading, + ), + ); + } + }, + ); + } + + void _changeDietLikeState(DietLikesState likesState) { + if (state is! DietsStateLoaded) return; + + final currentDiets = (state as DietsStateLoaded).dietsList; + final dietsForModification = [...currentDiets]; + final currentDiet = currentDiets[likesState.index]; + + dietsForModification[likesState.index] = currentDiet.copyWith( + totalLikes: likesState.totalLikes, + wasLikedByMe: likesState.wasLikedByMe, + ); + emit( + DietsState.loaded( + dietsList: [ + ...dietsForModification, + ], + isLoading: isLoading, + ), + ); + } + + void _changeDietFavoriteState(DietFavoriteState favoriteState) { + if (state is! DietsStateLoaded) return; + + final currentDiets = (state as DietsStateLoaded).dietsList; + final dietsForModification = [...currentDiets]; + final currentDiet = currentDiets[favoriteState.index]; + + dietsForModification[favoriteState.index] = currentDiet.copyWith( + isFavorite: favoriteState.isFavorite, + ); + emit( + DietsState.loaded( + dietsList: [ + ...dietsForModification, + ], + isLoading: isLoading, + ), + ); + } + + void _changeDietCommentsState(DietCommentsState commentsState) { + if (state is! DietsStateLoaded) return; + + final currentDiets = (state as DietsStateLoaded).dietsList; + final dietsForModification = [...currentDiets]; + final currentDiet = currentDiets[commentsState.index]; + + dietsForModification[commentsState.index] = currentDiet.copyWith( + totalComments: commentsState.totalComments, + ); + emit( + DietsState.loaded( + dietsList: [ + ...dietsForModification, + ], + isLoading: isLoading, + ), + ); + } + + Future addDietToFavorite(int id, int index) async { + if (state is! DietsStateLoaded) return; + final currentDiets = (state as DietsStateLoaded).dietsList; + final dietsForModification = [...currentDiets]; + final currentDiet = currentDiets[index]; + + dietsForModification[index] = currentDiet.copyWith( + isFavorite: true, + ); + emit( + DietsState.loaded( + dietsList: [ + ...dietsForModification, + ], + isLoading: isLoading, + ), + ); + EasyDebounce.debounce( + 'add_or_remove_diet_from_favorite', + Duration(milliseconds: 200), + () async { + try { + await dietsRepository.addToFavorite(id); + } catch (e) { + log(e.toString()); + emit( + DietsState.loaded( + dietsList: [ + ...currentDiets, + ], + isLoading: isLoading, + ), + ); + } + }, + ); + } + + Future removeDietFromFavorite(int id, int index) async { + if (state is! DietsStateLoaded) return; + final currentDiets = (state as DietsStateLoaded).dietsList; + final dietsForModification = [...currentDiets]; + final currentDiet = currentDiets[index]; + + dietsForModification[index] = currentDiet.copyWith( + isFavorite: false, + ); + emit( + DietsState.loaded( + dietsList: [ + ...dietsForModification, + ], + isLoading: isLoading, + ), + ); + EasyDebounce.debounce( + 'add_or_remove_diet_from_favorite', + Duration(milliseconds: 200), + () async { + try { + await dietsRepository.removeFromFavorite(id); + } catch (e) { + log(e.toString()); + emit( + DietsState.loaded( + dietsList: [ + ...currentDiets, + ], + isLoading: isLoading, + ), + ); + } + }, + ); + } } diff --git a/lib/features/feed/presentation/pages/feed_screen.dart b/lib/features/feed/presentation/pages/feed_screen.dart index 0abbb6c2..00cc21ba 100644 --- a/lib/features/feed/presentation/pages/feed_screen.dart +++ b/lib/features/feed/presentation/pages/feed_screen.dart @@ -7,6 +7,7 @@ import 'package:eatvio_app/features/feed/presentation/bloc/recipes_cubit/recipes import 'package:eatvio_app/features/feed/presentation/bloc/recipes_cubit/recipes_state.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/blog_post_widget.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/diets_widget.dart'; +import 'package:eatvio_app/features/feed/presentation/widgets/filter_widget.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/plan_widget.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/recipes_widget.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/tags_modal_widget.dart'; @@ -282,17 +283,26 @@ class _FeedScreenState extends State { child: BlocBuilder( builder: (BuildContext context, DietsState state) { if (state is DietsStateLoaded) { - return ListView.separated( - padding: EdgeInsets.symmetric(vertical: 8), - shrinkWrap: true, - physics: BouncingScrollPhysics(), - itemBuilder: (context, index) { - return DietsWidget(diet: state.dietsList[index]); - }, - separatorBuilder: (context, index) { - return SizedBox(height: 8); - }, - itemCount: state.dietsList.length, + return Stack( + children: [ + ListView.separated( + padding: EdgeInsets.symmetric(vertical: 8), + shrinkWrap: true, + physics: BouncingScrollPhysics(), + itemBuilder: (context, index) { + return DietsWidget(diet: state.dietsList[index], index: index); + }, + separatorBuilder: (context, index) { + return SizedBox(height: 8); + }, + itemCount: state.dietsList.length, + ), + Positioned( + right: 0, + bottom: 74, + child: FilterWidget(), + ), + ], ); } else if (state is DietsStateError) { return Scaffold( diff --git a/lib/features/feed/presentation/widgets/blog_post_widget.dart b/lib/features/feed/presentation/widgets/blog_post_widget.dart index 781024cb..ff7dc653 100644 --- a/lib/features/feed/presentation/widgets/blog_post_widget.dart +++ b/lib/features/feed/presentation/widgets/blog_post_widget.dart @@ -2,6 +2,7 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:dismissible_page/dismissible_page.dart'; import 'package:eatvio_app/core/const.dart'; import 'package:eatvio_app/core/utils/date_time_utils.dart'; +import 'package:eatvio_app/core/widgets/feed_icon_button.dart'; import 'package:eatvio_app/features/chat/presentation/pages/photo_view_screen.dart'; import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart'; @@ -153,7 +154,7 @@ class _BlogPostWidgetState extends State { padding: const EdgeInsets.symmetric(horizontal: 12), child: Row( children: [ - _iconButton( + FeedIconButton( icon: isLiked ? Icons.favorite_rounded : Icons.favorite_border_rounded, text: totalLikes.toString(), iconColor: isLiked ? Colors.red.withOpacity(0.8) : null, @@ -171,7 +172,7 @@ class _BlogPostWidgetState extends State { }, ), SizedBox(width: 8), - _iconButton( + FeedIconButton( svgIcon: SvgPicture.asset( 'assets/icons/comment.svg', height: 20, @@ -188,7 +189,7 @@ class _BlogPostWidgetState extends State { ), ), SizedBox(width: 8), - _iconButton( + FeedIconButton( svgIcon: SvgPicture.asset( height: 20, width: 20, @@ -225,40 +226,4 @@ class _BlogPostWidgetState extends State { ), ); } - - _iconButton({IconData? icon, SvgPicture? svgIcon, String? text, Function()? onTap, Color? iconColor, Color? backgroundColor, Color? textColor}) { - return InkWell( - onTap: onTap ?? () {}, - borderRadius: BorderRadius.circular(16), - child: Ink( - padding: EdgeInsets.symmetric(horizontal: 12, vertical: 4), - decoration: BoxDecoration( - color: backgroundColor ?? appTheme.gray100, - borderRadius: BorderRadius.circular(16), - ), - height: 32, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - if (svgIcon != null) svgIcon, - if (icon != null) - Icon( - icon, - size: 20, - color: iconColor ?? appTheme.gray600, - ), - if (text != null) SizedBox(width: 8), - if (text != null) - Text( - text, - style: TextStyle( - color: textColor ?? appTheme.gray600, - fontWeight: FontWeight.w500, - ), - ), - ], - ), - ), - ); - } } diff --git a/lib/features/feed/presentation/widgets/comments_widget.dart b/lib/features/feed/presentation/widgets/comments_widget.dart index 4421a4aa..72be3b63 100644 --- a/lib/features/feed/presentation/widgets/comments_widget.dart +++ b/lib/features/feed/presentation/widgets/comments_widget.dart @@ -71,7 +71,7 @@ class _CommentsWidgetState extends State { comment.authorName, style: TextStyle( height: 1, - color: appTheme.grey, + color: appTheme.gray, fontSize: 12, fontWeight: FontWeight.w500, ), @@ -81,7 +81,7 @@ class _CommentsWidgetState extends State { comment.body, style: TextStyle( height: 1, - color: appTheme.blueGray800, + color: appTheme.black, fontSize: 12, fontWeight: FontWeight.w500, ), @@ -93,7 +93,7 @@ class _CommentsWidgetState extends State { comment.createdAt.format('dd MMMM', 'ru'), style: TextStyle( height: 1, - color: appTheme.grey, + color: appTheme.gray, fontSize: 12, fontWeight: FontWeight.w500, ), @@ -108,7 +108,7 @@ class _CommentsWidgetState extends State { s.answer, style: TextStyle( height: 1, - color: appTheme.grey, + color: appTheme.gray, fontSize: 12, fontWeight: FontWeight.w500, ), diff --git a/lib/features/feed/presentation/widgets/diets_widget.dart b/lib/features/feed/presentation/widgets/diets_widget.dart index ce8a9e15..2437c5ad 100644 --- a/lib/features/feed/presentation/widgets/diets_widget.dart +++ b/lib/features/feed/presentation/widgets/diets_widget.dart @@ -1,15 +1,27 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:eatvio_app/core/const.dart'; +import 'package:eatvio_app/core/widgets/bookmark_button.dart'; +import 'package:eatvio_app/core/widgets/diet_info_row.dart'; +import 'package:eatvio_app/core/widgets/feed_icon_button.dart'; import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; +import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart'; +import 'package:eatvio_app/theme/custom_text_style.dart'; import 'package:eatvio_app/theme/theme_helper.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_html/flutter_html.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:go_router/go_router.dart'; +import 'package:share_plus/share_plus.dart'; class DietsWidget extends StatefulWidget { final Diet diet; - - const DietsWidget({super.key, required this.diet}); + final int index; + const DietsWidget({ + super.key, + required this.diet, + required this.index, + }); @override State createState() => _DietsWidgetState(); @@ -18,21 +30,21 @@ class DietsWidget extends StatefulWidget { class _DietsWidgetState extends State { @override Widget build(BuildContext context) { - return InkWell( - borderRadius: BorderRadius.circular(12), - onTap: () => GoRouter.of(context).pushNamed('aboutDietScreen', extra: widget.diet), - child: Ink( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Stack( - children: [ - ClipRRect( + return DecoratedBox( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.white, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Stack( + children: [ + InkWell( + onTap: () => + GoRouter.of(context).pushNamed('aboutDietScreen', extra: {'diet': widget.diet, 'index': widget.index, 'navigateToComments': false}), + child: ClipRRect( borderRadius: BorderRadius.vertical(top: Radius.circular(12)), child: CachedNetworkImage( imageUrl: baseUrl + '/storage/' + widget.diet.image, @@ -40,148 +52,121 @@ class _DietsWidgetState extends State { width: MediaQuery.of(context).size.width, ), ), - Positioned( - left: 8, - bottom: 8, - child: Wrap( - runSpacing: 8, - children: [ - _iconButton(Icons.fastfood, '139.9 ккал'), - SizedBox(width: 8), - _iconButton(Icons.timer_rounded, widget.diet.state), - SizedBox(width: 8), - _iconButton(Icons.fast_forward_rounded, widget.diet.duration.toString()), - ], - ), - ), - Positioned( - left: 8, - top: 8, - child: Container( - padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4), - decoration: BoxDecoration( - color: Colors.white.withOpacity(0.8), - borderRadius: BorderRadius.circular(16), - ), - child: Row( - children: [ - Icon( - Icons.favorite_rounded, - size: 16, - color: Colors.black, - ), - SizedBox(width: 4), - Text( - widget.diet.totalLikes.toString(), - style: TextStyle( - fontSize: 12, - color: Colors.black, - fontWeight: FontWeight.w400, - ), - ), - ], - ), - ), - ), - Positioned( - right: 8, - top: 8, - child: Container( - padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4), - decoration: BoxDecoration( - color: Colors.white.withOpacity(0.8), - borderRadius: BorderRadius.circular(16), - ), - child: Row( - children: [ - Icon( - Icons.visibility_rounded, - size: 16, - color: Colors.black, - ), - SizedBox(width: 4), - Text( - widget.diet.totalViews.toString(), - style: TextStyle( - fontSize: 12, - color: Colors.black, - fontWeight: FontWeight.w400, - ), - ), - ], - ), - ), - ), - ], - ), - SizedBox(height: 12), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 12), - child: Text( - widget.diet.name, - style: TextStyle( - fontWeight: FontWeight.w600, - color: Colors.black87, - ), ), - ), - if (widget.diet.details.isNotEmpty) - Padding( - padding: const EdgeInsets.symmetric(horizontal: 4), - child: Html( - data: widget.diet.details.length > 200 ? widget.diet.details.substring(0, 200) : widget.diet.details, - style: { - "*": Style( - color: Colors.black87, - ), + Positioned( + right: 14, + child: BookmarkButton( + onTap: () async { + if (widget.diet.isFavorite) { + await context.read().removeDietFromFavorite(widget.diet.id, widget.index); + } else { + await context.read().addDietToFavorite(widget.diet.id, widget.index); + } }, + color: appTheme.whiteA700, + isFavorite: widget.diet.isFavorite, + borderRadius: BorderRadius.vertical(bottom: Radius.circular(12)), + width: 40, + height: 44, + size: 19, ), ), - if (widget.diet.details.length > 200) + Positioned( + bottom: 16, + child: SizedBox( + width: MediaQuery.sizeOf(context).width, + child: DietInfoRow( + diet: widget.diet, + itemsBackgroundColor: appTheme.whiteA700, + disableDescriptionOfTypes: true, + ), + ), + ), + ], + ), + SizedBox(height: 12), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Text( - 'Читать полностью...', - style: TextStyle( - height: 1, - color: appTheme.blueA400, - decoration: TextDecoration.underline, - ), + widget.diet.name, + style: TextStyles.textMSemibold.copyWith(color: appTheme.black), ), ), - SizedBox(height: 12), - ], - ), - ), - ); - } - - _iconButton(IconData icon, [String? text]) { - return Container( - padding: EdgeInsets.symmetric(horizontal: 12, vertical: 4), - decoration: BoxDecoration( - color: Colors.white.withOpacity(0.8), - borderRadius: BorderRadius.circular(16), - ), - height: 32, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Icon( - icon, - size: 16, - color: Colors.black, + if (widget.diet.details.isNotEmpty) ...[ + SizedBox( + height: 12, + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Html( + data: widget.diet.details.length > 200 ? widget.diet.details.substring(0, 200) + '...' : widget.diet.details, + style: { + "*": Style( + margin: Margins.zero, + color: appTheme.black, + fontSize: FontSize(TextStyles.textSMedium.fontSize ?? 14), + fontWeight: TextStyles.textSMedium.fontWeight ?? FontWeight.w400, + ), + }, + ), + ), + ], + ], ), - if (text != null) SizedBox(width: 8), - if (text != null) - Text( - text, - style: TextStyle( - fontSize: 12, - color: Colors.black, - fontWeight: FontWeight.w500, - ), + Padding( + padding: const EdgeInsets.only(left: 16, top: 12), + child: Row( + children: [ + FeedIconButton( + icon: widget.diet.wasLikedByMe ? Icons.favorite_rounded : Icons.favorite_border_rounded, + text: widget.diet.totalLikes.toString(), + iconColor: widget.diet.wasLikedByMe ? appTheme.blueA400 : null, + backgroundColor: widget.diet.wasLikedByMe ? appTheme.transparentBlue : null, + onTap: () async { + await context.read().likeDiet(widget.diet.id, widget.index); + }, + ), + SizedBox( + width: 12, + ), + FeedIconButton( + icon: Icons.chat_bubble_outline, + text: widget.diet.totalComments.toString(), + onTap: () => + GoRouter.of(context).pushNamed('aboutDietScreen', extra: {'diet': widget.diet, 'index': widget.index, 'navigateToComments': true}), + ), + SizedBox( + width: 12, + ), + FeedIconButton( + svgIcon: SvgPicture.asset('assets/icons/repost.svg'), + text: '0', + onTap: () async { + final result = await Share.shareUri( + Uri.parse( + baseUrl + '/ru/diet/' + widget.diet.id.toString(), + ), + ); + switch (result.status) { + case ShareResultStatus.success: + case ShareResultStatus.dismissed: + case ShareResultStatus.unavailable: + } + }, + ), + Spacer(), + FeedIconButton( + svgIcon: SvgPicture.asset('assets/icons/eye2.svg'), + text: widget.diet.totalViews.toString(), + backgroundColor: Colors.transparent, + ), + ], ), + ), + SizedBox(height: 12), ], ), ); diff --git a/lib/features/feed/presentation/widgets/filter_widget.dart b/lib/features/feed/presentation/widgets/filter_widget.dart new file mode 100644 index 00000000..ad652227 --- /dev/null +++ b/lib/features/feed/presentation/widgets/filter_widget.dart @@ -0,0 +1,24 @@ +import 'package:eatvio_app/theme/theme_helper.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class FilterWidget extends StatelessWidget { + const FilterWidget({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.only(left: 20, top: 12, bottom: 12, right: 24), + width: 70, + decoration: BoxDecoration( + color: appTheme.blueA400, + borderRadius: BorderRadius.horizontal(left: Radius.circular(100)), + ), + child: SvgPicture.asset( + 'assets/icons/filter2.svg', + width: 24, + height: 16, + ), + ); + } +} diff --git a/lib/features/feed/repositories/feed_repository.dart b/lib/features/feed/repositories/feed_repository.dart index 459923fc..0556029c 100644 --- a/lib/features/feed/repositories/feed_repository.dart +++ b/lib/features/feed/repositories/feed_repository.dart @@ -153,4 +153,5 @@ class FeedRepository { rethrow; } } + } diff --git a/lib/features/feed/services/feed_service.dart b/lib/features/feed/services/feed_service.dart index 1321fa6b..579d20c1 100644 --- a/lib/features/feed/services/feed_service.dart +++ b/lib/features/feed/services/feed_service.dart @@ -74,5 +74,6 @@ abstract class FeedService { @POST('/api/blogPosts/{id}/unliked') Future unlikedBlogPost({ @Path() required int id, - }); + }); + } diff --git a/lib/generated/intl/messages_all.dart b/lib/generated/intl/messages_all.dart index b6510a8a..203415cc 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 42f0d564..427c3a5e 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("Углеводы"), @@ -51,11 +51,11 @@ class MessageLookup extends MessageLookupByLibrary { "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("Город"), @@ -70,7 +70,7 @@ class MessageLookup extends MessageLookupByLibrary { "copy_link": MessageLookupByLibrary.simpleMessage("Скопировать ссылку"), "corb_type": MessageLookupByLibrary.simpleMessage("Мучное"), "corb_type_desc": MessageLookupByLibrary.simpleMessage( - "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы.",), + "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы."), "country": MessageLookupByLibrary.simpleMessage("Страна"), "date_of_birth": MessageLookupByLibrary.simpleMessage("Дата рождения"), "day": MessageLookupByLibrary.simpleMessage("День"), @@ -83,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("Выйти"), @@ -102,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": @@ -126,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("Ссылка успешно скопирована"), @@ -137,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("Сетевая ошибка!"), @@ -146,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("У меня нет аккаунта"), @@ -158,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("Место проживания"), @@ -169,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("Сохранить"), @@ -180,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": @@ -192,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("Обхват талии"), @@ -203,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": @@ -211,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 2cc942c5..90f32100 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!; } diff --git a/lib/locator_service.dart b/lib/locator_service.dart index c459e3fd..8afebb45 100644 --- a/lib/locator_service.dart +++ b/lib/locator_service.dart @@ -1,5 +1,7 @@ import 'package:dio/dio.dart'; import 'package:eatvio_app/core/const.dart'; +import 'package:eatvio_app/core/data/diet/repositories/diet_repository.dart'; +import 'package:eatvio_app/core/data/diet/services/diet_service.dart'; import 'package:eatvio_app/core/initialization_cubit/initialization_cubit.dart'; import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/new_messages_cubit/new_messages_cubit.dart'; import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/notifications_cubit/notifications_cubit.dart'; @@ -18,8 +20,6 @@ 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'; @@ -62,7 +62,7 @@ Future init() async { sl.registerFactory(() => ProfileCubit(profileRepository: sl(), chatRepository: sl())); sl.registerFactory(() => ProfileAvatarCubit(profileRepository: sl())); sl.registerFactory(() => RecipeCreateCubit(recipeRepository: sl())); - sl.registerFactory(() => DietsCubit(feedRepository: sl())); + sl.registerFactory(() => DietsCubit(feedRepository: sl(), dietsRepository: sl())); sl.registerFactory(() => CommentsCubit(feedRepository: sl())); sl.registerFactory(() => ChatSelectCubit(chatRepository: sl())); sl.registerFactory(() => PlansCubit(plansRepository: sl())); @@ -83,7 +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())); + sl.registerLazySingleton(() => DietRepository(dietsService: sl())); // Services sl.registerLazySingleton(() => ChatService(sl())); @@ -97,9 +97,8 @@ Future init() async { sl.registerLazySingleton(() => ConsultantService(sl())); sl.registerLazySingleton(() => DiaryService(sl())); sl.registerLazySingleton(() => GlossaryService(sl())); - sl.registerLazySingleton(() => DietsService(sl())); - - + sl.registerLazySingleton(() => DietService(sl())); + // External sl.registerLazySingleton( () => Dio( diff --git a/lib/theme/app_decoration.dart b/lib/theme/app_decoration.dart index 3868338c..b84dc7fe 100644 --- a/lib/theme/app_decoration.dart +++ b/lib/theme/app_decoration.dart @@ -54,7 +54,7 @@ class AppDecoration { static BoxDecoration get outlineBlueGray => BoxDecoration( border: Border.all( - color: appTheme.blueGray800, + color: appTheme.black, width: 1, strokeAlign: strokeAlignOutside, ), @@ -90,7 +90,7 @@ class BorderRadiusStyle { static BoxDecoration get outlineBlueGray => BoxDecoration( border: Border.all( - color: appTheme.blueGray800, + color: appTheme.black, width: 1, strokeAlign: strokeAlignOutside, ), diff --git a/lib/theme/custom_text_style.dart b/lib/theme/custom_text_style.dart index 59f10924..dcc15aea 100644 --- a/lib/theme/custom_text_style.dart +++ b/lib/theme/custom_text_style.dart @@ -24,15 +24,15 @@ class CustomTextStyles { ); static get bodyMediumBluegray800 => theme.textTheme.bodyMedium!.copyWith( - color: appTheme.blueGray800, + color: appTheme.black, ); static get bodyMediumBluegray800_1 => theme.textTheme.bodyMedium!.copyWith( - color: appTheme.blueGray800, + color: appTheme.black, ); static get bodyMediumBluegray800_2 => theme.textTheme.bodyMedium!.copyWith( - color: appTheme.blueGray800, + color: appTheme.black, ); static get bodyMediumWhiteA700 => theme.textTheme.bodyMedium!.copyWith( @@ -45,17 +45,17 @@ class CustomTextStyles { ); static get bodySmallMulishBluegray800 => theme.textTheme.bodySmall!.mulish.copyWith( - color: appTheme.blueGray800, + color: appTheme.black, fontSize: 12, ); static get bodySmallMulishBluegray80012 => theme.textTheme.bodySmall!.mulish.copyWith( - color: appTheme.blueGray800, + color: appTheme.black, fontSize: 12, ); static get bodySmallMulishBluegray80012_1 => theme.textTheme.bodySmall!.mulish.copyWith( - color: appTheme.blueGray800, + color: appTheme.black, fontSize: 12, ); @@ -116,16 +116,16 @@ class CustomTextStyles { ); static get titleSmallBluegray800 => theme.textTheme.titleSmall!.copyWith( - color: appTheme.blueGray800, + color: appTheme.black, ); static get titleSmallBluegray800Bold => theme.textTheme.titleSmall!.copyWith( - color: appTheme.blueGray800, + color: appTheme.black, fontWeight: FontWeight.w700, ); static get titleSmallBluegray800ExtraBold => theme.textTheme.titleSmall!.copyWith( - color: appTheme.blueGray800, + color: appTheme.black, fontWeight: FontWeight.w800, ); @@ -165,8 +165,6 @@ class CustomTextStyles { static get titleSmallSegoeUIOnPrimary => theme.textTheme.titleSmall!.segoeUI.copyWith( color: theme.colorScheme.onPrimary, ); - - } extension on TextStyle { @@ -179,4 +177,52 @@ extension on TextStyle { } } +abstract class TextStyles { + static const headingXLSemibold = TextStyle( + fontSize: 20, + fontWeight: FontWeight.w600, + height: 1.255, + ); + static const textLSemibold = TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + height: 1.255, + ); + + static const textMSemibold = TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + height: 1.255, + ); + + static const textMMedium = TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + height: 1, + ); + + static const textMMediumAuto = TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + height: 1.255, + ); + + static const textSSemibold = TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + height: 1.255, + ); + + static const textSMedium = TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + height: 1.255, + ); + + static const textXSSemibold = TextStyle( + fontSize: 12, + fontWeight: FontWeight.w500, + height: 1.255, + ); +} diff --git a/lib/theme/theme_helper.dart b/lib/theme/theme_helper.dart index d0a8635e..c29978b4 100644 --- a/lib/theme/theme_helper.dart +++ b/lib/theme/theme_helper.dart @@ -114,7 +114,7 @@ class PrimaryColors { // BlueGray Color get blueGray300 => Color(0XFF9AA5B1); - Color get blueGray800 => Color(0XFF323F4B); + Color get black => Color(0XFF323F4B); Color get blueGray900 => Color(0XFF2A2F4C); @@ -169,9 +169,13 @@ class PrimaryColors { Color get dividerColor => Color(0xFFF1F2F6); - Color get grey => Color(0xFF6D6F71); + Color get gray => Color(0xFF6D6F71); - Color get lightGrey => Color(0xFFCECECE); + Color get lightGray600 => Color(0xFFB0B0B0); + + Color get lightGray => Color(0xFFCECECE); + + Color get transparentBlue => Color(0xFF2F80ED).withOpacity(0.1); } PrimaryColors get appTheme => ThemeHelper().themeColor(); From 64baf15cbdea734e9a5a61a3d0d92d4c96411ec8 Mon Sep 17 00:00:00 2001 From: Username1548 Date: Thu, 14 Nov 2024 17:31:59 +0700 Subject: [PATCH 2/5] fixed analyzer errors --- .../presentation/pages/diary_screen.dart | 8 +-- .../feed/models/diets_pagination_model.dart | 1 - lib/generated/intl/messages_all.dart | 2 +- lib/generated/intl/messages_en.dart | 54 +++++++++---------- lib/generated/l10n.dart | 4 +- 5 files changed, 34 insertions(+), 35 deletions(-) diff --git a/lib/features/diary/presentation/pages/diary_screen.dart b/lib/features/diary/presentation/pages/diary_screen.dart index 79f9ac2f..88a8b1b0 100644 --- a/lib/features/diary/presentation/pages/diary_screen.dart +++ b/lib/features/diary/presentation/pages/diary_screen.dart @@ -505,16 +505,16 @@ class _DiaryScreenState extends State { Column( children: [ _chartData('Калории', - '${nutrition.dailyNutritionIntake.energy.toStringAsFixed(0)} из ${nutrition.dailyNutritionRecommendation.energy.toStringAsFixed(0)} ккал'), + '${nutrition.dailyNutritionIntake.energy.toStringAsFixed(0)} из ${nutrition.dailyNutritionRecommendation.energy.toStringAsFixed(0)} ккал',), const SizedBox(height: 8), _chartData('Белки', - '${nutrition.dailyNutritionIntake.proteins.toStringAsFixed(0)} из ${nutrition.dailyNutritionRecommendation.proteins.toStringAsFixed(0)} грамм'), + '${nutrition.dailyNutritionIntake.proteins.toStringAsFixed(0)} из ${nutrition.dailyNutritionRecommendation.proteins.toStringAsFixed(0)} грамм',), const SizedBox(height: 8), _chartData('Жиры', - '${nutrition.dailyNutritionIntake.fats.toStringAsFixed(0)} из ${nutrition.dailyNutritionRecommendation.fats.toStringAsFixed(0)} грамм'), + '${nutrition.dailyNutritionIntake.fats.toStringAsFixed(0)} из ${nutrition.dailyNutritionRecommendation.fats.toStringAsFixed(0)} грамм',), const SizedBox(height: 8), _chartData('Углеводы', - '${nutrition.dailyNutritionIntake.carbohydrates.toStringAsFixed(0)} из ${nutrition.dailyNutritionRecommendation.carbohydrates.toStringAsFixed(0)} грамм'), + '${nutrition.dailyNutritionIntake.carbohydrates.toStringAsFixed(0)} из ${nutrition.dailyNutritionRecommendation.carbohydrates.toStringAsFixed(0)} грамм',), ], ), ], diff --git a/lib/features/feed/models/diets_pagination_model.dart b/lib/features/feed/models/diets_pagination_model.dart index c3be8c4f..462b899d 100644 --- a/lib/features/feed/models/diets_pagination_model.dart +++ b/lib/features/feed/models/diets_pagination_model.dart @@ -1,4 +1,3 @@ -import 'package:eatvio_app/core/data/diet/repositories/diet_repository.dart'; import 'package:eatvio_app/core/models/pagination_model.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; 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 427c3a5e..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("Углеводы"), @@ -51,11 +51,11 @@ class MessageLookup extends MessageLookupByLibrary { "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("Город"), @@ -70,7 +70,7 @@ class MessageLookup extends MessageLookupByLibrary { "copy_link": MessageLookupByLibrary.simpleMessage("Скопировать ссылку"), "corb_type": MessageLookupByLibrary.simpleMessage("Мучное"), "corb_type_desc": MessageLookupByLibrary.simpleMessage( - "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы."), + "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы.",), "country": MessageLookupByLibrary.simpleMessage("Страна"), "date_of_birth": MessageLookupByLibrary.simpleMessage("Дата рождения"), "day": MessageLookupByLibrary.simpleMessage("День"), @@ -83,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("Выйти"), @@ -102,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": @@ -126,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("Ссылка успешно скопирована"), @@ -137,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("Сетевая ошибка!"), @@ -146,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("У меня нет аккаунта"), @@ -158,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("Место проживания"), @@ -169,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("Сохранить"), @@ -180,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": @@ -192,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("Обхват талии"), @@ -203,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": @@ -211,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 90f32100..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!; } From 00da6528607be65531173c709dc05bb4cf04f714 Mon Sep 17 00:00:00 2001 From: Username1548 Date: Fri, 15 Nov 2024 19:07:15 +0700 Subject: [PATCH 3/5] fixed likes and favourite sync and adeded filter leayoutfor diets --- .../data/diet/models/diet_likes_model.dart | 14 ++ .../diet/models/diet_likes_model.freezed.dart | 197 ++++++++++++++++++ .../data/diet/models/diet_likes_model.g.dart | 20 ++ .../diet/repositories/diet_repository.dart | 13 +- lib/core/data/diet/services/diet_service.dart | 7 +- .../data/diet/services/diet_service.g.dart | 42 +++- .../widgets/bottom_sheet_handler_bar.dart | 15 ++ .../presentation/bloc/about_diet_cubit.dart | 23 +- .../widgets/start_diet_bottom_sheet.dart | 7 +- .../bloc/diets_cubit/diets_cubit.dart | 37 +++- .../feed/presentation/pages/feed_screen.dart | 73 ++++++- .../widgets/choice_chip_widget.dart | 32 +++ .../widgets/diet_filter_bottom_sheet.dart | 97 +++++++++ .../presentation/widgets/diets_widget.dart | 1 - .../duration_choice_filter_widget.dart | 84 ++++++++ .../presentation/widgets/filter_badge.dart | 34 +++ .../presentation/widgets/filter_widget.dart | 24 --- .../widgets/type_choice_filter_widget.dart | 97 +++++++++ lib/features/feed/services/feed_service.dart | 2 +- lib/generated/intl/messages_all.dart | 2 +- lib/generated/intl/messages_en.dart | 58 +++--- lib/generated/l10n.dart | 44 +++- lib/l10n/intl_en.arb | 6 +- lib/theme/theme_helper.dart | 2 + 24 files changed, 831 insertions(+), 100 deletions(-) create mode 100644 lib/core/data/diet/models/diet_likes_model.dart create mode 100644 lib/core/data/diet/models/diet_likes_model.freezed.dart create mode 100644 lib/core/data/diet/models/diet_likes_model.g.dart create mode 100644 lib/core/widgets/bottom_sheet_handler_bar.dart create mode 100644 lib/features/feed/presentation/widgets/choice_chip_widget.dart create mode 100644 lib/features/feed/presentation/widgets/diet_filter_bottom_sheet.dart create mode 100644 lib/features/feed/presentation/widgets/duration_choice_filter_widget.dart create mode 100644 lib/features/feed/presentation/widgets/filter_badge.dart delete mode 100644 lib/features/feed/presentation/widgets/filter_widget.dart create mode 100644 lib/features/feed/presentation/widgets/type_choice_filter_widget.dart diff --git a/lib/core/data/diet/models/diet_likes_model.dart b/lib/core/data/diet/models/diet_likes_model.dart new file mode 100644 index 00000000..eaa2d615 --- /dev/null +++ b/lib/core/data/diet/models/diet_likes_model.dart @@ -0,0 +1,14 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'diet_likes_model.freezed.dart'; +part 'diet_likes_model.g.dart'; + +@freezed +class DietLikesModel with _$DietLikesModel { + const factory DietLikesModel({ + @JsonKey(name: 'total_likers') required int totalLikes, + @JsonKey(name: 'is_liked') required bool isLiked, + }) = _DietLikesModel; + + factory DietLikesModel.fromJson(Map json) => _$DietLikesModelFromJson(json); +} \ No newline at end of file diff --git a/lib/core/data/diet/models/diet_likes_model.freezed.dart b/lib/core/data/diet/models/diet_likes_model.freezed.dart new file mode 100644 index 00000000..7c1b630d --- /dev/null +++ b/lib/core/data/diet/models/diet_likes_model.freezed.dart @@ -0,0 +1,197 @@ +// 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 'diet_likes_model.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'); + +DietLikesModel _$DietLikesModelFromJson(Map json) { + return _DietLikesModel.fromJson(json); +} + +/// @nodoc +mixin _$DietLikesModel { + @JsonKey(name: 'total_likers') + int get totalLikes => throw _privateConstructorUsedError; + @JsonKey(name: 'is_liked') + bool get isLiked => throw _privateConstructorUsedError; + + /// Serializes this DietLikesModel to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of DietLikesModel + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $DietLikesModelCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $DietLikesModelCopyWith<$Res> { + factory $DietLikesModelCopyWith( + DietLikesModel value, $Res Function(DietLikesModel) then) = + _$DietLikesModelCopyWithImpl<$Res, DietLikesModel>; + @useResult + $Res call( + {@JsonKey(name: 'total_likers') int totalLikes, + @JsonKey(name: 'is_liked') bool isLiked}); +} + +/// @nodoc +class _$DietLikesModelCopyWithImpl<$Res, $Val extends DietLikesModel> + implements $DietLikesModelCopyWith<$Res> { + _$DietLikesModelCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of DietLikesModel + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? totalLikes = null, + Object? isLiked = null, + }) { + return _then(_value.copyWith( + totalLikes: null == totalLikes + ? _value.totalLikes + : totalLikes // ignore: cast_nullable_to_non_nullable + as int, + isLiked: null == isLiked + ? _value.isLiked + : isLiked // ignore: cast_nullable_to_non_nullable + as bool, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$DietLikesModelImplCopyWith<$Res> + implements $DietLikesModelCopyWith<$Res> { + factory _$$DietLikesModelImplCopyWith(_$DietLikesModelImpl value, + $Res Function(_$DietLikesModelImpl) then) = + __$$DietLikesModelImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {@JsonKey(name: 'total_likers') int totalLikes, + @JsonKey(name: 'is_liked') bool isLiked}); +} + +/// @nodoc +class __$$DietLikesModelImplCopyWithImpl<$Res> + extends _$DietLikesModelCopyWithImpl<$Res, _$DietLikesModelImpl> + implements _$$DietLikesModelImplCopyWith<$Res> { + __$$DietLikesModelImplCopyWithImpl( + _$DietLikesModelImpl _value, $Res Function(_$DietLikesModelImpl) _then) + : super(_value, _then); + + /// Create a copy of DietLikesModel + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? totalLikes = null, + Object? isLiked = null, + }) { + return _then(_$DietLikesModelImpl( + totalLikes: null == totalLikes + ? _value.totalLikes + : totalLikes // ignore: cast_nullable_to_non_nullable + as int, + isLiked: null == isLiked + ? _value.isLiked + : isLiked // ignore: cast_nullable_to_non_nullable + as bool, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$DietLikesModelImpl implements _DietLikesModel { + const _$DietLikesModelImpl( + {@JsonKey(name: 'total_likers') required this.totalLikes, + @JsonKey(name: 'is_liked') required this.isLiked}); + + factory _$DietLikesModelImpl.fromJson(Map json) => + _$$DietLikesModelImplFromJson(json); + + @override + @JsonKey(name: 'total_likers') + final int totalLikes; + @override + @JsonKey(name: 'is_liked') + final bool isLiked; + + @override + String toString() { + return 'DietLikesModel(totalLikes: $totalLikes, isLiked: $isLiked)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$DietLikesModelImpl && + (identical(other.totalLikes, totalLikes) || + other.totalLikes == totalLikes) && + (identical(other.isLiked, isLiked) || other.isLiked == isLiked)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash(runtimeType, totalLikes, isLiked); + + /// Create a copy of DietLikesModel + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$DietLikesModelImplCopyWith<_$DietLikesModelImpl> get copyWith => + __$$DietLikesModelImplCopyWithImpl<_$DietLikesModelImpl>( + this, _$identity); + + @override + Map toJson() { + return _$$DietLikesModelImplToJson( + this, + ); + } +} + +abstract class _DietLikesModel implements DietLikesModel { + const factory _DietLikesModel( + {@JsonKey(name: 'total_likers') required final int totalLikes, + @JsonKey(name: 'is_liked') required final bool isLiked}) = + _$DietLikesModelImpl; + + factory _DietLikesModel.fromJson(Map json) = + _$DietLikesModelImpl.fromJson; + + @override + @JsonKey(name: 'total_likers') + int get totalLikes; + @override + @JsonKey(name: 'is_liked') + bool get isLiked; + + /// Create a copy of DietLikesModel + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$DietLikesModelImplCopyWith<_$DietLikesModelImpl> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/lib/core/data/diet/models/diet_likes_model.g.dart b/lib/core/data/diet/models/diet_likes_model.g.dart new file mode 100644 index 00000000..36ddacba --- /dev/null +++ b/lib/core/data/diet/models/diet_likes_model.g.dart @@ -0,0 +1,20 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'diet_likes_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$DietLikesModelImpl _$$DietLikesModelImplFromJson(Map json) => + _$DietLikesModelImpl( + totalLikes: (json['total_likers'] as num).toInt(), + isLiked: json['is_liked'] as bool, + ); + +Map _$$DietLikesModelImplToJson( + _$DietLikesModelImpl instance) => + { + 'total_likers': instance.totalLikes, + 'is_liked': instance.isLiked, + }; diff --git a/lib/core/data/diet/repositories/diet_repository.dart b/lib/core/data/diet/repositories/diet_repository.dart index 5e78ae33..aff946b7 100644 --- a/lib/core/data/diet/repositories/diet_repository.dart +++ b/lib/core/data/diet/repositories/diet_repository.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:eatvio_app/core/data/diet/models/diet_likes_model.dart'; import 'package:eatvio_app/core/data/diet/services/diet_service.dart'; import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; import 'package:equatable/equatable.dart'; @@ -15,9 +16,9 @@ class DietRepository { Stream get dietFavoriteState => _dietFavoriteStateStreamController.stream; Stream get dietCommentsState => _dietCommentsStateStreamController.stream; - Future likeDiet(int id) async { + Future likeDiet(int id) async { try { - await dietsService.likeDiet(id: id); + return await dietsService.likeDiet(id: id); } catch (e) { rethrow; } @@ -32,17 +33,17 @@ class DietRepository { } } - Future addToFavorite(int id) async { + Future addToFavorite(int id) async { try { - await dietsService.addToFavorite(id: id); + return await dietsService.addToFavorite(id: id); } catch (e) { rethrow; } } - Future removeFromFavorite(int id) async { + Future removeFromFavorite(int id) async { try { - await dietsService.removeFromFavorite(id: id); + return await dietsService.removeFromFavorite(id: id); } catch (e) { rethrow; } diff --git a/lib/core/data/diet/services/diet_service.dart b/lib/core/data/diet/services/diet_service.dart index fec1966c..4baffdcb 100644 --- a/lib/core/data/diet/services/diet_service.dart +++ b/lib/core/data/diet/services/diet_service.dart @@ -1,4 +1,5 @@ import 'package:dio/dio.dart'; +import 'package:eatvio_app/core/data/diet/models/diet_likes_model.dart'; import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; import 'package:retrofit/retrofit.dart'; @@ -9,17 +10,17 @@ abstract class DietService { factory DietService(Dio dio, {String baseUrl}) = _DietService; @POST('/api/diets/{id}/like') - Future likeDiet({ + Future likeDiet({ @Path() required int id, }); @POST('/api/diets/{id}/add_to_favorite') - Future addToFavorite({ + Future addToFavorite({ @Path() required int id, }); @POST('/api/diets/{id}/remove_from_favorite') - Future removeFromFavorite({ + Future removeFromFavorite({ @Path() required int id, }); diff --git a/lib/core/data/diet/services/diet_service.g.dart b/lib/core/data/diet/services/diet_service.g.dart index db4a1f56..63e35fb5 100644 --- a/lib/core/data/diet/services/diet_service.g.dart +++ b/lib/core/data/diet/services/diet_service.g.dart @@ -22,12 +22,12 @@ class _DietService implements DietService { final ParseErrorLogger? errorLogger; @override - Future likeDiet({required int id}) async { + Future likeDiet({required int id}) async { final _extra = {}; final queryParameters = {}; final _headers = {}; const Map? _data = null; - final _options = _setStreamType(Options( + final _options = _setStreamType(Options( method: 'POST', headers: _headers, extra: _extra, @@ -43,16 +43,24 @@ class _DietService implements DietService { _dio.options.baseUrl, baseUrl, ))); - await _dio.fetch(_options); + final _result = await _dio.fetch>(_options); + late DietLikesModel _value; + try { + _value = DietLikesModel.fromJson(_result.data!); + } on Object catch (e, s) { + errorLogger?.logError(e, s, _options); + rethrow; + } + return _value; } @override - Future addToFavorite({required int id}) async { + Future addToFavorite({required int id}) async { final _extra = {}; final queryParameters = {}; final _headers = {}; const Map? _data = null; - final _options = _setStreamType(Options( + final _options = _setStreamType(Options( method: 'POST', headers: _headers, extra: _extra, @@ -68,16 +76,24 @@ class _DietService implements DietService { _dio.options.baseUrl, baseUrl, ))); - await _dio.fetch(_options); + final _result = await _dio.fetch>(_options); + late Diet _value; + try { + _value = Diet.fromJson(_result.data!); + } on Object catch (e, s) { + errorLogger?.logError(e, s, _options); + rethrow; + } + return _value; } @override - Future removeFromFavorite({required int id}) async { + Future removeFromFavorite({required int id}) async { final _extra = {}; final queryParameters = {}; final _headers = {}; const Map? _data = null; - final _options = _setStreamType(Options( + final _options = _setStreamType(Options( method: 'POST', headers: _headers, extra: _extra, @@ -93,7 +109,15 @@ class _DietService implements DietService { _dio.options.baseUrl, baseUrl, ))); - await _dio.fetch(_options); + final _result = await _dio.fetch>(_options); + late Diet _value; + try { + _value = Diet.fromJson(_result.data!); + } on Object catch (e, s) { + errorLogger?.logError(e, s, _options); + rethrow; + } + return _value; } @override diff --git a/lib/core/widgets/bottom_sheet_handler_bar.dart b/lib/core/widgets/bottom_sheet_handler_bar.dart new file mode 100644 index 00000000..1645fda5 --- /dev/null +++ b/lib/core/widgets/bottom_sheet_handler_bar.dart @@ -0,0 +1,15 @@ +import 'package:eatvio_app/theme/theme_helper.dart'; +import 'package:flutter/material.dart'; + +class BottomSheetHandlerBar extends StatelessWidget { + const BottomSheetHandlerBar({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + height: 4, + width: 40, + decoration: BoxDecoration(color: appTheme.lightGray, borderRadius: BorderRadius.circular(20)), + ); + } +} diff --git a/lib/features/diets/presentation/bloc/about_diet_cubit.dart b/lib/features/diets/presentation/bloc/about_diet_cubit.dart index 498f15ea..14fa564b 100644 --- a/lib/features/diets/presentation/bloc/about_diet_cubit.dart +++ b/lib/features/diets/presentation/bloc/about_diet_cubit.dart @@ -59,8 +59,13 @@ class AboutDietCubit extends Cubit { Duration(seconds: 1), () async { try { - await dietsRepository.likeDiet(id); - await getDiet(id); + final dietLikeStateData = await dietsRepository.likeDiet(id); + final actualDiet = currentDiet.copyWith( + wasLikedByMe: dietLikeStateData.isLiked, + totalLikes: dietLikeStateData.totalLikes, + ); + emit(AboutDietState.loaded(actualDiet)); + dietsRepository.emitLikesStateToFeed(DietLikesState(wasLikedByMe: actualDiet.wasLikedByMe, totalLikes: actualDiet.totalLikes, index: dietIndexInFeed)); } catch (e) { log(e.toString()); dietsRepository @@ -87,10 +92,9 @@ class AboutDietCubit extends Cubit { Duration(seconds: 1), () async { try { - await dietsRepository.addToFavorite(id); - Future.delayed(const Duration(seconds: 1), () async { - await getDiet(id); - }); + final diet = await dietsRepository.addToFavorite(id); + emit(AboutDietState.loaded(diet)); + dietsRepository.emitFavoriteStateToFeed(DietFavoriteState(isFavorite: diet.isFavorite, index: dietIndexInFeed)); } catch (e) { log(e.toString()); dietsRepository.emitFavoriteStateToFeed(DietFavoriteState(isFavorite: currentDiet.isFavorite, index: dietIndexInFeed)); @@ -116,10 +120,9 @@ class AboutDietCubit extends Cubit { Duration(seconds: 1), () async { try { - await dietsRepository.removeFromFavorite(id); - Future.delayed(const Duration(seconds: 1), () async { - await getDiet(id); - }); + final diet = await dietsRepository.removeFromFavorite(id); + emit(AboutDietState.loaded(diet)); + dietsRepository.emitFavoriteStateToFeed(DietFavoriteState(isFavorite: diet.isFavorite, index: dietIndexInFeed)); } catch (e) { log(e.toString()); dietsRepository.emitFavoriteStateToFeed(DietFavoriteState(isFavorite: currentDiet.isFavorite, index: dietIndexInFeed)); diff --git a/lib/features/diets/presentation/widgets/start_diet_bottom_sheet.dart b/lib/features/diets/presentation/widgets/start_diet_bottom_sheet.dart index 100c706d..63facccf 100644 --- a/lib/features/diets/presentation/widgets/start_diet_bottom_sheet.dart +++ b/lib/features/diets/presentation/widgets/start_diet_bottom_sheet.dart @@ -1,3 +1,4 @@ +import 'package:eatvio_app/core/widgets/bottom_sheet_handler_bar.dart'; import 'package:eatvio_app/core/widgets/custom_divider.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/calendar_widget.dart'; import 'package:eatvio_app/generated/l10n.dart'; @@ -16,11 +17,7 @@ class StartDietBottomSheet extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ SizedBox(height: 4), - Container( - height: 4, - width: 40, - decoration: BoxDecoration(color: appTheme.lightGray, borderRadius: BorderRadius.circular(20)), - ), + BottomSheetHandlerBar(), SizedBox(height: 12), Text( s.startDiet, 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 476b1e97..745df313 100644 --- a/lib/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart +++ b/lib/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart @@ -132,7 +132,20 @@ class DietsCubit extends Cubit { Duration(milliseconds: 200), () async { try { - await dietsRepository.likeDiet(id); + final dietLikeStateData = await dietsRepository.likeDiet(id); + final actualDiet = currentDiet.copyWith( + wasLikedByMe: dietLikeStateData.isLiked, + totalLikes: dietLikeStateData.totalLikes, + ); + dietsForModification[index] = actualDiet; + emit( + DietsState.loaded( + dietsList: [ + ...dietsForModification, + ], + isLoading: isLoading, + ), + ); } catch (e) { log(e.toString()); emit( @@ -231,7 +244,16 @@ class DietsCubit extends Cubit { Duration(milliseconds: 200), () async { try { - await dietsRepository.addToFavorite(id); + final diet = await dietsRepository.addToFavorite(id); + dietsForModification[index] = diet; + emit( + DietsState.loaded( + dietsList: [ + ...dietsForModification, + ], + isLoading: isLoading, + ), + ); } catch (e) { log(e.toString()); emit( @@ -269,7 +291,16 @@ class DietsCubit extends Cubit { Duration(milliseconds: 200), () async { try { - await dietsRepository.removeFromFavorite(id); + final diet = await dietsRepository.removeFromFavorite(id); + dietsForModification[index] = diet; + emit( + DietsState.loaded( + dietsList: [ + ...dietsForModification, + ], + isLoading: isLoading, + ), + ); } catch (e) { log(e.toString()); emit( diff --git a/lib/features/feed/presentation/pages/feed_screen.dart b/lib/features/feed/presentation/pages/feed_screen.dart index 00cc21ba..00f334e5 100644 --- a/lib/features/feed/presentation/pages/feed_screen.dart +++ b/lib/features/feed/presentation/pages/feed_screen.dart @@ -6,8 +6,10 @@ import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_state import 'package:eatvio_app/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/recipes_cubit/recipes_state.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/blog_post_widget.dart'; +import 'package:eatvio_app/features/feed/presentation/widgets/choice_chip_widget.dart'; +import 'package:eatvio_app/features/feed/presentation/widgets/diet_filter_bottom_sheet.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/diets_widget.dart'; -import 'package:eatvio_app/features/feed/presentation/widgets/filter_widget.dart'; +import 'package:eatvio_app/features/feed/presentation/widgets/filter_badge.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/plan_widget.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/recipes_widget.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/tags_modal_widget.dart'; @@ -300,7 +302,9 @@ class _FeedScreenState extends State { Positioned( right: 0, bottom: 74, - child: FilterWidget(), + child: FilterBadge( + filterBottomSheet: DietFilterBottomSheet(), + ), ), ], ); @@ -394,15 +398,70 @@ class _FeedScreenState extends State { scrollDirection: Axis.horizontal, child: Row( children: [ - _choiceChipWidget(0), + ChoiceChipWidget( + index: 0, + selectedChipIndex: _selectedChipIndex, + chipsLabelList: chipsLabelList, + onSelected: (bool selected) { + setState(() { + _selectedChipIndex = 0; + searchController.clear(); + FocusScope.of(context).requestFocus(new FocusNode()); + }); + }, + ), SizedBox(width: 8), - _choiceChipWidget(1), + ChoiceChipWidget( + index: 1, + selectedChipIndex: _selectedChipIndex, + chipsLabelList: chipsLabelList, + onSelected: (bool selected) { + setState(() { + _selectedChipIndex = 1; + searchController.clear(); + FocusScope.of(context).requestFocus(new FocusNode()); + }); + }, + ), SizedBox(width: 8), - _choiceChipWidget(2), + ChoiceChipWidget( + index: 2, + selectedChipIndex: _selectedChipIndex, + chipsLabelList: chipsLabelList, + onSelected: (bool selected) { + setState(() { + _selectedChipIndex = 2; + searchController.clear(); + FocusScope.of(context).requestFocus(new FocusNode()); + }); + }, + ), SizedBox(width: 8), - _choiceChipWidget(3), + ChoiceChipWidget( + index: 3, + selectedChipIndex: _selectedChipIndex, + chipsLabelList: chipsLabelList, + onSelected: (bool selected) { + setState(() { + _selectedChipIndex = 3; + searchController.clear(); + FocusScope.of(context).requestFocus(new FocusNode()); + }); + }, + ), SizedBox(width: 8), - _choiceChipWidget(4), + ChoiceChipWidget( + index: 4, + selectedChipIndex: _selectedChipIndex, + chipsLabelList: chipsLabelList, + onSelected: (bool selected) { + setState(() { + _selectedChipIndex = 4; + searchController.clear(); + FocusScope.of(context).requestFocus(new FocusNode()); + }); + }, + ), ], ), ), diff --git a/lib/features/feed/presentation/widgets/choice_chip_widget.dart b/lib/features/feed/presentation/widgets/choice_chip_widget.dart new file mode 100644 index 00000000..acadd0d7 --- /dev/null +++ b/lib/features/feed/presentation/widgets/choice_chip_widget.dart @@ -0,0 +1,32 @@ +import 'package:eatvio_app/theme/theme_helper.dart'; +import 'package:flutter/material.dart'; + +class ChoiceChipWidget extends StatelessWidget { + const ChoiceChipWidget({super.key, required this.chipsLabelList, required this.index, required this.selectedChipIndex, required this.onSelected}); + final List chipsLabelList; + final int index; + final int selectedChipIndex; + final void Function(bool) onSelected; + @override + Widget build(BuildContext context) { + return ChoiceChip( + selectedColor: appTheme.blueA400, + pressElevation: 0, + showCheckmark: false, + side: BorderSide.none, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + label: Text(chipsLabelList[index]), + labelStyle: TextStyle( + color: index == selectedChipIndex ? Colors.white : appTheme.gray600, + fontWeight: FontWeight.w500, + fontSize: 12, + ), + selected: selectedChipIndex == index, + backgroundColor: appTheme.gray100, + onSelected: onSelected, + ); + } +} diff --git a/lib/features/feed/presentation/widgets/diet_filter_bottom_sheet.dart b/lib/features/feed/presentation/widgets/diet_filter_bottom_sheet.dart new file mode 100644 index 00000000..f9bd41f5 --- /dev/null +++ b/lib/features/feed/presentation/widgets/diet_filter_bottom_sheet.dart @@ -0,0 +1,97 @@ +import 'package:eatvio_app/core/widgets/bottom_sheet_handler_bar.dart'; +import 'package:eatvio_app/core/widgets/custom_divider.dart'; +import 'package:eatvio_app/features/feed/presentation/widgets/type_choice_filter_widget.dart'; +import 'package:eatvio_app/generated/l10n.dart'; +import 'package:eatvio_app/theme/custom_text_style.dart'; +import 'package:eatvio_app/theme/theme_helper.dart'; +import 'package:flutter/material.dart'; + +class DietFilterBottomSheet extends StatelessWidget { + const DietFilterBottomSheet({super.key}); + + @override + Widget build(BuildContext context) { + final s = S.of(context); + return SizedBox( + width: MediaQuery.sizeOf(context).width, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 12), + Center(child: BottomSheetHandlerBar()), + SizedBox(height: 16), + Text( + s.order, + style: TextStyles.textMSemibold.copyWith(color: appTheme.black), + ), + SizedBox(height: 12), + DropdownButtonFormField( + borderRadius: BorderRadius.circular(20), + dropdownColor: appTheme.qwe, + decoration: InputDecoration( + border: OutlineInputBorder( + borderRadius: const BorderRadius.all(Radius.circular(20)), + borderSide: BorderSide.none, + ), + fillColor: appTheme.qwe, + filled: true, + ), + value: 'qwe', + items: [ + DropdownMenuItem( + child: Text('qwe'), + value: 'qwe', + ), + DropdownMenuItem( + child: Text('qwe2'), + value: 'qwe2', + ), + DropdownMenuItem( + child: Text('qwe3'), + value: 'qwe3', + ), + ], + onChanged: (value) {}, + ), + SizedBox( + height: 16, + ), + CustomDivider(), + SizedBox( + height: 16, + ), + Text( + s.diet_time, + style: TextStyles.textMSemibold.copyWith(color: appTheme.black), + ), + SizedBox( + height: 12, + ), + TypeChoiceFilterWidget(), + SizedBox( + height: 16, + ), + CustomDivider(), + SizedBox( + height: 16, + ), + Text( + s.diet_type, + style: TextStyles.textMSemibold.copyWith(color: appTheme.black), + ), + SizedBox( + height: 12, + ), + TypeChoiceFilterWidget(), + SizedBox( + height: 24, + ), + ], + ), + ), + ); + } +} diff --git a/lib/features/feed/presentation/widgets/diets_widget.dart b/lib/features/feed/presentation/widgets/diets_widget.dart index 2437c5ad..b41bb869 100644 --- a/lib/features/feed/presentation/widgets/diets_widget.dart +++ b/lib/features/feed/presentation/widgets/diets_widget.dart @@ -143,7 +143,6 @@ class _DietsWidgetState extends State { ), FeedIconButton( svgIcon: SvgPicture.asset('assets/icons/repost.svg'), - text: '0', onTap: () async { final result = await Share.shareUri( Uri.parse( diff --git a/lib/features/feed/presentation/widgets/duration_choice_filter_widget.dart b/lib/features/feed/presentation/widgets/duration_choice_filter_widget.dart new file mode 100644 index 00000000..7be17e8e --- /dev/null +++ b/lib/features/feed/presentation/widgets/duration_choice_filter_widget.dart @@ -0,0 +1,84 @@ +import 'package:eatvio_app/core/utils/localization_utils.dart'; +import 'package:eatvio_app/features/feed/presentation/widgets/choice_chip_widget.dart'; +import 'package:eatvio_app/generated/l10n.dart'; +import 'package:flutter/widgets.dart'; + +class DurationChoiceFilterWidget extends StatefulWidget { + const DurationChoiceFilterWidget({super.key}); + + @override + State createState() => _DurationChoiceFilterWidgetState(); +} + +class _DurationChoiceFilterWidgetState extends State { + final List chipsLabelList = []; + int selectedChipIndex = 0; + @override + void didChangeDependencies() { + final s = S.of(context); + super.didChangeDependencies(); + if (chipsLabelList.isEmpty) { + chipsLabelList.add(s.all); + chipsLabelList.add('7 ${getDayForm(7, s)}'); + chipsLabelList.add('14 ${getDayForm(14, s)}'); + chipsLabelList.add('21 ${getDayForm(21, s)}'); + } + } + + @override + Widget build(BuildContext context) { + return Wrap( + children: [ + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + index: 0, + selectedChipIndex: selectedChipIndex, + onSelected: (selectedValue) { + setState(() { + selectedChipIndex = 0; + }); + }, + ), + SizedBox( + width: 8, + ), + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + index: 1, + selectedChipIndex: selectedChipIndex, + onSelected: (selectedValue) { + setState(() { + selectedChipIndex = 1; + }); + }, + ), + SizedBox( + width: 8, + ), + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + index: 2, + selectedChipIndex: selectedChipIndex, + onSelected: (selectedValue) { + setState(() { + selectedChipIndex = 2; + }); + }, + ), + SizedBox( + width: 8, + ), + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + index: 3, + selectedChipIndex: selectedChipIndex, + onSelected: (selectedValue) { + setState(() { + selectedChipIndex = 3; + }); + }, + ), + ], + ); + } +} diff --git a/lib/features/feed/presentation/widgets/filter_badge.dart b/lib/features/feed/presentation/widgets/filter_badge.dart new file mode 100644 index 00000000..8fadb5e4 --- /dev/null +++ b/lib/features/feed/presentation/widgets/filter_badge.dart @@ -0,0 +1,34 @@ +import 'package:eatvio_app/theme/theme_helper.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class FilterBadge extends StatelessWidget { + const FilterBadge({super.key, required this.filterBottomSheet}); + final Widget filterBottomSheet; + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: () { + showModalBottomSheet( + context: context, + builder: (context) => filterBottomSheet, + useRootNavigator: true, + barrierColor: Colors.transparent, + backgroundColor: appTheme.whiteA700); + }, + child: Container( + padding: EdgeInsets.only(left: 20, top: 12, bottom: 12, right: 24), + width: 70, + decoration: BoxDecoration( + color: appTheme.blueA400, + borderRadius: BorderRadius.horizontal(left: Radius.circular(100)), + ), + child: SvgPicture.asset( + 'assets/icons/filter2.svg', + width: 24, + height: 16, + ), + ), + ); + } +} diff --git a/lib/features/feed/presentation/widgets/filter_widget.dart b/lib/features/feed/presentation/widgets/filter_widget.dart deleted file mode 100644 index ad652227..00000000 --- a/lib/features/feed/presentation/widgets/filter_widget.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:eatvio_app/theme/theme_helper.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; - -class FilterWidget extends StatelessWidget { - const FilterWidget({super.key}); - - @override - Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.only(left: 20, top: 12, bottom: 12, right: 24), - width: 70, - decoration: BoxDecoration( - color: appTheme.blueA400, - borderRadius: BorderRadius.horizontal(left: Radius.circular(100)), - ), - child: SvgPicture.asset( - 'assets/icons/filter2.svg', - width: 24, - height: 16, - ), - ); - } -} diff --git a/lib/features/feed/presentation/widgets/type_choice_filter_widget.dart b/lib/features/feed/presentation/widgets/type_choice_filter_widget.dart new file mode 100644 index 00000000..d7b57801 --- /dev/null +++ b/lib/features/feed/presentation/widgets/type_choice_filter_widget.dart @@ -0,0 +1,97 @@ +import 'package:eatvio_app/features/feed/presentation/widgets/choice_chip_widget.dart'; +import 'package:eatvio_app/generated/l10n.dart'; +import 'package:flutter/widgets.dart'; + +class TypeChoiceFilterWidget extends StatefulWidget { + const TypeChoiceFilterWidget({super.key}); + + @override + State createState() => _TypeChoiceFilterWidgetState(); +} + +class _TypeChoiceFilterWidgetState extends State { + final List chipsLabelList = []; + int selectedChipIndex = 0; + @override + void didChangeDependencies() { + final s = S.of(context); + super.didChangeDependencies(); + if (chipsLabelList.isEmpty) { + chipsLabelList.add(s.all); + chipsLabelList.add(s.vegan_type); + chipsLabelList.add(s.alko_type); + chipsLabelList.add(s.corb_type); + chipsLabelList.add(s.meat_type); + } + } + + @override + Widget build(BuildContext context) { + return Wrap( + children: [ + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + index: 0, + selectedChipIndex: selectedChipIndex, + onSelected: (selectedValue) { + setState(() { + selectedChipIndex = 0; + }); + }, + ), + SizedBox( + width: 8, + ), + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + index: 1, + selectedChipIndex: selectedChipIndex, + onSelected: (selectedValue) { + setState(() { + selectedChipIndex = 1; + }); + }, + ), + SizedBox( + width: 8, + ), + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + index: 2, + selectedChipIndex: selectedChipIndex, + onSelected: (selectedValue) { + setState(() { + selectedChipIndex = 2; + }); + }, + ), + SizedBox( + width: 8, + ), + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + index: 3, + selectedChipIndex: selectedChipIndex, + onSelected: (selectedValue) { + setState(() { + selectedChipIndex = 3; + }); + }, + ), + SizedBox( + width: 8, + ), + ChoiceChipWidget( + chipsLabelList: chipsLabelList, + index: 4, + selectedChipIndex: selectedChipIndex, + onSelected: (selectedValue) { + setState(() { + selectedChipIndex = 4; + }); + }, + ), + ], + ); + } +} diff --git a/lib/features/feed/services/feed_service.dart b/lib/features/feed/services/feed_service.dart index 579d20c1..8c08bf36 100644 --- a/lib/features/feed/services/feed_service.dart +++ b/lib/features/feed/services/feed_service.dart @@ -27,7 +27,7 @@ abstract class FeedService { @GET('/api/diets/index') Future getDiets({ @Query('page') required int page, - @Query('query_search') String? query, + @Query('query_search') String? query, }); @GET('/api/blogPosts/{id}/comments/show') diff --git a/lib/generated/intl/messages_all.dart b/lib/generated/intl/messages_all.dart index b6510a8a..203415cc 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 42f0d564..ed377a7a 100644 --- a/lib/generated/intl/messages_en.dart +++ b/lib/generated/intl/messages_en.dart @@ -32,7 +32,8 @@ class MessageLookup extends MessageLookupByLibrary { "admin": MessageLookupByLibrary.simpleMessage("Админ"), "alko_type": MessageLookupByLibrary.simpleMessage("Алкоголь"), "alko_type_desc": MessageLookupByLibrary.simpleMessage( - "С некоторыми видами диет можно употреблять алкоголь в умеренных количествах. Рекомендуется совмещать вместе с низкокалорийными закусками.",), + "С некоторыми видами диет можно употреблять алкоголь в умеренных количествах. Рекомендуется совмещать вместе с низкокалорийными закусками."), + "all": MessageLookupByLibrary.simpleMessage("Все"), "allergies_presence": MessageLookupByLibrary.simpleMessage("Наличие аллергии"), "another_form_of_comment": @@ -42,7 +43,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("Углеводы"), @@ -51,11 +52,11 @@ class MessageLookup extends MessageLookupByLibrary { "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("Город"), @@ -70,7 +71,7 @@ class MessageLookup extends MessageLookupByLibrary { "copy_link": MessageLookupByLibrary.simpleMessage("Скопировать ссылку"), "corb_type": MessageLookupByLibrary.simpleMessage("Мучное"), "corb_type_desc": MessageLookupByLibrary.simpleMessage( - "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы.",), + "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы."), "country": MessageLookupByLibrary.simpleMessage("Страна"), "date_of_birth": MessageLookupByLibrary.simpleMessage("Дата рождения"), "day": MessageLookupByLibrary.simpleMessage("День"), @@ -78,22 +79,24 @@ class MessageLookup extends MessageLookupByLibrary { "diary": MessageLookupByLibrary.simpleMessage("Дневник"), "diet_author": MessageLookupByLibrary.simpleMessage("Автор диеты"), "diet_plan": MessageLookupByLibrary.simpleMessage("План диеты"), + "diet_time": MessageLookupByLibrary.simpleMessage("Время прохождения"), + "diet_type": MessageLookupByLibrary.simpleMessage("Тип диеты"), "do_you_have_hypertension_tendency": MessageLookupByLibrary.simpleMessage("Есть ли у вас гипертония?"), "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("Выйти"), @@ -102,16 +105,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": @@ -126,9 +129,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("Ссылка успешно скопирована"), @@ -137,7 +140,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("Сетевая ошибка!"), @@ -146,21 +149,22 @@ 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("У меня нет аккаунта"), + "order": MessageLookupByLibrary.simpleMessage("Порядок"), "password": MessageLookupByLibrary.simpleMessage("Пароль"), "password_confirmation": MessageLookupByLibrary.simpleMessage("Подтвердите пароль"), "password_confirmation_mismatch": MessageLookupByLibrary.simpleMessage("Пароли не совпадают"), "password_empty": MessageLookupByLibrary.simpleMessage( - "Пароль обязателен для заполнения",), + "Пароль обязателен для заполнения"), "password_short": MessageLookupByLibrary.simpleMessage( - "В пароле должно быть минимум 6 символов",), + "В пароле должно быть минимум 6 символов"), "pcs": MessageLookupByLibrary.simpleMessage("шт"), "place_of_living": MessageLookupByLibrary.simpleMessage("Место проживания"), @@ -169,9 +173,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("Сохранить"), @@ -180,11 +184,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": @@ -192,7 +196,7 @@ class MessageLookup extends MessageLookupByLibrary { "username": MessageLookupByLibrary.simpleMessage("Имя пользователя"), "vegan_type": MessageLookupByLibrary.simpleMessage("Вегетарианская"), "vegan_type_desc": MessageLookupByLibrary.simpleMessage( - "Диета основана на потреблении растительной пищи и отказе от продуктов животного происхождения. Такой тип питания может быть разнообразным и вкусным, а также полезным для здоровья.",), + "Диета основана на потреблении растительной пищи и отказе от продуктов животного происхождения. Такой тип питания может быть разнообразным и вкусным, а также полезным для здоровья."), "waist": MessageLookupByLibrary.simpleMessage("Талия"), "waist_circumference": MessageLookupByLibrary.simpleMessage("Обхват талии"), @@ -203,7 +207,7 @@ class MessageLookup extends MessageLookupByLibrary { "what_is_your_name": MessageLookupByLibrary.simpleMessage("Как вас зовут?"), "wrong_credentials": MessageLookupByLibrary.simpleMessage( - "Неверные данные пользователя",), + "Неверные данные пользователя"), "your_blood_pressure": MessageLookupByLibrary.simpleMessage("Ваше артериальное давление?"), "your_favorite_sports": @@ -211,6 +215,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 2cc942c5..96121d43 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!; } @@ -1369,6 +1369,46 @@ class S { args: [], ); } + + /// `Порядок` + String get order { + return Intl.message( + 'Порядок', + name: 'order', + desc: '', + args: [], + ); + } + + /// `Время прохождения` + String get diet_time { + return Intl.message( + 'Время прохождения', + name: 'diet_time', + desc: '', + args: [], + ); + } + + /// `Все` + String get all { + return Intl.message( + 'Все', + name: 'all', + desc: '', + args: [], + ); + } + + /// `Тип диеты` + String get diet_type { + return Intl.message( + 'Тип диеты', + name: 'diet_type', + desc: '', + args: [], + ); + } } class AppLocalizationDelegate extends LocalizationsDelegate { diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 0d0d086a..0b130595 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -130,5 +130,9 @@ "answer": "Ответить", "link_was_copied": "Ссылка успешно скопирована", "choose_start_diet_date": "Выберите дату старты диеты. Она отобразиться у Вас в дневнике", - "continue_": "Продолжить" + "continue_": "Продолжить", + "order": "Порядок", + "diet_time": "Время прохождения", + "all": "Все", + "diet_type": "Тип диеты" } diff --git a/lib/theme/theme_helper.dart b/lib/theme/theme_helper.dart index c29978b4..39cede01 100644 --- a/lib/theme/theme_helper.dart +++ b/lib/theme/theme_helper.dart @@ -176,6 +176,8 @@ class PrimaryColors { Color get lightGray => Color(0xFFCECECE); Color get transparentBlue => Color(0xFF2F80ED).withOpacity(0.1); + + Color get qwe => Color(0xFFF6F6F6); } PrimaryColors get appTheme => ThemeHelper().themeColor(); From ced2a7708a1569602ecd4df397da2bc149313a92 Mon Sep 17 00:00:00 2001 From: Username1548 Date: Fri, 15 Nov 2024 19:10:06 +0700 Subject: [PATCH 4/5] fixed analyzer issue --- .../presentation/widgets/filter_badge.dart | 2 +- lib/generated/intl/messages_all.dart | 2 +- lib/generated/intl/messages_en.dart | 54 +++++++++---------- lib/generated/l10n.dart | 4 +- 4 files changed, 31 insertions(+), 31 deletions(-) diff --git a/lib/features/feed/presentation/widgets/filter_badge.dart b/lib/features/feed/presentation/widgets/filter_badge.dart index 8fadb5e4..2b49e645 100644 --- a/lib/features/feed/presentation/widgets/filter_badge.dart +++ b/lib/features/feed/presentation/widgets/filter_badge.dart @@ -14,7 +14,7 @@ class FilterBadge extends StatelessWidget { builder: (context) => filterBottomSheet, useRootNavigator: true, barrierColor: Colors.transparent, - backgroundColor: appTheme.whiteA700); + backgroundColor: appTheme.whiteA700,); }, child: Container( padding: EdgeInsets.only(left: 20, top: 12, bottom: 12, right: 24), 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 ed377a7a..910355a7 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( - "С некоторыми видами диет можно употреблять алкоголь в умеренных количествах. Рекомендуется совмещать вместе с низкокалорийными закусками."), + "С некоторыми видами диет можно употреблять алкоголь в умеренных количествах. Рекомендуется совмещать вместе с низкокалорийными закусками.",), "all": MessageLookupByLibrary.simpleMessage("Все"), "allergies_presence": MessageLookupByLibrary.simpleMessage("Наличие аллергии"), @@ -43,7 +43,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("Углеводы"), @@ -52,11 +52,11 @@ class MessageLookup extends MessageLookupByLibrary { "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("Город"), @@ -71,7 +71,7 @@ class MessageLookup extends MessageLookupByLibrary { "copy_link": MessageLookupByLibrary.simpleMessage("Скопировать ссылку"), "corb_type": MessageLookupByLibrary.simpleMessage("Мучное"), "corb_type_desc": MessageLookupByLibrary.simpleMessage( - "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы."), + "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы.",), "country": MessageLookupByLibrary.simpleMessage("Страна"), "date_of_birth": MessageLookupByLibrary.simpleMessage("Дата рождения"), "day": MessageLookupByLibrary.simpleMessage("День"), @@ -86,17 +86,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("Выйти"), @@ -105,16 +105,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": @@ -129,9 +129,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("Ссылка успешно скопирована"), @@ -140,7 +140,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("Сетевая ошибка!"), @@ -149,9 +149,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("У меня нет аккаунта"), @@ -162,9 +162,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("Место проживания"), @@ -173,9 +173,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("Сохранить"), @@ -184,11 +184,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": @@ -196,7 +196,7 @@ class MessageLookup extends MessageLookupByLibrary { "username": MessageLookupByLibrary.simpleMessage("Имя пользователя"), "vegan_type": MessageLookupByLibrary.simpleMessage("Вегетарианская"), "vegan_type_desc": MessageLookupByLibrary.simpleMessage( - "Диета основана на потреблении растительной пищи и отказе от продуктов животного происхождения. Такой тип питания может быть разнообразным и вкусным, а также полезным для здоровья."), + "Диета основана на потреблении растительной пищи и отказе от продуктов животного происхождения. Такой тип питания может быть разнообразным и вкусным, а также полезным для здоровья.",), "waist": MessageLookupByLibrary.simpleMessage("Талия"), "waist_circumference": MessageLookupByLibrary.simpleMessage("Обхват талии"), @@ -207,7 +207,7 @@ class MessageLookup extends MessageLookupByLibrary { "what_is_your_name": MessageLookupByLibrary.simpleMessage("Как вас зовут?"), "wrong_credentials": MessageLookupByLibrary.simpleMessage( - "Неверные данные пользователя"), + "Неверные данные пользователя",), "your_blood_pressure": MessageLookupByLibrary.simpleMessage("Ваше артериальное давление?"), "your_favorite_sports": @@ -215,6 +215,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 96121d43..9fd1162c 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!; } From fd5adabf313cc3e81e04c8d71fbc2586a538b050 Mon Sep 17 00:00:00 2001 From: Username1548 Date: Fri, 15 Nov 2024 19:31:59 +0700 Subject: [PATCH 5/5] fixed analyze issue --- .../feed/presentation/pages/feed_screen.dart | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/lib/features/feed/presentation/pages/feed_screen.dart b/lib/features/feed/presentation/pages/feed_screen.dart index 00f334e5..d55f6579 100644 --- a/lib/features/feed/presentation/pages/feed_screen.dart +++ b/lib/features/feed/presentation/pages/feed_screen.dart @@ -569,31 +569,4 @@ class _FeedScreenState extends State { ); } - _choiceChipWidget(int index) { - return ChoiceChip( - selectedColor: appTheme.blueA400, - pressElevation: 0, - showCheckmark: false, - side: BorderSide.none, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(16), - ), - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), - label: Text(chipsLabelList[index]), - labelStyle: TextStyle( - color: index == _selectedChipIndex ? Colors.white : appTheme.gray600, - fontWeight: FontWeight.w500, - fontSize: 12, - ), - selected: _selectedChipIndex == index, - backgroundColor: appTheme.gray100, - onSelected: (bool selected) { - setState(() { - _selectedChipIndex = index; - searchController.clear(); - FocusScope.of(context).requestFocus(new FocusNode()); - }); - }, - ); - } }