forked from eatvio/eatvio_app
Merge pull request 'chats have been updated to work with consultatons' (#255) from misha/eatvio_app:main into main
Reviewed-on: eatvio/eatvio_app#255
This commit is contained in:
4
assets/icons/reversed_exclamation_mark.svg
Normal file
4
assets/icons/reversed_exclamation_mark.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="68" height="69" viewBox="0 0 68 69" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M68 34.6406C68 53.2716 52.7777 68.375 34 68.375C15.2223 68.375 0 53.2716 0 34.6406C0 16.0096 15.2223 0.90625 34 0.90625C52.7777 0.90625 68 16.0096 68 34.6406Z" fill="white"/>
|
||||
<path d="M31.6767 54.8812V26.6568H36.2667V54.8812H31.6767ZM31.11 20.2473V15.1309H36.7767V20.2473H31.11Z" fill="#2F80ED"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 409 B |
@@ -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';
|
||||
@@ -242,12 +241,10 @@ class AppRouter {
|
||||
path: '/chat-screen',
|
||||
name: 'chatScreen',
|
||||
builder: (context, state) {
|
||||
final data = state.extra as Map<String, dynamic>;
|
||||
final chatsCubit = data['chatsCubit'] as ChatsCubit;
|
||||
final data = state.extra as Map<String, dynamic>;
|
||||
final chatId = data['chatId'] as String;
|
||||
return ChatScreen(
|
||||
chatId: chatId,
|
||||
chatsCubit: chatsCubit,
|
||||
chatId: chatId,
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
@@ -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<int> durationValues = [7, 14, 21];
|
||||
|
||||
@@ -9,3 +9,4 @@ const List<String> planTypeValues = ['fit', 'slim', 'wellness', 'behavior'];
|
||||
const newMessagesChannelName = 'private-new-chat-messages';
|
||||
const newNotificationsChannelName = 'private-message-events';
|
||||
const directChatChannelName = 'private-direct-chat';
|
||||
const thresholdForPagination = 150;
|
||||
|
||||
@@ -87,6 +87,7 @@ Future<void> init() async {
|
||||
sl.registerLazySingleton<NotificationsCubit>(() => NotificationsCubit(wsManager: sl()));
|
||||
sl.registerLazySingleton<FeedCubit>(() => FeedCubit(feedRepository: sl()));
|
||||
sl.registerLazySingleton<ProfileAvatarCubit>(() => ProfileAvatarCubit(profileRepository: sl()));
|
||||
sl.registerLazySingleton<ChatsCubit>(() => ChatsCubit(chatRepository: sl(), wsManager: sl(), profileRepository: sl()));
|
||||
|
||||
// Cubit factories
|
||||
sl.registerFactory<RegistrationCubit>(() => RegistrationCubit(registrationRepository: sl()));
|
||||
@@ -96,8 +97,7 @@ Future<void> init() async {
|
||||
sl.registerFactory<ProfileCubit>(() => ProfileCubit(profileRepository: sl(), chatRepository: sl()));
|
||||
sl.registerFactory<profilePlans.PlansCubit>(() => profilePlans.PlansCubit(plansRepository: sl()));
|
||||
sl.registerFactory<DietsCubit>(() => DietsCubit(feedRepository: sl(), dietsRepository: sl()));
|
||||
sl.registerFactory<CommentsCubit>(() => CommentsCubit(feedRepository: sl()));
|
||||
sl.registerFactory<ChatsCubit>(() => ChatsCubit(chatRepository: sl(), wsManager: sl(), profileRepository: sl()));
|
||||
sl.registerFactory<CommentsCubit>(() => CommentsCubit(feedRepository: sl()));
|
||||
sl.registerFactory<PlansCubit>(() => PlansCubit(feedRepository: sl(), planRepository: sl()));
|
||||
sl.registerFactory<SettingsCubit>(() => SettingsCubit(profileRepository: sl(), settingsRepository: sl()));
|
||||
sl.registerFactory<RegisterConsultantCubit>(() => RegisterConsultantCubit(consultantRepository: sl()));
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
8
lib/core/utils/pagination_utils.dart
Normal file
8
lib/core/utils/pagination_utils.dart
Normal file
@@ -0,0 +1,8 @@
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
void loadNewContent(ScrollNotification notification, Future<void> Function() load) {
|
||||
if (notification.metrics.pixels >= notification.metrics.maxScrollExtent - thresholdForPagination && !notification.metrics.outOfRange) {
|
||||
load();
|
||||
}
|
||||
}
|
||||
47
lib/core/widgets/item_widget.dart
Normal file
47
lib/core/widgets/item_widget.dart
Normal file
@@ -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,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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<AuthState> {
|
||||
required this.authRepository,
|
||||
}) : super(AuthState());
|
||||
|
||||
getTokenByCredentials(String email, String password) async {
|
||||
Future<bool> getTokenByCredentials(String email, String password) async {
|
||||
emit(AuthState.loading());
|
||||
try {
|
||||
final token = (await authRepository.getTokenByCredentials(
|
||||
@@ -23,7 +21,6 @@ class AuthCubit extends Cubit<AuthState> {
|
||||
password,
|
||||
))
|
||||
.token;
|
||||
print(token);
|
||||
emit(
|
||||
AuthState.loaded(
|
||||
token: token,
|
||||
@@ -31,12 +28,13 @@ class AuthCubit extends Cubit<AuthState> {
|
||||
);
|
||||
showSuccessToast('Успешный вход');
|
||||
await TokenStorage.saveTokenInStorage(token);
|
||||
await sl<ProfileAvatarCubit>().getMyProfile();
|
||||
AppRouter.navigatorKey.currentContext?.go('/my-profile-screen');
|
||||
return true;
|
||||
} catch (e) {
|
||||
print(e);
|
||||
showErrorToast('Неверный адрес электронной почты или пароль');
|
||||
emit(AuthState.error(errorMessage: '$e'));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,11 @@ 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';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
|
||||
@@ -116,30 +119,30 @@ class _AuthScreenState extends State<AuthScreen> {
|
||||
],
|
||||
),
|
||||
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(
|
||||
@@ -156,10 +159,16 @@ class _AuthScreenState extends State<AuthScreen> {
|
||||
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<ProfileAvatarCubit>().getMyProfile();
|
||||
context.read<ChatsCubit>().getChatRoomsWithLoading();
|
||||
}
|
||||
},
|
||||
label: state is AuthStateLoading
|
||||
? CupertinoActivityIndicator()
|
||||
: Text(
|
||||
|
||||
@@ -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';
|
||||
@@ -10,8 +11,23 @@ class ChatRoomModel with _$ChatRoomModel {
|
||||
const factory ChatRoomModel({
|
||||
required String id,
|
||||
@JsonKey(name: 'chat_room_setting') required ChatRoomSettingsModel chatRoomSettings,
|
||||
required Map<String, ChatUserModel> users,
|
||||
required Users users,
|
||||
@JsonKey(name: 'chosen_plan', fromJson: parseChosenPlan) required ChosenPlanModel? chosenPlan,
|
||||
}) = _ChatRoomModel;
|
||||
|
||||
factory ChatRoomModel.fromJson(Map<String, Object?> json) => _$ChatRoomModelFromJson(json);
|
||||
}
|
||||
|
||||
@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<String, Object?> json) => _$UsersFromJson(json);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,9 @@ mixin _$ChatRoomModel {
|
||||
@JsonKey(name: 'chat_room_setting')
|
||||
ChatRoomSettingsModel get chatRoomSettings =>
|
||||
throw _privateConstructorUsedError;
|
||||
Map<String, ChatUserModel> get users => throw _privateConstructorUsedError;
|
||||
Users get users => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'chosen_plan', fromJson: parseChosenPlan)
|
||||
ChosenPlanModel? get chosenPlan => throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this ChatRoomModel to a JSON map.
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
@@ -46,9 +48,13 @@ abstract class $ChatRoomModelCopyWith<$Res> {
|
||||
{String id,
|
||||
@JsonKey(name: 'chat_room_setting')
|
||||
ChatRoomSettingsModel chatRoomSettings,
|
||||
Map<String, ChatUserModel> users});
|
||||
Users users,
|
||||
@JsonKey(name: 'chosen_plan', fromJson: parseChosenPlan)
|
||||
ChosenPlanModel? chosenPlan});
|
||||
|
||||
$ChatRoomSettingsModelCopyWith<$Res> get chatRoomSettings;
|
||||
$UsersCopyWith<$Res> get users;
|
||||
$ChosenPlanModelCopyWith<$Res>? get chosenPlan;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -69,6 +75,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
|
||||
@@ -82,7 +89,11 @@ class _$ChatRoomModelCopyWithImpl<$Res, $Val extends ChatRoomModel>
|
||||
users: null == users
|
||||
? _value.users
|
||||
: users // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, ChatUserModel>,
|
||||
as Users,
|
||||
chosenPlan: freezed == chosenPlan
|
||||
? _value.chosenPlan
|
||||
: chosenPlan // ignore: cast_nullable_to_non_nullable
|
||||
as ChosenPlanModel?,
|
||||
) as $Val);
|
||||
}
|
||||
|
||||
@@ -96,6 +107,30 @@ 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')
|
||||
$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
|
||||
@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 +145,16 @@ abstract class _$$ChatRoomModelImplCopyWith<$Res>
|
||||
{String id,
|
||||
@JsonKey(name: 'chat_room_setting')
|
||||
ChatRoomSettingsModel chatRoomSettings,
|
||||
Map<String, ChatUserModel> users});
|
||||
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;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -132,6 +173,7 @@ class __$$ChatRoomModelImplCopyWithImpl<$Res>
|
||||
Object? id = null,
|
||||
Object? chatRoomSettings = null,
|
||||
Object? users = null,
|
||||
Object? chosenPlan = freezed,
|
||||
}) {
|
||||
return _then(_$ChatRoomModelImpl(
|
||||
id: null == id
|
||||
@@ -143,9 +185,13 @@ 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<String, ChatUserModel>,
|
||||
as Users,
|
||||
chosenPlan: freezed == chosenPlan
|
||||
? _value.chosenPlan
|
||||
: chosenPlan // ignore: cast_nullable_to_non_nullable
|
||||
as ChosenPlanModel?,
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -156,8 +202,9 @@ class _$ChatRoomModelImpl implements _ChatRoomModel {
|
||||
const _$ChatRoomModelImpl(
|
||||
{required this.id,
|
||||
@JsonKey(name: 'chat_room_setting') required this.chatRoomSettings,
|
||||
required final Map<String, ChatUserModel> users})
|
||||
: _users = users;
|
||||
required this.users,
|
||||
@JsonKey(name: 'chosen_plan', fromJson: parseChosenPlan)
|
||||
required this.chosenPlan});
|
||||
|
||||
factory _$ChatRoomModelImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$ChatRoomModelImplFromJson(json);
|
||||
@@ -167,17 +214,15 @@ class _$ChatRoomModelImpl implements _ChatRoomModel {
|
||||
@override
|
||||
@JsonKey(name: 'chat_room_setting')
|
||||
final ChatRoomSettingsModel chatRoomSettings;
|
||||
final Map<String, ChatUserModel> _users;
|
||||
@override
|
||||
Map<String, ChatUserModel> 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)
|
||||
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 +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));
|
||||
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.
|
||||
@@ -217,7 +264,9 @@ abstract class _ChatRoomModel implements ChatRoomModel {
|
||||
{required final String id,
|
||||
@JsonKey(name: 'chat_room_setting')
|
||||
required final ChatRoomSettingsModel chatRoomSettings,
|
||||
required final Map<String, ChatUserModel> users}) = _$ChatRoomModelImpl;
|
||||
required final Users users,
|
||||
@JsonKey(name: 'chosen_plan', fromJson: parseChosenPlan)
|
||||
required final ChosenPlanModel? chosenPlan}) = _$ChatRoomModelImpl;
|
||||
|
||||
factory _ChatRoomModel.fromJson(Map<String, dynamic> json) =
|
||||
_$ChatRoomModelImpl.fromJson;
|
||||
@@ -228,7 +277,10 @@ abstract class _ChatRoomModel implements ChatRoomModel {
|
||||
@JsonKey(name: 'chat_room_setting')
|
||||
ChatRoomSettingsModel get chatRoomSettings;
|
||||
@override
|
||||
Map<String, ChatUserModel> get users;
|
||||
Users 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.
|
||||
@@ -237,3 +289,208 @@ abstract class _ChatRoomModel implements ChatRoomModel {
|
||||
_$$ChatRoomModelImplCopyWith<_$ChatRoomModelImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
Users _$UsersFromJson(Map<String, dynamic> 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<String, dynamic> 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<Users> 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<String, dynamic> 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<String, dynamic> 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<String, dynamic> 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;
|
||||
}
|
||||
|
||||
@@ -11,10 +11,8 @@ _$ChatRoomModelImpl _$$ChatRoomModelImplFromJson(Map<String, dynamic> json) =>
|
||||
id: json['id'] as String,
|
||||
chatRoomSettings: ChatRoomSettingsModel.fromJson(
|
||||
json['chat_room_setting'] as Map<String, dynamic>),
|
||||
users: (json['users'] as Map<String, dynamic>).map(
|
||||
(k, e) =>
|
||||
MapEntry(k, ChatUserModel.fromJson(e as Map<String, dynamic>)),
|
||||
),
|
||||
users: Users.fromJson(json['users'] as Map<String, dynamic>),
|
||||
chosenPlan: parseChosenPlan(json['chosen_plan']),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ChatRoomModelImplToJson(_$ChatRoomModelImpl instance) =>
|
||||
@@ -22,4 +20,18 @@ Map<String, dynamic> _$$ChatRoomModelImplToJson(_$ChatRoomModelImpl instance) =>
|
||||
'id': instance.id,
|
||||
'chat_room_setting': instance.chatRoomSettings,
|
||||
'users': instance.users,
|
||||
'chosen_plan': instance.chosenPlan,
|
||||
};
|
||||
|
||||
_$UsersImpl _$$UsersImplFromJson(Map<String, dynamic> json) => _$UsersImpl(
|
||||
sender: ChatUserModel.fromJson(
|
||||
json['from_chat_user'] as Map<String, dynamic>),
|
||||
receiver:
|
||||
ChatUserModel.fromJson(json['to_chat_user'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$UsersImplToJson(_$UsersImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'from_chat_user': instance.sender,
|
||||
'to_chat_user': instance.receiver,
|
||||
};
|
||||
|
||||
@@ -1,16 +1,29 @@
|
||||
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_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<ChatRoom> 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<String, dynamic> json) => _$ChatRoomPreviewModelFromJson(json);
|
||||
factory ChatRoomPaginationModel.fromJson(Map<String, dynamic> json) => _$ChatRoomPaginationModelFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ChatRooms with _$ChatRooms {
|
||||
const factory ChatRooms({
|
||||
@JsonKey(name: "data") required List<ChatRoom> data,
|
||||
@JsonKey(name: "last_page") required int lastPage,
|
||||
@JsonKey(name: "current_page") required int currentPage,
|
||||
}) = _ChatRooms;
|
||||
|
||||
factory ChatRooms.fromJson(Map<String, dynamic> json) => _$ChatRoomsFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
@@ -21,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<String, dynamic> json) => _$ChatRoomFromJson(json);
|
||||
@@ -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>(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<String, dynamic> json) {
|
||||
ChatRoomPaginationModel _$ChatRoomPaginationModelFromJson(
|
||||
Map<String, dynamic> json) {
|
||||
return _ChatRoomPreviewModel.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$ChatRoomPreviewModel {
|
||||
mixin _$ChatRoomPaginationModel {
|
||||
@JsonKey(name: "chatRooms")
|
||||
List<ChatRoom> 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<String, dynamic> 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<ChatRoomPreviewModel> get copyWith =>
|
||||
$ChatRoomPaginationModelCopyWith<ChatRoomPaginationModel> 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<ChatRoom> 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<ChatRoom>,
|
||||
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<ChatRoom> 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<ChatRoom>,
|
||||
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<ChatRoom> chatRooms})
|
||||
: _chatRooms = chatRooms;
|
||||
{@JsonKey(name: "chatRooms") required this.chatRooms,
|
||||
@JsonKey(name: "number_of_unread_chat_rooms")
|
||||
required this.unreadChatsCount});
|
||||
|
||||
factory _$ChatRoomPreviewModelImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$ChatRoomPreviewModelImplFromJson(json);
|
||||
|
||||
final List<ChatRoom> _chatRooms;
|
||||
@override
|
||||
@JsonKey(name: "chatRooms")
|
||||
List<ChatRoom> 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<ChatRoom> 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<String, dynamic> json) =
|
||||
_$ChatRoomPreviewModelImpl.fromJson;
|
||||
|
||||
@override
|
||||
@JsonKey(name: "chatRooms")
|
||||
List<ChatRoom> 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<String, dynamic> json) {
|
||||
return _ChatRooms.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$ChatRooms {
|
||||
@JsonKey(name: "data")
|
||||
List<ChatRoom> 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<String, dynamic> 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<ChatRooms> 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<ChatRoom> 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<ChatRoom>,
|
||||
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<ChatRoom> 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<ChatRoom>,
|
||||
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<ChatRoom> data,
|
||||
@JsonKey(name: "last_page") required this.lastPage,
|
||||
@JsonKey(name: "current_page") required this.currentPage})
|
||||
: _data = data;
|
||||
|
||||
factory _$ChatRoomsImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$ChatRoomsImplFromJson(json);
|
||||
|
||||
final List<ChatRoom> _data;
|
||||
@override
|
||||
@JsonKey(name: "data")
|
||||
List<ChatRoom> 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<String, dynamic> toJson() {
|
||||
return _$$ChatRoomsImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _ChatRooms implements ChatRooms {
|
||||
const factory _ChatRooms(
|
||||
{@JsonKey(name: "data") required final List<ChatRoom> data,
|
||||
@JsonKey(name: "last_page") required final int lastPage,
|
||||
@JsonKey(name: "current_page") required final int currentPage}) =
|
||||
_$ChatRoomsImpl;
|
||||
|
||||
factory _ChatRooms.fromJson(Map<String, dynamic> json) =
|
||||
_$ChatRoomsImpl.fromJson;
|
||||
|
||||
@override
|
||||
@JsonKey(name: "data")
|
||||
List<ChatRoom> 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<String, dynamic> json) {
|
||||
return _ChatRoom.fromJson(json);
|
||||
}
|
||||
@@ -196,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<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
@@ -218,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
|
||||
@@ -244,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
|
||||
@@ -266,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);
|
||||
}
|
||||
|
||||
@@ -292,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
|
||||
@@ -308,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
|
||||
@@ -334,6 +611,7 @@ class __$$ChatRoomImplCopyWithImpl<$Res>
|
||||
Object? lastMessage = freezed,
|
||||
Object? users = null,
|
||||
Object? unreadMessagesCount = null,
|
||||
Object? chosenPlan = freezed,
|
||||
}) {
|
||||
return _then(_$ChatRoomImpl(
|
||||
id: null == id
|
||||
@@ -356,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?,
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -369,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<String, dynamic> json) =>
|
||||
_$$ChatRoomImplFromJson(json);
|
||||
@@ -390,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
|
||||
@@ -408,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.
|
||||
@@ -440,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<String, dynamic> json) =
|
||||
_$ChatRoomImpl.fromJson;
|
||||
@@ -460,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.
|
||||
@@ -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<String, dynamic> json) =>
|
||||
_$ChatRoomPreviewModelImpl(
|
||||
chatRooms: (json['chatRooms'] as List<dynamic>)
|
||||
.map((e) => ChatRoom.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
chatRooms: ChatRooms.fromJson(json['chatRooms'] as Map<String, dynamic>),
|
||||
unreadChatsCount: (json['number_of_unread_chat_rooms'] as num).toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ChatRoomPreviewModelImplToJson(
|
||||
_$ChatRoomPreviewModelImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'chatRooms': instance.chatRooms,
|
||||
'number_of_unread_chat_rooms': instance.unreadChatsCount,
|
||||
};
|
||||
|
||||
_$ChatRoomsImpl _$$ChatRoomsImplFromJson(Map<String, dynamic> json) =>
|
||||
_$ChatRoomsImpl(
|
||||
data: (json['data'] as List<dynamic>)
|
||||
.map((e) => ChatRoom.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
lastPage: (json['last_page'] as num).toInt(),
|
||||
currentPage: (json['current_page'] as num).toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ChatRoomsImplToJson(_$ChatRoomsImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'data': instance.data,
|
||||
'last_page': instance.lastPage,
|
||||
'current_page': instance.currentPage,
|
||||
};
|
||||
|
||||
_$ChatRoomImpl _$$ChatRoomImplFromJson(Map<String, dynamic> json) =>
|
||||
@@ -27,6 +43,7 @@ _$ChatRoomImpl _$$ChatRoomImplFromJson(Map<String, dynamic> json) =>
|
||||
lastMessage: parseLastMessage(json['last_message']),
|
||||
users: Users.fromJson(json['users'] as Map<String, dynamic>),
|
||||
unreadMessagesCount: (json['unread_messages_count'] as num).toInt(),
|
||||
chosenPlan: parseChosenPlan(json['chosen_plan']),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ChatRoomImplToJson(_$ChatRoomImpl instance) =>
|
||||
@@ -36,6 +53,7 @@ Map<String, dynamic> _$$ChatRoomImplToJson(_$ChatRoomImpl instance) =>
|
||||
'last_message': instance.lastMessage,
|
||||
'users': instance.users,
|
||||
'unread_messages_count': instance.unreadMessagesCount,
|
||||
'chosen_plan': instance.chosenPlan,
|
||||
};
|
||||
|
||||
_$UsersImpl _$$UsersImplFromJson(Map<String, dynamic> json) => _$UsersImpl(
|
||||
@@ -86,6 +86,18 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> cancelChosenPlan({required String chatId, required int planId}) async {
|
||||
try {
|
||||
await chatRepository.cancelChosenPlan(id: planId);
|
||||
final chatRoom = await chatRepository.getChatRoom(chatId);
|
||||
emit(
|
||||
(state as ChatRoomStateLoaded).copyWith(chatRoom: chatRoom),
|
||||
);
|
||||
} catch (e) {
|
||||
emit(ChatRoomState.error(errorMessage: 'Ошибка получеия данных'));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _subscribeToChatChannel({
|
||||
required String chatId,
|
||||
}) async {
|
||||
@@ -93,7 +105,7 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
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<ChatMessageModel> messagesList = [
|
||||
@@ -111,7 +123,7 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
);
|
||||
});
|
||||
|
||||
wsManager.clientTypingStream?.listen((event) {
|
||||
typingSubscription = wsManager.clientTypingStream?.listen((event) {
|
||||
emit(
|
||||
ChatRoomState.loaded(
|
||||
chatRoom: (state as ChatRoomStateLoaded).chatRoom,
|
||||
@@ -180,6 +192,8 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
@override
|
||||
Future<void> close() async {
|
||||
wsManager.unsubscribeDirectChatChannel();
|
||||
messagesSubscription?.cancel();
|
||||
typingSubscription?.cancel();
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<ChatsState> {
|
||||
});
|
||||
}
|
||||
String? _query;
|
||||
int page = 1;
|
||||
late int lastPage;
|
||||
Future<void> 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<ChatsState> {
|
||||
}
|
||||
|
||||
Future<void> 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<void> 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) {
|
||||
|
||||
@@ -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<ChatRoom> chatRooms,
|
||||
@Default(false) bool isLoadingMoreChats,
|
||||
@Default(null) String? errorMessage,
|
||||
}) = _ChatsState;
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ mixin _$ChatsState {
|
||||
BaseState get state => throw _privateConstructorUsedError;
|
||||
int get chatsWithUnreadMessagesCount => throw _privateConstructorUsedError;
|
||||
List<ChatRoom> 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<ChatRoom> 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<ChatRoom>,
|
||||
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<ChatRoom> 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<ChatRoom>,
|
||||
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<ChatRoom> 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<ChatRoom> chatRooms,
|
||||
final bool isLoadingMoreChats,
|
||||
final String? errorMessage}) = _$ChatsStateImpl;
|
||||
|
||||
@override
|
||||
@@ -217,6 +238,8 @@ abstract class _ChatsState implements ChatsState {
|
||||
@override
|
||||
List<ChatRoom> get chatRooms;
|
||||
@override
|
||||
bool get isLoadingMoreChats;
|
||||
@override
|
||||
String? get errorMessage;
|
||||
|
||||
/// Create a copy of ChatsState
|
||||
|
||||
@@ -11,18 +11,20 @@ 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';
|
||||
|
||||
class ChatScreen extends StatefulWidget {
|
||||
final String chatId;
|
||||
final ChatsCubit chatsCubit;
|
||||
const ChatScreen({
|
||||
required this.chatId,
|
||||
required this.chatsCubit,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@@ -36,6 +38,7 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
final ChatRoomCubit chatRoomCubit = sl<ChatRoomCubit>();
|
||||
final List<({int id, int index})> unreadMessagesIds = [];
|
||||
final List<({int id, int index})> unreadMessagesIdsCopy = [];
|
||||
final showableChatBadgeStates = ChosenPlanStateEnum.getShowableChatBadgeStates();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -53,6 +56,7 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
@override
|
||||
void dispose() {
|
||||
scrollController.dispose();
|
||||
chatRoomCubit.close();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -80,6 +84,9 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
}
|
||||
|
||||
_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(
|
||||
@@ -88,12 +95,12 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
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,
|
||||
@@ -103,7 +110,7 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
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,
|
||||
@@ -116,7 +123,7 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
state.chatRoom.users['to_chat_user']!.name,
|
||||
state.chatRoom.users.receiver.name,
|
||||
style: CustomTextStyles.titleSmallBold.copyWith(
|
||||
color: PrimaryColors().black,
|
||||
),
|
||||
@@ -138,28 +145,38 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
),
|
||||
),
|
||||
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),
|
||||
@@ -174,7 +191,9 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
() async {
|
||||
final result = await context.read<ChatRoomCubit>().markMessagesAsRead(state.chatRoom.id, unreadMessagesIdsCopy);
|
||||
if (!result) return;
|
||||
widget.chatsCubit.reduceUnreadMessagesCount(chatId: state.chatRoom.id, count: unreadMessagesIdsCopy.length);
|
||||
context
|
||||
.read<ChatsCubit>()
|
||||
.reduceUnreadMessagesCount(chatId: state.chatRoom.id, count: unreadMessagesIdsCopy.length);
|
||||
unreadMessagesIdsCopy.clear();
|
||||
},
|
||||
);
|
||||
@@ -191,7 +210,7 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
],
|
||||
);
|
||||
}
|
||||
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) {
|
||||
@@ -203,7 +222,7 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
() async {
|
||||
final result = await context.read<ChatRoomCubit>().markMessagesAsRead(state.chatRoom.id, unreadMessagesIds);
|
||||
if (!result) return;
|
||||
widget.chatsCubit.reduceUnreadMessagesCount(chatId: state.chatRoom.id, count: unreadMessagesIds.length);
|
||||
context.read<ChatsCubit>().reduceUnreadMessagesCount(chatId: state.chatRoom.id, count: unreadMessagesIds.length);
|
||||
unreadMessagesIds.clear();
|
||||
},
|
||||
);
|
||||
@@ -217,157 +236,208 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
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<ChatRoomCubit>().cancelChosenPlan(chatId: state.chatRoom.id, planId: chosenPlan.id);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
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<File> 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<File> 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),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -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<ChatsScreen> createState() => _ChatsScreenState();
|
||||
}
|
||||
|
||||
class _ChatsScreenState extends State<ChatsScreen> {
|
||||
class _ChatsScreenState extends State<ChatsScreen> {
|
||||
final searchController = TextEditingController();
|
||||
|
||||
Widget build(BuildContext context) {
|
||||
@@ -65,45 +66,40 @@ class _ChatsScreenState extends State<ChatsScreen> {
|
||||
),
|
||||
];
|
||||
},
|
||||
body: stateBuilder(state),
|
||||
body: switch (state.state) {
|
||||
BaseState.error => DataErrorWidget(onReload: () => context.read<ChatsCubit>().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<ChatsCubit>().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<ScrollNotification>(
|
||||
onNotification: (notification) {
|
||||
loadNewContent(notification, context.read<ChatsCubit>().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]);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
@@ -28,7 +26,6 @@ class _ChatEntryWidgetState extends State<ChatEntryWidget> {
|
||||
'chatScreen',
|
||||
extra: {
|
||||
'chatId': widget.chatRoom.id.toString(),
|
||||
'chatsCubit': context.read<ChatsCubit>(),
|
||||
},
|
||||
),
|
||||
child: Ink(
|
||||
|
||||
@@ -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 }
|
||||
138
lib/features/chat/presentation/widgets/order_card.dart
Normal file
138
lib/features/chat/presentation/widgets/order_card.dart
Normal file
@@ -0,0 +1,138 @@
|
||||
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 StatefulWidget {
|
||||
final PlanModel plan;
|
||||
final String optionType;
|
||||
final bool isUserView;
|
||||
final Future<void> Function() onCancel;
|
||||
const OrderCard({super.key, required this.plan, required this.isUserView, required this.optionType, required this.onCancel});
|
||||
|
||||
@override
|
||||
State<OrderCard> createState() => _OrderCardState();
|
||||
}
|
||||
|
||||
class _OrderCardState extends State<OrderCard> {
|
||||
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),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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<List<ChatRoom>> getChatRoomPreviews({String? query}) async {
|
||||
Future<ChatRoomPaginationModel> 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;
|
||||
}
|
||||
@@ -93,4 +93,14 @@ class ChatRepository {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> cancelChosenPlan({
|
||||
required int id,
|
||||
}) async {
|
||||
try {
|
||||
await chatService.cancelChosenPlan(id: id);
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<ChatRoomPreviewModel> getChatRoomPreviews({
|
||||
Future<ChatRoomPaginationModel> getChatRooms({
|
||||
@Query('page') required int page,
|
||||
@Query('find') String? query,
|
||||
});
|
||||
|
||||
@@ -40,5 +41,13 @@ abstract class ChatService {
|
||||
});
|
||||
|
||||
@POST('/api/chat/{id}/messages/markAsRead')
|
||||
Future<void> markMessagesAsRead({@Path() required String id, @Body() required Map<String, List<int>> body});
|
||||
Future<void> markMessagesAsRead({
|
||||
@Path() required String id,
|
||||
@Body() required Map<String, List<int>> body,
|
||||
});
|
||||
|
||||
@POST('/api/chosen_plans/{id}/cancel')
|
||||
Future<void> cancelChosenPlan({
|
||||
@Path() required int id,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -18,13 +18,16 @@ class _ChatService implements ChatService {
|
||||
final ParseErrorLogger? errorLogger;
|
||||
|
||||
@override
|
||||
Future<ChatRoomPreviewModel> getChatRoomPreviews({String? query}) async {
|
||||
Future<ChatRoomPaginationModel> getChatRooms({
|
||||
required int page,
|
||||
String? query,
|
||||
}) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{r'find': query};
|
||||
final queryParameters = <String, dynamic>{r'page': page, r'find': query};
|
||||
queryParameters.removeWhere((k, v) => v == null);
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<ChatRoomPreviewModel>(
|
||||
final _options = _setStreamType<ChatRoomPaginationModel>(
|
||||
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<Map<String, dynamic>>(_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;
|
||||
@@ -190,6 +193,25 @@ class _ChatService implements ChatService {
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> cancelChosenPlan({required int id}) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<void>(
|
||||
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<void>(_options);
|
||||
}
|
||||
|
||||
RequestOptions _setStreamType<T>(RequestOptions requestOptions) {
|
||||
if (T != dynamic &&
|
||||
!(requestOptions.responseType == ResponseType.bytes ||
|
||||
|
||||
@@ -140,10 +140,10 @@ class GetChatRoomPreviews implements TestCases {
|
||||
Future<bool> run({required String baseUrl}) async {
|
||||
try {
|
||||
// get all of needed services
|
||||
final dio = sl<Dio>();
|
||||
final chatService = ChatService(dio, baseUrl: baseUrl);
|
||||
// final dio = sl<Dio>();
|
||||
// final chatService = ChatService(dio, baseUrl: baseUrl);
|
||||
|
||||
await chatService.getChatRoomPreviews();
|
||||
// await chatService.getChatRooms();
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
@@ -158,11 +158,11 @@ class GetChatRoom implements TestCases {
|
||||
@override
|
||||
Future<bool> run({required String baseUrl}) async {
|
||||
try {
|
||||
final dio = sl<Dio>();
|
||||
final chatService = ChatService(dio, baseUrl: baseUrl);
|
||||
// final dio = sl<Dio>();
|
||||
// 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;
|
||||
@@ -177,11 +177,11 @@ class SendMessage implements TestCases {
|
||||
@override
|
||||
Future<bool> run({required String baseUrl}) async {
|
||||
try {
|
||||
final dio = sl<Dio>();
|
||||
final chatService = ChatService(dio, baseUrl: baseUrl);
|
||||
// final dio = sl<Dio>();
|
||||
// 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;
|
||||
@@ -196,11 +196,11 @@ class GetChatMessages implements TestCases {
|
||||
@override
|
||||
Future<bool> run({required String baseUrl}) async {
|
||||
try {
|
||||
final dio = sl<Dio>();
|
||||
final chatService = ChatService(dio, baseUrl: baseUrl);
|
||||
// final dio = sl<Dio>();
|
||||
// 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;
|
||||
|
||||
@@ -115,7 +115,7 @@ class DietsCubit extends Cubit<DietsState> {
|
||||
}
|
||||
}
|
||||
|
||||
loadNextPage() async {
|
||||
Future<void> loadNextPage() async {
|
||||
if (currentPage < lastPage && !isLoading) {
|
||||
isLoading = true;
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ class FeedCubit extends Cubit<FeedState> {
|
||||
}
|
||||
}
|
||||
|
||||
loadNextPage() async {
|
||||
Future<void> loadNextPage() async {
|
||||
if (currentPage < lastPage && !isLoading) {
|
||||
isLoading = true;
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@ class PlansCubit extends Cubit<PlansState> {
|
||||
}
|
||||
}
|
||||
|
||||
loadNextPage() async {
|
||||
Future<void> loadNextPage() async {
|
||||
if (currentPage < lastPage && !isLoading) {
|
||||
isLoading = true;
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ class RecipesCubit extends Cubit<RecipesState> {
|
||||
}
|
||||
}
|
||||
|
||||
loadNextPage() async {
|
||||
Future<void> loadNextPage() async {
|
||||
if (currentPage < lastPage && !isLoading) {
|
||||
isLoading = true;
|
||||
|
||||
|
||||
@@ -77,38 +77,12 @@ class _FeedScreenContentState extends State<FeedScreenContent> {
|
||||
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<FeedCubit>().loadNextPage();
|
||||
}
|
||||
}
|
||||
|
||||
_onScrollRecipes() {
|
||||
if (recipesScrollController.offset >= recipesScrollController.position.maxScrollExtent && !recipesScrollController.position.outOfRange) {
|
||||
context.read<RecipesCubit>().loadNextPage();
|
||||
}
|
||||
}
|
||||
|
||||
_onScrollDiets() {
|
||||
if (dietsScrollController.offset >= dietsScrollController.position.maxScrollExtent && !dietsScrollController.position.outOfRange) {
|
||||
context.read<DietsCubit>().loadNextPage();
|
||||
}
|
||||
}
|
||||
|
||||
_onScrollPlans() {
|
||||
if (plansScrollController.offset >= plansScrollController.position.maxScrollExtent && !plansScrollController.position.outOfRange) {
|
||||
context.read<PlansCubit>().loadNextPage();
|
||||
}
|
||||
}
|
||||
|
||||
_onScrollConsultants() {
|
||||
if (consultantsScrollController.offset >= consultantsScrollController.position.maxScrollExtent && !consultantsScrollController.position.outOfRange) {}
|
||||
|
||||
@@ -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<FeedCubit, FeedState>(
|
||||
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<ScrollNotification>(
|
||||
onNotification: (notification) {
|
||||
loadNewContent(notification, context.read<FeedCubit>().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(
|
||||
|
||||
@@ -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<ScrollNotification>(
|
||||
onNotification: (notification) {
|
||||
loadNewContent(notification, context.read<DietsCubit>().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,
|
||||
|
||||
@@ -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<ScrollNotification>(
|
||||
onNotification: (notification) {
|
||||
loadNewContent(notification, context.read<PlansCubit>().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,
|
||||
|
||||
@@ -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<ScrollNotification>(
|
||||
onNotification: (notification) {
|
||||
loadNewContent(notification, context.read<RecipesCubit>().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,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
@@ -155,7 +155,7 @@ class MenuScreen extends StatelessWidget {
|
||||
);
|
||||
} catch (e) {
|
||||
} finally {
|
||||
await TokenStorage.removeTokenInStorage();
|
||||
await TokenStorage.removeTokenInStorage();
|
||||
GoRouter.of(context).go('/auth-screen', extra: true);
|
||||
}
|
||||
},
|
||||
|
||||
44
lib/features/plans/enums/chosen_plan_state_enum.dart
Normal file
44
lib/features/plans/enums/chosen_plan_state_enum.dart
Normal file
@@ -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<ChosenPlanStateEnum> getShowableChatBadgeStates() {
|
||||
return [
|
||||
ChosenPlanStateEnum.stateInCoordination,
|
||||
ChosenPlanStateEnum.stateStartDateHasBeenSet,
|
||||
ChosenPlanStateEnum.statePendingPayment,
|
||||
ChosenPlanStateEnum.statePaid,
|
||||
ChosenPlanStateEnum.stateLastDayStarted,
|
||||
ChosenPlanStateEnum.stateLastDayFinished,
|
||||
ChosenPlanStateEnum.stateDone,
|
||||
];
|
||||
}
|
||||
}
|
||||
29
lib/features/plans/models/chosen_plan_model.dart
Normal file
29
lib/features/plans/models/chosen_plan_model.dart
Normal file
@@ -0,0 +1,29 @@
|
||||
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';
|
||||
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: '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<String, dynamic> json) => _$ChosenPlanModelFromJson(json);
|
||||
}
|
||||
|
||||
ChosenPlanModel? parseChosenPlan(json) {
|
||||
if (json is Map<String, dynamic>) {
|
||||
return ChosenPlanModel.fromJson(json);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
332
lib/features/plans/models/chosen_plan_model.freezed.dart
Normal file
332
lib/features/plans/models/chosen_plan_model.freezed.dart
Normal file
@@ -0,0 +1,332 @@
|
||||
// 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>(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<String, dynamic> 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: 'last_state')
|
||||
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<String, dynamic> 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<ChosenPlanModel> 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: 'last_state') ChosenPlanStateEnum chosenPlanState,
|
||||
@JsonKey(name: 'chat_id') String chatId,
|
||||
@JsonKey(name: 'consultant_id') int consultantId,
|
||||
@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? chosenPlanState = null,
|
||||
Object? chatId = null,
|
||||
Object? consultantId = 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,
|
||||
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,
|
||||
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
|
||||
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: 'last_state') ChosenPlanStateEnum chosenPlanState,
|
||||
@JsonKey(name: 'chat_id') String chatId,
|
||||
@JsonKey(name: 'consultant_id') int consultantId,
|
||||
@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? chosenPlanState = null,
|
||||
Object? chatId = null,
|
||||
Object? consultantId = 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,
|
||||
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,
|
||||
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,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @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: 'last_state') required this.chosenPlanState,
|
||||
@JsonKey(name: 'chat_id') required this.chatId,
|
||||
@JsonKey(name: 'consultant_id') required this.consultantId,
|
||||
@JsonKey(name: 'plan') required this.plan});
|
||||
|
||||
factory _$ChosenPlanModelImpl.fromJson(Map<String, dynamic> 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: 'last_state')
|
||||
final ChosenPlanStateEnum chosenPlanState;
|
||||
@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, consultantId: $consultantId, 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.chosenPlanState, chosenPlanState) ||
|
||||
other.chosenPlanState == chosenPlanState) &&
|
||||
(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, consultantId, 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<String, dynamic> 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: 'last_state')
|
||||
required final ChosenPlanStateEnum chosenPlanState,
|
||||
@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<String, dynamic> 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: 'last_state')
|
||||
ChosenPlanStateEnum get chosenPlanState;
|
||||
@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.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$ChosenPlanModelImplCopyWith<_$ChosenPlanModelImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
49
lib/features/plans/models/chosen_plan_model.g.dart
Normal file
49
lib/features/plans/models/chosen_plan_model.g.dart
Normal file
@@ -0,0 +1,49 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'chosen_plan_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_$ChosenPlanModelImpl _$$ChosenPlanModelImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$ChosenPlanModelImpl(
|
||||
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,
|
||||
consultantId: (json['consultant_id'] as num).toInt(),
|
||||
plan: PlanModel.fromJson(json['plan'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ChosenPlanModelImplToJson(
|
||||
_$ChosenPlanModelImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'option_type': instance.optionType,
|
||||
'start_date': instance.startDate.toIso8601String(),
|
||||
'last_state': _$ChosenPlanStateEnumEnumMap[instance.chosenPlanState]!,
|
||||
'chat_id': instance.chatId,
|
||||
'consultant_id': instance.consultantId,
|
||||
'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',
|
||||
};
|
||||
@@ -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<AboutPlanState> {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<ChosenPlanModel?> 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',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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<AboutPlanScreen> {
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
backgroundColor: appTheme.greenA700,
|
||||
onPressed: () {
|
||||
/// TODO: добавить обработку покупки плана
|
||||
// showModalBottomSheet(
|
||||
// context: context,
|
||||
// builder: (context) => StartDietBottomSheet(
|
||||
// aboutDietCubit: context.read<AboutDietCubit>(),
|
||||
// ),
|
||||
// );
|
||||
onPressed: () async {
|
||||
final chosenPlan = await context.read<AboutPlanCubit>().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),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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<ChosenPlanModel> chosePlan(String slug, Map<String, dynamic> 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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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<PlanModel> getPlan(@Path('slug') String slug);
|
||||
|
||||
@POST('/api/plans/{slug}/like')
|
||||
@POST('/api/plans/{slug}/like')
|
||||
Future<void> likePlan({
|
||||
@Path() required String slug,
|
||||
});
|
||||
@@ -28,4 +26,10 @@ abstract class PlanService {
|
||||
Future<void> removeFromFavorite({
|
||||
@Path() required String slug,
|
||||
});
|
||||
}
|
||||
|
||||
@POST('/api/plans/{slug}/choose')
|
||||
Future<ChosenPlanModel> chosePlan({
|
||||
@Path() required String slug,
|
||||
@Body() required Map<String, dynamic> option,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -101,6 +101,37 @@ class _PlanService implements PlanService {
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ChosenPlanModel> chosePlan({
|
||||
required String slug,
|
||||
required Map<String, dynamic> option,
|
||||
}) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = <String, dynamic>{};
|
||||
_data.addAll(option);
|
||||
final _options = _setStreamType<ChosenPlanModel>(
|
||||
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<Map<String, dynamic>>(_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<T>(RequestOptions requestOptions) {
|
||||
if (T != dynamic &&
|
||||
!(requestOptions.responseType == ResponseType.bytes ||
|
||||
|
||||
@@ -101,8 +101,9 @@ class ProfileCubit extends Cubit<ProfileState> {
|
||||
}) async {
|
||||
try {
|
||||
return (await chatRepository.getChatRoomIdByUserSlug(slug: slug)).id;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
} catch (e, st) {
|
||||
log(e.toString(), stackTrace: st);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1079,7 +1079,9 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
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(
|
||||
|
||||
@@ -62,8 +62,10 @@ class _SubActionButtonWidgetState extends State<SubActionButtonWidget> {
|
||||
return InkWell(
|
||||
onTap: () async {
|
||||
GoRouter.of(context).pushNamed(
|
||||
'chatScreen',
|
||||
extra: await sl<ProfileCubit>().getChatRoomIdBySlug(slug: widget.slug),
|
||||
'chatScreen',
|
||||
extra: {
|
||||
'chatId': await sl<ProfileCubit>().getChatRoomIdBySlug(slug: widget.slug),
|
||||
},
|
||||
);
|
||||
},
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
|
||||
@@ -39,10 +39,8 @@ MessageLookupByLibrary? _findExact(String localeName) {
|
||||
/// User programs should call this before using [localeName] for messages.
|
||||
Future<bool> 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);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,353 +22,301 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
|
||||
final messages = _notInlinedMessages(_notInlinedMessages);
|
||||
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
|
||||
"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("Ваш вес:")
|
||||
};
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -312,6 +312,18 @@
|
||||
"could_not_publish_blog_post": "Не удалось опубликовать пост",
|
||||
"could_not_update_blog_post": "Не удалось обновить пост",
|
||||
"could_not_delete_blog_post": "Не удалось удалить пост",
|
||||
"infoAboutOrder": "Информация о заказе"
|
||||
"infoAboutOrder": "Информация о заказе",
|
||||
"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": "Оплатить",
|
||||
"more_about_order": "Подробнее о заказе",
|
||||
"cancel_order": "Отменить заказ",
|
||||
"refuse_order":"Отказаться от заказа"
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user