From f590c49deff3760469e37c62dcc29ab9ece6bce9 Mon Sep 17 00:00:00 2001 From: Username1548 Date: Mon, 10 Mar 2025 22:25:30 +0700 Subject: [PATCH 1/4] pre merge commit --- assets/icons/reversed_exclamation_mark.svg | 4 + lib/core/app_router.dart | 6 +- lib/core/const.dart | 6 +- lib/core/locator_service.dart | 4 +- .../chat/presentation/pages/chat_screen.dart | 9 +- .../widgets/chat_entry_widget.dart | 1 - .../widgets/notification_banner.dart | 77 +++++ .../plans/models/chosen_plan_model.dart | 20 ++ .../models/chosen_plan_model.freezed.dart | 283 ++++++++++++++++++ .../plans/models/chosen_plan_model.g.dart | 27 ++ .../presentation/cubit/about_plan_cubit.dart | 25 ++ .../presentation/pages/about_plan_screen.dart | 24 +- .../plans/repositories/plan_repository.dart | 12 +- lib/features/plans/services/plan_service.dart | 14 +- .../plans/services/plan_service.g.dart | 31 ++ lib/generated/intl/messages_en.dart | 10 + lib/generated/l10n.dart | 72 +++++ lib/l10n/intl_en.arb | 11 +- 18 files changed, 604 insertions(+), 32 deletions(-) create mode 100644 assets/icons/reversed_exclamation_mark.svg create mode 100644 lib/features/chat/presentation/widgets/notification_banner.dart create mode 100644 lib/features/plans/models/chosen_plan_model.dart create mode 100644 lib/features/plans/models/chosen_plan_model.freezed.dart create mode 100644 lib/features/plans/models/chosen_plan_model.g.dart diff --git a/assets/icons/reversed_exclamation_mark.svg b/assets/icons/reversed_exclamation_mark.svg new file mode 100644 index 00000000..77b506bc --- /dev/null +++ b/assets/icons/reversed_exclamation_mark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/lib/core/app_router.dart b/lib/core/app_router.dart index 78d7d25f..bee9eaf8 100644 --- a/lib/core/app_router.dart +++ b/lib/core/app_router.dart @@ -241,12 +241,10 @@ class AppRouter { path: '/chat-screen', name: 'chatScreen', builder: (context, state) { - final data = state.extra as Map; - final chatsCubit = data['chatsCubit'] as ChatsCubit; + final data = state.extra as Map; final chatId = data['chatId'] as String; return ChatScreen( - chatId: chatId, - chatsCubit: chatsCubit, + chatId: chatId, ); }, ), diff --git a/lib/core/const.dart b/lib/core/const.dart index dfeae1fc..0b91d766 100644 --- a/lib/core/const.dart +++ b/lib/core/const.dart @@ -1,5 +1,5 @@ -String baseUrl = 'https://eatvio.ru'; -// String baseUrl = 'https://dev2.eatvio.com'; +// String baseUrl = 'https://eatvio.ru'; +String baseUrl = 'https://dev2.eatvio.com'; const List durationValues = [7, 14, 21]; @@ -8,4 +8,4 @@ const List planTypeValues = ['fit', 'slim', 'wellness', 'behavior']; const newMessagesChannelName = 'private-new-chat-messages'; const newNotificationsChannelName = 'private-message-events'; -const directChatChannelName = 'private-direct-chat'; +const directChatChannelName = 'private-direct-chat'; \ No newline at end of file diff --git a/lib/core/locator_service.dart b/lib/core/locator_service.dart index 7e79faf4..cfca3868 100644 --- a/lib/core/locator_service.dart +++ b/lib/core/locator_service.dart @@ -87,6 +87,7 @@ Future init() async { sl.registerLazySingleton(() => NotificationsCubit(wsManager: sl())); sl.registerLazySingleton(() => FeedCubit(feedRepository: sl())); sl.registerLazySingleton(() => ProfileAvatarCubit(profileRepository: sl())); + sl.registerLazySingleton(() => ChatsCubit(chatRepository: sl(), wsManager: sl(), profileRepository: sl())); // Cubit factories sl.registerFactory(() => RegistrationCubit(registrationRepository: sl())); @@ -96,8 +97,7 @@ Future init() async { sl.registerFactory(() => ProfileCubit(profileRepository: sl(), chatRepository: sl())); sl.registerFactory(() => profilePlans.PlansCubit(plansRepository: sl())); sl.registerFactory(() => DietsCubit(feedRepository: sl(), dietsRepository: sl())); - sl.registerFactory(() => CommentsCubit(feedRepository: sl())); - sl.registerFactory(() => ChatsCubit(chatRepository: sl(), wsManager: sl(), profileRepository: sl())); + sl.registerFactory(() => CommentsCubit(feedRepository: sl())); sl.registerFactory(() => PlansCubit(feedRepository: sl(), planRepository: sl())); sl.registerFactory(() => SettingsCubit(profileRepository: sl(), settingsRepository: sl())); sl.registerFactory(() => RegisterConsultantCubit(consultantRepository: sl())); diff --git a/lib/features/chat/presentation/pages/chat_screen.dart b/lib/features/chat/presentation/pages/chat_screen.dart index 4144fbd5..4b2d8b94 100644 --- a/lib/features/chat/presentation/pages/chat_screen.dart +++ b/lib/features/chat/presentation/pages/chat_screen.dart @@ -11,6 +11,7 @@ import 'package:eatvio_app/features/chat/presentation/widgets/chat_bubble_widget import 'package:eatvio_app/core/locator_service.dart'; import 'package:eatvio_app/core/theme/custom_text_style.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; +import 'package:eatvio_app/features/chat/presentation/widgets/notification_banner.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -19,10 +20,8 @@ import 'package:visibility_detector/visibility_detector.dart'; class ChatScreen extends StatefulWidget { final String chatId; - final ChatsCubit chatsCubit; const ChatScreen({ required this.chatId, - required this.chatsCubit, super.key, }); @@ -174,7 +173,9 @@ class _ChatScreenState extends State { () async { final result = await context.read().markMessagesAsRead(state.chatRoom.id, unreadMessagesIdsCopy); if (!result) return; - widget.chatsCubit.reduceUnreadMessagesCount(chatId: state.chatRoom.id, count: unreadMessagesIdsCopy.length); + context + .read() + .reduceUnreadMessagesCount(chatId: state.chatRoom.id, count: unreadMessagesIdsCopy.length); unreadMessagesIdsCopy.clear(); }, ); @@ -203,7 +204,7 @@ class _ChatScreenState extends State { () async { final result = await context.read().markMessagesAsRead(state.chatRoom.id, unreadMessagesIds); if (!result) return; - widget.chatsCubit.reduceUnreadMessagesCount(chatId: state.chatRoom.id, count: unreadMessagesIds.length); + context.read().reduceUnreadMessagesCount(chatId: state.chatRoom.id, count: unreadMessagesIds.length); unreadMessagesIds.clear(); }, ); diff --git a/lib/features/chat/presentation/widgets/chat_entry_widget.dart b/lib/features/chat/presentation/widgets/chat_entry_widget.dart index 61e6ea17..66e0d700 100644 --- a/lib/features/chat/presentation/widgets/chat_entry_widget.dart +++ b/lib/features/chat/presentation/widgets/chat_entry_widget.dart @@ -28,7 +28,6 @@ class _ChatEntryWidgetState extends State { 'chatScreen', extra: { 'chatId': widget.chatRoom.id.toString(), - 'chatsCubit': context.read(), }, ), child: Ink( diff --git a/lib/features/chat/presentation/widgets/notification_banner.dart b/lib/features/chat/presentation/widgets/notification_banner.dart new file mode 100644 index 00000000..5d3c8097 --- /dev/null +++ b/lib/features/chat/presentation/widgets/notification_banner.dart @@ -0,0 +1,77 @@ +import 'package:eatvio_app/core/theme/custom_text_style.dart'; +import 'package:eatvio_app/core/theme/theme_helper.dart'; +import 'package:eatvio_app/generated/l10n.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; + +class NotificationBanner extends StatelessWidget { + const NotificationBanner({super.key, required this.bannerType}); + final BannerType bannerType; + @override + Widget build(BuildContext context) { + final size = MediaQuery.sizeOf(context); + final s = S.of(context); + return Container( + decoration: BoxDecoration( + color: appTheme.gray50, + borderRadius: BorderRadius.circular(20), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 12, right: 8, left: 12), + child: SvgPicture.asset('assets/icons/reversed_exclamation_mark.svg', height: 68, width: 68), + ), + Padding( + padding: const EdgeInsets.only(top: 16), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: switch (bannerType) { + BannerType.date => [ + SizedBox( + width: size.width * 0.6, + child: Text(s.can_not_choose_start_date, style: TextStyles.textMMedium.copyWith(color: appTheme.black)), + ), + SizedBox(height: 12), + GestureDetector( + onTap: () {}, + child: Text(s.add_card, style: TextStyles.textLSemibold.copyWith(color: appTheme.blueA400)), + ), + SizedBox(height: 16), + ], + BannerType.card => [ + SizedBox( + width: size.width * 0.6, + child: Text(s.can_not_choose_start_date, style: TextStyles.textMMedium.copyWith(color: appTheme.black)), + ), + SizedBox(height: 12), + GestureDetector( + onTap: () {}, + child: Text(s.add_card, style: TextStyles.textLSemibold.copyWith(color: appTheme.blueA400)), + ), + SizedBox(height: 16), + ], + BannerType.payment => [ + SizedBox( + width: size.width * 0.6, + child: Text(s.can_not_choose_start_date, style: TextStyles.textMMedium.copyWith(color: appTheme.black)), + ), + SizedBox(height: 12), + GestureDetector( + onTap: () {}, + child: Text(s.add_card, style: TextStyles.textLSemibold.copyWith(color: appTheme.blueA400)), + ), + SizedBox(height: 16), + ], + }, + ), + ), + ], + ), + ); + } +} + +enum BannerType { date, card, payment } diff --git a/lib/features/plans/models/chosen_plan_model.dart b/lib/features/plans/models/chosen_plan_model.dart new file mode 100644 index 00000000..525418b2 --- /dev/null +++ b/lib/features/plans/models/chosen_plan_model.dart @@ -0,0 +1,20 @@ +import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'chosen_plan_model.freezed.dart'; +part 'chosen_plan_model.g.dart'; + +@freezed +class ChosenPlanModel with _$ChosenPlanModel { + + factory ChosenPlanModel({ + @JsonKey() required int id, + @JsonKey(name: 'option_type') required String optionType, + @JsonKey(name: 'start_date') required DateTime startDate, + @JsonKey(name: 'chat_id') required String chatId, + @JsonKey(name: 'plan') required PlanModel plan, + + }) = _ChosenPlanModel; + + factory ChosenPlanModel.fromJson(Map json) => _$ChosenPlanModelFromJson(json); +} \ No newline at end of file diff --git a/lib/features/plans/models/chosen_plan_model.freezed.dart b/lib/features/plans/models/chosen_plan_model.freezed.dart new file mode 100644 index 00000000..b26b04cd --- /dev/null +++ b/lib/features/plans/models/chosen_plan_model.freezed.dart @@ -0,0 +1,283 @@ +// 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 'chosen_plan_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'); + +ChosenPlanModel _$ChosenPlanModelFromJson(Map json) { + return _ChosenPlanModel.fromJson(json); +} + +/// @nodoc +mixin _$ChosenPlanModel { + @JsonKey() + int get id => throw _privateConstructorUsedError; + @JsonKey(name: 'option_type') + String get optionType => throw _privateConstructorUsedError; + @JsonKey(name: 'start_date') + DateTime get startDate => throw _privateConstructorUsedError; + @JsonKey(name: 'chat_id') + String get chatId => throw _privateConstructorUsedError; + @JsonKey(name: 'plan') + PlanModel get plan => throw _privateConstructorUsedError; + + /// Serializes this ChosenPlanModel to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of ChosenPlanModel + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $ChosenPlanModelCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ChosenPlanModelCopyWith<$Res> { + factory $ChosenPlanModelCopyWith( + ChosenPlanModel value, $Res Function(ChosenPlanModel) then) = + _$ChosenPlanModelCopyWithImpl<$Res, ChosenPlanModel>; + @useResult + $Res call( + {@JsonKey() int id, + @JsonKey(name: 'option_type') String optionType, + @JsonKey(name: 'start_date') DateTime startDate, + @JsonKey(name: 'chat_id') String chatId, + @JsonKey(name: 'plan') PlanModel plan}); + + $PlanModelCopyWith<$Res> get plan; +} + +/// @nodoc +class _$ChosenPlanModelCopyWithImpl<$Res, $Val extends ChosenPlanModel> + implements $ChosenPlanModelCopyWith<$Res> { + _$ChosenPlanModelCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of ChosenPlanModel + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? id = null, + Object? optionType = null, + Object? startDate = null, + Object? chatId = null, + Object? plan = null, + }) { + return _then(_value.copyWith( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as int, + optionType: null == optionType + ? _value.optionType + : optionType // ignore: cast_nullable_to_non_nullable + as String, + startDate: null == startDate + ? _value.startDate + : startDate // ignore: cast_nullable_to_non_nullable + as DateTime, + chatId: null == chatId + ? _value.chatId + : chatId // ignore: cast_nullable_to_non_nullable + as String, + plan: null == plan + ? _value.plan + : plan // ignore: cast_nullable_to_non_nullable + as PlanModel, + ) as $Val); + } + + /// Create a copy of ChosenPlanModel + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $PlanModelCopyWith<$Res> get plan { + return $PlanModelCopyWith<$Res>(_value.plan, (value) { + return _then(_value.copyWith(plan: value) as $Val); + }); + } +} + +/// @nodoc +abstract class _$$ChosenPlanModelImplCopyWith<$Res> + implements $ChosenPlanModelCopyWith<$Res> { + factory _$$ChosenPlanModelImplCopyWith(_$ChosenPlanModelImpl value, + $Res Function(_$ChosenPlanModelImpl) then) = + __$$ChosenPlanModelImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {@JsonKey() int id, + @JsonKey(name: 'option_type') String optionType, + @JsonKey(name: 'start_date') DateTime startDate, + @JsonKey(name: 'chat_id') String chatId, + @JsonKey(name: 'plan') PlanModel plan}); + + @override + $PlanModelCopyWith<$Res> get plan; +} + +/// @nodoc +class __$$ChosenPlanModelImplCopyWithImpl<$Res> + extends _$ChosenPlanModelCopyWithImpl<$Res, _$ChosenPlanModelImpl> + implements _$$ChosenPlanModelImplCopyWith<$Res> { + __$$ChosenPlanModelImplCopyWithImpl( + _$ChosenPlanModelImpl _value, $Res Function(_$ChosenPlanModelImpl) _then) + : super(_value, _then); + + /// Create a copy of ChosenPlanModel + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? id = null, + Object? optionType = null, + Object? startDate = null, + Object? chatId = null, + Object? plan = null, + }) { + return _then(_$ChosenPlanModelImpl( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as int, + optionType: null == optionType + ? _value.optionType + : optionType // ignore: cast_nullable_to_non_nullable + as String, + startDate: null == startDate + ? _value.startDate + : startDate // ignore: cast_nullable_to_non_nullable + as DateTime, + chatId: null == chatId + ? _value.chatId + : chatId // ignore: cast_nullable_to_non_nullable + as String, + plan: null == plan + ? _value.plan + : plan // ignore: cast_nullable_to_non_nullable + as PlanModel, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$ChosenPlanModelImpl implements _ChosenPlanModel { + _$ChosenPlanModelImpl( + {@JsonKey() required this.id, + @JsonKey(name: 'option_type') required this.optionType, + @JsonKey(name: 'start_date') required this.startDate, + @JsonKey(name: 'chat_id') required this.chatId, + @JsonKey(name: 'plan') required this.plan}); + + factory _$ChosenPlanModelImpl.fromJson(Map json) => + _$$ChosenPlanModelImplFromJson(json); + + @override + @JsonKey() + final int id; + @override + @JsonKey(name: 'option_type') + final String optionType; + @override + @JsonKey(name: 'start_date') + final DateTime startDate; + @override + @JsonKey(name: 'chat_id') + final String chatId; + @override + @JsonKey(name: 'plan') + final PlanModel plan; + + @override + String toString() { + return 'ChosenPlanModel(id: $id, optionType: $optionType, startDate: $startDate, chatId: $chatId, plan: $plan)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ChosenPlanModelImpl && + (identical(other.id, id) || other.id == id) && + (identical(other.optionType, optionType) || + other.optionType == optionType) && + (identical(other.startDate, startDate) || + other.startDate == startDate) && + (identical(other.chatId, chatId) || other.chatId == chatId) && + (identical(other.plan, plan) || other.plan == plan)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => + Object.hash(runtimeType, id, optionType, startDate, chatId, plan); + + /// Create a copy of ChosenPlanModel + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ChosenPlanModelImplCopyWith<_$ChosenPlanModelImpl> get copyWith => + __$$ChosenPlanModelImplCopyWithImpl<_$ChosenPlanModelImpl>( + this, _$identity); + + @override + Map toJson() { + return _$$ChosenPlanModelImplToJson( + this, + ); + } +} + +abstract class _ChosenPlanModel implements ChosenPlanModel { + factory _ChosenPlanModel( + {@JsonKey() required final int id, + @JsonKey(name: 'option_type') required final String optionType, + @JsonKey(name: 'start_date') required final DateTime startDate, + @JsonKey(name: 'chat_id') required final String chatId, + @JsonKey(name: 'plan') required final PlanModel plan}) = + _$ChosenPlanModelImpl; + + factory _ChosenPlanModel.fromJson(Map json) = + _$ChosenPlanModelImpl.fromJson; + + @override + @JsonKey() + int get id; + @override + @JsonKey(name: 'option_type') + String get optionType; + @override + @JsonKey(name: 'start_date') + DateTime get startDate; + @override + @JsonKey(name: 'chat_id') + String get chatId; + @override + @JsonKey(name: 'plan') + PlanModel get plan; + + /// Create a copy of ChosenPlanModel + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ChosenPlanModelImplCopyWith<_$ChosenPlanModelImpl> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/lib/features/plans/models/chosen_plan_model.g.dart b/lib/features/plans/models/chosen_plan_model.g.dart new file mode 100644 index 00000000..52ecbdb7 --- /dev/null +++ b/lib/features/plans/models/chosen_plan_model.g.dart @@ -0,0 +1,27 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'chosen_plan_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$ChosenPlanModelImpl _$$ChosenPlanModelImplFromJson( + Map json) => + _$ChosenPlanModelImpl( + id: (json['id'] as num).toInt(), + optionType: json['option_type'] as String, + startDate: DateTime.parse(json['start_date'] as String), + chatId: json['chat_id'] as String, + plan: PlanModel.fromJson(json['plan'] as Map), + ); + +Map _$$ChosenPlanModelImplToJson( + _$ChosenPlanModelImpl instance) => + { + 'id': instance.id, + 'option_type': instance.optionType, + 'start_date': instance.startDate.toIso8601String(), + 'chat_id': instance.chatId, + 'plan': instance.plan, + }; diff --git a/lib/features/plans/presentation/cubit/about_plan_cubit.dart b/lib/features/plans/presentation/cubit/about_plan_cubit.dart index 20ca860b..4cf93e12 100644 --- a/lib/features/plans/presentation/cubit/about_plan_cubit.dart +++ b/lib/features/plans/presentation/cubit/about_plan_cubit.dart @@ -1,8 +1,10 @@ import 'dart:developer'; +import 'package:dio/dio.dart'; import 'package:easy_debounce/easy_debounce.dart'; import 'package:eatvio_app/core/utils/toasts.dart'; import 'package:eatvio_app/features/diets/repositories/diet_repository.dart'; +import 'package:eatvio_app/features/plans/models/chosen_plan_model.dart'; import 'package:eatvio_app/features/plans/presentation/cubit/about_plan_state.dart'; import 'package:eatvio_app/features/plans/repositories/plan_repository.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -125,4 +127,27 @@ class AboutPlanCubit extends Cubit { }, ); } + + Future chosePlan() async { + try { + final slug = state.planModel?.slug; + final optionIndex = state.chosenOptionIndex; + if (slug != null) { + final optionName = _getOptionNameFromIndex(optionIndex); + final body = {'options_type': optionName}; + return await planRepository.chosePlan(slug, body); + } + } on DioException catch (e, st) { + log(e.toString(), stackTrace: st); + } catch (e, st) { + log(e.toString(), stackTrace: st); + } + return null; + } + + String _getOptionNameFromIndex(int index) => switch (index) { + 1 => 'options2', + 2 => 'options3', + _ => 'options1', + }; } diff --git a/lib/features/plans/presentation/pages/about_plan_screen.dart b/lib/features/plans/presentation/pages/about_plan_screen.dart index 0022a4f2..c34985a1 100644 --- a/lib/features/plans/presentation/pages/about_plan_screen.dart +++ b/lib/features/plans/presentation/pages/about_plan_screen.dart @@ -10,6 +10,7 @@ import 'package:eatvio_app/core/widgets/bookmark_button.dart'; import 'package:eatvio_app/core/widgets/data_error_widget.dart'; import 'package:eatvio_app/core/widgets/info_row.dart'; import 'package:eatvio_app/core/widgets/loader.dart'; +import 'package:eatvio_app/core/widgets/show_error_dialog.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/author_card.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/expandable_text.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/info_bouble.dart'; @@ -30,6 +31,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_portal/flutter_portal.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:go_router/go_router.dart'; import '../widgets/option_widget.dart'; @@ -217,17 +219,21 @@ class _AboutPlanScreenState extends State { borderRadius: BorderRadius.circular(16), ), backgroundColor: appTheme.greenA700, - onPressed: () { - /// TODO: добавить обработку покупки плана - // showModalBottomSheet( - // context: context, - // builder: (context) => StartDietBottomSheet( - // aboutDietCubit: context.read(), - // ), - // ); + onPressed: () async { + final chosenPlan = await context.read().chosePlan(); + if (chosenPlan == null) { + showErrorDialog(context, title: 'Не удалось заказать план'); + return; + } + GoRouter.of(context).pushReplacementNamed( + 'chatScreen', + extra: { + 'chatId': chosenPlan.chatId, + }, + ); }, label: Text( - s.startDiet, + s.to_order, style: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700), ), ), diff --git a/lib/features/plans/repositories/plan_repository.dart b/lib/features/plans/repositories/plan_repository.dart index 313ad8b1..75ca7a08 100644 --- a/lib/features/plans/repositories/plan_repository.dart +++ b/lib/features/plans/repositories/plan_repository.dart @@ -1,9 +1,9 @@ import 'dart:async'; import 'package:eatvio_app/features/diets/repositories/diet_repository.dart'; import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart'; +import 'package:eatvio_app/features/plans/models/chosen_plan_model.dart'; import 'package:eatvio_app/features/plans/services/plan_service.dart'; - class PlanRepository { final PlanService planService; @@ -48,9 +48,15 @@ class PlanRepository { } } + Future chosePlan(String slug, Map option ) async { + try { + return await planService.chosePlan(slug: slug, option: option); + } catch (e) { + rethrow; + } + } + void emitLikesStateToFeed(LikesState state) => _planLikeStateStreamController.add(state); void emitFavoriteStateToFeed(FavoriteState state) => _planFavoriteStateStreamController.add(state); void emitCommentsStateToFeed(CommentsState state) => _planCommentsStateStreamController.add(state); } - - diff --git a/lib/features/plans/services/plan_service.dart b/lib/features/plans/services/plan_service.dart index d8a49a90..8a179760 100644 --- a/lib/features/plans/services/plan_service.dart +++ b/lib/features/plans/services/plan_service.dart @@ -1,20 +1,18 @@ - - import 'package:dio/dio.dart'; import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart'; +import 'package:eatvio_app/features/plans/models/chosen_plan_model.dart'; import 'package:retrofit/retrofit.dart'; part 'plan_service.g.dart'; @RestApi() abstract class PlanService { - factory PlanService(Dio dio, {String baseUrl}) = _PlanService; @GET('/api/plans/show/{slug}') Future getPlan(@Path('slug') String slug); - @POST('/api/plans/{slug}/like') + @POST('/api/plans/{slug}/like') Future likePlan({ @Path() required String slug, }); @@ -28,4 +26,10 @@ abstract class PlanService { Future removeFromFavorite({ @Path() required String slug, }); -} \ No newline at end of file + + @POST('/api/plans/{slug}/choose') + Future chosePlan({ + @Path() required String slug, + @Body() required Map option, + }); +} diff --git a/lib/features/plans/services/plan_service.g.dart b/lib/features/plans/services/plan_service.g.dart index 09f90b41..189f1e31 100644 --- a/lib/features/plans/services/plan_service.g.dart +++ b/lib/features/plans/services/plan_service.g.dart @@ -101,6 +101,37 @@ class _PlanService implements PlanService { await _dio.fetch(_options); } + @override + Future chosePlan({ + required String slug, + required Map option, + }) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + final _data = {}; + _data.addAll(option); + final _options = _setStreamType( + Options(method: 'POST', headers: _headers, extra: _extra) + .compose( + _dio.options, + '/api/plans/${slug}/choose', + queryParameters: queryParameters, + data: _data, + ) + .copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)), + ); + final _result = await _dio.fetch>(_options); + late ChosenPlanModel _value; + try { + _value = ChosenPlanModel.fromJson(_result.data!); + } on Object catch (e, s) { + errorLogger?.logError(e, s, _options); + rethrow; + } + return _value; + } + RequestOptions _setStreamType(RequestOptions requestOptions) { if (T != dynamic && !(requestOptions.responseType == ResponseType.bytes || diff --git a/lib/generated/intl/messages_en.dart b/lib/generated/intl/messages_en.dart index 9b5fef07..6d76f87e 100644 --- a/lib/generated/intl/messages_en.dart +++ b/lib/generated/intl/messages_en.dart @@ -32,6 +32,7 @@ class MessageLookup extends MessageLookupByLibrary { "Кол-во активных консультаций"), "active_diet_state": MessageLookupByLibrary.simpleMessage("Активная"), "add": MessageLookupByLibrary.simpleMessage("Добавить"), + "add_card": MessageLookupByLibrary.simpleMessage("Привязать карту"), "add_cover": MessageLookupByLibrary.simpleMessage("Добавьте обложку"), "add_measure": MessageLookupByLibrary.simpleMessage("Добавить замер"), "adding_plan": MessageLookupByLibrary.simpleMessage("Добавление плана"), @@ -58,6 +59,8 @@ class MessageLookup extends MessageLookupByLibrary { "calls_for_bullying": MessageLookupByLibrary.simpleMessage("Призывы к травле"), "calories": MessageLookupByLibrary.simpleMessage("Калории"), + "can_not_choose_start_date": MessageLookupByLibrary.simpleMessage( + "Дату старта плана невозможно выбрать, пока Вы не привяжите карту"), "can_not_load_data_please_try_again": MessageLookupByLibrary.simpleMessage( "Не удалось загрузить данные. Попробуйте обновить страницу"), @@ -72,10 +75,13 @@ class MessageLookup extends MessageLookupByLibrary { "chest": MessageLookupByLibrary.simpleMessage("Грудь"), "chest_circumference": MessageLookupByLibrary.simpleMessage("Обхват груди"), + "choose_date": MessageLookupByLibrary.simpleMessage("Выбрать дату"), "choose_diet_duration": MessageLookupByLibrary.simpleMessage("Выберите срок диеты"), "choose_plan_duration": MessageLookupByLibrary.simpleMessage("Выберите срок плана"), + "choose_plan_start_date": MessageLookupByLibrary.simpleMessage( + "Выберите дату старта плана питания"), "choose_start_diet_date": MessageLookupByLibrary.simpleMessage( "Выберите дату старты диеты. Она отобразиться у Вас в дневнике"), "circumference_empty": MessageLookupByLibrary.simpleMessage( @@ -130,6 +136,8 @@ class MessageLookup extends MessageLookupByLibrary { "create_diet": MessageLookupByLibrary.simpleMessage("Создание диеты"), "customer_price": MessageLookupByLibrary.simpleMessage("Цена для покупателя"), + "date_has_ben_set": MessageLookupByLibrary.simpleMessage( + "Дата старта начала консультации установлена"), "date_of_birth": MessageLookupByLibrary.simpleMessage("Дата рождения"), "day": MessageLookupByLibrary.simpleMessage("День"), "days": MessageLookupByLibrary.simpleMessage("дней"), @@ -327,6 +335,7 @@ class MessageLookup extends MessageLookupByLibrary { "Пароль обязателен для заполнения"), "password_short": MessageLookupByLibrary.simpleMessage( "В пароле должно быть минимум 6 символов"), + "pay": MessageLookupByLibrary.simpleMessage("Оплатить"), "pcs": MessageLookupByLibrary.simpleMessage("шт"), "personal": MessageLookupByLibrary.simpleMessage("Персональные"), "personal_diet_state": @@ -424,6 +433,7 @@ class MessageLookup extends MessageLookupByLibrary { "time": MessageLookupByLibrary.simpleMessage("Время прохождения"), "toOffer": MessageLookupByLibrary.simpleMessage("Предложить"), "to_draft": MessageLookupByLibrary.simpleMessage("В черновик"), + "to_order": MessageLookupByLibrary.simpleMessage("Заказать"), "try_again": MessageLookupByLibrary.simpleMessage("Попробовать снова"), "type_here_your_complaint": MessageLookupByLibrary.simpleMessage("Напишите здесь свою жалобу"), diff --git a/lib/generated/l10n.dart b/lib/generated/l10n.dart index 1bca8570..3c20bf57 100644 --- a/lib/generated/l10n.dart +++ b/lib/generated/l10n.dart @@ -3179,6 +3179,78 @@ class S { args: [], ); } + + /// `Заказать` + String get to_order { + return Intl.message( + 'Заказать', + name: 'to_order', + desc: '', + args: [], + ); + } + + /// `Дату старта плана невозможно выбрать, пока Вы не привяжите карту` + String get can_not_choose_start_date { + return Intl.message( + 'Дату старта плана невозможно выбрать, пока Вы не привяжите карту', + name: 'can_not_choose_start_date', + desc: '', + args: [], + ); + } + + /// `Привязать карту` + String get add_card { + return Intl.message( + 'Привязать карту', + name: 'add_card', + desc: '', + args: [], + ); + } + + /// `Выберите дату старта плана питания` + String get choose_plan_start_date { + return Intl.message( + 'Выберите дату старта плана питания', + name: 'choose_plan_start_date', + desc: '', + args: [], + ); + } + + /// `Выбрать дату` + String get choose_date { + return Intl.message( + 'Выбрать дату', + name: 'choose_date', + desc: '', + args: [], + ); + } + + /// `Дата старта начала консультации установлена` + String get date_has_ben_set { + return Intl.message( + 'Дата старта начала консультации установлена', + name: 'date_has_ben_set', + desc: '', + args: [], + ); + } + + // skipped getter for the 'tap_on_link_to)pay' key + + /// `Оплатить` + String get pay { + return Intl.message( + 'Оплатить', + name: 'pay', + desc: '', + args: [], + ); + } } class AppLocalizationDelegate extends LocalizationsDelegate { diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index c976ed0e..3594ada0 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -311,6 +311,15 @@ "could_not_update_diet": "Не удалось обновить диету", "could_not_publish_blog_post": "Не удалось опубликовать пост", "could_not_update_blog_post": "Не удалось обновить пост", - "could_not_delete_blog_post": "Не удалось удалить пост" + "could_not_delete_blog_post": "Не удалось удалить пост", + "to_order": "Заказать", + "can_not_choose_start_date": "Дату старта плана невозможно выбрать, пока Вы не привяжите карту", + "add_card": "Привязать карту", + "choose_plan_start_date": "Выберите дату старта плана питания", + "choose_date": "Выбрать дату", + "date_has_ben_set": "Дата старта начала консультации установлена", + "tap_on_link_to)pay": "Перейдите по ссылке для оплаты консультации", + "pay": "Оплатить" + } From 9d53760137db12d0848b7e8e657a173be6989341 Mon Sep 17 00:00:00 2001 From: Username1548 Date: Thu, 13 Mar 2025 02:30:10 +0700 Subject: [PATCH 2/4] fixed pagination --- lib/core/app_router.dart | 1 - lib/core/const.dart | 5 +- lib/core/utils/pagination_utils.dart | 8 + .../auth/presentation/pages/auth_screen.dart | 39 +- lib/features/chat/models/chat_room_model.dart | 9 + .../chat/models/chat_room_model.freezed.dart | 60 +++- .../chat/models/chat_room_model.g.dart | 2 + ...l.dart => chat_room_pagination_model.dart} | 24 +- ...> chat_room_pagination_model.freezed.dart} | 335 +++++++++++++++--- ...dart => chat_room_pagination_model.g.dart} | 24 +- .../bloc/chat_room_cubit/chat_room_cubit.dart | 11 + .../bloc/chats_cubit/chats_cubit.dart | 59 ++- .../bloc/chats_cubit/chats_state.dart | 3 +- .../bloc/chats_cubit/chats_state.freezed.dart | 25 +- .../chat/presentation/pages/chat_screen.dart | 1 - .../chat/presentation/pages/chats_screen.dart | 60 ++-- .../widgets/chat_entry_widget.dart | 4 +- .../chat/presentation/widgets/order_card.dart | 20 ++ .../chat/repositories/chat_repository.dart | 6 +- lib/features/chat/services/chat_service.dart | 5 +- .../chat/services/chat_service.g.dart | 13 +- lib/features/dev_tools/test_cases.dart | 30 +- .../bloc/diets_cubit/diets_cubit.dart | 2 +- .../bloc/feed_cubit/feed_cubit.dart | 2 +- .../bloc/plans_cubit/plans_cubit.dart | 2 +- .../bloc/recipes_cubit/recipes_cubit.dart | 2 +- .../feed/presentation/pages/feed_screen.dart | 30 +- .../feed/presentation/widgets/blog_posts.dart | 33 +- .../feed/presentation/widgets/diets.dart | 27 +- .../feed/presentation/widgets/plans.dart | 33 +- .../feed/presentation/widgets/recipes.dart | 33 +- .../plans/enums/chosen_plan_state_enum.dart | 44 +++ .../plans/models/chosen_plan_model.dart | 4 +- .../models/chosen_plan_model.freezed.dart | 79 ++--- .../plans/models/chosen_plan_model.g.dart | 22 +- .../bloc/profile_cubit/profile_cubit.dart | 5 +- .../presentation/pages/profile_screen.dart | 4 +- .../widgets/sub_action_button_widget.dart | 6 +- 38 files changed, 778 insertions(+), 294 deletions(-) create mode 100644 lib/core/utils/pagination_utils.dart rename lib/features/chat/models/{chat_room_preview_model.dart => chat_room_pagination_model.dart} (65%) rename lib/features/chat/models/{chat_room_preview_model.freezed.dart => chat_room_pagination_model.freezed.dart} (73%) rename lib/features/chat/models/{chat_room_preview_model.g.dart => chat_room_pagination_model.g.dart} (76%) create mode 100644 lib/features/chat/presentation/widgets/order_card.dart create mode 100644 lib/features/plans/enums/chosen_plan_state_enum.dart diff --git a/lib/core/app_router.dart b/lib/core/app_router.dart index fca6fac5..bea9fda0 100644 --- a/lib/core/app_router.dart +++ b/lib/core/app_router.dart @@ -7,7 +7,6 @@ import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/prof import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/profile_avatar_cubit/profile_avatar_state.dart'; import 'package:eatvio_app/features/bottom_navigation_bar/presentation/widgets/bottom_navigation_bar_widget.dart'; import 'package:eatvio_app/features/calendar/presentation/pages/calendar_screen.dart'; -import 'package:eatvio_app/features/chat/presentation/bloc/chats_cubit/chats_cubit.dart'; import 'package:eatvio_app/features/chat/presentation/pages/chat_screen.dart'; import 'package:eatvio_app/features/chat/presentation/pages/chats_screen.dart'; import 'package:eatvio_app/features/chat/presentation/pages/photo_view_screen.dart'; diff --git a/lib/core/const.dart b/lib/core/const.dart index 0b91d766..68cdc249 100644 --- a/lib/core/const.dart +++ b/lib/core/const.dart @@ -1,5 +1,5 @@ // String baseUrl = 'https://eatvio.ru'; -String baseUrl = 'https://dev2.eatvio.com'; +String baseUrl = 'http://10.55.5.123:8080'; const List durationValues = [7, 14, 21]; @@ -8,4 +8,5 @@ const List planTypeValues = ['fit', 'slim', 'wellness', 'behavior']; const newMessagesChannelName = 'private-new-chat-messages'; const newNotificationsChannelName = 'private-message-events'; -const directChatChannelName = 'private-direct-chat'; \ No newline at end of file +const directChatChannelName = 'private-direct-chat'; +const thresholdForPagination = 150; diff --git a/lib/core/utils/pagination_utils.dart b/lib/core/utils/pagination_utils.dart new file mode 100644 index 00000000..c6f6da95 --- /dev/null +++ b/lib/core/utils/pagination_utils.dart @@ -0,0 +1,8 @@ +import 'package:eatvio_app/core/const.dart'; +import 'package:flutter/material.dart'; + +void loadNewContent(ScrollNotification notification, Future Function() load) { + if (notification.metrics.pixels >= notification.metrics.maxScrollExtent - thresholdForPagination && !notification.metrics.outOfRange) { + load(); + } +} diff --git a/lib/features/auth/presentation/pages/auth_screen.dart b/lib/features/auth/presentation/pages/auth_screen.dart index e446ece8..818578ae 100644 --- a/lib/features/auth/presentation/pages/auth_screen.dart +++ b/lib/features/auth/presentation/pages/auth_screen.dart @@ -6,6 +6,7 @@ import 'package:eatvio_app/core/widgets/custom_text_form_field.dart'; import 'package:eatvio_app/features/auth/presentation/bloc/auth_cubit.dart'; import 'package:eatvio_app/generated/l10n.dart'; import 'package:flutter/cupertino.dart'; +import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_native_splash/flutter_native_splash.dart'; @@ -99,30 +100,30 @@ class _AuthScreenState extends State { ], ), Spacer(), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'Нажимая "Войти", Вы соглашаетесь с ', + Center( + child: RichText( + textAlign: TextAlign.center, + text: TextSpan( + text: 'Нажимая "Войти", Вы соглашаетесь \n', style: TextStyle( fontSize: 12, + color: Colors.black, ), - ), - GestureDetector( - onTap: () async { - await launchUrl(Uri.parse(baseUrl + '/oferta_bs.pdf')); - }, - child: Text( - 'Публичной офертой', - style: TextStyle( - fontSize: 12, - color: appTheme.blueA400, - decorationColor: appTheme.blueA400, - decoration: TextDecoration.underline, + children: [ + TextSpan(text: 'c '), + TextSpan( + text: ' Публичной офертой', + style: TextStyle( + fontSize: 12, + color: appTheme.blueA400, + decorationColor: appTheme.blueA400, + decoration: TextDecoration.underline, + ), + recognizer: TapGestureRecognizer()..onTap = () async => await launchUrl(Uri.parse(baseUrl + '/oferta_bs.pdf')), ), - ), + ], ), - ], + ), ), const SizedBox(height: 16), Container( diff --git a/lib/features/chat/models/chat_room_model.dart b/lib/features/chat/models/chat_room_model.dart index f9e9a416..13c12d0e 100644 --- a/lib/features/chat/models/chat_room_model.dart +++ b/lib/features/chat/models/chat_room_model.dart @@ -1,5 +1,6 @@ import 'package:eatvio_app/features/chat/models/chat_room_settings_model.dart'; import 'package:eatvio_app/features/chat/models/chat_user_model.dart'; +import 'package:eatvio_app/features/plans/models/chosen_plan_model.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; part 'chat_room_model.freezed.dart'; @@ -11,7 +12,15 @@ class ChatRoomModel with _$ChatRoomModel { required String id, @JsonKey(name: 'chat_room_setting') required ChatRoomSettingsModel chatRoomSettings, required Map users, + @JsonKey(name: 'chosen_plan', fromJson: _parseChosenPlan) required ChosenPlanModel? chosenPlan, }) = _ChatRoomModel; factory ChatRoomModel.fromJson(Map json) => _$ChatRoomModelFromJson(json); } + +ChosenPlanModel? _parseChosenPlan(json) { + if (json is Map) { + return ChosenPlanModel.fromJson(json); + } + return null; +} diff --git a/lib/features/chat/models/chat_room_model.freezed.dart b/lib/features/chat/models/chat_room_model.freezed.dart index 6afb3a94..7f46b373 100644 --- a/lib/features/chat/models/chat_room_model.freezed.dart +++ b/lib/features/chat/models/chat_room_model.freezed.dart @@ -25,6 +25,8 @@ mixin _$ChatRoomModel { ChatRoomSettingsModel get chatRoomSettings => throw _privateConstructorUsedError; Map get users => throw _privateConstructorUsedError; + @JsonKey(name: 'chosen_plan', fromJson: _parseChosenPlan) + ChosenPlanModel? get chosenPlan => throw _privateConstructorUsedError; /// Serializes this ChatRoomModel to a JSON map. Map toJson() => throw _privateConstructorUsedError; @@ -46,9 +48,12 @@ abstract class $ChatRoomModelCopyWith<$Res> { {String id, @JsonKey(name: 'chat_room_setting') ChatRoomSettingsModel chatRoomSettings, - Map users}); + Map users, + @JsonKey(name: 'chosen_plan', fromJson: _parseChosenPlan) + ChosenPlanModel? chosenPlan}); $ChatRoomSettingsModelCopyWith<$Res> get chatRoomSettings; + $ChosenPlanModelCopyWith<$Res>? get chosenPlan; } /// @nodoc @@ -69,6 +74,7 @@ class _$ChatRoomModelCopyWithImpl<$Res, $Val extends ChatRoomModel> Object? id = null, Object? chatRoomSettings = null, Object? users = null, + Object? chosenPlan = freezed, }) { return _then(_value.copyWith( id: null == id @@ -83,6 +89,10 @@ class _$ChatRoomModelCopyWithImpl<$Res, $Val extends ChatRoomModel> ? _value.users : users // ignore: cast_nullable_to_non_nullable as Map, + chosenPlan: freezed == chosenPlan + ? _value.chosenPlan + : chosenPlan // ignore: cast_nullable_to_non_nullable + as ChosenPlanModel?, ) as $Val); } @@ -96,6 +106,20 @@ class _$ChatRoomModelCopyWithImpl<$Res, $Val extends ChatRoomModel> return _then(_value.copyWith(chatRoomSettings: value) as $Val); }); } + + /// Create a copy of ChatRoomModel + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $ChosenPlanModelCopyWith<$Res>? get chosenPlan { + if (_value.chosenPlan == null) { + return null; + } + + return $ChosenPlanModelCopyWith<$Res>(_value.chosenPlan!, (value) { + return _then(_value.copyWith(chosenPlan: value) as $Val); + }); + } } /// @nodoc @@ -110,10 +134,14 @@ abstract class _$$ChatRoomModelImplCopyWith<$Res> {String id, @JsonKey(name: 'chat_room_setting') ChatRoomSettingsModel chatRoomSettings, - Map users}); + Map users, + @JsonKey(name: 'chosen_plan', fromJson: _parseChosenPlan) + ChosenPlanModel? chosenPlan}); @override $ChatRoomSettingsModelCopyWith<$Res> get chatRoomSettings; + @override + $ChosenPlanModelCopyWith<$Res>? get chosenPlan; } /// @nodoc @@ -132,6 +160,7 @@ class __$$ChatRoomModelImplCopyWithImpl<$Res> Object? id = null, Object? chatRoomSettings = null, Object? users = null, + Object? chosenPlan = freezed, }) { return _then(_$ChatRoomModelImpl( id: null == id @@ -146,6 +175,10 @@ class __$$ChatRoomModelImplCopyWithImpl<$Res> ? _value._users : users // ignore: cast_nullable_to_non_nullable as Map, + chosenPlan: freezed == chosenPlan + ? _value.chosenPlan + : chosenPlan // ignore: cast_nullable_to_non_nullable + as ChosenPlanModel?, )); } } @@ -156,7 +189,9 @@ class _$ChatRoomModelImpl implements _ChatRoomModel { const _$ChatRoomModelImpl( {required this.id, @JsonKey(name: 'chat_room_setting') required this.chatRoomSettings, - required final Map users}) + required final Map users, + @JsonKey(name: 'chosen_plan', fromJson: _parseChosenPlan) + required this.chosenPlan}) : _users = users; factory _$ChatRoomModelImpl.fromJson(Map json) => @@ -175,9 +210,13 @@ class _$ChatRoomModelImpl implements _ChatRoomModel { return EqualUnmodifiableMapView(_users); } + @override + @JsonKey(name: 'chosen_plan', fromJson: _parseChosenPlan) + final ChosenPlanModel? chosenPlan; + @override String toString() { - return 'ChatRoomModel(id: $id, chatRoomSettings: $chatRoomSettings, users: $users)'; + return 'ChatRoomModel(id: $id, chatRoomSettings: $chatRoomSettings, users: $users, chosenPlan: $chosenPlan)'; } @override @@ -188,13 +227,15 @@ class _$ChatRoomModelImpl implements _ChatRoomModel { (identical(other.id, id) || other.id == id) && (identical(other.chatRoomSettings, chatRoomSettings) || other.chatRoomSettings == chatRoomSettings) && - const DeepCollectionEquality().equals(other._users, _users)); + const DeepCollectionEquality().equals(other._users, _users) && + (identical(other.chosenPlan, chosenPlan) || + other.chosenPlan == chosenPlan)); } @JsonKey(includeFromJson: false, includeToJson: false) @override int get hashCode => Object.hash(runtimeType, id, chatRoomSettings, - const DeepCollectionEquality().hash(_users)); + const DeepCollectionEquality().hash(_users), chosenPlan); /// Create a copy of ChatRoomModel /// with the given fields replaced by the non-null parameter values. @@ -217,7 +258,9 @@ abstract class _ChatRoomModel implements ChatRoomModel { {required final String id, @JsonKey(name: 'chat_room_setting') required final ChatRoomSettingsModel chatRoomSettings, - required final Map users}) = _$ChatRoomModelImpl; + required final Map users, + @JsonKey(name: 'chosen_plan', fromJson: _parseChosenPlan) + required final ChosenPlanModel? chosenPlan}) = _$ChatRoomModelImpl; factory _ChatRoomModel.fromJson(Map json) = _$ChatRoomModelImpl.fromJson; @@ -229,6 +272,9 @@ abstract class _ChatRoomModel implements ChatRoomModel { ChatRoomSettingsModel get chatRoomSettings; @override Map get users; + @override + @JsonKey(name: 'chosen_plan', fromJson: _parseChosenPlan) + ChosenPlanModel? get chosenPlan; /// Create a copy of ChatRoomModel /// with the given fields replaced by the non-null parameter values. diff --git a/lib/features/chat/models/chat_room_model.g.dart b/lib/features/chat/models/chat_room_model.g.dart index 68d3195c..834f2d0e 100644 --- a/lib/features/chat/models/chat_room_model.g.dart +++ b/lib/features/chat/models/chat_room_model.g.dart @@ -15,6 +15,7 @@ _$ChatRoomModelImpl _$$ChatRoomModelImplFromJson(Map json) => (k, e) => MapEntry(k, ChatUserModel.fromJson(e as Map)), ), + chosenPlan: _parseChosenPlan(json['chosen_plan']), ); Map _$$ChatRoomModelImplToJson(_$ChatRoomModelImpl instance) => @@ -22,4 +23,5 @@ Map _$$ChatRoomModelImplToJson(_$ChatRoomModelImpl instance) => 'id': instance.id, 'chat_room_setting': instance.chatRoomSettings, 'users': instance.users, + 'chosen_plan': instance.chosenPlan, }; diff --git a/lib/features/chat/models/chat_room_preview_model.dart b/lib/features/chat/models/chat_room_pagination_model.dart similarity index 65% rename from lib/features/chat/models/chat_room_preview_model.dart rename to lib/features/chat/models/chat_room_pagination_model.dart index bc6e4b5d..6d44a685 100644 --- a/lib/features/chat/models/chat_room_preview_model.dart +++ b/lib/features/chat/models/chat_room_pagination_model.dart @@ -1,16 +1,28 @@ import 'package:eatvio_app/features/chat/models/chat_message_model.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; -part 'chat_room_preview_model.freezed.dart'; -part 'chat_room_preview_model.g.dart'; +part 'chat_room_pagination_model.freezed.dart'; +part 'chat_room_pagination_model.g.dart'; @freezed -class ChatRoomPreviewModel with _$ChatRoomPreviewModel { - const factory ChatRoomPreviewModel({ - @JsonKey(name: "chatRooms") required List chatRooms, +class ChatRoomPaginationModel with _$ChatRoomPaginationModel { + const factory ChatRoomPaginationModel({ + @JsonKey(name: "chatRooms") required ChatRooms chatRooms, + @JsonKey(name: "number_of_unread_chat_rooms") required int unreadChatsCount, }) = _ChatRoomPreviewModel; - factory ChatRoomPreviewModel.fromJson(Map json) => _$ChatRoomPreviewModelFromJson(json); + factory ChatRoomPaginationModel.fromJson(Map json) => _$ChatRoomPaginationModelFromJson(json); +} + +@freezed +class ChatRooms with _$ChatRooms { + const factory ChatRooms({ + @JsonKey(name: "data") required List data, + @JsonKey(name: "last_page") required int lastPage, + @JsonKey(name: "current_page") required int currentPage, + }) = _ChatRooms; + + factory ChatRooms.fromJson(Map json) => _$ChatRoomsFromJson(json); } @freezed diff --git a/lib/features/chat/models/chat_room_preview_model.freezed.dart b/lib/features/chat/models/chat_room_pagination_model.freezed.dart similarity index 73% rename from lib/features/chat/models/chat_room_preview_model.freezed.dart rename to lib/features/chat/models/chat_room_pagination_model.freezed.dart index 940c3106..42d8ef5f 100644 --- a/lib/features/chat/models/chat_room_preview_model.freezed.dart +++ b/lib/features/chat/models/chat_room_pagination_model.freezed.dart @@ -3,7 +3,7 @@ // 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 'chat_room_preview_model.dart'; +part of 'chat_room_pagination_model.dart'; // ************************************************************************** // FreezedGenerator @@ -14,92 +14,125 @@ 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'); -ChatRoomPreviewModel _$ChatRoomPreviewModelFromJson(Map json) { +ChatRoomPaginationModel _$ChatRoomPaginationModelFromJson( + Map json) { return _ChatRoomPreviewModel.fromJson(json); } /// @nodoc -mixin _$ChatRoomPreviewModel { +mixin _$ChatRoomPaginationModel { @JsonKey(name: "chatRooms") - List get chatRooms => throw _privateConstructorUsedError; + ChatRooms get chatRooms => throw _privateConstructorUsedError; + @JsonKey(name: "number_of_unread_chat_rooms") + int get unreadChatsCount => throw _privateConstructorUsedError; - /// Serializes this ChatRoomPreviewModel to a JSON map. + /// Serializes this ChatRoomPaginationModel to a JSON map. Map toJson() => throw _privateConstructorUsedError; - /// Create a copy of ChatRoomPreviewModel + /// Create a copy of ChatRoomPaginationModel /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) - $ChatRoomPreviewModelCopyWith get copyWith => + $ChatRoomPaginationModelCopyWith get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class $ChatRoomPreviewModelCopyWith<$Res> { - factory $ChatRoomPreviewModelCopyWith(ChatRoomPreviewModel value, - $Res Function(ChatRoomPreviewModel) then) = - _$ChatRoomPreviewModelCopyWithImpl<$Res, ChatRoomPreviewModel>; +abstract class $ChatRoomPaginationModelCopyWith<$Res> { + factory $ChatRoomPaginationModelCopyWith(ChatRoomPaginationModel value, + $Res Function(ChatRoomPaginationModel) then) = + _$ChatRoomPaginationModelCopyWithImpl<$Res, ChatRoomPaginationModel>; @useResult - $Res call({@JsonKey(name: "chatRooms") List chatRooms}); + $Res call( + {@JsonKey(name: "chatRooms") ChatRooms chatRooms, + @JsonKey(name: "number_of_unread_chat_rooms") int unreadChatsCount}); + + $ChatRoomsCopyWith<$Res> get chatRooms; } /// @nodoc -class _$ChatRoomPreviewModelCopyWithImpl<$Res, - $Val extends ChatRoomPreviewModel> - implements $ChatRoomPreviewModelCopyWith<$Res> { - _$ChatRoomPreviewModelCopyWithImpl(this._value, this._then); +class _$ChatRoomPaginationModelCopyWithImpl<$Res, + $Val extends ChatRoomPaginationModel> + implements $ChatRoomPaginationModelCopyWith<$Res> { + _$ChatRoomPaginationModelCopyWithImpl(this._value, this._then); // ignore: unused_field final $Val _value; // ignore: unused_field final $Res Function($Val) _then; - /// Create a copy of ChatRoomPreviewModel + /// Create a copy of ChatRoomPaginationModel /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ Object? chatRooms = null, + Object? unreadChatsCount = null, }) { return _then(_value.copyWith( chatRooms: null == chatRooms ? _value.chatRooms : chatRooms // ignore: cast_nullable_to_non_nullable - as List, + as ChatRooms, + unreadChatsCount: null == unreadChatsCount + ? _value.unreadChatsCount + : unreadChatsCount // ignore: cast_nullable_to_non_nullable + as int, ) as $Val); } + + /// Create a copy of ChatRoomPaginationModel + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $ChatRoomsCopyWith<$Res> get chatRooms { + return $ChatRoomsCopyWith<$Res>(_value.chatRooms, (value) { + return _then(_value.copyWith(chatRooms: value) as $Val); + }); + } } /// @nodoc abstract class _$$ChatRoomPreviewModelImplCopyWith<$Res> - implements $ChatRoomPreviewModelCopyWith<$Res> { + implements $ChatRoomPaginationModelCopyWith<$Res> { factory _$$ChatRoomPreviewModelImplCopyWith(_$ChatRoomPreviewModelImpl value, $Res Function(_$ChatRoomPreviewModelImpl) then) = __$$ChatRoomPreviewModelImplCopyWithImpl<$Res>; @override @useResult - $Res call({@JsonKey(name: "chatRooms") List chatRooms}); + $Res call( + {@JsonKey(name: "chatRooms") ChatRooms chatRooms, + @JsonKey(name: "number_of_unread_chat_rooms") int unreadChatsCount}); + + @override + $ChatRoomsCopyWith<$Res> get chatRooms; } /// @nodoc class __$$ChatRoomPreviewModelImplCopyWithImpl<$Res> - extends _$ChatRoomPreviewModelCopyWithImpl<$Res, _$ChatRoomPreviewModelImpl> + extends _$ChatRoomPaginationModelCopyWithImpl<$Res, + _$ChatRoomPreviewModelImpl> implements _$$ChatRoomPreviewModelImplCopyWith<$Res> { __$$ChatRoomPreviewModelImplCopyWithImpl(_$ChatRoomPreviewModelImpl _value, $Res Function(_$ChatRoomPreviewModelImpl) _then) : super(_value, _then); - /// Create a copy of ChatRoomPreviewModel + /// Create a copy of ChatRoomPaginationModel /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ Object? chatRooms = null, + Object? unreadChatsCount = null, }) { return _then(_$ChatRoomPreviewModelImpl( chatRooms: null == chatRooms - ? _value._chatRooms + ? _value.chatRooms : chatRooms // ignore: cast_nullable_to_non_nullable - as List, + as ChatRooms, + unreadChatsCount: null == unreadChatsCount + ? _value.unreadChatsCount + : unreadChatsCount // ignore: cast_nullable_to_non_nullable + as int, )); } } @@ -108,24 +141,23 @@ class __$$ChatRoomPreviewModelImplCopyWithImpl<$Res> @JsonSerializable() class _$ChatRoomPreviewModelImpl implements _ChatRoomPreviewModel { const _$ChatRoomPreviewModelImpl( - {@JsonKey(name: "chatRooms") required final List chatRooms}) - : _chatRooms = chatRooms; + {@JsonKey(name: "chatRooms") required this.chatRooms, + @JsonKey(name: "number_of_unread_chat_rooms") + required this.unreadChatsCount}); factory _$ChatRoomPreviewModelImpl.fromJson(Map json) => _$$ChatRoomPreviewModelImplFromJson(json); - final List _chatRooms; @override @JsonKey(name: "chatRooms") - List get chatRooms { - if (_chatRooms is EqualUnmodifiableListView) return _chatRooms; - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(_chatRooms); - } + final ChatRooms chatRooms; + @override + @JsonKey(name: "number_of_unread_chat_rooms") + final int unreadChatsCount; @override String toString() { - return 'ChatRoomPreviewModel(chatRooms: $chatRooms)'; + return 'ChatRoomPaginationModel(chatRooms: $chatRooms, unreadChatsCount: $unreadChatsCount)'; } @override @@ -133,16 +165,17 @@ class _$ChatRoomPreviewModelImpl implements _ChatRoomPreviewModel { return identical(this, other) || (other.runtimeType == runtimeType && other is _$ChatRoomPreviewModelImpl && - const DeepCollectionEquality() - .equals(other._chatRooms, _chatRooms)); + (identical(other.chatRooms, chatRooms) || + other.chatRooms == chatRooms) && + (identical(other.unreadChatsCount, unreadChatsCount) || + other.unreadChatsCount == unreadChatsCount)); } @JsonKey(includeFromJson: false, includeToJson: false) @override - int get hashCode => - Object.hash(runtimeType, const DeepCollectionEquality().hash(_chatRooms)); + int get hashCode => Object.hash(runtimeType, chatRooms, unreadChatsCount); - /// Create a copy of ChatRoomPreviewModel + /// Create a copy of ChatRoomPaginationModel /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @override @@ -160,19 +193,23 @@ class _$ChatRoomPreviewModelImpl implements _ChatRoomPreviewModel { } } -abstract class _ChatRoomPreviewModel implements ChatRoomPreviewModel { +abstract class _ChatRoomPreviewModel implements ChatRoomPaginationModel { const factory _ChatRoomPreviewModel( - {@JsonKey(name: "chatRooms") - required final List chatRooms}) = _$ChatRoomPreviewModelImpl; + {@JsonKey(name: "chatRooms") required final ChatRooms chatRooms, + @JsonKey(name: "number_of_unread_chat_rooms") + required final int unreadChatsCount}) = _$ChatRoomPreviewModelImpl; factory _ChatRoomPreviewModel.fromJson(Map json) = _$ChatRoomPreviewModelImpl.fromJson; @override @JsonKey(name: "chatRooms") - List get chatRooms; + ChatRooms get chatRooms; + @override + @JsonKey(name: "number_of_unread_chat_rooms") + int get unreadChatsCount; - /// Create a copy of ChatRoomPreviewModel + /// Create a copy of ChatRoomPaginationModel /// with the given fields replaced by the non-null parameter values. @override @JsonKey(includeFromJson: false, includeToJson: false) @@ -180,6 +217,218 @@ abstract class _ChatRoomPreviewModel implements ChatRoomPreviewModel { get copyWith => throw _privateConstructorUsedError; } +ChatRooms _$ChatRoomsFromJson(Map json) { + return _ChatRooms.fromJson(json); +} + +/// @nodoc +mixin _$ChatRooms { + @JsonKey(name: "data") + List get data => throw _privateConstructorUsedError; + @JsonKey(name: "last_page") + int get lastPage => throw _privateConstructorUsedError; + @JsonKey(name: "current_page") + int get currentPage => throw _privateConstructorUsedError; + + /// Serializes this ChatRooms to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of ChatRooms + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $ChatRoomsCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ChatRoomsCopyWith<$Res> { + factory $ChatRoomsCopyWith(ChatRooms value, $Res Function(ChatRooms) then) = + _$ChatRoomsCopyWithImpl<$Res, ChatRooms>; + @useResult + $Res call( + {@JsonKey(name: "data") List data, + @JsonKey(name: "last_page") int lastPage, + @JsonKey(name: "current_page") int currentPage}); +} + +/// @nodoc +class _$ChatRoomsCopyWithImpl<$Res, $Val extends ChatRooms> + implements $ChatRoomsCopyWith<$Res> { + _$ChatRoomsCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of ChatRooms + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? data = null, + Object? lastPage = null, + Object? currentPage = null, + }) { + return _then(_value.copyWith( + data: null == data + ? _value.data + : data // ignore: cast_nullable_to_non_nullable + as List, + lastPage: null == lastPage + ? _value.lastPage + : lastPage // ignore: cast_nullable_to_non_nullable + as int, + currentPage: null == currentPage + ? _value.currentPage + : currentPage // ignore: cast_nullable_to_non_nullable + as int, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$ChatRoomsImplCopyWith<$Res> + implements $ChatRoomsCopyWith<$Res> { + factory _$$ChatRoomsImplCopyWith( + _$ChatRoomsImpl value, $Res Function(_$ChatRoomsImpl) then) = + __$$ChatRoomsImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {@JsonKey(name: "data") List data, + @JsonKey(name: "last_page") int lastPage, + @JsonKey(name: "current_page") int currentPage}); +} + +/// @nodoc +class __$$ChatRoomsImplCopyWithImpl<$Res> + extends _$ChatRoomsCopyWithImpl<$Res, _$ChatRoomsImpl> + implements _$$ChatRoomsImplCopyWith<$Res> { + __$$ChatRoomsImplCopyWithImpl( + _$ChatRoomsImpl _value, $Res Function(_$ChatRoomsImpl) _then) + : super(_value, _then); + + /// Create a copy of ChatRooms + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? data = null, + Object? lastPage = null, + Object? currentPage = null, + }) { + return _then(_$ChatRoomsImpl( + data: null == data + ? _value._data + : data // ignore: cast_nullable_to_non_nullable + as List, + lastPage: null == lastPage + ? _value.lastPage + : lastPage // ignore: cast_nullable_to_non_nullable + as int, + currentPage: null == currentPage + ? _value.currentPage + : currentPage // ignore: cast_nullable_to_non_nullable + as int, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$ChatRoomsImpl implements _ChatRooms { + const _$ChatRoomsImpl( + {@JsonKey(name: "data") required final List data, + @JsonKey(name: "last_page") required this.lastPage, + @JsonKey(name: "current_page") required this.currentPage}) + : _data = data; + + factory _$ChatRoomsImpl.fromJson(Map json) => + _$$ChatRoomsImplFromJson(json); + + final List _data; + @override + @JsonKey(name: "data") + List get data { + if (_data is EqualUnmodifiableListView) return _data; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_data); + } + + @override + @JsonKey(name: "last_page") + final int lastPage; + @override + @JsonKey(name: "current_page") + final int currentPage; + + @override + String toString() { + return 'ChatRooms(data: $data, lastPage: $lastPage, currentPage: $currentPage)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ChatRoomsImpl && + const DeepCollectionEquality().equals(other._data, _data) && + (identical(other.lastPage, lastPage) || + other.lastPage == lastPage) && + (identical(other.currentPage, currentPage) || + other.currentPage == currentPage)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash(runtimeType, + const DeepCollectionEquality().hash(_data), lastPage, currentPage); + + /// Create a copy of ChatRooms + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ChatRoomsImplCopyWith<_$ChatRoomsImpl> get copyWith => + __$$ChatRoomsImplCopyWithImpl<_$ChatRoomsImpl>(this, _$identity); + + @override + Map toJson() { + return _$$ChatRoomsImplToJson( + this, + ); + } +} + +abstract class _ChatRooms implements ChatRooms { + const factory _ChatRooms( + {@JsonKey(name: "data") required final List data, + @JsonKey(name: "last_page") required final int lastPage, + @JsonKey(name: "current_page") required final int currentPage}) = + _$ChatRoomsImpl; + + factory _ChatRooms.fromJson(Map json) = + _$ChatRoomsImpl.fromJson; + + @override + @JsonKey(name: "data") + List get data; + @override + @JsonKey(name: "last_page") + int get lastPage; + @override + @JsonKey(name: "current_page") + int get currentPage; + + /// Create a copy of ChatRooms + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ChatRoomsImplCopyWith<_$ChatRoomsImpl> get copyWith => + throw _privateConstructorUsedError; +} + ChatRoom _$ChatRoomFromJson(Map json) { return _ChatRoom.fromJson(json); } diff --git a/lib/features/chat/models/chat_room_preview_model.g.dart b/lib/features/chat/models/chat_room_pagination_model.g.dart similarity index 76% rename from lib/features/chat/models/chat_room_preview_model.g.dart rename to lib/features/chat/models/chat_room_pagination_model.g.dart index ad812d46..3b9ac87b 100644 --- a/lib/features/chat/models/chat_room_preview_model.g.dart +++ b/lib/features/chat/models/chat_room_pagination_model.g.dart @@ -1,6 +1,6 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'chat_room_preview_model.dart'; +part of 'chat_room_pagination_model.dart'; // ************************************************************************** // JsonSerializableGenerator @@ -9,15 +9,31 @@ part of 'chat_room_preview_model.dart'; _$ChatRoomPreviewModelImpl _$$ChatRoomPreviewModelImplFromJson( Map json) => _$ChatRoomPreviewModelImpl( - chatRooms: (json['chatRooms'] as List) - .map((e) => ChatRoom.fromJson(e as Map)) - .toList(), + chatRooms: ChatRooms.fromJson(json['chatRooms'] as Map), + unreadChatsCount: (json['number_of_unread_chat_rooms'] as num).toInt(), ); Map _$$ChatRoomPreviewModelImplToJson( _$ChatRoomPreviewModelImpl instance) => { 'chatRooms': instance.chatRooms, + 'number_of_unread_chat_rooms': instance.unreadChatsCount, + }; + +_$ChatRoomsImpl _$$ChatRoomsImplFromJson(Map json) => + _$ChatRoomsImpl( + data: (json['data'] as List) + .map((e) => ChatRoom.fromJson(e as Map)) + .toList(), + lastPage: (json['last_page'] as num).toInt(), + currentPage: (json['current_page'] as num).toInt(), + ); + +Map _$$ChatRoomsImplToJson(_$ChatRoomsImpl instance) => + { + 'data': instance.data, + 'last_page': instance.lastPage, + 'current_page': instance.currentPage, }; _$ChatRoomImpl _$$ChatRoomImplFromJson(Map json) => diff --git a/lib/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart b/lib/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart index a7f94802..3ba4422c 100644 --- a/lib/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart +++ b/lib/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart @@ -86,6 +86,17 @@ class ChatRoomCubit extends Cubit { } } + Future updateChatRoom(String chatId) async{ + try { + final chatRoom = await chatRepository.getChatRoom(chatId); + emit( + (state as ChatRoomStateLoaded).copyWith(chatRoom: chatRoom), + ); + } catch (e) { + emit(ChatRoomState.error(errorMessage: 'Ошибка получеия данных')); + } + } + Future _subscribeToChatChannel({ required String chatId, }) async { diff --git a/lib/features/chat/presentation/bloc/chats_cubit/chats_cubit.dart b/lib/features/chat/presentation/bloc/chats_cubit/chats_cubit.dart index f165ca83..a4f0bbf2 100644 --- a/lib/features/chat/presentation/bloc/chats_cubit/chats_cubit.dart +++ b/lib/features/chat/presentation/bloc/chats_cubit/chats_cubit.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:convert'; +import 'dart:developer'; import 'package:eatvio_app/core/enums/base_state.dart'; import 'package:eatvio_app/core/websockets/ws_manager.dart'; @@ -30,21 +31,24 @@ class ChatsCubit extends Cubit { }); } String? _query; + int page = 1; + late int lastPage; Future getChatRoomsWithLoading({String? query}) async { + page = 1; _query = query; emit(state.copyWith(state: BaseState.loading)); try { - final chatRooms = await chatRepository.getChatRoomPreviews(query: query); - final unreadChats = chatRooms.where( - (element) => element.unreadMessagesCount > 0, - ); + final chatRoomsPaginationModel = await chatRepository.getChatRooms(query: query); + final unreadChats = chatRoomsPaginationModel.unreadChatsCount; + lastPage = chatRoomsPaginationModel.chatRooms.lastPage + 1; emit( state.copyWith( - chatRooms: chatRooms, - chatsWithUnreadMessagesCount: unreadChats.length, + chatRooms: chatRoomsPaginationModel.chatRooms.data, + chatsWithUnreadMessagesCount: unreadChats, state: BaseState.success, ), ); + page++; } catch (e) { emit( state.copyWith(errorMessage: e.toString(), state: BaseState.error), @@ -53,26 +57,55 @@ class ChatsCubit extends Cubit { } Future getChatRooms({String? query}) async { + page = 1; _query = query; try { - final chatRooms = await chatRepository.getChatRoomPreviews(query: query); - final unreadChats = chatRooms.where( - (element) => element.unreadMessagesCount > 0, - ); + final chatRoomsPaginationModel = await chatRepository.getChatRooms(query: query); + final unreadChats = chatRoomsPaginationModel.unreadChatsCount; + lastPage = chatRoomsPaginationModel.chatRooms.lastPage + 1; emit( state.copyWith( - chatRooms: chatRooms, - chatsWithUnreadMessagesCount: unreadChats.length, + chatRooms: chatRoomsPaginationModel.chatRooms.data, + chatsWithUnreadMessagesCount: unreadChats, state: BaseState.success, ), ); - } catch (e) { + page++; + } catch (e, st) { + log(e.toString(), stackTrace: st); emit( state.copyWith(errorMessage: e.toString(), state: BaseState.error), ); } } + Future loadMoreChatRooms() async { + try { + if (state.isLoadingMoreChats || lastPage == page) return; + emit(state.copyWith(isLoadingMoreChats: true)); + final chatRoomsPaginationModel = await chatRepository.getChatRooms(query: _query, page: page); + final unreadChats = chatRoomsPaginationModel.unreadChatsCount; + emit( + state.copyWith( + chatRooms: [...state.chatRooms, ...chatRoomsPaginationModel.chatRooms.data], + chatsWithUnreadMessagesCount: unreadChats, + state: BaseState.success, + isLoadingMoreChats: false, + ), + ); + page++; + } catch (e, st) { + log(e.toString(), stackTrace: st); + emit( + state.copyWith( + errorMessage: e.toString(), + state: BaseState.error, + isLoadingMoreChats: false, + ), + ); + } + } + void reduceUnreadMessagesCount({required String chatId, required int count}) { bool isChatRead = false; final updatedChatRooms = state.chatRooms.map((room) { diff --git a/lib/features/chat/presentation/bloc/chats_cubit/chats_state.dart b/lib/features/chat/presentation/bloc/chats_cubit/chats_state.dart index 24bde4fa..700542d0 100644 --- a/lib/features/chat/presentation/bloc/chats_cubit/chats_state.dart +++ b/lib/features/chat/presentation/bloc/chats_cubit/chats_state.dart @@ -1,5 +1,5 @@ import 'package:eatvio_app/core/enums/base_state.dart'; -import 'package:eatvio_app/features/chat/models/chat_room_preview_model.dart'; +import 'package:eatvio_app/features/chat/models/chat_room_pagination_model.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; part 'chats_state.freezed.dart'; @@ -11,6 +11,7 @@ class ChatsState with _$ChatsState { @Default(BaseState.initial) BaseState state, @Default(0) int chatsWithUnreadMessagesCount, @Default([]) List chatRooms, + @Default(false) bool isLoadingMoreChats, @Default(null) String? errorMessage, }) = _ChatsState; diff --git a/lib/features/chat/presentation/bloc/chats_cubit/chats_state.freezed.dart b/lib/features/chat/presentation/bloc/chats_cubit/chats_state.freezed.dart index 77fd911d..a2271568 100644 --- a/lib/features/chat/presentation/bloc/chats_cubit/chats_state.freezed.dart +++ b/lib/features/chat/presentation/bloc/chats_cubit/chats_state.freezed.dart @@ -19,6 +19,7 @@ mixin _$ChatsState { BaseState get state => throw _privateConstructorUsedError; int get chatsWithUnreadMessagesCount => throw _privateConstructorUsedError; List get chatRooms => throw _privateConstructorUsedError; + bool get isLoadingMoreChats => throw _privateConstructorUsedError; String? get errorMessage => throw _privateConstructorUsedError; /// Create a copy of ChatsState @@ -38,6 +39,7 @@ abstract class $ChatsStateCopyWith<$Res> { {BaseState state, int chatsWithUnreadMessagesCount, List chatRooms, + bool isLoadingMoreChats, String? errorMessage}); } @@ -59,6 +61,7 @@ class _$ChatsStateCopyWithImpl<$Res, $Val extends ChatsState> Object? state = null, Object? chatsWithUnreadMessagesCount = null, Object? chatRooms = null, + Object? isLoadingMoreChats = null, Object? errorMessage = freezed, }) { return _then(_value.copyWith( @@ -74,6 +77,10 @@ class _$ChatsStateCopyWithImpl<$Res, $Val extends ChatsState> ? _value.chatRooms : chatRooms // ignore: cast_nullable_to_non_nullable as List, + isLoadingMoreChats: null == isLoadingMoreChats + ? _value.isLoadingMoreChats + : isLoadingMoreChats // ignore: cast_nullable_to_non_nullable + as bool, errorMessage: freezed == errorMessage ? _value.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable @@ -94,6 +101,7 @@ abstract class _$$ChatsStateImplCopyWith<$Res> {BaseState state, int chatsWithUnreadMessagesCount, List chatRooms, + bool isLoadingMoreChats, String? errorMessage}); } @@ -113,6 +121,7 @@ class __$$ChatsStateImplCopyWithImpl<$Res> Object? state = null, Object? chatsWithUnreadMessagesCount = null, Object? chatRooms = null, + Object? isLoadingMoreChats = null, Object? errorMessage = freezed, }) { return _then(_$ChatsStateImpl( @@ -128,6 +137,10 @@ class __$$ChatsStateImplCopyWithImpl<$Res> ? _value._chatRooms : chatRooms // ignore: cast_nullable_to_non_nullable as List, + isLoadingMoreChats: null == isLoadingMoreChats + ? _value.isLoadingMoreChats + : isLoadingMoreChats // ignore: cast_nullable_to_non_nullable + as bool, errorMessage: freezed == errorMessage ? _value.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable @@ -143,6 +156,7 @@ class _$ChatsStateImpl implements _ChatsState { {this.state = BaseState.initial, this.chatsWithUnreadMessagesCount = 0, final List chatRooms = const [], + this.isLoadingMoreChats = false, this.errorMessage = null}) : _chatRooms = chatRooms; @@ -161,13 +175,16 @@ class _$ChatsStateImpl implements _ChatsState { return EqualUnmodifiableListView(_chatRooms); } + @override + @JsonKey() + final bool isLoadingMoreChats; @override @JsonKey() final String? errorMessage; @override String toString() { - return 'ChatsState(state: $state, chatsWithUnreadMessagesCount: $chatsWithUnreadMessagesCount, chatRooms: $chatRooms, errorMessage: $errorMessage)'; + return 'ChatsState(state: $state, chatsWithUnreadMessagesCount: $chatsWithUnreadMessagesCount, chatRooms: $chatRooms, isLoadingMoreChats: $isLoadingMoreChats, errorMessage: $errorMessage)'; } @override @@ -182,6 +199,8 @@ class _$ChatsStateImpl implements _ChatsState { chatsWithUnreadMessagesCount) && const DeepCollectionEquality() .equals(other._chatRooms, _chatRooms) && + (identical(other.isLoadingMoreChats, isLoadingMoreChats) || + other.isLoadingMoreChats == isLoadingMoreChats) && (identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)); } @@ -192,6 +211,7 @@ class _$ChatsStateImpl implements _ChatsState { state, chatsWithUnreadMessagesCount, const DeepCollectionEquality().hash(_chatRooms), + isLoadingMoreChats, errorMessage); /// Create a copy of ChatsState @@ -208,6 +228,7 @@ abstract class _ChatsState implements ChatsState { {final BaseState state, final int chatsWithUnreadMessagesCount, final List chatRooms, + final bool isLoadingMoreChats, final String? errorMessage}) = _$ChatsStateImpl; @override @@ -217,6 +238,8 @@ abstract class _ChatsState implements ChatsState { @override List get chatRooms; @override + bool get isLoadingMoreChats; + @override String? get errorMessage; /// Create a copy of ChatsState diff --git a/lib/features/chat/presentation/pages/chat_screen.dart b/lib/features/chat/presentation/pages/chat_screen.dart index 4b2d8b94..1d0b8b0c 100644 --- a/lib/features/chat/presentation/pages/chat_screen.dart +++ b/lib/features/chat/presentation/pages/chat_screen.dart @@ -11,7 +11,6 @@ import 'package:eatvio_app/features/chat/presentation/widgets/chat_bubble_widget import 'package:eatvio_app/core/locator_service.dart'; import 'package:eatvio_app/core/theme/custom_text_style.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; -import 'package:eatvio_app/features/chat/presentation/widgets/notification_banner.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/lib/features/chat/presentation/pages/chats_screen.dart b/lib/features/chat/presentation/pages/chats_screen.dart index 18f2b581..75882083 100644 --- a/lib/features/chat/presentation/pages/chats_screen.dart +++ b/lib/features/chat/presentation/pages/chats_screen.dart @@ -1,5 +1,6 @@ import 'package:easy_debounce/easy_debounce.dart'; import 'package:eatvio_app/core/enums/base_state.dart'; +import 'package:eatvio_app/core/utils/pagination_utils.dart'; import 'package:eatvio_app/core/widgets/data_error_widget.dart'; import 'package:eatvio_app/core/widgets/loader.dart'; import 'package:eatvio_app/features/chat/presentation/bloc/chats_cubit/chats_cubit.dart'; @@ -16,7 +17,7 @@ class ChatsScreen extends StatefulWidget { State createState() => _ChatsScreenState(); } -class _ChatsScreenState extends State { +class _ChatsScreenState extends State { final searchController = TextEditingController(); Widget build(BuildContext context) { @@ -65,45 +66,40 @@ class _ChatsScreenState extends State { ), ]; }, - body: stateBuilder(state), + body: switch (state.state) { + BaseState.error => DataErrorWidget(onReload: () => context.read().getChatRooms()), + BaseState.success => _buildChatList(context, state), + _ => const Loader(), + }, ), ); }, ); } - stateBuilder(ChatsState state) { - if (state.state == BaseState.loading) { - return Scaffold( - body: const Loader(), - ); - } else if (state.state == BaseState.success) { - return _buildChatList(context, state); - } else if (state.state == BaseState.error) { - return Scaffold( - body: DataErrorWidget(onReload: () => context.read().getChatRooms()), - ); - } else { - return Scaffold( - body: const Loader(), - ); - } - } - _buildChatList(BuildContext context, ChatsState state) { - return ListView.separated( - padding: EdgeInsets.all(16), - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - separatorBuilder: (context, index) { - return SizedBox( - height: 8, - ); - }, - itemCount: state.chatRooms.length, - itemBuilder: (context, index) { - return ChatEntryWidget(chatRoom: state.chatRooms[index]); + return NotificationListener( + onNotification: (notification) { + loadNewContent(notification, context.read().loadMoreChatRooms); + return false; }, + child: ListView.separated( + padding: EdgeInsets.all(16), + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + separatorBuilder: (context, index) { + return SizedBox( + height: 8, + ); + }, + itemCount: state.isLoadingMoreChats ? state.chatRooms.length + 1 : state.chatRooms.length, + itemBuilder: (context, index) { + if (index == state.chatRooms.length) { + return Center(child: Loader()); + } + return ChatEntryWidget(chatRoom: state.chatRooms[index]); + }, + ), ); } } diff --git a/lib/features/chat/presentation/widgets/chat_entry_widget.dart b/lib/features/chat/presentation/widgets/chat_entry_widget.dart index 66e0d700..4e1eea67 100644 --- a/lib/features/chat/presentation/widgets/chat_entry_widget.dart +++ b/lib/features/chat/presentation/widgets/chat_entry_widget.dart @@ -1,10 +1,8 @@ import 'package:eatvio_app/core/utils/date_time_utils.dart'; -import 'package:eatvio_app/features/chat/models/chat_room_preview_model.dart'; +import 'package:eatvio_app/features/chat/models/chat_room_pagination_model.dart'; import 'package:eatvio_app/core/theme/custom_text_style.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; -import 'package:eatvio_app/features/chat/presentation/bloc/chats_cubit/chats_cubit.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; class ChatEntryWidget extends StatefulWidget { diff --git a/lib/features/chat/presentation/widgets/order_card.dart b/lib/features/chat/presentation/widgets/order_card.dart new file mode 100644 index 00000000..5f57f362 --- /dev/null +++ b/lib/features/chat/presentation/widgets/order_card.dart @@ -0,0 +1,20 @@ +import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart'; +import 'package:flutter/material.dart'; + +class OrderCard extends StatelessWidget { + final PlanModel plan; + final bool isUserView; + const OrderCard({super.key, required this.plan, required this.isUserView}); + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.only(top: 8, bottom: 12, left: 8, right: 8), + child: Column( + children: [ + + ], + ), + ); + } +} diff --git a/lib/features/chat/repositories/chat_repository.dart b/lib/features/chat/repositories/chat_repository.dart index 9458d9f5..bdc537f8 100644 --- a/lib/features/chat/repositories/chat_repository.dart +++ b/lib/features/chat/repositories/chat_repository.dart @@ -5,7 +5,7 @@ import 'package:dio/dio.dart'; import 'package:eatvio_app/features/chat/models/chat_message_model.dart'; import 'package:eatvio_app/features/chat/models/chat_messages_model.dart'; import 'package:eatvio_app/features/chat/models/chat_room_model.dart'; -import 'package:eatvio_app/features/chat/models/chat_room_preview_model.dart'; +import 'package:eatvio_app/features/chat/models/chat_room_pagination_model.dart'; import 'package:eatvio_app/features/chat/services/chat_service.dart'; import 'package:http_parser/http_parser.dart'; @@ -62,9 +62,9 @@ class ChatRepository { } } - Future> getChatRoomPreviews({String? query}) async { + Future getChatRooms({String? query, int page = 1}) async { try { - return (await chatService.getChatRoomPreviews(query: query)).chatRooms; + return (await chatService.getChatRooms(query: query, page: page)); } catch (e) { rethrow; } diff --git a/lib/features/chat/services/chat_service.dart b/lib/features/chat/services/chat_service.dart index 2eb2423f..65910a34 100644 --- a/lib/features/chat/services/chat_service.dart +++ b/lib/features/chat/services/chat_service.dart @@ -1,7 +1,7 @@ import 'package:dio/dio.dart'; import 'package:eatvio_app/features/chat/models/chat_messages_model.dart'; import 'package:eatvio_app/features/chat/models/chat_room_model.dart'; -import 'package:eatvio_app/features/chat/models/chat_room_preview_model.dart'; +import 'package:eatvio_app/features/chat/models/chat_room_pagination_model.dart'; import 'package:retrofit/retrofit.dart'; part 'chat_service.g.dart'; @@ -11,7 +11,8 @@ abstract class ChatService { factory ChatService(Dio dio, {String baseUrl}) = _ChatService; @GET('/api/chat/index') - Future getChatRoomPreviews({ + Future getChatRooms({ + @Query('page') required int page, @Query('find') String? query, }); diff --git a/lib/features/chat/services/chat_service.g.dart b/lib/features/chat/services/chat_service.g.dart index 4cd570df..69a70741 100644 --- a/lib/features/chat/services/chat_service.g.dart +++ b/lib/features/chat/services/chat_service.g.dart @@ -18,13 +18,16 @@ class _ChatService implements ChatService { final ParseErrorLogger? errorLogger; @override - Future getChatRoomPreviews({String? query}) async { + Future getChatRooms({ + required int page, + String? query, + }) async { final _extra = {}; - final queryParameters = {r'find': query}; + final queryParameters = {r'page': page, r'find': query}; queryParameters.removeWhere((k, v) => v == null); final _headers = {}; const Map? _data = null; - final _options = _setStreamType( + final _options = _setStreamType( Options(method: 'GET', headers: _headers, extra: _extra) .compose( _dio.options, @@ -35,9 +38,9 @@ class _ChatService implements ChatService { .copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)), ); final _result = await _dio.fetch>(_options); - late ChatRoomPreviewModel _value; + late ChatRoomPaginationModel _value; try { - _value = ChatRoomPreviewModel.fromJson(_result.data!); + _value = ChatRoomPaginationModel.fromJson(_result.data!); } on Object catch (e, s) { errorLogger?.logError(e, s, _options); rethrow; diff --git a/lib/features/dev_tools/test_cases.dart b/lib/features/dev_tools/test_cases.dart index 8c92a104..39e563f5 100644 --- a/lib/features/dev_tools/test_cases.dart +++ b/lib/features/dev_tools/test_cases.dart @@ -125,10 +125,10 @@ class GetChatRoomPreviews implements TestCases { Future run({required String baseUrl}) async { try { // get all of needed services - final dio = sl(); - final chatService = ChatService(dio, baseUrl: baseUrl); + // final dio = sl(); + // final chatService = ChatService(dio, baseUrl: baseUrl); - await chatService.getChatRoomPreviews(); + // await chatService.getChatRooms(); return true; } catch (e) { return false; @@ -143,11 +143,11 @@ class GetChatRoom implements TestCases { @override Future run({required String baseUrl}) async { try { - final dio = sl(); - final chatService = ChatService(dio, baseUrl: baseUrl); + // final dio = sl(); + // final chatService = ChatService(dio, baseUrl: baseUrl); - final chatRoomsModels = await chatService.getChatRoomPreviews(); - await chatService.getChatRoom(id: chatRoomsModels.chatRooms.firstOrNull?.id ?? ''); + // final chatRoomsModels = await chatService.getChatRoomPreviews(); + // await chatService.getChatRoom(id: chatRoomsModels.chatRooms.firstOrNull?.id ?? ''); return true; } catch (e) { return false; @@ -162,11 +162,11 @@ class SendMessage implements TestCases { @override Future run({required String baseUrl}) async { try { - final dio = sl(); - final chatService = ChatService(dio, baseUrl: baseUrl); + // final dio = sl(); + // final chatService = ChatService(dio, baseUrl: baseUrl); - final chatRoomsModels = await chatService.getChatRoomPreviews(); - await chatService.sendMessage(id: chatRoomsModels.chatRooms.firstOrNull?.id ?? '', data: 'test message'); + // final chatRoomsModels = await chatService.getChatRoomPreviews(); + // await chatService.sendMessage(id: chatRoomsModels.chatRooms.firstOrNull?.id ?? '', data: 'test message'); return true; } catch (e) { return false; @@ -181,11 +181,11 @@ class GetChatMessages implements TestCases { @override Future run({required String baseUrl}) async { try { - final dio = sl(); - final chatService = ChatService(dio, baseUrl: baseUrl); + // final dio = sl(); + // final chatService = ChatService(dio, baseUrl: baseUrl); - final chatRoomsModels = await chatService.getChatRoomPreviews(); - await chatService.getChatMessages(id: chatRoomsModels.chatRooms.firstOrNull?.id ?? '', page: 1); + // final chatRoomsModels = await chatService.getChatRoomPreviews(); + // await chatService.getChatMessages(id: chatRoomsModels.chatRooms.firstOrNull?.id ?? '', page: 1); return true; } catch (e) { return false; 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 1770e23d..84da2f34 100644 --- a/lib/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart +++ b/lib/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart @@ -115,7 +115,7 @@ class DietsCubit extends Cubit { } } - loadNextPage() async { + Future loadNextPage() async { if (currentPage < lastPage && !isLoading) { isLoading = true; diff --git a/lib/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart b/lib/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart index 2af91d22..51552e2b 100644 --- a/lib/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart +++ b/lib/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart @@ -47,7 +47,7 @@ class FeedCubit extends Cubit { } } - loadNextPage() async { + Future loadNextPage() async { if (currentPage < lastPage && !isLoading) { isLoading = true; diff --git a/lib/features/feed/presentation/bloc/plans_cubit/plans_cubit.dart b/lib/features/feed/presentation/bloc/plans_cubit/plans_cubit.dart index 69c0f2ee..10d6addb 100644 --- a/lib/features/feed/presentation/bloc/plans_cubit/plans_cubit.dart +++ b/lib/features/feed/presentation/bloc/plans_cubit/plans_cubit.dart @@ -174,7 +174,7 @@ class PlansCubit extends Cubit { } } - loadNextPage() async { + Future loadNextPage() async { if (currentPage < lastPage && !isLoading) { isLoading = true; diff --git a/lib/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart b/lib/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart index 0144fc00..1eb1027f 100644 --- a/lib/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart +++ b/lib/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart @@ -67,7 +67,7 @@ class RecipesCubit extends Cubit { } } - loadNextPage() async { + Future loadNextPage() async { if (currentPage < lastPage && !isLoading) { isLoading = true; diff --git a/lib/features/feed/presentation/pages/feed_screen.dart b/lib/features/feed/presentation/pages/feed_screen.dart index faf90370..e139da56 100644 --- a/lib/features/feed/presentation/pages/feed_screen.dart +++ b/lib/features/feed/presentation/pages/feed_screen.dart @@ -77,38 +77,12 @@ class _FeedScreenContentState extends State { final consultantsScrollController = ScrollController(); @override - void initState() { - blogPostsScrollController.addListener(_onScrollBlogPosts); - recipesScrollController.addListener(_onScrollRecipes); - dietsScrollController.addListener(_onScrollDiets); - plansScrollController.addListener(_onScrollPlans); + void initState() { consultantsScrollController.addListener(_onScrollConsultants); super.initState(); - } + } - _onScrollBlogPosts() { - if (blogPostsScrollController.offset >= blogPostsScrollController.position.maxScrollExtent && !blogPostsScrollController.position.outOfRange) { - context.read().loadNextPage(); - } - } - _onScrollRecipes() { - if (recipesScrollController.offset >= recipesScrollController.position.maxScrollExtent && !recipesScrollController.position.outOfRange) { - context.read().loadNextPage(); - } - } - - _onScrollDiets() { - if (dietsScrollController.offset >= dietsScrollController.position.maxScrollExtent && !dietsScrollController.position.outOfRange) { - context.read().loadNextPage(); - } - } - - _onScrollPlans() { - if (plansScrollController.offset >= plansScrollController.position.maxScrollExtent && !plansScrollController.position.outOfRange) { - context.read().loadNextPage(); - } - } _onScrollConsultants() { if (consultantsScrollController.offset >= consultantsScrollController.position.maxScrollExtent && !consultantsScrollController.position.outOfRange) {} diff --git a/lib/features/feed/presentation/widgets/blog_posts.dart b/lib/features/feed/presentation/widgets/blog_posts.dart index da5363fe..fa77dcf9 100644 --- a/lib/features/feed/presentation/widgets/blog_posts.dart +++ b/lib/features/feed/presentation/widgets/blog_posts.dart @@ -1,3 +1,4 @@ +import 'package:eatvio_app/core/utils/pagination_utils.dart'; import 'package:eatvio_app/core/widgets/data_error_widget.dart'; import 'package:eatvio_app/core/widgets/loader.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart'; @@ -16,20 +17,26 @@ class BlogPosts extends StatelessWidget { child: BlocBuilder( builder: (BuildContext context, FeedState state) { if (state is FeedStateLoaded) { - return ListView.separated( - padding: EdgeInsets.symmetric(vertical: 8), - shrinkWrap: true, - physics: BouncingScrollPhysics(), - itemBuilder: (context, index) { - if (index == state.feedBlogPostList.length) { - return const Loader(); - } - return BlogPostWidget(index: index); + return NotificationListener( + onNotification: (notification) { + loadNewContent(notification, context.read().loadNextPage); + return false; }, - separatorBuilder: (context, index) { - return SizedBox(height: 8); - }, - itemCount: state.isLoading ? state.feedBlogPostList.length + 1 : state.feedBlogPostList.length, + child: ListView.separated( + padding: EdgeInsets.symmetric(vertical: 8), + shrinkWrap: true, + physics: BouncingScrollPhysics(), + itemBuilder: (context, index) { + if (index == state.feedBlogPostList.length) { + return const Loader(); + } + return BlogPostWidget(index: index); + }, + separatorBuilder: (context, index) { + return SizedBox(height: 8); + }, + itemCount: state.isLoading ? state.feedBlogPostList.length + 1 : state.feedBlogPostList.length, + ), ); } else if (state is FeedStateError) { return DataErrorWidget( diff --git a/lib/features/feed/presentation/widgets/diets.dart b/lib/features/feed/presentation/widgets/diets.dart index 254a9567..405d6469 100644 --- a/lib/features/feed/presentation/widgets/diets.dart +++ b/lib/features/feed/presentation/widgets/diets.dart @@ -1,3 +1,4 @@ +import 'package:eatvio_app/core/utils/pagination_utils.dart'; import 'package:eatvio_app/core/widgets/data_error_widget.dart'; import 'package:eatvio_app/core/widgets/loader.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart'; @@ -28,17 +29,23 @@ class Diets extends StatelessWidget { return Stack( children: [ SizedBox.expand(), - ListView.separated( - padding: EdgeInsets.symmetric(vertical: 8), - shrinkWrap: true, - physics: BouncingScrollPhysics(), - itemBuilder: (context, index) { - return DietsWidget(diet: state.dietsList[index], index: index); + NotificationListener( + onNotification: (notification) { + loadNewContent(notification, context.read().loadNextPage); + return false; }, - separatorBuilder: (context, index) { - return SizedBox(height: 8); - }, - itemCount: state.dietsList.length, + child: 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, diff --git a/lib/features/feed/presentation/widgets/plans.dart b/lib/features/feed/presentation/widgets/plans.dart index cc3a1a63..e8d894a3 100644 --- a/lib/features/feed/presentation/widgets/plans.dart +++ b/lib/features/feed/presentation/widgets/plans.dart @@ -1,3 +1,4 @@ +import 'package:eatvio_app/core/utils/pagination_utils.dart'; import 'package:eatvio_app/core/widgets/data_error_widget.dart'; import 'package:eatvio_app/core/widgets/loader.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/plans_cubit/plans_cubit.dart'; @@ -28,20 +29,26 @@ class Plans extends StatelessWidget { return Stack( children: [ SizedBox.expand(), - ListView.separated( - padding: EdgeInsets.symmetric(vertical: 8), - shrinkWrap: true, - physics: BouncingScrollPhysics(), - itemBuilder: (context, index) { - return PlanWidget( - plan: state.plans[index], - index: index, - ); + NotificationListener( + onNotification: (notification) { + loadNewContent(notification, context.read().loadNextPage); + return false; }, - separatorBuilder: (context, index) { - return SizedBox(height: 8); - }, - itemCount: state.plans.length, + child: ListView.separated( + padding: EdgeInsets.symmetric(vertical: 8), + shrinkWrap: true, + physics: BouncingScrollPhysics(), + itemBuilder: (context, index) { + return PlanWidget( + plan: state.plans[index], + index: index, + ); + }, + separatorBuilder: (context, index) { + return SizedBox(height: 8); + }, + itemCount: state.plans.length, + ), ), Positioned( right: 0, diff --git a/lib/features/feed/presentation/widgets/recipes.dart b/lib/features/feed/presentation/widgets/recipes.dart index b75d50ee..d62f2320 100644 --- a/lib/features/feed/presentation/widgets/recipes.dart +++ b/lib/features/feed/presentation/widgets/recipes.dart @@ -1,3 +1,4 @@ +import 'package:eatvio_app/core/utils/pagination_utils.dart'; import 'package:eatvio_app/core/widgets/data_error_widget.dart'; import 'package:eatvio_app/core/widgets/loader.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart'; @@ -29,20 +30,26 @@ class Recipes extends StatelessWidget { ); } - return ListView.separated( - padding: EdgeInsets.symmetric(vertical: 8), - shrinkWrap: true, - physics: BouncingScrollPhysics(), - itemBuilder: (context, index) { - return RecipesWidget( - recipe: state.recipesList[index], - index: index, - ); + return NotificationListener( + onNotification: (notification) { + loadNewContent(notification, context.read().loadNextPage); + return false; }, - separatorBuilder: (context, index) { - return SizedBox(height: 8); - }, - itemCount: state.recipesList.length, + child: ListView.separated( + padding: EdgeInsets.symmetric(vertical: 8), + shrinkWrap: true, + physics: BouncingScrollPhysics(), + itemBuilder: (context, index) { + return RecipesWidget( + recipe: state.recipesList[index], + index: index, + ); + }, + separatorBuilder: (context, index) { + return SizedBox(height: 8); + }, + itemCount: state.recipesList.length, + ), ); }, ), diff --git a/lib/features/plans/enums/chosen_plan_state_enum.dart b/lib/features/plans/enums/chosen_plan_state_enum.dart new file mode 100644 index 00000000..03016712 --- /dev/null +++ b/lib/features/plans/enums/chosen_plan_state_enum.dart @@ -0,0 +1,44 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +enum ChosenPlanStateEnum { + @JsonValue('initied') + stateInited, + @JsonValue('start_date_has_been_set') + stateStartDateHasBeenSet, + @JsonValue('in_coordination') + stateInCoordination, + @JsonValue('started') + stateStarted, + @JsonValue('in_progress') + stateInProgress, + @JsonValue('pending_payment') + statePendingPayment, + @JsonValue('confirmed_by_consultant') + stateConfirmedByConsultant, + @JsonValue('paid') + statePaid, + @JsonValue('canceled_by_the_initiator') + stateCanceledByTheInitiator, + @JsonValue('last_day_started') + stateLastDayStarted, + @JsonValue('last_day_finished') + stateLastDayFinished, + @JsonValue('complained') + stateComplained, + @JsonValue('done') + stateDone, + @JsonValue('charge_was_collected') + stateChargeWasCollected; + + static List getShowableChatBadgeStates() { + return [ + ChosenPlanStateEnum.stateInCoordination, + ChosenPlanStateEnum.stateStartDateHasBeenSet, + ChosenPlanStateEnum.statePendingPayment, + ChosenPlanStateEnum.statePaid, + ChosenPlanStateEnum.stateLastDayStarted, + ChosenPlanStateEnum.stateLastDayFinished, + ChosenPlanStateEnum.stateDone, + ]; + } +} diff --git a/lib/features/plans/models/chosen_plan_model.dart b/lib/features/plans/models/chosen_plan_model.dart index 525418b2..f42d6d80 100644 --- a/lib/features/plans/models/chosen_plan_model.dart +++ b/lib/features/plans/models/chosen_plan_model.dart @@ -1,4 +1,4 @@ -import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart'; +import 'package:eatvio_app/features/plans/enums/chosen_plan_state_enum.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; part 'chosen_plan_model.freezed.dart'; @@ -11,8 +11,8 @@ class ChosenPlanModel with _$ChosenPlanModel { @JsonKey() required int id, @JsonKey(name: 'option_type') required String optionType, @JsonKey(name: 'start_date') required DateTime startDate, + @JsonKey(name: 'last_state') required ChosenPlanStateEnum chosenPlanState, @JsonKey(name: 'chat_id') required String chatId, - @JsonKey(name: 'plan') required PlanModel plan, }) = _ChosenPlanModel; diff --git a/lib/features/plans/models/chosen_plan_model.freezed.dart b/lib/features/plans/models/chosen_plan_model.freezed.dart index b26b04cd..3c7d7325 100644 --- a/lib/features/plans/models/chosen_plan_model.freezed.dart +++ b/lib/features/plans/models/chosen_plan_model.freezed.dart @@ -26,10 +26,10 @@ mixin _$ChosenPlanModel { String get optionType => throw _privateConstructorUsedError; @JsonKey(name: 'start_date') DateTime get startDate => throw _privateConstructorUsedError; + @JsonKey(name: 'last_state') + ChosenPlanStateEnum get chosenPlanState => throw _privateConstructorUsedError; @JsonKey(name: 'chat_id') String get chatId => throw _privateConstructorUsedError; - @JsonKey(name: 'plan') - PlanModel get plan => throw _privateConstructorUsedError; /// Serializes this ChosenPlanModel to a JSON map. Map toJson() => throw _privateConstructorUsedError; @@ -51,10 +51,8 @@ abstract class $ChosenPlanModelCopyWith<$Res> { {@JsonKey() int id, @JsonKey(name: 'option_type') String optionType, @JsonKey(name: 'start_date') DateTime startDate, - @JsonKey(name: 'chat_id') String chatId, - @JsonKey(name: 'plan') PlanModel plan}); - - $PlanModelCopyWith<$Res> get plan; + @JsonKey(name: 'last_state') ChosenPlanStateEnum chosenPlanState, + @JsonKey(name: 'chat_id') String chatId}); } /// @nodoc @@ -75,8 +73,8 @@ class _$ChosenPlanModelCopyWithImpl<$Res, $Val extends ChosenPlanModel> Object? id = null, Object? optionType = null, Object? startDate = null, + Object? chosenPlanState = null, Object? chatId = null, - Object? plan = null, }) { return _then(_value.copyWith( id: null == id @@ -91,26 +89,16 @@ class _$ChosenPlanModelCopyWithImpl<$Res, $Val extends ChosenPlanModel> ? _value.startDate : startDate // ignore: cast_nullable_to_non_nullable as DateTime, + chosenPlanState: null == chosenPlanState + ? _value.chosenPlanState + : chosenPlanState // ignore: cast_nullable_to_non_nullable + as ChosenPlanStateEnum, chatId: null == chatId ? _value.chatId : chatId // ignore: cast_nullable_to_non_nullable as String, - plan: null == plan - ? _value.plan - : plan // ignore: cast_nullable_to_non_nullable - as PlanModel, ) as $Val); } - - /// Create a copy of ChosenPlanModel - /// with the given fields replaced by the non-null parameter values. - @override - @pragma('vm:prefer-inline') - $PlanModelCopyWith<$Res> get plan { - return $PlanModelCopyWith<$Res>(_value.plan, (value) { - return _then(_value.copyWith(plan: value) as $Val); - }); - } } /// @nodoc @@ -125,11 +113,8 @@ abstract class _$$ChosenPlanModelImplCopyWith<$Res> {@JsonKey() int id, @JsonKey(name: 'option_type') String optionType, @JsonKey(name: 'start_date') DateTime startDate, - @JsonKey(name: 'chat_id') String chatId, - @JsonKey(name: 'plan') PlanModel plan}); - - @override - $PlanModelCopyWith<$Res> get plan; + @JsonKey(name: 'last_state') ChosenPlanStateEnum chosenPlanState, + @JsonKey(name: 'chat_id') String chatId}); } /// @nodoc @@ -148,8 +133,8 @@ class __$$ChosenPlanModelImplCopyWithImpl<$Res> Object? id = null, Object? optionType = null, Object? startDate = null, + Object? chosenPlanState = null, Object? chatId = null, - Object? plan = null, }) { return _then(_$ChosenPlanModelImpl( id: null == id @@ -164,14 +149,14 @@ class __$$ChosenPlanModelImplCopyWithImpl<$Res> ? _value.startDate : startDate // ignore: cast_nullable_to_non_nullable as DateTime, + chosenPlanState: null == chosenPlanState + ? _value.chosenPlanState + : chosenPlanState // ignore: cast_nullable_to_non_nullable + as ChosenPlanStateEnum, chatId: null == chatId ? _value.chatId : chatId // ignore: cast_nullable_to_non_nullable as String, - plan: null == plan - ? _value.plan - : plan // ignore: cast_nullable_to_non_nullable - as PlanModel, )); } } @@ -183,8 +168,8 @@ class _$ChosenPlanModelImpl implements _ChosenPlanModel { {@JsonKey() required this.id, @JsonKey(name: 'option_type') required this.optionType, @JsonKey(name: 'start_date') required this.startDate, - @JsonKey(name: 'chat_id') required this.chatId, - @JsonKey(name: 'plan') required this.plan}); + @JsonKey(name: 'last_state') required this.chosenPlanState, + @JsonKey(name: 'chat_id') required this.chatId}); factory _$ChosenPlanModelImpl.fromJson(Map json) => _$$ChosenPlanModelImplFromJson(json); @@ -199,15 +184,15 @@ class _$ChosenPlanModelImpl implements _ChosenPlanModel { @JsonKey(name: 'start_date') final DateTime startDate; @override + @JsonKey(name: 'last_state') + final ChosenPlanStateEnum chosenPlanState; + @override @JsonKey(name: 'chat_id') final String chatId; - @override - @JsonKey(name: 'plan') - final PlanModel plan; @override String toString() { - return 'ChosenPlanModel(id: $id, optionType: $optionType, startDate: $startDate, chatId: $chatId, plan: $plan)'; + return 'ChosenPlanModel(id: $id, optionType: $optionType, startDate: $startDate, chosenPlanState: $chosenPlanState, chatId: $chatId)'; } @override @@ -220,14 +205,15 @@ class _$ChosenPlanModelImpl implements _ChosenPlanModel { other.optionType == optionType) && (identical(other.startDate, startDate) || other.startDate == startDate) && - (identical(other.chatId, chatId) || other.chatId == chatId) && - (identical(other.plan, plan) || other.plan == plan)); + (identical(other.chosenPlanState, chosenPlanState) || + other.chosenPlanState == chosenPlanState) && + (identical(other.chatId, chatId) || other.chatId == chatId)); } @JsonKey(includeFromJson: false, includeToJson: false) @override - int get hashCode => - Object.hash(runtimeType, id, optionType, startDate, chatId, plan); + int get hashCode => Object.hash( + runtimeType, id, optionType, startDate, chosenPlanState, chatId); /// Create a copy of ChosenPlanModel /// with the given fields replaced by the non-null parameter values. @@ -251,8 +237,9 @@ abstract class _ChosenPlanModel implements ChosenPlanModel { {@JsonKey() required final int id, @JsonKey(name: 'option_type') required final String optionType, @JsonKey(name: 'start_date') required final DateTime startDate, - @JsonKey(name: 'chat_id') required final String chatId, - @JsonKey(name: 'plan') required final PlanModel plan}) = + @JsonKey(name: 'last_state') + required final ChosenPlanStateEnum chosenPlanState, + @JsonKey(name: 'chat_id') required final String chatId}) = _$ChosenPlanModelImpl; factory _ChosenPlanModel.fromJson(Map json) = @@ -268,11 +255,11 @@ abstract class _ChosenPlanModel implements ChosenPlanModel { @JsonKey(name: 'start_date') DateTime get startDate; @override + @JsonKey(name: 'last_state') + ChosenPlanStateEnum get chosenPlanState; + @override @JsonKey(name: 'chat_id') String get chatId; - @override - @JsonKey(name: 'plan') - PlanModel get plan; /// Create a copy of ChosenPlanModel /// with the given fields replaced by the non-null parameter values. diff --git a/lib/features/plans/models/chosen_plan_model.g.dart b/lib/features/plans/models/chosen_plan_model.g.dart index 52ecbdb7..7e64a4e4 100644 --- a/lib/features/plans/models/chosen_plan_model.g.dart +++ b/lib/features/plans/models/chosen_plan_model.g.dart @@ -12,8 +12,9 @@ _$ChosenPlanModelImpl _$$ChosenPlanModelImplFromJson( id: (json['id'] as num).toInt(), optionType: json['option_type'] as String, startDate: DateTime.parse(json['start_date'] as String), + chosenPlanState: + $enumDecode(_$ChosenPlanStateEnumEnumMap, json['last_state']), chatId: json['chat_id'] as String, - plan: PlanModel.fromJson(json['plan'] as Map), ); Map _$$ChosenPlanModelImplToJson( @@ -22,6 +23,23 @@ Map _$$ChosenPlanModelImplToJson( 'id': instance.id, 'option_type': instance.optionType, 'start_date': instance.startDate.toIso8601String(), + 'last_state': _$ChosenPlanStateEnumEnumMap[instance.chosenPlanState]!, 'chat_id': instance.chatId, - 'plan': instance.plan, }; + +const _$ChosenPlanStateEnumEnumMap = { + ChosenPlanStateEnum.stateInited: 'initied', + ChosenPlanStateEnum.stateStartDateHasBeenSet: 'start_date_has_been_set', + ChosenPlanStateEnum.stateInCoordination: 'in_coordination', + ChosenPlanStateEnum.stateStarted: 'started', + ChosenPlanStateEnum.stateInProgress: 'in_progress', + ChosenPlanStateEnum.statePendingPayment: 'pending_payment', + ChosenPlanStateEnum.stateConfirmedByConsultant: 'confirmed_by_consultant', + ChosenPlanStateEnum.statePaid: 'paid', + ChosenPlanStateEnum.stateCanceledByTheInitiator: 'canceled_by_the_initiator', + ChosenPlanStateEnum.stateLastDayStarted: 'last_day_started', + ChosenPlanStateEnum.stateLastDayFinished: 'last_day_finished', + ChosenPlanStateEnum.stateComplained: 'complained', + ChosenPlanStateEnum.stateDone: 'done', + ChosenPlanStateEnum.stateChargeWasCollected: 'charge_was_collected', +}; diff --git a/lib/features/profile/presentation/bloc/profile_cubit/profile_cubit.dart b/lib/features/profile/presentation/bloc/profile_cubit/profile_cubit.dart index 6b89e051..71fb1729 100644 --- a/lib/features/profile/presentation/bloc/profile_cubit/profile_cubit.dart +++ b/lib/features/profile/presentation/bloc/profile_cubit/profile_cubit.dart @@ -101,8 +101,9 @@ class ProfileCubit extends Cubit { }) async { try { return (await chatRepository.getChatRoomIdByUserSlug(slug: slug)).id; - } catch (e) { - rethrow; + } catch (e, st) { + log(e.toString(), stackTrace: st); + return ''; } } diff --git a/lib/features/profile/presentation/pages/profile_screen.dart b/lib/features/profile/presentation/pages/profile_screen.dart index 6d12aa9b..707eddfa 100644 --- a/lib/features/profile/presentation/pages/profile_screen.dart +++ b/lib/features/profile/presentation/pages/profile_screen.dart @@ -1079,7 +1079,9 @@ class _ProfileScreenState extends State { onTap: () async { GoRouter.of(context).pushNamed( 'chatScreen', - extra: await profileCubit.getChatRoomIdBySlug(slug: widget.author!.authorSlug), + extra: { + 'chatId': await profileCubit.getChatRoomIdBySlug(slug: widget.author!.authorSlug), + }, ); }, child: Container( diff --git a/lib/features/profile/presentation/widgets/sub_action_button_widget.dart b/lib/features/profile/presentation/widgets/sub_action_button_widget.dart index 0db41687..429d7176 100644 --- a/lib/features/profile/presentation/widgets/sub_action_button_widget.dart +++ b/lib/features/profile/presentation/widgets/sub_action_button_widget.dart @@ -62,8 +62,10 @@ class _SubActionButtonWidgetState extends State { return InkWell( onTap: () async { GoRouter.of(context).pushNamed( - 'chatScreen', - extra: await sl().getChatRoomIdBySlug(slug: widget.slug), + 'chatScreen', + extra: { + 'chatId': await sl().getChatRoomIdBySlug(slug: widget.slug), + }, ); }, borderRadius: BorderRadius.circular(8), From 803588a289be53eaaa82153b045c551f70b12a8b Mon Sep 17 00:00:00 2001 From: Username1548 Date: Fri, 14 Mar 2025 19:56:55 +0700 Subject: [PATCH 3/4] chats have been updated to work with consultatons --- lib/core/const.dart | 2 +- lib/core/theme/theme_helper.dart | 1 + lib/core/widgets/item_widget.dart | 47 ++ .../auth/presentation/bloc/auth_cubit.dart | 8 +- .../auth/presentation/pages/auth_screen.dart | 12 +- lib/features/chat/models/chat_room_model.dart | 21 +- .../chat/models/chat_room_model.freezed.dart | 267 +++++++++-- .../chat/models/chat_room_model.g.dart | 20 +- .../models/chat_room_pagination_model.dart | 2 + .../chat_room_pagination_model.freezed.dart | 62 ++- .../models/chat_room_pagination_model.g.dart | 2 + .../bloc/chat_room_cubit/chat_room_cubit.dart | 13 +- .../chat/presentation/pages/chat_screen.dart | 442 +++++++++++------- .../chat/presentation/widgets/order_card.dart | 132 +++++- .../chat/repositories/chat_repository.dart | 10 + lib/features/chat/services/chat_service.dart | 12 +- .../chat/services/chat_service.g.dart | 19 + .../menu/presentation/pages/menu_screen.dart | 4 +- .../plans/models/chosen_plan_model.dart | 11 +- .../models/chosen_plan_model.freezed.dart | 78 +++- .../plans/models/chosen_plan_model.g.dart | 4 + .../presentation/widgets/item_widget.dart | 27 -- .../presentation/widgets/option_widget.dart | 2 +- lib/generated/intl/messages_en.dart | 5 + lib/generated/l10n.dart | 30 ++ lib/l10n/intl_en.arb | 5 +- 26 files changed, 957 insertions(+), 281 deletions(-) create mode 100644 lib/core/widgets/item_widget.dart delete mode 100644 lib/features/plans/presentation/widgets/item_widget.dart diff --git a/lib/core/const.dart b/lib/core/const.dart index 68cdc249..4f38a54e 100644 --- a/lib/core/const.dart +++ b/lib/core/const.dart @@ -1,5 +1,5 @@ // String baseUrl = 'https://eatvio.ru'; -String baseUrl = 'http://10.55.5.123:8080'; +String baseUrl = 'https://dev2.eatvio.com'; const List durationValues = [7, 14, 21]; diff --git a/lib/core/theme/theme_helper.dart b/lib/core/theme/theme_helper.dart index 2c319dd8..d4326bf4 100644 --- a/lib/core/theme/theme_helper.dart +++ b/lib/core/theme/theme_helper.dart @@ -184,6 +184,7 @@ class PrimaryColors { Color get dottedBorder => Color(0xFFE6E6E6); Color get red => Color(0xFFCD4141); + Color get strongRed => Color(0xFFD01717); Color get transparentRed => Color(0xFFCD4141).withValues(alpha: 0.75); diff --git a/lib/core/widgets/item_widget.dart b/lib/core/widgets/item_widget.dart new file mode 100644 index 00000000..c7af63c5 --- /dev/null +++ b/lib/core/widgets/item_widget.dart @@ -0,0 +1,47 @@ +import 'package:eatvio_app/core/theme/custom_text_style.dart'; +import 'package:eatvio_app/core/theme/theme_helper.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class ItemWidget extends StatelessWidget { + const ItemWidget({super.key, required this.text, this.reversed = false, this.iconSize = 20}); + final String text; + final bool reversed; + final double iconSize; + @override + Widget build(BuildContext context) { + if (reversed) { + return Row( + children: [ + SvgPicture.asset( + 'assets/icons/ok.svg', + width: iconSize, + height: iconSize, + ), + SizedBox(width: 8), + Expanded( + child: Text( + text, + style: TextStyles.textMMedium.copyWith(color: appTheme.black), + ), + ), + ], + ); + } + return Row( + children: [ + Expanded( + child: Text( + text, + style: TextStyles.textMMedium.copyWith(color: appTheme.black), + ), + ), + SvgPicture.asset( + 'assets/icons/ok.svg', + width: iconSize, + height: iconSize, + ), + ], + ); + } +} diff --git a/lib/features/auth/presentation/bloc/auth_cubit.dart b/lib/features/auth/presentation/bloc/auth_cubit.dart index da1c3fef..dc521829 100644 --- a/lib/features/auth/presentation/bloc/auth_cubit.dart +++ b/lib/features/auth/presentation/bloc/auth_cubit.dart @@ -1,10 +1,8 @@ import 'package:eatvio_app/core/app_router.dart'; -import 'package:eatvio_app/core/locator_service.dart'; import 'package:eatvio_app/core/token_storage.dart'; import 'package:eatvio_app/core/utils/toasts.dart'; import 'package:eatvio_app/features/auth/presentation/bloc/auth_state.dart'; import 'package:eatvio_app/features/auth/repositories/auth_repository.dart'; -import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/profile_avatar_cubit/profile_avatar_cubit.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; @@ -15,7 +13,7 @@ class AuthCubit extends Cubit { required this.authRepository, }) : super(AuthState()); - getTokenByCredentials(String email, String password) async { + Future getTokenByCredentials(String email, String password) async { emit(AuthState.loading()); try { final token = (await authRepository.getTokenByCredentials( @@ -23,7 +21,6 @@ class AuthCubit extends Cubit { password, )) .token; - print(token); emit( AuthState.loaded( token: token, @@ -31,12 +28,13 @@ class AuthCubit extends Cubit { ); showSuccessToast('Успешный вход'); await TokenStorage.saveTokenInStorage(token); - await sl().getMyProfile(); AppRouter.navigatorKey.currentContext?.go('/my-profile-screen'); + return true; } catch (e) { print(e); showErrorToast('Неверный адрес электронной почты или пароль'); emit(AuthState.error(errorMessage: '$e')); + return false; } } } diff --git a/lib/features/auth/presentation/pages/auth_screen.dart b/lib/features/auth/presentation/pages/auth_screen.dart index 818578ae..3ba8097e 100644 --- a/lib/features/auth/presentation/pages/auth_screen.dart +++ b/lib/features/auth/presentation/pages/auth_screen.dart @@ -4,6 +4,8 @@ import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:eatvio_app/core/utils/image_constant.dart'; import 'package:eatvio_app/core/widgets/custom_text_form_field.dart'; import 'package:eatvio_app/features/auth/presentation/bloc/auth_cubit.dart'; +import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/profile_avatar_cubit/profile_avatar_cubit.dart'; +import 'package:eatvio_app/features/chat/presentation/bloc/chats_cubit/chats_cubit.dart'; import 'package:eatvio_app/generated/l10n.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/gestures.dart'; @@ -140,10 +142,16 @@ class _AuthScreenState extends State { backgroundColor: state is AuthStateLoading ? Colors.black.withAlpha(50) : appTheme.blueA400, onPressed: state is AuthStateLoading ? null - : () => authCubit.getTokenByCredentials( + : () async { + final isAuthenticated = await authCubit.getTokenByCredentials( emailController.text, passwordController.text, - ), + ); + if (isAuthenticated) { + context.read().getMyProfile(); + context.read().getChatRoomsWithLoading(); + } + }, label: state is AuthStateLoading ? CupertinoActivityIndicator() : Text( diff --git a/lib/features/chat/models/chat_room_model.dart b/lib/features/chat/models/chat_room_model.dart index 13c12d0e..9d77fdf0 100644 --- a/lib/features/chat/models/chat_room_model.dart +++ b/lib/features/chat/models/chat_room_model.dart @@ -11,16 +11,23 @@ class ChatRoomModel with _$ChatRoomModel { const factory ChatRoomModel({ required String id, @JsonKey(name: 'chat_room_setting') required ChatRoomSettingsModel chatRoomSettings, - required Map users, - @JsonKey(name: 'chosen_plan', fromJson: _parseChosenPlan) required ChosenPlanModel? chosenPlan, + required Users users, + @JsonKey(name: 'chosen_plan', fromJson: parseChosenPlan) required ChosenPlanModel? chosenPlan, }) = _ChatRoomModel; factory ChatRoomModel.fromJson(Map json) => _$ChatRoomModelFromJson(json); } -ChosenPlanModel? _parseChosenPlan(json) { - if (json is Map) { - return ChosenPlanModel.fromJson(json); - } - return null; +@freezed +class Users with _$Users { + const factory Users({ + + @JsonKey(name: 'from_chat_user') required ChatUserModel sender, + @JsonKey(name: 'to_chat_user') required ChatUserModel receiver, + + }) = _Users; + + factory Users.fromJson(Map json) => _$UsersFromJson(json); } + + diff --git a/lib/features/chat/models/chat_room_model.freezed.dart b/lib/features/chat/models/chat_room_model.freezed.dart index 7f46b373..829dd69f 100644 --- a/lib/features/chat/models/chat_room_model.freezed.dart +++ b/lib/features/chat/models/chat_room_model.freezed.dart @@ -24,8 +24,8 @@ mixin _$ChatRoomModel { @JsonKey(name: 'chat_room_setting') ChatRoomSettingsModel get chatRoomSettings => throw _privateConstructorUsedError; - Map get users => throw _privateConstructorUsedError; - @JsonKey(name: 'chosen_plan', fromJson: _parseChosenPlan) + Users get users => throw _privateConstructorUsedError; + @JsonKey(name: 'chosen_plan', fromJson: parseChosenPlan) ChosenPlanModel? get chosenPlan => throw _privateConstructorUsedError; /// Serializes this ChatRoomModel to a JSON map. @@ -48,11 +48,12 @@ abstract class $ChatRoomModelCopyWith<$Res> { {String id, @JsonKey(name: 'chat_room_setting') ChatRoomSettingsModel chatRoomSettings, - Map users, - @JsonKey(name: 'chosen_plan', fromJson: _parseChosenPlan) + Users users, + @JsonKey(name: 'chosen_plan', fromJson: parseChosenPlan) ChosenPlanModel? chosenPlan}); $ChatRoomSettingsModelCopyWith<$Res> get chatRoomSettings; + $UsersCopyWith<$Res> get users; $ChosenPlanModelCopyWith<$Res>? get chosenPlan; } @@ -88,7 +89,7 @@ class _$ChatRoomModelCopyWithImpl<$Res, $Val extends ChatRoomModel> users: null == users ? _value.users : users // ignore: cast_nullable_to_non_nullable - as Map, + as Users, chosenPlan: freezed == chosenPlan ? _value.chosenPlan : chosenPlan // ignore: cast_nullable_to_non_nullable @@ -107,6 +108,16 @@ class _$ChatRoomModelCopyWithImpl<$Res, $Val extends ChatRoomModel> }); } + /// Create a copy of ChatRoomModel + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $UsersCopyWith<$Res> get users { + return $UsersCopyWith<$Res>(_value.users, (value) { + return _then(_value.copyWith(users: value) as $Val); + }); + } + /// Create a copy of ChatRoomModel /// with the given fields replaced by the non-null parameter values. @override @@ -134,13 +145,15 @@ abstract class _$$ChatRoomModelImplCopyWith<$Res> {String id, @JsonKey(name: 'chat_room_setting') ChatRoomSettingsModel chatRoomSettings, - Map users, - @JsonKey(name: 'chosen_plan', fromJson: _parseChosenPlan) + Users users, + @JsonKey(name: 'chosen_plan', fromJson: parseChosenPlan) ChosenPlanModel? chosenPlan}); @override $ChatRoomSettingsModelCopyWith<$Res> get chatRoomSettings; @override + $UsersCopyWith<$Res> get users; + @override $ChosenPlanModelCopyWith<$Res>? get chosenPlan; } @@ -172,9 +185,9 @@ class __$$ChatRoomModelImplCopyWithImpl<$Res> : chatRoomSettings // ignore: cast_nullable_to_non_nullable as ChatRoomSettingsModel, users: null == users - ? _value._users + ? _value.users : users // ignore: cast_nullable_to_non_nullable - as Map, + as Users, chosenPlan: freezed == chosenPlan ? _value.chosenPlan : chosenPlan // ignore: cast_nullable_to_non_nullable @@ -189,10 +202,9 @@ class _$ChatRoomModelImpl implements _ChatRoomModel { const _$ChatRoomModelImpl( {required this.id, @JsonKey(name: 'chat_room_setting') required this.chatRoomSettings, - required final Map users, - @JsonKey(name: 'chosen_plan', fromJson: _parseChosenPlan) - required this.chosenPlan}) - : _users = users; + required this.users, + @JsonKey(name: 'chosen_plan', fromJson: parseChosenPlan) + required this.chosenPlan}); factory _$ChatRoomModelImpl.fromJson(Map json) => _$$ChatRoomModelImplFromJson(json); @@ -202,16 +214,10 @@ class _$ChatRoomModelImpl implements _ChatRoomModel { @override @JsonKey(name: 'chat_room_setting') final ChatRoomSettingsModel chatRoomSettings; - final Map _users; @override - Map get users { - if (_users is EqualUnmodifiableMapView) return _users; - // ignore: implicit_dynamic_type - return EqualUnmodifiableMapView(_users); - } - + final Users users; @override - @JsonKey(name: 'chosen_plan', fromJson: _parseChosenPlan) + @JsonKey(name: 'chosen_plan', fromJson: parseChosenPlan) final ChosenPlanModel? chosenPlan; @override @@ -227,15 +233,15 @@ class _$ChatRoomModelImpl implements _ChatRoomModel { (identical(other.id, id) || other.id == id) && (identical(other.chatRoomSettings, chatRoomSettings) || other.chatRoomSettings == chatRoomSettings) && - const DeepCollectionEquality().equals(other._users, _users) && + (identical(other.users, users) || other.users == users) && (identical(other.chosenPlan, chosenPlan) || other.chosenPlan == chosenPlan)); } @JsonKey(includeFromJson: false, includeToJson: false) @override - int get hashCode => Object.hash(runtimeType, id, chatRoomSettings, - const DeepCollectionEquality().hash(_users), chosenPlan); + int get hashCode => + Object.hash(runtimeType, id, chatRoomSettings, users, chosenPlan); /// Create a copy of ChatRoomModel /// with the given fields replaced by the non-null parameter values. @@ -258,8 +264,8 @@ abstract class _ChatRoomModel implements ChatRoomModel { {required final String id, @JsonKey(name: 'chat_room_setting') required final ChatRoomSettingsModel chatRoomSettings, - required final Map users, - @JsonKey(name: 'chosen_plan', fromJson: _parseChosenPlan) + required final Users users, + @JsonKey(name: 'chosen_plan', fromJson: parseChosenPlan) required final ChosenPlanModel? chosenPlan}) = _$ChatRoomModelImpl; factory _ChatRoomModel.fromJson(Map json) = @@ -271,9 +277,9 @@ abstract class _ChatRoomModel implements ChatRoomModel { @JsonKey(name: 'chat_room_setting') ChatRoomSettingsModel get chatRoomSettings; @override - Map get users; + Users get users; @override - @JsonKey(name: 'chosen_plan', fromJson: _parseChosenPlan) + @JsonKey(name: 'chosen_plan', fromJson: parseChosenPlan) ChosenPlanModel? get chosenPlan; /// Create a copy of ChatRoomModel @@ -283,3 +289,208 @@ abstract class _ChatRoomModel implements ChatRoomModel { _$$ChatRoomModelImplCopyWith<_$ChatRoomModelImpl> get copyWith => throw _privateConstructorUsedError; } + +Users _$UsersFromJson(Map json) { + return _Users.fromJson(json); +} + +/// @nodoc +mixin _$Users { + @JsonKey(name: 'from_chat_user') + ChatUserModel get sender => throw _privateConstructorUsedError; + @JsonKey(name: 'to_chat_user') + ChatUserModel get receiver => throw _privateConstructorUsedError; + + /// Serializes this Users to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of Users + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $UsersCopyWith get copyWith => throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $UsersCopyWith<$Res> { + factory $UsersCopyWith(Users value, $Res Function(Users) then) = + _$UsersCopyWithImpl<$Res, Users>; + @useResult + $Res call( + {@JsonKey(name: 'from_chat_user') ChatUserModel sender, + @JsonKey(name: 'to_chat_user') ChatUserModel receiver}); + + $ChatUserModelCopyWith<$Res> get sender; + $ChatUserModelCopyWith<$Res> get receiver; +} + +/// @nodoc +class _$UsersCopyWithImpl<$Res, $Val extends Users> + implements $UsersCopyWith<$Res> { + _$UsersCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of Users + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? sender = null, + Object? receiver = null, + }) { + return _then(_value.copyWith( + sender: null == sender + ? _value.sender + : sender // ignore: cast_nullable_to_non_nullable + as ChatUserModel, + receiver: null == receiver + ? _value.receiver + : receiver // ignore: cast_nullable_to_non_nullable + as ChatUserModel, + ) as $Val); + } + + /// Create a copy of Users + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $ChatUserModelCopyWith<$Res> get sender { + return $ChatUserModelCopyWith<$Res>(_value.sender, (value) { + return _then(_value.copyWith(sender: value) as $Val); + }); + } + + /// Create a copy of Users + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $ChatUserModelCopyWith<$Res> get receiver { + return $ChatUserModelCopyWith<$Res>(_value.receiver, (value) { + return _then(_value.copyWith(receiver: value) as $Val); + }); + } +} + +/// @nodoc +abstract class _$$UsersImplCopyWith<$Res> implements $UsersCopyWith<$Res> { + factory _$$UsersImplCopyWith( + _$UsersImpl value, $Res Function(_$UsersImpl) then) = + __$$UsersImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {@JsonKey(name: 'from_chat_user') ChatUserModel sender, + @JsonKey(name: 'to_chat_user') ChatUserModel receiver}); + + @override + $ChatUserModelCopyWith<$Res> get sender; + @override + $ChatUserModelCopyWith<$Res> get receiver; +} + +/// @nodoc +class __$$UsersImplCopyWithImpl<$Res> + extends _$UsersCopyWithImpl<$Res, _$UsersImpl> + implements _$$UsersImplCopyWith<$Res> { + __$$UsersImplCopyWithImpl( + _$UsersImpl _value, $Res Function(_$UsersImpl) _then) + : super(_value, _then); + + /// Create a copy of Users + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? sender = null, + Object? receiver = null, + }) { + return _then(_$UsersImpl( + sender: null == sender + ? _value.sender + : sender // ignore: cast_nullable_to_non_nullable + as ChatUserModel, + receiver: null == receiver + ? _value.receiver + : receiver // ignore: cast_nullable_to_non_nullable + as ChatUserModel, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$UsersImpl implements _Users { + const _$UsersImpl( + {@JsonKey(name: 'from_chat_user') required this.sender, + @JsonKey(name: 'to_chat_user') required this.receiver}); + + factory _$UsersImpl.fromJson(Map json) => + _$$UsersImplFromJson(json); + + @override + @JsonKey(name: 'from_chat_user') + final ChatUserModel sender; + @override + @JsonKey(name: 'to_chat_user') + final ChatUserModel receiver; + + @override + String toString() { + return 'Users(sender: $sender, receiver: $receiver)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$UsersImpl && + (identical(other.sender, sender) || other.sender == sender) && + (identical(other.receiver, receiver) || + other.receiver == receiver)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash(runtimeType, sender, receiver); + + /// Create a copy of Users + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$UsersImplCopyWith<_$UsersImpl> get copyWith => + __$$UsersImplCopyWithImpl<_$UsersImpl>(this, _$identity); + + @override + Map toJson() { + return _$$UsersImplToJson( + this, + ); + } +} + +abstract class _Users implements Users { + const factory _Users( + {@JsonKey(name: 'from_chat_user') required final ChatUserModel sender, + @JsonKey(name: 'to_chat_user') + required final ChatUserModel receiver}) = _$UsersImpl; + + factory _Users.fromJson(Map json) = _$UsersImpl.fromJson; + + @override + @JsonKey(name: 'from_chat_user') + ChatUserModel get sender; + @override + @JsonKey(name: 'to_chat_user') + ChatUserModel get receiver; + + /// Create a copy of Users + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$UsersImplCopyWith<_$UsersImpl> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/lib/features/chat/models/chat_room_model.g.dart b/lib/features/chat/models/chat_room_model.g.dart index 834f2d0e..fb9e6257 100644 --- a/lib/features/chat/models/chat_room_model.g.dart +++ b/lib/features/chat/models/chat_room_model.g.dart @@ -11,11 +11,8 @@ _$ChatRoomModelImpl _$$ChatRoomModelImplFromJson(Map json) => id: json['id'] as String, chatRoomSettings: ChatRoomSettingsModel.fromJson( json['chat_room_setting'] as Map), - users: (json['users'] as Map).map( - (k, e) => - MapEntry(k, ChatUserModel.fromJson(e as Map)), - ), - chosenPlan: _parseChosenPlan(json['chosen_plan']), + users: Users.fromJson(json['users'] as Map), + chosenPlan: parseChosenPlan(json['chosen_plan']), ); Map _$$ChatRoomModelImplToJson(_$ChatRoomModelImpl instance) => @@ -25,3 +22,16 @@ Map _$$ChatRoomModelImplToJson(_$ChatRoomModelImpl instance) => 'users': instance.users, 'chosen_plan': instance.chosenPlan, }; + +_$UsersImpl _$$UsersImplFromJson(Map json) => _$UsersImpl( + sender: ChatUserModel.fromJson( + json['from_chat_user'] as Map), + receiver: + ChatUserModel.fromJson(json['to_chat_user'] as Map), + ); + +Map _$$UsersImplToJson(_$UsersImpl instance) => + { + 'from_chat_user': instance.sender, + 'to_chat_user': instance.receiver, + }; diff --git a/lib/features/chat/models/chat_room_pagination_model.dart b/lib/features/chat/models/chat_room_pagination_model.dart index 6d44a685..2d7e875d 100644 --- a/lib/features/chat/models/chat_room_pagination_model.dart +++ b/lib/features/chat/models/chat_room_pagination_model.dart @@ -1,4 +1,5 @@ import 'package:eatvio_app/features/chat/models/chat_message_model.dart'; +import 'package:eatvio_app/features/plans/models/chosen_plan_model.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; part 'chat_room_pagination_model.freezed.dart'; @@ -33,6 +34,7 @@ class ChatRoom with _$ChatRoom { @JsonKey(name: "last_message", fromJson: parseLastMessage) required ChatMessageModel? lastMessage, @JsonKey(name: "users") required Users users, @JsonKey(name: "unread_messages_count") required int unreadMessagesCount, + @JsonKey(name: 'chosen_plan', fromJson: parseChosenPlan) required ChosenPlanModel? chosenPlan, }) = _ChatRoom; factory ChatRoom.fromJson(Map json) => _$ChatRoomFromJson(json); diff --git a/lib/features/chat/models/chat_room_pagination_model.freezed.dart b/lib/features/chat/models/chat_room_pagination_model.freezed.dart index 42d8ef5f..54e56ee3 100644 --- a/lib/features/chat/models/chat_room_pagination_model.freezed.dart +++ b/lib/features/chat/models/chat_room_pagination_model.freezed.dart @@ -445,6 +445,8 @@ mixin _$ChatRoom { Users get users => throw _privateConstructorUsedError; @JsonKey(name: "unread_messages_count") int get unreadMessagesCount => throw _privateConstructorUsedError; + @JsonKey(name: 'chosen_plan', fromJson: parseChosenPlan) + ChosenPlanModel? get chosenPlan => throw _privateConstructorUsedError; /// Serializes this ChatRoom to a JSON map. Map toJson() => throw _privateConstructorUsedError; @@ -467,10 +469,13 @@ abstract class $ChatRoomCopyWith<$Res> { @JsonKey(name: "last_message", fromJson: parseLastMessage) ChatMessageModel? lastMessage, @JsonKey(name: "users") Users users, - @JsonKey(name: "unread_messages_count") int unreadMessagesCount}); + @JsonKey(name: "unread_messages_count") int unreadMessagesCount, + @JsonKey(name: 'chosen_plan', fromJson: parseChosenPlan) + ChosenPlanModel? chosenPlan}); $ChatMessageModelCopyWith<$Res>? get lastMessage; $UsersCopyWith<$Res> get users; + $ChosenPlanModelCopyWith<$Res>? get chosenPlan; } /// @nodoc @@ -493,6 +498,7 @@ class _$ChatRoomCopyWithImpl<$Res, $Val extends ChatRoom> Object? lastMessage = freezed, Object? users = null, Object? unreadMessagesCount = null, + Object? chosenPlan = freezed, }) { return _then(_value.copyWith( id: null == id @@ -515,6 +521,10 @@ class _$ChatRoomCopyWithImpl<$Res, $Val extends ChatRoom> ? _value.unreadMessagesCount : unreadMessagesCount // ignore: cast_nullable_to_non_nullable as int, + chosenPlan: freezed == chosenPlan + ? _value.chosenPlan + : chosenPlan // ignore: cast_nullable_to_non_nullable + as ChosenPlanModel?, ) as $Val); } @@ -541,6 +551,20 @@ class _$ChatRoomCopyWithImpl<$Res, $Val extends ChatRoom> return _then(_value.copyWith(users: value) as $Val); }); } + + /// Create a copy of ChatRoom + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $ChosenPlanModelCopyWith<$Res>? get chosenPlan { + if (_value.chosenPlan == null) { + return null; + } + + return $ChosenPlanModelCopyWith<$Res>(_value.chosenPlan!, (value) { + return _then(_value.copyWith(chosenPlan: value) as $Val); + }); + } } /// @nodoc @@ -557,12 +581,16 @@ abstract class _$$ChatRoomImplCopyWith<$Res> @JsonKey(name: "last_message", fromJson: parseLastMessage) ChatMessageModel? lastMessage, @JsonKey(name: "users") Users users, - @JsonKey(name: "unread_messages_count") int unreadMessagesCount}); + @JsonKey(name: "unread_messages_count") int unreadMessagesCount, + @JsonKey(name: 'chosen_plan', fromJson: parseChosenPlan) + ChosenPlanModel? chosenPlan}); @override $ChatMessageModelCopyWith<$Res>? get lastMessage; @override $UsersCopyWith<$Res> get users; + @override + $ChosenPlanModelCopyWith<$Res>? get chosenPlan; } /// @nodoc @@ -583,6 +611,7 @@ class __$$ChatRoomImplCopyWithImpl<$Res> Object? lastMessage = freezed, Object? users = null, Object? unreadMessagesCount = null, + Object? chosenPlan = freezed, }) { return _then(_$ChatRoomImpl( id: null == id @@ -605,6 +634,10 @@ class __$$ChatRoomImplCopyWithImpl<$Res> ? _value.unreadMessagesCount : unreadMessagesCount // ignore: cast_nullable_to_non_nullable as int, + chosenPlan: freezed == chosenPlan + ? _value.chosenPlan + : chosenPlan // ignore: cast_nullable_to_non_nullable + as ChosenPlanModel?, )); } } @@ -618,8 +651,9 @@ class _$ChatRoomImpl implements _ChatRoom { @JsonKey(name: "last_message", fromJson: parseLastMessage) required this.lastMessage, @JsonKey(name: "users") required this.users, - @JsonKey(name: "unread_messages_count") - required this.unreadMessagesCount}); + @JsonKey(name: "unread_messages_count") required this.unreadMessagesCount, + @JsonKey(name: 'chosen_plan', fromJson: parseChosenPlan) + required this.chosenPlan}); factory _$ChatRoomImpl.fromJson(Map json) => _$$ChatRoomImplFromJson(json); @@ -639,10 +673,13 @@ class _$ChatRoomImpl implements _ChatRoom { @override @JsonKey(name: "unread_messages_count") final int unreadMessagesCount; + @override + @JsonKey(name: 'chosen_plan', fromJson: parseChosenPlan) + final ChosenPlanModel? chosenPlan; @override String toString() { - return 'ChatRoom(id: $id, roomName: $roomName, lastMessage: $lastMessage, users: $users, unreadMessagesCount: $unreadMessagesCount)'; + return 'ChatRoom(id: $id, roomName: $roomName, lastMessage: $lastMessage, users: $users, unreadMessagesCount: $unreadMessagesCount, chosenPlan: $chosenPlan)'; } @override @@ -657,13 +694,15 @@ class _$ChatRoomImpl implements _ChatRoom { other.lastMessage == lastMessage) && (identical(other.users, users) || other.users == users) && (identical(other.unreadMessagesCount, unreadMessagesCount) || - other.unreadMessagesCount == unreadMessagesCount)); + other.unreadMessagesCount == unreadMessagesCount) && + (identical(other.chosenPlan, chosenPlan) || + other.chosenPlan == chosenPlan)); } @JsonKey(includeFromJson: false, includeToJson: false) @override - int get hashCode => Object.hash( - runtimeType, id, roomName, lastMessage, users, unreadMessagesCount); + int get hashCode => Object.hash(runtimeType, id, roomName, lastMessage, users, + unreadMessagesCount, chosenPlan); /// Create a copy of ChatRoom /// with the given fields replaced by the non-null parameter values. @@ -689,7 +728,9 @@ abstract class _ChatRoom implements ChatRoom { required final ChatMessageModel? lastMessage, @JsonKey(name: "users") required final Users users, @JsonKey(name: "unread_messages_count") - required final int unreadMessagesCount}) = _$ChatRoomImpl; + required final int unreadMessagesCount, + @JsonKey(name: 'chosen_plan', fromJson: parseChosenPlan) + required final ChosenPlanModel? chosenPlan}) = _$ChatRoomImpl; factory _ChatRoom.fromJson(Map json) = _$ChatRoomImpl.fromJson; @@ -709,6 +750,9 @@ abstract class _ChatRoom implements ChatRoom { @override @JsonKey(name: "unread_messages_count") int get unreadMessagesCount; + @override + @JsonKey(name: 'chosen_plan', fromJson: parseChosenPlan) + ChosenPlanModel? get chosenPlan; /// Create a copy of ChatRoom /// with the given fields replaced by the non-null parameter values. diff --git a/lib/features/chat/models/chat_room_pagination_model.g.dart b/lib/features/chat/models/chat_room_pagination_model.g.dart index 3b9ac87b..d6f6e057 100644 --- a/lib/features/chat/models/chat_room_pagination_model.g.dart +++ b/lib/features/chat/models/chat_room_pagination_model.g.dart @@ -43,6 +43,7 @@ _$ChatRoomImpl _$$ChatRoomImplFromJson(Map json) => lastMessage: parseLastMessage(json['last_message']), users: Users.fromJson(json['users'] as Map), unreadMessagesCount: (json['unread_messages_count'] as num).toInt(), + chosenPlan: parseChosenPlan(json['chosen_plan']), ); Map _$$ChatRoomImplToJson(_$ChatRoomImpl instance) => @@ -52,6 +53,7 @@ Map _$$ChatRoomImplToJson(_$ChatRoomImpl instance) => 'last_message': instance.lastMessage, 'users': instance.users, 'unread_messages_count': instance.unreadMessagesCount, + 'chosen_plan': instance.chosenPlan, }; _$UsersImpl _$$UsersImplFromJson(Map json) => _$UsersImpl( diff --git a/lib/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart b/lib/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart index 3ba4422c..1e456fc6 100644 --- a/lib/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart +++ b/lib/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart @@ -86,11 +86,12 @@ class ChatRoomCubit extends Cubit { } } - Future updateChatRoom(String chatId) async{ + Future cancelChosenPlan({required String chatId, required int planId}) async { try { - final chatRoom = await chatRepository.getChatRoom(chatId); + await chatRepository.cancelChosenPlan(id: planId); + final chatRoom = await chatRepository.getChatRoom(chatId); emit( - (state as ChatRoomStateLoaded).copyWith(chatRoom: chatRoom), + (state as ChatRoomStateLoaded).copyWith(chatRoom: chatRoom), ); } catch (e) { emit(ChatRoomState.error(errorMessage: 'Ошибка получеия данных')); @@ -104,7 +105,7 @@ class ChatRoomCubit extends Cubit { if (client == null) return; await wsManager.initPrivateDirectChatChannel(chatId); wsManager.subscribeDirectChatChannel(); - wsManager.directChatStream?.listen((event) { + messagesSubscription = wsManager.directChatStream?.listen((event) { AudioPlayer().play((AssetSource('audio/recive_message.wav'))); final message = ChatMessageModel.fromJson(jsonDecode(event.data)['message']); List messagesList = [ @@ -122,7 +123,7 @@ class ChatRoomCubit extends Cubit { ); }); - wsManager.clientTypingStream?.listen((event) { + typingSubscription = wsManager.clientTypingStream?.listen((event) { emit( ChatRoomState.loaded( chatRoom: (state as ChatRoomStateLoaded).chatRoom, @@ -191,6 +192,8 @@ class ChatRoomCubit extends Cubit { @override Future close() async { wsManager.unsubscribeDirectChatChannel(); + messagesSubscription?.cancel(); + typingSubscription?.cancel(); super.close(); } } diff --git a/lib/features/chat/presentation/pages/chat_screen.dart b/lib/features/chat/presentation/pages/chat_screen.dart index 1d0b8b0c..c39947b0 100644 --- a/lib/features/chat/presentation/pages/chat_screen.dart +++ b/lib/features/chat/presentation/pages/chat_screen.dart @@ -11,9 +11,13 @@ import 'package:eatvio_app/features/chat/presentation/widgets/chat_bubble_widget import 'package:eatvio_app/core/locator_service.dart'; import 'package:eatvio_app/core/theme/custom_text_style.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; +import 'package:eatvio_app/features/chat/presentation/widgets/order_card.dart'; +import 'package:eatvio_app/features/plans/enums/chosen_plan_state_enum.dart'; +import 'package:eatvio_app/generated/l10n.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/svg.dart'; import 'package:intl/intl.dart'; import 'package:visibility_detector/visibility_detector.dart'; @@ -34,6 +38,7 @@ class _ChatScreenState extends State { final ChatRoomCubit chatRoomCubit = sl(); final List<({int id, int index})> unreadMessagesIds = []; final List<({int id, int index})> unreadMessagesIdsCopy = []; + final showableChatBadgeStates = ChosenPlanStateEnum.getShowableChatBadgeStates(); @override void initState() { @@ -51,6 +56,7 @@ class _ChatScreenState extends State { @override void dispose() { scrollController.dispose(); + chatRoomCubit.close(); super.dispose(); } @@ -78,6 +84,9 @@ class _ChatScreenState extends State { } _buildChat(BuildContext context, ChatRoomStateLoaded state) { + final chosenPlan = state.chatRoom.chosenPlan; + final amIConsultant = chosenPlan?.consultantId == state.chatRoom.users.sender.id; + final showAboutOrderButton = showableChatBadgeStates.contains(chosenPlan?.chosenPlanState); return Scaffold( resizeToAvoidBottomInset: true, appBar: AppBar( @@ -86,12 +95,12 @@ class _ChatScreenState extends State { centerTitle: false, title: Row( children: [ - if (state.chatRoom.users['to_chat_user']!.profilePhotoUrl != null) + if (state.chatRoom.users.receiver.profilePhotoUrl != null) CircleAvatar( radius: 20, - foregroundImage: NetworkImage(state.chatRoom.users['to_chat_user']!.profilePhotoUrl!), + foregroundImage: NetworkImage(state.chatRoom.users.receiver.profilePhotoUrl!), ), - if (state.chatRoom.users['to_chat_user']!.profilePhotoUrl == null) + if (state.chatRoom.users.receiver.profilePhotoUrl == null) Container( width: 40, height: 40, @@ -101,7 +110,7 @@ class _ChatScreenState extends State { shape: BoxShape.circle, ), child: Text( - state.chatRoom.users['to_chat_user']!.name.split(' ').first[0] + state.chatRoom.users['to_chat_user']!.name.split(' ')[1][0], + state.chatRoom.users.receiver.name.split(' ').first[0] + state.chatRoom.users.receiver.name.split(' ')[1][0], style: TextStyle( color: Color(0xFF7F9CF5), fontWeight: FontWeight.w400, @@ -114,7 +123,7 @@ class _ChatScreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - state.chatRoom.users['to_chat_user']!.name, + state.chatRoom.users.receiver.name, style: CustomTextStyles.titleSmallBold.copyWith( color: PrimaryColors().black, ), @@ -136,28 +145,38 @@ class _ChatScreenState extends State { ), ), body: SafeArea( - child: Column( - mainAxisSize: MainAxisSize.min, + child: Stack( children: [ - Expanded( - child: Container( - color: appTheme.whiteA700, - width: double.maxFinite, - child: CustomScrollView( - physics: BouncingScrollPhysics(), - controller: scrollController, - reverse: true, - slivers: [ - SliverPadding( - padding: EdgeInsets.symmetric(vertical: 16), - sliver: SliverList( - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index < state.chatMessages.length) { + Column( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded( + child: Container( + color: appTheme.whiteA700, + width: double.maxFinite, + child: SingleChildScrollView( + physics: BouncingScrollPhysics(), + controller: scrollController, + reverse: true, + child: Column( + children: [ + SizedBox(height: 16), + ListView.builder( + physics: NeverScrollableScrollPhysics(), + reverse: true, + shrinkWrap: true, + itemBuilder: (context, index) { + if (index == state.chatMessages.length) { + return Padding( + padding: const EdgeInsets.all(8), + child: const Loader(), + ); + } + if ((index + 1 != state.chatMessages.length && state.chatMessages[index].updatedAt.day != state.chatMessages[index + 1].updatedAt.day) || index + 1 == state.chatMessages.length) { - final isCurrentUserAuthor = state.chatRoom.users['to_chat_user']!.id != state.chatMessages[index].authorId; + final isCurrentUserAuthor = state.chatRoom.users.receiver.id != state.chatMessages[index].authorId; return Column( children: [ _messageDate(state.chatMessages[index].updatedAt), @@ -191,7 +210,7 @@ class _ChatScreenState extends State { ], ); } - final isCurrentUserAuthor = state.chatRoom.users['to_chat_user']!.id != state.chatMessages[index].authorId; + final isCurrentUserAuthor = state.chatRoom.users.receiver.id != state.chatMessages[index].authorId; return VisibilityDetector( key: Key(state.chatMessages[index].id.toString()), onVisibilityChanged: (VisibilityInfo info) { @@ -217,157 +236,238 @@ class _ChatScreenState extends State { mediaData: state.chatMessages[index].mediaData ?? [], ), ); - } else { - return Padding( - padding: const EdgeInsets.all(8), - child: const Loader(), - ); - } - }, - childCount: state.chatMessages.length + (state.isLoading ? 1 : 0), - ), + }, + itemCount: state.chatMessages.length + (state.isLoading ? 1 : 0), + ), + SizedBox(height: 16), + if (chosenPlan != null) + OrderCard( + plan: chosenPlan.plan, + isUserView: !amIConsultant, + optionType: chosenPlan.optionType, + onCancel: () async { + await context.read().cancelChosenPlan(chatId: state.chatRoom.id, planId: chosenPlan.id); + }, + ), + // switch (chosenPlan.chosenPlanState) { + // // TODO: Handle this case. + // ChosenPlanStateEnum.stateInited => throw UnimplementedError(), + // // TODO: Handle this case. + // ChosenPlanStateEnum.stateStartDateHasBeenSet => throw UnimplementedError(), + // // TODO: Handle this case. + // ChosenPlanStateEnum.stateInCoordination => throw UnimplementedError(), + // // TODO: Handle this case. + // ChosenPlanStateEnum.stateStarted => throw UnimplementedError(), + // // TODO: Handle this case. + // ChosenPlanStateEnum.stateInProgress => throw UnimplementedError(), + // // TODO: Handle this case. + // ChosenPlanStateEnum.statePendingPayment => throw UnimplementedError(), + // // TODO: Handle this case. + // ChosenPlanStateEnum.stateConfirmedByConsultant => throw UnimplementedError(), + // // TODO: Handle this case. + // ChosenPlanStateEnum.statePaid => throw UnimplementedError(), + // // TODO: Handle this case. + // ChosenPlanStateEnum.stateCanceledByTheInitiator => throw UnimplementedError(), + // // TODO: Handle this case. + // ChosenPlanStateEnum.stateLastDayStarted => throw UnimplementedError(), + // // TODO: Handle this case. + // ChosenPlanStateEnum.stateLastDayFinished => throw UnimplementedError(), + // // TODO: Handle this case. + // ChosenPlanStateEnum.stateComplained => throw UnimplementedError(), + // // TODO: Handle this case. + // ChosenPlanStateEnum.stateDone => throw UnimplementedError(), + // // TODO: Handle this case. + // ChosenPlanStateEnum.stateChargeWasCollected => throw UnimplementedError(), + // }, + ], ), ), - ], + ), + ), + Container( + padding: EdgeInsets.symmetric(vertical: 8), + child: Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + SizedBox(width: 8), + InkWell( + onTap: () async { + FilePickerResult? result = await FilePicker.platform.pickFiles( + allowMultiple: true, + type: FileType.custom, + allowedExtensions: [ + 'pdf', + 'doc', + 'docx', + 'json', + 'ppt', + 'pptx', + 'rtf', + 'txt', + 'xls', + 'xlsx', + 'csv', + 'jpeg', + 'jpg', + 'png', + 'gif', + 'svg', + 'xml', + 'webp', + ], + ); + + if (result != null) { + List files = result.paths.map((path) => File(path!)).toList(); + await chatRoomCubit.sendMessage( + chatId: widget.chatId, + files: files, + ); + } else { + // User canceled the picker + } + }, + customBorder: CircleBorder(), + child: Ink( + height: 40, + width: 40, + child: Transform.rotate( + angle: pi / 4, + child: Icon( + Icons.attach_file_rounded, + size: 30, + color: Color(0xFF858E99), + ), + ), + ), + ), + SizedBox(width: 8), + Expanded( + child: SizedBox( + height: 40, + child: TextFormField( + expands: true, + controller: textEditingController, + maxLines: null, + minLines: null, + 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: 10), + hintText: 'Сообщение', + hintStyle: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w400, + height: 1, + color: Color(0xFFAEAEB2), + ), + filled: true, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(100), + borderSide: BorderSide( + color: Color(0xFFD1D1D6), + width: 1, + ), + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(100), + borderSide: BorderSide( + color: Color(0xFFD1D1D6), + width: 1, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(100), + borderSide: BorderSide( + color: Color(0xFFD1D1D6), + width: 1, + ), + ), + ), + ), + ), + ), + SizedBox(width: 8), + InkWell( + customBorder: CircleBorder(), + onTap: () { + if (textEditingController.text.isNotEmpty) { + chatRoomCubit.sendMessage( + chatId: widget.chatId, + data: textEditingController.text.trim(), + ); + setState(() { + textEditingController.clear(); + }); + } + }, + child: Ink( + decoration: BoxDecoration( + color: appTheme.blueA400, + shape: BoxShape.circle, + ), + height: 40, + width: 40, + child: Icon( + Icons.arrow_upward_rounded, + size: 24, + color: Colors.white, + ), + ), + ), + SizedBox(width: 8), + ], + ), + ), + ], + ), + if (showAboutOrderButton) + Positioned( + top: 8, + right: 15, + left: 16, + child: GestureDetector( + onTap: () {}, + child: Container( + height: 44, + decoration: BoxDecoration( + color: appTheme.gray50, + borderRadius: BorderRadius.circular(20), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SizedBox.shrink(), + Text( + S.current.more_about_order, + style: TextStyles.textSMedium.copyWith(color: appTheme.black), + ), + Container( + margin: EdgeInsets.only(right: 4), + width: 36, + height: 36, + decoration: BoxDecoration( + color: appTheme.whiteA700, + shape: BoxShape.circle, + ), + child: Center( + child: SvgPicture.asset( + 'assets/icons/right_arrow.svg', + height: 14, + width: 8, + colorFilter: ColorFilter.mode( + appTheme.blueA400, + BlendMode.srcIn, + ), + ), + ), + ), + ], + ), + ), ), ), - ), - Container( - padding: EdgeInsets.symmetric(vertical: 8), - child: Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - SizedBox(width: 8), - InkWell( - onTap: () async { - FilePickerResult? result = await FilePicker.platform.pickFiles( - allowMultiple: true, - type: FileType.custom, - allowedExtensions: [ - 'pdf', - 'doc', - 'docx', - 'json', - 'ppt', - 'pptx', - 'rtf', - 'txt', - 'xls', - 'xlsx', - 'csv', - 'jpeg', - 'jpg', - 'png', - 'gif', - 'svg', - 'xml', - 'webp', - ], - ); - - if (result != null) { - List files = result.paths.map((path) => File(path!)).toList(); - await chatRoomCubit.sendMessage( - chatId: widget.chatId, - files: files, - ); - } else { - // User canceled the picker - } - }, - customBorder: CircleBorder(), - child: Ink( - height: 40, - width: 40, - child: Transform.rotate( - angle: pi / 4, - child: Icon( - Icons.attach_file_rounded, - size: 30, - color: Color(0xFF858E99), - ), - ), - ), - ), - SizedBox(width: 8), - Expanded( - child: SizedBox( - height: 40, - child: TextFormField( - expands: true, - controller: textEditingController, - maxLines: null, - minLines: null, - 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: 10), - hintText: 'Сообщение', - hintStyle: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w400, - height: 1, - color: Color(0xFFAEAEB2), - ), - filled: true, - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(100), - borderSide: BorderSide( - color: Color(0xFFD1D1D6), - width: 1, - ), - ), - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(100), - borderSide: BorderSide( - color: Color(0xFFD1D1D6), - width: 1, - ), - ), - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(100), - borderSide: BorderSide( - color: Color(0xFFD1D1D6), - width: 1, - ), - ), - ), - ), - ), - ), - SizedBox(width: 8), - InkWell( - customBorder: CircleBorder(), - onTap: () { - if (textEditingController.text.isNotEmpty) { - chatRoomCubit.sendMessage( - chatId: widget.chatId, - data: textEditingController.text.trim(), - ); - setState(() { - textEditingController.clear(); - }); - } - }, - child: Ink( - decoration: BoxDecoration( - color: appTheme.blueA400, - shape: BoxShape.circle, - ), - height: 40, - width: 40, - child: Icon( - Icons.arrow_upward_rounded, - size: 24, - color: Colors.white, - ), - ), - ), - SizedBox(width: 8), - ], - ), - ), ], ), ), diff --git a/lib/features/chat/presentation/widgets/order_card.dart b/lib/features/chat/presentation/widgets/order_card.dart index 5f57f362..fdb8180d 100644 --- a/lib/features/chat/presentation/widgets/order_card.dart +++ b/lib/features/chat/presentation/widgets/order_card.dart @@ -1,18 +1,136 @@ +import 'package:eatvio_app/core/const.dart'; +import 'package:eatvio_app/core/theme/custom_text_style.dart'; +import 'package:eatvio_app/core/theme/theme_helper.dart'; +import 'package:eatvio_app/core/utils/localization_utils.dart'; +import 'package:eatvio_app/core/utils/string_extentions.dart'; +import 'package:eatvio_app/core/widgets/item_widget.dart'; +import 'package:eatvio_app/core/widgets/loader.dart'; import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart'; +import 'package:eatvio_app/generated/l10n.dart'; import 'package:flutter/material.dart'; -class OrderCard extends StatelessWidget { +class OrderCard extends StatefulWidget { final PlanModel plan; + final String optionType; final bool isUserView; - const OrderCard({super.key, required this.plan, required this.isUserView}); + final Future Function() onCancel; + const OrderCard({super.key, required this.plan, required this.isUserView, required this.optionType, required this.onCancel}); @override - Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.only(top: 8, bottom: 12, left: 8, right: 8), - child: Column( - children: [ + State createState() => _OrderCardState(); +} +class _OrderCardState extends State { + bool isLoading = false; + @override + Widget build(BuildContext context) { + final optionIndex = int.parse(widget.optionType.characters.last); + final option = switch (optionIndex) { + 1 => widget.plan.packet1Options, + 2 => widget.plan.packet2Options, + 3 => widget.plan.packet3Options, + _ => null, + }; + final s = S.of(context); + return Container( + margin: EdgeInsets.symmetric(horizontal: 16), + padding: EdgeInsets.only(top: 8, bottom: 12, left: 8, right: 8), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: appTheme.gray60004), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 200, + width: double.infinity, + child: Stack( + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(12), + child: Image.network( + baseUrl + '/storage/' + widget.plan.image, + width: double.infinity, + fit: BoxFit.cover, + ), + ), + Positioned( + left: 0, + bottom: 44, + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), + decoration: BoxDecoration( + color: appTheme.blueA400, + borderRadius: BorderRadius.only( + topRight: Radius.circular(12), + bottomRight: Radius.circular(12), + ), + ), + child: Text( + '${widget.plan.duration} ${getDayForm(widget.plan.duration, s).capitalize()}', + style: TextStyles.textSMedium.copyWith(color: appTheme.whiteA700), + ), + ), + ), + Positioned( + left: 0, + bottom: 12, + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), + decoration: BoxDecoration( + color: appTheme.greenA700, + borderRadius: BorderRadius.only( + topRight: Radius.circular(12), + bottomRight: Radius.circular(12), + ), + ), + child: Text( + '${s.from} ${widget.plan.minPriceOfOptions.toStringAsFixed(0)}₽', + style: TextStyles.textSMedium.copyWith(color: appTheme.whiteA700), + ), + ), + ), + ], + ), + ), + SizedBox(height: 12), + Text( + '${widget.plan.name}', + style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black), + ), + SizedBox(height: 12), + Text( + '${s.option}: ${option?.short ?? ''}', + style: TextStyles.textMSemibold.copyWith(color: appTheme.black), + ), + SizedBox(height: 8), + if (option != null) + ...option.items + .map( + (element) => Padding( + padding: const EdgeInsets.only(bottom: 4), + child: ItemWidget( + reversed: true, + iconSize: 12, + text: element, + ), + ), + ) + .toList(), + if (widget.isUserView) ...[ + SizedBox(height: 8), + isLoading + ? Loader() + : GestureDetector( + onTap: () async { + setState(() => isLoading = true); + await widget.onCancel(); + setState(() => isLoading = false); + }, + child: Text( + '${s.cancel_order}', + style: TextStyles.textSMedium.copyWith(color: appTheme.strongRed), + ), + ), + ], ], ), ); diff --git a/lib/features/chat/repositories/chat_repository.dart b/lib/features/chat/repositories/chat_repository.dart index bdc537f8..c6b1bf8d 100644 --- a/lib/features/chat/repositories/chat_repository.dart +++ b/lib/features/chat/repositories/chat_repository.dart @@ -93,4 +93,14 @@ class ChatRepository { rethrow; } } + + Future cancelChosenPlan({ + required int id, + }) async { + try { + await chatService.cancelChosenPlan(id: id); + } catch (e) { + rethrow; + } + } } diff --git a/lib/features/chat/services/chat_service.dart b/lib/features/chat/services/chat_service.dart index 65910a34..3eae96fd 100644 --- a/lib/features/chat/services/chat_service.dart +++ b/lib/features/chat/services/chat_service.dart @@ -12,7 +12,7 @@ abstract class ChatService { @GET('/api/chat/index') Future getChatRooms({ - @Query('page') required int page, + @Query('page') required int page, @Query('find') String? query, }); @@ -41,5 +41,13 @@ abstract class ChatService { }); @POST('/api/chat/{id}/messages/markAsRead') - Future markMessagesAsRead({@Path() required String id, @Body() required Map> body}); + Future markMessagesAsRead({ + @Path() required String id, + @Body() required Map> body, + }); + + @POST('/api/chosen_plans/{id}/cancel') + Future cancelChosenPlan({ + @Path() required int id, + }); } diff --git a/lib/features/chat/services/chat_service.g.dart b/lib/features/chat/services/chat_service.g.dart index 69a70741..849f0ac3 100644 --- a/lib/features/chat/services/chat_service.g.dart +++ b/lib/features/chat/services/chat_service.g.dart @@ -193,6 +193,25 @@ class _ChatService implements ChatService { await _dio.fetch(_options); } + @override + Future cancelChosenPlan({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/chosen_plans/${id}/cancel', + queryParameters: queryParameters, + data: _data, + ) + .copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)), + ); + await _dio.fetch(_options); + } + RequestOptions _setStreamType(RequestOptions requestOptions) { if (T != dynamic && !(requestOptions.responseType == ResponseType.bytes || diff --git a/lib/features/menu/presentation/pages/menu_screen.dart b/lib/features/menu/presentation/pages/menu_screen.dart index 73a3a358..8fbb2dbb 100644 --- a/lib/features/menu/presentation/pages/menu_screen.dart +++ b/lib/features/menu/presentation/pages/menu_screen.dart @@ -4,12 +4,14 @@ import 'package:eatvio_app/core/token_storage.dart'; import 'package:eatvio_app/core/utils/image_constant.dart'; import 'package:eatvio_app/core/locator_service.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; +import 'package:eatvio_app/features/chat/presentation/bloc/chats_cubit/chats_cubit.dart'; import 'package:eatvio_app/features/dev_tools/presentation/dev_tools_screen.dart'; import 'package:eatvio_app/features/my_diets/presentation/my_diets_screen.dart'; import 'package:eatvio_app/features/my_plans/presentation/my_plans_screen.dart'; import 'package:eatvio_app/features/profile/models/profile_model.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:go_router/go_router.dart'; @@ -155,7 +157,7 @@ class MenuScreen extends StatelessWidget { ); } catch (e) { } finally { - await TokenStorage.removeTokenInStorage(); + await TokenStorage.removeTokenInStorage(); GoRouter.of(context).go('/auth-screen', extra: true); } }, diff --git a/lib/features/plans/models/chosen_plan_model.dart b/lib/features/plans/models/chosen_plan_model.dart index f42d6d80..670e6380 100644 --- a/lib/features/plans/models/chosen_plan_model.dart +++ b/lib/features/plans/models/chosen_plan_model.dart @@ -1,3 +1,4 @@ +import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart'; import 'package:eatvio_app/features/plans/enums/chosen_plan_state_enum.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -13,8 +14,16 @@ class ChosenPlanModel with _$ChosenPlanModel { @JsonKey(name: 'start_date') required DateTime startDate, @JsonKey(name: 'last_state') required ChosenPlanStateEnum chosenPlanState, @JsonKey(name: 'chat_id') required String chatId, - + @JsonKey(name: 'consultant_id') required int consultantId, + @JsonKey(name: 'plan') required PlanModel plan, }) = _ChosenPlanModel; factory ChosenPlanModel.fromJson(Map json) => _$ChosenPlanModelFromJson(json); +} + +ChosenPlanModel? parseChosenPlan(json) { + if (json is Map) { + return ChosenPlanModel.fromJson(json); + } + return null; } \ No newline at end of file diff --git a/lib/features/plans/models/chosen_plan_model.freezed.dart b/lib/features/plans/models/chosen_plan_model.freezed.dart index 3c7d7325..859c9ad6 100644 --- a/lib/features/plans/models/chosen_plan_model.freezed.dart +++ b/lib/features/plans/models/chosen_plan_model.freezed.dart @@ -30,6 +30,10 @@ mixin _$ChosenPlanModel { ChosenPlanStateEnum get chosenPlanState => throw _privateConstructorUsedError; @JsonKey(name: 'chat_id') String get chatId => throw _privateConstructorUsedError; + @JsonKey(name: 'consultant_id') + int get consultantId => throw _privateConstructorUsedError; + @JsonKey(name: 'plan') + PlanModel get plan => throw _privateConstructorUsedError; /// Serializes this ChosenPlanModel to a JSON map. Map toJson() => throw _privateConstructorUsedError; @@ -52,7 +56,11 @@ abstract class $ChosenPlanModelCopyWith<$Res> { @JsonKey(name: 'option_type') String optionType, @JsonKey(name: 'start_date') DateTime startDate, @JsonKey(name: 'last_state') ChosenPlanStateEnum chosenPlanState, - @JsonKey(name: 'chat_id') String chatId}); + @JsonKey(name: 'chat_id') String chatId, + @JsonKey(name: 'consultant_id') int consultantId, + @JsonKey(name: 'plan') PlanModel plan}); + + $PlanModelCopyWith<$Res> get plan; } /// @nodoc @@ -75,6 +83,8 @@ class _$ChosenPlanModelCopyWithImpl<$Res, $Val extends ChosenPlanModel> Object? startDate = null, Object? chosenPlanState = null, Object? chatId = null, + Object? consultantId = null, + Object? plan = null, }) { return _then(_value.copyWith( id: null == id @@ -97,8 +107,26 @@ class _$ChosenPlanModelCopyWithImpl<$Res, $Val extends ChosenPlanModel> ? _value.chatId : chatId // ignore: cast_nullable_to_non_nullable as String, + consultantId: null == consultantId + ? _value.consultantId + : consultantId // ignore: cast_nullable_to_non_nullable + as int, + plan: null == plan + ? _value.plan + : plan // ignore: cast_nullable_to_non_nullable + as PlanModel, ) as $Val); } + + /// Create a copy of ChosenPlanModel + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $PlanModelCopyWith<$Res> get plan { + return $PlanModelCopyWith<$Res>(_value.plan, (value) { + return _then(_value.copyWith(plan: value) as $Val); + }); + } } /// @nodoc @@ -114,7 +142,12 @@ abstract class _$$ChosenPlanModelImplCopyWith<$Res> @JsonKey(name: 'option_type') String optionType, @JsonKey(name: 'start_date') DateTime startDate, @JsonKey(name: 'last_state') ChosenPlanStateEnum chosenPlanState, - @JsonKey(name: 'chat_id') String chatId}); + @JsonKey(name: 'chat_id') String chatId, + @JsonKey(name: 'consultant_id') int consultantId, + @JsonKey(name: 'plan') PlanModel plan}); + + @override + $PlanModelCopyWith<$Res> get plan; } /// @nodoc @@ -135,6 +168,8 @@ class __$$ChosenPlanModelImplCopyWithImpl<$Res> Object? startDate = null, Object? chosenPlanState = null, Object? chatId = null, + Object? consultantId = null, + Object? plan = null, }) { return _then(_$ChosenPlanModelImpl( id: null == id @@ -157,6 +192,14 @@ class __$$ChosenPlanModelImplCopyWithImpl<$Res> ? _value.chatId : chatId // ignore: cast_nullable_to_non_nullable as String, + consultantId: null == consultantId + ? _value.consultantId + : consultantId // ignore: cast_nullable_to_non_nullable + as int, + plan: null == plan + ? _value.plan + : plan // ignore: cast_nullable_to_non_nullable + as PlanModel, )); } } @@ -169,7 +212,9 @@ class _$ChosenPlanModelImpl implements _ChosenPlanModel { @JsonKey(name: 'option_type') required this.optionType, @JsonKey(name: 'start_date') required this.startDate, @JsonKey(name: 'last_state') required this.chosenPlanState, - @JsonKey(name: 'chat_id') required this.chatId}); + @JsonKey(name: 'chat_id') required this.chatId, + @JsonKey(name: 'consultant_id') required this.consultantId, + @JsonKey(name: 'plan') required this.plan}); factory _$ChosenPlanModelImpl.fromJson(Map json) => _$$ChosenPlanModelImplFromJson(json); @@ -189,10 +234,16 @@ class _$ChosenPlanModelImpl implements _ChosenPlanModel { @override @JsonKey(name: 'chat_id') final String chatId; + @override + @JsonKey(name: 'consultant_id') + final int consultantId; + @override + @JsonKey(name: 'plan') + final PlanModel plan; @override String toString() { - return 'ChosenPlanModel(id: $id, optionType: $optionType, startDate: $startDate, chosenPlanState: $chosenPlanState, chatId: $chatId)'; + return 'ChosenPlanModel(id: $id, optionType: $optionType, startDate: $startDate, chosenPlanState: $chosenPlanState, chatId: $chatId, consultantId: $consultantId, plan: $plan)'; } @override @@ -207,13 +258,16 @@ class _$ChosenPlanModelImpl implements _ChosenPlanModel { other.startDate == startDate) && (identical(other.chosenPlanState, chosenPlanState) || other.chosenPlanState == chosenPlanState) && - (identical(other.chatId, chatId) || other.chatId == chatId)); + (identical(other.chatId, chatId) || other.chatId == chatId) && + (identical(other.consultantId, consultantId) || + other.consultantId == consultantId) && + (identical(other.plan, plan) || other.plan == plan)); } @JsonKey(includeFromJson: false, includeToJson: false) @override - int get hashCode => Object.hash( - runtimeType, id, optionType, startDate, chosenPlanState, chatId); + int get hashCode => Object.hash(runtimeType, id, optionType, startDate, + chosenPlanState, chatId, consultantId, plan); /// Create a copy of ChosenPlanModel /// with the given fields replaced by the non-null parameter values. @@ -239,7 +293,9 @@ abstract class _ChosenPlanModel implements ChosenPlanModel { @JsonKey(name: 'start_date') required final DateTime startDate, @JsonKey(name: 'last_state') required final ChosenPlanStateEnum chosenPlanState, - @JsonKey(name: 'chat_id') required final String chatId}) = + @JsonKey(name: 'chat_id') required final String chatId, + @JsonKey(name: 'consultant_id') required final int consultantId, + @JsonKey(name: 'plan') required final PlanModel plan}) = _$ChosenPlanModelImpl; factory _ChosenPlanModel.fromJson(Map json) = @@ -260,6 +316,12 @@ abstract class _ChosenPlanModel implements ChosenPlanModel { @override @JsonKey(name: 'chat_id') String get chatId; + @override + @JsonKey(name: 'consultant_id') + int get consultantId; + @override + @JsonKey(name: 'plan') + PlanModel get plan; /// Create a copy of ChosenPlanModel /// with the given fields replaced by the non-null parameter values. diff --git a/lib/features/plans/models/chosen_plan_model.g.dart b/lib/features/plans/models/chosen_plan_model.g.dart index 7e64a4e4..d3e8613c 100644 --- a/lib/features/plans/models/chosen_plan_model.g.dart +++ b/lib/features/plans/models/chosen_plan_model.g.dart @@ -15,6 +15,8 @@ _$ChosenPlanModelImpl _$$ChosenPlanModelImplFromJson( chosenPlanState: $enumDecode(_$ChosenPlanStateEnumEnumMap, json['last_state']), chatId: json['chat_id'] as String, + consultantId: (json['consultant_id'] as num).toInt(), + plan: PlanModel.fromJson(json['plan'] as Map), ); Map _$$ChosenPlanModelImplToJson( @@ -25,6 +27,8 @@ Map _$$ChosenPlanModelImplToJson( 'start_date': instance.startDate.toIso8601String(), 'last_state': _$ChosenPlanStateEnumEnumMap[instance.chosenPlanState]!, 'chat_id': instance.chatId, + 'consultant_id': instance.consultantId, + 'plan': instance.plan, }; const _$ChosenPlanStateEnumEnumMap = { diff --git a/lib/features/plans/presentation/widgets/item_widget.dart b/lib/features/plans/presentation/widgets/item_widget.dart deleted file mode 100644 index 5ec3b288..00000000 --- a/lib/features/plans/presentation/widgets/item_widget.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:eatvio_app/core/theme/custom_text_style.dart'; -import 'package:eatvio_app/core/theme/theme_helper.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; - -class ItemWidget extends StatelessWidget { - const ItemWidget({super.key, required this.text}); - final String text; - @override - Widget build(BuildContext context) { - return Row( - children: [ - Expanded( - child: Text( - text, - style: TextStyles.textMMedium.copyWith(color: appTheme.black), - ), - ), - SvgPicture.asset( - 'assets/icons/ok.svg', - width: 20, - height: 20, - ), - ], - ); - } -} diff --git a/lib/features/plans/presentation/widgets/option_widget.dart b/lib/features/plans/presentation/widgets/option_widget.dart index 96849dfb..6251dbe4 100644 --- a/lib/features/plans/presentation/widgets/option_widget.dart +++ b/lib/features/plans/presentation/widgets/option_widget.dart @@ -3,7 +3,7 @@ import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:eatvio_app/core/widgets/custom_divider.dart'; import 'package:eatvio_app/core/widgets/main_background_bouble.dart'; import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart'; -import 'package:eatvio_app/features/plans/presentation/widgets/item_widget.dart'; +import 'package:eatvio_app/core/widgets/item_widget.dart'; import 'package:eatvio_app/features/plans/presentation/widgets/option_duration_widget.dart'; import 'package:flutter/material.dart'; diff --git a/lib/generated/intl/messages_en.dart b/lib/generated/intl/messages_en.dart index 6d76f87e..e087b400 100644 --- a/lib/generated/intl/messages_en.dart +++ b/lib/generated/intl/messages_en.dart @@ -65,6 +65,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage( "Не удалось загрузить данные. Попробуйте обновить страницу"), "cancel_diet": MessageLookupByLibrary.simpleMessage("Отменить диету?"), + "cancel_order": MessageLookupByLibrary.simpleMessage("Отменить заказ"), "carb_type": MessageLookupByLibrary.simpleMessage("Мучное"), "carb_type_desc": MessageLookupByLibrary.simpleMessage( "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы."), @@ -288,6 +289,8 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Введение в заблуждение"), "misrepresentation_description": MessageLookupByLibrary.simpleMessage( "Новости, которые могут вызвать широкий резонанс или несут угрозу, распространяемые с целью введения людей в заблуждение."), + "more_about_order": + MessageLookupByLibrary.simpleMessage("Подробнее о заказе"), "most_new": MessageLookupByLibrary.simpleMessage("Самые новые"), "most_old": MessageLookupByLibrary.simpleMessage("Самые старые"), "msg_network_err": @@ -387,6 +390,8 @@ class MessageLookup extends MessageLookupByLibrary { "recipe_author": MessageLookupByLibrary.simpleMessage("Автор рецепта"), "recipe_publishing": MessageLookupByLibrary.simpleMessage("Публикация рецепта"), + "refuse_order": + MessageLookupByLibrary.simpleMessage("Отказаться от заказа"), "removeFromActive": MessageLookupByLibrary.simpleMessage("Снять с публикации"), "save": MessageLookupByLibrary.simpleMessage("Сохранить"), diff --git a/lib/generated/l10n.dart b/lib/generated/l10n.dart index 3c20bf57..81cfa1c9 100644 --- a/lib/generated/l10n.dart +++ b/lib/generated/l10n.dart @@ -3251,6 +3251,36 @@ class S { args: [], ); } + + /// `Подробнее о заказе` + String get more_about_order { + return Intl.message( + 'Подробнее о заказе', + name: 'more_about_order', + desc: '', + args: [], + ); + } + + /// `Отменить заказ` + String get cancel_order { + return Intl.message( + 'Отменить заказ', + name: 'cancel_order', + desc: '', + args: [], + ); + } + + /// `Отказаться от заказа` + String get refuse_order { + return Intl.message( + 'Отказаться от заказа', + name: 'refuse_order', + desc: '', + args: [], + ); + } } class AppLocalizationDelegate extends LocalizationsDelegate { diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 3594ada0..07020bcd 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -319,7 +319,10 @@ "choose_date": "Выбрать дату", "date_has_ben_set": "Дата старта начала консультации установлена", "tap_on_link_to)pay": "Перейдите по ссылке для оплаты консультации", - "pay": "Оплатить" + "pay": "Оплатить", + "more_about_order": "Подробнее о заказе", + "cancel_order": "Отменить заказ", + "refuse_order":"Отказаться от заказа" } From fe4076f9aca3c3e06f2398031ab94a34fd793336 Mon Sep 17 00:00:00 2001 From: Username1548 Date: Fri, 14 Mar 2025 20:01:39 +0700 Subject: [PATCH 4/4] fixed translations --- .../chat/presentation/pages/chat_screen.dart | 32 +- .../menu/presentation/pages/menu_screen.dart | 2 - lib/generated/intl/messages_all.dart | 13 +- lib/generated/intl/messages_en.dart | 1028 ++++++++--------- lib/generated/intl/messages_ru.dart | 646 +++++------ lib/generated/l10n.dart | 950 ++++++++++++--- 6 files changed, 1582 insertions(+), 1089 deletions(-) diff --git a/lib/features/chat/presentation/pages/chat_screen.dart b/lib/features/chat/presentation/pages/chat_screen.dart index c39947b0..c9a28d32 100644 --- a/lib/features/chat/presentation/pages/chat_screen.dart +++ b/lib/features/chat/presentation/pages/chat_screen.dart @@ -248,37 +248,7 @@ class _ChatScreenState extends State { onCancel: () async { await context.read().cancelChosenPlan(chatId: state.chatRoom.id, planId: chosenPlan.id); }, - ), - // switch (chosenPlan.chosenPlanState) { - // // TODO: Handle this case. - // ChosenPlanStateEnum.stateInited => throw UnimplementedError(), - // // TODO: Handle this case. - // ChosenPlanStateEnum.stateStartDateHasBeenSet => throw UnimplementedError(), - // // TODO: Handle this case. - // ChosenPlanStateEnum.stateInCoordination => throw UnimplementedError(), - // // TODO: Handle this case. - // ChosenPlanStateEnum.stateStarted => throw UnimplementedError(), - // // TODO: Handle this case. - // ChosenPlanStateEnum.stateInProgress => throw UnimplementedError(), - // // TODO: Handle this case. - // ChosenPlanStateEnum.statePendingPayment => throw UnimplementedError(), - // // TODO: Handle this case. - // ChosenPlanStateEnum.stateConfirmedByConsultant => throw UnimplementedError(), - // // TODO: Handle this case. - // ChosenPlanStateEnum.statePaid => throw UnimplementedError(), - // // TODO: Handle this case. - // ChosenPlanStateEnum.stateCanceledByTheInitiator => throw UnimplementedError(), - // // TODO: Handle this case. - // ChosenPlanStateEnum.stateLastDayStarted => throw UnimplementedError(), - // // TODO: Handle this case. - // ChosenPlanStateEnum.stateLastDayFinished => throw UnimplementedError(), - // // TODO: Handle this case. - // ChosenPlanStateEnum.stateComplained => throw UnimplementedError(), - // // TODO: Handle this case. - // ChosenPlanStateEnum.stateDone => throw UnimplementedError(), - // // TODO: Handle this case. - // ChosenPlanStateEnum.stateChargeWasCollected => throw UnimplementedError(), - // }, + ), ], ), ), diff --git a/lib/features/menu/presentation/pages/menu_screen.dart b/lib/features/menu/presentation/pages/menu_screen.dart index 8fbb2dbb..41c9706c 100644 --- a/lib/features/menu/presentation/pages/menu_screen.dart +++ b/lib/features/menu/presentation/pages/menu_screen.dart @@ -4,14 +4,12 @@ import 'package:eatvio_app/core/token_storage.dart'; import 'package:eatvio_app/core/utils/image_constant.dart'; import 'package:eatvio_app/core/locator_service.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; -import 'package:eatvio_app/features/chat/presentation/bloc/chats_cubit/chats_cubit.dart'; import 'package:eatvio_app/features/dev_tools/presentation/dev_tools_screen.dart'; import 'package:eatvio_app/features/my_diets/presentation/my_diets_screen.dart'; import 'package:eatvio_app/features/my_plans/presentation/my_plans_screen.dart'; import 'package:eatvio_app/features/profile/models/profile_model.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:go_router/go_router.dart'; diff --git a/lib/generated/intl/messages_all.dart b/lib/generated/intl/messages_all.dart index 3139e159..abae25a5 100644 --- a/lib/generated/intl/messages_all.dart +++ b/lib/generated/intl/messages_all.dart @@ -39,10 +39,8 @@ MessageLookupByLibrary? _findExact(String localeName) { /// User programs should call this before using [localeName] for messages. Future initializeMessages(String localeName) { var availableLocale = Intl.verifiedLocale( - localeName, - (locale) => _deferredLibraries[locale] != null, - onFailure: (_) => null, - ); + localeName, (locale) => _deferredLibraries[locale] != null, + onFailure: (_) => null); if (availableLocale == null) { return new SynchronousFuture(false); } @@ -62,11 +60,8 @@ bool _messagesExistFor(String locale) { } MessageLookupByLibrary? _findGeneratedMessagesFor(String locale) { - var actualLocale = Intl.verifiedLocale( - locale, - _messagesExistFor, - onFailure: (_) => null, - ); + var actualLocale = + Intl.verifiedLocale(locale, _messagesExistFor, onFailure: (_) => null); if (actualLocale == null) return null; return _findExact(actualLocale); } diff --git a/lib/generated/intl/messages_en.dart b/lib/generated/intl/messages_en.dart index 13dfa95f..ab2b76d5 100644 --- a/lib/generated/intl/messages_en.dart +++ b/lib/generated/intl/messages_en.dart @@ -22,557 +22,479 @@ class MessageLookup extends MessageLookupByLibrary { final messages = _notInlinedMessages(_notInlinedMessages); static Map _notInlinedMessages(_) => { - "Moscow": MessageLookupByLibrary.simpleMessage("Москва"), - "Russia": MessageLookupByLibrary.simpleMessage("Россия"), - "about_diet": MessageLookupByLibrary.simpleMessage("Об этой диете"), - "about_plan": MessageLookupByLibrary.simpleMessage("Об этом плане"), - "about_recipe": MessageLookupByLibrary.simpleMessage("Об этом рецепте"), - "active": MessageLookupByLibrary.simpleMessage("Активен"), - "active_consultations_count": MessageLookupByLibrary.simpleMessage( - "Кол-во активных консультаций", - ), - "active_diet_state": MessageLookupByLibrary.simpleMessage("Активная"), - "add": MessageLookupByLibrary.simpleMessage("Добавить"), - "add_cover": MessageLookupByLibrary.simpleMessage("Добавьте обложку"), - "add_measure": MessageLookupByLibrary.simpleMessage("Добавить замер"), - "adding_plan": MessageLookupByLibrary.simpleMessage("Добавление плана"), - "additional_information": MessageLookupByLibrary.simpleMessage( - "Дополнительная информация", - ), - "admin": MessageLookupByLibrary.simpleMessage("Админ"), - "alcohol": MessageLookupByLibrary.simpleMessage("Алкоголь"), - "all": MessageLookupByLibrary.simpleMessage("Все"), - "allergies_presence": MessageLookupByLibrary.simpleMessage( - "Наличие аллергии", - ), - "another_form_of_comment": MessageLookupByLibrary.simpleMessage( - "комментария", - ), - "another_form_of_day": MessageLookupByLibrary.simpleMessage("дня"), - "another_form_of_hour": MessageLookupByLibrary.simpleMessage("часа"), - "another_form_of_minute": MessageLookupByLibrary.simpleMessage("минут"), - "another_form_of_stage": MessageLookupByLibrary.simpleMessage("этапа"), - "answer": MessageLookupByLibrary.simpleMessage("Ответить"), - "archived": MessageLookupByLibrary.simpleMessage("В архиве"), - "authentificate": MessageLookupByLibrary.simpleMessage("Войти"), - "average_pressure": MessageLookupByLibrary.simpleMessage( - "Средние показатели давления:", - ), - "bodymass_chart": MessageLookupByLibrary.simpleMessage("График ИМТ"), - "by_default": MessageLookupByLibrary.simpleMessage("По умолчянию"), - "calls_for_bullying": MessageLookupByLibrary.simpleMessage( - "Призывы к травле", - ), - "calories": MessageLookupByLibrary.simpleMessage("Калории"), - "can_not_load_data_please_try_again": MessageLookupByLibrary.simpleMessage( - "Не удалось загрузить данные. Попробуйте обновить страницу", - ), - "cancel_diet": MessageLookupByLibrary.simpleMessage("Отменить диету?"), - "carb_type": MessageLookupByLibrary.simpleMessage("Мучное"), - "carb_type_desc": MessageLookupByLibrary.simpleMessage( - "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы.", - ), - "carbohydrates": MessageLookupByLibrary.simpleMessage("Углеводы"), - "chat": MessageLookupByLibrary.simpleMessage("Чат"), - "check_out_video_recipe": MessageLookupByLibrary.simpleMessage( - "Посмотреть видео рецепт", - ), - "chest": MessageLookupByLibrary.simpleMessage("Грудь"), - "chest_circumference": MessageLookupByLibrary.simpleMessage("Обхват груди"), - "choose_diet_duration": MessageLookupByLibrary.simpleMessage( - "Выберите срок диеты", - ), - "choose_plan_duration": 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("Город"), - "city_of_living": MessageLookupByLibrary.simpleMessage("Город проживания"), - "comfort": MessageLookupByLibrary.simpleMessage("Комфорт"), - "comment": MessageLookupByLibrary.simpleMessage("комментарий"), - "comments": MessageLookupByLibrary.simpleMessage("Комментарии"), - "comments_plural": MessageLookupByLibrary.simpleMessage("комментариев"), - "complain": MessageLookupByLibrary.simpleMessage("Пожаловаться"), - "complaint": MessageLookupByLibrary.simpleMessage("Жалоба"), - "complaint_question": MessageLookupByLibrary.simpleMessage( - "Что именно в этом материале Вы считаете неприемлемым и нарушающим правила?", - ), - "complaint_sent": MessageLookupByLibrary.simpleMessage( - "Жалоба успешно отправлена", - ), - "complaint_sent_description": MessageLookupByLibrary.simpleMessage( - "Ваше обращение принято! Мы рассмотрим его в ближайшее время и примем необходимые меры. Спасибо за вашу бдительность и помощь в улучшении нашего сервиса.", - ), - "confirm": MessageLookupByLibrary.simpleMessage("Подтвердить"), - "consultations_count": MessageLookupByLibrary.simpleMessage( - "Кол-во проведенных консулдьтаций", - ), - "continueButton": MessageLookupByLibrary.simpleMessage("Продолжить"), - "continue_": MessageLookupByLibrary.simpleMessage("Продолжить"), - "copied": MessageLookupByLibrary.simpleMessage("cкопирован"), - "copy_link": MessageLookupByLibrary.simpleMessage("Скопировать ссылку"), - "copy_referral_link": MessageLookupByLibrary.simpleMessage( - "Скопировать пригласительную ссылку", - ), - "could_not_cancel_diet": MessageLookupByLibrary.simpleMessage( - "Не удалось отменить диету", - ), - "could_not_delete_blog_post": MessageLookupByLibrary.simpleMessage( - "Не удалось удалить пост", - ), - "could_not_launch_video": MessageLookupByLibrary.simpleMessage( - "Не удалось запустить видео", - ), - "could_not_publish_blog_post": MessageLookupByLibrary.simpleMessage( - "Не удалось опубликовать пост", - ), - "could_not_publish_diet": MessageLookupByLibrary.simpleMessage( - "Не удалось опубликовать диету", - ), - "could_not_publish_recipe": MessageLookupByLibrary.simpleMessage( - "Не удалось опубликовать рецепт", - ), - "could_not_send_complain": MessageLookupByLibrary.simpleMessage( - "Не удалось отправить жалобу", - ), - "could_not_update_blog_post": MessageLookupByLibrary.simpleMessage( - "Не удалось обновить пост", - ), - "could_not_update_diet": MessageLookupByLibrary.simpleMessage( - "Не удалось обновить диету", - ), - "country": MessageLookupByLibrary.simpleMessage("Страна"), - "create_diet": MessageLookupByLibrary.simpleMessage("Создание диеты"), - "customer_price": MessageLookupByLibrary.simpleMessage( - "Цена для покупателя", - ), - "date_of_birth": MessageLookupByLibrary.simpleMessage("Дата рождения"), - "day": MessageLookupByLibrary.simpleMessage("День"), - "days": MessageLookupByLibrary.simpleMessage("дней"), - "deception": MessageLookupByLibrary.simpleMessage("Обман"), - "deleted": MessageLookupByLibrary.simpleMessage("Удалена"), - "diary": MessageLookupByLibrary.simpleMessage("Дневник"), - "diet": MessageLookupByLibrary.simpleMessage("Диета"), - "diet_author": MessageLookupByLibrary.simpleMessage("Автор диеты"), - "diet_has_been_sent_to_draft": MessageLookupByLibrary.simpleMessage( - "снята с публикации и перенесена в черновик", - ), - "diet_plan": MessageLookupByLibrary.simpleMessage("План диеты"), - "diet_started": MessageLookupByLibrary.simpleMessage("Диета уже начата"), - "diet_state": 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("Черновик"), - "drafted": MessageLookupByLibrary.simpleMessage("Черновики"), - "drugs": MessageLookupByLibrary.simpleMessage("Наркотики"), - "eating_behavior": MessageLookupByLibrary.simpleMessage( - "Пищевое поведение", - ), - "eating_behavior_type": MessageLookupByLibrary.simpleMessage( - "Формирование пищевого поведения", - ), - "eating_behavior_type_desc": MessageLookupByLibrary.simpleMessage( - "Формирование здорового пищевого поведения — это процесс, который включает в себя изменение привычек и отношения к еде. Он направлен на то, чтобы помочь людям научиться правильно питаться и поддерживать здоровый образ жизни.Основные принципы формирования здорового пищевого поведения: \n● Разнообразие продуктов; \n● Сбалансированный рацион; \n● Питьевой режим; \n● Ограничение вредных продуктов; \n● Регулярные приёмы пищи; \n● Умеренность;Осознанное питание; \n● Физическая активность;", - ), - "economy": MessageLookupByLibrary.simpleMessage("Эконом"), - "edit": MessageLookupByLibrary.simpleMessage("Редактировать"), - "email": MessageLookupByLibrary.simpleMessage("Электронная почта"), - "email_empty": MessageLookupByLibrary.simpleMessage( - "Необходимо ввести адрес электронной почты", - ), - "email_invalid": MessageLookupByLibrary.simpleMessage( - "Некорректный адрес электронной почты", - ), - "enter_additional_information": MessageLookupByLibrary.simpleMessage( - "Введите любую дополнительную информацию на своё усмотрение:", - ), - "enter_diet_description": MessageLookupByLibrary.simpleMessage( - "Введите описание диеты", - ), - "enter_diet_name": MessageLookupByLibrary.simpleMessage( - "Выведите название диеты", - ), - "enter_information": MessageLookupByLibrary.simpleMessage( - "Введите информацию...", - ), - "exit": MessageLookupByLibrary.simpleMessage("Выйти"), - "expand": MessageLookupByLibrary.simpleMessage("Показать полностью"), - "explicitImage": MessageLookupByLibrary.simpleMessage( - "Откровенное изображение", - ), - "explicitImages": MessageLookupByLibrary.simpleMessage( - "Откровенные изображения", - ), - "explicitImagesDescription": MessageLookupByLibrary.simpleMessage( - "Отправьте жалобу, если кто-то разместил откровенные изображения", - ), - "extremism": MessageLookupByLibrary.simpleMessage("Экстремизм"), - "fake_documents": MessageLookupByLibrary.simpleMessage( - "Поддельные документы", - ), - "fats": MessageLookupByLibrary.simpleMessage("Жиры"), - "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 символ", - ), - "fit_type": MessageLookupByLibrary.simpleMessage("Поддержание формы"), - "fit_type_desc": MessageLookupByLibrary.simpleMessage( - "План питания для поддержания формы сбалансированный и разнообразный, чтобы обеспечить организм всеми необходимыми питательными веществами. Общие принципы: \n● Дробное питание; \n● Разнообразие продуктов; \n● Контроль порций; \n● Питьевой режим; \n● Ограничение вредных продуктов;", - ), - "fitness": MessageLookupByLibrary.simpleMessage("Поддержка формы"), - "for_a_month": MessageLookupByLibrary.simpleMessage("За месяц"), - "for_a_week": MessageLookupByLibrary.simpleMessage("За неделю"), - "for_a_year": MessageLookupByLibrary.simpleMessage("За год"), - "for_whole_period_of_time": MessageLookupByLibrary.simpleMessage( - "За всё время", - ), - "fraud": MessageLookupByLibrary.simpleMessage("Мошенничество"), - "fraud_description": MessageLookupByLibrary.simpleMessage( - "Мошенничество с целью наживы. Если вас обманули, пожалуйста, сообщите об этом в правоохранительные органы.", - ), - "from": MessageLookupByLibrary.simpleMessage("от"), - "from_a_to_z": MessageLookupByLibrary.simpleMessage("Название: А-Я"), - "from_z_to_a": MessageLookupByLibrary.simpleMessage("Название: Я-А"), - "gallery": MessageLookupByLibrary.simpleMessage("Галерея"), - "general_info": MessageLookupByLibrary.simpleMessage("Общая информация"), - "gr": MessageLookupByLibrary.simpleMessage("гр"), - "grams": MessageLookupByLibrary.simpleMessage("гр"), - "has_alergy": MessageLookupByLibrary.simpleMessage("Наличие аллергии"), - "has_hyper": MessageLookupByLibrary.simpleMessage( - "Склонность к гипертонии", - ), - "has_hypo": MessageLookupByLibrary.simpleMessage("Склонность к гипотонии"), - "hatred": MessageLookupByLibrary.simpleMessage("Оскорбление"), - "hatred_description": MessageLookupByLibrary.simpleMessage( - "Враждебные высказывания", - ), - "height": MessageLookupByLibrary.simpleMessage("Рост"), - "height_measurements": MessageLookupByLibrary.simpleMessage("Замер роста"), - "hide": MessageLookupByLibrary.simpleMessage("Свернуть"), - "hip_circumference": MessageLookupByLibrary.simpleMessage("Обхват бедер"), - "hips": MessageLookupByLibrary.simpleMessage("Бедра"), - "hour": MessageLookupByLibrary.simpleMessage("час"), - "hours": MessageLookupByLibrary.simpleMessage("часов"), - "in_progress": MessageLookupByLibrary.simpleMessage("В процессе"), - "inactive_diet_state": MessageLookupByLibrary.simpleMessage("Черновик"), - "infoAboutOrder": MessageLookupByLibrary.simpleMessage( - "Информация о заказе", - ), - "ingredients": MessageLookupByLibrary.simpleMessage("Ингредиенты"), - "initial_measurements": MessageLookupByLibrary.simpleMessage( - "Первичные замеры", - ), - "invited_people_count": MessageLookupByLibrary.simpleMessage( - "Количество приглашенных", - ), - "label": MessageLookupByLibrary.simpleMessage("Название"), - "language": MessageLookupByLibrary.simpleMessage("Язык"), - "last_name": MessageLookupByLibrary.simpleMessage("Фамилия"), - "last_name_empty": MessageLookupByLibrary.simpleMessage( - "Фамилия обязательна для заполнения", - ), - "last_name_short": MessageLookupByLibrary.simpleMessage( - "В фамилии должен быть минимум 6 символов", - ), - "lawViolation": MessageLookupByLibrary.simpleMessage( - "Нарушение законодательства", - ), - "lbl_english": MessageLookupByLibrary.simpleMessage("English"), - "light_type": MessageLookupByLibrary.simpleMessage("Легкая"), - "light_type_desc": MessageLookupByLibrary.simpleMessage( - "С некоторыми видами диет можно употреблять алкоголь в умеренных количествах. Рекомендуется совмещать вместе с низкокалорийными закусками.", - ), - "liked_groceries": MessageLookupByLibrary.simpleMessage("Любимые продукты"), - "link_was_copied": MessageLookupByLibrary.simpleMessage( - "Ссылка успешно скопирована", - ), - "loading": MessageLookupByLibrary.simpleMessage("Загрузка..."), - "lower": MessageLookupByLibrary.simpleMessage("Нижнее"), - "male": MessageLookupByLibrary.simpleMessage("Мужской"), - "meal": MessageLookupByLibrary.simpleMessage("Приём пищи"), - "meat": MessageLookupByLibrary.simpleMessage("Мясо"), - "meat_type": MessageLookupByLibrary.simpleMessage("С мясом"), - "meat_type_desc": MessageLookupByLibrary.simpleMessage( - "Диета с мясом полезная и сбалансированная. Включает в себя нежирное мясо: курицу, индейку, кролика или говядину. В сочетании с овощами получаете все необходимые витамины и минералы. Не забывайте о порциях и старайтесь есть медленно, прислушиваясь к своему организму.", - ), - "milliliter": MessageLookupByLibrary.simpleMessage("мл"), - "minimal_customer_price": MessageLookupByLibrary.simpleMessage( - "Минимальная цена для покупателя: 1200₽", - ), - "minute": MessageLookupByLibrary.simpleMessage("минута"), - "minutes": MessageLookupByLibrary.simpleMessage("минуты"), - "misrepresentation": MessageLookupByLibrary.simpleMessage( - "Введение в заблуждение", - ), - "misrepresentation_description": MessageLookupByLibrary.simpleMessage( - "Новости, которые могут вызвать широкий резонанс или несут угрозу, распространяемые с целью введения людей в заблуждение.", - ), - "most_new": MessageLookupByLibrary.simpleMessage("Самые новые"), - "most_old": MessageLookupByLibrary.simpleMessage("Самые старые"), - "msg_network_err": MessageLookupByLibrary.simpleMessage("Сетевая ошибка!"), - "msg_something_went_wrong": MessageLookupByLibrary.simpleMessage( - "Что то пошло не так!", - ), - "my_blog": MessageLookupByLibrary.simpleMessage("Мой блог"), - "my_diets": MessageLookupByLibrary.simpleMessage("Мои диеты"), - "my_plans": MessageLookupByLibrary.simpleMessage("Мои планы"), - "my_settings": MessageLookupByLibrary.simpleMessage("Мои настройки"), - "name_empty": MessageLookupByLibrary.simpleMessage( - "Имя пользователя обязательно для заполнения", - ), - "name_short": MessageLookupByLibrary.simpleMessage( - "В имени пользователя должно быть минимум 6 символов", - ), - "nicotine": MessageLookupByLibrary.simpleMessage("Никотин"), - "no": MessageLookupByLibrary.simpleMessage("Нет"), - "no_account": MessageLookupByLibrary.simpleMessage("У меня нет аккаунта"), - "not_liked_groceries": MessageLookupByLibrary.simpleMessage( - "Не любимые продукты", - ), - "ok": MessageLookupByLibrary.simpleMessage("Хорошо"), - "one_option": MessageLookupByLibrary.simpleMessage("1 опция"), - "option": MessageLookupByLibrary.simpleMessage("Опция"), - "option_content": MessageLookupByLibrary.simpleMessage("Содержание опции"), - "option_content_hint_text": MessageLookupByLibrary.simpleMessage( - "На связи 7 дней в неделю", - ), - "option_desc": MessageLookupByLibrary.simpleMessage("Описание опции"), - "option_desc_hint_text": MessageLookupByLibrary.simpleMessage( - "Этот план питания для похудения на 7 дней сбалансированный и разнообразный", - ), - "option_duration": MessageLookupByLibrary.simpleMessage( - "Продолжительность опции", - ), - "option_personal_diet_desc": MessageLookupByLibrary.simpleMessage( - "Опция подразумевает создание индивидуальной диеты", - ), - "option_title": MessageLookupByLibrary.simpleMessage("Заголовок опции"), - "order": MessageLookupByLibrary.simpleMessage("Порядок"), - "other": MessageLookupByLibrary.simpleMessage("Другое"), - "other_info": MessageLookupByLibrary.simpleMessage("Прочая информация"), - "password": MessageLookupByLibrary.simpleMessage("Пароль"), - "password_confirmation": MessageLookupByLibrary.simpleMessage( - "Подтвердите пароль", - ), - "password_confirmation_mismatch": MessageLookupByLibrary.simpleMessage( - "Пароли не совпадают", - ), - "password_empty": MessageLookupByLibrary.simpleMessage( - "Пароль обязателен для заполнения", - ), - "password_short": MessageLookupByLibrary.simpleMessage( - "В пароле должно быть минимум 6 символов", - ), - "pcs": MessageLookupByLibrary.simpleMessage("шт"), - "personal": MessageLookupByLibrary.simpleMessage("Персональные"), - "personal_diet_state": MessageLookupByLibrary.simpleMessage("Персональная"), - "photo": MessageLookupByLibrary.simpleMessage("Фото"), - "physical_fitness": MessageLookupByLibrary.simpleMessage( - "Физическая форма", - ), - "place_of_living": MessageLookupByLibrary.simpleMessage("Место проживания"), - "plan_author": MessageLookupByLibrary.simpleMessage("Автор плана"), - "plan_desc": MessageLookupByLibrary.simpleMessage("Описание плана"), - "plan_desc_example": MessageLookupByLibrary.simpleMessage( - "Большое подробное, привлекательное описание плана", - ), - "plan_duration": MessageLookupByLibrary.simpleMessage("Срок плана"), - "plan_label_desc": MessageLookupByLibrary.simpleMessage( - "План для поддержания формы", - ), - "plan_type": MessageLookupByLibrary.simpleMessage("Тип плана"), - "plans_complete": MessageLookupByLibrary.simpleMessage("Пройденные планы"), - "please_try_again_later": MessageLookupByLibrary.simpleMessage( - "Пожалуйста, попробуйте еще раз позже", - ), - "popular": MessageLookupByLibrary.simpleMessage("Популярные"), - "preferred_language": MessageLookupByLibrary.simpleMessage( - "Предпочитаемый язык общения", - ), - "pressure": MessageLookupByLibrary.simpleMessage("Давление"), - "pressure_empty": MessageLookupByLibrary.simpleMessage( - "Все показатели давления обязательны к заполнению", - ), - "pressure_is_not_a_number": MessageLookupByLibrary.simpleMessage( - "Все показатели давления должны быть числами", - ), - "preview": MessageLookupByLibrary.simpleMessage("Превью"), - "price": MessageLookupByLibrary.simpleMessage("Цена"), - "price_explanation": MessageLookupByLibrary.simpleMessage( - "Разница в ценах, это комиссия Итвио", - ), - "profile": MessageLookupByLibrary.simpleMessage("Профиль"), - "prostitution": MessageLookupByLibrary.simpleMessage("Проституция"), - "proteins": MessageLookupByLibrary.simpleMessage("Белки"), - "publish": MessageLookupByLibrary.simpleMessage("Опубликовать"), - "published": MessageLookupByLibrary.simpleMessage("Опубликованные"), - "published_diets_count": MessageLookupByLibrary.simpleMessage( - "Кол-во опубликованных диет", - ), - "published_posts_count": MessageLookupByLibrary.simpleMessage( - "Количество опубликованных постов", - ), - "published_recipes_count": MessageLookupByLibrary.simpleMessage( - "Кол-во опубликованных рецептов", - ), - "rating_and_statistics": MessageLookupByLibrary.simpleMessage( - "Рейтинг и статистика", - ), - "rating_history": MessageLookupByLibrary.simpleMessage( - "Начисление рейтинга", - ), - "recipe_author": MessageLookupByLibrary.simpleMessage("Автор рецепта"), - "recipe_publishing": MessageLookupByLibrary.simpleMessage( - "Публикация рецепта", - ), - "removeFromActive": MessageLookupByLibrary.simpleMessage( - "Снять с публикации", - ), - "save": MessageLookupByLibrary.simpleMessage("Сохранить"), - "send_complain": MessageLookupByLibrary.simpleMessage("Отправить жалобу"), - "services": MessageLookupByLibrary.simpleMessage("Оказание услуг"), - "settings": MessageLookupByLibrary.simpleMessage("Настройки"), - "sex": MessageLookupByLibrary.simpleMessage("Пол"), - "share": MessageLookupByLibrary.simpleMessage("Поделиться"), - "skip": MessageLookupByLibrary.simpleMessage("Пропустить"), - "slim": MessageLookupByLibrary.simpleMessage("Похудение"), - "slim_type": MessageLookupByLibrary.simpleMessage("Похудение"), - "slim_type_desc": MessageLookupByLibrary.simpleMessage( - "План питания для похудения должен быть разработан с учётом индивидуальных особенностей организма, возраста, пола, уровня физической активности и состояния здоровья. Общие принципы: \n● Снижение калорийности; \n● Сбалансированный рацион; \n● Разнообразие продуктов; \n● Питьевой режим; \n● Ограничение вредных продуктов;", - ), - "some_error_occurred": MessageLookupByLibrary.simpleMessage( - "Упс! Произошла ошибка", - ), - "some_error_occurred_description": MessageLookupByLibrary.simpleMessage( - "Произошла ошибка. Мы уже работаем над ее устранением. Попробуйте позже.", - ), - "something_went_wrong": MessageLookupByLibrary.simpleMessage( - "Упс! Что-то пошло не так", - ), - "spam": MessageLookupByLibrary.simpleMessage("Спам"), - "spam_description": MessageLookupByLibrary.simpleMessage( - "Отправьте жалобу, если Вы заметили рекламу, размещенную в не предназначенном для этого месте.", - ), - "sport_hobbies": MessageLookupByLibrary.simpleMessage( - "Спортивные увлечения", - ), - "stage": MessageLookupByLibrary.simpleMessage("этап"), - "stages": MessageLookupByLibrary.simpleMessage("этапов"), - "standard": MessageLookupByLibrary.simpleMessage("Стандарт"), - "startDiet": MessageLookupByLibrary.simpleMessage("Начать диету"), - "statistic": MessageLookupByLibrary.simpleMessage("Статистика"), - "step": MessageLookupByLibrary.simpleMessage("Шаг"), - "step_by_step_photo_recipe": MessageLookupByLibrary.simpleMessage( - "Пошаговый фоторецепт", - ), - "successfully_published": MessageLookupByLibrary.simpleMessage( - "успешно опубликован", - ), - "suicide": MessageLookupByLibrary.simpleMessage("Склонение к самоубийству"), - "takes_pills": MessageLookupByLibrary.simpleMessage("Принимает лекарства"), - "tell_your_schedule": MessageLookupByLibrary.simpleMessage( - "Расскажите в свободной форме о том как просыпаетесь, когда едите, когда ложитесь спать:", - ), - "there_is_a_video": MessageLookupByLibrary.simpleMessage("Есть видео"), - "three_options": MessageLookupByLibrary.simpleMessage("3 опции"), - "time": MessageLookupByLibrary.simpleMessage("Время прохождения"), - "toOffer": MessageLookupByLibrary.simpleMessage("Предложить"), - "to_draft": MessageLookupByLibrary.simpleMessage("В черновик"), - "try_again": MessageLookupByLibrary.simpleMessage("Попробовать снова"), - "type_here_your_complaint": MessageLookupByLibrary.simpleMessage( - "Напишите здесь свою жалобу", - ), - "unfavorite_foods": MessageLookupByLibrary.simpleMessage( - "Нелюбимые продукты", - ), - "up_pressure": MessageLookupByLibrary.simpleMessage( - "Верхние показатели давления:", - ), - "upper": MessageLookupByLibrary.simpleMessage("Верхнее"), - "user_authorization": MessageLookupByLibrary.simpleMessage( - "Аутентификация", - ), - "user_data": MessageLookupByLibrary.simpleMessage("Данные пользователя"), - "user_registration": MessageLookupByLibrary.simpleMessage( - "Регистрация пользователя", - ), - "username": MessageLookupByLibrary.simpleMessage("Имя пользователя"), - "vegan": MessageLookupByLibrary.simpleMessage("Веган."), - "vegan_type": MessageLookupByLibrary.simpleMessage("Вегетарианская"), - "vegan_type_desc": MessageLookupByLibrary.simpleMessage( - "Диета основана на потреблении растительной пищи и отказе от продуктов животного происхождения. Такой тип питания может быть разнообразным и вкусным, а также полезным для здоровья.", - ), - "violenceAndHostility": MessageLookupByLibrary.simpleMessage( - "Насилие и вражда", - ), - "violence_against_people_or_animal": MessageLookupByLibrary.simpleMessage( - "Насилие над людьми или животными", - ), - "waist": MessageLookupByLibrary.simpleMessage("Талия"), - "waist_circumference": MessageLookupByLibrary.simpleMessage("Обхват талии"), - "weapon": MessageLookupByLibrary.simpleMessage("Оружие"), - "weight": MessageLookupByLibrary.simpleMessage("Вес"), - "weight_chart": MessageLookupByLibrary.simpleMessage("График веса"), - "weight_measurements": MessageLookupByLibrary.simpleMessage("Замер веса"), - "wellness": MessageLookupByLibrary.simpleMessage("Улучшение самочувствия"), - "wellness_type": MessageLookupByLibrary.simpleMessage( - "Улучшение самочувствия", - ), - "wellness_type_desc": MessageLookupByLibrary.simpleMessage( - "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы.", - ), - "what_do_you_want_to_complaint_about": MessageLookupByLibrary.simpleMessage( - "На что Вы хотите пожаловаться?", - ), - "what_is_your_name": MessageLookupByLibrary.simpleMessage("Как вас зовут?"), - "wrong_credentials": MessageLookupByLibrary.simpleMessage( - "Неверные данные пользователя", - ), - "you_will_get": MessageLookupByLibrary.simpleMessage("Вы получите"), - "your_blood_pressure": MessageLookupByLibrary.simpleMessage( - "Ваше артериальное давление?", - ), - "your_favorite_sports": MessageLookupByLibrary.simpleMessage( - "Ваши спортивные увлечения?", - ), - "your_gender": MessageLookupByLibrary.simpleMessage("Ваш пол?"), - "your_height": MessageLookupByLibrary.simpleMessage("Ваш рост:"), - "your_rating": MessageLookupByLibrary.simpleMessage("Ваш рейтинг"), - "your_schedule": MessageLookupByLibrary.simpleMessage("Ваш режим дня?"), - "your_weight": MessageLookupByLibrary.simpleMessage("Ваш вес:"), - }; + "Moscow": MessageLookupByLibrary.simpleMessage("Москва"), + "Russia": MessageLookupByLibrary.simpleMessage("Россия"), + "about_diet": MessageLookupByLibrary.simpleMessage("Об этой диете"), + "about_plan": MessageLookupByLibrary.simpleMessage("Об этом плане"), + "about_recipe": MessageLookupByLibrary.simpleMessage("Об этом рецепте"), + "active": MessageLookupByLibrary.simpleMessage("Активен"), + "active_consultations_count": MessageLookupByLibrary.simpleMessage( + "Кол-во активных консультаций"), + "active_diet_state": MessageLookupByLibrary.simpleMessage("Активная"), + "add": MessageLookupByLibrary.simpleMessage("Добавить"), + "add_card": MessageLookupByLibrary.simpleMessage("Привязать карту"), + "add_cover": MessageLookupByLibrary.simpleMessage("Добавьте обложку"), + "add_measure": MessageLookupByLibrary.simpleMessage("Добавить замер"), + "adding_plan": MessageLookupByLibrary.simpleMessage("Добавление плана"), + "additional_information": + MessageLookupByLibrary.simpleMessage("Дополнительная информация"), + "admin": MessageLookupByLibrary.simpleMessage("Админ"), + "alcohol": MessageLookupByLibrary.simpleMessage("Алкоголь"), + "all": MessageLookupByLibrary.simpleMessage("Все"), + "allergies_presence": + MessageLookupByLibrary.simpleMessage("Наличие аллергии"), + "another_form_of_comment": + MessageLookupByLibrary.simpleMessage("комментария"), + "another_form_of_day": MessageLookupByLibrary.simpleMessage("дня"), + "another_form_of_hour": MessageLookupByLibrary.simpleMessage("часа"), + "another_form_of_minute": MessageLookupByLibrary.simpleMessage("минут"), + "another_form_of_stage": MessageLookupByLibrary.simpleMessage("этапа"), + "answer": MessageLookupByLibrary.simpleMessage("Ответить"), + "archived": MessageLookupByLibrary.simpleMessage("В архиве"), + "authentificate": MessageLookupByLibrary.simpleMessage("Войти"), + "average_pressure": MessageLookupByLibrary.simpleMessage( + "Средние показатели давления:"), + "bodymass_chart": MessageLookupByLibrary.simpleMessage("График ИМТ"), + "by_default": MessageLookupByLibrary.simpleMessage("По умолчянию"), + "calls_for_bullying": + MessageLookupByLibrary.simpleMessage("Призывы к травле"), + "calories": MessageLookupByLibrary.simpleMessage("Калории"), + "can_not_choose_start_date": MessageLookupByLibrary.simpleMessage( + "Дату старта плана невозможно выбрать, пока Вы не привяжите карту"), + "can_not_load_data_please_try_again": + MessageLookupByLibrary.simpleMessage( + "Не удалось загрузить данные. Попробуйте обновить страницу"), + "cancel_diet": MessageLookupByLibrary.simpleMessage("Отменить диету?"), + "cancel_order": MessageLookupByLibrary.simpleMessage("Отменить заказ"), + "carb_type": MessageLookupByLibrary.simpleMessage("Мучное"), + "carb_type_desc": MessageLookupByLibrary.simpleMessage( + "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы."), + "carbohydrates": MessageLookupByLibrary.simpleMessage("Углеводы"), + "chat": MessageLookupByLibrary.simpleMessage("Чат"), + "check_out_video_recipe": + MessageLookupByLibrary.simpleMessage("Посмотреть видео рецепт"), + "chest": MessageLookupByLibrary.simpleMessage("Грудь"), + "chest_circumference": + MessageLookupByLibrary.simpleMessage("Обхват груди"), + "choose_date": MessageLookupByLibrary.simpleMessage("Выбрать дату"), + "choose_diet_duration": + MessageLookupByLibrary.simpleMessage("Выберите срок диеты"), + "choose_plan_duration": + MessageLookupByLibrary.simpleMessage("Выберите срок плана"), + "choose_plan_start_date": 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("Город"), + "city_of_living": + MessageLookupByLibrary.simpleMessage("Город проживания"), + "comfort": MessageLookupByLibrary.simpleMessage("Комфорт"), + "comment": MessageLookupByLibrary.simpleMessage("комментарий"), + "comments": MessageLookupByLibrary.simpleMessage("Комментарии"), + "comments_plural": MessageLookupByLibrary.simpleMessage("комментариев"), + "complain": MessageLookupByLibrary.simpleMessage("Пожаловаться"), + "complaint": MessageLookupByLibrary.simpleMessage("Жалоба"), + "complaint_question": MessageLookupByLibrary.simpleMessage( + "Что именно в этом материале Вы считаете неприемлемым и нарушающим правила?"), + "complaint_sent": + MessageLookupByLibrary.simpleMessage("Жалоба успешно отправлена"), + "complaint_sent_description": MessageLookupByLibrary.simpleMessage( + "Ваше обращение принято! Мы рассмотрим его в ближайшее время и примем необходимые меры. Спасибо за вашу бдительность и помощь в улучшении нашего сервиса."), + "confirm": MessageLookupByLibrary.simpleMessage("Подтвердить"), + "consultations_count": MessageLookupByLibrary.simpleMessage( + "Кол-во проведенных консулдьтаций"), + "continueButton": MessageLookupByLibrary.simpleMessage("Продолжить"), + "continue_": MessageLookupByLibrary.simpleMessage("Продолжить"), + "copied": MessageLookupByLibrary.simpleMessage("cкопирован"), + "copy_link": MessageLookupByLibrary.simpleMessage("Скопировать ссылку"), + "copy_referral_link": MessageLookupByLibrary.simpleMessage( + "Скопировать пригласительную ссылку"), + "could_not_cancel_diet": + MessageLookupByLibrary.simpleMessage("Не удалось отменить диету"), + "could_not_delete_blog_post": + MessageLookupByLibrary.simpleMessage("Не удалось удалить пост"), + "could_not_launch_video": + MessageLookupByLibrary.simpleMessage("Не удалось запустить видео"), + "could_not_publish_blog_post": MessageLookupByLibrary.simpleMessage( + "Не удалось опубликовать пост"), + "could_not_publish_diet": MessageLookupByLibrary.simpleMessage( + "Не удалось опубликовать диету"), + "could_not_publish_recipe": MessageLookupByLibrary.simpleMessage( + "Не удалось опубликовать рецепт"), + "could_not_send_complain": + MessageLookupByLibrary.simpleMessage("Не удалось отправить жалобу"), + "could_not_update_blog_post": + MessageLookupByLibrary.simpleMessage("Не удалось обновить пост"), + "could_not_update_diet": + MessageLookupByLibrary.simpleMessage("Не удалось обновить диету"), + "country": MessageLookupByLibrary.simpleMessage("Страна"), + "create_diet": MessageLookupByLibrary.simpleMessage("Создание диеты"), + "customer_price": + MessageLookupByLibrary.simpleMessage("Цена для покупателя"), + "date_has_ben_set": MessageLookupByLibrary.simpleMessage( + "Дата старта начала консультации установлена"), + "date_of_birth": MessageLookupByLibrary.simpleMessage("Дата рождения"), + "day": MessageLookupByLibrary.simpleMessage("День"), + "days": MessageLookupByLibrary.simpleMessage("дней"), + "deception": MessageLookupByLibrary.simpleMessage("Обман"), + "deleted": MessageLookupByLibrary.simpleMessage("Удалена"), + "diary": MessageLookupByLibrary.simpleMessage("Дневник"), + "diet": MessageLookupByLibrary.simpleMessage("Диета"), + "diet_author": MessageLookupByLibrary.simpleMessage("Автор диеты"), + "diet_has_been_sent_to_draft": MessageLookupByLibrary.simpleMessage( + "снята с публикации и перенесена в черновик"), + "diet_plan": MessageLookupByLibrary.simpleMessage("План диеты"), + "diet_started": + MessageLookupByLibrary.simpleMessage("Диета уже начата"), + "diet_state": 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("Черновик"), + "drafted": MessageLookupByLibrary.simpleMessage("Черновики"), + "drugs": MessageLookupByLibrary.simpleMessage("Наркотики"), + "eating_behavior": + MessageLookupByLibrary.simpleMessage("Пищевое поведение"), + "eating_behavior_type": MessageLookupByLibrary.simpleMessage( + "Формирование пищевого поведения"), + "eating_behavior_type_desc": MessageLookupByLibrary.simpleMessage( + "Формирование здорового пищевого поведения — это процесс, который включает в себя изменение привычек и отношения к еде. Он направлен на то, чтобы помочь людям научиться правильно питаться и поддерживать здоровый образ жизни.Основные принципы формирования здорового пищевого поведения: \n● Разнообразие продуктов; \n● Сбалансированный рацион; \n● Питьевой режим; \n● Ограничение вредных продуктов; \n● Регулярные приёмы пищи; \n● Умеренность;Осознанное питание; \n● Физическая активность;"), + "economy": MessageLookupByLibrary.simpleMessage("Эконом"), + "edit": MessageLookupByLibrary.simpleMessage("Редактировать"), + "email": MessageLookupByLibrary.simpleMessage("Электронная почта"), + "email_empty": MessageLookupByLibrary.simpleMessage( + "Необходимо ввести адрес электронной почты"), + "email_invalid": MessageLookupByLibrary.simpleMessage( + "Некорректный адрес электронной почты"), + "enter_additional_information": MessageLookupByLibrary.simpleMessage( + "Введите любую дополнительную информацию на своё усмотрение:"), + "enter_diet_description": + MessageLookupByLibrary.simpleMessage("Введите описание диеты"), + "enter_diet_name": + MessageLookupByLibrary.simpleMessage("Выведите название диеты"), + "enter_information": + MessageLookupByLibrary.simpleMessage("Введите информацию..."), + "exit": MessageLookupByLibrary.simpleMessage("Выйти"), + "expand": MessageLookupByLibrary.simpleMessage("Показать полностью"), + "explicitImage": + MessageLookupByLibrary.simpleMessage("Откровенное изображение"), + "explicitImages": + MessageLookupByLibrary.simpleMessage("Откровенные изображения"), + "explicitImagesDescription": MessageLookupByLibrary.simpleMessage( + "Отправьте жалобу, если кто-то разместил откровенные изображения"), + "extremism": MessageLookupByLibrary.simpleMessage("Экстремизм"), + "fake_documents": + MessageLookupByLibrary.simpleMessage("Поддельные документы"), + "fats": MessageLookupByLibrary.simpleMessage("Жиры"), + "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 символ"), + "fit_type": MessageLookupByLibrary.simpleMessage("Поддержание формы"), + "fit_type_desc": MessageLookupByLibrary.simpleMessage( + "План питания для поддержания формы сбалансированный и разнообразный, чтобы обеспечить организм всеми необходимыми питательными веществами. Общие принципы: \n● Дробное питание; \n● Разнообразие продуктов; \n● Контроль порций; \n● Питьевой режим; \n● Ограничение вредных продуктов;"), + "fitness": MessageLookupByLibrary.simpleMessage("Поддержка формы"), + "for_a_month": MessageLookupByLibrary.simpleMessage("За месяц"), + "for_a_week": MessageLookupByLibrary.simpleMessage("За неделю"), + "for_a_year": MessageLookupByLibrary.simpleMessage("За год"), + "for_whole_period_of_time": + MessageLookupByLibrary.simpleMessage("За всё время"), + "fraud": MessageLookupByLibrary.simpleMessage("Мошенничество"), + "fraud_description": MessageLookupByLibrary.simpleMessage( + "Мошенничество с целью наживы. Если вас обманули, пожалуйста, сообщите об этом в правоохранительные органы."), + "from": MessageLookupByLibrary.simpleMessage("от"), + "from_a_to_z": MessageLookupByLibrary.simpleMessage("Название: А-Я"), + "from_z_to_a": MessageLookupByLibrary.simpleMessage("Название: Я-А"), + "gallery": MessageLookupByLibrary.simpleMessage("Галерея"), + "general_info": + MessageLookupByLibrary.simpleMessage("Общая информация"), + "gr": MessageLookupByLibrary.simpleMessage("гр"), + "grams": MessageLookupByLibrary.simpleMessage("гр"), + "has_alergy": MessageLookupByLibrary.simpleMessage("Наличие аллергии"), + "has_hyper": + MessageLookupByLibrary.simpleMessage("Склонность к гипертонии"), + "has_hypo": + MessageLookupByLibrary.simpleMessage("Склонность к гипотонии"), + "hatred": MessageLookupByLibrary.simpleMessage("Оскорбление"), + "hatred_description": + MessageLookupByLibrary.simpleMessage("Враждебные высказывания"), + "height": MessageLookupByLibrary.simpleMessage("Рост"), + "height_measurements": + MessageLookupByLibrary.simpleMessage("Замер роста"), + "hide": MessageLookupByLibrary.simpleMessage("Свернуть"), + "hip_circumference": + MessageLookupByLibrary.simpleMessage("Обхват бедер"), + "hips": MessageLookupByLibrary.simpleMessage("Бедра"), + "hour": MessageLookupByLibrary.simpleMessage("час"), + "hours": MessageLookupByLibrary.simpleMessage("часов"), + "in_progress": MessageLookupByLibrary.simpleMessage("В процессе"), + "inactive_diet_state": MessageLookupByLibrary.simpleMessage("Черновик"), + "infoAboutOrder": + MessageLookupByLibrary.simpleMessage("Информация о заказе"), + "ingredients": MessageLookupByLibrary.simpleMessage("Ингредиенты"), + "initial_measurements": + MessageLookupByLibrary.simpleMessage("Первичные замеры"), + "invited_people_count": + MessageLookupByLibrary.simpleMessage("Количество приглашенных"), + "label": MessageLookupByLibrary.simpleMessage("Название"), + "language": MessageLookupByLibrary.simpleMessage("Язык"), + "last_name": MessageLookupByLibrary.simpleMessage("Фамилия"), + "last_name_empty": MessageLookupByLibrary.simpleMessage( + "Фамилия обязательна для заполнения"), + "last_name_short": MessageLookupByLibrary.simpleMessage( + "В фамилии должен быть минимум 6 символов"), + "lawViolation": + MessageLookupByLibrary.simpleMessage("Нарушение законодательства"), + "lbl_english": MessageLookupByLibrary.simpleMessage("English"), + "light_type": MessageLookupByLibrary.simpleMessage("Легкая"), + "light_type_desc": MessageLookupByLibrary.simpleMessage( + "С некоторыми видами диет можно употреблять алкоголь в умеренных количествах. Рекомендуется совмещать вместе с низкокалорийными закусками."), + "liked_groceries": + MessageLookupByLibrary.simpleMessage("Любимые продукты"), + "link_was_copied": + MessageLookupByLibrary.simpleMessage("Ссылка успешно скопирована"), + "loading": MessageLookupByLibrary.simpleMessage("Загрузка..."), + "lower": MessageLookupByLibrary.simpleMessage("Нижнее"), + "male": MessageLookupByLibrary.simpleMessage("Мужской"), + "meal": MessageLookupByLibrary.simpleMessage("Приём пищи"), + "meat": MessageLookupByLibrary.simpleMessage("Мясо"), + "meat_type": MessageLookupByLibrary.simpleMessage("С мясом"), + "meat_type_desc": MessageLookupByLibrary.simpleMessage( + "Диета с мясом полезная и сбалансированная. Включает в себя нежирное мясо: курицу, индейку, кролика или говядину. В сочетании с овощами получаете все необходимые витамины и минералы. Не забывайте о порциях и старайтесь есть медленно, прислушиваясь к своему организму."), + "milliliter": MessageLookupByLibrary.simpleMessage("мл"), + "minimal_customer_price": MessageLookupByLibrary.simpleMessage( + "Минимальная цена для покупателя: 1200₽"), + "minute": MessageLookupByLibrary.simpleMessage("минута"), + "minutes": MessageLookupByLibrary.simpleMessage("минуты"), + "misrepresentation": + MessageLookupByLibrary.simpleMessage("Введение в заблуждение"), + "misrepresentation_description": MessageLookupByLibrary.simpleMessage( + "Новости, которые могут вызвать широкий резонанс или несут угрозу, распространяемые с целью введения людей в заблуждение."), + "more_about_order": + MessageLookupByLibrary.simpleMessage("Подробнее о заказе"), + "most_new": MessageLookupByLibrary.simpleMessage("Самые новые"), + "most_old": MessageLookupByLibrary.simpleMessage("Самые старые"), + "msg_network_err": + MessageLookupByLibrary.simpleMessage("Сетевая ошибка!"), + "msg_something_went_wrong": + MessageLookupByLibrary.simpleMessage("Что то пошло не так!"), + "my_blog": MessageLookupByLibrary.simpleMessage("Мой блог"), + "my_diets": MessageLookupByLibrary.simpleMessage("Мои диеты"), + "my_plans": MessageLookupByLibrary.simpleMessage("Мои планы"), + "my_settings": MessageLookupByLibrary.simpleMessage("Мои настройки"), + "name_empty": MessageLookupByLibrary.simpleMessage( + "Имя пользователя обязательно для заполнения"), + "name_short": MessageLookupByLibrary.simpleMessage( + "В имени пользователя должно быть минимум 6 символов"), + "nicotine": MessageLookupByLibrary.simpleMessage("Никотин"), + "no": MessageLookupByLibrary.simpleMessage("Нет"), + "no_account": + MessageLookupByLibrary.simpleMessage("У меня нет аккаунта"), + "not_liked_groceries": + MessageLookupByLibrary.simpleMessage("Не любимые продукты"), + "ok": MessageLookupByLibrary.simpleMessage("Хорошо"), + "one_option": MessageLookupByLibrary.simpleMessage("1 опция"), + "option": MessageLookupByLibrary.simpleMessage("Опция"), + "option_content": + MessageLookupByLibrary.simpleMessage("Содержание опции"), + "option_content_hint_text": + MessageLookupByLibrary.simpleMessage("На связи 7 дней в неделю"), + "option_desc": MessageLookupByLibrary.simpleMessage("Описание опции"), + "option_desc_hint_text": MessageLookupByLibrary.simpleMessage( + "Этот план питания для похудения на 7 дней сбалансированный и разнообразный"), + "option_duration": + MessageLookupByLibrary.simpleMessage("Продолжительность опции"), + "option_personal_diet_desc": MessageLookupByLibrary.simpleMessage( + "Опция подразумевает создание индивидуальной диеты"), + "option_title": MessageLookupByLibrary.simpleMessage("Заголовок опции"), + "order": MessageLookupByLibrary.simpleMessage("Порядок"), + "other": MessageLookupByLibrary.simpleMessage("Другое"), + "other_info": MessageLookupByLibrary.simpleMessage("Прочая информация"), + "password": MessageLookupByLibrary.simpleMessage("Пароль"), + "password_confirmation": + MessageLookupByLibrary.simpleMessage("Подтвердите пароль"), + "password_confirmation_mismatch": + MessageLookupByLibrary.simpleMessage("Пароли не совпадают"), + "password_empty": MessageLookupByLibrary.simpleMessage( + "Пароль обязателен для заполнения"), + "password_short": MessageLookupByLibrary.simpleMessage( + "В пароле должно быть минимум 6 символов"), + "pay": MessageLookupByLibrary.simpleMessage("Оплатить"), + "pcs": MessageLookupByLibrary.simpleMessage("шт"), + "personal": MessageLookupByLibrary.simpleMessage("Персональные"), + "personal_diet_state": + MessageLookupByLibrary.simpleMessage("Персональная"), + "photo": MessageLookupByLibrary.simpleMessage("Фото"), + "physical_fitness": + MessageLookupByLibrary.simpleMessage("Физическая форма"), + "place_of_living": + MessageLookupByLibrary.simpleMessage("Место проживания"), + "plan_author": MessageLookupByLibrary.simpleMessage("Автор плана"), + "plan_desc": MessageLookupByLibrary.simpleMessage("Описание плана"), + "plan_desc_example": MessageLookupByLibrary.simpleMessage( + "Большое подробное, привлекательное описание плана"), + "plan_duration": MessageLookupByLibrary.simpleMessage("Срок плана"), + "plan_label_desc": + MessageLookupByLibrary.simpleMessage("План для поддержания формы"), + "plan_type": MessageLookupByLibrary.simpleMessage("Тип плана"), + "plans_complete": + MessageLookupByLibrary.simpleMessage("Пройденные планы"), + "please_try_again_later": MessageLookupByLibrary.simpleMessage( + "Пожалуйста, попробуйте еще раз позже"), + "popular": MessageLookupByLibrary.simpleMessage("Популярные"), + "preferred_language": + MessageLookupByLibrary.simpleMessage("Предпочитаемый язык общения"), + "pressure": MessageLookupByLibrary.simpleMessage("Давление"), + "pressure_empty": MessageLookupByLibrary.simpleMessage( + "Все показатели давления обязательны к заполнению"), + "pressure_is_not_a_number": MessageLookupByLibrary.simpleMessage( + "Все показатели давления должны быть числами"), + "preview": MessageLookupByLibrary.simpleMessage("Превью"), + "price": MessageLookupByLibrary.simpleMessage("Цена"), + "price_explanation": MessageLookupByLibrary.simpleMessage( + "Разница в ценах, это комиссия Итвио"), + "profile": MessageLookupByLibrary.simpleMessage("Профиль"), + "prostitution": MessageLookupByLibrary.simpleMessage("Проституция"), + "proteins": MessageLookupByLibrary.simpleMessage("Белки"), + "publish": MessageLookupByLibrary.simpleMessage("Опубликовать"), + "published": MessageLookupByLibrary.simpleMessage("Опубликованные"), + "published_diets_count": + MessageLookupByLibrary.simpleMessage("Кол-во опубликованных диет"), + "published_posts_count": MessageLookupByLibrary.simpleMessage( + "Количество опубликованных постов"), + "published_recipes_count": MessageLookupByLibrary.simpleMessage( + "Кол-во опубликованных рецептов"), + "rating_and_statistics": + MessageLookupByLibrary.simpleMessage("Рейтинг и статистика"), + "rating_history": + MessageLookupByLibrary.simpleMessage("Начисление рейтинга"), + "recipe_author": MessageLookupByLibrary.simpleMessage("Автор рецепта"), + "recipe_publishing": + MessageLookupByLibrary.simpleMessage("Публикация рецепта"), + "refuse_order": + MessageLookupByLibrary.simpleMessage("Отказаться от заказа"), + "removeFromActive": + MessageLookupByLibrary.simpleMessage("Снять с публикации"), + "save": MessageLookupByLibrary.simpleMessage("Сохранить"), + "send_complain": + MessageLookupByLibrary.simpleMessage("Отправить жалобу"), + "services": MessageLookupByLibrary.simpleMessage("Оказание услуг"), + "settings": MessageLookupByLibrary.simpleMessage("Настройки"), + "sex": MessageLookupByLibrary.simpleMessage("Пол"), + "share": MessageLookupByLibrary.simpleMessage("Поделиться"), + "skip": MessageLookupByLibrary.simpleMessage("Пропустить"), + "slim": MessageLookupByLibrary.simpleMessage("Похудение"), + "slim_type": MessageLookupByLibrary.simpleMessage("Похудение"), + "slim_type_desc": MessageLookupByLibrary.simpleMessage( + "План питания для похудения должен быть разработан с учётом индивидуальных особенностей организма, возраста, пола, уровня физической активности и состояния здоровья. Общие принципы: \n● Снижение калорийности; \n● Сбалансированный рацион; \n● Разнообразие продуктов; \n● Питьевой режим; \n● Ограничение вредных продуктов;"), + "some_error_occurred": + MessageLookupByLibrary.simpleMessage("Упс! Произошла ошибка"), + "some_error_occurred_description": MessageLookupByLibrary.simpleMessage( + "Произошла ошибка. Мы уже работаем над ее устранением. Попробуйте позже."), + "something_went_wrong": + MessageLookupByLibrary.simpleMessage("Упс! Что-то пошло не так"), + "spam": MessageLookupByLibrary.simpleMessage("Спам"), + "spam_description": MessageLookupByLibrary.simpleMessage( + "Отправьте жалобу, если Вы заметили рекламу, размещенную в не предназначенном для этого месте."), + "sport_hobbies": + MessageLookupByLibrary.simpleMessage("Спортивные увлечения"), + "stage": MessageLookupByLibrary.simpleMessage("этап"), + "stages": MessageLookupByLibrary.simpleMessage("этапов"), + "standard": MessageLookupByLibrary.simpleMessage("Стандарт"), + "startDiet": MessageLookupByLibrary.simpleMessage("Начать диету"), + "statistic": MessageLookupByLibrary.simpleMessage("Статистика"), + "step": MessageLookupByLibrary.simpleMessage("Шаг"), + "step_by_step_photo_recipe": + MessageLookupByLibrary.simpleMessage("Пошаговый фоторецепт"), + "successfully_published": + MessageLookupByLibrary.simpleMessage("успешно опубликован"), + "suicide": + MessageLookupByLibrary.simpleMessage("Склонение к самоубийству"), + "takes_pills": + MessageLookupByLibrary.simpleMessage("Принимает лекарства"), + "tell_your_schedule": MessageLookupByLibrary.simpleMessage( + "Расскажите в свободной форме о том как просыпаетесь, когда едите, когда ложитесь спать:"), + "there_is_a_video": MessageLookupByLibrary.simpleMessage("Есть видео"), + "three_options": MessageLookupByLibrary.simpleMessage("3 опции"), + "time": MessageLookupByLibrary.simpleMessage("Время прохождения"), + "toOffer": MessageLookupByLibrary.simpleMessage("Предложить"), + "to_draft": MessageLookupByLibrary.simpleMessage("В черновик"), + "to_order": MessageLookupByLibrary.simpleMessage("Заказать"), + "try_again": MessageLookupByLibrary.simpleMessage("Попробовать снова"), + "type_here_your_complaint": + MessageLookupByLibrary.simpleMessage("Напишите здесь свою жалобу"), + "unfavorite_foods": + MessageLookupByLibrary.simpleMessage("Нелюбимые продукты"), + "up_pressure": MessageLookupByLibrary.simpleMessage( + "Верхние показатели давления:"), + "upper": MessageLookupByLibrary.simpleMessage("Верхнее"), + "user_authorization": + MessageLookupByLibrary.simpleMessage("Аутентификация"), + "user_data": + MessageLookupByLibrary.simpleMessage("Данные пользователя"), + "user_registration": + MessageLookupByLibrary.simpleMessage("Регистрация пользователя"), + "username": MessageLookupByLibrary.simpleMessage("Имя пользователя"), + "vegan": MessageLookupByLibrary.simpleMessage("Веган."), + "vegan_type": MessageLookupByLibrary.simpleMessage("Вегетарианская"), + "vegan_type_desc": MessageLookupByLibrary.simpleMessage( + "Диета основана на потреблении растительной пищи и отказе от продуктов животного происхождения. Такой тип питания может быть разнообразным и вкусным, а также полезным для здоровья."), + "violenceAndHostility": + MessageLookupByLibrary.simpleMessage("Насилие и вражда"), + "violence_against_people_or_animal": + MessageLookupByLibrary.simpleMessage( + "Насилие над людьми или животными"), + "waist": MessageLookupByLibrary.simpleMessage("Талия"), + "waist_circumference": + MessageLookupByLibrary.simpleMessage("Обхват талии"), + "weapon": MessageLookupByLibrary.simpleMessage("Оружие"), + "weight": MessageLookupByLibrary.simpleMessage("Вес"), + "weight_chart": MessageLookupByLibrary.simpleMessage("График веса"), + "weight_measurements": + MessageLookupByLibrary.simpleMessage("Замер веса"), + "wellness": + MessageLookupByLibrary.simpleMessage("Улучшение самочувствия"), + "wellness_type": + MessageLookupByLibrary.simpleMessage("Улучшение самочувствия"), + "wellness_type_desc": MessageLookupByLibrary.simpleMessage( + "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы."), + "what_do_you_want_to_complaint_about": + MessageLookupByLibrary.simpleMessage( + "На что Вы хотите пожаловаться?"), + "what_is_your_name": + MessageLookupByLibrary.simpleMessage("Как вас зовут?"), + "wrong_credentials": MessageLookupByLibrary.simpleMessage( + "Неверные данные пользователя"), + "you_will_get": MessageLookupByLibrary.simpleMessage("Вы получите"), + "your_blood_pressure": + MessageLookupByLibrary.simpleMessage("Ваше артериальное давление?"), + "your_favorite_sports": + MessageLookupByLibrary.simpleMessage("Ваши спортивные увлечения?"), + "your_gender": MessageLookupByLibrary.simpleMessage("Ваш пол?"), + "your_height": MessageLookupByLibrary.simpleMessage("Ваш рост:"), + "your_rating": MessageLookupByLibrary.simpleMessage("Ваш рейтинг"), + "your_schedule": MessageLookupByLibrary.simpleMessage("Ваш режим дня?"), + "your_weight": MessageLookupByLibrary.simpleMessage("Ваш вес:") + }; } diff --git a/lib/generated/intl/messages_ru.dart b/lib/generated/intl/messages_ru.dart index 914d96c1..32433d08 100644 --- a/lib/generated/intl/messages_ru.dart +++ b/lib/generated/intl/messages_ru.dart @@ -22,353 +22,301 @@ class MessageLookup extends MessageLookupByLibrary { final messages = _notInlinedMessages(_notInlinedMessages); static Map _notInlinedMessages(_) => { - "Moscow": MessageLookupByLibrary.simpleMessage("Москва"), - "Russia": MessageLookupByLibrary.simpleMessage("Россия"), - "about_diet": MessageLookupByLibrary.simpleMessage("Об этой диете"), - "about_plan": MessageLookupByLibrary.simpleMessage("Об этом плане"), - "active": MessageLookupByLibrary.simpleMessage("Активен"), - "active_diet_state": MessageLookupByLibrary.simpleMessage("Активная"), - "add": MessageLookupByLibrary.simpleMessage("Добавить"), - "add_cover": MessageLookupByLibrary.simpleMessage("Добавьте обложку"), - "add_measure": MessageLookupByLibrary.simpleMessage("Добавить замер"), - "adding_plan": MessageLookupByLibrary.simpleMessage("Добавление плана"), - "additional_information": MessageLookupByLibrary.simpleMessage( - "Дополнительная информация", - ), - "admin": MessageLookupByLibrary.simpleMessage("Админ"), - "all": MessageLookupByLibrary.simpleMessage("Все"), - "allergies_presence": MessageLookupByLibrary.simpleMessage( - "Наличие аллергии", - ), - "another_form_of_comment": MessageLookupByLibrary.simpleMessage( - "комментария", - ), - "another_form_of_day": MessageLookupByLibrary.simpleMessage("дня"), - "answer": MessageLookupByLibrary.simpleMessage("Ответить"), - "archived": MessageLookupByLibrary.simpleMessage("В архиве"), - "authentificate": MessageLookupByLibrary.simpleMessage("Войти"), - "average_pressure": MessageLookupByLibrary.simpleMessage( - "Средние показатели давления:", - ), - "bodymass_chart": MessageLookupByLibrary.simpleMessage("График ИМТ"), - "by_default": MessageLookupByLibrary.simpleMessage("По умолчянию"), - "calories": MessageLookupByLibrary.simpleMessage("Калории"), - "carb_type": MessageLookupByLibrary.simpleMessage("Мучное"), - "carb_type_desc": MessageLookupByLibrary.simpleMessage( - "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы.", - ), - "carbohydrates": MessageLookupByLibrary.simpleMessage("Углеводы"), - "chat": MessageLookupByLibrary.simpleMessage("Чат"), - "chest": MessageLookupByLibrary.simpleMessage("Грудь"), - "chest_circumference": MessageLookupByLibrary.simpleMessage("Обхват груди"), - "choose_diet_duration": MessageLookupByLibrary.simpleMessage( - "Выберите срок диеты", - ), - "choose_plan_duration": 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("Город"), - "city_of_living": MessageLookupByLibrary.simpleMessage("Город проживания"), - "comfort": MessageLookupByLibrary.simpleMessage("Комфорт"), - "comment": MessageLookupByLibrary.simpleMessage("комментарий"), - "comments": MessageLookupByLibrary.simpleMessage("Комментарии"), - "comments_plural": MessageLookupByLibrary.simpleMessage("комментариев"), - "complain": MessageLookupByLibrary.simpleMessage("Пожаловаться"), - "continueButton": MessageLookupByLibrary.simpleMessage("Продолжить"), - "continue_": MessageLookupByLibrary.simpleMessage("Продолжить"), - "copied": MessageLookupByLibrary.simpleMessage("cкопирован"), - "copy_link": MessageLookupByLibrary.simpleMessage("Скопировать ссылку"), - "country": MessageLookupByLibrary.simpleMessage("Страна"), - "create_diet": MessageLookupByLibrary.simpleMessage("Создание диеты"), - "customer_price": MessageLookupByLibrary.simpleMessage( - "Цена для покупателя", - ), - "date_of_birth": MessageLookupByLibrary.simpleMessage("Дата рождения"), - "day": MessageLookupByLibrary.simpleMessage("День"), - "days": MessageLookupByLibrary.simpleMessage("дней"), - "deleted": MessageLookupByLibrary.simpleMessage("Удалена"), - "diary": MessageLookupByLibrary.simpleMessage("Дневник"), - "diet": MessageLookupByLibrary.simpleMessage("Диета"), - "diet_author": MessageLookupByLibrary.simpleMessage("Автор диеты"), - "diet_plan": MessageLookupByLibrary.simpleMessage("План диеты"), - "diet_state": 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("Черновик"), - "drafted": MessageLookupByLibrary.simpleMessage("Черновики"), - "eating_behavior": MessageLookupByLibrary.simpleMessage( - "Пищевое поведение", - ), - "eating_behavior_type": MessageLookupByLibrary.simpleMessage( - "Формирование пищевого поведения", - ), - "eating_behavior_type_desc": MessageLookupByLibrary.simpleMessage( - "Формирование здорового пищевого поведения — это процесс, который включает в себя изменение привычек и отношения к еде. Он направлен на то, чтобы помочь людям научиться правильно питаться и поддерживать здоровый образ жизни.Основные принципы формирования здорового пищевого поведения: \n● Разнообразие продуктов; \n● Сбалансированный рацион; \n● Питьевой режим; \n● Ограничение вредных продуктов; \n● Регулярные приёмы пищи; \n● Умеренность;Осознанное питание; \n● Физическая активность;", - ), - "economy": MessageLookupByLibrary.simpleMessage("Эконом"), - "edit": MessageLookupByLibrary.simpleMessage("Редактировать"), - "email": MessageLookupByLibrary.simpleMessage("Электронная почта"), - "email_empty": MessageLookupByLibrary.simpleMessage( - "Необходимо ввести адрес электронной почты", - ), - "email_invalid": MessageLookupByLibrary.simpleMessage( - "Некорректный адрес электронной почты", - ), - "enter_additional_information": MessageLookupByLibrary.simpleMessage( - "Введите любую дополнительную информацию на своё усмотрение:", - ), - "enter_diet_description": MessageLookupByLibrary.simpleMessage( - "Введите описание диеты", - ), - "enter_diet_name": MessageLookupByLibrary.simpleMessage( - "Выведите название диеты", - ), - "enter_information": MessageLookupByLibrary.simpleMessage( - "Введите информацию...", - ), - "exit": MessageLookupByLibrary.simpleMessage("Выйти"), - "expand": MessageLookupByLibrary.simpleMessage("Показать полностью"), - "fats": MessageLookupByLibrary.simpleMessage("Жиры"), - "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 символ", - ), - "fit_type": MessageLookupByLibrary.simpleMessage("Поддержание формы"), - "fit_type_desc": MessageLookupByLibrary.simpleMessage( - "План питания для поддержания формы сбалансированный и разнообразный, чтобы обеспечить организм всеми необходимыми питательными веществами. Общие принципы: \n● Дробное питание; \n● Разнообразие продуктов; \n● Контроль порций; \n● Питьевой режим; \n● Ограничение вредных продуктов;", - ), - "fitness": MessageLookupByLibrary.simpleMessage("Поддержка формы"), - "from": MessageLookupByLibrary.simpleMessage("от"), - "from_a_to_z": MessageLookupByLibrary.simpleMessage("Название: А-Я"), - "from_z_to_a": MessageLookupByLibrary.simpleMessage("Название: Я-А"), - "gallery": MessageLookupByLibrary.simpleMessage("Галерея"), - "gr": MessageLookupByLibrary.simpleMessage("гр"), - "grams": MessageLookupByLibrary.simpleMessage("гр"), - "height_measurements": MessageLookupByLibrary.simpleMessage("Замер роста"), - "hide": MessageLookupByLibrary.simpleMessage("Свернуть"), - "hip_circumference": MessageLookupByLibrary.simpleMessage("Обхват бедер"), - "hips": MessageLookupByLibrary.simpleMessage("Бедра"), - "in_progress": MessageLookupByLibrary.simpleMessage("В процессе"), - "inactive_diet_state": MessageLookupByLibrary.simpleMessage("Черновик"), - "infoAboutOrder": MessageLookupByLibrary.simpleMessage( - "Информация о заказе", - ), - "initial_measurements": MessageLookupByLibrary.simpleMessage( - "Первичные замеры", - ), - "label": MessageLookupByLibrary.simpleMessage("Название"), - "language": MessageLookupByLibrary.simpleMessage("Язык"), - "last_name": MessageLookupByLibrary.simpleMessage("Фамилия"), - "last_name_empty": MessageLookupByLibrary.simpleMessage( - "Фамилия обязательна для заполнения", - ), - "last_name_short": MessageLookupByLibrary.simpleMessage( - "В фамилии должен быть минимум 6 символов", - ), - "lbl_english": MessageLookupByLibrary.simpleMessage("English"), - "light_type": MessageLookupByLibrary.simpleMessage("Легкая"), - "light_type_desc": MessageLookupByLibrary.simpleMessage( - "С некоторыми видами диет можно употреблять алкоголь в умеренных количествах. Рекомендуется совмещать вместе с низкокалорийными закусками.", - ), - "link_was_copied": MessageLookupByLibrary.simpleMessage( - "Ссылка успешно скопирована", - ), - "loading": MessageLookupByLibrary.simpleMessage("Загрузка..."), - "male": MessageLookupByLibrary.simpleMessage("Мужской"), - "meal": MessageLookupByLibrary.simpleMessage("Приём пищи"), - "meat": MessageLookupByLibrary.simpleMessage("Мясо"), - "meat_type": MessageLookupByLibrary.simpleMessage("С мясом"), - "meat_type_desc": MessageLookupByLibrary.simpleMessage( - "Диета с мясом полезная и сбалансированная. Включает в себя нежирное мясо: курицу, индейку, кролика или говядину. В сочетании с овощами получаете все необходимые витамины и минералы. Не забывайте о порциях и старайтесь есть медленно, прислушиваясь к своему организму.", - ), - "milliliter": MessageLookupByLibrary.simpleMessage("мл"), - "minimal_customer_price": MessageLookupByLibrary.simpleMessage( - "Минимальная цена для покупателя: 1200₽", - ), - "most_new": MessageLookupByLibrary.simpleMessage("Самые новые"), - "most_old": MessageLookupByLibrary.simpleMessage("Самые старые"), - "msg_network_err": MessageLookupByLibrary.simpleMessage("Сетевая ошибка!"), - "msg_something_went_wrong": MessageLookupByLibrary.simpleMessage( - "Что то пошло не так!", - ), - "my_blog": MessageLookupByLibrary.simpleMessage("Мой блог"), - "my_diets": MessageLookupByLibrary.simpleMessage("Мои диеты"), - "my_plans": MessageLookupByLibrary.simpleMessage("Мои планы"), - "my_settings": MessageLookupByLibrary.simpleMessage("Мои настройки"), - "name_empty": MessageLookupByLibrary.simpleMessage( - "Имя пользователя обязательно для заполнения", - ), - "name_short": MessageLookupByLibrary.simpleMessage( - "В имени пользователя должно быть минимум 6 символов", - ), - "no": MessageLookupByLibrary.simpleMessage("Нет"), - "no_account": MessageLookupByLibrary.simpleMessage("У меня нет аккаунта"), - "one_option": MessageLookupByLibrary.simpleMessage("1 опция"), - "option": MessageLookupByLibrary.simpleMessage("Опция"), - "option_content": MessageLookupByLibrary.simpleMessage("Содержание опции"), - "option_content_hint_text": MessageLookupByLibrary.simpleMessage( - "На связи 7 дней в неделю", - ), - "option_desc": MessageLookupByLibrary.simpleMessage("Описание опции"), - "option_desc_hint_text": MessageLookupByLibrary.simpleMessage( - "Этот план питания для похудения на 7 дней сбалансированный и разнообразный", - ), - "option_duration": MessageLookupByLibrary.simpleMessage( - "Продолжительность опции", - ), - "option_personal_diet_desc": MessageLookupByLibrary.simpleMessage( - "Опция подразумевает создание индивидуальной диеты", - ), - "option_title": 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 символов", - ), - "pcs": MessageLookupByLibrary.simpleMessage("шт"), - "personal": MessageLookupByLibrary.simpleMessage("Персональные"), - "personal_diet_state": MessageLookupByLibrary.simpleMessage("Персональная"), - "photo": MessageLookupByLibrary.simpleMessage("Фото"), - "place_of_living": MessageLookupByLibrary.simpleMessage("Место проживания"), - "plan_author": MessageLookupByLibrary.simpleMessage("Автор плана"), - "plan_desc": MessageLookupByLibrary.simpleMessage("Описание плана"), - "plan_desc_example": MessageLookupByLibrary.simpleMessage( - "Большое подробное, привлекательное описание плана", - ), - "plan_duration": MessageLookupByLibrary.simpleMessage("Срок плана"), - "plan_label_desc": MessageLookupByLibrary.simpleMessage( - "План для поддержания формы", - ), - "plans_complete": MessageLookupByLibrary.simpleMessage("Пройденные планы"), - "popular": MessageLookupByLibrary.simpleMessage("Популярные"), - "preferred_language": MessageLookupByLibrary.simpleMessage( - "Предпочитаемый язык общения", - ), - "pressure_empty": MessageLookupByLibrary.simpleMessage( - "Все показатели давления обязательны к заполнению", - ), - "pressure_is_not_a_number": MessageLookupByLibrary.simpleMessage( - "Все показатели давления должны быть числами", - ), - "preview": MessageLookupByLibrary.simpleMessage("Превью"), - "price": MessageLookupByLibrary.simpleMessage("Цена"), - "price_explanation": MessageLookupByLibrary.simpleMessage( - "Разница в ценах, это комиссия Итвио", - ), - "profile": MessageLookupByLibrary.simpleMessage("Профиль"), - "proteins": MessageLookupByLibrary.simpleMessage("Белки"), - "publish": MessageLookupByLibrary.simpleMessage("Опубликовать"), - "published": MessageLookupByLibrary.simpleMessage("Опубликованные"), - "removeFromActive": MessageLookupByLibrary.simpleMessage( - "Снять с публикации", - ), - "save": MessageLookupByLibrary.simpleMessage("Сохранить"), - "services": MessageLookupByLibrary.simpleMessage("Оказание услуг"), - "settings": MessageLookupByLibrary.simpleMessage("Настройки"), - "share": MessageLookupByLibrary.simpleMessage("Поделиться"), - "skip": MessageLookupByLibrary.simpleMessage("Пропустить"), - "slim": MessageLookupByLibrary.simpleMessage("Похудение"), - "slim_type": MessageLookupByLibrary.simpleMessage("Похудение"), - "slim_type_desc": MessageLookupByLibrary.simpleMessage( - "План питания для похудения должен быть разработан с учётом индивидуальных особенностей организма, возраста, пола, уровня физической активности и состояния здоровья. Общие принципы: \n● Снижение калорийности; \n● Сбалансированный рацион; \n● Разнообразие продуктов; \n● Питьевой режим; \n● Ограничение вредных продуктов;", - ), - "standard": MessageLookupByLibrary.simpleMessage("Стандарт"), - "startDiet": MessageLookupByLibrary.simpleMessage("Начать диету"), - "tell_your_schedule": MessageLookupByLibrary.simpleMessage( - "Расскажите в свободной форме о том как просыпаетесь, когда едите, когда ложитесь спать:", - ), - "three_options": MessageLookupByLibrary.simpleMessage("3 опции"), - "toOffer": MessageLookupByLibrary.simpleMessage("Предложить"), - "to_draft": MessageLookupByLibrary.simpleMessage("В черновик"), - "unfavorite_foods": MessageLookupByLibrary.simpleMessage( - "Нелюбимые продукты", - ), - "up_pressure": MessageLookupByLibrary.simpleMessage( - "Верхние показатели давления:", - ), - "user_authorization": MessageLookupByLibrary.simpleMessage( - "Аутентификация", - ), - "user_data": MessageLookupByLibrary.simpleMessage("Данные пользователя"), - "user_registration": MessageLookupByLibrary.simpleMessage( - "Регистрация пользователя", - ), - "username": MessageLookupByLibrary.simpleMessage("Имя пользователя"), - "vegan": MessageLookupByLibrary.simpleMessage("Веган."), - "vegan_type": MessageLookupByLibrary.simpleMessage("Вегетарианская"), - "vegan_type_desc": MessageLookupByLibrary.simpleMessage( - "Диета основана на потреблении растительной пищи и отказе от продуктов животного происхождения. Такой тип питания может быть разнообразным и вкусным, а также полезным для здоровья.", - ), - "waist": MessageLookupByLibrary.simpleMessage("Талия"), - "waist_circumference": MessageLookupByLibrary.simpleMessage("Обхват талии"), - "weight": MessageLookupByLibrary.simpleMessage("Вес"), - "weight_chart": MessageLookupByLibrary.simpleMessage("График веса"), - "weight_measurements": MessageLookupByLibrary.simpleMessage("Замер веса"), - "wellness": MessageLookupByLibrary.simpleMessage("Улучшение самочувствия"), - "wellness_type": MessageLookupByLibrary.simpleMessage( - "Улучшение самочувствия", - ), - "wellness_type_desc": MessageLookupByLibrary.simpleMessage( - "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы.", - ), - "what_is_your_name": MessageLookupByLibrary.simpleMessage("Как вас зовут?"), - "wrong_credentials": MessageLookupByLibrary.simpleMessage( - "Неверные данные пользователя", - ), - "you_will_get": MessageLookupByLibrary.simpleMessage("Вы получите"), - "your_blood_pressure": MessageLookupByLibrary.simpleMessage( - "Ваше артериальное давление?", - ), - "your_favorite_sports": MessageLookupByLibrary.simpleMessage( - "Ваши спортивные увлечения?", - ), - "your_gender": MessageLookupByLibrary.simpleMessage("Ваш пол?"), - "your_height": MessageLookupByLibrary.simpleMessage("Ваш рост:"), - "your_schedule": MessageLookupByLibrary.simpleMessage("Ваш режим дня?"), - "your_weight": MessageLookupByLibrary.simpleMessage("Ваш вес:"), - }; + "Moscow": MessageLookupByLibrary.simpleMessage("Москва"), + "Russia": MessageLookupByLibrary.simpleMessage("Россия"), + "about_diet": MessageLookupByLibrary.simpleMessage("Об этой диете"), + "about_plan": MessageLookupByLibrary.simpleMessage("Об этом плане"), + "active": MessageLookupByLibrary.simpleMessage("Активен"), + "active_diet_state": MessageLookupByLibrary.simpleMessage("Активная"), + "add": MessageLookupByLibrary.simpleMessage("Добавить"), + "add_cover": MessageLookupByLibrary.simpleMessage("Добавьте обложку"), + "add_measure": MessageLookupByLibrary.simpleMessage("Добавить замер"), + "adding_plan": MessageLookupByLibrary.simpleMessage("Добавление плана"), + "additional_information": + MessageLookupByLibrary.simpleMessage("Дополнительная информация"), + "admin": MessageLookupByLibrary.simpleMessage("Админ"), + "all": MessageLookupByLibrary.simpleMessage("Все"), + "allergies_presence": + MessageLookupByLibrary.simpleMessage("Наличие аллергии"), + "another_form_of_comment": + MessageLookupByLibrary.simpleMessage("комментария"), + "another_form_of_day": MessageLookupByLibrary.simpleMessage("дня"), + "answer": MessageLookupByLibrary.simpleMessage("Ответить"), + "archived": MessageLookupByLibrary.simpleMessage("В архиве"), + "authentificate": MessageLookupByLibrary.simpleMessage("Войти"), + "average_pressure": MessageLookupByLibrary.simpleMessage( + "Средние показатели давления:"), + "bodymass_chart": MessageLookupByLibrary.simpleMessage("График ИМТ"), + "by_default": MessageLookupByLibrary.simpleMessage("По умолчянию"), + "calories": MessageLookupByLibrary.simpleMessage("Калории"), + "carb_type": MessageLookupByLibrary.simpleMessage("Мучное"), + "carb_type_desc": MessageLookupByLibrary.simpleMessage( + "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы."), + "carbohydrates": MessageLookupByLibrary.simpleMessage("Углеводы"), + "chat": MessageLookupByLibrary.simpleMessage("Чат"), + "chest": MessageLookupByLibrary.simpleMessage("Грудь"), + "chest_circumference": + MessageLookupByLibrary.simpleMessage("Обхват груди"), + "choose_diet_duration": + MessageLookupByLibrary.simpleMessage("Выберите срок диеты"), + "choose_plan_duration": + 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("Город"), + "city_of_living": + MessageLookupByLibrary.simpleMessage("Город проживания"), + "comfort": MessageLookupByLibrary.simpleMessage("Комфорт"), + "comment": MessageLookupByLibrary.simpleMessage("комментарий"), + "comments": MessageLookupByLibrary.simpleMessage("Комментарии"), + "comments_plural": MessageLookupByLibrary.simpleMessage("комментариев"), + "complain": MessageLookupByLibrary.simpleMessage("Пожаловаться"), + "continueButton": MessageLookupByLibrary.simpleMessage("Продолжить"), + "continue_": MessageLookupByLibrary.simpleMessage("Продолжить"), + "copied": MessageLookupByLibrary.simpleMessage("cкопирован"), + "copy_link": MessageLookupByLibrary.simpleMessage("Скопировать ссылку"), + "country": MessageLookupByLibrary.simpleMessage("Страна"), + "create_diet": MessageLookupByLibrary.simpleMessage("Создание диеты"), + "customer_price": + MessageLookupByLibrary.simpleMessage("Цена для покупателя"), + "date_of_birth": MessageLookupByLibrary.simpleMessage("Дата рождения"), + "day": MessageLookupByLibrary.simpleMessage("День"), + "days": MessageLookupByLibrary.simpleMessage("дней"), + "deleted": MessageLookupByLibrary.simpleMessage("Удалена"), + "diary": MessageLookupByLibrary.simpleMessage("Дневник"), + "diet": MessageLookupByLibrary.simpleMessage("Диета"), + "diet_author": MessageLookupByLibrary.simpleMessage("Автор диеты"), + "diet_plan": MessageLookupByLibrary.simpleMessage("План диеты"), + "diet_state": 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("Черновик"), + "drafted": MessageLookupByLibrary.simpleMessage("Черновики"), + "eating_behavior": + MessageLookupByLibrary.simpleMessage("Пищевое поведение"), + "eating_behavior_type": MessageLookupByLibrary.simpleMessage( + "Формирование пищевого поведения"), + "eating_behavior_type_desc": MessageLookupByLibrary.simpleMessage( + "Формирование здорового пищевого поведения — это процесс, который включает в себя изменение привычек и отношения к еде. Он направлен на то, чтобы помочь людям научиться правильно питаться и поддерживать здоровый образ жизни.Основные принципы формирования здорового пищевого поведения: \n● Разнообразие продуктов; \n● Сбалансированный рацион; \n● Питьевой режим; \n● Ограничение вредных продуктов; \n● Регулярные приёмы пищи; \n● Умеренность;Осознанное питание; \n● Физическая активность;"), + "economy": MessageLookupByLibrary.simpleMessage("Эконом"), + "edit": MessageLookupByLibrary.simpleMessage("Редактировать"), + "email": MessageLookupByLibrary.simpleMessage("Электронная почта"), + "email_empty": MessageLookupByLibrary.simpleMessage( + "Необходимо ввести адрес электронной почты"), + "email_invalid": MessageLookupByLibrary.simpleMessage( + "Некорректный адрес электронной почты"), + "enter_additional_information": MessageLookupByLibrary.simpleMessage( + "Введите любую дополнительную информацию на своё усмотрение:"), + "enter_diet_description": + MessageLookupByLibrary.simpleMessage("Введите описание диеты"), + "enter_diet_name": + MessageLookupByLibrary.simpleMessage("Выведите название диеты"), + "enter_information": + MessageLookupByLibrary.simpleMessage("Введите информацию..."), + "exit": MessageLookupByLibrary.simpleMessage("Выйти"), + "expand": MessageLookupByLibrary.simpleMessage("Показать полностью"), + "fats": MessageLookupByLibrary.simpleMessage("Жиры"), + "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 символ"), + "fit_type": MessageLookupByLibrary.simpleMessage("Поддержание формы"), + "fit_type_desc": MessageLookupByLibrary.simpleMessage( + "План питания для поддержания формы сбалансированный и разнообразный, чтобы обеспечить организм всеми необходимыми питательными веществами. Общие принципы: \n● Дробное питание; \n● Разнообразие продуктов; \n● Контроль порций; \n● Питьевой режим; \n● Ограничение вредных продуктов;"), + "fitness": MessageLookupByLibrary.simpleMessage("Поддержка формы"), + "from": MessageLookupByLibrary.simpleMessage("от"), + "from_a_to_z": MessageLookupByLibrary.simpleMessage("Название: А-Я"), + "from_z_to_a": MessageLookupByLibrary.simpleMessage("Название: Я-А"), + "gallery": MessageLookupByLibrary.simpleMessage("Галерея"), + "gr": MessageLookupByLibrary.simpleMessage("гр"), + "grams": MessageLookupByLibrary.simpleMessage("гр"), + "height_measurements": + MessageLookupByLibrary.simpleMessage("Замер роста"), + "hide": MessageLookupByLibrary.simpleMessage("Свернуть"), + "hip_circumference": + MessageLookupByLibrary.simpleMessage("Обхват бедер"), + "hips": MessageLookupByLibrary.simpleMessage("Бедра"), + "in_progress": MessageLookupByLibrary.simpleMessage("В процессе"), + "inactive_diet_state": MessageLookupByLibrary.simpleMessage("Черновик"), + "infoAboutOrder": + MessageLookupByLibrary.simpleMessage("Информация о заказе"), + "initial_measurements": + MessageLookupByLibrary.simpleMessage("Первичные замеры"), + "label": MessageLookupByLibrary.simpleMessage("Название"), + "language": MessageLookupByLibrary.simpleMessage("Язык"), + "last_name": MessageLookupByLibrary.simpleMessage("Фамилия"), + "last_name_empty": MessageLookupByLibrary.simpleMessage( + "Фамилия обязательна для заполнения"), + "last_name_short": MessageLookupByLibrary.simpleMessage( + "В фамилии должен быть минимум 6 символов"), + "lbl_english": MessageLookupByLibrary.simpleMessage("English"), + "light_type": MessageLookupByLibrary.simpleMessage("Легкая"), + "light_type_desc": MessageLookupByLibrary.simpleMessage( + "С некоторыми видами диет можно употреблять алкоголь в умеренных количествах. Рекомендуется совмещать вместе с низкокалорийными закусками."), + "link_was_copied": + MessageLookupByLibrary.simpleMessage("Ссылка успешно скопирована"), + "loading": MessageLookupByLibrary.simpleMessage("Загрузка..."), + "male": MessageLookupByLibrary.simpleMessage("Мужской"), + "meal": MessageLookupByLibrary.simpleMessage("Приём пищи"), + "meat": MessageLookupByLibrary.simpleMessage("Мясо"), + "meat_type": MessageLookupByLibrary.simpleMessage("С мясом"), + "meat_type_desc": MessageLookupByLibrary.simpleMessage( + "Диета с мясом полезная и сбалансированная. Включает в себя нежирное мясо: курицу, индейку, кролика или говядину. В сочетании с овощами получаете все необходимые витамины и минералы. Не забывайте о порциях и старайтесь есть медленно, прислушиваясь к своему организму."), + "milliliter": MessageLookupByLibrary.simpleMessage("мл"), + "minimal_customer_price": MessageLookupByLibrary.simpleMessage( + "Минимальная цена для покупателя: 1200₽"), + "most_new": MessageLookupByLibrary.simpleMessage("Самые новые"), + "most_old": MessageLookupByLibrary.simpleMessage("Самые старые"), + "msg_network_err": + MessageLookupByLibrary.simpleMessage("Сетевая ошибка!"), + "msg_something_went_wrong": + MessageLookupByLibrary.simpleMessage("Что то пошло не так!"), + "my_blog": MessageLookupByLibrary.simpleMessage("Мой блог"), + "my_diets": MessageLookupByLibrary.simpleMessage("Мои диеты"), + "my_plans": MessageLookupByLibrary.simpleMessage("Мои планы"), + "my_settings": MessageLookupByLibrary.simpleMessage("Мои настройки"), + "name_empty": MessageLookupByLibrary.simpleMessage( + "Имя пользователя обязательно для заполнения"), + "name_short": MessageLookupByLibrary.simpleMessage( + "В имени пользователя должно быть минимум 6 символов"), + "no": MessageLookupByLibrary.simpleMessage("Нет"), + "no_account": + MessageLookupByLibrary.simpleMessage("У меня нет аккаунта"), + "one_option": MessageLookupByLibrary.simpleMessage("1 опция"), + "option": MessageLookupByLibrary.simpleMessage("Опция"), + "option_content": + MessageLookupByLibrary.simpleMessage("Содержание опции"), + "option_content_hint_text": + MessageLookupByLibrary.simpleMessage("На связи 7 дней в неделю"), + "option_desc": MessageLookupByLibrary.simpleMessage("Описание опции"), + "option_desc_hint_text": MessageLookupByLibrary.simpleMessage( + "Этот план питания для похудения на 7 дней сбалансированный и разнообразный"), + "option_duration": + MessageLookupByLibrary.simpleMessage("Продолжительность опции"), + "option_personal_diet_desc": MessageLookupByLibrary.simpleMessage( + "Опция подразумевает создание индивидуальной диеты"), + "option_title": 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 символов"), + "pcs": MessageLookupByLibrary.simpleMessage("шт"), + "personal": MessageLookupByLibrary.simpleMessage("Персональные"), + "personal_diet_state": + MessageLookupByLibrary.simpleMessage("Персональная"), + "photo": MessageLookupByLibrary.simpleMessage("Фото"), + "place_of_living": + MessageLookupByLibrary.simpleMessage("Место проживания"), + "plan_author": MessageLookupByLibrary.simpleMessage("Автор плана"), + "plan_desc": MessageLookupByLibrary.simpleMessage("Описание плана"), + "plan_desc_example": MessageLookupByLibrary.simpleMessage( + "Большое подробное, привлекательное описание плана"), + "plan_duration": MessageLookupByLibrary.simpleMessage("Срок плана"), + "plan_label_desc": + MessageLookupByLibrary.simpleMessage("План для поддержания формы"), + "plans_complete": + MessageLookupByLibrary.simpleMessage("Пройденные планы"), + "popular": MessageLookupByLibrary.simpleMessage("Популярные"), + "preferred_language": + MessageLookupByLibrary.simpleMessage("Предпочитаемый язык общения"), + "pressure_empty": MessageLookupByLibrary.simpleMessage( + "Все показатели давления обязательны к заполнению"), + "pressure_is_not_a_number": MessageLookupByLibrary.simpleMessage( + "Все показатели давления должны быть числами"), + "preview": MessageLookupByLibrary.simpleMessage("Превью"), + "price": MessageLookupByLibrary.simpleMessage("Цена"), + "price_explanation": MessageLookupByLibrary.simpleMessage( + "Разница в ценах, это комиссия Итвио"), + "profile": MessageLookupByLibrary.simpleMessage("Профиль"), + "proteins": MessageLookupByLibrary.simpleMessage("Белки"), + "publish": MessageLookupByLibrary.simpleMessage("Опубликовать"), + "published": MessageLookupByLibrary.simpleMessage("Опубликованные"), + "removeFromActive": + MessageLookupByLibrary.simpleMessage("Снять с публикации"), + "save": MessageLookupByLibrary.simpleMessage("Сохранить"), + "services": MessageLookupByLibrary.simpleMessage("Оказание услуг"), + "settings": MessageLookupByLibrary.simpleMessage("Настройки"), + "share": MessageLookupByLibrary.simpleMessage("Поделиться"), + "skip": MessageLookupByLibrary.simpleMessage("Пропустить"), + "slim": MessageLookupByLibrary.simpleMessage("Похудение"), + "slim_type": MessageLookupByLibrary.simpleMessage("Похудение"), + "slim_type_desc": MessageLookupByLibrary.simpleMessage( + "План питания для похудения должен быть разработан с учётом индивидуальных особенностей организма, возраста, пола, уровня физической активности и состояния здоровья. Общие принципы: \n● Снижение калорийности; \n● Сбалансированный рацион; \n● Разнообразие продуктов; \n● Питьевой режим; \n● Ограничение вредных продуктов;"), + "standard": MessageLookupByLibrary.simpleMessage("Стандарт"), + "startDiet": MessageLookupByLibrary.simpleMessage("Начать диету"), + "tell_your_schedule": MessageLookupByLibrary.simpleMessage( + "Расскажите в свободной форме о том как просыпаетесь, когда едите, когда ложитесь спать:"), + "three_options": MessageLookupByLibrary.simpleMessage("3 опции"), + "toOffer": MessageLookupByLibrary.simpleMessage("Предложить"), + "to_draft": MessageLookupByLibrary.simpleMessage("В черновик"), + "unfavorite_foods": + MessageLookupByLibrary.simpleMessage("Нелюбимые продукты"), + "up_pressure": MessageLookupByLibrary.simpleMessage( + "Верхние показатели давления:"), + "user_authorization": + MessageLookupByLibrary.simpleMessage("Аутентификация"), + "user_data": + MessageLookupByLibrary.simpleMessage("Данные пользователя"), + "user_registration": + MessageLookupByLibrary.simpleMessage("Регистрация пользователя"), + "username": MessageLookupByLibrary.simpleMessage("Имя пользователя"), + "vegan": MessageLookupByLibrary.simpleMessage("Веган."), + "vegan_type": MessageLookupByLibrary.simpleMessage("Вегетарианская"), + "vegan_type_desc": MessageLookupByLibrary.simpleMessage( + "Диета основана на потреблении растительной пищи и отказе от продуктов животного происхождения. Такой тип питания может быть разнообразным и вкусным, а также полезным для здоровья."), + "waist": MessageLookupByLibrary.simpleMessage("Талия"), + "waist_circumference": + MessageLookupByLibrary.simpleMessage("Обхват талии"), + "weight": MessageLookupByLibrary.simpleMessage("Вес"), + "weight_chart": MessageLookupByLibrary.simpleMessage("График веса"), + "weight_measurements": + MessageLookupByLibrary.simpleMessage("Замер веса"), + "wellness": + MessageLookupByLibrary.simpleMessage("Улучшение самочувствия"), + "wellness_type": + MessageLookupByLibrary.simpleMessage("Улучшение самочувствия"), + "wellness_type_desc": MessageLookupByLibrary.simpleMessage( + "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы."), + "what_is_your_name": + MessageLookupByLibrary.simpleMessage("Как вас зовут?"), + "wrong_credentials": MessageLookupByLibrary.simpleMessage( + "Неверные данные пользователя"), + "you_will_get": MessageLookupByLibrary.simpleMessage("Вы получите"), + "your_blood_pressure": + MessageLookupByLibrary.simpleMessage("Ваше артериальное давление?"), + "your_favorite_sports": + MessageLookupByLibrary.simpleMessage("Ваши спортивные увлечения?"), + "your_gender": MessageLookupByLibrary.simpleMessage("Ваш пол?"), + "your_height": MessageLookupByLibrary.simpleMessage("Ваш рост:"), + "your_schedule": MessageLookupByLibrary.simpleMessage("Ваш режим дня?"), + "your_weight": MessageLookupByLibrary.simpleMessage("Ваш вес:") + }; } diff --git a/lib/generated/l10n.dart b/lib/generated/l10n.dart index 88b93a40..10cb4a70 100644 --- a/lib/generated/l10n.dart +++ b/lib/generated/l10n.dart @@ -18,20 +18,17 @@ class S { static S? _current; static S get current { - assert( - _current != null, - 'No instance of S was loaded. Try to initialize the S delegate before accessing S.current.', - ); + assert(_current != null, + 'No instance of S was loaded. Try to initialize the S delegate before accessing S.current.'); return _current!; } static const AppLocalizationDelegate delegate = AppLocalizationDelegate(); static Future load(Locale locale) { - final name = - (locale.countryCode?.isEmpty ?? false) - ? locale.languageCode - : locale.toString(); + final name = (locale.countryCode?.isEmpty ?? false) + ? locale.languageCode + : locale.toString(); final localeName = Intl.canonicalizedLocale(name); return initializeMessages(localeName).then((_) { Intl.defaultLocale = localeName; @@ -44,10 +41,8 @@ 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?', - ); + assert(instance != null, + 'No instance of S present in the widget tree. Did you add S.delegate in localizationsDelegates?'); return instance!; } @@ -67,7 +62,12 @@ class S { /// `Электронная почта` String get email { - return Intl.message('Электронная почта', name: 'email', desc: '', args: []); + return Intl.message( + 'Электронная почта', + name: 'email', + desc: '', + args: [], + ); } /// `Имя пользователя` @@ -82,7 +82,12 @@ class S { /// `Пароль` String get password { - return Intl.message('Пароль', name: 'password', desc: '', args: []); + return Intl.message( + 'Пароль', + name: 'password', + desc: '', + args: [], + ); } /// `Подтвердите пароль` @@ -107,12 +112,22 @@ class S { /// `Имя` String get first_name { - return Intl.message('Имя', name: 'first_name', desc: '', args: []); + return Intl.message( + 'Имя', + name: 'first_name', + desc: '', + args: [], + ); } /// `Фамилия` String get last_name { - return Intl.message('Фамилия', name: 'last_name', desc: '', args: []); + return Intl.message( + 'Фамилия', + name: 'last_name', + desc: '', + args: [], + ); } /// `Как вас зовут?` @@ -137,22 +152,42 @@ class S { /// `Страна` String get country { - return Intl.message('Страна', name: 'country', desc: '', args: []); + return Intl.message( + 'Страна', + name: 'country', + desc: '', + args: [], + ); } /// `Россия` String get Russia { - return Intl.message('Россия', name: 'Russia', desc: '', args: []); + return Intl.message( + 'Россия', + name: 'Russia', + desc: '', + args: [], + ); } /// `Город` String get city { - return Intl.message('Город', name: 'city', desc: '', args: []); + return Intl.message( + 'Город', + name: 'city', + desc: '', + args: [], + ); } /// `Москва` String get Moscow { - return Intl.message('Москва', name: 'Moscow', desc: '', args: []); + return Intl.message( + 'Москва', + name: 'Moscow', + desc: '', + args: [], + ); } /// `Место проживания` @@ -207,12 +242,22 @@ class S { /// `Мужской` String get male { - return Intl.message('Мужской', name: 'male', desc: '', args: []); + return Intl.message( + 'Мужской', + name: 'male', + desc: '', + args: [], + ); } /// `Женский` String get female { - return Intl.message('Женский', name: 'female', desc: '', args: []); + return Intl.message( + 'Женский', + name: 'female', + desc: '', + args: [], + ); } /// `Замер веса` @@ -227,7 +272,12 @@ class S { /// `Ваш вес:` String get your_weight { - return Intl.message('Ваш вес:', name: 'your_weight', desc: '', args: []); + return Intl.message( + 'Ваш вес:', + name: 'your_weight', + desc: '', + args: [], + ); } /// `Замер роста` @@ -242,7 +292,12 @@ class S { /// `Ваш рост:` String get your_height { - return Intl.message('Ваш рост:', name: 'your_height', desc: '', args: []); + return Intl.message( + 'Ваш рост:', + name: 'your_height', + desc: '', + args: [], + ); } /// `Наличие аллергии` @@ -267,12 +322,22 @@ class S { /// `Ваш пол?` String get your_gender { - return Intl.message('Ваш пол?', name: 'your_gender', desc: '', args: []); + return Intl.message( + 'Ваш пол?', + name: 'your_gender', + desc: '', + args: [], + ); } /// `Нет` String get no { - return Intl.message('Нет', name: 'no', desc: '', args: []); + return Intl.message( + 'Нет', + name: 'no', + desc: '', + args: [], + ); } /// `Есть ли у вас гипертония?` @@ -417,12 +482,22 @@ class S { /// `English` String get lbl_english { - return Intl.message('English', name: 'lbl_english', desc: '', args: []); + return Intl.message( + 'English', + name: 'lbl_english', + desc: '', + args: [], + ); } /// `Завершить` String get finish { - return Intl.message('Завершить', name: 'finish', desc: '', args: []); + return Intl.message( + 'Завершить', + name: 'finish', + desc: '', + args: [], + ); } /// `Предпочитаемый язык общения` @@ -447,7 +522,12 @@ class S { /// `Пропустить` String get skip { - return Intl.message('Пропустить', name: 'skip', desc: '', args: []); + return Intl.message( + 'Пропустить', + name: 'skip', + desc: '', + args: [], + ); } /// `Заполните информацию:` @@ -652,7 +732,12 @@ class S { /// `Войти` String get authentificate { - return Intl.message('Войти', name: 'authentificate', desc: '', args: []); + return Intl.message( + 'Войти', + name: 'authentificate', + desc: '', + args: [], + ); } /// `Аутентификация` @@ -667,7 +752,12 @@ class S { /// `Загрузка...` String get loading { - return Intl.message('Загрузка...', name: 'loading', desc: '', args: []); + return Intl.message( + 'Загрузка...', + name: 'loading', + desc: '', + args: [], + ); } /// `График веса` @@ -712,52 +802,102 @@ class S { /// `Грудь` String get chest { - return Intl.message('Грудь', name: 'chest', desc: '', args: []); + return Intl.message( + 'Грудь', + name: 'chest', + desc: '', + args: [], + ); } /// `Талия` String get waist { - return Intl.message('Талия', name: 'waist', desc: '', args: []); + return Intl.message( + 'Талия', + name: 'waist', + desc: '', + args: [], + ); } /// `Бедра` String get hips { - return Intl.message('Бедра', name: 'hips', desc: '', args: []); + return Intl.message( + 'Бедра', + name: 'hips', + desc: '', + args: [], + ); } /// `Выйти` String get exit { - return Intl.message('Выйти', name: 'exit', desc: '', args: []); + return Intl.message( + 'Выйти', + name: 'exit', + desc: '', + args: [], + ); } /// `Активен` String get active { - return Intl.message('Активен', name: 'active', desc: '', args: []); + return Intl.message( + 'Активен', + name: 'active', + desc: '', + args: [], + ); } /// `В архиве` String get archived { - return Intl.message('В архиве', name: 'archived', desc: '', args: []); + return Intl.message( + 'В архиве', + name: 'archived', + desc: '', + args: [], + ); } /// `Черновик` String get draft { - return Intl.message('Черновик', name: 'draft', desc: '', args: []); + return Intl.message( + 'Черновик', + name: 'draft', + desc: '', + args: [], + ); } /// `Мой блог` String get my_blog { - return Intl.message('Мой блог', name: 'my_blog', desc: '', args: []); + return Intl.message( + 'Мой блог', + name: 'my_blog', + desc: '', + args: [], + ); } /// `Язык` String get language { - return Intl.message('Язык', name: 'language', desc: '', args: []); + return Intl.message( + 'Язык', + name: 'language', + desc: '', + args: [], + ); } /// `В процессе` String get in_progress { - return Intl.message('В процессе', name: 'in_progress', desc: '', args: []); + return Intl.message( + 'В процессе', + name: 'in_progress', + desc: '', + args: [], + ); } /// `Добавить замер` @@ -772,7 +912,12 @@ class S { /// `Вес` String get weight { - return Intl.message('Вес', name: 'weight', desc: '', args: []); + return Intl.message( + 'Вес', + name: 'weight', + desc: '', + args: [], + ); } /// `Пройденные планы` @@ -797,67 +942,132 @@ class S { /// `Настройки` String get settings { - return Intl.message('Настройки', name: 'settings', desc: '', args: []); + return Intl.message( + 'Настройки', + name: 'settings', + desc: '', + args: [], + ); } /// `Профиль` String get profile { - return Intl.message('Профиль', name: 'profile', desc: '', args: []); + return Intl.message( + 'Профиль', + name: 'profile', + desc: '', + args: [], + ); } /// `Чат` String get chat { - return Intl.message('Чат', name: 'chat', desc: '', args: []); + return Intl.message( + 'Чат', + name: 'chat', + desc: '', + args: [], + ); } /// `Админ` String get admin { - return Intl.message('Админ', name: 'admin', desc: '', args: []); + return Intl.message( + 'Админ', + name: 'admin', + desc: '', + args: [], + ); } /// `Дневник` String get diary { - return Intl.message('Дневник', name: 'diary', desc: '', args: []); + return Intl.message( + 'Дневник', + name: 'diary', + desc: '', + args: [], + ); } /// `Сохранить` String get save { - return Intl.message('Сохранить', name: 'save', desc: '', args: []); + return Intl.message( + 'Сохранить', + name: 'save', + desc: '', + args: [], + ); } /// `шт` String get pcs { - return Intl.message('шт', name: 'pcs', desc: '', args: []); + return Intl.message( + 'шт', + name: 'pcs', + desc: '', + args: [], + ); } /// `гр` String get gr { - return Intl.message('гр', name: 'gr', desc: '', args: []); + return Intl.message( + 'гр', + name: 'gr', + desc: '', + args: [], + ); } /// `мл` String get milliliter { - return Intl.message('мл', name: 'milliliter', desc: '', args: []); + return Intl.message( + 'мл', + name: 'milliliter', + desc: '', + args: [], + ); } /// `гр` String get grams { - return Intl.message('гр', name: 'grams', desc: '', args: []); + return Intl.message( + 'гр', + name: 'grams', + desc: '', + args: [], + ); } /// `Начать диету` String get startDiet { - return Intl.message('Начать диету', name: 'startDiet', desc: '', args: []); + return Intl.message( + 'Начать диету', + name: 'startDiet', + desc: '', + args: [], + ); } /// `Комментарии` String get comments { - return Intl.message('Комментарии', name: 'comments', desc: '', args: []); + return Intl.message( + 'Комментарии', + name: 'comments', + desc: '', + args: [], + ); } /// `комментарий` String get comment { - return Intl.message('комментарий', name: 'comment', desc: '', args: []); + return Intl.message( + 'комментарий', + name: 'comment', + desc: '', + args: [], + ); } /// `комментария` @@ -882,17 +1092,32 @@ class S { /// `дней` String get days { - return Intl.message('дней', name: 'days', desc: '', args: []); + return Intl.message( + 'дней', + name: 'days', + desc: '', + args: [], + ); } /// `День` String get day { - return Intl.message('День', name: 'day', desc: '', args: []); + return Intl.message( + 'День', + name: 'day', + desc: '', + args: [], + ); } /// `дня` String get another_form_of_day { - return Intl.message('дня', name: 'another_form_of_day', desc: '', args: []); + return Intl.message( + 'дня', + name: 'another_form_of_day', + desc: '', + args: [], + ); } /// `комментариев` @@ -907,17 +1132,32 @@ class S { /// `Приём пищи` String get meal { - return Intl.message('Приём пищи', name: 'meal', desc: '', args: []); + return Intl.message( + 'Приём пищи', + name: 'meal', + desc: '', + args: [], + ); } /// `Автор диеты` String get diet_author { - return Intl.message('Автор диеты', name: 'diet_author', desc: '', args: []); + return Intl.message( + 'Автор диеты', + name: 'diet_author', + desc: '', + args: [], + ); } /// `Свернуть` String get hide { - return Intl.message('Свернуть', name: 'hide', desc: '', args: []); + return Intl.message( + 'Свернуть', + name: 'hide', + desc: '', + args: [], + ); } /// `Показать полностью` @@ -942,12 +1182,22 @@ class S { /// `Поделиться` String get share { - return Intl.message('Поделиться', name: 'share', desc: '', args: []); + return Intl.message( + 'Поделиться', + name: 'share', + desc: '', + args: [], + ); } /// `Пожаловаться` String get complain { - return Intl.message('Пожаловаться', name: 'complain', desc: '', args: []); + return Intl.message( + 'Пожаловаться', + name: 'complain', + desc: '', + args: [], + ); } /// `Вегетарианская` @@ -962,17 +1212,32 @@ class S { /// `Легкая` String get light_type { - return Intl.message('Легкая', name: 'light_type', desc: '', args: []); + return Intl.message( + 'Легкая', + name: 'light_type', + desc: '', + args: [], + ); } /// `С мясом` String get meat_type { - return Intl.message('С мясом', name: 'meat_type', desc: '', args: []); + return Intl.message( + 'С мясом', + name: 'meat_type', + desc: '', + args: [], + ); } /// `Мучное` String get carb_type { - return Intl.message('Мучное', name: 'carb_type', desc: '', args: []); + return Intl.message( + 'Мучное', + name: 'carb_type', + desc: '', + args: [], + ); } /// `Диета основана на потреблении растительной пищи и отказе от продуктов животного происхождения. Такой тип питания может быть разнообразным и вкусным, а также полезным для здоровья.` @@ -1017,32 +1282,62 @@ class S { /// `План диеты` String get diet_plan { - return Intl.message('План диеты', name: 'diet_plan', desc: '', args: []); + return Intl.message( + 'План диеты', + name: 'diet_plan', + desc: '', + args: [], + ); } /// `Калории` String get calories { - return Intl.message('Калории', name: 'calories', desc: '', args: []); + return Intl.message( + 'Калории', + name: 'calories', + desc: '', + args: [], + ); } /// `Белки` String get proteins { - return Intl.message('Белки', name: 'proteins', desc: '', args: []); + return Intl.message( + 'Белки', + name: 'proteins', + desc: '', + args: [], + ); } /// `Жиры` String get fats { - return Intl.message('Жиры', name: 'fats', desc: '', args: []); + return Intl.message( + 'Жиры', + name: 'fats', + desc: '', + args: [], + ); } /// `Углеводы` String get carbohydrates { - return Intl.message('Углеводы', name: 'carbohydrates', desc: '', args: []); + return Intl.message( + 'Углеводы', + name: 'carbohydrates', + desc: '', + args: [], + ); } /// `Ответить` String get answer { - return Intl.message('Ответить', name: 'answer', desc: '', args: []); + return Intl.message( + 'Ответить', + name: 'answer', + desc: '', + args: [], + ); } /// `Ссылка успешно скопирована` @@ -1067,47 +1362,92 @@ class S { /// `Продолжить` String get continue_ { - return Intl.message('Продолжить', name: 'continue_', desc: '', args: []); + return Intl.message( + 'Продолжить', + name: 'continue_', + desc: '', + args: [], + ); } /// `Порядок` String get order { - return Intl.message('Порядок', name: 'order', desc: '', args: []); + return Intl.message( + 'Порядок', + name: 'order', + desc: '', + args: [], + ); } /// `Время прохождения` String get time { - return Intl.message('Время прохождения', name: 'time', desc: '', args: []); + return Intl.message( + 'Время прохождения', + name: 'time', + desc: '', + args: [], + ); } /// `Все` String get all { - return Intl.message('Все', name: 'all', desc: '', args: []); + return Intl.message( + 'Все', + name: 'all', + desc: '', + args: [], + ); } /// `Тип диеты` String get diet_type { - return Intl.message('Тип диеты', name: 'diet_type', desc: '', args: []); + return Intl.message( + 'Тип диеты', + name: 'diet_type', + desc: '', + args: [], + ); } /// `Тип плана` String get plan_type { - return Intl.message('Тип плана', name: 'plan_type', desc: '', args: []); + return Intl.message( + 'Тип плана', + name: 'plan_type', + desc: '', + args: [], + ); } /// `Популярные` String get popular { - return Intl.message('Популярные', name: 'popular', desc: '', args: []); + return Intl.message( + 'Популярные', + name: 'popular', + desc: '', + args: [], + ); } /// `Самые новые` String get most_new { - return Intl.message('Самые новые', name: 'most_new', desc: '', args: []); + return Intl.message( + 'Самые новые', + name: 'most_new', + desc: '', + args: [], + ); } /// `Самые старые` String get most_old { - return Intl.message('Самые старые', name: 'most_old', desc: '', args: []); + return Intl.message( + 'Самые старые', + name: 'most_old', + desc: '', + args: [], + ); } /// `Название: А-Я` @@ -1132,7 +1472,12 @@ class S { /// `По умолчянию` String get by_default { - return Intl.message('По умолчянию', name: 'by_default', desc: '', args: []); + return Intl.message( + 'По умолчянию', + name: 'by_default', + desc: '', + args: [], + ); } /// `Создание диеты` @@ -1177,7 +1522,12 @@ class S { /// `Статус диеты` String get diet_state { - return Intl.message('Статус диеты', name: 'diet_state', desc: '', args: []); + return Intl.message( + 'Статус диеты', + name: 'diet_state', + desc: '', + args: [], + ); } /// `Активная` @@ -1212,22 +1562,42 @@ class S { /// `Мясо` String get meat { - return Intl.message('Мясо', name: 'meat', desc: '', args: []); + return Intl.message( + 'Мясо', + name: 'meat', + desc: '', + args: [], + ); } /// `Веган.` String get vegan { - return Intl.message('Веган.', name: 'vegan', desc: '', args: []); + return Intl.message( + 'Веган.', + name: 'vegan', + desc: '', + args: [], + ); } /// `Фото` String get photo { - return Intl.message('Фото', name: 'photo', desc: '', args: []); + return Intl.message( + 'Фото', + name: 'photo', + desc: '', + args: [], + ); } /// `Галерея` String get gallery { - return Intl.message('Галерея', name: 'gallery', desc: '', args: []); + return Intl.message( + 'Галерея', + name: 'gallery', + desc: '', + args: [], + ); } /// `Добавьте обложку` @@ -1242,27 +1612,52 @@ class S { /// `Добавить` String get add { - return Intl.message('Добавить', name: 'add', desc: '', args: []); + return Intl.message( + 'Добавить', + name: 'add', + desc: '', + args: [], + ); } /// `cкопирован` String get copied { - return Intl.message('cкопирован', name: 'copied', desc: '', args: []); + return Intl.message( + 'cкопирован', + name: 'copied', + desc: '', + args: [], + ); } /// `В черновик` String get to_draft { - return Intl.message('В черновик', name: 'to_draft', desc: '', args: []); + return Intl.message( + 'В черновик', + name: 'to_draft', + desc: '', + args: [], + ); } /// `Превью` String get preview { - return Intl.message('Превью', name: 'preview', desc: '', args: []); + return Intl.message( + 'Превью', + name: 'preview', + desc: '', + args: [], + ); } /// `Опубликовать` String get publish { - return Intl.message('Опубликовать', name: 'publish', desc: '', args: []); + return Intl.message( + 'Опубликовать', + name: 'publish', + desc: '', + args: [], + ); } /// `Добавление плана` @@ -1277,7 +1672,12 @@ class S { /// `Название` String get label { - return Intl.message('Название', name: 'label', desc: '', args: []); + return Intl.message( + 'Название', + name: 'label', + desc: '', + args: [], + ); } /// `План для поддержания формы` @@ -1302,12 +1702,22 @@ class S { /// `Похудение` String get slim { - return Intl.message('Похудение', name: 'slim', desc: '', args: []); + return Intl.message( + 'Похудение', + name: 'slim', + desc: '', + args: [], + ); } /// `Поддержка формы` String get fitness { - return Intl.message('Поддержка формы', name: 'fitness', desc: '', args: []); + return Intl.message( + 'Поддержка формы', + name: 'fitness', + desc: '', + args: [], + ); } /// `Улучшение самочувствия` @@ -1362,37 +1772,72 @@ class S { /// `1 опция` String get one_option { - return Intl.message('1 опция', name: 'one_option', desc: '', args: []); + return Intl.message( + '1 опция', + name: 'one_option', + desc: '', + args: [], + ); } /// `3 опции` String get three_options { - return Intl.message('3 опции', name: 'three_options', desc: '', args: []); + return Intl.message( + '3 опции', + name: 'three_options', + desc: '', + args: [], + ); } /// `Опция` String get option { - return Intl.message('Опция', name: 'option', desc: '', args: []); + return Intl.message( + 'Опция', + name: 'option', + desc: '', + args: [], + ); } /// `Оказание услуг` String get services { - return Intl.message('Оказание услуг', name: 'services', desc: '', args: []); + return Intl.message( + 'Оказание услуг', + name: 'services', + desc: '', + args: [], + ); } /// `Эконом` String get economy { - return Intl.message('Эконом', name: 'economy', desc: '', args: []); + return Intl.message( + 'Эконом', + name: 'economy', + desc: '', + args: [], + ); } /// `Стандарт` String get standard { - return Intl.message('Стандарт', name: 'standard', desc: '', args: []); + return Intl.message( + 'Стандарт', + name: 'standard', + desc: '', + args: [], + ); } /// `Комфорт` String get comfort { - return Intl.message('Комфорт', name: 'comfort', desc: '', args: []); + return Intl.message( + 'Комфорт', + name: 'comfort', + desc: '', + args: [], + ); } /// `Заголовок опции` @@ -1507,7 +1952,12 @@ class S { /// `Автор плана` String get plan_author { - return Intl.message('Автор плана', name: 'plan_author', desc: '', args: []); + return Intl.message( + 'Автор плана', + name: 'plan_author', + desc: '', + args: [], + ); } /// `Продолжительность опции` @@ -1542,7 +1992,12 @@ class S { /// `Похудение` String get slim_type { - return Intl.message('Похудение', name: 'slim_type', desc: '', args: []); + return Intl.message( + 'Похудение', + name: 'slim_type', + desc: '', + args: [], + ); } /// `План питания для похудения должен быть разработан с учётом индивидуальных особенностей организма, возраста, пола, уровня физической активности и состояния здоровья. Общие принципы: \n● Снижение калорийности; \n● Сбалансированный рацион; \n● Разнообразие продуктов; \n● Питьевой режим; \n● Ограничение вредных продуктов;` @@ -1597,12 +2052,22 @@ class S { /// `Цена` String get price { - return Intl.message('Цена', name: 'price', desc: '', args: []); + return Intl.message( + 'Цена', + name: 'price', + desc: '', + args: [], + ); } /// `Мои диеты` String get my_diets { - return Intl.message('Мои диеты', name: 'my_diets', desc: '', args: []); + return Intl.message( + 'Мои диеты', + name: 'my_diets', + desc: '', + args: [], + ); } /// `Опубликованные` @@ -1617,22 +2082,42 @@ class S { /// `Черновики` String get drafted { - return Intl.message('Черновики', name: 'drafted', desc: '', args: []); + return Intl.message( + 'Черновики', + name: 'drafted', + desc: '', + args: [], + ); } /// `Персональные` String get personal { - return Intl.message('Персональные', name: 'personal', desc: '', args: []); + return Intl.message( + 'Персональные', + name: 'personal', + desc: '', + args: [], + ); } /// `Редактировать` String get edit { - return Intl.message('Редактировать', name: 'edit', desc: '', args: []); + return Intl.message( + 'Редактировать', + name: 'edit', + desc: '', + args: [], + ); } /// `Предложить` String get toOffer { - return Intl.message('Предложить', name: 'toOffer', desc: '', args: []); + return Intl.message( + 'Предложить', + name: 'toOffer', + desc: '', + args: [], + ); } /// `Снять с публикации` @@ -1647,22 +2132,42 @@ class S { /// `Диета` String get diet { - return Intl.message('Диета', name: 'diet', desc: '', args: []); + return Intl.message( + 'Диета', + name: 'diet', + desc: '', + args: [], + ); } /// `Удалена` String get deleted { - return Intl.message('Удалена', name: 'deleted', desc: '', args: []); + return Intl.message( + 'Удалена', + name: 'deleted', + desc: '', + args: [], + ); } /// `Мои планы` String get my_plans { - return Intl.message('Мои планы', name: 'my_plans', desc: '', args: []); + return Intl.message( + 'Мои планы', + name: 'my_plans', + desc: '', + args: [], + ); } /// `от` String get from { - return Intl.message('от', name: 'from', desc: '', args: []); + return Intl.message( + 'от', + name: 'from', + desc: '', + args: [], + ); } /// `Данные пользователя` @@ -1687,7 +2192,12 @@ class S { /// `Пол` String get sex { - return Intl.message('Пол', name: 'sex', desc: '', args: []); + return Intl.message( + 'Пол', + name: 'sex', + desc: '', + args: [], + ); } /// `Физическая форма` @@ -1702,22 +2212,42 @@ class S { /// `Рост` String get height { - return Intl.message('Рост', name: 'height', desc: '', args: []); + return Intl.message( + 'Рост', + name: 'height', + desc: '', + args: [], + ); } /// `Давление` String get pressure { - return Intl.message('Давление', name: 'pressure', desc: '', args: []); + return Intl.message( + 'Давление', + name: 'pressure', + desc: '', + args: [], + ); } /// `Верхнее` String get upper { - return Intl.message('Верхнее', name: 'upper', desc: '', args: []); + return Intl.message( + 'Верхнее', + name: 'upper', + desc: '', + args: [], + ); } /// `Нижнее` String get lower { - return Intl.message('Нижнее', name: 'lower', desc: '', args: []); + return Intl.message( + 'Нижнее', + name: 'lower', + desc: '', + args: [], + ); } /// `Склонность к гипотонии` @@ -1822,7 +2352,12 @@ class S { /// `Подтвердить` String get confirm { - return Intl.message('Подтвердить', name: 'confirm', desc: '', args: []); + return Intl.message( + 'Подтвердить', + name: 'confirm', + desc: '', + args: [], + ); } /// `Не удалось отменить диету` @@ -1837,12 +2372,22 @@ class S { /// `часов` String get hours { - return Intl.message('часов', name: 'hours', desc: '', args: []); + return Intl.message( + 'часов', + name: 'hours', + desc: '', + args: [], + ); } /// `час` String get hour { - return Intl.message('час', name: 'hour', desc: '', args: []); + return Intl.message( + 'час', + name: 'hour', + desc: '', + args: [], + ); } /// `часа` @@ -1857,12 +2402,22 @@ class S { /// `минуты` String get minutes { - return Intl.message('минуты', name: 'minutes', desc: '', args: []); + return Intl.message( + 'минуты', + name: 'minutes', + desc: '', + args: [], + ); } /// `минута` String get minute { - return Intl.message('минута', name: 'minute', desc: '', args: []); + return Intl.message( + 'минута', + name: 'minute', + desc: '', + args: [], + ); } /// `минут` @@ -1907,12 +2462,22 @@ class S { /// `этапов` String get stages { - return Intl.message('этапов', name: 'stages', desc: '', args: []); + return Intl.message( + 'этапов', + name: 'stages', + desc: '', + args: [], + ); } /// `этап` String get stage { - return Intl.message('этап', name: 'stage', desc: '', args: []); + return Intl.message( + 'этап', + name: 'stage', + desc: '', + args: [], + ); } /// `этапа` @@ -1947,12 +2512,22 @@ class S { /// `Ингредиенты` String get ingredients { - return Intl.message('Ингредиенты', name: 'ingredients', desc: '', args: []); + return Intl.message( + 'Ингредиенты', + name: 'ingredients', + desc: '', + args: [], + ); } /// `Шаг` String get step { - return Intl.message('Шаг', name: 'step', desc: '', args: []); + return Intl.message( + 'Шаг', + name: 'step', + desc: '', + args: [], + ); } /// `Пошаговый фоторецепт` @@ -1977,7 +2552,12 @@ class S { /// `Спам` String get spam { - return Intl.message('Спам', name: 'spam', desc: '', args: []); + return Intl.message( + 'Спам', + name: 'spam', + desc: '', + args: [], + ); } /// `Нарушение законодательства` @@ -1992,7 +2572,12 @@ class S { /// `Обман` String get deception { - return Intl.message('Обман', name: 'deception', desc: '', args: []); + return Intl.message( + 'Обман', + name: 'deception', + desc: '', + args: [], + ); } /// `Насилие и вражда` @@ -2037,7 +2622,12 @@ class S { /// `Жалоба` String get complaint { - return Intl.message('Жалоба', name: 'complaint', desc: '', args: []); + return Intl.message( + 'Жалоба', + name: 'complaint', + desc: '', + args: [], + ); } /// `Что именно в этом материале Вы считаете неприемлемым и нарушающим правила?` @@ -2102,27 +2692,52 @@ class S { /// `Хорошо` String get ok { - return Intl.message('Хорошо', name: 'ok', desc: '', args: []); + return Intl.message( + 'Хорошо', + name: 'ok', + desc: '', + args: [], + ); } /// `Алкоголь` String get alcohol { - return Intl.message('Алкоголь', name: 'alcohol', desc: '', args: []); + return Intl.message( + 'Алкоголь', + name: 'alcohol', + desc: '', + args: [], + ); } /// `Наркотики` String get drugs { - return Intl.message('Наркотики', name: 'drugs', desc: '', args: []); + return Intl.message( + 'Наркотики', + name: 'drugs', + desc: '', + args: [], + ); } /// `Никотин` String get nicotine { - return Intl.message('Никотин', name: 'nicotine', desc: '', args: []); + return Intl.message( + 'Никотин', + name: 'nicotine', + desc: '', + args: [], + ); } /// `Оружие` String get weapon { - return Intl.message('Оружие', name: 'weapon', desc: '', args: []); + return Intl.message( + 'Оружие', + name: 'weapon', + desc: '', + args: [], + ); } /// `Поддельные документы` @@ -2147,7 +2762,12 @@ class S { /// `Другое` String get other { - return Intl.message('Другое', name: 'other', desc: '', args: []); + return Intl.message( + 'Другое', + name: 'other', + desc: '', + args: [], + ); } /// `Введение в заблуждение` @@ -2172,7 +2792,12 @@ class S { /// `Мошенничество` String get fraud { - return Intl.message('Мошенничество', name: 'fraud', desc: '', args: []); + return Intl.message( + 'Мошенничество', + name: 'fraud', + desc: '', + args: [], + ); } /// `Мошенничество с целью наживы. Если вас обманули, пожалуйста, сообщите об этом в правоохранительные органы.` @@ -2197,7 +2822,12 @@ class S { /// `Оскорбление` String get hatred { - return Intl.message('Оскорбление', name: 'hatred', desc: '', args: []); + return Intl.message( + 'Оскорбление', + name: 'hatred', + desc: '', + args: [], + ); } /// `Склонение к самоубийству` @@ -2222,7 +2852,12 @@ class S { /// `Экстремизм` String get extremism { - return Intl.message('Экстремизм', name: 'extremism', desc: '', args: []); + return Intl.message( + 'Экстремизм', + name: 'extremism', + desc: '', + args: [], + ); } /// `Призывы к травле` @@ -2277,7 +2912,12 @@ class S { /// `Ваш рейтинг` String get your_rating { - return Intl.message('Ваш рейтинг', name: 'your_rating', desc: '', args: []); + return Intl.message( + 'Ваш рейтинг', + name: 'your_rating', + desc: '', + args: [], + ); } /// `Скопировать пригласительную ссылку` @@ -2292,7 +2932,12 @@ class S { /// `Статистика` String get statistic { - return Intl.message('Статистика', name: 'statistic', desc: '', args: []); + return Intl.message( + 'Статистика', + name: 'statistic', + desc: '', + args: [], + ); } /// `За всё время` @@ -2307,17 +2952,32 @@ class S { /// `За год` String get for_a_year { - return Intl.message('За год', name: 'for_a_year', desc: '', args: []); + return Intl.message( + 'За год', + name: 'for_a_year', + desc: '', + args: [], + ); } /// `За месяц` String get for_a_month { - return Intl.message('За месяц', name: 'for_a_month', desc: '', args: []); + return Intl.message( + 'За месяц', + name: 'for_a_month', + desc: '', + args: [], + ); } /// `За неделю` String get for_a_week { - return Intl.message('За неделю', name: 'for_a_week', desc: '', args: []); + return Intl.message( + 'За неделю', + name: 'for_a_week', + desc: '', + args: [], + ); } /// `Количество приглашенных`