Merge pull request 'build 40' (#549) from main into test-flight

Reviewed-on: eatvio/eatvio_app#549
This commit is contained in:
mso7nueh
2025-07-07 13:03:13 +00:00
11 changed files with 191 additions and 82 deletions

View File

@@ -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 = (

View File

@@ -21,7 +21,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>38</string>
<string>39</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSRequiresIPhoneOS</key>

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(
@@ -258,8 +258,77 @@ class _AuthScreenState extends State<AuthScreen> {
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()

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: 'Сменить пароль',
),

View File

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