import 'package:eatvio_app/core/app_config.dart'; import 'package:eatvio_app/core/enums/complained_content.dart'; import 'package:eatvio_app/core/locator_service.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:eatvio_app/core/utils/toasts.dart'; import 'package:eatvio_app/core/widgets/show_error_dialog.dart'; import 'package:eatvio_app/features/blog_post_create/bloc/blog_post_create_cubit/blog_post_create_cubit.dart'; import 'package:eatvio_app/features/complaining/presentation/complaining_bottom_sheet.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.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/recipes_model.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/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/profile/presentation/bloc/profile_cubit/profile_cubit.dart'; import 'package:eatvio_app/generated/l10n.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:go_router/go_router.dart'; import 'package:share_plus/share_plus.dart'; class CustomPopup extends StatelessWidget { final bool isAuthor; final ComplainedContent? complainedContentType; final String path; final String? slug; final int? id; final FeedBlogPostModel? feedBlogPostModel; final Recipe? recipe; final Diet? diet; final String userSlug; final VoidCallback? onPostsChanged; const CustomPopup({ super.key, required this.isAuthor, this.complainedContentType, required this.path, this.id, this.slug, this.feedBlogPostModel, this.recipe, this.diet, required this.userSlug, this.onPostsChanged, }); @override Widget build(BuildContext context) { final s = S.of(context); return GestureDetector( onTap: () async { final RenderBox button = context.findRenderObject() as RenderBox; final RenderBox overlay = Overlay.of(context).context.findRenderObject() as RenderBox; final Offset position = button.localToGlobal(Offset.zero, ancestor: overlay); await showMenu( context: context, position: RelativeRect.fromLTRB( position.dx, position.dy + button.size.height, position.dx + button.size.width, position.dy, ), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), color: Colors.white, constraints: const BoxConstraints(minWidth: 260), surfaceTintColor: Colors.transparent, elevation: 2, items: _buildMenuItems(s, context), ); }, child: const Icon( Icons.more_horiz_rounded, ), ); } List _buildMenuItems(S s,BuildContext context) { final entries = []; void addItem(String icon, String text, Function() onTap) { entries.add(_buildCompactItem(icon: icon, text: text, onTap: onTap)); entries.add(_buildDivider()); } if (isAuthor) { addItem('assets/icons/copy2.svg', 'Скопировать ссылку', () { Clipboard.setData(ClipboardData(text: '${sl().baseUrl}/ru/$path')); showInfoToast(s.link_was_copied); }); addItem('assets/icons/share2.svg', 'Поделиться', () { final box = context.findRenderObject() as RenderBox?; SharePlus.instance.share( ShareParams( uri: Uri.parse( '${sl().baseUrl}/ru/$path', ), sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size, ), ); }); if (complainedContentType == ComplainedContent.posts) { addItem('assets/icons/edit_paint.svg', 'Редактировать', () async { if (complainedContentType == ComplainedContent.posts) { await GoRouter.of(context).pushNamed('blogPostCreateScreen', extra: feedBlogPostModel); onPostsChanged?.call(); } }); } addItem('assets/icons/red_trash.svg', 'Удалить', () async { if (complainedContentType == ComplainedContent.posts) { final result = await sl().deleteBlogPost(id!); if (!result && context.mounted) { showErrorDialog(context, title: S.current.could_not_delete_blog_post); return; } onPostsChanged?.call(); ProfileCubit.myProfileCubit?.reloadBlogPosts(); if (context.mounted) { try { context.read().loadFeedBlogPostList(); } catch (_) {} } showSuccessToast('Пост удален'); } else if (complainedContentType == ComplainedContent.recipe) { final result = await sl().deleteRecipe(slug!); if (!result && context.mounted) { showErrorDialog(context, title: 'Не удалось удалить рецепт'); return; } showSuccessToast('Рецепт удален, обновите ленту'); } else if (complainedContentType == ComplainedContent.diet) { final result = await sl().deleteDiet(id!); if (!result && context.mounted) { showErrorDialog(context, title: 'Не удалось удалить диету'); return; } showSuccessToast('Диета удалена, обновите ленту'); } else if (complainedContentType == ComplainedContent.plan) { final result = await sl().deletePlan(slug!); if (!result && context.mounted) { showErrorDialog(context, title: 'Не удалось удалить план'); return; } showSuccessToast('План удален, обновите ленту'); } }); } else { addItem('assets/icons/copy2.svg', 'Скопировать ссылку', () { Clipboard.setData(ClipboardData(text: '${sl().baseUrl}/ru/$path')); showInfoToast(s.link_was_copied); }); addItem('assets/icons/share2.svg', 'Поделиться', () { final box = context.findRenderObject() as RenderBox?; SharePlus.instance.share( ShareParams( uri: Uri.parse( '${sl().baseUrl}/ru/$path', ), sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size, ), ); }); addItem('assets/icons/complain.svg', 'Пожаловаться', () { if (complainedContentType != null) { showModalBottomSheet( context: context, isScrollControlled: true, builder: (context) => ComplainingBottomSheet( complainedContentType: complainedContentType!, id: id, slug: slug, ), ); } }); addItem( 'assets/icons/complain.svg', 'Заблокировать автора', () { sl().blockUser(userSlug); }, ); } if (entries.isNotEmpty && entries.last is PopupMenuItem) { entries.removeLast(); } return entries; } PopupMenuItem _buildCompactItem({required String icon, required String text, required Function() onTap}) { return PopupMenuItem( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), height: 36, onTap: onTap, child: SizedBox( width: double.infinity, child: Row( children: [ Text(text, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500)), const Spacer(), SvgPicture.asset(icon), ], ), ), ); } PopupMenuItem _buildDivider() { return PopupMenuItem( enabled: false, height: 1, padding: EdgeInsets.zero, child: Container( margin: const EdgeInsets.symmetric(horizontal: 12), height: 1, color: appTheme.dividerColor, ), ); } }