Merge remote-tracking branch 'upstream/main'

This commit is contained in:
Username1548
2025-04-30 21:25:40 +07:00
7 changed files with 215 additions and 62 deletions

View File

@@ -11,6 +11,9 @@ jobs:
- name: Checkout
uses: actions/checkout@v2
- name: Remove cache
run: rm -rf /Users/gitea_runner_ci/Library/Developer/Xcode/DerivedData/*
- name: Download provisioning
uses: mso7nueh/apple-provisioning-profiles-downloader@v1.0.8
with:

View File

@@ -0,0 +1,11 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1_84405)">
<path d="M14.1226 0.273893C13.9443 0.330415 13.7009 0.430415 13.5791 0.495632C13.4356 0.57824 11.6661 2.31737 8.0052 5.97389C3.29651 10.6782 2.63129 11.3565 2.51825 11.5869C2.39216 11.8348 2.37911 11.913 2.25738 13.2391C2.1052 14.8782 2.09651 15.213 2.20955 15.4609C2.37911 15.8348 2.70085 16.0826 3.1052 16.1478C3.29651 16.1782 6.02694 15.9435 6.33998 15.8695C6.83564 15.7478 6.70955 15.8652 12.2835 10.2913C18.1313 4.44346 17.8574 4.73911 18.0443 3.99998C18.2139 3.33911 18.1095 2.62607 17.7574 2.01737C17.6922 1.89998 17.3704 1.53911 17.0443 1.21737C16.3965 0.569545 16.0835 0.365197 15.5574 0.23911C15.14 0.143457 14.5226 0.156502 14.1226 0.273893ZM15.2835 1.63476C15.4574 1.69563 15.5922 1.80433 16.0226 2.23476C16.4487 2.66085 16.5617 2.79998 16.6182 2.97389C16.8009 3.51737 16.6791 3.83041 16.0226 4.47824L15.5617 4.93476L14.44 3.81302L13.3226 2.69128L13.8226 2.19998C14.1965 1.83476 14.3748 1.69128 14.5182 1.63911C14.7748 1.55215 15.0182 1.54781 15.2835 1.63476ZM10.2922 10.2087C7.96607 12.5348 6.02259 14.4478 5.97477 14.4565C5.87042 14.4826 3.58781 14.6956 3.57477 14.6782C3.57042 14.6739 3.6139 14.1217 3.67477 13.4522L3.78781 12.2391L8.03564 7.99128L12.2791 3.73911L13.3965 4.8565L14.5182 5.97824L10.2922 10.2087Z" fill="#2F80ED"/>
<path d="M0.409546 18.4521C0.244329 18.526 0.148677 18.6304 0.06172 18.8391C-0.0295844 19.0565 -0.0208887 19.213 0.0965026 19.4347C0.166068 19.5652 0.257372 19.6565 0.387807 19.726L0.574764 19.826H9.9965H19.4182L19.6052 19.726C19.8226 19.613 19.9965 19.3347 19.9965 19.113C19.9965 18.9304 19.8313 18.613 19.6791 18.5043L19.5574 18.413L10.0487 18.4043C2.22259 18.3956 0.518242 18.4043 0.409546 18.4521Z" fill="#2F80ED"/>
</g>
<defs>
<clipPath id="clip0_1_84405">
<rect width="20" height="20" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,6 @@
<svg width="18" height="20" viewBox="0 0 18 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.01268 0.0752392C5.47681 0.262703 5.0649 0.668873 4.87694 1.20002C4.81696 1.36405 4.80096 1.52417 4.80096 1.87957V2.34042H3.12934C1.5737 2.34042 1.43773 2.34432 1.22978 2.41462C0.813875 2.55522 0.473952 2.8247 0.226009 3.21134C-0.101916 3.72686 -0.069923 4.57044 0.301992 5.10549C0.465954 5.33982 0.825872 5.63273 1.06182 5.72256L1.22178 5.78114L1.75766 12.0807C2.04959 15.5487 2.30553 18.47 2.32553 18.5716C2.4415 19.1925 2.95738 19.7471 3.59724 19.9385C3.87317 20.0205 14.1268 20.0205 14.4028 19.9385C14.6947 19.8526 14.8907 19.7393 15.1346 19.5245C15.3825 19.298 15.6145 18.8957 15.6745 18.5755C15.6945 18.47 15.9504 15.5487 16.2423 12.0846L16.7782 5.78114L16.9382 5.72256C17.1741 5.63273 17.534 5.33982 17.698 5.10549C18.0699 4.57044 18.1019 3.72686 17.774 3.21134C17.526 2.8247 17.1861 2.55522 16.7702 2.41462C16.5623 2.34432 16.4263 2.34042 14.8707 2.34042H13.199V1.87957C13.199 1.52417 13.183 1.36405 13.1231 1.20002C12.9351 0.66106 12.5192 0.254892 11.9713 0.0713348C11.7554 0.00103569 11.6194 -0.00287056 8.984 0.00103569C6.3966 0.00103569 6.20864 0.00884628 6.01268 0.0752392ZM11.6714 1.26641C11.8953 1.3992 11.9673 1.55932 11.9913 1.9733L12.0113 2.34042H9H5.98869L6.00869 1.9733C6.03668 1.47731 6.15665 1.28594 6.50057 1.20392C6.56856 1.1883 7.72829 1.17658 9.07998 1.18049C11.4634 1.1883 11.5434 1.19221 11.6714 1.26641ZM16.4783 3.61751C16.6622 3.72686 16.7582 3.89479 16.7582 4.09788C16.7582 4.30096 16.6622 4.4689 16.4783 4.57825L16.3383 4.66417H9C1.73366 4.66417 1.66168 4.66417 1.52971 4.58606C1.07382 4.31659 1.17779 3.67218 1.69767 3.54721C1.76566 3.53159 5.0889 3.52378 9.07998 3.52378L16.3383 3.53159L16.4783 3.61751ZM15.5185 5.88268C15.5185 5.90221 15.2826 8.70634 14.9946 12.1236C14.5787 17.0445 14.4587 18.3607 14.4068 18.4661C14.3228 18.6341 14.1828 18.7356 13.9749 18.7825C13.7669 18.8293 4.23309 18.8293 4.02514 18.7825C3.81719 18.7356 3.67722 18.6341 3.59324 18.4661C3.54125 18.3607 3.42128 17.0445 3.00537 12.1236C2.71744 8.70634 2.48149 5.90221 2.48149 5.88268C2.48149 5.86706 5.41682 5.85534 9 5.85534C12.5872 5.85534 15.5185 5.86706 15.5185 5.88268Z" fill="#FF3B3B"/>
<path d="M5.06478 7.10111C4.85683 7.23389 4.80084 7.36668 4.80084 7.71036C4.80084 7.8822 4.93681 10.1005 5.09677 12.6391C5.4207 17.7084 5.38471 17.4038 5.66464 17.5756C5.8446 17.681 6.17653 17.6771 6.34449 17.5639C6.54844 17.4272 6.60043 17.3061 6.60043 16.9585C6.60043 16.7906 6.46446 14.5762 6.3045 12.0337C6.01656 7.50337 6.00857 7.41355 5.91659 7.28467C5.8646 7.21046 5.77662 7.12454 5.71663 7.08939C5.56467 6.99957 5.21275 7.00738 5.06478 7.10111Z" fill="#FF3B3B"/>
<path d="M8.66393 7.10121C8.60395 7.14027 8.51597 7.22619 8.47598 7.28477C8.40399 7.39412 8.39999 7.56596 8.39999 12.3385C8.39999 17.1109 8.40399 17.2828 8.47598 17.3921C8.59995 17.5718 8.75191 17.6499 8.99986 17.6499C9.2478 17.6499 9.39977 17.5718 9.52374 17.3921C9.59572 17.2828 9.59972 17.1109 9.59972 12.3385C9.59972 7.56596 9.59572 7.39412 9.52374 7.28477C9.39977 7.10512 9.2478 7.02701 8.99986 7.02701C8.85189 7.02701 8.74392 7.05044 8.66393 7.10121Z" fill="#FF3B3B"/>
<path d="M12.2632 7.10121C11.9833 7.28086 12.0193 6.95671 11.6953 12.0377C11.5354 14.5763 11.3994 16.7946 11.3994 16.9664C11.3994 17.3101 11.4554 17.4429 11.6634 17.5757C11.8193 17.6772 12.1672 17.6772 12.3352 17.5757C12.6151 17.4039 12.5791 17.7085 12.9031 12.6392C13.063 10.1006 13.199 7.88231 13.199 7.71047C13.199 7.36678 13.143 7.234 12.9351 7.10121C12.7751 6.99967 12.4192 6.99967 12.2632 7.10121Z" fill="#FF3B3B"/>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -0,0 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.41406 3.63281C6.50391 3.85547 3.34766 5.75391 0.675781 8.89453C0.078125 9.59766 0 9.72266 0 10C0 10.2773 0.078125 10.4023 0.675781 11.1055C2.87891 13.6953 5.51953 15.5156 7.95703 16.1289C8.66016 16.3047 9.25781 16.375 10 16.375C10.7578 16.375 11.3594 16.3008 12.0898 16.1133C14.5156 15.4922 17.1328 13.6797 19.3242 11.1055C19.9219 10.4023 20 10.2773 20 10C20 9.72266 19.9219 9.59766 19.3242 8.89453C17.1211 6.30469 14.4805 4.48437 12.043 3.87109C11.2031 3.66015 10.2188 3.57422 9.41406 3.63281ZM11.0742 5.05859C13.1172 5.42187 15.2031 6.64453 17.2305 8.66797C17.8945 9.33594 18.4375 9.93359 18.4375 10C18.4375 10.1211 16.8438 11.7617 16.1914 12.3086C14.457 13.7656 12.7617 14.6367 11.0547 14.9492C10.5977 15.0312 9.49609 15.0391 9.04297 14.9648C7.15625 14.6562 5.21484 13.6016 3.3125 11.8594C2.63672 11.2422 1.5625 10.0977 1.5625 10C1.5625 9.87891 3.15625 8.23828 3.80859 7.69141C5.71094 6.09375 7.59375 5.1875 9.43359 4.98437C9.73438 4.95312 10.7266 4.99609 11.0742 5.05859Z" fill="#2F80ED"/>
<path d="M9.49999 6.05859C8.40234 6.1875 7.32421 6.85156 6.69531 7.79687C5.64843 9.36719 5.85546 11.4687 7.19531 12.8047C8.74218 14.3555 11.2578 14.3555 12.8047 12.8047C14.3555 11.2578 14.3555 8.74219 12.8047 7.19531C12.168 6.55469 11.3437 6.16016 10.4492 6.05469C10.0547 6.01172 9.90624 6.01172 9.49999 6.05859ZM10.5273 7.44141C10.6797 7.47266 10.9687 7.58203 11.1719 7.67969C12.0352 8.10937 12.6172 9.03906 12.6172 10C12.6172 10.9609 12.0352 11.8906 11.1719 12.3203C10.3672 12.7148 9.63281 12.7148 8.82812 12.3203C7.96484 11.8906 7.38281 10.9609 7.38281 10C7.38281 9.61328 7.48046 9.23828 7.67968 8.82812C8.19921 7.78125 9.38281 7.20312 10.5273 7.44141Z" fill="#2F80ED"/>
<rect x="3" y="2" width="21" height="1.5" rx="0.75" transform="rotate(45 3 2)" fill="#2F80ED"/>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,175 @@
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,
),
);
}
}

View File

@@ -3,10 +3,8 @@ import 'package:cached_network_image/cached_network_image.dart';
import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/core/enums/complained_content.dart';
import 'package:eatvio_app/core/utils/date_time_utils.dart';
import 'package:eatvio_app/core/widgets/show_error_dialog.dart';
import 'package:eatvio_app/features/complaining/presentation/complaining_bottom_sheet.dart';
import 'package:eatvio_app/core/widgets/custom_popup.dart';
import 'package:eatvio_app/core/widgets/loader.dart';
import 'package:eatvio_app/features/blog_post_create/bloc/blog_post_create_cubit/blog_post_create_cubit.dart';
import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/comments_cubit/comments_cubit.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/comments_cubit/comments_state.dart';
@@ -14,7 +12,6 @@ import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit
import 'package:eatvio_app/features/feed/presentation/widgets/comments_widget.dart';
import 'package:eatvio_app/core/locator_service.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_html/flutter_html.dart';
@@ -163,39 +160,14 @@ class _BlogPostScreenState extends State<BlogPostScreen> {
appBar: AppBar(
title: Text(widget.blogPost.title),
actions: [
PopupMenuButton(
onSelected: (value) async {
if (value == 'delete') {
final result = await sl<BlogPostCreateCubit>().deleteBlogPost(widget.blogPost.id);
if (!context.mounted) return;
if (!result) {
showErrorDialog(context, title: S.current.could_not_delete_blog_post);
return;
}
context.read<FeedCubit>().loadFeedBlogPostList();
Navigator.of(context).pop();
}
if (value == 'edit') {
GoRouter.of(context).replaceNamed('blogPostCreateScreen', extra: widget.blogPost);
}
},
itemBuilder: (context) => [
if (widget.blogPost.author.authorIsMe) const PopupMenuItem(value: 'edit', child: Text('Редактировать')),
if (widget.blogPost.author.authorIsMe) const PopupMenuItem(value: 'delete', child: Text('Удалить')),
if (!widget.blogPost.author.authorIsMe)
PopupMenuItem(
value: 'report',
child: const Text('Пожаловаться'),
onTap: () {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) => ComplainingBottomSheet(complainedContentType: ComplainedContent.posts, id: widget.blogPost.id),
);
},
),
],
CustomPopup(
isAuthor: widget.blogPost.author.authorIsMe,
complainedContentType: ComplainedContent.posts,
path: 'blog_post/${(widget.blogPost.id)}',
id: widget.blogPost.id,
feedBlogPostModel: widget.blogPost,
),
const SizedBox(width: 16),
],
),
body: SingleChildScrollView(

View File

@@ -4,9 +4,9 @@ import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/core/enums/complained_content.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart';
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/feed_icon_button.dart';
import 'package:eatvio_app/features/chat/presentation/pages/photo_view_screen.dart';
import 'package:eatvio_app/features/diets/presentation/widgets/more_options.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_state.dart';
@@ -14,7 +14,6 @@ import 'package:eatvio_app/features/feed/presentation/widgets/subscribe_button_w
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:flutter_portal/flutter_portal.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:go_router/go_router.dart';
import 'package:share_plus/share_plus.dart';
@@ -119,30 +118,12 @@ class _BlogPostWidgetState extends State<BlogPostWidget> {
slug: state.feedBlogPostList[widget.index].author.authorSlug,
),
),
PortalTarget(
visible: isMoreOptionsVisible,
portalFollower: MoreOptions(
complainedContentType: ComplainedContent.posts,
path: 'blog_post/${(state.feedBlogPostList[widget.index].id)}',
id: state.feedBlogPostList[widget.index].id,
),
anchor: const Aligned(shiftToWithinBound: AxisFlag(x: true, y: true), follower: Alignment.topRight, target: Alignment.bottomRight),
child: InkWell(
onTap: () {
setState(() {
isMoreOptionsVisible = !isMoreOptionsVisible;
});
},
child: SizedBox(
width: 32,
height: 24,
child: Material(
color: Colors.white,
borderRadius: BorderRadius.circular(4),
child: const Icon(Icons.more_horiz),
),
),
),
CustomPopup(
isAuthor: state.feedBlogPostList[widget.index].author.authorIsMe,
complainedContentType: ComplainedContent.posts,
path: 'blog_post/${(state.feedBlogPostList[widget.index].id)}',
id: state.feedBlogPostList[widget.index].id,
feedBlogPostModel: state.feedBlogPostList[widget.index],
),
],
),