lint
This commit is contained in:
@@ -36,10 +36,13 @@ typedef UserItemBuilder = Widget Function(BuildContext, User, bool);
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// Make sure to have a [UsersBloc] ancestor in order to provide the information about the users.
|
/// Make sure to have a [UsersBloc] ancestor in order to provide the
|
||||||
/// The widget uses a [ListView.separated], [GridView.builder] to render the list, grid of channels.
|
/// information about the users.
|
||||||
|
/// The widget uses a [ListView.separated], [GridView.builder] to render the
|
||||||
|
/// list, grid of channels.
|
||||||
///
|
///
|
||||||
/// The widget components render the ui based on the first ancestor of type [StreamChatTheme].
|
/// The widget components render the ui based on the first ancestor of
|
||||||
|
/// type [StreamChatTheme].
|
||||||
/// Modify it to change the widget appearance.
|
/// Modify it to change the widget appearance.
|
||||||
class UserListView extends StatefulWidget {
|
class UserListView extends StatefulWidget {
|
||||||
/// Instantiate a new UserListView
|
/// Instantiate a new UserListView
|
||||||
@@ -81,8 +84,10 @@ class UserListView extends StatefulWidget {
|
|||||||
final Map<String, dynamic>? options;
|
final Map<String, dynamic>? options;
|
||||||
|
|
||||||
/// The sorting used for the channels matching the filters.
|
/// The sorting used for the channels matching the filters.
|
||||||
/// Sorting is based on field and direction, multiple sorting options can be provided.
|
/// Sorting is based on field and direction, multiple sorting options can
|
||||||
/// You can sort based on last_updated, last_message_at, updated_at, created_at or member_count.
|
/// be provided.
|
||||||
|
/// You can sort based on last_updated, last_message_at, updated_at, created_
|
||||||
|
/// at or member_count.
|
||||||
/// Direction can be ascending or descending.
|
/// Direction can be ascending or descending.
|
||||||
final List<SortOption>? sort;
|
final List<SortOption>? sort;
|
||||||
|
|
||||||
@@ -115,7 +120,8 @@ class UserListView extends StatefulWidget {
|
|||||||
/// Set it to false to disable the pull-to-refresh widget
|
/// Set it to false to disable the pull-to-refresh widget
|
||||||
final bool pullToRefresh;
|
final bool pullToRefresh;
|
||||||
|
|
||||||
/// Sets a blue trailing checkMark in [ListUserItem] for all the [selectedUsers]
|
/// Sets a blue trailing checkMark in [ListUserItem] for all the
|
||||||
|
/// [selectedUsers]
|
||||||
final Set<User>? selectedUsers;
|
final Set<User>? selectedUsers;
|
||||||
|
|
||||||
/// Set it to true to group users by their first character
|
/// Set it to true to group users by their first character
|
||||||
@@ -153,35 +159,25 @@ class _UserListViewState extends State<UserListView>
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final child = UserListCore(
|
final child = UserListCore(
|
||||||
errorBuilder: widget.errorBuilder as Widget Function(Object)? ??
|
errorBuilder: widget.errorBuilder as Widget Function(Object)? ??
|
||||||
(err) {
|
(err) => _buildError(err as Error),
|
||||||
return _buildError(err as Error);
|
emptyBuilder: widget.emptyBuilder ?? (context) => _buildEmpty(),
|
||||||
},
|
|
||||||
emptyBuilder: widget.emptyBuilder ??
|
|
||||||
(context) {
|
|
||||||
return _buildEmpty();
|
|
||||||
},
|
|
||||||
loadingBuilder: widget.loadingBuilder ??
|
loadingBuilder: widget.loadingBuilder ??
|
||||||
(context) {
|
(context) => LayoutBuilder(
|
||||||
return LayoutBuilder(
|
builder: (context, viewportConstraints) =>
|
||||||
builder: (context, viewportConstraints) {
|
SingleChildScrollView(
|
||||||
return SingleChildScrollView(
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
physics: AlwaysScrollableScrollPhysics(),
|
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
minHeight: viewportConstraints.maxHeight,
|
minHeight: viewportConstraints.maxHeight,
|
||||||
),
|
),
|
||||||
child: Center(
|
child: const Center(
|
||||||
child: CircularProgressIndicator(),
|
child: CircularProgressIndicator(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
},
|
),
|
||||||
);
|
listBuilder:
|
||||||
},
|
widget.listBuilder ?? (context, list) => _buildListView(list),
|
||||||
listBuilder: widget.listBuilder ??
|
|
||||||
(context, list) {
|
|
||||||
return _buildListView(list);
|
|
||||||
},
|
|
||||||
pagination: widget.pagination,
|
pagination: widget.pagination,
|
||||||
options: widget.options,
|
options: widget.options,
|
||||||
sort: widget.sort,
|
sort: widget.sort,
|
||||||
@@ -204,7 +200,7 @@ class _UserListViewState extends State<UserListView>
|
|||||||
widget.sort?.any((e) => e.field == 'name' && e.direction == 1) ?? false;
|
widget.sort?.any((e) => e.field == 'name' && e.direction == 1) ?? false;
|
||||||
|
|
||||||
Widget _buildError(Error error) {
|
Widget _buildError(Error error) {
|
||||||
print((error).stackTrace);
|
print(error.stackTrace);
|
||||||
|
|
||||||
var message = error.toString();
|
var message = error.toString();
|
||||||
if (error is DioError) {
|
if (error is DioError) {
|
||||||
@@ -220,11 +216,11 @@ class _UserListViewState extends State<UserListView>
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text.rich(
|
Text.rich(
|
||||||
TextSpan(
|
const TextSpan(
|
||||||
children: [
|
children: [
|
||||||
WidgetSpan(
|
WidgetSpan(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
right: 2,
|
right: 2,
|
||||||
),
|
),
|
||||||
child: Icon(Icons.error_outline),
|
child: Icon(Icons.error_outline),
|
||||||
@@ -243,37 +239,33 @@ class _UserListViewState extends State<UserListView>
|
|||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => _userListController.loadData!(),
|
onPressed: () => _userListController.loadData!(),
|
||||||
child: Text('Retry'),
|
child: const Text('Retry'),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildEmpty() {
|
Widget _buildEmpty() => LayoutBuilder(
|
||||||
return LayoutBuilder(
|
builder: (context, viewportConstraints) => SingleChildScrollView(
|
||||||
builder: (context, viewportConstraints) {
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
return SingleChildScrollView(
|
|
||||||
physics: AlwaysScrollableScrollPhysics(),
|
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
minHeight: viewportConstraints.maxHeight,
|
minHeight: viewportConstraints.maxHeight,
|
||||||
),
|
),
|
||||||
child: Center(
|
child: const Center(
|
||||||
child: Text('There are no users currently'),
|
child: Text('There are no users currently'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
},
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildListView(
|
Widget _buildListView(
|
||||||
List<ListItem> items,
|
List<ListItem> items,
|
||||||
) {
|
) {
|
||||||
final child = _isListView
|
final child = _isListView
|
||||||
? ListView.separated(
|
? ListView.separated(
|
||||||
physics: AlwaysScrollableScrollPhysics(),
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
itemCount: items.isNotEmpty ? items.length + 1 : items.length,
|
itemCount: items.isNotEmpty ? items.length + 1 : items.length,
|
||||||
separatorBuilder: (_, index) {
|
separatorBuilder: (_, index) {
|
||||||
if (widget.separatorBuilder != null) {
|
if (widget.separatorBuilder != null) {
|
||||||
@@ -281,19 +273,17 @@ class _UserListViewState extends State<UserListView>
|
|||||||
}
|
}
|
||||||
return _separatorBuilder(context, index);
|
return _separatorBuilder(context, index);
|
||||||
},
|
},
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) =>
|
||||||
return _listItemBuilder(context, index, items);
|
_listItemBuilder(context, index, items),
|
||||||
},
|
|
||||||
)
|
)
|
||||||
: GridView.builder(
|
: GridView.builder(
|
||||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
crossAxisCount: widget.crossAxisCount,
|
crossAxisCount: widget.crossAxisCount,
|
||||||
),
|
),
|
||||||
itemCount: items.isNotEmpty ? items.length + 1 : items.length,
|
itemCount: items.isNotEmpty ? items.length + 1 : items.length,
|
||||||
physics: AlwaysScrollableScrollPhysics(),
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) =>
|
||||||
return _gridItemBuilder(context, index, items);
|
_gridItemBuilder(context, index, items),
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return LazyLoadScrollView(
|
return LazyLoadScrollView(
|
||||||
@@ -307,24 +297,21 @@ class _UserListViewState extends State<UserListView>
|
|||||||
if (i < items.length) {
|
if (i < items.length) {
|
||||||
final item = items[i];
|
final item = items[i];
|
||||||
return item.when(
|
return item.when(
|
||||||
headerItem: (header) {
|
headerItem: (header) => Container(
|
||||||
return Container(
|
key: ValueKey<String>('HEADER-$header'),
|
||||||
key: ValueKey<String>('HEADER-$header'),
|
color: StreamChatTheme.of(context).colorTheme.black.withOpacity(0.05),
|
||||||
color:
|
child: Padding(
|
||||||
StreamChatTheme.of(context).colorTheme.black.withOpacity(0.05),
|
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
|
||||||
child: Padding(
|
child: Text(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
|
header,
|
||||||
child: Text(
|
style: TextStyle(
|
||||||
header,
|
fontWeight: FontWeight.bold,
|
||||||
style: TextStyle(
|
fontSize: 14.5,
|
||||||
fontWeight: FontWeight.bold,
|
color: StreamChatTheme.of(context).colorTheme.grey,
|
||||||
fontSize: 14.5,
|
|
||||||
color: StreamChatTheme.of(context).colorTheme.grey,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
},
|
),
|
||||||
userItem: (user) {
|
userItem: (user) {
|
||||||
final selected = widget.selectedUsers?.contains(user) ?? false;
|
final selected = widget.selectedUsers?.contains(user) ?? false;
|
||||||
return Container(
|
return Container(
|
||||||
@@ -351,7 +338,7 @@ class _UserListViewState extends State<UserListView>
|
|||||||
if (i < items.length) {
|
if (i < items.length) {
|
||||||
final item = items[i];
|
final item = items[i];
|
||||||
return item.when(
|
return item.when(
|
||||||
headerItem: (_) => Offstage(),
|
headerItem: (_) => const Offstage(),
|
||||||
userItem: (user) {
|
userItem: (user) {
|
||||||
final selected = widget.selectedUsers?.contains(user) ?? false;
|
final selected = widget.selectedUsers?.contains(user) ?? false;
|
||||||
return Container(
|
return Container(
|
||||||
@@ -365,11 +352,12 @@ class _UserListViewState extends State<UserListView>
|
|||||||
user: user,
|
user: user,
|
||||||
borderRadius: BorderRadius.circular(32),
|
borderRadius: BorderRadius.circular(32),
|
||||||
selected: selected,
|
selected: selected,
|
||||||
constraints: BoxConstraints.tightFor(
|
constraints: const BoxConstraints.tightFor(
|
||||||
height: 64,
|
height: 64,
|
||||||
width: 64,
|
width: 64,
|
||||||
),
|
),
|
||||||
onlineIndicatorConstraints: BoxConstraints.tightFor(
|
onlineIndicatorConstraints:
|
||||||
|
const BoxConstraints.tightFor(
|
||||||
height: 12,
|
height: 12,
|
||||||
width: 12,
|
width: 12,
|
||||||
),
|
),
|
||||||
@@ -377,7 +365,7 @@ class _UserListViewState extends State<UserListView>
|
|||||||
widget.onUserTap!(user, widget.userWidget),
|
widget.onUserTap!(user, widget.userWidget),
|
||||||
onLongPress: widget.onUserLongPress,
|
onLongPress: widget.onUserLongPress,
|
||||||
),
|
),
|
||||||
SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
child: Text(
|
child: Text(
|
||||||
@@ -385,7 +373,7 @@ class _UserListViewState extends State<UserListView>
|
|||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: TextStyle(
|
style: const TextStyle(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
),
|
),
|
||||||
@@ -401,39 +389,38 @@ class _UserListViewState extends State<UserListView>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildQueryProgressIndicator(context, UsersBlocState usersProvider) {
|
Widget _buildQueryProgressIndicator(context, UsersBlocState usersProvider) =>
|
||||||
return StreamBuilder<bool>(
|
StreamBuilder<bool>(
|
||||||
stream: usersProvider.queryUsersLoading,
|
stream: usersProvider.queryUsersLoading,
|
||||||
initialData: false,
|
initialData: false,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.hasError) {
|
if (snapshot.hasError) {
|
||||||
return Container(
|
return Container(
|
||||||
color: StreamChatTheme.of(context)
|
color: StreamChatTheme.of(context)
|
||||||
.colorTheme
|
.colorTheme
|
||||||
.accentRed
|
.accentRed
|
||||||
.withOpacity(.2),
|
.withOpacity(.2),
|
||||||
child: Padding(
|
child: const Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
padding: EdgeInsets.symmetric(vertical: 16),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text('Error loading users'),
|
child: Text('Error loading users'),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Container(
|
||||||
|
height: 100,
|
||||||
|
padding: const EdgeInsets.all(32),
|
||||||
|
child: Center(
|
||||||
|
child: snapshot.data!
|
||||||
|
? const CircularProgressIndicator()
|
||||||
|
: Container(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
return Container(
|
|
||||||
height: 100,
|
|
||||||
padding: EdgeInsets.all(32),
|
|
||||||
child: Center(
|
|
||||||
child: snapshot.data! ? CircularProgressIndicator() : Container(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _separatorBuilder(context, i) {
|
Widget _separatorBuilder(context, i) => Container(
|
||||||
return Container(
|
height: 1,
|
||||||
height: 1,
|
color: StreamChatTheme.of(context).colorTheme.greyWhisper,
|
||||||
color: StreamChatTheme.of(context).colorTheme.greyWhisper,
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user