forked from eatvio/eatvio_app
Merge remote-tracking branch 'upstream/main'
This commit is contained in:
@@ -22,6 +22,7 @@ import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
|
||||
import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart';
|
||||
import 'package:eatvio_app/features/feed/models/recipes_model.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/pages/feed_screen.dart';
|
||||
import 'package:eatvio_app/features/glossary/presentation/pages/glossary_screen.dart';
|
||||
import 'package:eatvio_app/features/menu/presentation/pages/menu_screen.dart';
|
||||
import 'package:eatvio_app/features/my_diets/presentation/my_diets_screen.dart';
|
||||
import 'package:eatvio_app/features/my_plans/presentation/my_plans_screen.dart';
|
||||
@@ -65,7 +66,17 @@ class AppRouter {
|
||||
}
|
||||
return null;
|
||||
},
|
||||
builder: (context, state) => AuthScreen.builder(context),
|
||||
builder: (context, state) {
|
||||
final bool needLogout;
|
||||
if (state.extra == null) {
|
||||
needLogout = false;
|
||||
} else {
|
||||
needLogout = true;
|
||||
}
|
||||
return AuthScreen(
|
||||
needLogout: needLogout,
|
||||
);
|
||||
},
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'registration-screen',
|
||||
@@ -127,6 +138,11 @@ class AppRouter {
|
||||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: '/glossary-screen',
|
||||
name: '/glossaryScreen',
|
||||
builder: (context, state) => GlossaryScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/about-recipes-screen',
|
||||
name: 'aboutRecipesScreen',
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
32
lib/core/credentials_storage.dart
Normal file
32
lib/core/credentials_storage.dart
Normal file
@@ -0,0 +1,32 @@
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
|
||||
abstract class CredentialsStorage {
|
||||
static Future<bool> haveCredentialsInStorage() async {
|
||||
try {
|
||||
if (await FlutterSecureStorage().read(key: 'email') == null || await FlutterSecureStorage().read(key: 'password') == null) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<Map<String, String>> getCredentialsFromStorage() async {
|
||||
return {
|
||||
'email': (await FlutterSecureStorage().read(key: 'email'))!,
|
||||
'password': (await FlutterSecureStorage().read(key: 'password'))!,
|
||||
};
|
||||
}
|
||||
|
||||
static saveCredentials(String email, String password) async {
|
||||
await FlutterSecureStorage().write(key: 'email', value: email);
|
||||
await FlutterSecureStorage().write(key: 'password', value: password);
|
||||
}
|
||||
|
||||
static removeCredentials() async {
|
||||
await FlutterSecureStorage().delete(key: 'email');
|
||||
await FlutterSecureStorage().delete(key: 'password');
|
||||
}
|
||||
}
|
||||
@@ -67,6 +67,7 @@ import 'package:eatvio_app/features/settings/presentation/bloc/settings_cubit/se
|
||||
import 'package:eatvio_app/features/settings/repositories/service_repository.dart';
|
||||
import 'package:eatvio_app/features/settings/services/settings_service.dart';
|
||||
import 'package:eatvio_app/features/user_details/presentation/cubit/user_details_cubit.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:eatvio_app/features/profile/presentation/bloc/plans_cubit/plans_cubit.dart' as profilePlans;
|
||||
|
||||
@@ -161,4 +162,5 @@ Future<void> init() async {
|
||||
),
|
||||
),
|
||||
);
|
||||
sl.registerLazySingleton(() async => await FlutterSecureStorage());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ abstract class TokenStorage {
|
||||
sl<Dio>().options.headers['Authorization'] = 'Bearer $token';
|
||||
}
|
||||
|
||||
static haveTokenInStorage() async {
|
||||
static Future<bool> haveTokenInStorage() async {
|
||||
try {
|
||||
if (await FlutterSecureStorage().read(key: 'token') == null) {
|
||||
return false;
|
||||
|
||||
@@ -1,41 +1,22 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/core/credentials_storage.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/token_storage.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/const/strings.dart';
|
||||
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/profile_avatar_cubit/profile_avatar_cubit.dart';
|
||||
import 'package:eatvio_app/generated/l10n.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_native_splash/flutter_native_splash.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:validators/validators.dart';
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
|
||||
import 'bloc/auth_bloc.dart';
|
||||
import 'models/auth_model.dart';
|
||||
|
||||
class AuthScreen extends StatefulWidget {
|
||||
static Widget builder(BuildContext context) {
|
||||
return BlocProvider<AuthBloc>(
|
||||
create: (context) => AuthBloc(
|
||||
AuthState(
|
||||
authModelObj: AuthModel(),
|
||||
),
|
||||
)..add(
|
||||
AuthInitialEvent(),
|
||||
),
|
||||
child: AuthScreen(),
|
||||
);
|
||||
}
|
||||
final bool needLogout;
|
||||
|
||||
const AuthScreen({
|
||||
this.needLogout = false,
|
||||
});
|
||||
|
||||
@override
|
||||
State<AuthScreen> createState() => _AuthScreenState();
|
||||
@@ -47,51 +28,80 @@ class _AuthScreenState extends State<AuthScreen> {
|
||||
final baseUrlController = TextEditingController();
|
||||
late final WebViewController _controller;
|
||||
|
||||
String email = '';
|
||||
String password = '';
|
||||
bool needLogout = false;
|
||||
|
||||
Future<void> logoutFromWeb() async {
|
||||
await CredentialsStorage.removeCredentials();
|
||||
await _controller.runJavaScript('''
|
||||
document.querySelector('.header-list__link button[type="submit"]').click();
|
||||
''');
|
||||
}
|
||||
|
||||
Future<void> loginInApplication() async {
|
||||
final credentialsFromStorage = await CredentialsStorage.getCredentialsFromStorage();
|
||||
final Map<String, String> credentials = {
|
||||
'email': credentialsFromStorage['email']!,
|
||||
'password': credentialsFromStorage['password']!,
|
||||
};
|
||||
final response = await http.post(
|
||||
Uri.parse(baseUrl + '/api/login'),
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: json.encode(credentials),
|
||||
encoding: utf8,
|
||||
);
|
||||
var res = await jsonDecode(response.body);
|
||||
final token = res['token'];
|
||||
await TokenStorage.saveTokenInStorage(token);
|
||||
await Future.delayed(Duration.zero, () => GoRouter.of(context).go('/my-profile-screen'));
|
||||
await sl<ProfileAvatarCubit>().getMyProfile();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
needLogout = widget.needLogout;
|
||||
|
||||
_controller = WebViewController()
|
||||
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||||
..addJavaScriptChannel(
|
||||
'FlutterChannel',
|
||||
onMessageReceived: (JavaScriptMessage message) {
|
||||
// Handle messages from JavaScript
|
||||
final data = jsonDecode(message.message);
|
||||
final email = data['email'];
|
||||
final password = data['password'];
|
||||
print('Email: $email, Password: $password');
|
||||
email = data['email'];
|
||||
password = data['password'];
|
||||
},
|
||||
)
|
||||
..setNavigationDelegate(
|
||||
NavigationDelegate(
|
||||
onPageFinished: (String url) async {
|
||||
await _controller.runJavaScript('''
|
||||
function initializeListeners() {
|
||||
const emailInput = document.getElementById("inputEmail_main");
|
||||
const passwordInput = document.getElementById("inputPassword_main");
|
||||
final bool tokenInStorage = await TokenStorage.haveTokenInStorage();
|
||||
final bool credentialsInStorage = await CredentialsStorage.haveCredentialsInStorage();
|
||||
|
||||
if (emailInput && passwordInput) {
|
||||
function sendToFlutter() {
|
||||
const email = emailInput.value;
|
||||
const password = passwordInput.value;
|
||||
const data = JSON.stringify({ email: email, password: password });
|
||||
if (window.FlutterChannel) {
|
||||
window.FlutterChannel.postMessage(data);
|
||||
}
|
||||
}
|
||||
|
||||
emailInput.addEventListener("input", sendToFlutter);
|
||||
passwordInput.addEventListener("input", sendToFlutter);
|
||||
if (needLogout) {
|
||||
await logoutFromWeb();
|
||||
needLogout = false;
|
||||
} else if (!url.contains('profile') && !url.contains('registration')) {
|
||||
await _controller.runJavaScript(jsChannelAuthScript);
|
||||
} else if (url.contains('profile')) {
|
||||
if (credentialsInStorage) {
|
||||
await loginInApplication();
|
||||
} else {
|
||||
if (email.isNotEmpty && password.isNotEmpty) {
|
||||
await CredentialsStorage.saveCredentials(email, password);
|
||||
await loginInApplication();
|
||||
} else {
|
||||
console.error("Email or Password input not found.");
|
||||
await logoutFromWeb();
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure DOM is loaded before attaching listeners
|
||||
document.addEventListener("DOMContentLoaded", initializeListeners);
|
||||
initializeListeners();
|
||||
''');
|
||||
} else {
|
||||
if (tokenInStorage && credentialsInStorage) {
|
||||
GoRouter.of(context).go('/my-profile-screen');
|
||||
} else if (!tokenInStorage && credentialsInStorage) {
|
||||
await loginInApplication();
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
@@ -101,269 +111,13 @@ class _AuthScreenState extends State<AuthScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
FlutterNativeSplash.remove();
|
||||
final s = S.of(context);
|
||||
|
||||
// return Scaffold(
|
||||
// appBar: AppBar(
|
||||
// toolbarHeight: 0,
|
||||
// ),
|
||||
// body: WebViewWidget(controller: _controller),
|
||||
// );
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
title: GestureDetector(
|
||||
onLongPress: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text('Base url без https:// и /api'),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
CustomTextFormField(
|
||||
controller: baseUrlController,
|
||||
hintText: 'dev2.eatvio.com',
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
InkWell(
|
||||
onTap: () async {
|
||||
baseUrl = 'https://${baseUrlController.text}';
|
||||
sl<Dio>().options.baseUrl = baseUrl;
|
||||
},
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
child: Ink(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
color: appTheme.blueA400,
|
||||
),
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
'Сохранить',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: SvgPicture.asset(
|
||||
ImageConstant.imgLogoEatvio,
|
||||
height: 70,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
toolbarHeight: 0,
|
||||
),
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(s.email),
|
||||
const SizedBox(height: 4),
|
||||
BlocSelector<AuthBloc, AuthState, TextEditingController?>(
|
||||
selector: (state) => state.emailController,
|
||||
builder: (context, emailController) {
|
||||
return CustomTextFormField(
|
||||
controller: emailController,
|
||||
textInputAction: TextInputAction.next,
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
textInputType: TextInputType.emailAddress,
|
||||
hintText: 'Введите email',
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(s.password),
|
||||
const SizedBox(height: 4),
|
||||
BlocSelector<AuthBloc, AuthState, TextEditingController?>(
|
||||
selector: (state) => state.passwordController,
|
||||
builder: (context, passwordController) {
|
||||
return CustomTextFormField(
|
||||
obscureText: hidePassword,
|
||||
controller: passwordController,
|
||||
hintText: 'Введите пароль',
|
||||
suffix: IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
hidePassword = !hidePassword;
|
||||
});
|
||||
},
|
||||
icon: Icon(
|
||||
hidePassword ? Icons.visibility_outlined : Icons.visibility_off_outlined,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text('Нет аккаунта? '),
|
||||
GestureDetector(
|
||||
onTap: () => GoRouter.of(context).goNamed('registrationScreen'),
|
||||
child: Text(
|
||||
'Зарегистрироваться',
|
||||
style: TextStyle(
|
||||
color: appTheme.blueA400,
|
||||
decorationColor: appTheme.blueA400,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
Center(
|
||||
child: RichText(
|
||||
textAlign: TextAlign.center,
|
||||
text: TextSpan(
|
||||
text: 'Нажимая "Войти", Вы соглашаетесь \n',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
),
|
||||
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),
|
||||
BlocBuilder<AuthBloc, AuthState>(
|
||||
builder: (context, state) {
|
||||
return Container(
|
||||
height: 48,
|
||||
width: MediaQuery.of(context).size.width - 32,
|
||||
child: FloatingActionButton.extended(
|
||||
heroTag: 'authButton',
|
||||
highlightElevation: 0,
|
||||
elevation: 0,
|
||||
focusElevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
backgroundColor: appTheme.blueA400,
|
||||
onPressed: onTapAuth(state, context),
|
||||
label: Text(
|
||||
'Войти',
|
||||
style: theme.textTheme.titleSmall!.copyWith(color: Colors.white),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
child: WebViewWidget(controller: _controller),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
onTapAuth(AuthState state, BuildContext context) {
|
||||
final s = S.of(context);
|
||||
return () async {
|
||||
List<String> errors = validateFields(state.emailController!.text, state.passwordController!.text);
|
||||
if (errors.isEmpty) {
|
||||
final Map<String, dynamic> credentials = {
|
||||
'email': state.emailController!.text,
|
||||
'password': state.passwordController!.text,
|
||||
};
|
||||
final response = await http.post(
|
||||
Uri.parse(baseUrl + '/api/login'),
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: json.encode(credentials),
|
||||
encoding: utf8,
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
var res = await jsonDecode(response.body);
|
||||
final token = res['token'];
|
||||
await TokenStorage.saveTokenInStorage(token);
|
||||
GoRouter.of(context).go('/my-profile-screen');
|
||||
sl<ProfileAvatarCubit>().getMyProfile();
|
||||
} else {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text('Ошибка'),
|
||||
content: Text(s.wrong_credentials),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: Text('OK'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
String errorMessage = '';
|
||||
|
||||
for (var error in errors) {
|
||||
errorMessage += error + '\n\n';
|
||||
}
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text('Ошибка'),
|
||||
content: Text(errorMessage),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: Text('OK'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
List<String> validateFields(String email, String password) {
|
||||
final s = S.of(context);
|
||||
|
||||
List<String> errors = [];
|
||||
|
||||
if (!isEmail(email)) {
|
||||
errors.add(s.email_invalid);
|
||||
}
|
||||
|
||||
if (email.isEmpty) {
|
||||
errors.add(s.email_empty);
|
||||
}
|
||||
|
||||
if (password.isEmpty) {
|
||||
errors.add(s.password_empty);
|
||||
}
|
||||
|
||||
if (password.length < 6) {
|
||||
errors.add(s.password_short);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
import 'package:eatvio_app/features/auth/auth_screen/models/auth_model.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
part 'auth_event.dart';
|
||||
part 'auth_state.dart';
|
||||
|
||||
/// A bloc that manages the state of a Auth according to the event that is dispatched to it.
|
||||
class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
||||
AuthBloc(AuthState initialState) : super(initialState) {
|
||||
on<AuthInitialEvent>(_onInitialize);
|
||||
}
|
||||
|
||||
_onInitialize(
|
||||
AuthInitialEvent event,
|
||||
Emitter<AuthState> emit,
|
||||
) async {
|
||||
emit(
|
||||
state.copyWith(
|
||||
emailController: TextEditingController(),
|
||||
passwordController: TextEditingController(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
// ignore_for_file: must_be_immutable
|
||||
|
||||
part of 'auth_bloc.dart';
|
||||
|
||||
/// Abstract class for all events that can be dispatched from the
|
||||
///Credentials widget.
|
||||
///
|
||||
/// Events must be immutable and implement the [Equatable] interface.
|
||||
@immutable
|
||||
abstract class AuthEvent extends Equatable {}
|
||||
|
||||
/// Event that is dispatched when the Credentials widget is first created.
|
||||
class AuthInitialEvent extends AuthEvent {
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
// ignore_for_file: must_be_immutable
|
||||
|
||||
part of 'auth_bloc.dart';
|
||||
|
||||
/// Represents the state of Auth in the application.
|
||||
class AuthState extends Equatable {
|
||||
AuthState({
|
||||
this.emailController,
|
||||
this.passwordController,
|
||||
this.authModelObj,
|
||||
});
|
||||
|
||||
TextEditingController? emailController;
|
||||
|
||||
TextEditingController? passwordController;
|
||||
|
||||
AuthModel? authModelObj;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
emailController,
|
||||
passwordController,
|
||||
authModelObj,
|
||||
];
|
||||
|
||||
AuthState copyWith({
|
||||
TextEditingController? emailController,
|
||||
TextEditingController? passwordController,
|
||||
AuthModel? authModelObj,
|
||||
}) {
|
||||
return AuthState(
|
||||
emailController: emailController ?? this.emailController,
|
||||
passwordController: passwordController ?? this.passwordController,
|
||||
authModelObj: authModelObj ?? this.authModelObj,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
// ignore_for_file: must_be_immutable
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
/// This class defines the variables used in the [auth_screen],
|
||||
/// and is typically used to hold data that is passed between different parts of the application.
|
||||
class AuthModel extends Equatable {
|
||||
AuthModel();
|
||||
|
||||
AuthModel copyWith() {
|
||||
return AuthModel();
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
22
lib/features/auth/const/strings.dart
Normal file
22
lib/features/auth/const/strings.dart
Normal file
@@ -0,0 +1,22 @@
|
||||
const String jsChannelAuthScript = '''
|
||||
function initializeListeners() {
|
||||
const emailInput = document.getElementById("inputEmail_main");
|
||||
const passwordInput = document.getElementById("inputPassword_main");
|
||||
if (emailInput && passwordInput) {
|
||||
function sendToFlutter() {
|
||||
const email = emailInput.value;
|
||||
const password = passwordInput.value;
|
||||
const data = JSON.stringify({ email: email, password: password });
|
||||
if (window.FlutterChannel) {
|
||||
window.FlutterChannel.postMessage(data);
|
||||
}
|
||||
}
|
||||
emailInput.addEventListener("input", sendToFlutter);
|
||||
passwordInput.addEventListener("input", sendToFlutter);
|
||||
} else {
|
||||
console.error("Email or Password input not found.");
|
||||
}
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", initializeListeners);
|
||||
initializeListeners();
|
||||
''';
|
||||
@@ -0,0 +1,33 @@
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
|
||||
class GlossaryScreen extends StatefulWidget {
|
||||
const GlossaryScreen({super.key});
|
||||
|
||||
@override
|
||||
State<GlossaryScreen> createState() => _GlossaryScreenState();
|
||||
}
|
||||
|
||||
class _GlossaryScreenState extends State<GlossaryScreen> {
|
||||
late final WebViewController _controller;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
_controller = WebViewController()
|
||||
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||||
..loadRequest(Uri.parse(baseUrl + '/product_nutritional_value'));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text('Глоссарий'),
|
||||
),
|
||||
body: WebViewWidget(controller: _controller),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -127,7 +127,7 @@ class MenuScreen extends StatelessWidget {
|
||||
} catch (e) {
|
||||
} finally {
|
||||
await TokenStorage.removeTokenInStorage();
|
||||
GoRouter.of(context).go('/auth-screen');
|
||||
GoRouter.of(context).go('/auth-screen', extra: true);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,350 +22,381 @@ 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("Об этом плане"),
|
||||
"about_recipe": 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("дня"),
|
||||
"another_form_of_hour": MessageLookupByLibrary.simpleMessage("часа"),
|
||||
"another_form_of_minute": MessageLookupByLibrary.simpleMessage("минут"),
|
||||
"another_form_of_stage": MessageLookupByLibrary.simpleMessage("этапа"),
|
||||
"answer": MessageLookupByLibrary.simpleMessage("Ответить"),
|
||||
"archived": MessageLookupByLibrary.simpleMessage("В архиве"),
|
||||
"authentificate": MessageLookupByLibrary.simpleMessage("Войти"),
|
||||
"average_pressure": MessageLookupByLibrary.simpleMessage(
|
||||
"Средние показатели давления:"),
|
||||
"bodymass_chart": MessageLookupByLibrary.simpleMessage("График ИМТ"),
|
||||
"by_default": MessageLookupByLibrary.simpleMessage("По умолчянию"),
|
||||
"calories": MessageLookupByLibrary.simpleMessage("Калории"),
|
||||
"cancel_diet": MessageLookupByLibrary.simpleMessage("Отменить диету?"),
|
||||
"carb_type": MessageLookupByLibrary.simpleMessage("Мучное"),
|
||||
"carb_type_desc": MessageLookupByLibrary.simpleMessage(
|
||||
"Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы."),
|
||||
"carbohydrates": MessageLookupByLibrary.simpleMessage("Углеводы"),
|
||||
"chat": MessageLookupByLibrary.simpleMessage("Чат"),
|
||||
"check_out_video_recipe":
|
||||
MessageLookupByLibrary.simpleMessage("Посмотреть видео рецепт"),
|
||||
"chest": MessageLookupByLibrary.simpleMessage("Грудь"),
|
||||
"chest_circumference":
|
||||
MessageLookupByLibrary.simpleMessage("Обхват груди"),
|
||||
"choose_diet_duration":
|
||||
MessageLookupByLibrary.simpleMessage("Выберите срок диеты"),
|
||||
"choose_plan_duration":
|
||||
MessageLookupByLibrary.simpleMessage("Выберите срок плана"),
|
||||
"choose_start_diet_date": MessageLookupByLibrary.simpleMessage(
|
||||
"Выберите дату старты диеты. Она отобразиться у Вас в дневнике"),
|
||||
"circumference_empty": MessageLookupByLibrary.simpleMessage(
|
||||
"Все замеры обязательны к заполнению"),
|
||||
"circumference_is_not_a_number": MessageLookupByLibrary.simpleMessage(
|
||||
"Все замеры должны быть числами"),
|
||||
"circumferences_chart":
|
||||
MessageLookupByLibrary.simpleMessage("График обхватов"),
|
||||
"city": MessageLookupByLibrary.simpleMessage("Город"),
|
||||
"city_of_living":
|
||||
MessageLookupByLibrary.simpleMessage("Город проживания"),
|
||||
"comfort": MessageLookupByLibrary.simpleMessage("Комфорт"),
|
||||
"comment": MessageLookupByLibrary.simpleMessage("комментарий"),
|
||||
"comments": MessageLookupByLibrary.simpleMessage("Комментарии"),
|
||||
"comments_plural": MessageLookupByLibrary.simpleMessage("комментариев"),
|
||||
"complain": MessageLookupByLibrary.simpleMessage("Пожаловаться"),
|
||||
"confirm": MessageLookupByLibrary.simpleMessage("Подтвердить"),
|
||||
"continueButton": MessageLookupByLibrary.simpleMessage("Продолжить"),
|
||||
"continue_": MessageLookupByLibrary.simpleMessage("Продолжить"),
|
||||
"copied": MessageLookupByLibrary.simpleMessage("cкопирован"),
|
||||
"copy_link": MessageLookupByLibrary.simpleMessage("Скопировать ссылку"),
|
||||
"could_not_cancel_diet":
|
||||
MessageLookupByLibrary.simpleMessage("Не удалось отменить диету"),
|
||||
"could_not_launch_video":
|
||||
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_started":
|
||||
MessageLookupByLibrary.simpleMessage("Диета уже начата"),
|
||||
"diet_state": MessageLookupByLibrary.simpleMessage("Статус диеты"),
|
||||
"diet_type": MessageLookupByLibrary.simpleMessage("Тип диеты"),
|
||||
"do_you_have_hypertension_tendency":
|
||||
MessageLookupByLibrary.simpleMessage("Есть ли у вас гипертония?"),
|
||||
"do_you_have_hypotension_tendency":
|
||||
MessageLookupByLibrary.simpleMessage("Есть ли у вас гипотония?"),
|
||||
"do_you_take_pills": MessageLookupByLibrary.simpleMessage(
|
||||
"Принимаете ли вы лекарства или бады?"),
|
||||
"down_pressure":
|
||||
MessageLookupByLibrary.simpleMessage("Нижние показатели давления:"),
|
||||
"draft": MessageLookupByLibrary.simpleMessage("Черновик"),
|
||||
"drafted": MessageLookupByLibrary.simpleMessage("Черновики"),
|
||||
"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("Галерея"),
|
||||
"general_info":
|
||||
MessageLookupByLibrary.simpleMessage("Общая информация"),
|
||||
"gr": MessageLookupByLibrary.simpleMessage("гр"),
|
||||
"grams": MessageLookupByLibrary.simpleMessage("гр"),
|
||||
"has_alergy": MessageLookupByLibrary.simpleMessage("Наличие аллергии"),
|
||||
"has_hyper":
|
||||
MessageLookupByLibrary.simpleMessage("Склонность к гипертонии"),
|
||||
"has_hypo":
|
||||
MessageLookupByLibrary.simpleMessage("Склонность к гипотонии"),
|
||||
"height": MessageLookupByLibrary.simpleMessage("Рост"),
|
||||
"height_measurements":
|
||||
MessageLookupByLibrary.simpleMessage("Замер роста"),
|
||||
"hide": MessageLookupByLibrary.simpleMessage("Свернуть"),
|
||||
"hip_circumference":
|
||||
MessageLookupByLibrary.simpleMessage("Обхват бедер"),
|
||||
"hips": MessageLookupByLibrary.simpleMessage("Бедра"),
|
||||
"hour": MessageLookupByLibrary.simpleMessage("час"),
|
||||
"hours": MessageLookupByLibrary.simpleMessage("часов"),
|
||||
"in_progress": MessageLookupByLibrary.simpleMessage("В процессе"),
|
||||
"inactive_diet_state": MessageLookupByLibrary.simpleMessage("Черновик"),
|
||||
"ingredients": 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(
|
||||
"С некоторыми видами диет можно употреблять алкоголь в умеренных количествах. Рекомендуется совмещать вместе с низкокалорийными закусками."),
|
||||
"liked_groceries":
|
||||
MessageLookupByLibrary.simpleMessage("Любимые продукты"),
|
||||
"link_was_copied":
|
||||
MessageLookupByLibrary.simpleMessage("Ссылка успешно скопирована"),
|
||||
"loading": MessageLookupByLibrary.simpleMessage("Загрузка..."),
|
||||
"lower": MessageLookupByLibrary.simpleMessage("Нижнее"),
|
||||
"male": MessageLookupByLibrary.simpleMessage("Мужской"),
|
||||
"meal": MessageLookupByLibrary.simpleMessage("Приём пищи"),
|
||||
"meat": MessageLookupByLibrary.simpleMessage("Мясо"),
|
||||
"meat_type": MessageLookupByLibrary.simpleMessage("С мясом"),
|
||||
"meat_type_desc": MessageLookupByLibrary.simpleMessage(
|
||||
"Диета с мясом полезная и сбалансированная. Включает в себя нежирное мясо: курицу, индейку, кролика или говядину. В сочетании с овощами получаете все необходимые витамины и минералы. Не забывайте о порциях и старайтесь есть медленно, прислушиваясь к своему организму."),
|
||||
"milliliter": MessageLookupByLibrary.simpleMessage("мл"),
|
||||
"minimal_customer_price": MessageLookupByLibrary.simpleMessage(
|
||||
"Минимальная цена для покупателя: 1200₽"),
|
||||
"minute": MessageLookupByLibrary.simpleMessage("минута"),
|
||||
"minutes": MessageLookupByLibrary.simpleMessage("минуты"),
|
||||
"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("У меня нет аккаунта"),
|
||||
"not_liked_groceries":
|
||||
MessageLookupByLibrary.simpleMessage("Не любимые продукты"),
|
||||
"one_option": MessageLookupByLibrary.simpleMessage("1 опция"),
|
||||
"option": MessageLookupByLibrary.simpleMessage("Опция"),
|
||||
"option_content":
|
||||
MessageLookupByLibrary.simpleMessage("Содержание опции"),
|
||||
"option_content_hint_text":
|
||||
MessageLookupByLibrary.simpleMessage("На связи 7 дней в неделю"),
|
||||
"option_desc": MessageLookupByLibrary.simpleMessage("Описание опции"),
|
||||
"option_desc_hint_text": MessageLookupByLibrary.simpleMessage(
|
||||
"Этот план питания для похудения на 7 дней сбалансированный и разнообразный"),
|
||||
"option_duration":
|
||||
MessageLookupByLibrary.simpleMessage("Продолжительность опции"),
|
||||
"option_personal_diet_desc": MessageLookupByLibrary.simpleMessage(
|
||||
"Опция подразумевает создание индивидуальной диеты"),
|
||||
"option_title": MessageLookupByLibrary.simpleMessage("Заголовок опции"),
|
||||
"order": MessageLookupByLibrary.simpleMessage("Порядок"),
|
||||
"other_info": MessageLookupByLibrary.simpleMessage("Прочая информация"),
|
||||
"password": MessageLookupByLibrary.simpleMessage("Пароль"),
|
||||
"password_confirmation":
|
||||
MessageLookupByLibrary.simpleMessage("Подтвердите пароль"),
|
||||
"password_confirmation_mismatch":
|
||||
MessageLookupByLibrary.simpleMessage("Пароли не совпадают"),
|
||||
"password_empty": MessageLookupByLibrary.simpleMessage(
|
||||
"Пароль обязателен для заполнения"),
|
||||
"password_short": MessageLookupByLibrary.simpleMessage(
|
||||
"В пароле должно быть минимум 6 символов"),
|
||||
"pcs": MessageLookupByLibrary.simpleMessage("шт"),
|
||||
"personal": MessageLookupByLibrary.simpleMessage("Персональные"),
|
||||
"personal_diet_state":
|
||||
MessageLookupByLibrary.simpleMessage("Персональная"),
|
||||
"photo": MessageLookupByLibrary.simpleMessage("Фото"),
|
||||
"physical_fitness":
|
||||
MessageLookupByLibrary.simpleMessage("Физическая форма"),
|
||||
"place_of_living":
|
||||
MessageLookupByLibrary.simpleMessage("Место проживания"),
|
||||
"plan_author": MessageLookupByLibrary.simpleMessage("Автор плана"),
|
||||
"plan_desc": MessageLookupByLibrary.simpleMessage("Описание плана"),
|
||||
"plan_desc_example": MessageLookupByLibrary.simpleMessage(
|
||||
"Большое подробное, привлекательное описание плана"),
|
||||
"plan_duration": MessageLookupByLibrary.simpleMessage("Срок плана"),
|
||||
"plan_label_desc":
|
||||
MessageLookupByLibrary.simpleMessage("План для поддержания формы"),
|
||||
"plan_type": MessageLookupByLibrary.simpleMessage("Тип плана"),
|
||||
"plans_complete":
|
||||
MessageLookupByLibrary.simpleMessage("Пройденные планы"),
|
||||
"popular": MessageLookupByLibrary.simpleMessage("Популярные"),
|
||||
"preferred_language":
|
||||
MessageLookupByLibrary.simpleMessage("Предпочитаемый язык общения"),
|
||||
"pressure": MessageLookupByLibrary.simpleMessage("Давление"),
|
||||
"pressure_empty": MessageLookupByLibrary.simpleMessage(
|
||||
"Все показатели давления обязательны к заполнению"),
|
||||
"pressure_is_not_a_number": MessageLookupByLibrary.simpleMessage(
|
||||
"Все показатели давления должны быть числами"),
|
||||
"preview": MessageLookupByLibrary.simpleMessage("Превью"),
|
||||
"price": MessageLookupByLibrary.simpleMessage("Цена"),
|
||||
"price_explanation": MessageLookupByLibrary.simpleMessage(
|
||||
"Разница в ценах, это комиссия Итвио"),
|
||||
"profile": MessageLookupByLibrary.simpleMessage("Профиль"),
|
||||
"proteins": MessageLookupByLibrary.simpleMessage("Белки"),
|
||||
"publish": MessageLookupByLibrary.simpleMessage("Опубликовать"),
|
||||
"published": MessageLookupByLibrary.simpleMessage("Опубликованные"),
|
||||
"recipe_author": MessageLookupByLibrary.simpleMessage("Автор рецепта"),
|
||||
"removeFromActive":
|
||||
MessageLookupByLibrary.simpleMessage("Снять с публикации"),
|
||||
"save": MessageLookupByLibrary.simpleMessage("Сохранить"),
|
||||
"services": MessageLookupByLibrary.simpleMessage("Оказание услуг"),
|
||||
"settings": MessageLookupByLibrary.simpleMessage("Настройки"),
|
||||
"sex": MessageLookupByLibrary.simpleMessage("Пол"),
|
||||
"share": MessageLookupByLibrary.simpleMessage("Поделиться"),
|
||||
"skip": MessageLookupByLibrary.simpleMessage("Пропустить"),
|
||||
"slim": MessageLookupByLibrary.simpleMessage("Похудение"),
|
||||
"slim_type": MessageLookupByLibrary.simpleMessage("Похудение"),
|
||||
"slim_type_desc": MessageLookupByLibrary.simpleMessage(
|
||||
"План питания для похудения должен быть разработан с учётом индивидуальных особенностей организма, возраста, пола, уровня физической активности и состояния здоровья. Общие принципы: \n● Снижение калорийности; \n● Сбалансированный рацион; \n● Разнообразие продуктов; \n● Питьевой режим; \n● Ограничение вредных продуктов;"),
|
||||
"sport_hobbies":
|
||||
MessageLookupByLibrary.simpleMessage("Спортивные увлечения"),
|
||||
"stage": MessageLookupByLibrary.simpleMessage("этап"),
|
||||
"stages": MessageLookupByLibrary.simpleMessage("этапов"),
|
||||
"standard": MessageLookupByLibrary.simpleMessage("Стандарт"),
|
||||
"startDiet": MessageLookupByLibrary.simpleMessage("Начать диету"),
|
||||
"step": MessageLookupByLibrary.simpleMessage("Шаг"),
|
||||
"step_by_step_photo_recipe":
|
||||
MessageLookupByLibrary.simpleMessage("Пошаговый фоторецепт"),
|
||||
"takes_pills":
|
||||
MessageLookupByLibrary.simpleMessage("Принимает лекарства"),
|
||||
"tell_your_schedule": MessageLookupByLibrary.simpleMessage(
|
||||
"Расскажите в свободной форме о том как просыпаетесь, когда едите, когда ложитесь спать:"),
|
||||
"there_is_a_video": MessageLookupByLibrary.simpleMessage("Есть видео"),
|
||||
"three_options": MessageLookupByLibrary.simpleMessage("3 опции"),
|
||||
"time": MessageLookupByLibrary.simpleMessage("Время прохождения"),
|
||||
"toOffer": MessageLookupByLibrary.simpleMessage("Предложить"),
|
||||
"to_draft": MessageLookupByLibrary.simpleMessage("В черновик"),
|
||||
"unfavorite_foods":
|
||||
MessageLookupByLibrary.simpleMessage("Нелюбимые продукты"),
|
||||
"up_pressure": MessageLookupByLibrary.simpleMessage(
|
||||
"Верхние показатели давления:"),
|
||||
"upper": MessageLookupByLibrary.simpleMessage("Верхнее"),
|
||||
"user_authorization":
|
||||
MessageLookupByLibrary.simpleMessage("Аутентификация"),
|
||||
"user_data":
|
||||
MessageLookupByLibrary.simpleMessage("Данные пользователя"),
|
||||
"user_registration":
|
||||
MessageLookupByLibrary.simpleMessage("Регистрация пользователя"),
|
||||
"username": MessageLookupByLibrary.simpleMessage("Имя пользователя"),
|
||||
"vegan": MessageLookupByLibrary.simpleMessage("Веган."),
|
||||
"vegan_type": MessageLookupByLibrary.simpleMessage("Вегетарианская"),
|
||||
"vegan_type_desc": MessageLookupByLibrary.simpleMessage(
|
||||
"Диета основана на потреблении растительной пищи и отказе от продуктов животного происхождения. Такой тип питания может быть разнообразным и вкусным, а также полезным для здоровья."),
|
||||
"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("Калории"),
|
||||
"cancel_diet": 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("Пожаловаться"),
|
||||
"confirm": MessageLookupByLibrary.simpleMessage("Подтвердить"),
|
||||
"continueButton": MessageLookupByLibrary.simpleMessage("Продолжить"),
|
||||
"continue_": MessageLookupByLibrary.simpleMessage("Продолжить"),
|
||||
"copied": MessageLookupByLibrary.simpleMessage("cкопирован"),
|
||||
"copy_link": MessageLookupByLibrary.simpleMessage("Скопировать ссылку"),
|
||||
"could_not_cancel_diet": MessageLookupByLibrary.simpleMessage(
|
||||
"Не удалось отменить диету",
|
||||
),
|
||||
"country": MessageLookupByLibrary.simpleMessage("Страна"),
|
||||
"create_diet": MessageLookupByLibrary.simpleMessage("Создание диеты"),
|
||||
"customer_price": MessageLookupByLibrary.simpleMessage(
|
||||
"Цена для покупателя",
|
||||
),
|
||||
"date_of_birth": MessageLookupByLibrary.simpleMessage("Дата рождения"),
|
||||
"day": MessageLookupByLibrary.simpleMessage("День"),
|
||||
"days": MessageLookupByLibrary.simpleMessage("дней"),
|
||||
"deleted": MessageLookupByLibrary.simpleMessage("Удалена"),
|
||||
"diary": MessageLookupByLibrary.simpleMessage("Дневник"),
|
||||
"diet": MessageLookupByLibrary.simpleMessage("Диета"),
|
||||
"diet_author": MessageLookupByLibrary.simpleMessage("Автор диеты"),
|
||||
"diet_plan": MessageLookupByLibrary.simpleMessage("План диеты"),
|
||||
"diet_started": MessageLookupByLibrary.simpleMessage("Диета уже начата"),
|
||||
"diet_state": MessageLookupByLibrary.simpleMessage("Статус диеты"),
|
||||
"diet_type": MessageLookupByLibrary.simpleMessage("Тип диеты"),
|
||||
"do_you_have_hypertension_tendency": MessageLookupByLibrary.simpleMessage(
|
||||
"Есть ли у вас гипертония?",
|
||||
),
|
||||
"do_you_have_hypotension_tendency": MessageLookupByLibrary.simpleMessage(
|
||||
"Есть ли у вас гипотония?",
|
||||
),
|
||||
"do_you_take_pills": MessageLookupByLibrary.simpleMessage(
|
||||
"Принимаете ли вы лекарства или бады?",
|
||||
),
|
||||
"down_pressure": MessageLookupByLibrary.simpleMessage(
|
||||
"Нижние показатели давления:",
|
||||
),
|
||||
"draft": MessageLookupByLibrary.simpleMessage("Черновик"),
|
||||
"drafted": MessageLookupByLibrary.simpleMessage("Черновики"),
|
||||
"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("Галерея"),
|
||||
"general_info": MessageLookupByLibrary.simpleMessage("Общая информация"),
|
||||
"gr": MessageLookupByLibrary.simpleMessage("гр"),
|
||||
"grams": MessageLookupByLibrary.simpleMessage("гр"),
|
||||
"has_alergy": MessageLookupByLibrary.simpleMessage("Наличие аллергии"),
|
||||
"has_hyper": MessageLookupByLibrary.simpleMessage(
|
||||
"Склонность к гипертонии",
|
||||
),
|
||||
"has_hypo": MessageLookupByLibrary.simpleMessage("Склонность к гипотонии"),
|
||||
"height": 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("Черновик"),
|
||||
"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(
|
||||
"С некоторыми видами диет можно употреблять алкоголь в умеренных количествах. Рекомендуется совмещать вместе с низкокалорийными закусками.",
|
||||
),
|
||||
"liked_groceries": MessageLookupByLibrary.simpleMessage("Любимые продукты"),
|
||||
"link_was_copied": MessageLookupByLibrary.simpleMessage(
|
||||
"Ссылка успешно скопирована",
|
||||
),
|
||||
"loading": MessageLookupByLibrary.simpleMessage("Загрузка..."),
|
||||
"lower": MessageLookupByLibrary.simpleMessage("Нижнее"),
|
||||
"male": MessageLookupByLibrary.simpleMessage("Мужской"),
|
||||
"meal": MessageLookupByLibrary.simpleMessage("Приём пищи"),
|
||||
"meat": MessageLookupByLibrary.simpleMessage("Мясо"),
|
||||
"meat_type": MessageLookupByLibrary.simpleMessage("С мясом"),
|
||||
"meat_type_desc": MessageLookupByLibrary.simpleMessage(
|
||||
"Диета с мясом полезная и сбалансированная. Включает в себя нежирное мясо: курицу, индейку, кролика или говядину. В сочетании с овощами получаете все необходимые витамины и минералы. Не забывайте о порциях и старайтесь есть медленно, прислушиваясь к своему организму.",
|
||||
),
|
||||
"milliliter": MessageLookupByLibrary.simpleMessage("мл"),
|
||||
"minimal_customer_price": MessageLookupByLibrary.simpleMessage(
|
||||
"Минимальная цена для покупателя: 1200₽",
|
||||
),
|
||||
"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("У меня нет аккаунта"),
|
||||
"not_liked_groceries": MessageLookupByLibrary.simpleMessage(
|
||||
"Не любимые продукты",
|
||||
),
|
||||
"one_option": MessageLookupByLibrary.simpleMessage("1 опция"),
|
||||
"option": MessageLookupByLibrary.simpleMessage("Опция"),
|
||||
"option_content": MessageLookupByLibrary.simpleMessage("Содержание опции"),
|
||||
"option_content_hint_text": MessageLookupByLibrary.simpleMessage(
|
||||
"На связи 7 дней в неделю",
|
||||
),
|
||||
"option_desc": MessageLookupByLibrary.simpleMessage("Описание опции"),
|
||||
"option_desc_hint_text": MessageLookupByLibrary.simpleMessage(
|
||||
"Этот план питания для похудения на 7 дней сбалансированный и разнообразный",
|
||||
),
|
||||
"option_duration": MessageLookupByLibrary.simpleMessage(
|
||||
"Продолжительность опции",
|
||||
),
|
||||
"option_personal_diet_desc": MessageLookupByLibrary.simpleMessage(
|
||||
"Опция подразумевает создание индивидуальной диеты",
|
||||
),
|
||||
"option_title": MessageLookupByLibrary.simpleMessage("Заголовок опции"),
|
||||
"order": MessageLookupByLibrary.simpleMessage("Порядок"),
|
||||
"other_info": MessageLookupByLibrary.simpleMessage("Прочая информация"),
|
||||
"password": MessageLookupByLibrary.simpleMessage("Пароль"),
|
||||
"password_confirmation": MessageLookupByLibrary.simpleMessage(
|
||||
"Подтвердите пароль",
|
||||
),
|
||||
"password_confirmation_mismatch": MessageLookupByLibrary.simpleMessage(
|
||||
"Пароли не совпадают",
|
||||
),
|
||||
"password_empty": MessageLookupByLibrary.simpleMessage(
|
||||
"Пароль обязателен для заполнения",
|
||||
),
|
||||
"password_short": MessageLookupByLibrary.simpleMessage(
|
||||
"В пароле должно быть минимум 6 символов",
|
||||
),
|
||||
"pcs": MessageLookupByLibrary.simpleMessage("шт"),
|
||||
"personal": MessageLookupByLibrary.simpleMessage("Персональные"),
|
||||
"personal_diet_state": MessageLookupByLibrary.simpleMessage("Персональная"),
|
||||
"photo": MessageLookupByLibrary.simpleMessage("Фото"),
|
||||
"physical_fitness": MessageLookupByLibrary.simpleMessage(
|
||||
"Физическая форма",
|
||||
),
|
||||
"place_of_living": MessageLookupByLibrary.simpleMessage("Место проживания"),
|
||||
"plan_author": MessageLookupByLibrary.simpleMessage("Автор плана"),
|
||||
"plan_desc": MessageLookupByLibrary.simpleMessage("Описание плана"),
|
||||
"plan_desc_example": MessageLookupByLibrary.simpleMessage(
|
||||
"Большое подробное, привлекательное описание плана",
|
||||
),
|
||||
"plan_duration": MessageLookupByLibrary.simpleMessage("Срок плана"),
|
||||
"plan_label_desc": MessageLookupByLibrary.simpleMessage(
|
||||
"План для поддержания формы",
|
||||
),
|
||||
"plan_type": MessageLookupByLibrary.simpleMessage("Тип плана"),
|
||||
"plans_complete": MessageLookupByLibrary.simpleMessage("Пройденные планы"),
|
||||
"popular": MessageLookupByLibrary.simpleMessage("Популярные"),
|
||||
"preferred_language": MessageLookupByLibrary.simpleMessage(
|
||||
"Предпочитаемый язык общения",
|
||||
),
|
||||
"pressure": MessageLookupByLibrary.simpleMessage("Давление"),
|
||||
"pressure_empty": MessageLookupByLibrary.simpleMessage(
|
||||
"Все показатели давления обязательны к заполнению",
|
||||
),
|
||||
"pressure_is_not_a_number": MessageLookupByLibrary.simpleMessage(
|
||||
"Все показатели давления должны быть числами",
|
||||
),
|
||||
"preview": MessageLookupByLibrary.simpleMessage("Превью"),
|
||||
"price": MessageLookupByLibrary.simpleMessage("Цена"),
|
||||
"price_explanation": MessageLookupByLibrary.simpleMessage(
|
||||
"Разница в ценах, это комиссия Итвио",
|
||||
),
|
||||
"profile": MessageLookupByLibrary.simpleMessage("Профиль"),
|
||||
"proteins": MessageLookupByLibrary.simpleMessage("Белки"),
|
||||
"publish": MessageLookupByLibrary.simpleMessage("Опубликовать"),
|
||||
"published": MessageLookupByLibrary.simpleMessage("Опубликованные"),
|
||||
"removeFromActive": MessageLookupByLibrary.simpleMessage(
|
||||
"Снять с публикации",
|
||||
),
|
||||
"save": MessageLookupByLibrary.simpleMessage("Сохранить"),
|
||||
"services": MessageLookupByLibrary.simpleMessage("Оказание услуг"),
|
||||
"settings": MessageLookupByLibrary.simpleMessage("Настройки"),
|
||||
"sex": MessageLookupByLibrary.simpleMessage("Пол"),
|
||||
"share": MessageLookupByLibrary.simpleMessage("Поделиться"),
|
||||
"skip": MessageLookupByLibrary.simpleMessage("Пропустить"),
|
||||
"slim": MessageLookupByLibrary.simpleMessage("Похудение"),
|
||||
"slim_type": MessageLookupByLibrary.simpleMessage("Похудение"),
|
||||
"slim_type_desc": MessageLookupByLibrary.simpleMessage(
|
||||
"План питания для похудения должен быть разработан с учётом индивидуальных особенностей организма, возраста, пола, уровня физической активности и состояния здоровья. Общие принципы: \n● Снижение калорийности; \n● Сбалансированный рацион; \n● Разнообразие продуктов; \n● Питьевой режим; \n● Ограничение вредных продуктов;",
|
||||
),
|
||||
"sport_hobbies": MessageLookupByLibrary.simpleMessage(
|
||||
"Спортивные увлечения",
|
||||
),
|
||||
"standard": MessageLookupByLibrary.simpleMessage("Стандарт"),
|
||||
"startDiet": MessageLookupByLibrary.simpleMessage("Начать диету"),
|
||||
"takes_pills": MessageLookupByLibrary.simpleMessage("Принимает лекарства"),
|
||||
"tell_your_schedule": MessageLookupByLibrary.simpleMessage(
|
||||
"Расскажите в свободной форме о том как просыпаетесь, когда едите, когда ложитесь спать:",
|
||||
),
|
||||
"three_options": MessageLookupByLibrary.simpleMessage("3 опции"),
|
||||
"time": MessageLookupByLibrary.simpleMessage("Время прохождения"),
|
||||
"toOffer": MessageLookupByLibrary.simpleMessage("Предложить"),
|
||||
"to_draft": MessageLookupByLibrary.simpleMessage("В черновик"),
|
||||
"unfavorite_foods": MessageLookupByLibrary.simpleMessage(
|
||||
"Нелюбимые продукты",
|
||||
),
|
||||
"up_pressure": MessageLookupByLibrary.simpleMessage(
|
||||
"Верхние показатели давления:",
|
||||
),
|
||||
"upper": MessageLookupByLibrary.simpleMessage("Верхнее"),
|
||||
"user_authorization": MessageLookupByLibrary.simpleMessage(
|
||||
"Аутентификация",
|
||||
),
|
||||
"user_data": MessageLookupByLibrary.simpleMessage("Данные пользователя"),
|
||||
"user_registration": MessageLookupByLibrary.simpleMessage(
|
||||
"Регистрация пользователя",
|
||||
),
|
||||
"username": MessageLookupByLibrary.simpleMessage("Имя пользователя"),
|
||||
"vegan": MessageLookupByLibrary.simpleMessage("Веган."),
|
||||
"vegan_type": MessageLookupByLibrary.simpleMessage("Вегетарианская"),
|
||||
"vegan_type_desc": MessageLookupByLibrary.simpleMessage(
|
||||
"Диета основана на потреблении растительной пищи и отказе от продуктов животного происхождения. Такой тип питания может быть разнообразным и вкусным, а также полезным для здоровья.",
|
||||
),
|
||||
"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("Ваш вес:"),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2352,12 +2352,7 @@ class S {
|
||||
|
||||
/// `Подтвердить`
|
||||
String get confirm {
|
||||
return Intl.message(
|
||||
'Подтвердить',
|
||||
name: 'confirm',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
return Intl.message('Подтвердить', name: 'confirm', desc: '', args: []);
|
||||
}
|
||||
|
||||
/// `Не удалось отменить диету`
|
||||
@@ -2369,176 +2364,6 @@ class S {
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `часов`
|
||||
String get hours {
|
||||
return Intl.message(
|
||||
'часов',
|
||||
name: 'hours',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `час`
|
||||
String get hour {
|
||||
return Intl.message(
|
||||
'час',
|
||||
name: 'hour',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `часа`
|
||||
String get another_form_of_hour {
|
||||
return Intl.message(
|
||||
'часа',
|
||||
name: 'another_form_of_hour',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `минуты`
|
||||
String get minutes {
|
||||
return Intl.message(
|
||||
'минуты',
|
||||
name: 'minutes',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `минута`
|
||||
String get minute {
|
||||
return Intl.message(
|
||||
'минута',
|
||||
name: 'minute',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `минут`
|
||||
String get another_form_of_minute {
|
||||
return Intl.message(
|
||||
'минут',
|
||||
name: 'another_form_of_minute',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Есть видео`
|
||||
String get there_is_a_video {
|
||||
return Intl.message(
|
||||
'Есть видео',
|
||||
name: 'there_is_a_video',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Автор рецепта`
|
||||
String get recipe_author {
|
||||
return Intl.message(
|
||||
'Автор рецепта',
|
||||
name: 'recipe_author',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Об этом рецепте`
|
||||
String get about_recipe {
|
||||
return Intl.message(
|
||||
'Об этом рецепте',
|
||||
name: 'about_recipe',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `этапов`
|
||||
String get stages {
|
||||
return Intl.message(
|
||||
'этапов',
|
||||
name: 'stages',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `этап`
|
||||
String get stage {
|
||||
return Intl.message(
|
||||
'этап',
|
||||
name: 'stage',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `этапа`
|
||||
String get another_form_of_stage {
|
||||
return Intl.message(
|
||||
'этапа',
|
||||
name: 'another_form_of_stage',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Посмотреть видео рецепт`
|
||||
String get check_out_video_recipe {
|
||||
return Intl.message(
|
||||
'Посмотреть видео рецепт',
|
||||
name: 'check_out_video_recipe',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Не удалось запустить видео`
|
||||
String get could_not_launch_video {
|
||||
return Intl.message(
|
||||
'Не удалось запустить видео',
|
||||
name: 'could_not_launch_video',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Ингредиенты`
|
||||
String get ingredients {
|
||||
return Intl.message(
|
||||
'Ингредиенты',
|
||||
name: 'ingredients',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Шаг`
|
||||
String get step {
|
||||
return Intl.message(
|
||||
'Шаг',
|
||||
name: 'step',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Пошаговый фоторецепт`
|
||||
String get step_by_step_photo_recipe {
|
||||
return Intl.message(
|
||||
'Пошаговый фоторецепт',
|
||||
name: 'step_by_step_photo_recipe',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AppLocalizationDelegate extends LocalizationsDelegate<S> {
|
||||
|
||||
@@ -14,12 +14,19 @@ import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_native_splash/flutter_native_splash.dart';
|
||||
import 'package:flutter_portal/flutter_portal.dart';
|
||||
import 'package:keyboard_dismisser/keyboard_dismisser.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
Future<void> main() async {
|
||||
WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
|
||||
FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
|
||||
await di.init();
|
||||
runApp(MyApp());
|
||||
await SentryFlutter.init(
|
||||
(options) {
|
||||
options.dsn = 'http://ba7f2653067776f3034e6e89850e85a1@sentry.md-desk.ru:9000/2';
|
||||
options.tracesSampleRate = 1.0;
|
||||
},
|
||||
appRunner: () => runApp(MyApp()),
|
||||
);
|
||||
FlutterNativeSplash.remove();
|
||||
}
|
||||
|
||||
|
||||
15
pubspec.yaml
15
pubspec.yaml
@@ -23,14 +23,14 @@ dependencies:
|
||||
validators: ^3.0.0
|
||||
path_provider: ^2.1.5
|
||||
carousel_slider_plus: ^7.1.0
|
||||
flutter_form_builder: ^7.0.0-alpha.3
|
||||
flutter_form_builder: ^9.7.0
|
||||
image_picker: ^1.1.2
|
||||
flutter_typeahead: ^5.2.0
|
||||
go_router: ^14.7.1
|
||||
go_router: ^14.7.2
|
||||
keyboard_dismisser: ^3.0.0
|
||||
retrofit: ^4.4.2
|
||||
get_it: ^8.0.3
|
||||
dio: ^5.7.0
|
||||
dio: ^5.8.0+1
|
||||
dart_pusher_channels: ^1.2.3
|
||||
photo_view: ^0.15.0
|
||||
dismissible_page: ^1.0.2
|
||||
@@ -38,14 +38,14 @@ dependencies:
|
||||
easy_debounce: ^2.0.3
|
||||
badges: ^3.1.2
|
||||
google_fonts: ^6.2.1
|
||||
syncfusion_flutter_charts: ^28.1.38
|
||||
syncfusion_flutter_gauges: ^28.1.38
|
||||
syncfusion_flutter_charts: ^28.2.3
|
||||
syncfusion_flutter_gauges: ^28.2.3
|
||||
table_calendar: ^3.2.0
|
||||
flutter_keyboard_visibility: ^6.0.0
|
||||
share_plus: ^10.1.4
|
||||
flutter_html: ^3.0.0-beta.2
|
||||
file_picker: ^8.1.7
|
||||
audioplayers: ^6.1.0
|
||||
file_picker: ^8.3.1
|
||||
audioplayers: ^6.1.1
|
||||
intl: ^0.20.2
|
||||
rive: ^0.13.20
|
||||
mask_text_input_formatter: ^2.9.0
|
||||
@@ -59,6 +59,7 @@ dependencies:
|
||||
http: ^1.3.0
|
||||
flutter_native_splash: ^2.4.4
|
||||
webview_flutter: ^4.10.0
|
||||
sentry_flutter: ^8.13.0
|
||||
connectivity_plus: ^6.1.2
|
||||
|
||||
dev_dependencies:
|
||||
|
||||
Reference in New Issue
Block a user