import 'package:cached_network_image/cached_network_image.dart'; import 'package:eatvio_app/core/app_config.dart'; import 'package:eatvio_app/core/enums/complained_content.dart'; import 'package:eatvio_app/core/enums/product_type.dart'; import 'package:eatvio_app/core/locator_service.dart'; import 'package:eatvio_app/core/widgets/bookmark_button.dart'; import 'package:eatvio_app/core/widgets/custom_popup.dart'; import 'package:eatvio_app/core/widgets/info_row.dart'; import 'package:eatvio_app/core/widgets/feed_icon_button.dart'; import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart'; import 'package:eatvio_app/core/theme/custom_text_style.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_html/flutter_html.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:go_router/go_router.dart'; import 'package:share_plus/share_plus.dart'; import 'package:markdown/markdown.dart' as md; class DietsWidget extends StatefulWidget { final Diet diet; final int index; const DietsWidget({super.key, required this.diet, required this.index}); @override State createState() => _DietsWidgetState(); } class _DietsWidgetState extends State { bool isMoreOptionsVisible = false; @override Widget build(BuildContext context) { return InkWell( onTap: () => GoRouter.of(context).pushNamed('aboutDietScreen', extra: {'slug': widget.diet.slug, 'index': widget.index, 'navigateToComments': false}), child: Material( borderRadius: BorderRadius.circular(12), color: Colors.white, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Stack( children: [ ClipRRect( borderRadius: const BorderRadius.vertical(top: Radius.circular(12)), child: CachedNetworkImage( imageUrl: '${sl().baseUrl}/storage/${widget.diet.image}', fit: BoxFit.fitWidth, width: MediaQuery.of(context).size.width, ), ), Positioned( left: 14, child: BookmarkButton( onTap: () async { if (widget.diet.isFavorite) { await context.read().removeDietFromFavorite(widget.diet.id, widget.index); } else { await context.read().addDietToFavorite(widget.diet.id, widget.index); } }, color: appTheme.whiteA700, isFavorite: widget.diet.isFavorite, borderRadius: const BorderRadius.vertical(bottom: Radius.circular(12)), width: 40, height: 44, size: 19, ), ), Positioned( right: 12, top: 12, child: SizedBox( width: 32, height: 24, child: Material( color: Colors.white, borderRadius: BorderRadius.circular(4), child: CustomPopup( isAuthor: widget.diet.author.authorIsMe, path: 'diet/${widget.diet.slug}', id: widget.diet.id, complainedContentType: ComplainedContent.diet, diet: widget.diet, userSlug: widget.diet.author.authorSlug, ), ), ), ), Positioned( bottom: 16, child: SizedBox( width: MediaQuery.sizeOf(context).width, child: InfoRow(diet: widget.diet, itemsBackgroundColor: appTheme.whiteA700, disableDescriptionOfTypes: true, type: ProductType.diet), ), ), ], ), const SizedBox(height: 12), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Text(widget.diet.name, style: TextStyles.textMSemibold.copyWith(color: appTheme.black)), ), if (widget.diet.details.isNotEmpty) ...[ const SizedBox(height: 12), Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Html( data: md.markdownToHtml( widget.diet.details.length > 200 ? '${widget.diet.details.substring(0, 200).replaceAll('\n', '
')}...' : widget.diet.details.replaceAll('\n', '
'), ), style: { "body": Style( margin: Margins.zero, padding: HtmlPaddings.zero, fontSize: FontSize(TextStyles.textSMedium.fontSize ?? 14), lineHeight: const LineHeight(1.5), ), "p": Style(margin: Margins.only(bottom: 12), color: appTheme.black), "h1, h2, h3, h4, h5, h6": Style(margin: Margins.only(top: 16, bottom: 8), color: appTheme.black, fontWeight: FontWeight.bold), "h1": Style(fontSize: FontSize(24)), "h2": Style(fontSize: FontSize(20)), "h3": Style(fontSize: FontSize(18)), "ul, ol": Style(margin: Margins.only(bottom: 12), padding: HtmlPaddings.only(left: 16)), "li": Style(margin: Margins.only(bottom: 4), color: appTheme.black), "strong, b": Style(fontWeight: FontWeight.bold, color: appTheme.black), "em, i": Style(fontStyle: FontStyle.italic), "code": Style( backgroundColor: Colors.grey.shade100, padding: HtmlPaddings.symmetric(horizontal: 4, vertical: 2), fontFamily: 'monospace', ), "pre": Style(backgroundColor: Colors.grey.shade100, padding: HtmlPaddings.all(12), margin: Margins.only(bottom: 12)), "blockquote": Style( padding: HtmlPaddings.only(left: 16), margin: Margins.only(left: 8, bottom: 12), fontStyle: FontStyle.italic, color: Colors.grey.shade700, ), "a": Style(color: Colors.blue, textDecoration: TextDecoration.underline), "img": Style(width: Width(MediaQuery.of(context).size.width - 32)), }, ), ), ], if (widget.diet.details.length > 200) const Padding( padding: EdgeInsets.only(left: 16, top: 8), child: Text( 'Показать ещё', style: TextStyle(height: 1, color: Color(0xFF8B8B8B), fontSize: 14, fontWeight: FontWeight.w600), ), ), ], ), Padding( padding: const EdgeInsets.only(left: 16, top: 12), child: Row( children: [ FeedIconButton( icon: widget.diet.wasLikedByMe ? Icons.favorite_rounded : Icons.favorite_border_rounded, text: widget.diet.totalLikes.toString(), iconColor: widget.diet.wasLikedByMe ? appTheme.blueA400 : null, backgroundColor: widget.diet.wasLikedByMe ? appTheme.transparentBlue : null, onTap: () async { await context.read().likeDiet(widget.diet.id, widget.index); }, ), const SizedBox(width: 12), FeedIconButton( icon: Icons.chat_bubble_outline, text: widget.diet.totalComments.toString(), onTap: () => GoRouter.of(context).pushNamed('aboutDietScreen', extra: {'slug': widget.diet.slug, 'index': widget.index, 'navigateToComments': true}), ), const SizedBox(width: 12), FeedIconButton( svgIcon: SvgPicture.asset('assets/icons/repost.svg'), onTap: () async { final box = context.findRenderObject() as RenderBox?; final result = await SharePlus.instance.share( ShareParams( uri: Uri.parse('${sl().baseUrl}/ru/diet/${widget.diet.id}'), sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size, ), ); switch (result.status) { case ShareResultStatus.success: case ShareResultStatus.dismissed: case ShareResultStatus.unavailable: } }, ), const Spacer(), FeedIconButton( svgIcon: SvgPicture.asset('assets/icons/eye2.svg'), text: widget.diet.totalViews.toString(), backgroundColor: Colors.transparent, ), ], ), ), const SizedBox(height: 12), ], ), ), ); } }