feat: Added fixes and user_list_view.dart

This commit is contained in:
Deven Joshi
2021-01-25 20:24:22 +05:30
parent 0f7a16dc6d
commit 5594a9a116
4 changed files with 429 additions and 516 deletions
@@ -185,8 +185,7 @@ class _NewChatScreenState extends State<NewChatScreen> {
), ),
padding: const EdgeInsets.only(left: 24), padding: const EdgeInsets.only(left: 24),
child: Padding( child: Padding(
padding: padding: const EdgeInsets.fromLTRB(8, 4, 12, 4),
const EdgeInsets.fromLTRB(8, 4, 12, 4),
child: Text( child: Text(
user.name, user.name,
maxLines: 1, maxLines: 1,
@@ -291,8 +290,7 @@ class _NewChatScreenState extends State<NewChatScreen> {
child: _showUserList child: _showUserList
? GestureDetector( ? GestureDetector(
behavior: HitTestBehavior.opaque, behavior: HitTestBehavior.opaque,
onPanDown: (_) => onPanDown: (_) => FocusScope.of(context).unfocus(),
FocusScope.of(context).unfocus(),
child: UsersBloc( child: UsersBloc(
child: UserListView( child: UserListView(
selectedUsers: _selectedUsers, selectedUsers: _selectedUsers,
@@ -342,8 +340,7 @@ class _NewChatScreenState extends State<NewChatScreen> {
children: [ children: [
Padding( Padding(
padding: padding:
const EdgeInsets.all( const EdgeInsets.all(24),
24),
child: StreamSvgIcon.search( child: StreamSvgIcon.search(
size: 96, size: 96,
color: Colors.grey, color: Colors.grey,
@@ -360,8 +357,7 @@ class _NewChatScreenState extends State<NewChatScreen> {
.of(context) .of(context)
.colorTheme .colorTheme
.black .black
.withOpacity( .withOpacity(.5)),
.5)),
), ),
], ],
), ),
@@ -415,7 +411,8 @@ class _NewChatScreenState extends State<NewChatScreen> {
), ),
), ),
); );
}), },
),
); );
} }
} }
@@ -159,15 +159,7 @@ class _ChannelListViewState extends State<ChannelListView>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (!widget.pullToRefresh) { var child = ChannelListCore(
_channelListController.loadData();
}
return RefreshIndicator(
onRefresh: () async {
_channelListController.loadData();
},
child: ChannelListCore(
channelListController: _channelListController, channelListController: _channelListController,
listBuilder: (context, list) { listBuilder: (context, list) {
return _buildListView(list); return _buildListView(list);
@@ -185,8 +177,18 @@ class _ChannelListViewState extends State<ChannelListView>
options: widget.options, options: widget.options,
sort: widget.sort, sort: widget.sort,
filter: widget.filter, filter: widget.filter,
),
); );
if (!widget.pullToRefresh) {
return child;
} else {
return RefreshIndicator(
onRefresh: () async {
_channelListController.loadData();
},
child: child,
);
}
} }
Widget _buildListView( Widget _buildListView(
@@ -140,87 +140,70 @@ class _UserListViewState extends State<UserListView>
with WidgetsBindingObserver { with WidgetsBindingObserver {
bool get _isListView => widget.crossAxisCount == 1; bool get _isListView => widget.crossAxisCount == 1;
@override UserListController _userListController = UserListController();
void initState() {
super.initState();
final usersBloc = UsersBloc.of(context);
usersBloc.queryUsers(
filter: widget.filter,
sort: widget.sort,
pagination: widget.pagination,
options: widget.options,
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final usersBloc = UsersBloc.of(context); var child = UserListCore(
errorBuilder: (err) {
if (!widget.pullToRefresh) { return _buildError(err);
return _buildListView(usersBloc); },
} emptyBuilder: (context) {
return _buildEmpty();
return RefreshIndicator( },
onRefresh: () async { loadingBuilder: (context) {
return usersBloc.queryUsers( return LayoutBuilder(
filter: widget.filter, builder: (context, viewportConstraints) {
sort: widget.sort, return SingleChildScrollView(
options: widget.options, physics: AlwaysScrollableScrollPhysics(),
pagination: widget.pagination, child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: Center(
child: CircularProgressIndicator(),
),
),
); );
}, },
child: _buildListView(usersBloc),
); );
},
listBuilder: (context, list) {
return _buildListView(list);
},
pagination: widget.pagination,
options: widget.options,
sort: widget.sort,
filter: widget.filter,
groupAlphabetically: widget.groupAlphabetically,
userListController: _userListController,
);
if (!widget.pullToRefresh) {
return child;
} else {
return RefreshIndicator(
onRefresh: () async {
_userListController.loadData();
},
child: child,
);
}
} }
bool get isListAlreadySorted => bool get isListAlreadySorted =>
widget.sort?.any((e) => e.field == 'name' && e.direction == 1) ?? false; widget.sort?.any((e) => e.field == 'name' && e.direction == 1) ?? false;
Stream<List<ListItem>> _buildUserStream( Widget _buildError(Error error) {
UsersBlocState usersBlocState, print((error).stackTrace);
) {
return usersBlocState.usersStream.map(
(users) {
if (widget.groupAlphabetically) {
var temp = users;
if (!isListAlreadySorted) {
temp = users..sort((curr, next) => curr.name.compareTo(next.name));
}
final groupedUsers = <String, List<User>>{};
for (var e in temp) {
final alphabet = e.name[0]?.toUpperCase();
groupedUsers[alphabet] = [...groupedUsers[alphabet] ?? [], e];
}
final items = <ListItem>[];
for (var key in groupedUsers.keys) {
items.add(ListHeaderItem(key));
items.addAll(groupedUsers[key].map((e) => ListUserItem(e)));
}
return items;
}
return users.map((e) => ListUserItem(e)).toList();
},
);
}
StreamBuilder<List<ListItem>> _buildListView(
UsersBlocState usersBlocState,
) {
return StreamBuilder(
stream: _buildUserStream(usersBlocState),
builder: (context, snapshot) {
if (snapshot.hasError) {
if (snapshot.error is Error) {
print((snapshot.error as Error).stackTrace);
}
if (widget.errorBuilder != null) { if (widget.errorBuilder != null) {
return widget.errorBuilder(snapshot.error); return widget.errorBuilder(error);
} }
var message = snapshot.error.toString(); var message = error.toString();
if (snapshot.error is DioError) { if (error is DioError) {
final dioError = snapshot.error as DioError; final dioError = error as DioError;
if (dioError.type == DioErrorType.RESPONSE) { if (dioError.type == DioErrorType.RESPONSE) {
message = dioError.message; message = dioError.message;
} else { } else {
@@ -255,12 +238,7 @@ class _UserListViewState extends State<UserListView>
), ),
FlatButton( FlatButton(
onPressed: () { onPressed: () {
usersBlocState.queryUsers( _userListController.loadData();
filter: widget.filter,
sort: widget.sort,
pagination: widget.pagination,
options: widget.options,
);
}, },
child: Text('Retry'), child: Text('Retry'),
), ),
@@ -269,31 +247,12 @@ class _UserListViewState extends State<UserListView>
); );
} }
if (!snapshot.hasData) { Widget _buildEmpty() {
return LayoutBuilder( if (widget.emptyBuilder != null) {
builder: (context, viewportConstraints) {
return SingleChildScrollView(
physics: AlwaysScrollableScrollPhysics(),
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: Center(
child: CircularProgressIndicator(),
),
),
);
},
);
}
final items = snapshot.data;
if (items.isEmpty && widget.emptyBuilder != null) {
return widget.emptyBuilder(context); return widget.emptyBuilder(context);
} }
if (items.isEmpty && widget.emptyBuilder == null) { if (widget.emptyBuilder == null) {
return LayoutBuilder( return LayoutBuilder(
builder: (context, viewportConstraints) { builder: (context, viewportConstraints) {
return SingleChildScrollView( return SingleChildScrollView(
@@ -310,7 +269,11 @@ class _UserListViewState extends State<UserListView>
}, },
); );
} }
}
Widget _buildListView(
List<ListItem> items,
) {
final child = _isListView final child = _isListView
? ListView.separated( ? ListView.separated(
physics: AlwaysScrollableScrollPhysics(), physics: AlwaysScrollableScrollPhysics(),
@@ -338,12 +301,10 @@ class _UserListViewState extends State<UserListView>
return LazyLoadScrollView( return LazyLoadScrollView(
onEndOfPage: () async { onEndOfPage: () async {
return _listenUserPagination(usersBlocState); return _userListController.paginateData();
}, },
child: child, child: child,
); );
},
);
} }
Widget _listItemBuilder(BuildContext context, int i, List<ListItem> items) { Widget _listItemBuilder(BuildContext context, int i, List<ListItem> items) {
@@ -481,33 +442,4 @@ class _UserListViewState extends State<UserListView>
color: StreamChatTheme.of(context).colorTheme.greyWhisper, color: StreamChatTheme.of(context).colorTheme.greyWhisper,
); );
} }
void _listenUserPagination(UsersBlocState usersProvider) {
usersProvider.queryUsers(
filter: widget.filter,
sort: widget.sort,
pagination: widget.pagination.copyWith(
offset: usersProvider.users?.length ?? 0,
),
options: widget.options,
);
}
@override
void didUpdateWidget(UserListView oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.filter?.toString() != oldWidget.filter?.toString() ||
jsonEncode(widget.sort) != jsonEncode(oldWidget.sort) ||
widget.pagination?.toJson()?.toString() !=
oldWidget.pagination?.toJson()?.toString() ||
widget.options?.toString() != oldWidget.options?.toString()) {
final usersBloc = UsersBloc.of(context);
usersBloc.queryUsers(
filter: widget.filter,
sort: widget.sort,
pagination: widget.pagination,
options: widget.options,
);
}
}
} }
@@ -43,7 +43,6 @@ class UserListCore extends StatefulWidget {
this.options, this.options,
this.sort, this.sort,
this.pagination, this.pagination,
this.pullToRefresh = true,
this.groupAlphabetically = false, this.groupAlphabetically = false,
@required this.errorBuilder, @required this.errorBuilder,
@required this.emptyBuilder, @required this.emptyBuilder,
@@ -89,9 +88,6 @@ class UserListCore extends StatefulWidget {
/// message_limit: how many messages should be included to each channel /// message_limit: how many messages should be included to each channel
final PaginationParams pagination; final PaginationParams pagination;
/// Set it to false to disable the pull-to-refresh widget
final bool pullToRefresh;
/// Set it to true to group users by their first character /// Set it to true to group users by their first character
/// ///
/// defaults to false /// defaults to false
@@ -124,23 +120,9 @@ class _UserListCoreState extends State<UserListCore>
Widget build(BuildContext context) { Widget build(BuildContext context) {
final usersBloc = UsersBloc.of(context); final usersBloc = UsersBloc.of(context);
if (!widget.pullToRefresh) {
return _buildListView(usersBloc); return _buildListView(usersBloc);
} }
return RefreshIndicator(
onRefresh: () async {
return usersBloc.queryUsers(
filter: widget.filter,
sort: widget.sort,
options: widget.options,
pagination: widget.pagination,
);
},
child: _buildListView(usersBloc),
);
}
bool get isListAlreadySorted => bool get isListAlreadySorted =>
widget.sort?.any((e) => e.field == 'name' && e.direction == 1) ?? false; widget.sort?.any((e) => e.field == 'name' && e.direction == 1) ?? false;