feat: Added fixes and user_list_view.dart
This commit is contained in:
@@ -185,8 +185,7 @@ class _NewChatScreenState extends State<NewChatScreen> {
|
||||
),
|
||||
padding: const EdgeInsets.only(left: 24),
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.fromLTRB(8, 4, 12, 4),
|
||||
padding: const EdgeInsets.fromLTRB(8, 4, 12, 4),
|
||||
child: Text(
|
||||
user.name,
|
||||
maxLines: 1,
|
||||
@@ -291,8 +290,7 @@ class _NewChatScreenState extends State<NewChatScreen> {
|
||||
child: _showUserList
|
||||
? GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onPanDown: (_) =>
|
||||
FocusScope.of(context).unfocus(),
|
||||
onPanDown: (_) => FocusScope.of(context).unfocus(),
|
||||
child: UsersBloc(
|
||||
child: UserListView(
|
||||
selectedUsers: _selectedUsers,
|
||||
@@ -342,8 +340,7 @@ class _NewChatScreenState extends State<NewChatScreen> {
|
||||
children: [
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.all(
|
||||
24),
|
||||
const EdgeInsets.all(24),
|
||||
child: StreamSvgIcon.search(
|
||||
size: 96,
|
||||
color: Colors.grey,
|
||||
@@ -360,8 +357,7 @@ class _NewChatScreenState extends State<NewChatScreen> {
|
||||
.of(context)
|
||||
.colorTheme
|
||||
.black
|
||||
.withOpacity(
|
||||
.5)),
|
||||
.withOpacity(.5)),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -415,7 +411,8 @@ class _NewChatScreenState extends State<NewChatScreen> {
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,15 +159,7 @@ class _ChannelListViewState extends State<ChannelListView>
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (!widget.pullToRefresh) {
|
||||
_channelListController.loadData();
|
||||
}
|
||||
|
||||
return RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
_channelListController.loadData();
|
||||
},
|
||||
child: ChannelListCore(
|
||||
var child = ChannelListCore(
|
||||
channelListController: _channelListController,
|
||||
listBuilder: (context, list) {
|
||||
return _buildListView(list);
|
||||
@@ -185,8 +177,18 @@ class _ChannelListViewState extends State<ChannelListView>
|
||||
options: widget.options,
|
||||
sort: widget.sort,
|
||||
filter: widget.filter,
|
||||
),
|
||||
);
|
||||
|
||||
if (!widget.pullToRefresh) {
|
||||
return child;
|
||||
} else {
|
||||
return RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
_channelListController.loadData();
|
||||
},
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildListView(
|
||||
|
||||
@@ -140,87 +140,70 @@ class _UserListViewState extends State<UserListView>
|
||||
with WidgetsBindingObserver {
|
||||
bool get _isListView => widget.crossAxisCount == 1;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
final usersBloc = UsersBloc.of(context);
|
||||
usersBloc.queryUsers(
|
||||
filter: widget.filter,
|
||||
sort: widget.sort,
|
||||
pagination: widget.pagination,
|
||||
options: widget.options,
|
||||
);
|
||||
}
|
||||
UserListController _userListController = UserListController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final usersBloc = UsersBloc.of(context);
|
||||
|
||||
if (!widget.pullToRefresh) {
|
||||
return _buildListView(usersBloc);
|
||||
}
|
||||
|
||||
return RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
return usersBloc.queryUsers(
|
||||
filter: widget.filter,
|
||||
sort: widget.sort,
|
||||
options: widget.options,
|
||||
pagination: widget.pagination,
|
||||
var child = UserListCore(
|
||||
errorBuilder: (err) {
|
||||
return _buildError(err);
|
||||
},
|
||||
emptyBuilder: (context) {
|
||||
return _buildEmpty();
|
||||
},
|
||||
loadingBuilder: (context) {
|
||||
return LayoutBuilder(
|
||||
builder: (context, viewportConstraints) {
|
||||
return SingleChildScrollView(
|
||||
physics: AlwaysScrollableScrollPhysics(),
|
||||
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 =>
|
||||
widget.sort?.any((e) => e.field == 'name' && e.direction == 1) ?? false;
|
||||
|
||||
Stream<List<ListItem>> _buildUserStream(
|
||||
UsersBlocState usersBlocState,
|
||||
) {
|
||||
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);
|
||||
}
|
||||
Widget _buildError(Error error) {
|
||||
print((error).stackTrace);
|
||||
|
||||
if (widget.errorBuilder != null) {
|
||||
return widget.errorBuilder(snapshot.error);
|
||||
return widget.errorBuilder(error);
|
||||
}
|
||||
|
||||
var message = snapshot.error.toString();
|
||||
if (snapshot.error is DioError) {
|
||||
final dioError = snapshot.error as DioError;
|
||||
var message = error.toString();
|
||||
if (error is DioError) {
|
||||
final dioError = error as DioError;
|
||||
if (dioError.type == DioErrorType.RESPONSE) {
|
||||
message = dioError.message;
|
||||
} else {
|
||||
@@ -255,12 +238,7 @@ class _UserListViewState extends State<UserListView>
|
||||
),
|
||||
FlatButton(
|
||||
onPressed: () {
|
||||
usersBlocState.queryUsers(
|
||||
filter: widget.filter,
|
||||
sort: widget.sort,
|
||||
pagination: widget.pagination,
|
||||
options: widget.options,
|
||||
);
|
||||
_userListController.loadData();
|
||||
},
|
||||
child: Text('Retry'),
|
||||
),
|
||||
@@ -269,31 +247,12 @@ class _UserListViewState extends State<UserListView>
|
||||
);
|
||||
}
|
||||
|
||||
if (!snapshot.hasData) {
|
||||
return LayoutBuilder(
|
||||
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) {
|
||||
Widget _buildEmpty() {
|
||||
if (widget.emptyBuilder != null) {
|
||||
return widget.emptyBuilder(context);
|
||||
}
|
||||
|
||||
if (items.isEmpty && widget.emptyBuilder == null) {
|
||||
if (widget.emptyBuilder == null) {
|
||||
return LayoutBuilder(
|
||||
builder: (context, viewportConstraints) {
|
||||
return SingleChildScrollView(
|
||||
@@ -310,7 +269,11 @@ class _UserListViewState extends State<UserListView>
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildListView(
|
||||
List<ListItem> items,
|
||||
) {
|
||||
final child = _isListView
|
||||
? ListView.separated(
|
||||
physics: AlwaysScrollableScrollPhysics(),
|
||||
@@ -338,12 +301,10 @@ class _UserListViewState extends State<UserListView>
|
||||
|
||||
return LazyLoadScrollView(
|
||||
onEndOfPage: () async {
|
||||
return _listenUserPagination(usersBlocState);
|
||||
return _userListController.paginateData();
|
||||
},
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _listItemBuilder(BuildContext context, int i, List<ListItem> items) {
|
||||
@@ -481,33 +442,4 @@ class _UserListViewState extends State<UserListView>
|
||||
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.sort,
|
||||
this.pagination,
|
||||
this.pullToRefresh = true,
|
||||
this.groupAlphabetically = false,
|
||||
@required this.errorBuilder,
|
||||
@required this.emptyBuilder,
|
||||
@@ -89,9 +88,6 @@ class UserListCore extends StatefulWidget {
|
||||
/// message_limit: how many messages should be included to each channel
|
||||
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
|
||||
///
|
||||
/// defaults to false
|
||||
@@ -124,23 +120,9 @@ class _UserListCoreState extends State<UserListCore>
|
||||
Widget build(BuildContext context) {
|
||||
final usersBloc = UsersBloc.of(context);
|
||||
|
||||
if (!widget.pullToRefresh) {
|
||||
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 =>
|
||||
widget.sort?.any((e) => e.field == 'name' && e.direction == 1) ?? false;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user