Merge pull request 'fix(password+recipe): Issue-221 and Issue-418 and Issue-317' (#545) from mso7nueh/eatvio_app:main into main

Reviewed-on: eatvio/eatvio_app#545
This commit is contained in:
mso7nueh
2025-07-04 08:05:13 +00:00
8 changed files with 113 additions and 73 deletions

View File

@@ -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',

View File

@@ -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,

View File

@@ -141,7 +141,7 @@ class _AuthScreenState extends State<AuthScreen> {
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(

View File

@@ -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<ForgetPasswordScreen> createState() => _ForgetPasswordScreenState();
@@ -29,7 +30,7 @@ class _ForgetPasswordScreenState extends State<ForgetPasswordScreen> {
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<ForgetPasswordScreen> {
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<ForgetPasswordScreen> {
}
if (state is ResetPasswordStateResetPassowrdSuccess) {
GoRouter.of(context).pop();
showSuccessToast('Пароль успешно сменён. Войдите в аккаунт');
showSuccessToast('Пароль успешно сменён. ${widget.isAuth ? '' : 'Войдите в аккаунт'}');
}
},
),

View File

@@ -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<ExpandableText> createState() => _ExpandableTextState();
@@ -18,6 +22,29 @@ class ExpandableText extends StatefulWidget {
class _ExpandableTextState extends State<ExpandableText> {
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<ExpandableText> {
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),
),
],
),
),
),
],
);
}

View File

@@ -216,7 +216,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
Scaffold _myProfileScreen(ProfileStateLoaded state) {
return Scaffold(
backgroundColor: Colors.grey.shade200,
appBar: AppBar(toolbarHeight: 0),
appBar: AppBar(),
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,

View File

@@ -205,14 +205,14 @@ class _AboutRecipeScreenState extends State<AboutRecipeScreen> {
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<AboutRecipeScreen> {
),
),
),
const SizedBox(height: 12),
ExpandableText(text: recipeState.recipe.description),
const SizedBox(height: 20),
Padding(
@@ -400,14 +401,14 @@ class _AboutRecipeScreenState extends State<AboutRecipeScreen> {
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,

View File

@@ -164,12 +164,8 @@ class _SettingsScreenState extends State<SettingsScreen> {
_divider(context),
_tile(
onTap: () => GoRouter.of(context).pushNamed(
'changePasswordScreen',
extra: SettingsEntity(
profileSettingsModel: state.profileSettings,
profileDetailsModel: state.profileDetails,
settingsCubit: settingsCubit,
),
'forgetPasswordScreen',
extra: true,
),
title: 'Сменить пароль',
),