refactor: add intl localization

This commit is contained in:
mso7nueh
2024-09-11 17:39:00 +03:00
parent 69472f422e
commit 6c69bbbf41
29 changed files with 1468 additions and 312 deletions

View File

@@ -6,7 +6,7 @@ import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/noti
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/notifications_cubit/notifications_state.dart';
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/profile_avatar_cubit/profile_avatar_cubit.dart';
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/profile_avatar_cubit/profile_avatar_state.dart';
import 'package:eatvio_app/localization/app_localization.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/locator_service.dart';
import 'package:eatvio_app/theme/theme_helper.dart';
import 'package:flutter/material.dart';
@@ -59,6 +59,7 @@ class _BottomNavigationBarWidgetState extends State<BottomNavigationBarWidget> {
@override
Widget build(BuildContext context) {
final s = S.of(context);
return Scaffold(
body: widget.child,
bottomNavigationBar: SizedBox(
@@ -103,7 +104,7 @@ class _BottomNavigationBarWidgetState extends State<BottomNavigationBarWidget> {
),
),
BottomNavigationBarItem(
label: "diary".tr,
label: s.diary,
icon: Padding(
padding: const EdgeInsets.only(bottom: 2),
child: SvgPicture.asset(
@@ -127,7 +128,7 @@ class _BottomNavigationBarWidgetState extends State<BottomNavigationBarWidget> {
),
),
BottomNavigationBarItem(
label: "chat".tr,
label: s.chat,
icon: BlocBuilder<NewMessagesCubit, NewMessagesState>(
builder: (BuildContext context, NewMessagesState state) {
return badges.Badge(

View File

@@ -1,5 +1,3 @@
// ignore_for_file: unused_local_variable
import 'package:carousel_slider_plus/carousel_slider_plus.dart';
import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model.dart';
@@ -10,7 +8,6 @@ import 'package:eatvio_app/features/diary/models/portion.dart';
import 'package:eatvio_app/features/diary/models/product.dart';
import 'package:eatvio_app/features/diary/presentation/bloc/diary_bloc.dart';
import 'package:eatvio_app/features/diary/presentation/bloc/diary_state.dart';
import 'package:eatvio_app/localization/app_localization.dart';
import 'package:eatvio_app/locator_service.dart';
import 'package:eatvio_app/theme/app_decoration.dart';
import 'package:eatvio_app/theme/custom_text_style.dart';
@@ -372,7 +369,6 @@ class DiaryScreen extends StatelessWidget {
_buildMeal(BuildContext context, DiaryStateLoaded state) {
final digitsOnly = FilteringTextInputFormatter.digitsOnly;
List<String> _options = state.autocompleteList.map((Product item) => item.name).toList();
FocusNode focusNodeName = FocusNode();
return Container(
padding: EdgeInsets.symmetric(
horizontal: 24,
@@ -781,7 +777,7 @@ class DiaryScreen extends StatelessWidget {
bottom: 4,
),
child: Text(
portion.quantity.toString() + ' ' + portion.portion.toString().tr,
portion.quantity.toString() + ' ' + portion.portion.toString(),
),
),
Spacer(),
@@ -839,7 +835,7 @@ class DiaryScreen extends StatelessWidget {
bottom: 4,
),
child: Text(
portion.quantity.toString() + ' ' + portion.portion.toString().tr,
portion.quantity.toString() + ' ' + portion.portion.toString(),
),
),
],

View File

@@ -7,7 +7,6 @@ import 'package:eatvio_app/features/recipes/models/recipe_model.dart';
import 'package:eatvio_app/features/recipes/models/step.dart' as step;
import 'package:eatvio_app/features/recipes/presentation/bloc/recipe_create_cubit.dart';
import 'package:eatvio_app/features/recipes/presentation/bloc/recipe_create_state.dart';
import 'package:eatvio_app/localization/app_localization.dart';
import 'package:eatvio_app/locator_service.dart';
import 'package:eatvio_app/theme/app_decoration.dart';
import 'package:eatvio_app/theme/custom_text_style.dart';
@@ -422,7 +421,7 @@ class RecipeCreateScreen extends StatelessWidget {
bottom: 4,
),
child: Text(
ingredient.portion.toString() + ' ' + ingredient.unit.toString().tr,
ingredient.portion.toString() + ' ' + ingredient.unit.toString(),
),
),
Spacer(),

View File

@@ -5,7 +5,6 @@ import 'package:eatvio_app/features/recipes/models/recipe_model.dart';
import 'package:eatvio_app/features/recipes/models/step.dart' as step;
import 'package:eatvio_app/features/recipes/presentation/bloc/recipe_create_cubit.dart';
import 'package:eatvio_app/features/recipes/presentation/bloc/recipe_create_state.dart';
import 'package:eatvio_app/localization/app_localization.dart';
import 'package:eatvio_app/theme/app_decoration.dart';
import 'package:eatvio_app/theme/custom_text_style.dart';
import 'package:eatvio_app/theme/theme_helper.dart';
@@ -430,7 +429,7 @@ class RecipeEditScreen extends StatelessWidget {
bottom: 4,
),
child: Text(
ingredient.portion.toString() + ' ' + ingredient.unit.toString().tr,
ingredient.portion.toString() + ' ' + ingredient.unit.toString(),
),
),
Spacer(),

View File

@@ -1,6 +1,6 @@
import 'package:eatvio_app/features/registration/models/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/localization/app_localization.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -27,12 +27,13 @@ class _AllergiesScreenState extends State<AllergiesScreen> {
@override
Widget build(BuildContext context) {
final s = S.of(context);
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80, left: 16, right: 16, top: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("allergies_presence".tr),
Text(s.allergies_presence),
SizedBox(height: 4),
CustomTextFormField(
controller: enterInformationController,

View File

@@ -2,7 +2,7 @@ import 'package:eatvio_app/core/utils/image_constant.dart';
import 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model.dart';
import 'package:eatvio_app/features/registration/models/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/localization/app_localization.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/widgets/custom_drop_down.dart';
import 'package:eatvio_app/widgets/custom_image_view.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
@@ -53,38 +53,39 @@ class _BloodPressureScreenState extends State<BloodPressureScreen> {
@override
Widget build(BuildContext context) {
final s = S.of(context);
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80, left: 16, right: 16, top: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("up_pressure".tr),
Text(s.up_pressure),
SizedBox(height: 4),
CustomTextFormField(
inputFormatters: [digitsOnly],
controller: upPressureController,
autofocus: true,
focusNode: upFocusNode,
hintText: "90".tr,
hintText: "90",
onChanged: (newValue) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(bloodPressureUp: int.parse(newValue)));
},
),
SizedBox(height: 16),
Text("down_pressure".tr),
Text(s.down_pressure),
SizedBox(height: 4),
CustomTextFormField(
inputFormatters: [digitsOnly],
controller: downPressureController,
hintText: "90".tr,
hintText: '90',
onChanged: (newValue) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(bloodPressureDown: int.parse(newValue)));
},
),
SizedBox(height: 16),
Text("do_you_have_hypotension_tendency".tr),
Text(s.do_you_have_hypotension_tendency),
SizedBox(height: 4),
CustomDropDown(
icon: Container(
@@ -98,7 +99,7 @@ class _BloodPressureScreenState extends State<BloodPressureScreen> {
width: 16,
),
),
hintText: "Не выбрано".tr,
hintText: "Не выбрано",
items: selectionPopupList,
value: selectedPopupHypo,
onChanged: (newPopup) {
@@ -110,7 +111,7 @@ class _BloodPressureScreenState extends State<BloodPressureScreen> {
},
),
SizedBox(height: 16),
Text("do_you_have_hypertension_tendency".tr),
Text(s.do_you_have_hypertension_tendency),
SizedBox(height: 4),
CustomDropDown(
icon: Container(
@@ -124,7 +125,7 @@ class _BloodPressureScreenState extends State<BloodPressureScreen> {
width: 16,
),
),
hintText: "Не выбрано".tr,
hintText: "Не выбрано",
items: selectionPopupList,
value: selectedPopupHyper,
onChanged: (newPopup) {

View File

@@ -1,6 +1,6 @@
import 'package:eatvio_app/features/registration/models/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/localization/app_localization.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@@ -33,43 +33,44 @@ class _BodyCircumferencesScreenState extends State<BodyCircumferencesScreen> {
@override
Widget build(BuildContext context) {
final s = S.of(context);
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80, left: 16, right: 16, top: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("chest_circumference".tr),
Text(s.chest_circumference),
SizedBox(height: 4),
CustomTextFormField(
inputFormatters: [digitsOnly],
autofocus: true,
focusNode: chestFocus,
controller: chestCircumferenceController,
hintText: "90".tr,
hintText: '90',
onChanged: (value) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(chestCircumference: int.parse(value)));
},
),
SizedBox(height: 16),
Text("waist_circumference".tr),
Text(s.waist_circumference),
SizedBox(height: 4),
CustomTextFormField(
inputFormatters: [digitsOnly],
controller: waistCircumferenceController,
hintText: "60".tr,
hintText: "60",
onChanged: (value) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(waistCircumference: int.parse(value)));
},
),
SizedBox(height: 16),
Text("hip_circumference".tr),
Text(s.hip_circumference),
SizedBox(height: 4),
CustomTextFormField(
inputFormatters: [digitsOnly],
controller: hipCircumferenceController,
hintText: "90".tr,
hintText: '90',
textInputAction: TextInputAction.done,
onChanged: (value) {
final registrationCubit = context.read<RegistrationCubit>();

View File

@@ -1,6 +1,6 @@
import 'package:eatvio_app/features/registration/models/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/localization/app_localization.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -31,13 +31,14 @@ class _CredentialsScreenState extends State<CredentialsScreen> {
@override
Widget build(BuildContext context) {
final s = S.of(context);
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80, top: 16, left: 16, right: 16),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("email".tr),
Text(s.email),
SizedBox(height: 4),
CustomTextFormField(
controller: emailController,
@@ -51,7 +52,7 @@ class _CredentialsScreenState extends State<CredentialsScreen> {
},
),
SizedBox(height: 16),
Text("password".tr),
Text(s.password),
SizedBox(height: 4),
CustomTextFormField(
obscureText: true,
@@ -64,7 +65,7 @@ class _CredentialsScreenState extends State<CredentialsScreen> {
},
),
SizedBox(height: 16),
Text("password_confirmation".tr),
Text(s.password_confirmation),
SizedBox(height: 4),
CustomTextFormField(
obscureText: true,

View File

@@ -1,7 +1,7 @@
import 'package:eatvio_app/core/utils/date_time_utils.dart';
import 'package:eatvio_app/features/registration/models/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/localization/app_localization.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/theme/theme_helper.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@@ -34,12 +34,13 @@ class _DateOfBirthScreenState extends State<DateOfBirthScreen> {
@override
Widget build(BuildContext context) {
final s = S.of(context);
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80, top: 16, left: 16, right: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("date_of_birth".tr),
Text(s.date_of_birth),
SizedBox(height: 4),
ListTile(
onTap: onTapCalendar(context),

View File

@@ -1,6 +1,6 @@
import 'package:eatvio_app/features/registration/models/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/localization/app_localization.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -29,16 +29,17 @@ class _FavoriteFoodsScreenState extends State<FavoriteFoodsScreen> {
@override
Widget build(BuildContext context) {
final s = S.of(context);
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80, left: 16, right: 16, top: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("favorite_foods".tr),
Text(s.favorite_foods),
SizedBox(height: 4),
CustomTextFormField(
controller: favoriteFoodsController,
hintText: "enter_information".tr,
hintText: s.enter_information,
maxLines: 7,
minLines: 2,
focusNode: favoriteFocusNode,
@@ -49,11 +50,11 @@ class _FavoriteFoodsScreenState extends State<FavoriteFoodsScreen> {
},
),
SizedBox(height: 16),
Text("unfavorite_foods".tr),
Text(s.unfavorite_foods),
SizedBox(height: 4),
CustomTextFormField(
controller: unFavoriteFoodsController,
hintText: "enter_information".tr,
hintText: s.enter_information,
textInputAction: TextInputAction.done,
maxLines: 7,
minLines: 2,

View File

@@ -1,6 +1,6 @@
import 'package:eatvio_app/features/registration/models/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/localization/app_localization.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -27,12 +27,13 @@ class _FavoriteSportsScreenState extends State<FavoriteSportsScreen> {
@override
Widget build(BuildContext context) {
final s = S.of(context);
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80, left: 16, right: 16, top: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("your_favorite_sports".tr),
Text(s.your_favorite_sports),
SizedBox(height: 4),
CustomTextFormField(
controller: enterInformationController,

View File

@@ -1,6 +1,6 @@
import 'package:eatvio_app/features/registration/models/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/localization/app_localization.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@@ -28,12 +28,13 @@ class _HeightScreenState extends State<HeightScreen> {
@override
Widget build(BuildContext context) {
final s = S.of(context);
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80, left: 16, right: 16, top: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("your_height".tr),
Text(s.your_height),
SizedBox(height: 4),
CustomTextFormField(
textInputAction: TextInputAction.done,

View File

@@ -1,7 +1,7 @@
import 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model.dart';
import 'package:eatvio_app/features/registration/models/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/localization/app_localization.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/widgets/custom_drop_down.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -36,18 +36,19 @@ class _LanguageSelectScreenState extends State<LanguageSelectScreen> {
@override
Widget build(BuildContext context) {
final s = S.of(context);
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80, right: 16, left: 16, top: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"preferred_language".tr,
s.preferred_language,
),
const SizedBox(height: 4),
CustomDropDown(
value: value,
hintText: "Не выбрано".tr,
hintText: "Не выбрано",
items: dropdownItemList,
onChanged: (SelectionPopupModel newValue) => setState(() {
value = newValue;

View File

@@ -1,6 +1,6 @@
import 'package:eatvio_app/features/registration/models/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/localization/app_localization.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -27,16 +27,17 @@ class _MedicineIntakeScreenState extends State<MedicineIntakeScreen> {
@override
Widget build(BuildContext context) {
final s = S.of(context);
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80, left: 16, right: 16, top: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("do_you_take_pills".tr),
Text(s.do_you_take_pills),
SizedBox(height: 4),
CustomTextFormField(
controller: enterInformationController,
hintText: "enter_information".tr,
hintText: s.enter_information,
textInputAction: TextInputAction.done,
focusNode: infoFocusNode,
autofocus: true,

View File

@@ -1,6 +1,6 @@
import 'package:eatvio_app/features/registration/models/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/localization/app_localization.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -29,12 +29,13 @@ class _NameScreenState extends State<NameScreen> {
@override
Widget build(BuildContext context) {
final s = S.of(context);
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80, top: 16, left: 16, right: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("first_name".tr),
Text(s.first_name),
SizedBox(height: 4),
CustomTextFormField(
controller: firstNameController,
@@ -47,7 +48,7 @@ class _NameScreenState extends State<NameScreen> {
},
),
SizedBox(height: 16),
Text("last_name".tr),
Text(s.last_name),
SizedBox(height: 4),
CustomTextFormField(
controller: lastNameController,

View File

@@ -16,7 +16,7 @@ import 'package:eatvio_app/features/registration/presentation/pages/language_sel
import 'package:eatvio_app/features/registration/presentation/pages/medicine_intake_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/name_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/weight_screen.dart';
import 'package:eatvio_app/localization/app_localization.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/locator_service.dart';
import 'package:eatvio_app/theme/theme_helper.dart';
import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart';
@@ -180,7 +180,12 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
Future<bool> canGoNext(RegistrationState state) async {
switch (step) {
case 2:
List<String> errors = validateCredentialsFields(state.sheet.email, state.sheet.password, state.sheet.passwordConfirmation);
List<String> errors = validateCredentialsFields(
state.sheet.email,
state.sheet.password,
state.sheet.passwordConfirmation,
context,
);
if (errors.isEmpty) {
return true;
} else {
@@ -209,6 +214,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
List<String> errors = validateNameFields(
state.sheet.firstName.toString(),
state.sheet.lastName.toString(),
context,
);
if (errors.isEmpty) {
return true;
@@ -277,6 +283,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
state.sheet.chestCircumference.toString(),
state.sheet.waistCircumference.toString(),
state.sheet.hipCircumference.toString(),
context,
);
if (errors.isEmpty) {
return true;
@@ -336,43 +343,57 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
String chestCircumference,
String waistCircumference,
String hipCircumference,
BuildContext context,
) {
final s = S.of(context);
List<String> errors = [];
if (chestCircumference.isEmpty | waistCircumference.isEmpty | hipCircumference.isEmpty) {
errors.add('circumference_empty'.tr);
errors.add(s.circumference_empty);
}
if (![chestCircumference, waistCircumference, hipCircumference].every((circumference) => int.tryParse(circumference) != null)) {
errors.add('circumference_is_not_a_number'.tr);
errors.add(s.circumference_is_not_a_number);
}
return errors;
}
List<String> validateCredentialsFields(String email, String password, String passwordConfirmation) {
List<String> validateCredentialsFields(
String email,
String password,
String passwordConfirmation,
BuildContext context,
) {
final s = S.of(context);
List<String> errors = [];
if (!isEmail(email)) {
errors.add('email_invalid'.tr);
errors.add(s.email_invalid);
}
if (email.isEmpty) {
errors.add('email_empty'.tr);
errors.add(s.email_empty);
}
if (password.length < 6) {
errors.add('password_short'.tr);
errors.add(s.password_short);
}
if (password != passwordConfirmation) {
errors.add('password_confirmation_mismatch'.tr);
errors.add(s.password_confirmation_mismatch);
}
return errors;
}
List<String> validateNameFields(String firstName, String lastName) {
List<String> validateNameFields(
String firstName,
String lastName,
BuildContext context,
) {
List<String> errors = [];
if (firstName.isEmpty) {

View File

@@ -1,6 +1,6 @@
import 'package:eatvio_app/features/registration/models/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/localization/app_localization.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@@ -28,12 +28,13 @@ class _WeightScreenState extends State<WeightScreen> {
@override
Widget build(BuildContext context) {
final s = S.of(context);
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80, left: 16, right: 16, top: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("your_weight".tr),
Text(s.your_weight),
SizedBox(height: 4),
CustomTextFormField(
autofocus: true,

View File

@@ -0,0 +1,63 @@
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
// This is a library that looks up messages for specific locales by
// delegating to the appropriate library.
// Ignore issues from commonly used lints in this file.
// ignore_for_file:implementation_imports, file_names, unnecessary_new
// ignore_for_file:unnecessary_brace_in_string_interps, directives_ordering
// ignore_for_file:argument_type_not_assignable, invalid_assignment
// ignore_for_file:prefer_single_quotes, prefer_generic_function_type_aliases
// ignore_for_file:comment_references
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:intl/intl.dart';
import 'package:intl/message_lookup_by_library.dart';
import 'package:intl/src/intl_helpers.dart';
import 'messages_en.dart' as messages_en;
typedef Future<dynamic> LibraryLoader();
Map<String, LibraryLoader> _deferredLibraries = {
'en': () => new SynchronousFuture(null),
};
MessageLookupByLibrary? _findExact(String localeName) {
switch (localeName) {
case 'en':
return messages_en.messages;
default:
return null;
}
}
/// 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);
if (availableLocale == null) {
return new SynchronousFuture(false);
}
var lib = _deferredLibraries[availableLocale];
lib == null ? new SynchronousFuture(false) : lib();
initializeInternalMessageLookup(() => new CompositeMessageLookup());
messageLookup.addLocale(availableLocale, _findGeneratedMessagesFor);
return new SynchronousFuture(true);
}
bool _messagesExistFor(String locale) {
try {
return _findExact(locale) != null;
} catch (e) {
return false;
}
}
MessageLookupByLibrary? _findGeneratedMessagesFor(String locale) {
var actualLocale =
Intl.verifiedLocale(locale, _messagesExistFor, onFailure: (_) => null);
if (actualLocale == null) return null;
return _findExact(actualLocale);
}

View File

@@ -0,0 +1,174 @@
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
// This is a library that provides messages for a en locale. All the
// messages from the main program should be duplicated here with the same
// function name.
// Ignore issues from commonly used lints in this file.
// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
// ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes
// ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes
import 'package:intl/intl.dart';
import 'package:intl/message_lookup_by_library.dart';
final messages = new MessageLookup();
typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
class MessageLookup extends MessageLookupByLibrary {
String get localeName => 'en';
final messages = _notInlinedMessages(_notInlinedMessages);
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
"Moscow": MessageLookupByLibrary.simpleMessage("Москва"),
"Russia": MessageLookupByLibrary.simpleMessage("Россия"),
"active": MessageLookupByLibrary.simpleMessage("Активен"),
"add_measure": MessageLookupByLibrary.simpleMessage("Добавить замер"),
"additional_information":
MessageLookupByLibrary.simpleMessage("Дополнительная информация"),
"admin": MessageLookupByLibrary.simpleMessage("Админ"),
"allergies_presence":
MessageLookupByLibrary.simpleMessage("Наличие аллергии"),
"archived": MessageLookupByLibrary.simpleMessage("В архиве"),
"authentificate": MessageLookupByLibrary.simpleMessage("Войти"),
"average_pressure": MessageLookupByLibrary.simpleMessage(
"Средние показатели давления:"),
"bodymass_chart": MessageLookupByLibrary.simpleMessage("График ИМТ"),
"chat": MessageLookupByLibrary.simpleMessage("Чат"),
"chest": MessageLookupByLibrary.simpleMessage("Грудь"),
"chest_circumference":
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("Город проживания"),
"continueButton": MessageLookupByLibrary.simpleMessage("Продолжить"),
"country": MessageLookupByLibrary.simpleMessage("Страна"),
"date_of_birth": MessageLookupByLibrary.simpleMessage("Дата рождения"),
"diary": MessageLookupByLibrary.simpleMessage("Дневник"),
"do_you_have_hypertension_tendency":
MessageLookupByLibrary.simpleMessage("Есть ли у вас гипертония?"),
"do_you_have_hypotension_tendency":
MessageLookupByLibrary.simpleMessage("Есть ли у вас гипотония?"),
"do_you_take_pills": MessageLookupByLibrary.simpleMessage(
"Принимаете ли вы лекарства или бады?"),
"down_pressure":
MessageLookupByLibrary.simpleMessage("Нижние показатели давления:"),
"draft": MessageLookupByLibrary.simpleMessage("Черновик"),
"email": MessageLookupByLibrary.simpleMessage("Элетронная почта"),
"email_empty": MessageLookupByLibrary.simpleMessage(
"Необходимо ввести адрес электронной почты"),
"email_invalid": MessageLookupByLibrary.simpleMessage(
"Некорректный адрес электронной почты"),
"enter_additional_information": MessageLookupByLibrary.simpleMessage(
"Введите любую дополнительную информацию на своё усмотрение:"),
"enter_information":
MessageLookupByLibrary.simpleMessage("Введите информацию..."),
"exit": MessageLookupByLibrary.simpleMessage("Выйти"),
"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 символ"),
"gr": MessageLookupByLibrary.simpleMessage("гр"),
"grams": MessageLookupByLibrary.simpleMessage("гр"),
"height_measurements":
MessageLookupByLibrary.simpleMessage("Замер роста"),
"hip_circumference":
MessageLookupByLibrary.simpleMessage("Обхват бедер"),
"hips": MessageLookupByLibrary.simpleMessage("Бедра"),
"in_progress": MessageLookupByLibrary.simpleMessage("В процессе"),
"initial_measurements":
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"),
"loading": MessageLookupByLibrary.simpleMessage("Загрузка..."),
"male": MessageLookupByLibrary.simpleMessage("Мужской"),
"msg_network_err":
MessageLookupByLibrary.simpleMessage("Сетевая ошибка!"),
"msg_something_went_wrong":
MessageLookupByLibrary.simpleMessage("Что то пошло не так!"),
"my_blog": MessageLookupByLibrary.simpleMessage("Мой блог"),
"my_settings": MessageLookupByLibrary.simpleMessage("Мои настройки"),
"name_empty": MessageLookupByLibrary.simpleMessage(
"Имя пользователя обязательно для заполнения"),
"name_short": MessageLookupByLibrary.simpleMessage(
"В имени пользователя должно быть минимум 6 символов"),
"no": MessageLookupByLibrary.simpleMessage("Нет"),
"no_account":
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("шт"),
"place_of_living":
MessageLookupByLibrary.simpleMessage("Место проживания"),
"plans_complete":
MessageLookupByLibrary.simpleMessage("Пройденные планы"),
"preferred_language":
MessageLookupByLibrary.simpleMessage("Предпочитаемый язык общения"),
"pressure_empty": MessageLookupByLibrary.simpleMessage(
"Все показатели давления обязательны к заполнению"),
"pressure_is_not_a_number": MessageLookupByLibrary.simpleMessage(
"Все показатели давления должны быть числами"),
"profile": MessageLookupByLibrary.simpleMessage("Профиль"),
"save": MessageLookupByLibrary.simpleMessage("Сохранить"),
"skip": MessageLookupByLibrary.simpleMessage("Пропустить"),
"tell_your_schedule": MessageLookupByLibrary.simpleMessage(
"Расскажите в свободной форме о том как просыпаетесь, когда едите, когда ложитесь спать:"),
"unfavorite_foods":
MessageLookupByLibrary.simpleMessage("Нелюбимые продукты"),
"up_pressure": MessageLookupByLibrary.simpleMessage(
"Верхние показатели давления:"),
"user_authorization":
MessageLookupByLibrary.simpleMessage("Аутентификация"),
"user_registration":
MessageLookupByLibrary.simpleMessage("Регистрация пользователя"),
"username": MessageLookupByLibrary.simpleMessage("Имя пользователя"),
"waist": MessageLookupByLibrary.simpleMessage("Талия"),
"waist_circumference":
MessageLookupByLibrary.simpleMessage("Обхват талии"),
"weight": MessageLookupByLibrary.simpleMessage("Вес"),
"weight_chart": MessageLookupByLibrary.simpleMessage("График веса"),
"weight_measurements":
MessageLookupByLibrary.simpleMessage("Замер веса"),
"what_is_your_name":
MessageLookupByLibrary.simpleMessage("Как вас зовут?"),
"wrong_credentials": 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("Ваш вес:")
};
}

1048
lib/generated/l10n.dart Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,44 +1,32 @@
final Map<String, String> ru = {
//credentials Screen
{
"user_registration": "Регистрация пользователя",
"email": "Элетронная почта",
"username": "Имя пользователя",
"password": "Пароль",
"password_confirmation": "Подтвердите пароль",
'wrong_credentials': "Неверные данные пользователя",
//name Screen
"wrong_credentials": "Неверные данные пользователя",
"first_name": "Имя",
"last_name": "Фамилия",
"what_is_your_name": "Как вас зовут?",
// date_of_birth Screen
"date_of_birth": "Дата рождения",
// city_of_living Screen
"country": "Страна", "Russia": "Россия", "city": "Город", "Moscow": "Москва",
"country": "Страна",
"Russia": "Россия",
"city": "Город",
"Moscow": "Москва",
"place_of_living": "Место проживания",
// body_circumferences Screen
"hip_circumference": "Обхват бедер", "chest_circumference": "Обхват груди",
"hip_circumference": "Обхват бедер",
"chest_circumference": "Обхват груди",
"waist_circumference": "Обхват талии",
"initial_measurements": "Первичные замеры",
"male": "Мужской",
"female": "Женский",
// weight Screen
"weight_measurements": "Замер веса", "your_weight": "Ваш вес:",
"height_measurements": "Замер роста", "your_height": "Ваш рост:",
// allergies Screen
"weight_measurements": "Замер веса",
"your_weight": "Ваш вес:",
"height_measurements": "Замер роста",
"your_height": "Ваш рост:",
"allergies_presence": "Наличие аллергии",
// medicine_intake Screen
"do_you_take_pills": "Принимаете ли вы лекарства или бады?",
// gender Screen
"your_gender": "Ваш пол?",
// blood_pressure Screen
"no": "Нет",
"do_you_have_hypertension_tendency": "Есть ли у вас гипертония?",
"your_blood_pressure": "Ваше артериальное давление?",
@@ -46,39 +34,23 @@ final Map<String, String> ru = {
"up_pressure": "Верхние показатели давления:",
"down_pressure": "Нижние показатели давления:",
"do_you_have_hypotension_tendency": "Есть ли у вас гипотония?",
// favorite_sports Screen
"your_favorite_sports": "Ваши спортивные увлечения?",
// favorite_foods Screen
"favorite_foods": "Любимые продукты",
"favorite_unfavorite_foods": "Ваши любимые/нелюбимые продукты питания?",
"unfavorite_foods": "Нелюбимые продукты",
// schedule Screen
"your_schedule": "Ваш режим дня?",
"tell_your_schedule": "Расскажите в свободной форме о том как просыпаетесь, когда едите, когда ложитесь спать:",
// additional_information Screen
"additional_information": "Дополнительная информация",
"enter_additional_information": "Введите любую дополнительную информацию на своё усмотрение:",
// language_select Screen
"lbl_english": "English",
"finish": "Завершить",
"preferred_language": "Предпочитаемый язык общения",
// Common String
"continue": "Продолжить", "skip": "Пропустить",
"continueButton": "Продолжить",
"skip": "Пропустить",
"fill_in_information": "Заполните информацию:",
"enter_information": "Введите информацию...",
// Network Error String
"msg_network_err": "Сетевая ошибка!",
"msg_something_went_wrong": "Что то пошло не так!",
// Errors
// Credentials
"email_empty": "Необходимо ввести адрес электронной почты",
"email_invalid": "Некорректный адрес электронной почты",
"password_empty": "Пароль обязателен для заполнения",
@@ -86,27 +58,17 @@ final Map<String, String> ru = {
"name_empty": "Имя пользователя обязательно для заполнения",
"name_short": "В имени пользователя должно быть минимум 6 символов",
"password_confirmation_mismatch": "Пароли не совпадают",
// Name
"first_name_empty": "Имя обязательно для заполнения",
"first_name_short": "В имени должен быть минимум 1 символ",
"last_name_empty": "Фамилия обязательна для заполнения",
"last_name_short": "В фамилии должен быть минимум 6 символов",
// Body Circumference
"circumference_empty": "Все замеры обязательны к заполнению",
"circumference_is_not_a_number": "Все замеры должны быть числами",
// Body Circumference
"pressure_empty": "Все показатели давления обязательны к заполнению",
"pressure_is_not_a_number": "Все показатели давления должны быть числами",
// Authorization
"no_account": "У меня нет аккаунта",
"authentificate": "Войти",
"user_authorization": "Аутентификация",
// Личный кабинет Screen
"loading": "Загрузка...",
"weight_chart": "График веса",
"circumferences_chart": "График обхватов",
@@ -133,5 +95,5 @@ final Map<String, String> ru = {
"save": "Сохранить",
"pcs": "шт",
"gr": "гр",
"grams": "гр",
};
"grams": "гр"
}

View File

@@ -1,61 +0,0 @@
import 'package:eatvio_app/app_router.dart';
import 'package:flutter/cupertino.dart';
//import 'en_us/en_us_translations.dart';
import 'package:flutter/foundation.dart';
import 'ru/ru_translations.dart';
class AppLocalization {
AppLocalization(this.locale);
Locale locale;
static final Map<String, Map<String, String>> _localizedValues = {
'ru': ru,
};
/*static final Map<String, Map<String, String>> __localizedValues = {
'en': enUs
};*/
static AppLocalization of() {
final context = AppRouter.navigatorKey.currentContext;
if (context != null) {
return Localizations.of<AppLocalization>(context, AppLocalization)!;
} else {
// Обработка ситуации, когда context равен null
return AppLocalization(
Locale(
'ru',
'',
),
); // Возвращаем дефолтное значение или обработку ошибки
}
}
static List<String> languages() => _localizedValues.keys.toList();
String getString(String text) => _localizedValues[locale.languageCode]![text] ?? text;
}
class AppLocalizationDelegate extends LocalizationsDelegate<AppLocalization> {
const AppLocalizationDelegate();
@override
bool isSupported(Locale locale) => AppLocalization.languages().contains(locale.languageCode);
//Returning a SynchronousFuture here because an async "load" operation
//cause an async "load" operation
@override
Future<AppLocalization> load(Locale locale) {
return SynchronousFuture<AppLocalization>(AppLocalization(locale));
}
@override
bool shouldReload(AppLocalizationDelegate old) => false;
}
extension LocalizationExtension on String {
String get tr => AppLocalization.of().getString(this);
}

View File

@@ -1,63 +0,0 @@
final Map<String, String> enUs = {
// date_of_birth Screen
"date_of_birth": "Date of Birth",
// city_of_living Screen
"country": "Country", "Russia": "Russia", "city": "City", "Moscow": "Moscow",
"place_of_living": "Place of Living",
// body_circumferences Screen
"hip_circumference": "Hip circumference",
"chest_circumference": "Chest circumference",
"waist_circumference": "Waist circumference",
"initial_measurements": "Initial measurements",
// weight Screen
"weight_measurements": "Weight measurements", "your_weight": "Your weight:",
"height_measurements": "Height measurements", "your_height": "Your height:",
// allergies Screen
"allergies_presence": "Allergies presence",
// medicine_intake Screen
"do_you_take_pills": "Do you take pills or supplements?",
// gender Screen
"your_gender": "Your Gender?",
// blood_pressure Screen
"no": "No",
"do_you_have_hypertension_tendency": "Do you have a tendency for hypertension?",
"your_blood_pressure": "Your blood pressure?",
"average_pressure": "Average pressure:",
"do_you_have_hypotension_tendency": "Do you have a tendency for hypotension?",
// favorite_sports Screen
"your_favorite_sports": "Your Favorite Sports?",
// favorite_foods Screen
"favorite_foods": "Favorite Foods:",
"favorite_unfavorite_foods": "Your most ot reast favorite foods?",
"unfavorite_foods": "Unfavorite Foods:",
// schedule Screen
"your_schedule": "Your Daily Schedule?",
"tell_your_schedule": "Tell us about your daily routine, when you wake up, eat, and go to sleep:",
// additional_information Screen
"additional_information": "Additional Information:",
"enter_additional_information": "Enter any additional information you would like to share:",
// language_select Screen
"lbl_english": "English",
"preferred_language": "Preferred Language",
// Common String
"continue": "Continue", "skip": "Skip",
"fill_in_information": "Fill in Information:",
"enter_information": "Enter Information...",
// Network Error String
"msg_network_err": "Network Error!",
"msg_something_went_wrong": "Something went wrong!",
};

View File

@@ -2,7 +2,7 @@ import 'package:eatvio_app/app_router.dart';
import 'package:eatvio_app/core/initialization_cubit/initialization_cubit.dart';
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/new_messages_cubit/new_messages_cubit.dart';
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/notifications_cubit/notifications_cubit.dart';
import 'package:eatvio_app/localization/app_localization.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/locator_service.dart' as di;
import 'package:eatvio_app/locator_service.dart';
import 'package:eatvio_app/theme/theme_helper.dart';
@@ -33,21 +33,19 @@ class MyApp extends StatelessWidget {
theme: ThemeData.light().copyWith(
colorScheme: ColorScheme.fromSeed(seedColor: appTheme.blueA400),
),
// darkTheme: ThemeData.dark().copyWith(),
darkTheme: ThemeData.dark().copyWith(
colorScheme: ColorScheme.fromSeed(seedColor: appTheme.blueA400),
),
themeMode: ThemeMode.system,
routerConfig: AppRouter.appRouter,
debugShowCheckedModeBanner: false,
localizationsDelegates: [
AppLocalizationDelegate(),
localizationsDelegates: const [
S.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
Locale(
'ru',
),
],
supportedLocales: S.delegate.supportedLocales,
),
),
);

View File

@@ -3,7 +3,7 @@ import 'dart:convert';
import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/core/token_storage.dart';
import 'package:eatvio_app/core/utils/image_constant.dart';
import 'package:eatvio_app/localization/app_localization.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/theme/theme_helper.dart';
import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
@@ -40,6 +40,7 @@ class _AuthScreenState extends State<AuthScreen> {
@override
Widget build(BuildContext context) {
final s = S.of(context);
return Scaffold(
appBar: AppBar(
centerTitle: true,
@@ -51,7 +52,7 @@ class _AuthScreenState extends State<AuthScreen> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("email".tr),
Text(s.email),
SizedBox(height: 4),
BlocSelector<AuthBloc, AuthState, TextEditingController?>(
selector: (state) => state.emailController,
@@ -66,7 +67,7 @@ class _AuthScreenState extends State<AuthScreen> {
},
),
SizedBox(height: 16),
Text("password".tr),
Text(s.password),
SizedBox(height: 4),
BlocSelector<AuthBloc, AuthState, TextEditingController?>(
selector: (state) => state.passwordController,
@@ -154,6 +155,7 @@ class _AuthScreenState extends State<AuthScreen> {
}
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) {
@@ -178,7 +180,7 @@ class _AuthScreenState extends State<AuthScreen> {
context: context,
builder: (context) => AlertDialog(
title: Text('Ошибка'),
content: Text('wrong_credentials'.tr),
content: Text(s.wrong_credentials),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
@@ -213,22 +215,24 @@ class _AuthScreenState extends State<AuthScreen> {
}
List<String> validateFields(String email, String password) {
final s = S.of(context);
List<String> errors = [];
if (!isEmail(email)) {
errors.add('email_invalid'.tr);
errors.add(s.email_invalid);
}
if (email.isEmpty) {
errors.add('email_empty'.tr);
errors.add(s.email_empty);
}
if (password.isEmpty) {
errors.add('password_empty'.tr);
errors.add(s.password_empty);
}
if (password.length < 6) {
errors.add('password_short'.tr);
errors.add(s.password_short);
}
return errors;

View File

@@ -1,10 +1,9 @@
import 'dart:convert';
import 'dart:math';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:carousel_slider_plus/carousel_slider_plus.dart';
import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/localization/app_localization.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/theme/app_decoration.dart';
import 'package:eatvio_app/theme/custom_text_style.dart';
import 'package:eatvio_app/theme/theme_helper.dart';
@@ -194,7 +193,8 @@ class MyProfileScreen extends StatelessWidget {
};
}
_buildCarousel(BuildContext contex, MyProfileLoadedState state) {
_buildCarousel(BuildContext context, MyProfileLoadedState state) {
final s = S.of(context);
return CarouselSlider(
options: CarouselOptions(height: 340),
items: [1, 2, 3].map((chartType) {
@@ -207,7 +207,7 @@ class MyProfileScreen extends StatelessWidget {
child: Column(
children: [
Text(
"weight_chart".tr,
s.weight_chart,
style: CustomTextStyles.titleMediumBlack.copyWith(
color: appTheme.black900,
),
@@ -225,7 +225,7 @@ class MyProfileScreen extends StatelessWidget {
return Column(
children: [
Text(
"bodymass_chart".tr,
s.bodymass_chart,
style: CustomTextStyles.titleMediumBlack.copyWith(
color: appTheme.black900,
),
@@ -247,14 +247,14 @@ class MyProfileScreen extends StatelessWidget {
child: Column(
children: [
Text(
"circumferences_chart".tr,
s.circumferences_chart,
style: CustomTextStyles.titleMediumBlack.copyWith(
color: appTheme.black900,
),
),
SizedBox(height: 30),
_buildCircumferenceChart(context, state.circumferences, state.chartDates),
_buildChartLegend(),
_buildChartLegend(context),
],
),
);
@@ -267,9 +267,10 @@ class MyProfileScreen extends StatelessWidget {
);
}
_buildChartLegend() {
_buildChartLegend(BuildContext context) {
final s = S.of(context);
final colors = [Colors.pink, Colors.green, Colors.purple];
final titles = ["chest".tr, "waist".tr, "hips".tr];
final titles = [s.chest, s.waist, s.hips];
final style = TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
@@ -650,13 +651,14 @@ class MyProfileScreen extends StatelessWidget {
/// Section Widget
_buildPlans(BuildContext context, List<dynamic>? plans, List<dynamic>? imagePaths, List<dynamic>? states) {
final s = S.of(context);
return Padding(
padding: EdgeInsets.only(left: 7),
child: Column(
children: [
Padding(
padding: EdgeInsets.only(left: 15),
child: Text("plans_complete".tr, style: CustomTextStyles.titleMediumBlack.copyWith(color: appTheme.black900)),
child: Text(s.plans_complete, style: CustomTextStyles.titleMediumBlack.copyWith(color: appTheme.black900)),
),
SizedBox(height: 5),
Container(
@@ -735,7 +737,7 @@ class MyProfileScreen extends StatelessWidget {
child: Container(
width: 70,
margin: EdgeInsets.only(bottom: 14, right: 22),
child: Text("$state".tr, maxLines: 3, overflow: TextOverflow.ellipsis, style: theme.textTheme.titleSmall),
child: Text("$state", maxLines: 3, overflow: TextOverflow.ellipsis, style: theme.textTheme.titleSmall),
),
),
],
@@ -765,6 +767,7 @@ class MyProfileScreen extends StatelessWidget {
}
_editCircumference(BuildContext context, MyProfileLoadedState state) {
final s = S.of(context);
showDialog(
context: context,
builder: (context) {
@@ -779,7 +782,7 @@ class MyProfileScreen extends StatelessWidget {
children: [
Padding(
padding: EdgeInsets.symmetric(vertical: 5),
child: Text("chest_circumference".tr, style: theme.textTheme.bodyLarge),
child: Text(s.chest_circumference, style: theme.textTheme.bodyLarge),
),
SizedBox(height: 5),
CustomTextFormField(
@@ -791,7 +794,7 @@ class MyProfileScreen extends StatelessWidget {
),
Padding(
padding: EdgeInsets.symmetric(vertical: 15),
child: Text("waist_circumference".tr, style: theme.textTheme.bodyLarge),
child: Text(s.waist_circumference, style: theme.textTheme.bodyLarge),
),
SizedBox(height: 5),
CustomTextFormField(
@@ -803,7 +806,7 @@ class MyProfileScreen extends StatelessWidget {
),
Padding(
padding: EdgeInsets.symmetric(vertical: 15),
child: Text("hip_circumference".tr, style: theme.textTheme.bodyLarge),
child: Text(s.hip_circumference, style: theme.textTheme.bodyLarge),
),
SizedBox(height: 5),
CustomTextFormField(
@@ -876,6 +879,7 @@ class MyProfileScreen extends StatelessWidget {
}
_editWeight(BuildContext context, MyProfileLoadedState state) {
final s = S.of(context);
showDialog(
context: context,
builder: (context) {
@@ -887,7 +891,7 @@ class MyProfileScreen extends StatelessWidget {
children: [
Padding(
padding: EdgeInsets.symmetric(vertical: 5),
child: Text("weight".tr, style: theme.textTheme.bodyLarge),
child: Text(s.weight, style: theme.textTheme.bodyLarge),
),
SizedBox(height: 5),
CustomTextFormField(

View File

@@ -2,7 +2,7 @@ import 'dart:convert';
import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/core/token_storage.dart';
import 'package:eatvio_app/localization/app_localization.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/old/profile/my_profile_screen/bloc/my_profile_bloc.dart';
import 'package:eatvio_app/theme/custom_button_style.dart';
import 'package:eatvio_app/widgets/custom_hyper_switch.dart';
@@ -87,6 +87,7 @@ class _ExpandableListState extends State<ExpandableList> {
}
_buildForm(BuildContext context, MyProfileLoadedState state) {
final s = S.of(context);
List<String> cities = [
'Москва',
'Санкт-Петербург',
@@ -134,14 +135,14 @@ class _ExpandableListState extends State<ExpandableList> {
children: [
TextField(
controller: state.firstNameFormController,
decoration: InputDecoration(labelText: 'first_name'.tr),
decoration: InputDecoration(labelText: s.first_name),
),
TextField(
controller: state.lastNameFormController,
decoration: InputDecoration(labelText: 'last_name'.tr),
decoration: InputDecoration(labelText: s.last_name),
),
TextField(
decoration: InputDecoration(labelText: 'date_of_birth'.tr),
decoration: InputDecoration(labelText: s.date_of_birth),
controller: state.dateFormController,
onTap: inputTime(context, state),
),
@@ -155,7 +156,7 @@ class _ExpandableListState extends State<ExpandableList> {
child: Text(value),
);
}).toList(),
decoration: InputDecoration(labelText: 'country'.tr),
decoration: InputDecoration(labelText: s.country),
),
DropdownButtonFormField<String>(
hint: Text(state.selectedCity ?? "Не выбрано"),
@@ -167,78 +168,78 @@ class _ExpandableListState extends State<ExpandableList> {
child: Text(value),
);
}).toList(),
decoration: InputDecoration(labelText: 'city_of_living'.tr),
decoration: InputDecoration(labelText: s.city_of_living),
),
TextField(
controller: state.weightFormController,
decoration: InputDecoration(labelText: 'weight_measurements'.tr),
decoration: InputDecoration(labelText: s.weight_measurements),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[digitsOnly],
),
TextField(
controller: state.heightFormController,
decoration: InputDecoration(labelText: 'height_measurements'.tr),
decoration: InputDecoration(labelText: s.height_measurements),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[digitsOnly],
),
TextField(
controller: state.chestCircumferenceFormController,
decoration: InputDecoration(labelText: 'chest_circumference'.tr),
decoration: InputDecoration(labelText: s.chest_circumference),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[digitsOnly],
),
TextField(
controller: state.waistCircumferenceFormController,
decoration: InputDecoration(labelText: 'waist_circumference'.tr),
decoration: InputDecoration(labelText: s.waist_circumference),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[digitsOnly],
),
TextField(
controller: state.hipCircumferenceFormController,
decoration: InputDecoration(labelText: 'hip_circumference'.tr),
decoration: InputDecoration(labelText: s.hip_circumference),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[digitsOnly],
),
TextField(
controller: state.upPressureFormController,
decoration: InputDecoration(labelText: 'up_pressure'.tr),
decoration: InputDecoration(labelText: s.up_pressure),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[digitsOnly],
),
TextField(
controller: state.downPressureFormController,
decoration: InputDecoration(labelText: 'down_pressure'.tr),
decoration: InputDecoration(labelText: s.down_pressure),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[digitsOnly],
),
TextField(
controller: state.allergiesFormController,
decoration: InputDecoration(labelText: 'allergies_presence'.tr),
decoration: InputDecoration(labelText: s.allergies_presence),
maxLines: null,
),
TextField(
controller: state.pillsFormController,
decoration: InputDecoration(labelText: 'do_you_take_pills'.tr),
decoration: InputDecoration(labelText: s.do_you_take_pills),
maxLines: null,
),
TextField(
controller: state.sportsFormController,
decoration: InputDecoration(labelText: 'your_favorite_sports'.tr),
decoration: InputDecoration(labelText: s.your_favorite_sports),
maxLines: null,
),
TextField(
controller: state.favoriteFormController,
decoration: InputDecoration(labelText: 'favorite_foods'.tr),
decoration: InputDecoration(labelText: s.favorite_foods),
maxLines: null,
),
TextField(
controller: state.unfavoriteFormController,
decoration: InputDecoration(labelText: 'unfavorite_foods'.tr),
decoration: InputDecoration(labelText: s.unfavorite_foods),
maxLines: null,
),
TextField(
controller: state.additionalFormController,
decoration: InputDecoration(labelText: 'additional_information'.tr),
decoration: InputDecoration(labelText: s.additional_information),
maxLines: null,
),
DropdownButtonFormField<String>(
@@ -261,18 +262,18 @@ class _ExpandableListState extends State<ExpandableList> {
),
Row(
children: [
HypoSwitch('do_you_have_hypotension_tendency'.tr, state),
HypoSwitch(s.do_you_have_hypotension_tendency, state),
],
),
Row(
children: [
HyperSwitch('do_you_have_hypertension_tendency'.tr, state),
HyperSwitch(s.do_you_have_hypertension_tendency, state),
],
),
NextStepButton(
onPressed: () => sendProfileData(state),
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
text: "save".tr.toUpperCase(),
text: s.save.toUpperCase(),
margin: EdgeInsets.only(top: 20, bottom: 20),
),
],

View File

@@ -54,6 +54,7 @@ dependencies:
flutter_html: ^3.0.0-beta.2
file_picker: ^8.1.2
audioplayers: ^6.1.0
intl: ^0.19.0
dev_dependencies:
build_runner: ^2.4.12
@@ -71,3 +72,5 @@ flutter:
- assets/images/
- assets/audio/
- assets/icons/
flutter_intl:
enabled: true

View File

@@ -1,11 +1,11 @@
import 'package:eatvio_app/localization/app_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/old/auth/auth_screen/auth_screen.dart';
import 'package:eatvio_app/old/auth/auth_screen/bloc/auth_bloc.dart';
import 'package:eatvio_app/old/auth/auth_screen/models/auth_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
group('AuthScreen', () {
@@ -14,18 +14,13 @@ void main() {
await tester.pumpWidget(
MaterialApp(
localizationsDelegates: [
AppLocalizationDelegate(),
localizationsDelegates: const [
S.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
Locale(
'ru',
'',
),
],
supportedLocales: S.delegate.supportedLocales,
home: BlocProvider<AuthBloc>(
create: (context) => authBloc,
child: Builder(