forked from eatvio/eatvio_app
fixed layout of diets feed and added text styles
This commit is contained in:
@@ -1,15 +1,44 @@
|
||||
import 'dart:async';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:easy_debounce/easy_debounce.dart';
|
||||
import 'package:eatvio_app/core/data/diet/repositories/diet_repository.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_state.dart';
|
||||
import 'package:eatvio_app/features/feed/repositories/feed_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class DietsCubit extends Cubit<DietsState> {
|
||||
final FeedRepository feedRepository;
|
||||
final DietRepository dietsRepository;
|
||||
int currentPage = 1;
|
||||
late int lastPage;
|
||||
bool isLoading = false;
|
||||
String? _query;
|
||||
late final StreamSubscription likesStateSubscription;
|
||||
late final StreamSubscription favoriteStateSubscription;
|
||||
late final StreamSubscription commentsStateSubscription;
|
||||
DietsCubit({
|
||||
required this.feedRepository,
|
||||
required this.dietsRepository,
|
||||
}) : super(const DietsState.loading()) {
|
||||
likesStateSubscription = dietsRepository.dietLikeState.listen((likesState) {
|
||||
_changeDietLikeState(likesState);
|
||||
});
|
||||
favoriteStateSubscription = dietsRepository.dietFavoriteState.listen((favoriteState) {
|
||||
_changeDietFavoriteState(favoriteState);
|
||||
});
|
||||
commentsStateSubscription = dietsRepository.dietCommentsState.listen((commentsState) {
|
||||
_changeDietCommentsState(commentsState);
|
||||
});
|
||||
}
|
||||
|
||||
DietsCubit({required this.feedRepository}) : super(const DietsState.loading());
|
||||
@override
|
||||
Future<void> close() async {
|
||||
likesStateSubscription.cancel();
|
||||
favoriteStateSubscription.cancel();
|
||||
commentsStateSubscription.cancel();
|
||||
super.close();
|
||||
}
|
||||
|
||||
loadDiets({
|
||||
String? query,
|
||||
@@ -20,14 +49,18 @@ class DietsCubit extends Cubit<DietsState> {
|
||||
query: query,
|
||||
);
|
||||
lastPage = dietsPagination.meta.lastPage;
|
||||
emit(DietsState.loaded(
|
||||
dietsList: dietsPagination.data,
|
||||
isLoading: isLoading,
|
||||
),);
|
||||
emit(
|
||||
DietsState.loaded(
|
||||
dietsList: dietsPagination.data,
|
||||
isLoading: isLoading,
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
emit(DietsState.error(
|
||||
errorMessage: e.toString(),
|
||||
),);
|
||||
emit(
|
||||
DietsState.error(
|
||||
errorMessage: e.toString(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,4 +93,195 @@ class DietsCubit extends Cubit<DietsState> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> likeDiet(int id, int index) async {
|
||||
if (state is! DietsStateLoaded) return;
|
||||
|
||||
final currentDiets = (state as DietsStateLoaded).dietsList;
|
||||
final dietsForModification = [...currentDiets];
|
||||
final currentDiet = currentDiets[index];
|
||||
if (currentDiet.wasLikedByMe) {
|
||||
dietsForModification[index] = currentDiet.copyWith(
|
||||
totalLikes: currentDiet.totalLikes - 1,
|
||||
wasLikedByMe: false,
|
||||
);
|
||||
emit(
|
||||
DietsState.loaded(
|
||||
dietsList: [
|
||||
...dietsForModification,
|
||||
],
|
||||
isLoading: isLoading,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
dietsForModification[index] = currentDiet.copyWith(
|
||||
totalLikes: currentDiet.totalLikes + 1,
|
||||
wasLikedByMe: true,
|
||||
);
|
||||
emit(
|
||||
DietsState.loaded(
|
||||
dietsList: [
|
||||
...dietsForModification,
|
||||
],
|
||||
isLoading: isLoading,
|
||||
),
|
||||
);
|
||||
}
|
||||
EasyDebounce.debounce(
|
||||
'like_diet',
|
||||
Duration(milliseconds: 200),
|
||||
() async {
|
||||
try {
|
||||
await dietsRepository.likeDiet(id);
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
emit(
|
||||
DietsState.loaded(
|
||||
dietsList: [
|
||||
...currentDiets,
|
||||
],
|
||||
isLoading: isLoading,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _changeDietLikeState(DietLikesState likesState) {
|
||||
if (state is! DietsStateLoaded) return;
|
||||
|
||||
final currentDiets = (state as DietsStateLoaded).dietsList;
|
||||
final dietsForModification = [...currentDiets];
|
||||
final currentDiet = currentDiets[likesState.index];
|
||||
|
||||
dietsForModification[likesState.index] = currentDiet.copyWith(
|
||||
totalLikes: likesState.totalLikes,
|
||||
wasLikedByMe: likesState.wasLikedByMe,
|
||||
);
|
||||
emit(
|
||||
DietsState.loaded(
|
||||
dietsList: [
|
||||
...dietsForModification,
|
||||
],
|
||||
isLoading: isLoading,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _changeDietFavoriteState(DietFavoriteState favoriteState) {
|
||||
if (state is! DietsStateLoaded) return;
|
||||
|
||||
final currentDiets = (state as DietsStateLoaded).dietsList;
|
||||
final dietsForModification = [...currentDiets];
|
||||
final currentDiet = currentDiets[favoriteState.index];
|
||||
|
||||
dietsForModification[favoriteState.index] = currentDiet.copyWith(
|
||||
isFavorite: favoriteState.isFavorite,
|
||||
);
|
||||
emit(
|
||||
DietsState.loaded(
|
||||
dietsList: [
|
||||
...dietsForModification,
|
||||
],
|
||||
isLoading: isLoading,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _changeDietCommentsState(DietCommentsState commentsState) {
|
||||
if (state is! DietsStateLoaded) return;
|
||||
|
||||
final currentDiets = (state as DietsStateLoaded).dietsList;
|
||||
final dietsForModification = [...currentDiets];
|
||||
final currentDiet = currentDiets[commentsState.index];
|
||||
|
||||
dietsForModification[commentsState.index] = currentDiet.copyWith(
|
||||
totalComments: commentsState.totalComments,
|
||||
);
|
||||
emit(
|
||||
DietsState.loaded(
|
||||
dietsList: [
|
||||
...dietsForModification,
|
||||
],
|
||||
isLoading: isLoading,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> addDietToFavorite(int id, int index) async {
|
||||
if (state is! DietsStateLoaded) return;
|
||||
final currentDiets = (state as DietsStateLoaded).dietsList;
|
||||
final dietsForModification = [...currentDiets];
|
||||
final currentDiet = currentDiets[index];
|
||||
|
||||
dietsForModification[index] = currentDiet.copyWith(
|
||||
isFavorite: true,
|
||||
);
|
||||
emit(
|
||||
DietsState.loaded(
|
||||
dietsList: [
|
||||
...dietsForModification,
|
||||
],
|
||||
isLoading: isLoading,
|
||||
),
|
||||
);
|
||||
EasyDebounce.debounce(
|
||||
'add_or_remove_diet_from_favorite',
|
||||
Duration(milliseconds: 200),
|
||||
() async {
|
||||
try {
|
||||
await dietsRepository.addToFavorite(id);
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
emit(
|
||||
DietsState.loaded(
|
||||
dietsList: [
|
||||
...currentDiets,
|
||||
],
|
||||
isLoading: isLoading,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> removeDietFromFavorite(int id, int index) async {
|
||||
if (state is! DietsStateLoaded) return;
|
||||
final currentDiets = (state as DietsStateLoaded).dietsList;
|
||||
final dietsForModification = [...currentDiets];
|
||||
final currentDiet = currentDiets[index];
|
||||
|
||||
dietsForModification[index] = currentDiet.copyWith(
|
||||
isFavorite: false,
|
||||
);
|
||||
emit(
|
||||
DietsState.loaded(
|
||||
dietsList: [
|
||||
...dietsForModification,
|
||||
],
|
||||
isLoading: isLoading,
|
||||
),
|
||||
);
|
||||
EasyDebounce.debounce(
|
||||
'add_or_remove_diet_from_favorite',
|
||||
Duration(milliseconds: 200),
|
||||
() async {
|
||||
try {
|
||||
await dietsRepository.removeFromFavorite(id);
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
emit(
|
||||
DietsState.loaded(
|
||||
dietsList: [
|
||||
...currentDiets,
|
||||
],
|
||||
isLoading: isLoading,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:eatvio_app/features/feed/presentation/bloc/recipes_cubit/recipes
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/recipes_cubit/recipes_state.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/blog_post_widget.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/diets_widget.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/filter_widget.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/plan_widget.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/recipes_widget.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/tags_modal_widget.dart';
|
||||
@@ -282,17 +283,26 @@ class _FeedScreenState extends State<FeedScreen> {
|
||||
child: BlocBuilder<DietsCubit, DietsState>(
|
||||
builder: (BuildContext context, DietsState state) {
|
||||
if (state is DietsStateLoaded) {
|
||||
return ListView.separated(
|
||||
padding: EdgeInsets.symmetric(vertical: 8),
|
||||
shrinkWrap: true,
|
||||
physics: BouncingScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
return DietsWidget(diet: state.dietsList[index]);
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return SizedBox(height: 8);
|
||||
},
|
||||
itemCount: state.dietsList.length,
|
||||
return Stack(
|
||||
children: [
|
||||
ListView.separated(
|
||||
padding: EdgeInsets.symmetric(vertical: 8),
|
||||
shrinkWrap: true,
|
||||
physics: BouncingScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
return DietsWidget(diet: state.dietsList[index], index: index);
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return SizedBox(height: 8);
|
||||
},
|
||||
itemCount: state.dietsList.length,
|
||||
),
|
||||
Positioned(
|
||||
right: 0,
|
||||
bottom: 74,
|
||||
child: FilterWidget(),
|
||||
),
|
||||
],
|
||||
);
|
||||
} else if (state is DietsStateError) {
|
||||
return Scaffold(
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:dismissible_page/dismissible_page.dart';
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/core/utils/date_time_utils.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/feed/models/feed_blog_post_model.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart';
|
||||
@@ -153,7 +154,7 @@ class _BlogPostWidgetState extends State<BlogPostWidget> {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
child: Row(
|
||||
children: [
|
||||
_iconButton(
|
||||
FeedIconButton(
|
||||
icon: isLiked ? Icons.favorite_rounded : Icons.favorite_border_rounded,
|
||||
text: totalLikes.toString(),
|
||||
iconColor: isLiked ? Colors.red.withOpacity(0.8) : null,
|
||||
@@ -171,7 +172,7 @@ class _BlogPostWidgetState extends State<BlogPostWidget> {
|
||||
},
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
_iconButton(
|
||||
FeedIconButton(
|
||||
svgIcon: SvgPicture.asset(
|
||||
'assets/icons/comment.svg',
|
||||
height: 20,
|
||||
@@ -188,7 +189,7 @@ class _BlogPostWidgetState extends State<BlogPostWidget> {
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
_iconButton(
|
||||
FeedIconButton(
|
||||
svgIcon: SvgPicture.asset(
|
||||
height: 20,
|
||||
width: 20,
|
||||
@@ -225,40 +226,4 @@ class _BlogPostWidgetState extends State<BlogPostWidget> {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_iconButton({IconData? icon, SvgPicture? svgIcon, String? text, Function()? onTap, Color? iconColor, Color? backgroundColor, Color? textColor}) {
|
||||
return InkWell(
|
||||
onTap: onTap ?? () {},
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
child: Ink(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: backgroundColor ?? appTheme.gray100,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
height: 32,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (svgIcon != null) svgIcon,
|
||||
if (icon != null)
|
||||
Icon(
|
||||
icon,
|
||||
size: 20,
|
||||
color: iconColor ?? appTheme.gray600,
|
||||
),
|
||||
if (text != null) SizedBox(width: 8),
|
||||
if (text != null)
|
||||
Text(
|
||||
text,
|
||||
style: TextStyle(
|
||||
color: textColor ?? appTheme.gray600,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ class _CommentsWidgetState extends State<CommentsWidget> {
|
||||
comment.authorName,
|
||||
style: TextStyle(
|
||||
height: 1,
|
||||
color: appTheme.grey,
|
||||
color: appTheme.gray,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
@@ -81,7 +81,7 @@ class _CommentsWidgetState extends State<CommentsWidget> {
|
||||
comment.body,
|
||||
style: TextStyle(
|
||||
height: 1,
|
||||
color: appTheme.blueGray800,
|
||||
color: appTheme.black,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
@@ -93,7 +93,7 @@ class _CommentsWidgetState extends State<CommentsWidget> {
|
||||
comment.createdAt.format('dd MMMM', 'ru'),
|
||||
style: TextStyle(
|
||||
height: 1,
|
||||
color: appTheme.grey,
|
||||
color: appTheme.gray,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
@@ -108,7 +108,7 @@ class _CommentsWidgetState extends State<CommentsWidget> {
|
||||
s.answer,
|
||||
style: TextStyle(
|
||||
height: 1,
|
||||
color: appTheme.grey,
|
||||
color: appTheme.gray,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
|
||||
@@ -1,15 +1,27 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/core/widgets/bookmark_button.dart';
|
||||
import 'package:eatvio_app/core/widgets/diet_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/theme/custom_text_style.dart';
|
||||
import 'package:eatvio_app/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';
|
||||
|
||||
class DietsWidget extends StatefulWidget {
|
||||
final Diet diet;
|
||||
|
||||
const DietsWidget({super.key, required this.diet});
|
||||
final int index;
|
||||
const DietsWidget({
|
||||
super.key,
|
||||
required this.diet,
|
||||
required this.index,
|
||||
});
|
||||
|
||||
@override
|
||||
State<DietsWidget> createState() => _DietsWidgetState();
|
||||
@@ -18,21 +30,21 @@ class DietsWidget extends StatefulWidget {
|
||||
class _DietsWidgetState extends State<DietsWidget> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
onTap: () => GoRouter.of(context).pushNamed('aboutDietScreen', extra: widget.diet),
|
||||
child: Ink(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: Colors.white,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Stack(
|
||||
children: [
|
||||
ClipRRect(
|
||||
return DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: Colors.white,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Stack(
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () =>
|
||||
GoRouter.of(context).pushNamed('aboutDietScreen', extra: {'diet': widget.diet, 'index': widget.index, 'navigateToComments': false}),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(12)),
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: baseUrl + '/storage/' + widget.diet.image,
|
||||
@@ -40,148 +52,121 @@ class _DietsWidgetState extends State<DietsWidget> {
|
||||
width: MediaQuery.of(context).size.width,
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
left: 8,
|
||||
bottom: 8,
|
||||
child: Wrap(
|
||||
runSpacing: 8,
|
||||
children: [
|
||||
_iconButton(Icons.fastfood, '139.9 ккал'),
|
||||
SizedBox(width: 8),
|
||||
_iconButton(Icons.timer_rounded, widget.diet.state),
|
||||
SizedBox(width: 8),
|
||||
_iconButton(Icons.fast_forward_rounded, widget.diet.duration.toString()),
|
||||
],
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
left: 8,
|
||||
top: 8,
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withOpacity(0.8),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.favorite_rounded,
|
||||
size: 16,
|
||||
color: Colors.black,
|
||||
),
|
||||
SizedBox(width: 4),
|
||||
Text(
|
||||
widget.diet.totalLikes.toString(),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
right: 8,
|
||||
top: 8,
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withOpacity(0.8),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.visibility_rounded,
|
||||
size: 16,
|
||||
color: Colors.black,
|
||||
),
|
||||
SizedBox(width: 4),
|
||||
Text(
|
||||
widget.diet.totalViews.toString(),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
child: Text(
|
||||
widget.diet.name,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (widget.diet.details.isNotEmpty)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||
child: Html(
|
||||
data: widget.diet.details.length > 200 ? widget.diet.details.substring(0, 200) : widget.diet.details,
|
||||
style: {
|
||||
"*": Style(
|
||||
color: Colors.black87,
|
||||
),
|
||||
Positioned(
|
||||
right: 14,
|
||||
child: BookmarkButton(
|
||||
onTap: () async {
|
||||
if (widget.diet.isFavorite) {
|
||||
await context.read<DietsCubit>().removeDietFromFavorite(widget.diet.id, widget.index);
|
||||
} else {
|
||||
await context.read<DietsCubit>().addDietToFavorite(widget.diet.id, widget.index);
|
||||
}
|
||||
},
|
||||
color: appTheme.whiteA700,
|
||||
isFavorite: widget.diet.isFavorite,
|
||||
borderRadius: BorderRadius.vertical(bottom: Radius.circular(12)),
|
||||
width: 40,
|
||||
height: 44,
|
||||
size: 19,
|
||||
),
|
||||
),
|
||||
if (widget.diet.details.length > 200)
|
||||
Positioned(
|
||||
bottom: 16,
|
||||
child: SizedBox(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
child: DietInfoRow(
|
||||
diet: widget.diet,
|
||||
itemsBackgroundColor: appTheme.whiteA700,
|
||||
disableDescriptionOfTypes: true,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Text(
|
||||
'Читать полностью...',
|
||||
style: TextStyle(
|
||||
height: 1,
|
||||
color: appTheme.blueA400,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
widget.diet.name,
|
||||
style: TextStyles.textMSemibold.copyWith(color: appTheme.black),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_iconButton(IconData icon, [String? text]) {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withOpacity(0.8),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
height: 32,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
icon,
|
||||
size: 16,
|
||||
color: Colors.black,
|
||||
if (widget.diet.details.isNotEmpty) ...[
|
||||
SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Html(
|
||||
data: widget.diet.details.length > 200 ? widget.diet.details.substring(0, 200) + '...' : widget.diet.details,
|
||||
style: {
|
||||
"*": Style(
|
||||
margin: Margins.zero,
|
||||
color: appTheme.black,
|
||||
fontSize: FontSize(TextStyles.textSMedium.fontSize ?? 14),
|
||||
fontWeight: TextStyles.textSMedium.fontWeight ?? FontWeight.w400,
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
if (text != null) SizedBox(width: 8),
|
||||
if (text != null)
|
||||
Text(
|
||||
text,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
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<DietsCubit>().likeDiet(widget.diet.id, widget.index);
|
||||
},
|
||||
),
|
||||
SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
FeedIconButton(
|
||||
icon: Icons.chat_bubble_outline,
|
||||
text: widget.diet.totalComments.toString(),
|
||||
onTap: () =>
|
||||
GoRouter.of(context).pushNamed('aboutDietScreen', extra: {'diet': widget.diet, 'index': widget.index, 'navigateToComments': true}),
|
||||
),
|
||||
SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
FeedIconButton(
|
||||
svgIcon: SvgPicture.asset('assets/icons/repost.svg'),
|
||||
text: '0',
|
||||
onTap: () async {
|
||||
final result = await Share.shareUri(
|
||||
Uri.parse(
|
||||
baseUrl + '/ru/diet/' + widget.diet.id.toString(),
|
||||
),
|
||||
);
|
||||
switch (result.status) {
|
||||
case ShareResultStatus.success:
|
||||
case ShareResultStatus.dismissed:
|
||||
case ShareResultStatus.unavailable:
|
||||
}
|
||||
},
|
||||
),
|
||||
Spacer(),
|
||||
FeedIconButton(
|
||||
svgIcon: SvgPicture.asset('assets/icons/eye2.svg'),
|
||||
text: widget.diet.totalViews.toString(),
|
||||
backgroundColor: Colors.transparent,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
24
lib/features/feed/presentation/widgets/filter_widget.dart
Normal file
24
lib/features/feed/presentation/widgets/filter_widget.dart
Normal file
@@ -0,0 +1,24 @@
|
||||
import 'package:eatvio_app/theme/theme_helper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
|
||||
class FilterWidget extends StatelessWidget {
|
||||
const FilterWidget({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(left: 20, top: 12, bottom: 12, right: 24),
|
||||
width: 70,
|
||||
decoration: BoxDecoration(
|
||||
color: appTheme.blueA400,
|
||||
borderRadius: BorderRadius.horizontal(left: Radius.circular(100)),
|
||||
),
|
||||
child: SvgPicture.asset(
|
||||
'assets/icons/filter2.svg',
|
||||
width: 24,
|
||||
height: 16,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user