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),
|
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;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user