import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:sonnat/core/extensions/context_extension.dart'; import 'package:sonnat/core/extensions/string_extension.dart'; import 'package:sonnat/core/language/translator.dart'; import 'package:sonnat/core/select_language/cubit/select_language_cubit.dart'; import 'package:sonnat/core/select_language/screen/select_language_screen.dart'; import 'package:sonnat/core/utils/app_constants.dart'; import 'package:sonnat/core/utils/base_cubit_type.dart'; import 'package:sonnat/core/widgets/loading_list_widget.dart'; import 'package:sonnat/features/aabout_us/about_us_screen.dart'; import 'package:sonnat/features/posts/cubit/posts_cubit.dart'; import 'package:sonnat/features/posts/widgets/filter_item_widget.dart'; import 'package:sonnat/features/posts/widgets/post_item_widget.dart'; import 'package:sonnat/features/posts/widgets/search_widget.dart'; import 'package:sonnat/features/single_post/cubit/single_post_cubit.dart'; import 'package:sonnat/features/single_post/screen/single_post_screen.dart'; import 'package:sonnat/features/single_post/view_models/post.dart'; class PostsScreen extends StatefulWidget { final String title; final bool searchMode; const PostsScreen({super.key, required this.title, this.searchMode = false}); @override State createState() => _PostsScreenState(); } class _PostsScreenState extends State { late final PostsCubit _cubit; bool _loading = true; bool _getListFlag = false; late bool _searchMode; final ScrollController _controller = ScrollController(); int _selectedFilterIndex = 1; final List _filterList = [ const FilterItem(selected: false, title: 'پر تکرارترین‌ها'), const FilterItem(selected: true, title: 'مشابه‌ها'), const FilterItem(selected: false, title: 'محبوبترین‌ها'), const FilterItem(selected: false, title: 'برای‌ شما'), const FilterItem(selected: false, title: 'محبوبترین‌ها'), const FilterItem(selected: false, title: 'پر تکرارترین‌ها'), const FilterItem(selected: true, title: 'مشابه‌ها'), const FilterItem(selected: false, title: 'محبوبترین‌ها'), const FilterItem(selected: false, title: 'برای‌ شما'), const FilterItem(selected: false, title: 'محبوبترین‌ها'), ]; @override void initState() { _searchMode = widget.searchMode; _cubit = BlocProvider.of(context); _cubit.getData(); _controller.addListener(_onScroll); super.initState(); } void _onScroll() { final double maxScroll = _controller.position.maxScrollExtent; final double currentScroll = _controller.position.pixels; if (maxScroll - currentScroll <= 400) { if (_getListFlag) { _getListFlag = false; _cubit.getData(); } } } @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: BlocBuilder>( builder: (context, state) { switch (state.eventName!) { case PostsState.empty: break; case PostsState.data: _loading = false; _getListFlag = true; break; case PostsState.loading: _loading = true; break; case PostsState.loadingPagination: break; case PostsState.changeFilterIndex: _selectedFilterIndex = state.data; _loading = true; break; } return Column( children: [ SizedBox(height: context.height * 26 / AppConstants.instance.appHeight), Padding( padding: EdgeInsets.symmetric(horizontal: context.width * 26 / AppConstants.instance.appWidth), child: _searchMode ? Row( children: [ Expanded( child: SearchWidget( search: (query) { _cubit.search(query: query); }, ), ), SizedBox(width: context.width * 12 / AppConstants.instance.appWidth), GestureDetector( onTap: () { _cubit.clearSearch(); setState(() { _searchMode = !_searchMode; }); }, child: SvgPicture.asset( 'ic_back'.svgPath, ), ), ], ) : Stack( children: [ Align( alignment: AlignmentDirectional.centerStart, child: GestureDetector( onTap: _showOptions, child: SvgPicture.asset( 'ic_more'.svgPath, ), ), ), PositionedDirectional( start: context.width * 44 / AppConstants.instance.appWidth, child: GestureDetector( onTap: () { setState(() { _searchMode = !_searchMode; }); }, child: SvgPicture.asset('ic_rounded_search'.svgPath), ), ), Align( alignment: AlignmentDirectional.center, child: Padding( padding: const EdgeInsets.only(top: 8), child: Text( widget.title, style: const TextStyle( color: Color(0xff404966), fontSize: 22, ), ), ), ), Align( alignment: AlignmentDirectional.centerEnd, child: GestureDetector( onTap: () { Navigator.pop(context); }, child: SvgPicture.asset( 'ic_back'.svgPath, ), ), ), ], ), ), if (_searchMode) Padding( padding: EdgeInsets.only( top: context.height * 17 / AppConstants.instance.appHeight, left: context.width * 26 / AppConstants.instance.appWidth, right: context.width * 26 / AppConstants.instance.appWidth, ), child: Row( children: [ SvgPicture.asset( 'ic_search'.svgPath, colorFilter: const ColorFilter.mode( Color(0xff26237A), BlendMode.srcIn, ), ), const SizedBox(width: 8), Text( '${Translator.translate('search')}:', style: const TextStyle( color: Color(0xff26237A), fontSize: 16, ), ), const SizedBox(width: 8), Expanded( child: Text( _cubit.query, maxLines: 1, overflow: TextOverflow.ellipsis, style: const TextStyle( color: Color(0xff26237A), fontSize: 16, ), ), ), const Spacer(), Text( _loading ? 'در حال جستجو' : _cubit.query.isEmpty ? '' : _cubit.searchedList.isEmpty ? 'موردی یافت نشد' : '${_cubit.searchedList.length} مورد یافت شد', style: const TextStyle( color: Color(0xff636E88), fontSize: 12, ), ) ], ), ), SizedBox(height: context.height * 35 / AppConstants.instance.appHeight), SizedBox( height: context.height * 31 / AppConstants.instance.appHeight, child: ListView.builder( padding: EdgeInsetsDirectional.only(start: context.width * 26 / AppConstants.instance.appWidth), itemBuilder: (context, index) { return GestureDetector( onTap: () { _cubit.changeFilter(index); }, child: FilterItemWidget( title: _filterList[index].title, selected: index == _selectedFilterIndex, ), ); }, itemCount: _filterList.length, scrollDirection: Axis.horizontal, ), ), SizedBox(height: context.height * 26 / AppConstants.instance.appHeight), if (_loading) const Expanded(child: LoadingListWidget()) else Expanded( child: ListView.builder( controller: _controller, itemBuilder: (context, index) { if (_searchMode) { return GestureDetector( onTap: () => _clickOnPost(_cubit.searchedList[index]), child: PostItemWidget(post: _cubit.searchedList[index]), ); } return GestureDetector( onTap: () => _clickOnPost(_cubit.postList[index]), child: PostItemWidget(post: _cubit.postList[index]), ); }, itemCount: _searchMode ? _cubit.searchedList.length : _cubit.postList.length, ), ) ], ); }, ), ), ); } void _clickOnPost(Post post) { Navigator.push( context, MaterialPageRoute( builder: (context) { return BlocProvider( child: SinglePostScreen(post: post), create: (context) => SinglePostCubit(), ); }, ), ); } void _showOptions() { showModalBottomSheet( context: context, backgroundColor: Colors.transparent, builder: (context) { return Container( height: 120, width: context.width, decoration: BoxDecoration( color: Colors.white, border: Border.all(color: Colors.white, width: 0.2), borderRadius: const BorderRadius.only( topLeft: Radius.circular(16), topRight: Radius.circular(16), ), ), padding: const EdgeInsets.only( top: 16, left: 4, right: 4, ), child: Column( children: [ MoreOptionsWidget( title: Translator.translate('about_us'), onTap: () { Navigator.pop(context); Navigator.push( context, MaterialPageRoute( builder: (context) { return const AboutUsScreen(); }, ), ); }, ), const SizedBox(height: 8), Container( width: context.width, height: 1, color: const Color(0xffD3D8E9), ), const SizedBox(height: 8), MoreOptionsWidget( title: Translator.translate('select_language'), onTap: () { Navigator.pop(context); Navigator.push( context, MaterialPageRoute( builder: (context) { return BlocProvider( child: const SelectLanguageScreen(), create: (context) => SelectLanguageCubit(), ); }, ), ); }, ), ], ), ); }, ); } } class FilterItem { final bool selected; final String title; const FilterItem({required this.selected, required this.title}); } class MoreOptionsWidget extends StatelessWidget { final String title; final Function() onTap; const MoreOptionsWidget({super.key, required this.title, required this.onTap}); @override Widget build(BuildContext context) { return GestureDetector( onTap: onTap, child: Text( title, style: const TextStyle( color: Color(0xff222D4E), fontSize: 16, fontWeight: FontWeight.bold, ), ), ); } }