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_bottom_bar.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( create: (context) => FeedBloc(FeedState(myProfileModelObj: FeedModel())) ..add(FeedInitialEvent()), child: FeedScreen()); } Widget build(BuildContext context) { return BlocBuilder( 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 Scaffold( backgroundColor: Colors.grey[200], resizeToAvoidBottomInset: true, body: SafeArea( child: SingleChildScrollView( child: Container( width: double.maxFinite, decoration: BoxDecoration(color: Colors.grey[200]), child: Padding( padding: EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ _buildSearch(), SizedBox(height: 20), _buildMenu(context, state), SizedBox(height: 20), _buildBlogPostList(context, state) ], ), ), ), ), ), bottomNavigationBar: _buildBottomBar(context), ); } _buildSearch() { 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: "+", buttonStyle: CustomButtonStyles.outlinePrimaryTL15, ), ), ], ) ], ), ), ); } _buildBlogPostList(BuildContext context, FeedLoadedState state) { List 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: () => Navigator.pushNamed( context, AppRoutes.blogPostScreen, arguments: post?['post']['id'].toString(), ), trailing: PopupMenuButton( onSelected: (value) => print("tap"), itemBuilder: (BuildContext context) => >[ PopupMenuItem( value: 'edit', child: Text('Редактировать'), ), PopupMenuItem( 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); }; } _buildBottomBar(BuildContext context) { return CustomBottomBar(onChanged: (BottomBarEnum type) {}); } onTapArrowLeft(BuildContext context) { NavigatorService.goBack(); } _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: [ ScrollItem(title: 'Все'), ScrollItem(title: 'Рецепты'), ScrollItem(title: 'Диеты'), ScrollItem(title: 'Планы'), ScrollItem(title: 'Записи'), ], ), ), ); } }