Compare commits

...

9 Commits

25 changed files with 226 additions and 255 deletions

View File

@@ -63,6 +63,18 @@
<data android:pathPattern="/ru/plan/.*" /> <data android:pathPattern="/ru/plan/.*" />
<data android:pathPattern="/en/plan/.*" /> <data android:pathPattern="/en/plan/.*" />
<data android:pathPattern="/ru/chat/.*" />
<data android:pathPattern="/en/chat/.*" />
<data android:pathPattern="/ru/chat" />
<data android:pathPattern="/en/chat" />
<data android:pathPattern="/ru/profile/.*" />
<data android:pathPattern="/en/profile/.*" />
<data android:pathPattern="/ru/diary/.*" />
<data android:pathPattern="/en/diary/.*" />
</intent-filter> </intent-filter>
</activity> </activity>
<!-- Don't delete the meta-data below. <!-- Don't delete the meta-data below.

View File

@@ -1,5 +1,7 @@
import 'package:eatvio_app/app_keys.dart'; import 'package:eatvio_app/app_keys.dart';
import 'package:eatvio_app/core/app_initializer.dart'; import 'package:eatvio_app/core/app_initializer.dart';
import 'package:eatvio_app/core/env_config.dart';
import 'package:eatvio_app/features/feed/presentation/pages/feed_screen.dart';
import 'package:eatvio_app/main.dart' as app; import 'package:eatvio_app/main.dart' as app;
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart'; import 'package:integration_test/integration_test.dart';
@@ -12,7 +14,7 @@ void main() {
await AppInitializer.initialize(buildType: AppBuildType.tests); await AppInitializer.initialize(buildType: AppBuildType.tests);
}); });
testWidgets('Signs in successfully with valid credentials', (WidgetTester tester) async { testWidgets('Signs in successfully with valid credentials', (WidgetTester tester) async {
await tester.pumpWidget(const app.MyApp()); await tester.pumpWidget(const app.MyApp());
await tester.pumpAndSettle(const Duration(seconds: 3)); await tester.pumpAndSettle(const Duration(seconds: 3));
await skipWelcomeScreen(tester); await skipWelcomeScreen(tester);
@@ -24,14 +26,14 @@ void main() {
expect(passwordFieldFinder, findsOneWidget, reason: 'Password text field should be found.'); expect(passwordFieldFinder, findsOneWidget, reason: 'Password text field should be found.');
expect(signInButtonFinder, findsOneWidget, reason: 'Sign In button should be found.'); expect(signInButtonFinder, findsOneWidget, reason: 'Sign In button should be found.');
await tester.enterText(emailFieldFinder, 'reshetnick.mike+user4@gmail.com'); await tester.enterText(emailFieldFinder, EnvConfig.testEmail);
await tester.enterText(passwordFieldFinder, '1234567890'); await tester.enterText(passwordFieldFinder, EnvConfig.testPassword);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
await tester.tap(signInButtonFinder); await tester.tap(signInButtonFinder);
await tester.pumpAndSettle(const Duration(seconds: 3)); await tester.pumpAndSettle(const Duration(seconds: 3));
expect(signInButtonFinder, findsNothing, reason: 'Sign-in button should not be visible after successful login and navigation.'); expect(FeedScreen, findsOne, reason: 'Feed screen should be visible after successful login and navigation.');
}); });
} }

View File

@@ -0,0 +1,21 @@
import 'package:eatvio_app/app_keys.dart';
import 'package:eatvio_app/core/env_config.dart';
import 'package:flutter_test/flutter_test.dart';
Future<void> skipSignIn(WidgetTester tester) async {
final emailFieldFinder = find.byKey(AppKeys.emailTextFieldAuthScreen);
final passwordFieldFinder = find.byKey(AppKeys.passwordTextFieldAuthScreen);
final signInButtonFinder = find.byKey(AppKeys.signInButtonAuthScreen);
expect(emailFieldFinder, findsOneWidget, reason: 'Email text field should be found.');
expect(passwordFieldFinder, findsOneWidget, reason: 'Password text field should be found.');
expect(signInButtonFinder, findsOneWidget, reason: 'Sign In button should be found.');
await tester.enterText(emailFieldFinder, EnvConfig.testEmail);
await tester.enterText(passwordFieldFinder, EnvConfig.testPassword);
await tester.pumpAndSettle();
await tester.tap(signInButtonFinder);
await tester.pumpAndSettle(const Duration(seconds: 3));
}

View File

@@ -5,4 +5,4 @@ Future<void> skipWelcomeScreen(WidgetTester tester) async {
final welcomeScreenButtonFinder = find.byKey(AppKeys.welcomeScreenButton); final welcomeScreenButtonFinder = find.byKey(AppKeys.welcomeScreenButton);
await tester.tap(welcomeScreenButtonFinder); await tester.tap(welcomeScreenButtonFinder);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
} }

View File

@@ -0,0 +1,31 @@
import 'package:eatvio_app/app_keys.dart';
import 'package:eatvio_app/core/app_initializer.dart';
import 'package:eatvio_app/main.dart' as app;
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../common_cases/skip_sign_in.dart';
import '../common_cases/skip_welcome_screen.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
setUpAll(() async {
await AppInitializer.initialize(buildType: AppBuildType.tests);
});
testWidgets('qwe', (WidgetTester tester) async {
await tester.pumpWidget(const app.MyApp());
await tester.pumpAndSettle(const Duration(seconds: 3));
await skipWelcomeScreen(tester);
await skipSignIn(tester);
final blogPostCreationFinder = find.byKey(AppKeys.feedScreenBlogPostCreationButton);
expect(blogPostCreationFinder, findsOneWidget, reason: 'Blog post creation button should be found.');
await tester.tap(blogPostCreationFinder);
await tester.pumpAndSettle();
});
}

View File

@@ -1,13 +1,22 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class AppKeys { class AppKeys {
// Auth Screen // Auth Screen
static const hiddenLogoButtonAuthScreen = ValueKey('hiddenLogoButtonAuthScreen'); static const hiddenLogoButtonAuthScreen = ValueKey('hiddenLogoButtonAuthScreen');
static const emailTextFieldAuthScreen = ValueKey('emailTextFieldAuthScreen'); static const emailTextFieldAuthScreen = ValueKey('emailTextFieldAuthScreen');
static const passwordTextFieldAuthScreen = ValueKey('passwordTextFieldAuthScreen'); static const passwordTextFieldAuthScreen = ValueKey('passwordTextFieldAuthScreen');
static const signInButtonAuthScreen = ValueKey('signInButtonAuthScreen'); static const signInButtonAuthScreen = ValueKey('signInButtonAuthScreen');
// Welcome Screen // Welcome Screen
static const welcomeScreenButton = ValueKey('welcomeScreenButton'); static const welcomeScreenButton = ValueKey('welcomeScreenButton');
// Feed Screen
static const feedScreenBlogPostCreationButton = ValueKey('feedScreenBlogPostCreationButton');
// BlogPostCreateScreen
static const blogPostCreateScreenTitleTextField = ValueKey('blogPostCreateScreenTitleTextField');
static const blogPostCreateScreenContentTextField = ValueKey('blogPostCreateScreenContentTextField');
static const blogPostCreateScreenVideoLinkTextField = ValueKey('blogPostCreateScreenVideoLinkTextField');
static const blogPostCreateScreenCreateButton = ValueKey('blogPostCreateScreenCreateButton');
static const imageWidget = ValueKey('imageWidget');
} }

View File

@@ -29,23 +29,45 @@ class AppRouter {
/// Обработка редиректов для deep links /// Обработка редиректов для deep links
static String? _handleRedirect(BuildContext context, GoRouterState state) { static String? _handleRedirect(BuildContext context, GoRouterState state) {
final segments = state.uri.pathSegments; final segments = state.uri.pathSegments;
if (segments.length >= 3) { if (segments.length == 4) {
final type = segments[1];
switch (type) {
case 'diary':
FlutterNativeSplash.remove();
return '/diary-screen';
}
}
if (segments.length == 3) {
final type = segments[1]; final type = segments[1];
final contentIdentifier = segments[2]; final contentIdentifier = segments[2];
switch (type) { switch (type) {
case 'recipe': case 'recipe':
FlutterNativeSplash.remove(); FlutterNativeSplash.remove();
return '${RouteConstants.aboutRecipesScreen}?slug=$contentIdentifier'; return '/about-recipes-screen?slug=$contentIdentifier';
case 'blog_post': case 'blog_post':
FlutterNativeSplash.remove(); FlutterNativeSplash.remove();
return '${RouteConstants.blogPostScreen}?id=$contentIdentifier'; return '/blog-post-screen?id=$contentIdentifier';
case 'plan': case 'plan':
FlutterNativeSplash.remove(); FlutterNativeSplash.remove();
return '${RouteConstants.aboutPlanScreen}?slug=$contentIdentifier'; return '/about-plan-screen?slug=$contentIdentifier';
case 'diet': case 'diet':
FlutterNativeSplash.remove(); FlutterNativeSplash.remove();
return '${RouteConstants.aboutDietScreen}?slug=$contentIdentifier'; return '/about-diet-screen?slug=$contentIdentifier';
case 'chat':
FlutterNativeSplash.remove();
return '/chat-select-screen';
case 'profile':
FlutterNativeSplash.remove();
return '/profile-screen?slug=$contentIdentifier';
}
}
if (segments.length == 2) {
final type = segments[1];
switch (type) {
case 'chat':
FlutterNativeSplash.remove();
return '/chat-select-screen';
} }
} }

View File

@@ -29,6 +29,7 @@ import 'package:eatvio_app/features/my_finance/presentation/pages/card_settings.
import 'package:eatvio_app/features/my_finance/presentation/pages/user_finance_screen.dart'; import 'package:eatvio_app/features/my_finance/presentation/pages/user_finance_screen.dart';
import 'package:eatvio_app/features/my_plans/presentation/my_plans_screen.dart'; import 'package:eatvio_app/features/my_plans/presentation/my_plans_screen.dart';
import 'package:eatvio_app/features/order_info/presentation/info_by_order_screen.dart'; import 'package:eatvio_app/features/order_info/presentation/info_by_order_screen.dart';
import 'package:eatvio_app/features/profile/models/profile_model.dart';
import 'package:eatvio_app/features/profile/presentation/pages/profile_screen.dart'; import 'package:eatvio_app/features/profile/presentation/pages/profile_screen.dart';
import 'package:eatvio_app/features/profile/presentation/pages/subs_screen.dart'; import 'package:eatvio_app/features/profile/presentation/pages/subs_screen.dart';
import 'package:eatvio_app/features/recipe/presentation/pages/my_recipes_screen.dart'; import 'package:eatvio_app/features/recipe/presentation/pages/my_recipes_screen.dart';
@@ -146,7 +147,13 @@ class OtherRoutes {
GoRoute( GoRoute(
path: RouteConstants.profileScreen, path: RouteConstants.profileScreen,
name: 'profileScreen', name: 'profileScreen',
builder: (context, state) => ProfileScreen(author: state.extra as Author), builder: (context, state) {
final slug = state.uri.queryParameters['slug'];
if (slug != null) {
return ProfileScreen(slug: slug);
}
return ProfileScreen(slug: state.extra as String);
},
), ),
GoRoute( GoRoute(
path: RouteConstants.subsScreen, path: RouteConstants.subsScreen,
@@ -168,7 +175,7 @@ class OtherRoutes {
GoRoute( GoRoute(
path: RouteConstants.emptyChatScreen, path: RouteConstants.emptyChatScreen,
name: 'emptyChatScreen', name: 'emptyChatScreen',
builder: (context, state) => EmptyChatScreen(author: state.extra as Author), builder: (context, state) => EmptyChatScreen(user: state.extra as ProfileModel),
), ),
// Consultant routes // Consultant routes

View File

@@ -198,7 +198,7 @@ class _BlogPostScreenState extends State<BlogPostScreen> {
child: Column( child: Column(
children: [ children: [
GestureDetector( GestureDetector(
onTap: () => GoRouter.of(context).pushNamed('profileScreen', extra: blogPostState.blogPostModel?.author), onTap: () => GoRouter.of(context).pushNamed('profileScreen', extra: blogPostState.blogPostModel?.author.authorSlug),
child: Ink( child: Ink(
padding: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row( child: Row(

View File

@@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:eatvio_app/app_keys.dart';
import 'package:eatvio_app/core/app_config.dart'; import 'package:eatvio_app/core/app_config.dart';
import 'package:eatvio_app/core/app_router.dart'; import 'package:eatvio_app/core/app_router.dart';
import 'package:eatvio_app/core/permission_handler/permission_handler.dart'; import 'package:eatvio_app/core/permission_handler/permission_handler.dart';
@@ -153,6 +154,7 @@ class _BlogPostCreateScreenState extends State<BlogPostCreateScreen> {
floatingActionButton: SizedBox( floatingActionButton: SizedBox(
width: MediaQuery.of(context).size.width - 32, width: MediaQuery.of(context).size.width - 32,
child: FloatingActionButton.extended( child: FloatingActionButton.extended(
key: AppKeys.blogPostCreateScreenCreateButton,
heroTag: 'createBlogPost', heroTag: 'createBlogPost',
highlightElevation: 0, highlightElevation: 0,
elevation: 0, elevation: 0,
@@ -225,12 +227,14 @@ class _BlogPostCreateScreenState extends State<BlogPostCreateScreen> {
const Text('Заголовок'), const Text('Заголовок'),
const SizedBox(height: 8), const SizedBox(height: 8),
CustomTextFormField( CustomTextFormField(
key: AppKeys.blogPostCreateScreenTitleTextField,
controller: titleController, controller: titleController,
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
const Text('Описание'), const Text('Описание'),
const SizedBox(height: 8), const SizedBox(height: 8),
CustomTextFormField( CustomTextFormField(
key: AppKeys.blogPostCreateScreenContentTextField,
controller: descriptionController, controller: descriptionController,
maxLines: 6, maxLines: 6,
minLines: 4, minLines: 4,
@@ -244,6 +248,7 @@ class _BlogPostCreateScreenState extends State<BlogPostCreateScreen> {
if (image == null && widget.feedBlogPostModel?.image == null) const SizedBox(height: 8), if (image == null && widget.feedBlogPostModel?.image == null) const SizedBox(height: 8),
if (image == null && widget.feedBlogPostModel?.image == null) if (image == null && widget.feedBlogPostModel?.image == null)
CustomTextFormField( CustomTextFormField(
key: AppKeys.blogPostCreateScreenVideoLinkTextField,
controller: videoUrlController, controller: videoUrlController,
), ),
const SizedBox(height: 80), const SizedBox(height: 80),

View File

@@ -18,7 +18,6 @@ import 'package:eatvio_app/features/menu/presentation/blocked_user_cubit/blocked
import 'package:eatvio_app/core/theme/custom_text_style.dart'; import 'package:eatvio_app/core/theme/custom_text_style.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:eatvio_app/features/chat/presentation/widgets/notification_banner.dart'; import 'package:eatvio_app/features/chat/presentation/widgets/notification_banner.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart'; import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
import 'package:eatvio_app/features/order_info/presentation/info_by_order_screen.dart'; import 'package:eatvio_app/features/order_info/presentation/info_by_order_screen.dart';
import 'package:eatvio_app/features/plans/enums/chosen_plan_state_enum.dart'; import 'package:eatvio_app/features/plans/enums/chosen_plan_state_enum.dart';
@@ -152,12 +151,7 @@ class _ChatScreenState extends State<ChatScreen> {
onTap: () { onTap: () {
GoRouter.of(context).pushNamed( GoRouter.of(context).pushNamed(
'profileScreen', 'profileScreen',
extra: Author( extra: state.chatRoom.users.receiver.slug,
authorSlug: state.chatRoom.users.receiver.slug,
authorName: state.chatRoom.users.receiver.name,
authorProfileIcon: state.chatRoom.users.receiver.profilePhotoUrl ?? '',
authorIsMe: false,
),
); );
}, },
child: Row( child: Row(

View File

@@ -6,7 +6,7 @@ import 'package:eatvio_app/core/locator_service.dart';
import 'package:eatvio_app/core/theme/custom_text_style.dart'; import 'package:eatvio_app/core/theme/custom_text_style.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:eatvio_app/features/chat/repositories/chat_repository.dart'; import 'package:eatvio_app/features/chat/repositories/chat_repository.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; import 'package:eatvio_app/features/profile/models/profile_model.dart';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -16,12 +16,9 @@ import 'package:eatvio_app/features/menu/presentation/blocked_user_cubit/blocked
import 'package:eatvio_app/features/menu/presentation/blocked_user_cubit/blocked_users_state.dart'; import 'package:eatvio_app/features/menu/presentation/blocked_user_cubit/blocked_users_state.dart';
class EmptyChatScreen extends StatefulWidget { class EmptyChatScreen extends StatefulWidget {
final Author author; final ProfileModel user;
const EmptyChatScreen({ const EmptyChatScreen({super.key, required this.user});
super.key,
required this.author,
});
@override @override
State<EmptyChatScreen> createState() => _EmptyChatScreenState(); State<EmptyChatScreen> createState() => _EmptyChatScreenState();
@@ -40,34 +37,19 @@ class _EmptyChatScreenState extends State<EmptyChatScreen> {
centerTitle: false, centerTitle: false,
title: GestureDetector( title: GestureDetector(
onTap: () { onTap: () {
GoRouter.of(context).pushNamed( GoRouter.of(context).pushNamed('profileScreen', extra: widget.user.slug);
'profileScreen',
extra: Author(
authorSlug: widget.author.authorSlug,
authorName: widget.author.authorName,
authorProfileIcon: widget.author.authorProfileIcon,
authorIsMe: false,
),
);
}, },
child: Row( child: Row(
children: [ children: [
CircleAvatar( CircleAvatar(
radius: 20, radius: 20,
foregroundImage: NetworkImage(widget.author.authorProfileIcon), foregroundImage: NetworkImage(widget.user.profilePhotoUrl),
backgroundImage: const AssetImage('assets/images/no_avatar.png'), backgroundImage: const AssetImage('assets/images/no_avatar.png'),
), ),
const SizedBox(width: 16), const SizedBox(width: 16),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [Text(widget.user.name, style: CustomTextStyles.titleSmallBold.copyWith(color: PrimaryColors().black))],
Text(
widget.author.authorName,
style: CustomTextStyles.titleSmallBold.copyWith(
color: PrimaryColors().black,
),
),
],
), ),
], ],
), ),
@@ -84,18 +66,14 @@ class _EmptyChatScreenState extends State<EmptyChatScreen> {
children: [ children: [
const SizedBox(width: 8), const SizedBox(width: 8),
InkWell( InkWell(
onTap: () => showImagePicker(widget.author.authorSlug), onTap: () => showImagePicker(widget.user.slug),
customBorder: const CircleBorder(), customBorder: const CircleBorder(),
child: Ink( child: Ink(
height: 40, height: 40,
width: 40, width: 40,
child: Transform.rotate( child: Transform.rotate(
angle: pi / 4, angle: pi / 4,
child: const Icon( child: const Icon(Icons.attach_file_rounded, size: 30, color: Color(0xFF858E99)),
Icons.attach_file_rounded,
size: 30,
color: Color(0xFF858E99),
),
), ),
), ),
), ),
@@ -117,8 +95,10 @@ class _EmptyChatScreenState extends State<EmptyChatScreen> {
hintText: 'Сообщение', hintText: 'Сообщение',
hintStyle: const TextStyle(fontSize: 14, fontWeight: FontWeight.w400, height: 1, color: Color(0xFFAEAEB2)), hintStyle: const TextStyle(fontSize: 14, fontWeight: FontWeight.w400, height: 1, color: Color(0xFFAEAEB2)),
filled: true, filled: true,
border: border: OutlineInputBorder(
OutlineInputBorder(borderRadius: BorderRadius.circular(100), borderSide: const BorderSide(color: Color(0xFFD1D1D6), width: 1)), borderRadius: BorderRadius.circular(100),
borderSide: const BorderSide(color: Color(0xFFD1D1D6), width: 1),
),
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(100), borderRadius: BorderRadius.circular(100),
borderSide: const BorderSide(color: Color(0xFFD1D1D6), width: 1), borderSide: const BorderSide(color: Color(0xFFD1D1D6), width: 1),
@@ -139,40 +119,29 @@ class _EmptyChatScreenState extends State<EmptyChatScreen> {
final blockedUsersCubit = sl<BlockedUsersCubit>(); final blockedUsersCubit = sl<BlockedUsersCubit>();
await blockedUsersCubit.getBlockedUsers(); await blockedUsersCubit.getBlockedUsers();
final blockedState = blockedUsersCubit.state; final blockedState = blockedUsersCubit.state;
if (blockedState is BlockedUsersStateLoaded) { if (blockedState is BlockedUsersStateLoaded) {
final isBlocked = blockedState.profilesList.any((profile) => profile.slug == widget.author.authorSlug); final isBlocked = blockedState.profilesList.any((profile) => profile.slug == widget.user.slug);
if (isBlocked) { if (isBlocked) {
if (context.mounted) { if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( const SnackBar(content: Text('Вы не можете отправить сообщение заблокированному пользователю'), backgroundColor: Colors.red),
content: Text('Вы не можете отправить сообщение заблокированному пользователю'),
backgroundColor: Colors.red,
),
); );
} }
return; return;
} }
} }
if (textEditingController.text.isNotEmpty) { if (textEditingController.text.isNotEmpty) {
await sl<ChatRepository>().sendMessage( await sl<ChatRepository>().sendMessage(data: textEditingController.text.trim(), slug: widget.user.slug);
data: textEditingController.text.trim(),
slug: widget.author.authorSlug,
);
if (mounted) { if (mounted) {
setState(() { setState(() {
textEditingController.clear(); textEditingController.clear();
}); });
} }
final chatIdOrError = await sl<ChatRepository>().getChatByUserSlug(widget.author.authorSlug); final chatIdOrError = await sl<ChatRepository>().getChatByUserSlug(widget.user.slug);
if (context.mounted) { if (context.mounted) {
AppRouter.navigatorKey.currentContext?.pushReplacementNamed( AppRouter.navigatorKey.currentContext?.pushReplacementNamed('chatScreen', extra: {'uuid': chatIdOrError});
'chatScreen',
extra: {
'uuid': chatIdOrError,
},
);
} }
} }
}, },
@@ -201,53 +170,36 @@ class _EmptyChatScreenState extends State<EmptyChatScreen> {
CupertinoActionSheetAction( CupertinoActionSheetAction(
onPressed: () async { onPressed: () async {
Navigator.of(context).pop(); Navigator.of(context).pop();
// Проверяем, заблокирован ли пользователь // Проверяем, заблокирован ли пользователь
final blockedUsersCubit = sl<BlockedUsersCubit>(); final blockedUsersCubit = sl<BlockedUsersCubit>();
await blockedUsersCubit.getBlockedUsers(); await blockedUsersCubit.getBlockedUsers();
final blockedState = blockedUsersCubit.state; final blockedState = blockedUsersCubit.state;
if (blockedState is BlockedUsersStateLoaded) { if (blockedState is BlockedUsersStateLoaded) {
final isBlocked = blockedState.profilesList.any((profile) => profile.slug == widget.author.authorSlug); final isBlocked = blockedState.profilesList.any((profile) => profile.slug == widget.user.slug);
if (isBlocked) { if (isBlocked) {
if (context.mounted) { if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( const SnackBar(content: Text('Вы не можете отправить сообщение заблокированному пользователю'), backgroundColor: Colors.red),
content: Text('Вы не можете отправить сообщение заблокированному пользователю'),
backgroundColor: Colors.red,
),
); );
} }
return; return;
} }
} }
final picker = ImagePicker(); final picker = ImagePicker();
List<XFile>? images = await picker.pickMultiImage(); List<XFile>? images = await picker.pickMultiImage();
if (images.isNotEmpty) { if (images.isNotEmpty) {
List<File> files = images.map((image) => File(image.path)).toList(); List<File> files = images.map((image) => File(image.path)).toList();
await sl<ChatRepository>().sendMessage( await sl<ChatRepository>().sendMessage(files: files, slug: widget.user.slug);
files: files, final chatIdOrError = await sl<ChatRepository>().getChatByUserSlug(widget.user.slug);
slug: widget.author.authorSlug,
);
final chatIdOrError = await sl<ChatRepository>().getChatByUserSlug(widget.author.authorSlug);
if (mounted) { if (mounted) {
AppRouter.navigatorKey.currentContext?.pushReplacementNamed( AppRouter.navigatorKey.currentContext?.pushReplacementNamed('chatScreen', extra: {'uuid': chatIdOrError});
'chatScreen',
extra: {
'uuid': chatIdOrError,
},
);
} }
} }
}, },
child: const Row( child: const Row(children: [Icon(Icons.photo_library_rounded), SizedBox(width: 8), Text('Галерея')]),
children: [
Icon(Icons.photo_library_rounded),
SizedBox(width: 8),
Text('Галерея'),
],
),
), ),
CupertinoActionSheetAction( CupertinoActionSheetAction(
onPressed: () async { onPressed: () async {
@@ -256,28 +208,14 @@ class _EmptyChatScreenState extends State<EmptyChatScreen> {
List<XFile>? images = await picker.pickMultiImage(); List<XFile>? images = await picker.pickMultiImage();
if (images.isNotEmpty) { if (images.isNotEmpty) {
List<File> files = images.map((image) => File(image.path)).toList(); List<File> files = images.map((image) => File(image.path)).toList();
await sl<ChatRepository>().sendMessage( await sl<ChatRepository>().sendMessage(files: files, slug: widget.user.slug);
files: files, final chatIdOrError = await sl<ChatRepository>().getChatByUserSlug(widget.user.slug);
slug: widget.author.authorSlug,
);
final chatIdOrError = await sl<ChatRepository>().getChatByUserSlug(widget.author.authorSlug);
if (mounted) { if (mounted) {
AppRouter.navigatorKey.currentContext?.pushReplacementNamed( AppRouter.navigatorKey.currentContext?.pushReplacementNamed('chatScreen', extra: {'uuid': chatIdOrError});
'chatScreen',
extra: {
'uuid': chatIdOrError,
},
);
} }
} }
}, },
child: const Row( child: const Row(children: [Icon(Icons.photo_camera), SizedBox(width: 8), Text('Фото')]),
children: [
Icon(Icons.photo_camera),
SizedBox(width: 8),
Text('Фото'),
],
),
), ),
CupertinoActionSheetAction( CupertinoActionSheetAction(
onPressed: () async { onPressed: () async {
@@ -308,35 +246,17 @@ class _EmptyChatScreenState extends State<EmptyChatScreen> {
); );
if (result != null) { if (result != null) {
List<File> files = result.paths.map((path) => File(path!)).toList(); List<File> files = result.paths.map((path) => File(path!)).toList();
await sl<ChatRepository>().sendMessage( await sl<ChatRepository>().sendMessage(files: files, slug: widget.user.slug);
files: files, final chatIdOrError = await sl<ChatRepository>().getChatByUserSlug(widget.user.slug);
slug: widget.author.authorSlug,
);
final chatIdOrError = await sl<ChatRepository>().getChatByUserSlug(widget.author.authorSlug);
if (mounted) { if (mounted) {
AppRouter.navigatorKey.currentContext?.pushReplacementNamed( AppRouter.navigatorKey.currentContext?.pushReplacementNamed('chatScreen', extra: {'uuid': chatIdOrError});
'chatScreen',
extra: {
'uuid': chatIdOrError,
},
);
} }
} }
}, },
child: const Row( child: const Row(children: [Icon(Icons.file_present_rounded), SizedBox(width: 8), Text('Файлы')]),
children: [
Icon(Icons.file_present_rounded),
SizedBox(width: 8),
Text('Файлы'),
],
),
), ),
], ],
cancelButton: CupertinoActionSheetAction( cancelButton: CupertinoActionSheetAction(onPressed: () => Navigator.of(context).pop(), isDestructiveAction: true, child: const Text('Отмена')),
onPressed: () => Navigator.of(context).pop(),
isDestructiveAction: true,
child: const Text('Отмена'),
),
), ),
); );
} }

View File

@@ -19,7 +19,7 @@ class AuthorCard extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
GoRouter.of(context).pushNamed('profileScreen', extra: author); GoRouter.of(context).pushNamed('profileScreen', extra: author.authorSlug);
}, },
child: Container( child: Container(
width: MediaQuery.sizeOf(context).width, width: MediaQuery.sizeOf(context).width,

View File

@@ -1,4 +1,5 @@
import 'package:easy_debounce/easy_debounce.dart'; import 'package:easy_debounce/easy_debounce.dart';
import 'package:eatvio_app/app_keys.dart';
import 'package:eatvio_app/core/const.dart'; import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/core/views/cubit/views_cubit.dart'; import 'package:eatvio_app/core/views/cubit/views_cubit.dart';
import 'package:eatvio_app/core/widgets/add_item_button.dart'; import 'package:eatvio_app/core/widgets/add_item_button.dart';
@@ -215,7 +216,7 @@ class _FeedScreenContentState extends State<FeedScreenContent> {
3 when !hidePlans => AddItemButton( 3 when !hidePlans => AddItemButton(
onTap: state.profile?.roles.contains('consultant') ?? false ? () => GoRouter.of(context).pushNamed(CreatePlanScreen.name) : null, onTap: state.profile?.roles.contains('consultant') ?? false ? () => GoRouter.of(context).pushNamed(CreatePlanScreen.name) : null,
), ),
_ => const AddItemButton(), _ => const AddItemButton(key: AppKeys.feedScreenBlogPostCreationButton),
}, },
], ],
), ),

View File

@@ -8,7 +8,6 @@ import 'package:eatvio_app/core/utils/date_time_utils.dart';
import 'package:eatvio_app/core/widgets/custom_popup.dart'; import 'package:eatvio_app/core/widgets/custom_popup.dart';
import 'package:eatvio_app/core/widgets/feed_icon_button.dart'; import 'package:eatvio_app/core/widgets/feed_icon_button.dart';
import 'package:eatvio_app/features/chat/presentation/pages/photo_view_screen.dart'; import 'package:eatvio_app/features/chat/presentation/pages/photo_view_screen.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_state.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_state.dart';
import 'package:eatvio_app/features/feed/presentation/widgets/subscribe_button_widget.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/subscribe_button_widget.dart';
@@ -60,14 +59,7 @@ class _BlogPostWidgetState extends State<BlogPostWidget> {
onTap: () { onTap: () {
GoRouter.of(context).pushNamed( GoRouter.of(context).pushNamed(
'profileScreen', 'profileScreen',
extra: Author( extra: state.feedBlogPostList[widget.index].author.authorSlug,
authorSlug: state.feedBlogPostList[widget.index].author.authorSlug,
authorName: state.feedBlogPostList[widget.index].author.authorName,
authorProfileIcon: state.feedBlogPostList[widget.index].author.authorProfileIcon.contains('https')
? state.feedBlogPostList[widget.index].author.authorProfileIcon
: sl<AppConfig>().baseUrl + state.feedBlogPostList[widget.index].author.authorProfileIcon,
authorIsMe: state.feedBlogPostList[widget.index].author.authorIsMe,
),
); );
}, },
child: CircleAvatar( child: CircleAvatar(

View File

@@ -8,7 +8,6 @@ import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/prof
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/profile_avatar_cubit/profile_avatar_state.dart'; import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/profile_avatar_cubit/profile_avatar_state.dart';
import 'package:eatvio_app/features/complaining/presentation/complaining_bottom_sheet.dart'; import 'package:eatvio_app/features/complaining/presentation/complaining_bottom_sheet.dart';
import 'package:eatvio_app/features/feed/models/comment_model.dart'; import 'package:eatvio_app/features/feed/models/comment_model.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:eatvio_app/core/comments/comments_cubit/comments_cubit.dart'; import 'package:eatvio_app/core/comments/comments_cubit/comments_cubit.dart';
import 'package:eatvio_app/generated/l10n.dart'; import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart';
@@ -96,12 +95,7 @@ class _CommentsWidgetState extends State<CommentsWidget> {
onTap: () { onTap: () {
GoRouter.of(context).pushNamed( GoRouter.of(context).pushNamed(
'profileScreen', 'profileScreen',
extra: Author( extra: comment.authorSlug,
authorSlug: comment.authorSlug,
authorName: comment.authorName,
authorProfileIcon: comment.authorProfileIcon.contains('https') ? comment.authorProfileIcon : sl<AppConfig>().baseUrl + comment.authorProfileIcon,
authorIsMe: isMe,
),
); );
}, },
child: CircleAvatar( child: CircleAvatar(

View File

@@ -2,9 +2,6 @@ import 'package:cached_network_image/cached_network_image.dart';
import 'package:eatvio_app/core/app_config.dart'; import 'package:eatvio_app/core/app_config.dart';
import 'package:eatvio_app/core/locator_service.dart'; import 'package:eatvio_app/core/locator_service.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:eatvio_app/core/theme/theme_helper.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/features/feed/models/diets_pagination_model.dart';
import 'package:eatvio_app/features/feed/models/feed_consultant_model.dart'; import 'package:eatvio_app/features/feed/models/feed_consultant_model.dart';
import 'package:eatvio_app/features/profile/models/badge_model.dart'; import 'package:eatvio_app/features/profile/models/badge_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -22,12 +19,7 @@ class ConsultantWidget extends StatelessWidget {
onTap: () { onTap: () {
GoRouter.of(context).pushNamed( GoRouter.of(context).pushNamed(
'profileScreen', 'profileScreen',
extra: Author( extra: consultant.slug,
authorSlug: consultant.slug,
authorName: consultant.name,
authorProfileIcon: consultant.photo,
authorIsMe: (sl<ProfileAvatarCubit>().state as ProfileAvatarStateLoaded).profile.slug == consultant.slug ? true : false,
),
); );
}, },
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),

View File

@@ -8,7 +8,6 @@ import 'package:eatvio_app/core/widgets/custom_popup.dart';
import 'package:eatvio_app/core/widgets/info_row.dart'; import 'package:eatvio_app/core/widgets/info_row.dart';
import 'package:eatvio_app/core/widgets/feed_icon_button.dart'; import 'package:eatvio_app/core/widgets/feed_icon_button.dart';
import 'package:eatvio_app/features/diets/presentation/widgets/info_bouble.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/info_bouble.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart'; import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
import 'package:eatvio_app/core/theme/custom_text_style.dart'; import 'package:eatvio_app/core/theme/custom_text_style.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart';
@@ -170,12 +169,7 @@ class _PlanWidgetState extends State<PlanWidget> {
onTap: () { onTap: () {
GoRouter.of(context).pushNamed( GoRouter.of(context).pushNamed(
'profileScreen', 'profileScreen',
extra: Author( extra: widget.plan.author.authorSlug,
authorSlug: widget.plan.author.authorSlug,
authorName: widget.plan.author.authorName,
authorProfileIcon: widget.plan.author.authorProfileIcon,
authorIsMe: widget.plan.author.authorIsMe,
),
); );
}, },
child: Padding( child: Padding(

View File

@@ -1,6 +1,5 @@
import 'package:eatvio_app/core/app_config.dart'; import 'package:eatvio_app/core/app_config.dart';
import 'package:eatvio_app/core/locator_service.dart'; import 'package:eatvio_app/core/locator_service.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:eatvio_app/features/menu/presentation/blocked_user_cubit/blocked_users_cubit.dart'; import 'package:eatvio_app/features/menu/presentation/blocked_user_cubit/blocked_users_cubit.dart';
import 'package:eatvio_app/features/profile/models/profile_model.dart'; import 'package:eatvio_app/features/profile/models/profile_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -21,13 +20,7 @@ class _BlockedUserWidgetState extends State<BlockedUserWidget> {
return InkWell( return InkWell(
onTap: () => GoRouter.of(context).pushNamed( onTap: () => GoRouter.of(context).pushNamed(
'profileScreen', 'profileScreen',
extra: Author( extra: widget.profile.slug,
authorSlug: widget.profile.slug,
authorName: widget.profile.name,
authorProfileIcon: widget.profile.profilePhotoUrl,
authorIsMe: false,
isEntitySubscribedByMe: false,
),
), ),
child: Ink( child: Ink(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),

View File

@@ -5,7 +5,6 @@ import 'package:eatvio_app/core/image_compressing/image_compress_utility.dart';
import 'package:eatvio_app/core/utils/toasts.dart'; import 'package:eatvio_app/core/utils/toasts.dart';
import 'package:eatvio_app/features/chat/repositories/chat_repository.dart'; import 'package:eatvio_app/features/chat/repositories/chat_repository.dart';
import 'package:eatvio_app/features/consultant/become_consultant/repositories/consultant_repository.dart'; import 'package:eatvio_app/features/consultant/become_consultant/repositories/consultant_repository.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart'; import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart';
import 'package:eatvio_app/features/profile/presentation/bloc/profile_cubit/profile_state.dart'; import 'package:eatvio_app/features/profile/presentation/bloc/profile_cubit/profile_state.dart';
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart'; import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
@@ -24,9 +23,11 @@ class ProfileCubit extends Cubit<ProfileState> {
emit(const ProfileState.loading()); emit(const ProfileState.loading());
try { try {
final profile = await profileRepository.getProfileBySlug(slug); final profile = await profileRepository.getProfileBySlug(slug);
final myProfile = await profileRepository.getMyProfile();
emit( emit(
ProfileState.loaded( ProfileState.loaded(
profile: profile, profile: profile,
isMyProfile: myProfile.slug == profile.slug,
profileDetails: await profileRepository.getProfileDetailsBySlug(slug), profileDetails: await profileRepository.getProfileDetailsBySlug(slug),
blogPosts: await profileRepository.getBlogPostsByAuthorSlug(slug: slug), blogPosts: await profileRepository.getBlogPostsByAuthorSlug(slug: slug),
consultantInfo: profile.roles.contains('consultant') ? await consultantRepository.getConsultantRequestStatus(slug) : null, consultantInfo: profile.roles.contains('consultant') ? await consultantRepository.getConsultantRequestStatus(slug) : null,
@@ -46,6 +47,7 @@ class ProfileCubit extends Cubit<ProfileState> {
emit( emit(
ProfileState.loaded( ProfileState.loaded(
profile: profile, profile: profile,
isMyProfile: true,
profileDetails: await profileRepository.getMyProfileDetails(), profileDetails: await profileRepository.getMyProfileDetails(),
blogPosts: await profileRepository.getBlogPostsByAuthorSlug(slug: profile.slug), blogPosts: await profileRepository.getBlogPostsByAuthorSlug(slug: profile.slug),
weightPoints: await profileRepository.getWeight(period: period), weightPoints: await profileRepository.getWeight(period: period),
@@ -74,6 +76,7 @@ class ProfileCubit extends Cubit<ProfileState> {
weightPoints: (state as ProfileStateLoaded).weightPoints, weightPoints: (state as ProfileStateLoaded).weightPoints,
circumferencePoints: (state as ProfileStateLoaded).circumferencePoints, circumferencePoints: (state as ProfileStateLoaded).circumferencePoints,
consultantInfo: (state as ProfileStateLoaded).consultantInfo, consultantInfo: (state as ProfileStateLoaded).consultantInfo,
isMyProfile: (state as ProfileStateLoaded).isMyProfile,
), ),
); );
} }
@@ -100,11 +103,12 @@ class ProfileCubit extends Cubit<ProfileState> {
} }
} }
Future<String?> getChatRoomIdBySlug({required Author author}) async { Future<String?> getChatRoomIdBySlug({required String slug}) async {
try { try {
final chatIdOrError = await chatRepository.getChatByUserSlug(author.authorSlug); final chatIdOrError = await chatRepository.getChatByUserSlug(slug);
final userProfile = await profileRepository.getProfileBySlug(slug);
if (chatIdOrError == '404') { if (chatIdOrError == '404') {
AppRouter.navigatorKey.currentContext?.pushNamed('emptyChatScreen', extra: author); AppRouter.navigatorKey.currentContext?.pushNamed('emptyChatScreen', extra: userProfile);
} else if (chatIdOrError == 'error') { } else if (chatIdOrError == 'error') {
showErrorToast('Ошибка создания чата'); showErrorToast('Ошибка создания чата');
} else { } else {

View File

@@ -14,9 +14,10 @@ abstract class ProfileState with _$ProfileState {
const factory ProfileState.loading() = ProfileStateLoading; const factory ProfileState.loading() = ProfileStateLoading;
const factory ProfileState.loaded({ const factory ProfileState.loaded({
required ProfileModel profile, required ProfileModel profile,
required ProfileDetailsModel profileDetails, required ProfileDetailsModel profileDetails,
required List<FeedBlogPostModel> blogPosts, required List<FeedBlogPostModel> blogPosts,
required bool isMyProfile,
List<WeightModel>? weightPoints, List<WeightModel>? weightPoints,
List<CircumferenceModel>? circumferencePoints, List<CircumferenceModel>? circumferencePoints,
ConsultationRequestModel? consultantInfo, ConsultationRequestModel? consultantInfo,

View File

@@ -13,7 +13,6 @@ import 'package:eatvio_app/core/widgets/loader.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_cubit.dart';
import 'package:eatvio_app/features/chat/presentation/pages/photo_view_screen.dart'; import 'package:eatvio_app/features/chat/presentation/pages/photo_view_screen.dart';
import 'package:eatvio_app/features/complaining/presentation/complaining_bottom_sheet.dart'; import 'package:eatvio_app/features/complaining/presentation/complaining_bottom_sheet.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:eatvio_app/features/feed/presentation/widgets/plan_widget.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/plan_widget.dart';
import 'package:eatvio_app/features/menu/presentation/blocked_user_cubit/blocked_users_cubit.dart'; import 'package:eatvio_app/features/menu/presentation/blocked_user_cubit/blocked_users_cubit.dart';
import 'package:eatvio_app/features/profile/models/circumference_model.dart'; import 'package:eatvio_app/features/profile/models/circumference_model.dart';
@@ -44,9 +43,9 @@ import 'package:share_plus/share_plus.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
class ProfileScreen extends StatefulWidget { class ProfileScreen extends StatefulWidget {
final Author? author; final String? slug;
const ProfileScreen({super.key, this.author}); const ProfileScreen({super.key, this.slug});
@override @override
State<ProfileScreen> createState() => _ProfileScreenState(); State<ProfileScreen> createState() => _ProfileScreenState();
@@ -71,7 +70,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
widget.author == null || widget.author!.authorIsMe ? profileCubit.getMyProfile() : profileCubit.getProfileBySlug(widget.author!.authorSlug); widget.slug == null ? profileCubit.getMyProfile() : profileCubit.getProfileBySlug(widget.slug!);
} }
@override @override
@@ -110,7 +109,6 @@ class _ProfileScreenState extends State<ProfileScreen> {
Text( Text(
'Пользователь ограничил доступ к своей странице', 'Пользователь ограничил доступ к своей странице',
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500, color: Colors.grey[600]), style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500, color: Colors.grey[600]),
), ),
], ],
@@ -120,15 +118,13 @@ class _ProfileScreenState extends State<ProfileScreen> {
); );
} }
return widget.author == null || widget.author!.authorIsMe ? _myProfileScreen(state) : _profileScreen(state); return state.isMyProfile ? _myProfileScreen(state) : _profileScreen(state);
} else if (state is ProfileStateError) { } else if (state is ProfileStateError) {
return Scaffold( return Scaffold(
appBar: AppBar(), appBar: AppBar(),
body: DataErrorWidget( body: DataErrorWidget(
onReload: () async { onReload: () async {
widget.author == null || widget.author!.authorIsMe widget.slug == null ? await profileCubit.getMyProfile() : await profileCubit.getProfileBySlug(widget.slug!);
? await profileCubit.getMyProfile()
: await profileCubit.getProfileBySlug(widget.author!.authorSlug);
}, },
), ),
); );
@@ -143,7 +139,17 @@ class _ProfileScreenState extends State<ProfileScreen> {
Scaffold _profileScreen(ProfileStateLoaded state) { Scaffold _profileScreen(ProfileStateLoaded state) {
return Scaffold( return Scaffold(
backgroundColor: Colors.grey.shade200, backgroundColor: Colors.grey.shade200,
appBar: AppBar(), appBar: AppBar(
leading: BackButton(
onPressed: () {
if (context.canPop()) {
GoRouter.of(context).pop();
return;
}
GoRouter.of(context).go('/feed-screen');
},
),
),
body: SingleChildScrollView( body: SingleChildScrollView(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@@ -246,7 +252,18 @@ class _ProfileScreenState extends State<ProfileScreen> {
Scaffold _myProfileScreen(ProfileStateLoaded state) { Scaffold _myProfileScreen(ProfileStateLoaded state) {
return Scaffold( return Scaffold(
backgroundColor: Colors.grey.shade200, backgroundColor: Colors.grey.shade200,
appBar: AppBar(toolbarHeight: widget.author == null ? 0 : null), appBar: AppBar(
toolbarHeight: widget.slug == null ? 0 : null,
leading: BackButton(
onPressed: () {
if (context.canPop()) {
GoRouter.of(context).pop();
return;
}
GoRouter.of(context).go('/feed-screen');
},
),
),
body: SingleChildScrollView( body: SingleChildScrollView(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@@ -440,7 +457,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
GoRouter.of(context).pushNamed('stepperBecomeConsultantScreen', extra: state.profile.slug); GoRouter.of(context).pushNamed('stepperBecomeConsultantScreen', extra: state.profile.slug);
}, },
child: Text( child: Text(
widget.author == null || widget.author!.authorIsMe ? 'Редактировать' : '', state.isMyProfile ? 'Редактировать' : '',
style: const TextStyle(color: Color(0xFF2F80ED), fontSize: 16, fontWeight: FontWeight.w500), style: const TextStyle(color: Color(0xFF2F80ED), fontSize: 16, fontWeight: FontWeight.w500),
), ),
), ),
@@ -518,7 +535,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
GoRouter.of(context).pushNamed('stepperBecomeConsultantScreen', extra: state.profile.slug); GoRouter.of(context).pushNamed('stepperBecomeConsultantScreen', extra: state.profile.slug);
}, },
child: Text( child: Text(
widget.author == null || widget.author!.authorIsMe ? 'Редактировать' : '', state.isMyProfile ? 'Редактировать' : '',
style: const TextStyle(color: Color(0xFF2F80ED), fontSize: 16, fontWeight: FontWeight.w500), style: const TextStyle(color: Color(0xFF2F80ED), fontSize: 16, fontWeight: FontWeight.w500),
), ),
), ),
@@ -832,7 +849,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
context.pushTransparentRoute(rootNavigator: true, PhotoViewScreen(imageUrls: [sl<AppConfig>().baseUrl + state.profile.profilePhotoUrl], index: 0)); context.pushTransparentRoute(rootNavigator: true, PhotoViewScreen(imageUrls: [sl<AppConfig>().baseUrl + state.profile.profilePhotoUrl], index: 0));
}, },
), ),
if (widget.author == null || widget.author!.authorIsMe) ...[ if (state.isMyProfile) ...[
_buildDivider(), _buildDivider(),
_buildCompactItem( _buildCompactItem(
icon: 'assets/icons/edit_paint.svg', icon: 'assets/icons/edit_paint.svg',
@@ -990,7 +1007,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
); );
}, },
), ),
if (widget.author != null) ...[ if (!state.isMyProfile) ...[
_buildDivider(), _buildDivider(),
_buildCompactItem( _buildCompactItem(
icon: 'assets/icons/complain.svg', icon: 'assets/icons/complain.svg',
@@ -999,12 +1016,12 @@ class _ProfileScreenState extends State<ProfileScreen> {
showModalBottomSheet( showModalBottomSheet(
context: context, context: context,
isScrollControlled: true, isScrollControlled: true,
builder: (context) => ComplainingBottomSheet(complainedContentType: ComplainedContent.profile, slug: widget.author?.authorSlug), builder: (context) => ComplainingBottomSheet(complainedContentType: ComplainedContent.profile, slug: widget.slug),
); );
}, },
), ),
], ],
if (widget.author != null && !state.profile.isBlockedByMe) ...[ if (!state.isMyProfile && !state.profile.isBlockedByMe) ...[
_buildDivider(), _buildDivider(),
_buildCompactItem( _buildCompactItem(
icon: 'assets/icons/complain.svg', icon: 'assets/icons/complain.svg',
@@ -1012,7 +1029,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
onTap: () { onTap: () {
isFirstFetch = true; isFirstFetch = true;
sl<BlockedUsersCubit>().blockUser(state.profile.slug); sl<BlockedUsersCubit>().blockUser(state.profile.slug);
widget.author == null || widget.author!.authorIsMe ? profileCubit.getMyProfile() : profileCubit.getProfileBySlug(widget.author!.authorSlug); state.isMyProfile ? profileCubit.getMyProfile() : profileCubit.getProfileBySlug(state.profile.slug);
if (state.profile.roles.contains('consultant')) { if (state.profile.roles.contains('consultant')) {
plansCubit.getPlans(state.profile.slug); plansCubit.getPlans(state.profile.slug);
} }
@@ -1020,7 +1037,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
}, },
), ),
], ],
if (widget.author != null && state.profile.isBlockedByMe) ...[ if (!state.isMyProfile && state.profile.isBlockedByMe) ...[
_buildDivider(), _buildDivider(),
_buildCompactItem( _buildCompactItem(
icon: 'assets/icons/complain.svg', icon: 'assets/icons/complain.svg',
@@ -1028,7 +1045,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
onTap: () { onTap: () {
isFirstFetch = true; isFirstFetch = true;
sl<BlockedUsersCubit>().unblockUser(state.profile.slug); sl<BlockedUsersCubit>().unblockUser(state.profile.slug);
widget.author == null || widget.author!.authorIsMe ? profileCubit.getMyProfile() : profileCubit.getProfileBySlug(widget.author!.authorSlug); state.isMyProfile ? profileCubit.getMyProfile() : profileCubit.getProfileBySlug(state.profile.slug);
if (state.profile.roles.contains('consultant')) { if (state.profile.roles.contains('consultant')) {
plansCubit.getPlans(state.profile.slug); plansCubit.getPlans(state.profile.slug);
} }
@@ -1091,7 +1108,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
children: [ children: [
const SizedBox(width: 16), const SizedBox(width: 16),
GestureDetector( GestureDetector(
onTap: () async => await profileCubit.getChatRoomIdBySlug(author: widget.author!), onTap: () async => await profileCubit.getChatRoomIdBySlug(slug: widget.slug!),
child: Container( child: Container(
alignment: Alignment.center, alignment: Alignment.center,
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),

View File

@@ -1,6 +1,5 @@
import 'package:eatvio_app/core/locator_service.dart'; import 'package:eatvio_app/core/locator_service.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:eatvio_app/features/profile/presentation/bloc/profile_cubit/profile_cubit.dart'; import 'package:eatvio_app/features/profile/presentation/bloc/profile_cubit/profile_cubit.dart';
import 'package:eatvio_app/features/profile/presentation/bloc/sub_cubit/sub_cubit.dart'; import 'package:eatvio_app/features/profile/presentation/bloc/sub_cubit/sub_cubit.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -15,13 +14,7 @@ class SubActionButtonWidget extends StatefulWidget {
final String name; final String name;
final String porfileIcon; final String porfileIcon;
const SubActionButtonWidget({ const SubActionButtonWidget({super.key, required this.subActionType, required this.slug, required this.name, required this.porfileIcon});
super.key,
required this.subActionType,
required this.slug,
required this.name,
required this.porfileIcon,
});
@override @override
State<SubActionButtonWidget> createState() => _SubActionButtonWidgetState(); State<SubActionButtonWidget> createState() => _SubActionButtonWidgetState();
@@ -49,51 +42,25 @@ class _SubActionButtonWidgetState extends State<SubActionButtonWidget> {
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
child: Ink( child: Ink(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
decoration: BoxDecoration( decoration: BoxDecoration(borderRadius: BorderRadius.circular(8), color: appTheme.blueA400),
borderRadius: BorderRadius.circular(8),
color: appTheme.blueA400,
),
child: const Text( child: const Text(
'Подписаться', 'Подписаться',
style: TextStyle( style: TextStyle(fontSize: 13, fontWeight: FontWeight.w500, color: Colors.white),
fontSize: 13,
fontWeight: FontWeight.w500,
color: Colors.white,
),
), ),
), ),
); );
} else { } else {
return InkWell( return InkWell(
onTap: () async { onTap: () async {
GoRouter.of(context).pushNamed( GoRouter.of(context).pushNamed('chatScreen', extra: {'uuid': await sl<ProfileCubit>().getChatRoomIdBySlug(slug: widget.slug)});
'chatScreen',
extra: {
'uuid': await sl<ProfileCubit>().getChatRoomIdBySlug(
author: Author(
authorSlug: widget.slug,
authorName: widget.name,
authorProfileIcon: widget.porfileIcon,
authorIsMe: false,
),
),
},
);
}, },
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
child: Ink( child: Ink(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
decoration: BoxDecoration( decoration: BoxDecoration(borderRadius: BorderRadius.circular(8), color: const Color(0xFFF1F2F6)),
borderRadius: BorderRadius.circular(8),
color: const Color(0xFFF1F2F6),
),
child: const Text( child: const Text(
'Сообщение', 'Сообщение',
style: TextStyle( style: TextStyle(fontSize: 13, fontWeight: FontWeight.w500, color: Color(0xFF6D6F71)),
fontSize: 13,
fontWeight: FontWeight.w500,
color: Color(0xFF6D6F71),
),
), ),
), ),
); );

View File

@@ -1,6 +1,5 @@
import 'package:eatvio_app/core/app_config.dart'; import 'package:eatvio_app/core/app_config.dart';
import 'package:eatvio_app/core/locator_service.dart'; import 'package:eatvio_app/core/locator_service.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:eatvio_app/features/profile/models/sub_model.dart'; import 'package:eatvio_app/features/profile/models/sub_model.dart';
import 'package:eatvio_app/features/profile/presentation/widgets/sub_action_button_widget.dart'; import 'package:eatvio_app/features/profile/presentation/widgets/sub_action_button_widget.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -24,13 +23,7 @@ class _SubWidgetState extends State<SubWidget> {
return InkWell( return InkWell(
onTap: () => GoRouter.of(context).pushNamed( onTap: () => GoRouter.of(context).pushNamed(
'profileScreen', 'profileScreen',
extra: Author( extra: widget.subModel.slug,
authorSlug: widget.subModel.slug,
authorName: widget.subModel.name,
authorProfileIcon: widget.subModel.profilePhotoUrl,
authorIsMe: false,
isEntitySubscribedByMe: false,
),
), ),
child: Ink( child: Ink(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),