Files
eatvio_app/lib/presentation/feed/feed_screen/feed_screen.dart
2024-06-25 16:05:55 +03:00

304 lines
10 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:go_router/go_router.dart';
import 'bloc/feed_bloc.dart';
import 'models/feed_model.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:eatvio_app/presentation/feed/feed_screen/widgets/feed_search_view.dart';
import 'package:eatvio_app/presentation/feed/feed_screen/widgets/feed_scroll_item.dart';
import 'package:eatvio_app/widgets/custom_outlined_button.dart';
import 'package:eatvio_app/core/app_export.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class FeedScreen extends StatelessWidget {
static Widget builder(BuildContext context) {
return BlocProvider<FeedBloc>(create: (context) => FeedBloc(FeedState(myProfileModelObj: FeedModel()))..add(FeedInitialEvent()), child: FeedScreen());
}
Widget build(BuildContext context) {
return BlocBuilder<FeedBloc, FeedState>(
builder: (context, state) {
if (state is FeedInitialState) {
// Это начальное состояние, данные ещё не загружены.
return CircularProgressIndicator(
color: Colors.white,
backgroundColor: Colors.white,
);
} else if (state is FeedLoadedState) {
// Данные загружены, можно строить экран.
return _buildFeedScreen(context, state);
} else {
// Другие состояния, если они есть.
return Container(); // Пустой контейнер для необработанных состояний.
}
},
);
}
_buildFeedScreen(BuildContext context, FeedLoadedState state) {
mediaQueryData = MediaQuery.of(context);
return SafeArea(
child: Scaffold(
backgroundColor: Colors.grey[200],
resizeToAvoidBottomInset: true,
body: SingleChildScrollView(
child: Container(
width: double.maxFinite,
decoration: BoxDecoration(color: Colors.grey[200]),
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SizedBox(height: 20),
_buildSearch(context),
SizedBox(height: 20),
_buildMenu(context, state),
SizedBox(height: 20),
_buildBlogPostList(context, state),
],
),
),
),
),
),
);
}
_buildSearch(BuildContext context) {
return Container(
margin: EdgeInsets.only(bottom: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.all(Radius.circular(12)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 2,
blurRadius: 5,
offset: Offset(0, 3),
),
],
),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
children: [
CustomSearchView(
hintText: "Поиск записей",
),
SizedBox(height: 10),
Row(
children: [
Flexible(
flex: 5,
child: CustomOutlinedButton(
text: "Найти запись",
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
),
),
SizedBox(width: 8), // Add some spacing between the buttons
Flexible(
flex: 1,
child: CustomOutlinedButton(
text: "+",
onPressed: () => GoRouter.of(context).goNamed('blogPostCreateScreen'),
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
),
),
],
),
],
),
),
);
}
_buildBlogPostList(BuildContext context, FeedLoadedState state) {
List<Widget> postWidgets = [];
if (state.posts != null) {
for (var post in state.posts!) {
postWidgets.add(_buildFeedEntry(post, context));
}
}
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: postWidgets,
);
}
_buildFeedEntry(post, BuildContext context) {
return Container(
margin: EdgeInsets.only(bottom: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.all(Radius.circular(12)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 2,
blurRadius: 5,
offset: Offset(0, 3),
),
],
),
child: Column(children: [
ListTile(
leading: CachedNetworkImage(
imageUrl: dotenv.env['STORAGE_URL']! + (post["author"]['profile_photo_path'] ?? ''),
imageBuilder: (context, imageProvider) => CircleAvatar(
backgroundImage: imageProvider,
radius: 25,
),
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => CircleAvatar(
child: Icon(Icons.person),
backgroundColor: Colors.white,
radius: 25,
),
),
title: Text(
post?['author']['name'] ?? '',
style: CustomTextStyles.titleMediumSemiBold,
),
subtitle: Text(
DateFormat('dd.MM.yyyy').format(DateTime.parse(post?['post']['updated_at'])),
style: theme.textTheme.bodyMedium,
),
onTap: () => GoRouter.of(context).goNamed(
'blogPostScreen',
extra: post?['post']['id'].toString(),
),
trailing: PopupMenuButton<String>(
onSelected: (value) => print("tap"),
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
PopupMenuItem<String>(
value: 'edit',
child: Text('Редактировать'),
),
PopupMenuItem<String>(
value: 'delete',
child: Text('Удалить'),
),
],
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Spacer(),
Align(
alignment: Alignment.center,
child: Text(
post?['post']['title'],
style: CustomTextStyles.titleMediumBlack,
),
),
Spacer(),
],
),
SizedBox(height: 8.0),
Text(
post?['post']['description'],
style: CustomTextStyles.bodyMediumBluegray800,
),
SizedBox(height: 16.0),
CachedNetworkImage(
imageUrl: dotenv.env['STORAGE_URL']! + (post?['post']['image'] ?? ''),
imageBuilder: (context, imageProvider) => Stack(
children: [
ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(8.0)),
child: Image(
image: imageProvider,
),
),
],
),
placeholder: (context, url) => CircularProgressIndicator(),
),
SizedBox(height: 16.0),
Row(children: [
Padding(
padding: EdgeInsets.only(left: 4),
child: Row(children: [
Padding(
padding: EdgeInsets.only(right: 4),
child: Icon(Icons.comment_outlined),
),
Text(
"Комментировать",
),
],),
),
Spacer(),
Row(children: [
Padding(
padding: const EdgeInsets.only(right: 4),
child: Icon(Icons.favorite_outline),
),
Text(
"Нравится",
),
],),
Spacer(),
Padding(
padding: EdgeInsets.only(right: 4),
child: Icon(Icons.share_outlined),
),
],),
],
),
),
],),);
}
Function onTapBack(BuildContext context) {
return () {
onTapArrowLeft(context);
};
}
onTapArrowLeft(BuildContext context) {
GoRouter.of(context).pop();
}
_buildMenu(BuildContext context, FeedLoadedState state) {
return Container(
padding: EdgeInsets.all(12),
margin: EdgeInsets.only(bottom: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.all(Radius.circular(12)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 2,
blurRadius: 5,
offset: Offset(0, 3),
),
],
),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: <Widget>[
ScrollItem(title: 'Все'),
ScrollItem(title: 'Рецепты'),
ScrollItem(title: 'Диеты'),
ScrollItem(title: 'Планы'),
ScrollItem(title: 'Записи'),
],
),
),
);
}
}