forked from eatvio/eatvio_app
merge upstream
This commit is contained in:
@@ -3,7 +3,7 @@ name: Eatvio App Android Test
|
|||||||
on: [ pull_request ]
|
on: [ pull_request ]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
flutter_version: "3.32.0"
|
flutter_version: "3.32.5"
|
||||||
java_version: "21.x"
|
java_version: "21.x"
|
||||||
flutter_channel: "stable"
|
flutter_channel: "stable"
|
||||||
my_local_cache_dir: "/opt/hostedtoolcache/"
|
my_local_cache_dir: "/opt/hostedtoolcache/"
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ if (keystorePropertiesFile.exists()) {
|
|||||||
android {
|
android {
|
||||||
namespace = "com.eatvioapp.app"
|
namespace = "com.eatvioapp.app"
|
||||||
compileSdk = flutter.compileSdkVersion
|
compileSdk = flutter.compileSdkVersion
|
||||||
ndkVersion = "27.0.12077973"
|
ndkVersion = "27.0.12077973"
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility = JavaVersion.VERSION_21
|
sourceCompatibility = JavaVersion.VERSION_21
|
||||||
|
|||||||
29
assets/icons/blocked_users.svg
Normal file
29
assets/icons/blocked_users.svg
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="19.633818mm"
|
||||||
|
height="19.633816mm"
|
||||||
|
viewBox="0 0 19.633818 19.633816"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs1" />
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-64.066064,-72.435122)">
|
||||||
|
<g
|
||||||
|
id="g2">
|
||||||
|
<path
|
||||||
|
id="path1"
|
||||||
|
style="fill-opacity:0;stroke:#2f80ed;stroke-width:1.065"
|
||||||
|
d="m 83.167381,82.252022 a 9.2844086,9.2844086 0 0 1 -9.284408,9.284408 9.2844086,9.2844086 0 0 1 -9.284409,-9.284408 9.2844086,9.2844086 0 0 1 9.284409,-9.284409 9.2844086,9.2844086 0 0 1 9.284408,9.284409 z" />
|
||||||
|
<path
|
||||||
|
style="fill:#000000;fill-opacity:0;stroke:#2f80ed;stroke-width:1.065;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 68.517124,89.22945 79.520546,75.54452"
|
||||||
|
id="path2" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 986 B |
@@ -388,7 +388,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)";
|
CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)";
|
||||||
CODE_SIGN_STYLE = Manual;
|
CODE_SIGN_STYLE = Manual;
|
||||||
CURRENT_PROJECT_VERSION = 36;
|
CURRENT_PROJECT_VERSION = 37;
|
||||||
DEVELOPMENT_TEAM = VL68C36HYS;
|
DEVELOPMENT_TEAM = VL68C36HYS;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
@@ -538,7 +538,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)";
|
CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)";
|
||||||
CODE_SIGN_STYLE = Manual;
|
CODE_SIGN_STYLE = Manual;
|
||||||
CURRENT_PROJECT_VERSION = 36;
|
CURRENT_PROJECT_VERSION = 37;
|
||||||
DEVELOPMENT_TEAM = VL68C36HYS;
|
DEVELOPMENT_TEAM = VL68C36HYS;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
@@ -576,7 +576,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)";
|
CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)";
|
||||||
CODE_SIGN_STYLE = Manual;
|
CODE_SIGN_STYLE = Manual;
|
||||||
CURRENT_PROJECT_VERSION = 36;
|
CURRENT_PROJECT_VERSION = 37;
|
||||||
DEVELOPMENT_TEAM = VL68C36HYS;
|
DEVELOPMENT_TEAM = VL68C36HYS;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>36</string>
|
<string>37</string>
|
||||||
<key>ITSAppUsesNonExemptEncryption</key>
|
<key>ITSAppUsesNonExemptEncryption</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import 'package:eatvio_app/features/consultant/become_consultant/presentation/pa
|
|||||||
import 'package:eatvio_app/features/consultations/presentation/pages/consultations_screen.dart';
|
import 'package:eatvio_app/features/consultations/presentation/pages/consultations_screen.dart';
|
||||||
import 'package:eatvio_app/features/finances_and_consultations_archive/presentation/consultant_finances_screen.dart';
|
import 'package:eatvio_app/features/finances_and_consultations_archive/presentation/consultant_finances_screen.dart';
|
||||||
import 'package:eatvio_app/features/finances_and_consultations_archive/presentation/user_purchases_screen.dart';
|
import 'package:eatvio_app/features/finances_and_consultations_archive/presentation/user_purchases_screen.dart';
|
||||||
|
import 'package:eatvio_app/features/menu/presentation/pages/blocked_users_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/create_diet/presentation/create_diet_screen.dart';
|
import 'package:eatvio_app/features/create_diet/presentation/create_diet_screen.dart';
|
||||||
import 'package:eatvio_app/features/create_diet/presentation/diet_preview_screen.dart';
|
import 'package:eatvio_app/features/create_diet/presentation/diet_preview_screen.dart';
|
||||||
@@ -169,6 +170,11 @@ class AppRouter {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
GoRoute(
|
||||||
|
name: 'blockedUsersScreen',
|
||||||
|
path: '/blocked-users-screen',
|
||||||
|
builder: (context, state) => const BlockedUsersScreen(),
|
||||||
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/welcome-screen',
|
path: '/welcome-screen',
|
||||||
name: 'welcomeScreen',
|
name: 'welcomeScreen',
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ import 'package:eatvio_app/features/blog_post_create/services/blog_post_service.
|
|||||||
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/new_messages_cubit/new_messages_cubit.dart';
|
||||||
import 'package:eatvio_app/features/finances_and_consultations_archive/cubit/consultant_finances/consultant_finances_cubit.dart';
|
import 'package:eatvio_app/features/finances_and_consultations_archive/cubit/consultant_finances/consultant_finances_cubit.dart';
|
||||||
import 'package:eatvio_app/features/finances_and_consultations_archive/cubit/user_purchases/user_purchases_cubit.dart';
|
import 'package:eatvio_app/features/finances_and_consultations_archive/cubit/user_purchases/user_purchases_cubit.dart';
|
||||||
|
import 'package:eatvio_app/features/menu/presentation/blocked_user_cubit/blocked_users_cubit.dart';
|
||||||
|
import 'package:eatvio_app/features/menu/presentation/repositories/blocked_users_repository.dart';
|
||||||
|
import 'package:eatvio_app/features/menu/services/blocked_users_service.dart';
|
||||||
import 'package:eatvio_app/features/notifications/presentation/notifications_cubit/notifications_cubit.dart';
|
import 'package:eatvio_app/features/notifications/presentation/notifications_cubit/notifications_cubit.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/calendar/presentation/bloc/calendar_cubit.dart';
|
import 'package:eatvio_app/features/calendar/presentation/bloc/calendar_cubit.dart';
|
||||||
@@ -162,6 +165,7 @@ Future<void> init() async {
|
|||||||
sl.registerFactory<ConsultantFinancesCubit>(() => ConsultantFinancesCubit(consultationsRepository: sl()));
|
sl.registerFactory<ConsultantFinancesCubit>(() => ConsultantFinancesCubit(consultationsRepository: sl()));
|
||||||
sl.registerFactory<UserPurchasesCubit>(() => UserPurchasesCubit(consultationsRepository: sl()));
|
sl.registerFactory<UserPurchasesCubit>(() => UserPurchasesCubit(consultationsRepository: sl()));
|
||||||
sl.registerFactory<ResetPasswordCubit>(() => ResetPasswordCubit(resetPasswordRepository: sl()));
|
sl.registerFactory<ResetPasswordCubit>(() => ResetPasswordCubit(resetPasswordRepository: sl()));
|
||||||
|
sl.registerFactory<BlockedUsersCubit>(() => BlockedUsersCubit(blockedUsersRepository: sl()));
|
||||||
|
|
||||||
// Repository
|
// Repository
|
||||||
sl.registerLazySingleton<ChatRepository>(() => ChatRepository(chatService: sl()));
|
sl.registerLazySingleton<ChatRepository>(() => ChatRepository(chatService: sl()));
|
||||||
@@ -191,6 +195,7 @@ Future<void> init() async {
|
|||||||
sl.registerLazySingleton<NotificationsRepository>(() => NotificationsRepository(notificationsService: sl()));
|
sl.registerLazySingleton<NotificationsRepository>(() => NotificationsRepository(notificationsService: sl()));
|
||||||
sl.registerFactory<MyRecipesRepository>(() => MyRecipesRepository(myRecipesService: sl()));
|
sl.registerFactory<MyRecipesRepository>(() => MyRecipesRepository(myRecipesService: sl()));
|
||||||
sl.registerFactory<ResetPasswordRepository>(() => ResetPasswordRepository(resetPasswordService: sl()));
|
sl.registerFactory<ResetPasswordRepository>(() => ResetPasswordRepository(resetPasswordService: sl()));
|
||||||
|
sl.registerLazySingleton<BlockedUsersRepository>(() => BlockedUsersRepository(blockedUserService: sl()));
|
||||||
|
|
||||||
// Services
|
// Services
|
||||||
sl.registerLazySingleton<ChatService>(() => ChatService(sl()));
|
sl.registerLazySingleton<ChatService>(() => ChatService(sl()));
|
||||||
@@ -222,6 +227,7 @@ Future<void> init() async {
|
|||||||
sl.registerLazySingleton<MyRecipesService>(() => MyRecipesService(sl()));
|
sl.registerLazySingleton<MyRecipesService>(() => MyRecipesService(sl()));
|
||||||
sl.registerLazySingleton<FirebaseApi>(() => FirebaseApi());
|
sl.registerLazySingleton<FirebaseApi>(() => FirebaseApi());
|
||||||
sl.registerLazySingleton<ResetPasswordService>(() => ResetPasswordService(sl()));
|
sl.registerLazySingleton<ResetPasswordService>(() => ResetPasswordService(sl()));
|
||||||
|
sl.registerLazySingleton<BlockedUserService>(() => BlockedUserService(sl()));
|
||||||
|
|
||||||
// External
|
// External
|
||||||
sl.registerLazySingleton(
|
sl.registerLazySingleton(
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart';
|
|||||||
import 'package:eatvio_app/features/feed/models/recipes_model.dart';
|
import 'package:eatvio_app/features/feed/models/recipes_model.dart';
|
||||||
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart';
|
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart';
|
||||||
import 'package:eatvio_app/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart';
|
import 'package:eatvio_app/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart';
|
||||||
|
import 'package:eatvio_app/features/menu/presentation/blocked_user_cubit/blocked_users_cubit.dart';
|
||||||
import 'package:eatvio_app/features/my_plans/presentation/cubit/my_plans_cubit.dart';
|
import 'package:eatvio_app/features/my_plans/presentation/cubit/my_plans_cubit.dart';
|
||||||
import 'package:eatvio_app/generated/l10n.dart';
|
import 'package:eatvio_app/generated/l10n.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -28,6 +29,7 @@ class CustomPopup extends StatelessWidget {
|
|||||||
final FeedBlogPostModel? feedBlogPostModel;
|
final FeedBlogPostModel? feedBlogPostModel;
|
||||||
final Recipe? recipe;
|
final Recipe? recipe;
|
||||||
final Diet? diet;
|
final Diet? diet;
|
||||||
|
final String userSlug;
|
||||||
|
|
||||||
const CustomPopup({
|
const CustomPopup({
|
||||||
super.key,
|
super.key,
|
||||||
@@ -39,6 +41,7 @@ class CustomPopup extends StatelessWidget {
|
|||||||
this.feedBlogPostModel,
|
this.feedBlogPostModel,
|
||||||
this.recipe,
|
this.recipe,
|
||||||
this.diet,
|
this.diet,
|
||||||
|
required this.userSlug
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -164,6 +167,13 @@ class CustomPopup extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
addItem(
|
||||||
|
'assets/icons/complain.svg',
|
||||||
|
'Заблокировать автора',
|
||||||
|
() {
|
||||||
|
sl<BlockedUsersCubit>().blockUser(userSlug);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entries.isNotEmpty && entries.last is PopupMenuItem) {
|
if (entries.isNotEmpty && entries.last is PopupMenuItem) {
|
||||||
|
|||||||
@@ -166,6 +166,7 @@ class _BlogPostScreenState extends State<BlogPostScreen> {
|
|||||||
path: 'blog_post/${(widget.blogPost.id)}',
|
path: 'blog_post/${(widget.blogPost.id)}',
|
||||||
id: widget.blogPost.id,
|
id: widget.blogPost.id,
|
||||||
feedBlogPostModel: widget.blogPost,
|
feedBlogPostModel: widget.blogPost,
|
||||||
|
userSlug: widget.blogPost.author.authorSlug,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 16),
|
const SizedBox(width: 16),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -194,6 +194,7 @@ class _DietPreviewScreenState extends State<DietPreviewScreen> {
|
|||||||
isAuthor: widget.diet.author.authorIsMe,
|
isAuthor: widget.diet.author.authorIsMe,
|
||||||
path: 'diet/${widget.diet.slug}',
|
path: 'diet/${widget.diet.slug}',
|
||||||
complainedContentType: ComplainedContent.diet,
|
complainedContentType: ComplainedContent.diet,
|
||||||
|
userSlug: widget.diet.author.authorSlug,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 16),
|
const SizedBox(width: 16),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -322,6 +322,7 @@ class _AboutDietScreenState extends State<AboutDietScreen> {
|
|||||||
complainedContentType: ComplainedContent.diet,
|
complainedContentType: ComplainedContent.diet,
|
||||||
id: widget.diet.id,
|
id: widget.diet.id,
|
||||||
diet: widget.diet,
|
diet: widget.diet,
|
||||||
|
userSlug: widget.diet.author.authorSlug,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 16),
|
const SizedBox(width: 16),
|
||||||
],
|
],
|
||||||
@@ -503,6 +504,7 @@ class _AboutDietScreenState extends State<AboutDietScreen> {
|
|||||||
complainedContentType: ComplainedContent.diet,
|
complainedContentType: ComplainedContent.diet,
|
||||||
id: widget.diet.id,
|
id: widget.diet.id,
|
||||||
diet: widget.diet,
|
diet: widget.diet,
|
||||||
|
userSlug: widget.diet.author.authorSlug,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 16),
|
const SizedBox(width: 16),
|
||||||
],
|
],
|
||||||
@@ -530,6 +532,7 @@ class _AboutDietScreenState extends State<AboutDietScreen> {
|
|||||||
complainedContentType: ComplainedContent.diet,
|
complainedContentType: ComplainedContent.diet,
|
||||||
id: widget.diet.id,
|
id: widget.diet.id,
|
||||||
diet: widget.diet,
|
diet: widget.diet,
|
||||||
|
userSlug: widget.diet.author.authorSlug,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 16),
|
const SizedBox(width: 16),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -130,6 +130,7 @@ class _BlogPostWidgetState extends State<BlogPostWidget> {
|
|||||||
path: 'blog_post/${(state.feedBlogPostList[widget.index].id)}',
|
path: 'blog_post/${(state.feedBlogPostList[widget.index].id)}',
|
||||||
id: state.feedBlogPostList[widget.index].id,
|
id: state.feedBlogPostList[widget.index].id,
|
||||||
feedBlogPostModel: state.feedBlogPostList[widget.index],
|
feedBlogPostModel: state.feedBlogPostList[widget.index],
|
||||||
|
userSlug: state.feedBlogPostList[widget.index].author.authorSlug,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ class _DietsWidgetState extends State<DietsWidget> {
|
|||||||
id: widget.diet.id,
|
id: widget.diet.id,
|
||||||
complainedContentType: ComplainedContent.diet,
|
complainedContentType: ComplainedContent.diet,
|
||||||
diet: widget.diet,
|
diet: widget.diet,
|
||||||
|
userSlug: widget.diet.author.authorSlug,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ class _PlanWidgetState extends State<PlanWidget> {
|
|||||||
id: widget.plan.id,
|
id: widget.plan.id,
|
||||||
slug: widget.plan.slug,
|
slug: widget.plan.slug,
|
||||||
complainedContentType: ComplainedContent.plan,
|
complainedContentType: ComplainedContent.plan,
|
||||||
|
userSlug: widget.plan.author.authorSlug,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ class _RecipesWidgetState extends State<RecipesWidget> {
|
|||||||
slug: widget.recipe.slug,
|
slug: widget.recipe.slug,
|
||||||
complainedContentType: ComplainedContent.recipe,
|
complainedContentType: ComplainedContent.recipe,
|
||||||
recipe: widget.recipe,
|
recipe: widget.recipe,
|
||||||
|
userSlug: widget.recipe.author.authorSlug,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
14
lib/features/menu/models/blocked_users_model.dart
Normal file
14
lib/features/menu/models/blocked_users_model.dart
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import 'package:eatvio_app/features/profile/models/profile_model.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'blocked_users_model.g.dart';
|
||||||
|
part 'blocked_users_model.freezed.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class BlockedUsersModel with _$BlockedUsersModel {
|
||||||
|
const factory BlockedUsersModel({
|
||||||
|
@JsonKey(name: 'data') required List<ProfileModel> profilesList,
|
||||||
|
}) = _BlockedUsersModel;
|
||||||
|
|
||||||
|
factory BlockedUsersModel.fromJson(Map<String, Object?> json) => _$BlockedUsersModelFromJson(json);
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import 'package:eatvio_app/features/menu/presentation/blocked_user_cubit/blocked_users_state.dart';
|
||||||
|
import 'package:eatvio_app/features/menu/presentation/repositories/blocked_users_repository.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
|
class BlockedUsersCubit extends Cubit<BlockedUsersState> {
|
||||||
|
final BlockedUsersRepository blockedUsersRepository;
|
||||||
|
|
||||||
|
BlockedUsersCubit({
|
||||||
|
required this.blockedUsersRepository,
|
||||||
|
}) : super(const BlockedUsersState());
|
||||||
|
|
||||||
|
getBlockedUsers() async {
|
||||||
|
try {
|
||||||
|
emit(BlockedUsersState.loaded(profilesList: await blockedUsersRepository.getBlockedUsers()));
|
||||||
|
} catch (e, st) {
|
||||||
|
emit(BlockedUsersState.error(errorMessage: '$e $st'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blockUser(String slug) async {
|
||||||
|
await blockedUsersRepository.blockUserBySlug(slug);
|
||||||
|
await getBlockedUsers();
|
||||||
|
}
|
||||||
|
|
||||||
|
unblockUser(String slug) async {
|
||||||
|
await blockedUsersRepository.unblockUserBySlug(slug);
|
||||||
|
await getBlockedUsers();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import 'package:eatvio_app/features/profile/models/profile_model.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'blocked_users_state.freezed.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class BlockedUsersState with _$BlockedUsersState {
|
||||||
|
const factory BlockedUsersState() = _BlockedUsersState;
|
||||||
|
const factory BlockedUsersState.loading() = BlockedUsersStateLoading;
|
||||||
|
const factory BlockedUsersState.loaded({required List<ProfileModel> profilesList}) = BlockedUsersStateLoaded;
|
||||||
|
const factory BlockedUsersState.error({
|
||||||
|
required String errorMessage,
|
||||||
|
}) = BlockedUsersStateError;
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import 'package:eatvio_app/core/locator_service.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_state.dart';
|
||||||
|
import 'package:eatvio_app/features/menu/presentation/widgets/blocked_user_widget.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
|
class BlockedUsersScreen extends StatefulWidget {
|
||||||
|
const BlockedUsersScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<BlockedUsersScreen> createState() => _BlockedUsersScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BlockedUsersScreenState extends State<BlockedUsersScreen> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider<BlockedUsersCubit>(
|
||||||
|
create: (BuildContext context) => sl<BlockedUsersCubit>()..getBlockedUsers(),
|
||||||
|
child: BlocBuilder<BlockedUsersCubit, BlockedUsersState>(
|
||||||
|
builder: (BuildContext context, BlockedUsersState state) {
|
||||||
|
if (state is BlockedUsersStateLoaded) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('Чёрный список'),
|
||||||
|
),
|
||||||
|
body: ListView.builder(
|
||||||
|
itemBuilder: (context, index) => BlockedUserWidget(profile: state.profilesList[index]),
|
||||||
|
itemCount: state.profilesList.length,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return const Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -53,6 +53,8 @@ class MenuScreen extends StatelessWidget {
|
|||||||
_tile(leading: ImageConstant.icnGlossary, title: 'Глоссарий', onTap: () => GoRouter.of(context).push('/glossary-screen')),
|
_tile(leading: ImageConstant.icnGlossary, title: 'Глоссарий', onTap: () => GoRouter.of(context).push('/glossary-screen')),
|
||||||
_divider(context),
|
_divider(context),
|
||||||
_tile(leading: ImageConstant.icnSupport, title: 'Поддержка', onTap: () => GoRouter.of(context).push('/support-screen')),
|
_tile(leading: ImageConstant.icnSupport, title: 'Поддержка', onTap: () => GoRouter.of(context).push('/support-screen')),
|
||||||
|
_divider(context),
|
||||||
|
_tile(leading: 'assets/icons/blocked_users.svg', title: 'Чёрный список', onTap: () => GoRouter.of(context).pushNamed('blockedUsersScreen')),
|
||||||
// _divider(context),
|
// _divider(context),
|
||||||
// _tile(
|
// _tile(
|
||||||
// leading: ImageConstant.icnDevTools,
|
// leading: ImageConstant.icnDevTools,
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
|
import 'package:eatvio_app/features/menu/services/blocked_users_service.dart';
|
||||||
|
import 'package:eatvio_app/features/profile/models/profile_model.dart';
|
||||||
|
|
||||||
|
class BlockedUsersRepository {
|
||||||
|
final BlockedUserService blockedUserService;
|
||||||
|
|
||||||
|
BlockedUsersRepository({
|
||||||
|
required this.blockedUserService,
|
||||||
|
});
|
||||||
|
|
||||||
|
Future<List<ProfileModel>> getBlockedUsers() async {
|
||||||
|
try {
|
||||||
|
return (await blockedUserService.getBlockedUsers()).profilesList;
|
||||||
|
} catch (e, st) {
|
||||||
|
log(e.toString(), stackTrace: st);
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blockUserBySlug(String slug) async {
|
||||||
|
try {
|
||||||
|
return await blockedUserService.blockUser(
|
||||||
|
data: {
|
||||||
|
'slug': slug,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} catch (e, st) {
|
||||||
|
log(e.toString(), stackTrace: st);
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unblockUserBySlug(String slug) async {
|
||||||
|
try {
|
||||||
|
return await blockedUserService.unblockUser(
|
||||||
|
data: {
|
||||||
|
'slug': slug,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} catch (e, st) {
|
||||||
|
log(e.toString(), stackTrace: st);
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
import 'package:eatvio_app/core/const.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/profile/models/profile_model.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
|
class BlockedUserWidget extends StatefulWidget {
|
||||||
|
final ProfileModel profile;
|
||||||
|
const BlockedUserWidget({super.key, required this.profile});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<BlockedUserWidget> createState() => _BlockedUserWidgetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BlockedUserWidgetState extends State<BlockedUserWidget> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return InkWell(
|
||||||
|
onTap: () => GoRouter.of(context).pushNamed(
|
||||||
|
'profileScreen',
|
||||||
|
extra: Author(
|
||||||
|
authorSlug: widget.profile.slug,
|
||||||
|
authorName: widget.profile.name,
|
||||||
|
authorProfileIcon: widget.profile.profilePhotoUrl,
|
||||||
|
authorIsMe: false,
|
||||||
|
isEntitySubscribedByMe: false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Ink(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
CircleAvatar(
|
||||||
|
foregroundImage: NetworkImage(baseUrl + widget.profile.profilePhotoUrl),
|
||||||
|
backgroundImage: const AssetImage('assets/images/no_avatar.png'),
|
||||||
|
radius: 28,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 12),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
widget.profile.name,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Color(0xFF323F4B),
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
height: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
context.read<BlockedUsersCubit>().unblockUser(widget.profile.slug);
|
||||||
|
},
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
child: Ink(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: const Color(0xFFF1F2F6),
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
),
|
||||||
|
child: const Text(
|
||||||
|
'Убрать',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Color(0xFF6D6F71),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:eatvio_app/features/menu/models/blocked_users_model.dart';
|
||||||
import 'package:retrofit/retrofit.dart';
|
import 'package:retrofit/retrofit.dart';
|
||||||
|
|
||||||
part 'blocked_users_service.g.dart';
|
part 'blocked_users_service.g.dart';
|
||||||
@@ -8,17 +9,15 @@ abstract class BlockedUserService {
|
|||||||
factory BlockedUserService(Dio dio, {String baseUrl}) = _BlockedUserService;
|
factory BlockedUserService(Dio dio, {String baseUrl}) = _BlockedUserService;
|
||||||
|
|
||||||
@GET('/api/blocked_users')
|
@GET('/api/blocked_users')
|
||||||
Future<void> getBlockedUsers();
|
Future<BlockedUsersModel> getBlockedUsers();
|
||||||
|
|
||||||
@POST('/api/blocked_users/block')
|
@POST('/api/blocked_users/block')
|
||||||
Future<void> blockUser({
|
Future<void> blockUser({
|
||||||
String? slug,
|
@Body() required Map<String, Object?> data,
|
||||||
String? id,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@POST('/api/blocked_users/unblock')
|
@POST('/api/blocked_users/unblock')
|
||||||
Future<void> unblockUser({
|
Future<void> unblockUser({
|
||||||
String? slug,
|
@Body() required Map<String, Object?> data,
|
||||||
String? id,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
|||||||
path: 'plan/${widget.plan.slug}',
|
path: 'plan/${widget.plan.slug}',
|
||||||
complainedContentType: ComplainedContent.plan,
|
complainedContentType: ComplainedContent.plan,
|
||||||
slug: widget.plan.slug,
|
slug: widget.plan.slug,
|
||||||
|
userSlug: widget.plan.author.authorSlug,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 16),
|
const SizedBox(width: 16),
|
||||||
],
|
],
|
||||||
@@ -146,6 +147,7 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
|||||||
path: 'plan/${widget.plan.slug}',
|
path: 'plan/${widget.plan.slug}',
|
||||||
complainedContentType: ComplainedContent.plan,
|
complainedContentType: ComplainedContent.plan,
|
||||||
slug: widget.plan.slug,
|
slug: widget.plan.slug,
|
||||||
|
userSlug: widget.plan.author.authorSlug,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 16),
|
const SizedBox(width: 16),
|
||||||
],
|
],
|
||||||
@@ -365,6 +367,7 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
|||||||
path: 'plan/${widget.plan.slug}',
|
path: 'plan/${widget.plan.slug}',
|
||||||
complainedContentType: ComplainedContent.plan,
|
complainedContentType: ComplainedContent.plan,
|
||||||
slug: widget.plan.slug,
|
slug: widget.plan.slug,
|
||||||
|
userSlug: widget.plan.author.authorSlug,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 16),
|
const SizedBox(width: 16),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import 'package:eatvio_app/features/chat/presentation/pages/photo_view_screen.da
|
|||||||
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/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/profile/models/circumference_model.dart';
|
import 'package:eatvio_app/features/profile/models/circumference_model.dart';
|
||||||
import 'package:eatvio_app/features/profile/models/weight_model.dart';
|
import 'package:eatvio_app/features/profile/models/weight_model.dart';
|
||||||
import 'package:eatvio_app/features/profile/presentation/bloc/plans_cubit/plans_cubit.dart';
|
import 'package:eatvio_app/features/profile/presentation/bloc/plans_cubit/plans_cubit.dart';
|
||||||
@@ -1175,6 +1176,8 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
|
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
} else if (value == 'block') {
|
||||||
|
sl<BlockedUsersCubit>().blockUser(state.profile.slug);
|
||||||
} else {
|
} else {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
@@ -1196,6 +1199,11 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
value: 'complain',
|
value: 'complain',
|
||||||
child: Text('Пожаловаться'),
|
child: Text('Пожаловаться'),
|
||||||
),
|
),
|
||||||
|
if (widget.author != null)
|
||||||
|
const PopupMenuItem(
|
||||||
|
value: 'block',
|
||||||
|
child: Text('Заблокировать'),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
child: const Icon(Icons.more_horiz_rounded),
|
child: const Icon(Icons.more_horiz_rounded),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ class _ProfileBlogPostWidgetState extends State<ProfileBlogPostWidget> {
|
|||||||
path: 'blog_post/${(state.blogPosts[widget.index].id)}',
|
path: 'blog_post/${(state.blogPosts[widget.index].id)}',
|
||||||
id: state.blogPosts[widget.index].id,
|
id: state.blogPosts[widget.index].id,
|
||||||
feedBlogPostModel: state.blogPosts[widget.index],
|
feedBlogPostModel: state.blogPosts[widget.index],
|
||||||
|
userSlug: state.blogPosts[widget.index].author.authorSlug,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -219,6 +219,7 @@ class _AboutRecipeScreenState extends State<AboutRecipeScreen> {
|
|||||||
complainedContentType: ComplainedContent.recipe,
|
complainedContentType: ComplainedContent.recipe,
|
||||||
slug: widget.recipe.slug,
|
slug: widget.recipe.slug,
|
||||||
recipe: widget.recipe,
|
recipe: widget.recipe,
|
||||||
|
userSlug: widget.recipe.author.authorSlug,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 16),
|
const SizedBox(width: 16),
|
||||||
],
|
],
|
||||||
@@ -403,6 +404,7 @@ class _AboutRecipeScreenState extends State<AboutRecipeScreen> {
|
|||||||
complainedContentType: ComplainedContent.recipe,
|
complainedContentType: ComplainedContent.recipe,
|
||||||
slug: widget.recipe.slug,
|
slug: widget.recipe.slug,
|
||||||
recipe: widget.recipe,
|
recipe: widget.recipe,
|
||||||
|
userSlug: widget.recipe.author.authorSlug,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 16),
|
const SizedBox(width: 16),
|
||||||
],
|
],
|
||||||
@@ -428,6 +430,7 @@ class _AboutRecipeScreenState extends State<AboutRecipeScreen> {
|
|||||||
complainedContentType: ComplainedContent.recipe,
|
complainedContentType: ComplainedContent.recipe,
|
||||||
slug: widget.recipe.slug,
|
slug: widget.recipe.slug,
|
||||||
recipe: widget.recipe,
|
recipe: widget.recipe,
|
||||||
|
userSlug: widget.recipe.author.authorSlug,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 16),
|
const SizedBox(width: 16),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
name: eatvio_app
|
name: eatvio_app
|
||||||
description: A new Flutter project.
|
description: A new Flutter project.
|
||||||
version: 1.1.13+43
|
version: 1.1.14+44
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
@@ -38,8 +38,8 @@ dependencies:
|
|||||||
easy_debounce: ^2.0.3
|
easy_debounce: ^2.0.3
|
||||||
badges: ^3.1.2
|
badges: ^3.1.2
|
||||||
google_fonts: ^6.2.1
|
google_fonts: ^6.2.1
|
||||||
syncfusion_flutter_charts: ^29.2.5
|
syncfusion_flutter_charts: ^30.1.37
|
||||||
syncfusion_flutter_gauges: ^29.2.5
|
syncfusion_flutter_gauges: ^30.1.37
|
||||||
table_calendar: ^3.2.0
|
table_calendar: ^3.2.0
|
||||||
flutter_keyboard_visibility: ^6.0.0
|
flutter_keyboard_visibility: ^6.0.0
|
||||||
share_plus: ^11.0.0
|
share_plus: ^11.0.0
|
||||||
@@ -83,7 +83,7 @@ dev_dependencies:
|
|||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
flutter_lints: ^5.0.0
|
flutter_lints: ^6.0.0
|
||||||
|
|
||||||
flutter:
|
flutter:
|
||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
|
|||||||
Reference in New Issue
Block a user