From 00da6528607be65531173c709dc05bb4cf04f714 Mon Sep 17 00:00:00 2001 From: Username1548 Date: Fri, 15 Nov 2024 19:07:15 +0700 Subject: [PATCH] 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();