From f3482fc05940bffdc9865d15eac3b80790185c2e Mon Sep 17 00:00:00 2001 From: Warakorn Sitthirit Date: Thu, 28 Nov 2024 22:17:19 +0700 Subject: [PATCH 1/2] feat: Use user live collection for global user search --- .../global_user_search.dart | 99 ++++++++----------- 1 file changed, 43 insertions(+), 56 deletions(-) diff --git a/lib/presentation/screen/global_user_search/global_user_search.dart b/lib/presentation/screen/global_user_search/global_user_search.dart index 6e6ca5b..612ecdc 100644 --- a/lib/presentation/screen/global_user_search/global_user_search.dart +++ b/lib/presentation/screen/global_user_search/global_user_search.dart @@ -1,9 +1,7 @@ import 'package:amity_sdk/amity_sdk.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_social_sample_app/core/constant/global_constant.dart'; import 'package:flutter_social_sample_app/core/utils/debouncer.dart'; import 'package:flutter_social_sample_app/core/widget/dialog/amity_user_info_widget.dart'; -import 'package:flutter_social_sample_app/core/widget/dialog/error_dialog.dart'; class GlobalUserSearch extends StatefulWidget { const GlobalUserSearch({Key? key, this.showAppBar = true}) : super(key: key); @@ -13,8 +11,8 @@ class GlobalUserSearch extends StatefulWidget { } class _GlobalUserSearchState extends State { - late PagingController _controller; - final amityUsers = []; + late UserLiveCollection _userLiveCollection; + List amityUsers = []; final scrollcontroller = ScrollController(); bool loading = false; @@ -26,54 +24,15 @@ class _GlobalUserSearchState extends State { AmityUserSortOption _sort = AmityUserSortOption.DISPLAY; @override void initState() { - _controller = PagingController( - pageFuture: (token) => AmityCoreClient.newUserRepository() - .searchUserByDisplayName(_keyword) - .sortBy(_sort) - .getPagingData(token: token, limit: GlobalConstant.pageSize), - pageSize: GlobalConstant.pageSize, - )..addListener( - () { - if (_controller.error == null) { - if (mounted) { - setState(() { - amityUsers.clear(); - amityUsers.addAll(_controller.loadedItems); - }); - } - } else { - //Error on pagination controller - setState(() {}); - ErrorDialog.show(context, - title: 'Error', message: _controller.error.toString()); - } - }, - ); - - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - _controller.fetchNextPage(); - }); - + resetLiveCollection(isReset: false); scrollcontroller.addListener(pagination); - super.initState(); } - // void addMembers(List members) { - // _controller.addAll(members); - // } - - // void removeMembers(List userIds) { - // _controller.removeWhere((member) => userIds.contains(member.userId)); - // } - void pagination() { - if ((scrollcontroller.position.pixels == - scrollcontroller.position.maxScrollExtent) && - _controller.hasMoreItems) { - setState(() { - _controller.fetchNextPage(); - }); + if ((scrollcontroller.position.pixels == scrollcontroller.position.maxScrollExtent) + && _userLiveCollection.hasNextPage()) { + _userLiveCollection.loadNext(); } } @@ -92,8 +51,7 @@ class _GlobalUserSearchState extends State { onChanged: (value) { _debouncer.run(() { _keyword = value; - _controller.reset(); - _controller.fetchNextPage(); + resetLiveCollection(); }); }, decoration: const InputDecoration(hintText: 'Enter Keybaord'), @@ -134,9 +92,7 @@ class _GlobalUserSearchState extends State { if (index == 3) { _sort = AmityUserSortOption.LAST_CREATED; } - - _controller.reset(); - _controller.fetchNextPage(); + resetLiveCollection(); }, ), ), @@ -146,8 +102,7 @@ class _GlobalUserSearchState extends State { child: amityUsers.isNotEmpty ? RefreshIndicator( onRefresh: () async { - _controller.reset(); - _controller.fetchNextPage(); + resetLiveCollection(); }, child: ListView.builder( physics: const AlwaysScrollableScrollPhysics(), @@ -163,12 +118,12 @@ class _GlobalUserSearchState extends State { ) : Container( alignment: Alignment.center, - child: _controller.isFetching + child: _userLiveCollection.isFetching ? const CircularProgressIndicator() : const Text('No Members'), ), ), - if (_controller.isFetching && amityUsers.isNotEmpty) + if (_userLiveCollection.isFetching && amityUsers.isNotEmpty) Container( alignment: Alignment.center, child: const CircularProgressIndicator(), @@ -178,6 +133,38 @@ class _GlobalUserSearchState extends State { ); } + void resetLiveCollection({ bool isReset = true }) async { + if (isReset) { + _userLiveCollection.getStreamController().close(); + setState(() { + amityUsers = []; + }); + } + + _userLiveCollection = AmityCoreClient.newUserRepository() + .searchUserByDisplayName(_keyword) + .sortBy(_sort) + .getLiveCollection(); + + _userLiveCollection.getStreamController().stream.listen((event) { + if (mounted) { + setState(() { + amityUsers = event; + }); + } + }); + + _userLiveCollection.observeLoadingState().listen((event) { + if (mounted) { + setState(() { + loading = event; + }); + } + }); + + _userLiveCollection.loadNext(); + } + // void _muteMember(BuildContext context, AmityChannelMember member) { // AmityChatClient.newChannelRepository() // .moderation(member.channelId!) From 40865b44e8d2e181d1c5d62eea038a7b307f93c9 Mon Sep 17 00:00:00 2001 From: Warakorn Sitthirit Date: Tue, 10 Dec 2024 23:15:04 +0700 Subject: [PATCH 2/2] feat: Show chat is push notifiable --- .../channel_list/channel_list_screen.dart | 18 +++++++++++++++++- pubspec.yaml | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/presentation/screen/channel_list/channel_list_screen.dart b/lib/presentation/screen/channel_list/channel_list_screen.dart index d78a717..97eb769 100644 --- a/lib/presentation/screen/channel_list/channel_list_screen.dart +++ b/lib/presentation/screen/channel_list/channel_list_screen.dart @@ -29,11 +29,13 @@ class _ChannelListScreenState extends State { AmityChannelSortOption _sort = AmityChannelSortOption.LAST_ACTIVITY; List? _tags; List? _excludingTags; + bool? isPushNotifiable; @override void initState() { resetLiveCollection(isReset: false); scrollcontroller.addListener(pagination); + fetchNotificationSettings(); super.initState(); } @@ -47,6 +49,14 @@ class _ChannelListScreenState extends State { } } + void fetchNotificationSettings() async { + final settings = await AmityNotification().user().getSettings(); + final chatModuleSetting = settings.events?.whereType().firstOrNull; + setState(() { + isPushNotifiable = (settings.isEnabled ?? true) && (chatModuleSetting?.isEnabled ?? true); + }); + } + void resetLiveCollection({ bool isReset = true }) async { if (isReset) { _channelLiveCollection.getStreamController().stream; @@ -85,6 +95,12 @@ class _ChannelListScreenState extends State { appBar: AppBar(title: const Text('Channel List ')), body: Column( children: [ + Container( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + width: double.infinity, + color: Colors.grey[200], + child: Text("chat.push_notification.enable: ${isPushNotifiable ?? "unknown"}"), + ), Container( padding: const EdgeInsets.all(12), child: TextFormField( @@ -304,7 +320,7 @@ class _ChannelListScreenState extends State { alignment: Alignment.center, child: _channelLiveCollection.isFetching ? const CircularProgressIndicator() - : const Text('No Post'), + : const Text('No channel found'), ), ), if (_channelLiveCollection.isFetching && amityChannels.isNotEmpty) diff --git a/pubspec.yaml b/pubspec.yaml index 1b81c2d..191cbeb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_social_sample_app description: Demonstrates how to use the flutter_application_1 plugin. -version: 1.1.50+67 +version: 1.1.51+68