diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
index 65f4f4f7..046c0614 100644
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -388,7 +388,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)";
CODE_SIGN_STYLE = Manual;
- CURRENT_PROJECT_VERSION = 38;
+ CURRENT_PROJECT_VERSION = 39;
DEVELOPMENT_TEAM = VL68C36HYS;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
@@ -538,7 +538,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)";
CODE_SIGN_STYLE = Manual;
- CURRENT_PROJECT_VERSION = 38;
+ CURRENT_PROJECT_VERSION = 39;
DEVELOPMENT_TEAM = VL68C36HYS;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
@@ -576,7 +576,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)";
CODE_SIGN_STYLE = Manual;
- CURRENT_PROJECT_VERSION = 38;
+ CURRENT_PROJECT_VERSION = 39;
DEVELOPMENT_TEAM = VL68C36HYS;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 72d42aff..d7a769f2 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -21,7 +21,7 @@
CFBundleSignature
????
CFBundleVersion
- 38
+ 39
ITSAppUsesNonExemptEncryption
LSRequiresIPhoneOS
diff --git a/lib/core/app_router.dart b/lib/core/app_router.dart
index 70107e0a..223a8913 100644
--- a/lib/core/app_router.dart
+++ b/lib/core/app_router.dart
@@ -121,7 +121,7 @@ class AppRouter {
GoRoute(
path: 'forget-password-screen',
name: 'forgetPasswordScreen',
- builder: (context, state) => const ForgetPasswordScreen(),
+ builder: (context, state) => ForgetPasswordScreen(isAuth: state.extra as bool,),
),
GoRoute(
path: 'scan-qr-code-screen',
diff --git a/lib/core/widgets/success_published_recipe_bottom_sheet.dart b/lib/core/widgets/success_published_recipe_bottom_sheet.dart
index 9fb1ddeb..796e7d91 100644
--- a/lib/core/widgets/success_published_recipe_bottom_sheet.dart
+++ b/lib/core/widgets/success_published_recipe_bottom_sheet.dart
@@ -26,9 +26,13 @@ class SuccessPublishedRecipeBottomSheet extends StatelessWidget {
s.recipe_publishing,
style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black),
),
- Text(
- '"$title" ${s.successfully_published}',
- style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black),
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 12),
+ child: Text(
+ '"$title" ${s.successfully_published}',
+ textAlign: TextAlign.center,
+ style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black),
+ ),
),
const SizedBox(
height: 20,
diff --git a/lib/features/auth/presentation/pages/auth_screen.dart b/lib/features/auth/presentation/pages/auth_screen.dart
index 31028059..6b4ec260 100644
--- a/lib/features/auth/presentation/pages/auth_screen.dart
+++ b/lib/features/auth/presentation/pages/auth_screen.dart
@@ -141,7 +141,7 @@ class _AuthScreenState extends State {
const SizedBox(height: 16),
Center(
child: GestureDetector(
- onTap: () => GoRouter.of(context).goNamed('forgetPasswordScreen'),
+ onTap: () => GoRouter.of(context).goNamed('forgetPasswordScreen', extra: false),
child: Text(
'Забыли пароль?',
style: TextStyle(
@@ -258,8 +258,77 @@ class _AuthScreenState extends State {
backgroundColor: state is AuthStateLoading ? Colors.black.withAlpha(50) : appTheme.blueA400,
onPressed: state is AuthStateLoading
? null
- : () {
- GoRouter.of(context).pushNamed('scanQRCodeScreen');
+ : () async {
+ await showDialog(
+ context: context,
+ builder: (BuildContext context) {
+ return Dialog(
+ child: Padding(
+ padding: const EdgeInsets.all(24),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ const Text(
+ 'Где взять QR-код?\n',
+ style: TextStyle(
+ fontSize: 18,
+ ),
+ ),
+ Text(
+ '1. Войдите на сайте $baseUrl в свой аккаунт\n\n2. Перейдите в настройки профиля\n\n3. В разделе "Доп информация" перейдите на "QR Login"'),
+ const SizedBox(height: 12),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ InkWell(
+ borderRadius: BorderRadius.circular(8),
+ onTap: () {
+ AppRouter.navigatorKey.currentContext?.pop();
+ },
+ child: Ink(
+ padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(8),
+ ),
+ child: const Text(
+ 'Отмена',
+ style: TextStyle(
+ color: Colors.black,
+ fontWeight: FontWeight.w400,
+ ),
+ ),
+ ),
+ ),
+ const SizedBox(width: 8),
+ InkWell(
+ borderRadius: BorderRadius.circular(8),
+ onTap: () {
+ AppRouter.navigatorKey.currentContext?.pop();
+ AppRouter.navigatorKey.currentContext?.pushNamed('scanQRCodeScreen');
+ },
+ child: Ink(
+ padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(8),
+ ),
+ child: Text(
+ 'Перейти',
+ style: TextStyle(
+ color: appTheme.blueA400,
+ fontWeight: FontWeight.w600,
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ );
+ },
+ );
},
label: state is AuthStateLoading
? const CupertinoActivityIndicator()
diff --git a/lib/features/auth/presentation/pages/forget_password_screen.dart b/lib/features/auth/presentation/pages/forget_password_screen.dart
index 78313a15..d842fcfc 100644
--- a/lib/features/auth/presentation/pages/forget_password_screen.dart
+++ b/lib/features/auth/presentation/pages/forget_password_screen.dart
@@ -9,7 +9,8 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
class ForgetPasswordScreen extends StatefulWidget {
- const ForgetPasswordScreen({super.key});
+ final bool isAuth;
+ const ForgetPasswordScreen({super.key, required this.isAuth});
@override
State createState() => _ForgetPasswordScreenState();
@@ -29,7 +30,7 @@ class _ForgetPasswordScreenState extends State {
builder: (BuildContext context, ResetPasswordState state) {
return Scaffold(
appBar: AppBar(
- title: const Text('Смена пароля'),
+ title: widget.isAuth ? const Text('Смена пароля') : const Text('Восстановление пароля'),
centerTitle: false,
),
body: state is ResetPasswordStateLoadingResetPassword || state is ResetPasswordStateLoadingSendEmailCode
@@ -42,9 +43,9 @@ class _ForgetPasswordScreenState extends State {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (state is ResetPasswordStateCodeSendError || state is ResetPasswordStateEmpty) ...[
- const Text(
- 'Забыли пароль? Укажите свой email,\nи мы пришлём код для сброса.',
- style: TextStyle(
+ Text(
+ '${widget.isAuth ? '' : 'Забыли пароль? '}Укажите свой email,\nи мы пришлём код для сброса.',
+ style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
),
@@ -156,7 +157,7 @@ class _ForgetPasswordScreenState extends State {
}
if (state is ResetPasswordStateResetPassowrdSuccess) {
GoRouter.of(context).pop();
- showSuccessToast('Пароль успешно сменён. Войдите в аккаунт');
+ showSuccessToast('Пароль успешно сменён. ${widget.isAuth ? '' : 'Войдите в аккаунт'}');
}
},
),
diff --git a/lib/features/diets/presentation/widgets/expandable_text.dart b/lib/features/diets/presentation/widgets/expandable_text.dart
index 18de6ae5..5832ec86 100644
--- a/lib/features/diets/presentation/widgets/expandable_text.dart
+++ b/lib/features/diets/presentation/widgets/expandable_text.dart
@@ -10,7 +10,11 @@ class ExpandableText extends StatefulWidget {
final String text;
final int maxLines;
- const ExpandableText({super.key, required this.text, this.maxLines = 3});
+ const ExpandableText({
+ super.key,
+ required this.text,
+ this.maxLines = 5, // по умолчанию 5 строк
+ });
@override
State createState() => _ExpandableTextState();
@@ -18,6 +22,29 @@ class ExpandableText extends StatefulWidget {
class _ExpandableTextState extends State {
bool isExpanded = false;
+ bool showExpandButton = false;
+
+ final GlobalKey _textKey = GlobalKey();
+
+ @override
+ void didChangeDependencies() {
+ super.didChangeDependencies();
+ WidgetsBinding.instance.addPostFrameCallback((_) => _checkTextOverflow());
+ }
+
+ void _checkTextOverflow() {
+ final textRenderObject = _textKey.currentContext?.findRenderObject();
+ if (textRenderObject is RenderBox) {
+ final maxLinesHeight = widget.maxLines * TextStyles.textMMediumAuto.fontSize! * 1.2;
+ final actualHeight = textRenderObject.size.height;
+
+ if (actualHeight > maxLinesHeight && !showExpandButton) {
+ setState(() {
+ showExpandButton = true;
+ });
+ }
+ }
+ }
void toggleExpansion() {
setState(() {
@@ -33,52 +60,63 @@ class _ExpandableTextState extends State {
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
- child: Stack(
- children: [
- Text(
- widget.text,
- style: TextStyles.textMMediumAuto.copyWith(color: appTheme.black),
- // style: {
- // "*": Style(
- // margin: Margins.all(0),
- // color: Colors.black87,
- // maxLines: isExpanded ? null : widget.maxLines,
- // textOverflow: TextOverflow.clip,
- // ),
- // },
- ),
- if (!isExpanded)
- Positioned.fill(
- child: Align(
- alignment: Alignment.bottomCenter,
- child: Container(
- height: 35,
- decoration: BoxDecoration(
- gradient: LinearGradient(
- begin: Alignment.topCenter,
- end: Alignment.bottomCenter,
- colors: [Colors.white.withValues(alpha: 0.0), Colors.white.withValues(alpha: 0.6), Colors.white],
+ child: AnimatedSize(
+ duration: const Duration(milliseconds: 200),
+ curve: Curves.easeInOut,
+ child: Stack(
+ children: [
+ Text(
+ widget.text,
+ key: _textKey,
+ style: TextStyles.textMMediumAuto.copyWith(color: appTheme.black),
+ maxLines: isExpanded ? null : widget.maxLines,
+ overflow: TextOverflow.clip,
+ ),
+ if (!isExpanded && showExpandButton)
+ Positioned.fill(
+ child: Align(
+ alignment: Alignment.bottomCenter,
+ child: Container(
+ height: 35,
+ decoration: BoxDecoration(
+ gradient: LinearGradient(
+ begin: Alignment.topCenter,
+ end: Alignment.bottomCenter,
+ colors: [
+ Colors.white.withAlpha(0),
+ Colors.white.withAlpha((255 * 0.6).toInt()),
+ Colors.white,
+ ],
+ ),
),
),
),
),
- ),
- ],
- ),
- ),
- Align(
- alignment: Alignment.bottomCenter,
- child: GestureDetector(
- onTap: toggleExpansion,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Text(isExpanded ? s.hide : s.expand, style: TextStyles.textMMedium.copyWith(color: appTheme.blueA400)),
- Transform.rotate(angle: isExpanded ? math.pi : 0, child: SvgPicture.asset('assets/icons/arrow_down.svg', width: 12, height: 12)),
],
),
),
),
+ if (showExpandButton)
+ Align(
+ alignment: Alignment.bottomCenter,
+ child: GestureDetector(
+ onTap: toggleExpansion,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Text(
+ isExpanded ? s.hide : s.expand,
+ style: TextStyles.textMMedium.copyWith(color: appTheme.blueA400),
+ ),
+ const SizedBox(width: 4),
+ Transform.rotate(
+ angle: isExpanded ? math.pi : 0,
+ child: SvgPicture.asset('assets/icons/arrow_down.svg', width: 12, height: 12),
+ ),
+ ],
+ ),
+ ),
+ ),
],
);
}
diff --git a/lib/features/profile/presentation/pages/profile_screen.dart b/lib/features/profile/presentation/pages/profile_screen.dart
index 359bd21a..7c94e537 100644
--- a/lib/features/profile/presentation/pages/profile_screen.dart
+++ b/lib/features/profile/presentation/pages/profile_screen.dart
@@ -216,7 +216,7 @@ class _ProfileScreenState extends State {
Scaffold _myProfileScreen(ProfileStateLoaded state) {
return Scaffold(
backgroundColor: Colors.grey.shade200,
- appBar: AppBar(toolbarHeight: 0),
+ appBar: AppBar(),
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
diff --git a/lib/features/recipe/presentation/pages/about_recipe_screen.dart b/lib/features/recipe/presentation/pages/about_recipe_screen.dart
index b9328ba3..8c6a5e8b 100644
--- a/lib/features/recipe/presentation/pages/about_recipe_screen.dart
+++ b/lib/features/recipe/presentation/pages/about_recipe_screen.dart
@@ -205,14 +205,14 @@ class _AboutRecipeScreenState extends State {
appBar: AppBar(
centerTitle: true,
leading: BackButton(
- onPressed: () {
- if (context.canPop()) {
- GoRouter.of(context).pop();
- return;
- }
- GoRouter.of(context).go('/feed-screen');
- },
- ),
+ onPressed: () {
+ if (context.canPop()) {
+ GoRouter.of(context).pop();
+ return;
+ }
+ GoRouter.of(context).go('/feed-screen');
+ },
+ ),
title: Text(
recipeState.recipe.title ?? '',
maxLines: 2,
@@ -356,6 +356,7 @@ class _AboutRecipeScreenState extends State {
),
),
),
+ const SizedBox(height: 12),
ExpandableText(text: recipeState.recipe.description),
const SizedBox(height: 20),
Padding(
@@ -400,14 +401,14 @@ class _AboutRecipeScreenState extends State {
appBar: AppBar(
centerTitle: true,
leading: BackButton(
- onPressed: () {
- if (context.canPop()) {
- GoRouter.of(context).pop();
- return;
- }
- GoRouter.of(context).go('/feed-screen');
- },
- ),
+ onPressed: () {
+ if (context.canPop()) {
+ GoRouter.of(context).pop();
+ return;
+ }
+ GoRouter.of(context).go('/feed-screen');
+ },
+ ),
title: Text(
'',
maxLines: 2,
diff --git a/lib/features/settings/presentation/pages/settings_screen.dart b/lib/features/settings/presentation/pages/settings_screen.dart
index c5c9dc99..67460955 100644
--- a/lib/features/settings/presentation/pages/settings_screen.dart
+++ b/lib/features/settings/presentation/pages/settings_screen.dart
@@ -164,12 +164,8 @@ class _SettingsScreenState extends State {
_divider(context),
_tile(
onTap: () => GoRouter.of(context).pushNamed(
- 'changePasswordScreen',
- extra: SettingsEntity(
- profileSettingsModel: state.profileSettings,
- profileDetailsModel: state.profileDetails,
- settingsCubit: settingsCubit,
- ),
+ 'forgetPasswordScreen',
+ extra: true,
),
title: 'Сменить пароль',
),
diff --git a/pubspec.yaml b/pubspec.yaml
index cdc5881d..d5c928e7 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
name: eatvio_app
description: A new Flutter project.
-version: 1.1.15+45
+version: 1.1.16+46
publish_to: 'none'
environment:
@@ -58,7 +58,7 @@ dependencies:
http: ^1.4.0
flutter_native_splash: ^2.4.6
webview_flutter: ^4.13.0
- sentry_flutter: ^9.2.0
+ sentry_flutter: ^8.14.2
connectivity_plus: ^6.1.4
visibility_detector: ^0.4.0+2
firebase_core: ^3.15.0
@@ -83,7 +83,7 @@ dev_dependencies:
flutter_test:
sdk: flutter
- flutter_lints: ^5.0.0
+ flutter_lints: ^6.0.0
flutter:
uses-material-design: true