Skip to content

Commit bf72ea0

Browse files
committed
✨ (feat) Add user sort feature.
1. User sort feature added on user search page.
1 parent 0d5dec1 commit bf72ea0

File tree

4 files changed

+193
-38
lines changed

4 files changed

+193
-38
lines changed

lib/helper/enum.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,12 @@ enum TweetType{
77
Tweet,
88
Detail,
99
Reply
10+
}
11+
12+
enum SortUser{
13+
ByVerified,
14+
ByAlphabetically,
15+
ByNewest,
16+
ByOldest,
17+
ByMaxFollower
1018
}

lib/page/search/SearchPage.dart

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,11 @@ class SearchPage extends StatefulWidget {
1919
}
2020

2121
class _SearchPageState extends State<SearchPage> {
22-
TextEditingController textController;
23-
2422
@override
2523
void initState() {
26-
textController = TextEditingController();
2724
WidgetsBinding.instance.addPostFrameCallback((_) {
2825
final state = Provider.of<SearchState>(context);
29-
state.filterByUsername("");
26+
state.resetFilterList();
3027
});
3128
super.initState();
3229
}
@@ -72,30 +69,32 @@ class _SearchPageState extends State<SearchPage> {
7269
@override
7370
Widget build(BuildContext context) {
7471
var state = Provider.of<SearchState>(context);
72+
7573
var list = state.userlist;
7674
return Scaffold(
77-
appBar: CustomAppBar(
78-
scaffoldKey: widget.scaffoldKey,
79-
textController: textController,
80-
icon: AppIcon.settings,
81-
onActionPressed: onSettingIconPressed,
82-
onSearchChanged: (text) {
83-
state.filterByUsername(text);
84-
},
85-
),
86-
body: RefreshIndicator(
87-
onRefresh: () async {
88-
state.getDataFromDatabase();
89-
return Future.value(true);
90-
},
91-
child: ListView.separated(
92-
physics: BouncingScrollPhysics(),
93-
itemBuilder: (context, index) => _userTile(list[index]),
94-
separatorBuilder: (_, index) => Divider(
95-
height: 0,
96-
),
97-
itemCount: list.length,
75+
appBar: CustomAppBar(
76+
scaffoldKey: widget.scaffoldKey,
77+
icon: AppIcon.settings,
78+
onActionPressed: onSettingIconPressed,
79+
onSearchChanged: (text) {
80+
state.filterByUsername(text);
81+
},
82+
),
83+
body: RefreshIndicator(
84+
onRefresh: () async {
85+
state.getDataFromDatabase();
86+
return Future.value(true);
87+
},
88+
child: ListView.separated(
89+
addAutomaticKeepAlives: false,
90+
physics: BouncingScrollPhysics(),
91+
itemBuilder: (context, index) => _userTile(list[index]),
92+
separatorBuilder: (_, index) => Divider(
93+
height: 0,
9894
),
99-
));
95+
itemCount: list?.length ?? 0,
96+
),
97+
),
98+
);
10099
}
101100
}

lib/page/settings/accountSettings/contentPrefrences/trends/trendsPage.dart

Lines changed: 96 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,97 @@
11
import 'package:flutter/material.dart';
2+
import 'package:flutter_twitter_clone/helper/enum.dart';
23
import 'package:flutter_twitter_clone/helper/theme.dart';
3-
import 'package:flutter_twitter_clone/page/settings/widgets/headerWidget.dart';
44
import 'package:flutter_twitter_clone/page/settings/widgets/settingsRowWidget.dart';
5+
import 'package:flutter_twitter_clone/state/searchState.dart';
56
import 'package:flutter_twitter_clone/widgets/customAppBar.dart';
67
import 'package:flutter_twitter_clone/widgets/customWidgets.dart';
8+
import 'package:flutter_twitter_clone/widgets/newWidget/title_text.dart';
9+
import 'package:provider/provider.dart';
710

811
class TrendsPage extends StatelessWidget {
9-
const TrendsPage({Key key}) : super(key: key);
12+
String sortBy = "";
13+
14+
TrendsPage({Key key}) : super(key: key);
15+
16+
void openBottomSheet(
17+
BuildContext context, double height, Widget child) async {
18+
await showModalBottomSheet(
19+
backgroundColor: Colors.transparent,
20+
context: context,
21+
builder: (context) {
22+
return Container(
23+
height: height,
24+
decoration: BoxDecoration(
25+
color: TwitterColor.white,
26+
borderRadius: BorderRadius.only(
27+
topLeft: Radius.circular(15),
28+
topRight: Radius.circular(15),
29+
),
30+
),
31+
child: child,
32+
);
33+
},
34+
);
35+
}
36+
37+
void openUserSortSettings(BuildContext context) {
38+
openBottomSheet(
39+
context,
40+
340,
41+
Column(
42+
children: <Widget>[
43+
SizedBox(height: 5),
44+
Container(
45+
width: 40,
46+
height: 5,
47+
decoration: BoxDecoration(
48+
color: TwitterColor.paleSky50,
49+
borderRadius: BorderRadius.circular(10),
50+
),
51+
),
52+
Padding(
53+
padding: EdgeInsets.symmetric(vertical: 10),
54+
child: TitleText('Sort user list'),
55+
),
56+
Divider(height: 0),
57+
_row(context, "Verified user first", SortUser.ByVerified),
58+
Divider(height: 0),
59+
_row(context, "alphabetically", SortUser.ByAlphabetically),
60+
Divider(height: 0),
61+
_row(context, "Newest user first", SortUser.ByNewest),
62+
Divider(height: 0),
63+
_row(context, "Oldest user first", SortUser.ByOldest),
64+
Divider(height: 0),
65+
_row(context, "User with max follower", SortUser.ByMaxFollower),
66+
],
67+
),
68+
);
69+
}
70+
71+
Widget _row(BuildContext context, String text, SortUser sortBy) {
72+
final state = Provider.of<SearchState>(context);
73+
return Padding(
74+
padding: EdgeInsets.symmetric(vertical: 0, horizontal: 5),
75+
child: RadioListTile<SortUser>(
76+
value: sortBy,
77+
activeColor: TwitterColor.dodgetBlue,
78+
groupValue: state.sortBy,
79+
onChanged: (val) {
80+
state.updateFilterProfrence = val;
81+
Navigator.pop(context);
82+
},
83+
title: Text(text, style: subtitleStyle),
84+
controlAffinity: ListTileControlAffinity.trailing,
85+
),
86+
);
87+
}
1088

1189
@override
1290
Widget build(BuildContext context) {
91+
WidgetsBinding.instance.addPostFrameCallback((_) {
92+
final state = Provider.of<SearchState>(context);
93+
sortBy = state.selectedFilter;
94+
});
1395
return Scaffold(
1496
backgroundColor: TwitterColor.white,
1597
appBar: CustomAppBar(
@@ -21,6 +103,14 @@ class TrendsPage extends StatelessWidget {
21103
body: ListView(
22104
physics: BouncingScrollPhysics(),
23105
children: <Widget>[
106+
SettingRowWidget(
107+
"Search Filter",
108+
subtitle: sortBy,
109+
onPressed: () {
110+
openUserSortSettings(context);
111+
},
112+
showDivider: false,
113+
),
24114
SettingRowWidget(
25115
"Trends location",
26116
navigateTo: null,
@@ -29,11 +119,12 @@ class TrendsPage extends StatelessWidget {
29119
),
30120
SettingRowWidget(
31121
null,
32-
subtitle: 'You can see what\'s trending in a specfic location by selecting which location appears in your Trending tab.',
33-
navigateTo:null,
122+
subtitle:
123+
'You can see what\'s trending in a specfic location by selecting which location appears in your Trending tab.',
124+
navigateTo: null,
34125
showDivider: false,
35126
vPadding: 12,
36-
),
127+
),
37128
],
38129
),
39130
);

lib/state/searchState.dart

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import 'package:firebase_database/firebase_database.dart';
2+
import 'package:flutter_twitter_clone/helper/enum.dart';
23
import 'package:flutter_twitter_clone/helper/utility.dart';
34
import 'package:flutter_twitter_clone/model/user.dart';
45
import 'appState.dart';
56

67
class SearchState extends AppState {
78
bool isBusy = false;
8-
9+
SortUser sortBy = SortUser.ByNewest;
910
List<User> _userFilterlist;
1011
List<User> _userlist;
1112

@@ -17,7 +18,7 @@ class SearchState extends AppState {
1718
}
1819
}
1920

20-
/// get [User list] from firebase realtime kDatabase
21+
/// get [User list] from firebase realtime Database
2122
void getDataFromDatabase() {
2223
try {
2324
isBusy = true;
@@ -34,13 +35,13 @@ class SearchState extends AppState {
3435
_userlist.add(model);
3536
_userFilterlist.add(model);
3637
});
37-
_userFilterlist.sort((x,y) => y.followers.compareTo(x.followers));
38+
_userFilterlist
39+
.sort((x, y) => y.followers.compareTo(x.followers));
3840
}
3941
} else {
4042
_userlist = null;
4143
}
4244
isBusy = false;
43-
notifyListeners();
4445
},
4546
);
4647
} catch (error) {
@@ -49,17 +50,32 @@ class SearchState extends AppState {
4950
}
5051
}
5152

53+
/// It will reset filter list
54+
/// If user has use search filter and change screen and came back to search screen It will reset user list.
55+
/// This function call when search page open.
56+
void resetFilterList() {
57+
if (_userlist != null && _userlist.length != _userFilterlist.length) {
58+
_userFilterlist = List.from(_userlist);
59+
_userFilterlist.sort((x, y) => y.followers.compareTo(x.followers));
60+
notifyListeners();
61+
}
62+
}
63+
64+
/// This function call when search fiels text change.
65+
/// User list on search field get filter by `name` string
5266
void filterByUsername(String name) {
53-
if (name.isEmpty && _userlist != null) {
67+
if (name.isEmpty &&
68+
_userlist != null &&
69+
_userlist.length != _userFilterlist.length) {
5470
_userFilterlist = List.from(_userlist);
5571
}
5672
// return if userList is empty or null
5773
if (_userlist == null && _userlist.isEmpty) {
5874
print("Empty userList");
5975
return;
6076
}
61-
// filter userlist on the basis of username
62-
else {
77+
// sortBy userlist on the basis of username
78+
else if (name != null) {
6379
_userFilterlist = _userlist
6480
.where((x) =>
6581
x.userName != null &&
@@ -68,4 +84,45 @@ class SearchState extends AppState {
6884
}
6985
notifyListeners();
7086
}
87+
88+
/// Sort user list on search user page.
89+
set updateFilterProfrence(SortUser val) {
90+
sortBy = val;
91+
notifyListeners();
92+
}
93+
94+
String get selectedFilter {
95+
switch (sortBy) {
96+
case SortUser.ByAlphabetically:
97+
_userFilterlist.sort((x, y) => x.displayName.compareTo(y.displayName));
98+
notifyListeners();
99+
return "alphabetically";
100+
101+
case SortUser.ByMaxFollower:
102+
_userFilterlist.sort((x, y) => y.followers.compareTo(x.followers));
103+
notifyListeners();
104+
return "User with max follower";
105+
106+
case SortUser.ByNewest:
107+
_userFilterlist.sort((x, y) =>
108+
DateTime.parse(y.createdAt).compareTo(DateTime.parse(x.createdAt)));
109+
notifyListeners();
110+
return "Newest user first";
111+
112+
case SortUser.ByOldest:
113+
_userFilterlist.sort((x, y) =>
114+
DateTime.parse(x.createdAt).compareTo(DateTime.parse(y.createdAt)));
115+
notifyListeners();
116+
return "Oldest user first";
117+
118+
case SortUser.ByVerified:
119+
_userFilterlist.sort((x, y) =>
120+
y.isVerified.toString().compareTo(x.isVerified.toString()));
121+
notifyListeners();
122+
return "Verified user first";
123+
124+
default:
125+
return "Unknown";
126+
}
127+
}
71128
}

0 commit comments

Comments
 (0)