update lists

This commit is contained in:
Salvatore Giordano
2022-04-28 14:53:00 +02:00
parent ad398090f6
commit 18e69cd4bd
6 changed files with 317 additions and 263 deletions
@@ -264,6 +264,7 @@
"${BUILT_PRODUCTS_DIR}/sqlite3/sqlite3.framework",
"${BUILT_PRODUCTS_DIR}/sqlite3_flutter_libs/sqlite3_flutter_libs.framework",
"${BUILT_PRODUCTS_DIR}/url_launcher_ios/url_launcher_ios.framework",
"${BUILT_PRODUCTS_DIR}/video_compress/video_compress.framework",
"${BUILT_PRODUCTS_DIR}/video_player_avfoundation/video_player_avfoundation.framework",
"${BUILT_PRODUCTS_DIR}/video_thumbnail/video_thumbnail.framework",
"${BUILT_PRODUCTS_DIR}/wakelock/wakelock.framework",
@@ -292,6 +293,7 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqlite3.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqlite3_flutter_libs.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher_ios.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/video_compress.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/video_player_avfoundation.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/video_thumbnail.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/wakelock.framework",
+33 -19
View File
@@ -20,9 +20,21 @@ class ChannelList extends StatefulWidget {
class _ChannelList extends State<ChannelList> {
ScrollController _scrollController = ScrollController();
TextEditingController? _controller;
late StreamMessageSearchListController _messageSearchListController =
StreamMessageSearchListController(
client: StreamChat.of(context).client,
filter: Filter.in_('members', [StreamChat.of(context).currentUser!.id]),
limit: 5,
searchQuery: '',
sort: [
SortOption(
'created_at',
direction: SortOption.ASC,
),
],
);
String _channelQuery = '';
TextEditingController? _controller;
bool _isSearchActive = false;
@@ -32,10 +44,11 @@ class _ChannelList extends State<ChannelList> {
if (_debounce?.isActive ?? false) _debounce!.cancel();
_debounce = Timer(const Duration(milliseconds: 350), () {
if (mounted) {
_messageSearchListController.searchQuery = _controller!.text;
setState(() {
_channelQuery = _controller!.text;
_isSearchActive = _channelQuery.isNotEmpty;
_isSearchActive = _controller!.text.isNotEmpty;
});
if (_isSearchActive) _messageSearchListController.doInitialLoad();
}
});
}
@@ -61,12 +74,12 @@ class _ChannelList extends State<ChannelList> {
_controller?.removeListener(_channelQueryListener);
_controller?.dispose();
_scrollController.dispose();
_channelListController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final user = StreamChat.of(context).currentUser;
return WillPopScope(
onWillPop: () async {
if (_isSearchActive) {
@@ -98,17 +111,7 @@ class _ChannelList extends State<ChannelList> {
],
body: _isSearchActive
? StreamMessageSearchListView(
showErrorTile: true,
messageQuery: _channelQuery,
filters: Filter.in_('members', [user!.id]),
sortOptions: [
SortOption(
'created_at',
direction: SortOption.ASC,
),
],
pullToRefresh: false,
limit: 30,
controller: _messageSearchListController,
emptyBuilder: (_) {
return LayoutBuilder(
builder: (context, viewportConstraints) {
@@ -139,7 +142,15 @@ class _ChannelList extends State<ChannelList> {
},
);
},
onItemTap: (messageResponse) async {
itemBuilder: (
context,
messageResponses,
index,
defaultWidget,
) {
return defaultWidget.copyWith(
onTap: () async {
final messageResponse = messageResponses[index];
FocusScope.of(context).requestFocus(FocusNode());
final client = StreamChat.of(context).client;
final message = messageResponse.message;
@@ -159,6 +170,8 @@ class _ChannelList extends State<ChannelList> {
),
);
},
);
},
)
: SlidableAutoCloseBehavior(
closeWhenOpened: true,
@@ -166,9 +179,10 @@ class _ChannelList extends State<ChannelList> {
onRefresh: _channelListController.refresh,
child: StreamChannelListView(
controller: _channelListController,
itemBuilder: (context, channel, tile) {
itemBuilder: (context, channels, index, defaultWidget) {
final chatTheme = StreamChatTheme.of(context);
final backgroundColor = chatTheme.colorTheme.inputBg;
final channel = channels[index];
final canDeleteChannel = channel.ownCapabilities
.contains(PermissionType.deleteChannel);
return Slidable(
@@ -249,7 +263,7 @@ class _ChannelList extends State<ChannelList> {
),
],
),
child: tile,
child: defaultWidget,
);
},
onChannelTap: (channel) {
@@ -704,41 +704,8 @@ class _GroupInfoScreenState extends State<GroupInfoScreen> {
void _buildAddUserModal(context) {
var channel = StreamChannel.of(context).channel;
showDialog(
useRootNavigator: false,
context: context,
barrierColor: StreamChatTheme.of(context).colorTheme.overlay,
builder: (context) {
return StatefulBuilder(builder: (context, modalSetState) {
modalSetStateCallback = modalSetState;
return Padding(
padding: EdgeInsets.only(top: 16.0, left: 8.0, right: 8.0),
child: Material(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16.0),
topRight: Radius.circular(16.0),
),
clipBehavior: Clip.antiAlias,
child: Scaffold(
body: UsersBloc(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(16),
child: _buildTextInputSection(modalSetState),
),
Expanded(
child: StreamUserListView(
selectedUsers: {},
onUserTap: (user, _) async {
_searchController!.clear();
await channel.addMembers([user.id]);
Navigator.pop(context);
setState(() {});
},
crossAxisCount: 4,
final userListController = StreamUserListController(
client: channel.client,
limit: 25,
filter: Filter.and(
[
@@ -758,6 +725,40 @@ class _GroupInfoScreenState extends State<GroupInfoScreen> {
direction: 1,
),
],
);
showDialog(
useRootNavigator: false,
context: context,
barrierColor: StreamChatTheme.of(context).colorTheme.overlay,
builder: (context) {
return StatefulBuilder(builder: (context, modalSetState) {
modalSetStateCallback = modalSetState;
return Padding(
padding: EdgeInsets.only(top: 16.0, left: 8.0, right: 8.0),
child: Material(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16.0),
topRight: Radius.circular(16.0),
),
clipBehavior: Clip.antiAlias,
child: Scaffold(
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(16),
child: _buildTextInputSection(modalSetState),
),
Expanded(
child: StreamUserListView(
controller: userListController,
onUserTap: (user) async {
_searchController!.clear();
await channel.addMembers([user.id]);
Navigator.pop(context);
setState(() {});
},
emptyBuilder: (_) {
return LayoutBuilder(
builder: (context, viewportConstraints) {
@@ -795,11 +796,10 @@ class _GroupInfoScreenState extends State<GroupInfoScreen> {
),
),
),
),
);
});
},
);
).then((_) => userListController.dispose());
}
Widget _buildTextInputSection(modalSetState) {
@@ -19,6 +19,20 @@ class _NewChatScreenState extends State<NewChatScreen> {
late TextEditingController _controller;
late final userListController = StreamUserListController(
client: StreamChat.of(context).client,
limit: 25,
filter: Filter.and([
Filter.notEqual('id', StreamChat.of(context).currentUser!.id),
]),
sort: [
SortOption(
'name',
direction: 1,
),
],
);
ChipInputTextFieldState? get _chipInputTextFieldState =>
_chipInputTextFieldStateKey.currentState;
@@ -45,6 +59,12 @@ class _NewChatScreenState extends State<NewChatScreen> {
_userNameQuery = _controller.text;
_isSearchActive = _userNameQuery.isNotEmpty;
});
userListController.filter = Filter.and([
if (_userNameQuery.isNotEmpty)
Filter.autoComplete('name', _userNameQuery),
Filter.notEqual('id', StreamChat.of(context).currentUser!.id),
]);
userListController.doInitialLoad();
});
}
@@ -112,6 +132,7 @@ class _NewChatScreenState extends State<NewChatScreen> {
_controller.clear();
_controller.removeListener(_userNameListener);
_controller.dispose();
userListController.dispose();
super.dispose();
}
@@ -289,10 +310,10 @@ class _NewChatScreenState extends State<NewChatScreen> {
onPanDown: (_) => FocusScope.of(context).unfocus(),
child: UsersBloc(
child: StreamUserListView(
selectedUsers: _selectedUsers,
groupAlphabetically:
_isSearchActive ? false : true,
onUserTap: (user, _) {
controller: userListController,
// groupAlphabetically:
// _isSearchActive ? false : true,
onUserTap: (user) {
_controller.clear();
if (!_selectedUsers.contains(user)) {
_chipInputTextFieldState
@@ -302,19 +323,17 @@ class _NewChatScreenState extends State<NewChatScreen> {
_chipInputTextFieldState!.removeItem(user);
}
},
limit: 25,
filter: Filter.and([
if (_userNameQuery.isNotEmpty)
Filter.autoComplete('name', _userNameQuery),
Filter.notEqual('id',
StreamChat.of(context).currentUser!.id),
]),
sort: [
SortOption(
'name',
direction: 1,
),
],
itemBuilder: (
context,
users,
index,
defaultWidget,
) {
return defaultWidget.copyWith(
selected:
_selectedUsers.contains(users[index]),
);
},
emptyBuilder: (_) {
return LayoutBuilder(
builder: (context, viewportConstraints) {
@@ -23,6 +23,20 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
Timer? _debounce;
late final userListController = StreamUserListController(
client: StreamChat.of(context).client,
sort: [
SortOption(
'name',
direction: 1,
),
],
limit: 25,
filter: Filter.and([
Filter.notEqual('id', StreamChat.of(context).currentUser!.id),
]),
);
void _userNameListener() {
if (_debounce?.isActive ?? false) _debounce!.cancel();
_debounce = Timer(const Duration(milliseconds: 350), () {
@@ -31,6 +45,12 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
_userNameQuery = _controller!.text;
_isSearchActive = _userNameQuery.isNotEmpty;
});
userListController.filter = Filter.and([
if (_userNameQuery.isNotEmpty)
Filter.autoComplete('name', _userNameQuery),
Filter.notEqual('id', StreamChat.of(context).currentUser!.id),
]);
userListController.doInitialLoad();
}
});
}
@@ -46,6 +66,7 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
_controller?.clear();
_controller?.removeListener(_userNameListener);
_controller?.dispose();
userListController.dispose();
super.dispose();
}
@@ -228,12 +249,15 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
body: GestureDetector(
behavior: HitTestBehavior.opaque,
onPanDown: (_) => FocusScope.of(context).unfocus(),
child: UsersBloc(
child: StreamUserListView(
selectedUsers: _selectedUsers,
pullToRefresh: false,
groupAlphabetically: _isSearchActive ? false : true,
onUserTap: (user, _) {
controller: userListController,
// groupAlphabetically: _isSearchActive ? false : true,
itemBuilder: (context, items, index, defaultWidget) {
return defaultWidget.copyWith(
selected: _selectedUsers.contains(items[index]),
);
},
onUserTap: (user) {
if (!_selectedUsers.contains(user)) {
setState(() {
_selectedUsers.add(user);
@@ -244,19 +268,6 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
});
}
},
limit: 25,
filter: Filter.and([
if (_userNameQuery.isNotEmpty)
Filter.autoComplete('name', _userNameQuery),
Filter.notEqual(
'id', StreamChat.of(context).currentUser!.id),
]),
sort: [
SortOption(
'name',
direction: 1,
),
],
emptyBuilder: (_) {
return LayoutBuilder(
builder: (context, viewportConstraints) {
@@ -301,7 +312,6 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
),
),
),
),
);
},
),
@@ -5,26 +5,32 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'channel_page.dart';
class UserMentionsPage extends StatelessWidget {
class UserMentionsPage extends StatefulWidget {
@override
Widget build(BuildContext context) {
final user = StreamChat.of(context).currentUser!;
return MessageSearchBloc(
child: StreamMessageSearchListView(
filters: Filter.in_('members', [user.id]),
messageFilters: Filter.custom(
State<UserMentionsPage> createState() => _UserMentionsPageState();
}
class _UserMentionsPageState extends State<UserMentionsPage> {
late final controller = StreamMessageSearchListController(
client: StreamChat.of(context).client,
filter: Filter.in_('members', [StreamChat.of(context).currentUser!.id]),
messageFilter: Filter.custom(
operator: r'$contains',
key: 'mentioned_users.id',
value: user.id,
value: StreamChat.of(context).currentUser!.id,
),
sortOptions: [
sort: [
SortOption(
'created_at',
direction: SortOption.ASC,
),
],
limit: 20,
showResultCount: false,
);
@override
Widget build(BuildContext context) {
return StreamMessageSearchListView(
controller: controller,
emptyBuilder: (_) {
return LayoutBuilder(
builder: (context, viewportConstraints) {
@@ -47,10 +53,8 @@ class UserMentionsPage extends StatelessWidget {
),
Text(
AppLocalizations.of(context).noMentionsExistYet,
style: StreamChatTheme.of(context)
.textTheme
.body
.copyWith(
style:
StreamChatTheme.of(context).textTheme.body.copyWith(
color: StreamChatTheme.of(context)
.colorTheme
.textLowEmphasis,
@@ -64,7 +68,7 @@ class UserMentionsPage extends StatelessWidget {
},
);
},
onItemTap: (messageResponse) async {
onMessageTap: (messageResponse) async {
final client = StreamChat.of(context).client;
final message = messageResponse.message;
final channel = client.channel(
@@ -83,7 +87,12 @@ class UserMentionsPage extends StatelessWidget {
),
);
},
),
);
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
}