|
|
@ -8,7 +8,9 @@ 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/utils/initializer.dart'; |
|
|
|
import 'package:sonnat/core/widgets/loading_list_widget.dart'; |
|
|
|
import 'package:sonnat/core/widgets/more_options_widget.dart'; |
|
|
|
import 'package:sonnat/features/about_us/about_us_screen.dart'; |
|
|
|
import 'package:sonnat/features/posts/cubit/posts_cubit.dart'; |
|
|
|
import 'package:sonnat/features/posts/widgets/filter_item_widget.dart'; |
|
|
@ -92,179 +94,205 @@ class _PostsScreenState extends State<PostsScreen> { |
|
|
|
_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, |
|
|
|
return CustomScrollView( |
|
|
|
controller: _controller, |
|
|
|
slivers: [ |
|
|
|
SliverAppBar( |
|
|
|
floating: true, |
|
|
|
elevation: 0, |
|
|
|
backgroundColor: const Color(0xffE7E7F5), |
|
|
|
automaticallyImplyLeading: false, |
|
|
|
forceElevated: false, |
|
|
|
shadowColor: Colors.transparent, |
|
|
|
bottom: PreferredSize( |
|
|
|
preferredSize: const Size.fromHeight(95), |
|
|
|
child: 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: RotatedBox( |
|
|
|
quarterTurns: |
|
|
|
Initializer.instance.getTextDirection() == TextDirection.ltr ? 90 : 0, |
|
|
|
child: SvgPicture.asset('ic_back'.svgPath), |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
PositionedDirectional( |
|
|
|
start: context.width * 44 / AppConstants.instance.appWidth, |
|
|
|
child: GestureDetector( |
|
|
|
onTap: () { |
|
|
|
setState(() { |
|
|
|
_searchMode = !_searchMode; |
|
|
|
}); |
|
|
|
}, |
|
|
|
child: SvgPicture.asset('ic_rounded_search'.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, |
|
|
|
), |
|
|
|
Align( |
|
|
|
alignment: AlignmentDirectional.center, |
|
|
|
child: Padding( |
|
|
|
padding: const EdgeInsets.only(top: 8), |
|
|
|
child: Text( |
|
|
|
widget.title, |
|
|
|
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(0xff404966), |
|
|
|
fontSize: 22, |
|
|
|
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, |
|
|
|
), |
|
|
|
) |
|
|
|
], |
|
|
|
), |
|
|
|
Align( |
|
|
|
alignment: AlignmentDirectional.centerEnd, |
|
|
|
child: GestureDetector( |
|
|
|
), |
|
|
|
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: () { |
|
|
|
Navigator.pop(context); |
|
|
|
_cubit.changeFilter(index); |
|
|
|
}, |
|
|
|
child: SvgPicture.asset( |
|
|
|
'ic_back'.svgPath, |
|
|
|
child: FilterItemWidget( |
|
|
|
title: _filterList[index].title, |
|
|
|
selected: index == _selectedFilterIndex, |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
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, |
|
|
|
), |
|
|
|
); |
|
|
|
}, |
|
|
|
itemCount: _filterList.length, |
|
|
|
scrollDirection: Axis.horizontal, |
|
|
|
), |
|
|
|
), |
|
|
|
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 * 26 / AppConstants.instance.appHeight), |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
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); |
|
|
|
), |
|
|
|
SliverList( |
|
|
|
delegate: SliverChildBuilderDelegate( |
|
|
|
(context, index) { |
|
|
|
if (_loading) { |
|
|
|
return const Expanded(child: LoadingListWidget()); |
|
|
|
} |
|
|
|
return ListView.builder( |
|
|
|
shrinkWrap: true, |
|
|
|
physics: NeverScrollableScrollPhysics(), |
|
|
|
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]), |
|
|
|
); |
|
|
|
}, |
|
|
|
child: FilterItemWidget( |
|
|
|
title: _filterList[index].title, |
|
|
|
selected: index == _selectedFilterIndex, |
|
|
|
), |
|
|
|
itemCount: _searchMode ? _cubit.searchedList.length : _cubit.postList.length, |
|
|
|
); |
|
|
|
}, |
|
|
|
itemCount: _filterList.length, |
|
|
|
scrollDirection: Axis.horizontal, |
|
|
|
childCount: 1, |
|
|
|
), |
|
|
|
), |
|
|
|
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, |
|
|
|
), |
|
|
|
) |
|
|
|
], |
|
|
|
); |
|
|
|
}, |
|
|
@ -362,25 +390,3 @@ class FilterItem { |
|
|
|
|
|
|
|
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, |
|
|
|
), |
|
|
|
), |
|
|
|
); |
|
|
|
} |
|
|
|
} |