Files
eatvio_app/lib/core/widgets/custom_popup.dart
2025-04-29 13:06:09 +03:00

176 lines
6.0 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:eatvio_app/core/const.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/models/feed_blog_post_model.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.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;
const CustomPopup({
super.key,
required this.isAuthor,
this.complainedContentType,
required this.path,
this.id,
this.slug,
this.feedBlogPostModel,
});
@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<PopupMenuEntry> _buildMenuItems(s, context) {
final entries = <PopupMenuEntry>[];
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: '$baseUrl/ru/$path'));
showInfoToast(s.link_was_copied);
});
addItem('assets/icons/share2.svg', 'Поделиться', () {
final box = context.findRenderObject() as RenderBox?;
Share.shareUri(
Uri.parse(
'$baseUrl/ru/$path',
),
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
);
});
addItem('assets/icons/edit_paint.svg', 'Редактировать', () {
if (complainedContentType == ComplainedContent.posts) {
GoRouter.of(context).pushNamed('blogPostCreateScreen', extra: feedBlogPostModel);
}
});
if (complainedContentType == ComplainedContent.plan || complainedContentType == ComplainedContent.diet) {
addItem('assets/icons/remove_from_public.svg', 'Снять с публикации', () {});
}
addItem('assets/icons/red_trash.svg', 'Удалить', () async {
if (complainedContentType == ComplainedContent.posts) {
final result = await sl<BlogPostCreateCubit>().deleteBlogPost(id!);
if (!context.mounted) return;
if (!result) {
showErrorDialog(context, title: S.current.could_not_delete_blog_post);
return;
}
context.read<FeedCubit>().loadFeedBlogPostList();
}
});
} else {
addItem('assets/icons/copy2.svg', 'Скопировать ссылку', () {
Clipboard.setData(ClipboardData(text: '$baseUrl/ru/$path'));
showInfoToast(s.link_was_copied);
});
addItem('assets/icons/share2.svg', 'Поделиться', () {
final box = context.findRenderObject() as RenderBox?;
Share.shareUri(
Uri.parse(
'$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,
),
);
}
});
}
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,
),
);
}
}