import 'package:easy_debounce/easy_debounce.dart'; import 'package:eatvio_app/core/const.dart'; import 'package:eatvio_app/core/views/cubit/views_cubit.dart'; import 'package:eatvio_app/core/widgets/add_item_button.dart'; import 'package:eatvio_app/core/widgets/custom_search_bar.dart'; import 'package:eatvio_app/features/create_diet/presentation/create_diet_screen.dart'; import 'package:eatvio_app/features/create_plan/presentation/create_plan_screen.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/consultants_cubit/consultants_cubit.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/profile_cubit/profile_cubit.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/profile_cubit/profile_state.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/blog_posts.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/chip_group.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/consultants.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/diets.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/plans.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/tags_modal_widget.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/plans_cubit/plans_cubit.dart'; import 'package:eatvio_app/core/locator_service.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:eatvio_app/features/create_recipe/presentation/pages/recipe_create_screen.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_native_splash/flutter_native_splash.dart'; import 'package:go_router/go_router.dart'; import '../widgets/recipes.dart'; class FeedScreen extends StatelessWidget { const FeedScreen({super.key}); @override Widget build(BuildContext context) { return MultiBlocProvider( providers: [ BlocProvider(create: (context) => sl()..loadRecipesList()), BlocProvider(create: (context) => sl()..getProfile()), BlocProvider(create: (context) => sl()..loadDiets()), if (!hidePlans) BlocProvider(create: (context) => sl()..loadPlans()), BlocProvider(create: (context) => sl()..getConsultants()), ], child: const FeedScreenContent(), ); } } class FeedScreenContent extends StatefulWidget { const FeedScreenContent({super.key}); @override State createState() => _FeedScreenContentState(); } class _FeedScreenContentState extends State { final postsController = TextEditingController(); final recipesController = TextEditingController(); final dietsController = TextEditingController(); final plansController = TextEditingController(); final consultantsController = TextEditingController(); late final List chipsLabelList; int _selectedChipIndex = 0; final blogPostsScrollController = ScrollController(); final recipesScrollController = ScrollController(); final dietsScrollController = ScrollController(); final plansScrollController = ScrollController(); final consultantsScrollController = ScrollController(); @override void initState() { chipsLabelList = hidePlans ? ['Все', 'Рецепты', 'Диеты', 'Консультанты'] : ['Все', 'Рецепты', 'Диеты', 'Планы питания', 'Консультанты']; consultantsScrollController.addListener(_onScrollConsultants); super.initState(); } void _onScrollConsultants() { if (consultantsScrollController.offset >= consultantsScrollController.position.maxScrollExtent && !consultantsScrollController.position.outOfRange) {} } @override void dispose() { blogPostsScrollController.dispose(); recipesScrollController.dispose(); dietsScrollController.dispose(); plansScrollController.dispose(); consultantsScrollController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { FlutterNativeSplash.remove(); return Scaffold( floatingActionButton: _selectedChipIndex == 1 ? FloatingActionButton.small( heroTag: 'recipesTagsFilter', backgroundColor: appTheme.blueA400, shape: const CircleBorder(), child: const Icon(Icons.filter_list_rounded, color: Colors.white), onPressed: () async { final recipesCubit = context.read(); await showModalBottomSheet( useRootNavigator: true, context: context, builder: (context) => TagsModalWidget(recipesCubit: recipesCubit), ); recipesCubit.loadRecipesList(); }, ) : null, appBar: AppBar(backgroundColor: Colors.white, toolbarHeight: 0), backgroundColor: Colors.grey.shade200, body: NestedScrollView( controller: switch (_selectedChipIndex) { 0 => blogPostsScrollController, 1 => recipesScrollController, 2 => dietsScrollController, 3 when !hidePlans => plansScrollController, 3 when hidePlans => consultantsScrollController, 4 when !hidePlans => consultantsScrollController, _ => blogPostsScrollController, }, headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { return [ BlocBuilder( builder: (context, state) { return SliverAppBar( shape: const RoundedRectangleBorder(borderRadius: BorderRadius.vertical(bottom: Radius.circular(12))), backgroundColor: Colors.white, foregroundColor: Colors.white, automaticallyImplyLeading: false, stretchTriggerOffset: 1, floating: true, snap: true, scrolledUnderElevation: 0, bottom: PreferredSize( preferredSize: Size(MediaQuery.of(context).size.width, 32), child: ChipGroup( selectedChipIndex: _selectedChipIndex, chipsLabelList: chipsLabelList, setSelectedChipIndex: (index) { setState(() { _selectedChipIndex = index; }); }, ), ), title: Row( children: [ CustomSearchBar( searchController: switch (_selectedChipIndex) { 1 => recipesController, 2 => dietsController, 3 when !hidePlans => plansController, 3 when hidePlans => consultantsController, 4 when !hidePlans => consultantsController, _ => postsController, }, onChanged: (query) { if (query.length > 2) { EasyDebounce.debounce('searchFeed', const Duration(milliseconds: 500), () { switch (_selectedChipIndex) { case 0: context.read().loadFeedBlogPostList(query: query); break; case 1: context.read().loadRecipesList(query: query); break; case 2: context.read().loadDiets(query: query); break; case 3 when !hidePlans: context.read().loadPlans(query: query); break; case 3 when hidePlans: case 4 when !hidePlans: context.read().getConsultants(); break; } }); } else { EasyDebounce.debounce('searchFeed', const Duration(milliseconds: 500), () { switch (_selectedChipIndex) { case 0: context.read().loadFeedBlogPostList(); break; case 1: context.read().loadRecipesList(); break; case 2: context.read().loadDiets(); break; case 3 when !hidePlans: context.read().loadPlans(); break; case 3 when hidePlans: case 4 when !hidePlans: context.read().getConsultants(); break; } }); } }, ), const SizedBox(width: 12), switch (_selectedChipIndex) { 1 => AddItemButton(onTap: () => GoRouter.of(context).pushNamed(RecipeCreateScreen.name)), 2 => AddItemButton( onTap: state.profile?.roles.contains('consultant') ?? false ? () async { await GoRouter.of(context).pushNamed(CreateDietScreen.name); } : null, ), 3 when !hidePlans => AddItemButton( onTap: state.profile?.roles.contains('consultant') ?? false ? () => GoRouter.of(context).pushNamed(CreatePlanScreen.name) : null, ), _ => const AddItemButton(), }, ], ), ); }, ), ]; }, body: switch (_selectedChipIndex) { 0 => BlogPosts(handleVisibility: context.read().handleVisibility), 1 => Recipes(handleVisibility: context.read().handleVisibility), 2 => Diets(handleVisibility: context.read().handleVisibility), 3 when !hidePlans => Plans(handleVisibility: context.read().handleVisibility), 3 when hidePlans => const Consultants(), 4 when !hidePlans => const Consultants(), _ => Center(child: Text(chipsLabelList[_selectedChipIndex])), }, ), ); } } enum ViewableContentType { plans, posts, diets, recipes; String getStringifiedVersion() => switch (this) { ViewableContentType.plans => 'plans', ViewableContentType.posts => 'blog_posts', ViewableContentType.diets => 'diets', ViewableContentType.recipes => 'recipes', }; }