import 'bloc/feed_bloc.dart'; import 'models/feed_model.dart'; import 'package:eatvio_app/core/app_export.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_subtitle.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; import 'package:eatvio_app/widgets/custom_bottom_bar.dart'; import 'package:cached_network_image/cached_network_image.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 _buildSetingsScreen(context, state); } else { // Другие состояния, если они есть. return Container(); // Пустой контейнер для необработанных состояний. } }, ); } _buildSetingsScreen(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: 10), Container( 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: CustomAppBar( height: 54.v, leadingWidth: 28.h, leading: AppbarLeadingImage( imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only( left: 16.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context), ), title: Padding( padding: EdgeInsets.only(left: 20.h), child: Row( children: [ AppbarSubtitle( text: "Лента", margin: EdgeInsets.only( left: 80.h, top: 12.v, bottom: 9.v), ), Spacer(), Padding( padding: const EdgeInsets.only(right: 20.0), child: GestureDetector( onTap: () => Navigator.pushNamed( context, AppRoutes.blogPostCreateScreen, ), child: Icon(Icons.create_outlined)), ) ], ), ), ), ), SizedBox(height: 20), _buildBlogPostList(context, state) ], ), ), ), ), bottomNavigationBar: _buildBottomBar(context), ), ); } _buildBlogPostList(BuildContext context, FeedLoadedState state) { return ListView.builder( shrinkWrap: true, // Add this line itemCount: state.posts?.length ?? 0, itemBuilder: (context, index) { final post = state.posts?[index]; print(post); 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['image'], 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?['title'] ?? '', style: CustomTextStyles.titleMediumSemiBold, ), subtitle: Text( DateFormat('dd.MM.yyyy') .format(DateTime.parse(post?['updated_at'])), style: theme.textTheme.bodyMedium, ), onTap: () => Navigator.pushNamed( context, AppRoutes.blogPostScreen, arguments: 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?['title'], style: CustomTextStyles.titleMediumBlack, ), ), Spacer(), ], ), SizedBox(height: 8.0), Text( post?['description'], style: CustomTextStyles.bodyMediumBluegray800, ), SizedBox(height: 16.0), CachedNetworkImage( imageUrl: dotenv.env['STORAGE_URL']! + (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(); } }