diff --git a/lib/pages/routines/create_new_routines/commu_dropdown.dart b/lib/pages/routines/create_new_routines/commu_dropdown.dart index 13e2a437..658b69a0 100644 --- a/lib/pages/routines/create_new_routines/commu_dropdown.dart +++ b/lib/pages/routines/create_new_routines/commu_dropdown.dart @@ -34,9 +34,8 @@ class CommunityDropdown extends StatelessWidget { const SizedBox(height: 8), BlocBuilder( builder: (context, state) { - List communities = state.isSearching - ? state.filteredCommunity - : state.communityList; + List communities = + state.searchQuery.isNotEmpty ? state.filteredCommunity : state.communityList; return SizedBox( child: DropdownButtonFormField( diff --git a/lib/pages/space_tree/bloc/space_tree_bloc.dart b/lib/pages/space_tree/bloc/space_tree_bloc.dart index 6315ee0f..ab20b430 100644 --- a/lib/pages/space_tree/bloc/space_tree_bloc.dart +++ b/lib/pages/space_tree/bloc/space_tree_bloc.dart @@ -1,7 +1,10 @@ +import 'dart:async'; + import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_state.dart'; +import 'package:syncrow_web/pages/space_tree/model/pagination_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; import 'package:syncrow_web/services/space_mana_api.dart'; @@ -18,7 +21,10 @@ class SpaceTreeBloc extends Bloc { on(_clearCachedData); on(_onCommunityAdded); on(_onCommunityUpdate); + on(_fetchPaginationSpaces); + on(_onDebouncedSearch); } + Timer _timer = Timer(const Duration(microseconds: 0), () {}); void _onCommunityUpdate( OnCommunityUpdated event, @@ -37,7 +43,7 @@ class SpaceTreeBloc extends Bloc { updatedCommunities[index] = updatedCommunity; emit(state.copyWith(communitiesList: updatedCommunities)); } else { - emit(SpaceTreeErrorState('Community not found in the list.')); + emit(const SpaceTreeErrorState('Community not found in the list.')); } } catch (e) { emit(SpaceTreeErrorState('Error updating community: $e')); @@ -49,8 +55,8 @@ class SpaceTreeBloc extends Bloc { try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - List communities = - await CommunitySpaceManagementApi().fetchCommunities(projectUuid, includeSpaces: true); + PaginationModel paginationModel = await CommunitySpaceManagementApi() + .fetchCommunitiesAndSpaces(projectId: projectUuid, page: 1); // List updatedCommunities = await Future.wait( // communities.map((community) async { @@ -69,12 +75,38 @@ class SpaceTreeBloc extends Bloc { // }).toList(), // ); - emit(state.copyWith(communitiesList: communities, expandedCommunity: [], expandedSpaces: [])); + emit(state.copyWith( + communitiesList: paginationModel.communities, + expandedCommunity: [], + expandedSpaces: [], + paginationModel: paginationModel)); } catch (e) { emit(SpaceTreeErrorState('Error loading communities and spaces: $e')); } } + _fetchPaginationSpaces(PaginationEvent event, Emitter emit) async { + emit(state.copyWith(paginationIsLoading: true)); + PaginationModel paginationModel = event.paginationModel; + List communities = List.from(event.communities); + try { + if (paginationModel.hasNext && state.searchQuery.isEmpty) { + final projectUuid = await ProjectManager.getProjectUUID() ?? ''; + + paginationModel = await CommunitySpaceManagementApi().fetchCommunitiesAndSpaces( + projectId: projectUuid, page: paginationModel.pageNum, search: state.searchQuery); + + communities.addAll(paginationModel.communities); + } + } catch (e) { + emit(SpaceTreeErrorState('Error loading communities and spaces: $e')); + } + emit(state.copyWith( + communitiesList: communities, + paginationModel: paginationModel, + paginationIsLoading: false)); + } + void _onCommunityAdded(OnCommunityAdded event, Emitter emit) async { final updatedCommunities = List.from(state.communityList); updatedCommunities.add(event.newCommunity); @@ -264,28 +296,52 @@ class SpaceTreeBloc extends Bloc { _onSearch(SearchQueryEvent event, Emitter emit) async { try { - List communities = List.from(state.communityList); - List filteredCommunity = []; + const duration = Duration(seconds: 1); + if (_timer.isActive) { + _timer.cancel(); // clear timer + } + _timer = Timer(duration, () async => add(DebouncedSearchEvent(event.searchQuery))); + + // List communities = List.from(state.communityList); + // List filteredCommunity = []; // Filter communities and expand only those that match the query - filteredCommunity = communities.where((community) { - final containsQueryInCommunity = - community.name.toLowerCase().contains(event.searchQuery.toLowerCase()); - final containsQueryInSpaces = - community.spaces.any((space) => _containsQuery(space, event.searchQuery.toLowerCase())); + // filteredCommunity = communities.where((community) { + // final containsQueryInCommunity = + // community.name.toLowerCase().contains(event.searchQuery.toLowerCase()); + // final containsQueryInSpaces = + // community.spaces.any((space) => _containsQuery(space, event.searchQuery.toLowerCase())); - return containsQueryInCommunity || containsQueryInSpaces; - }).toList(); + // return containsQueryInCommunity || containsQueryInSpaces; + // }).toList(); - emit(state.copyWith( - filteredCommunity: filteredCommunity, - isSearching: event.searchQuery.isNotEmpty, - searchQuery: event.searchQuery)); + // emit(state.copyWith( + // filteredCommunity: filteredCommunity, + // isSearching: event.searchQuery.isNotEmpty, + // searchQuery: event.searchQuery)); } catch (e) { emit(const SpaceTreeErrorState('Something went wrong')); } } + _onDebouncedSearch(DebouncedSearchEvent event, Emitter emit) async { + emit(state.copyWith( + isSearching: true, + )); + PaginationModel paginationModel = const PaginationModel.emptyConstructor(); + try { + final projectUuid = await ProjectManager.getProjectUUID() ?? ''; + + paginationModel = await CommunitySpaceManagementApi() + .fetchCommunitiesAndSpaces(projectId: projectUuid, page: 1, search: event.searchQuery); + } catch (_) {} + + emit(state.copyWith( + filteredCommunity: paginationModel.communities, + isSearching: false, + searchQuery: event.searchQuery)); + } + _clearAllData(ClearAllData event, Emitter emit) async { try { emit(state.copyWith( @@ -323,13 +379,13 @@ class SpaceTreeBloc extends Bloc { } // Helper function to determine if any space or its children match the search query - bool _containsQuery(SpaceModel space, String query) { - final matchesSpace = space.name.toLowerCase().contains(query); - final matchesChildren = - space.children.any((child) => _containsQuery(child, query)); // Recursive check for children + // bool _containsQuery(SpaceModel space, String query) { + // final matchesSpace = space.name.toLowerCase().contains(query); + // final matchesChildren = + // space.children.any((child) => _containsQuery(child, query)); // Recursive check for children - return matchesSpace || matchesChildren; - } + // return matchesSpace || matchesChildren; + // } List _getAllChildIds(List spaces) { List ids = []; @@ -403,6 +459,7 @@ class SpaceTreeBloc extends Bloc { @override Future close() async { + _timer.cancel(); super.close(); } } diff --git a/lib/pages/space_tree/bloc/space_tree_event.dart b/lib/pages/space_tree/bloc/space_tree_event.dart index fdf1240b..22254ce0 100644 --- a/lib/pages/space_tree/bloc/space_tree_event.dart +++ b/lib/pages/space_tree/bloc/space_tree_event.dart @@ -1,4 +1,5 @@ import 'package:equatable/equatable.dart'; +import 'package:syncrow_web/pages/space_tree/model/pagination_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; @@ -11,6 +12,16 @@ class SpaceTreeEvent extends Equatable { class InitialEvent extends SpaceTreeEvent {} +class PaginationEvent extends SpaceTreeEvent { + final PaginationModel paginationModel; + final List communities; + + const PaginationEvent(this.paginationModel, this.communities); + + @override + List get props => [paginationModel, communities]; +} + class SearchForSpace extends SpaceTreeEvent { final String searchQuery; @@ -69,6 +80,15 @@ class SearchQueryEvent extends SpaceTreeEvent { List get props => [searchQuery]; } +class DebouncedSearchEvent extends SpaceTreeEvent { + final String searchQuery; + + const DebouncedSearchEvent(this.searchQuery); + + @override + List get props => [searchQuery]; +} + class OnCommunityAdded extends SpaceTreeEvent { final CommunityModel newCommunity; const OnCommunityAdded(this.newCommunity); @@ -85,7 +105,6 @@ class OnCommunityUpdated extends SpaceTreeEvent { List get props => [updatedCommunity]; } - class ClearAllData extends SpaceTreeEvent {} class ClearCachedData extends SpaceTreeEvent {} diff --git a/lib/pages/space_tree/bloc/space_tree_state.dart b/lib/pages/space_tree/bloc/space_tree_state.dart index 915197dc..595380fd 100644 --- a/lib/pages/space_tree/bloc/space_tree_state.dart +++ b/lib/pages/space_tree/bloc/space_tree_state.dart @@ -1,4 +1,5 @@ import 'package:equatable/equatable.dart'; +import 'package:syncrow_web/pages/space_tree/model/pagination_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart'; class SpaceTreeState extends Equatable { @@ -12,6 +13,8 @@ class SpaceTreeState extends Equatable { final List soldCheck; final bool isSearching; final String searchQuery; + final PaginationModel paginationModel; + final bool paginationIsLoading; const SpaceTreeState( {this.communityList = const [], @@ -23,7 +26,9 @@ class SpaceTreeState extends Equatable { this.soldCheck = const [], this.isSearching = false, this.selectedCommunityAndSpaces = const {}, - this.searchQuery = ''}); + this.searchQuery = '', + this.paginationModel = const PaginationModel.emptyConstructor(), + this.paginationIsLoading = false}); SpaceTreeState copyWith( {List? communitiesList, @@ -35,7 +40,9 @@ class SpaceTreeState extends Equatable { List? soldCheck, bool? isSearching, Map>? selectedCommunityAndSpaces, - String? searchQuery}) { + String? searchQuery, + PaginationModel? paginationModel, + bool? paginationIsLoading}) { return SpaceTreeState( communityList: communitiesList ?? this.communityList, filteredCommunity: filteredCommunity ?? this.filteredCommunity, @@ -46,7 +53,9 @@ class SpaceTreeState extends Equatable { soldCheck: soldCheck ?? this.soldCheck, isSearching: isSearching ?? this.isSearching, selectedCommunityAndSpaces: selectedCommunityAndSpaces ?? this.selectedCommunityAndSpaces, - searchQuery: searchQuery ?? this.searchQuery); + searchQuery: searchQuery ?? this.searchQuery, + paginationModel: paginationModel ?? this.paginationModel, + paginationIsLoading: paginationIsLoading ?? this.paginationIsLoading); } @override @@ -60,7 +69,9 @@ class SpaceTreeState extends Equatable { soldCheck, isSearching, selectedCommunityAndSpaces, - searchQuery + searchQuery, + paginationModel, + paginationIsLoading ]; } diff --git a/lib/pages/space_tree/model/pagination_model.dart b/lib/pages/space_tree/model/pagination_model.dart new file mode 100644 index 00000000..c40df1e0 --- /dev/null +++ b/lib/pages/space_tree/model/pagination_model.dart @@ -0,0 +1,20 @@ +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart'; + +class PaginationModel { + final int pageNum; + final bool hasNext; + final int size; + final List communities; + + const PaginationModel( + {required this.pageNum, + required this.hasNext, + required this.size, + required this.communities}); + + const PaginationModel.emptyConstructor() + : pageNum = 1, + hasNext = true, + size = 10, + communities = const []; +} diff --git a/lib/pages/space_tree/view/space_tree_view.dart b/lib/pages/space_tree/view/space_tree_view.dart index 63926852..5b70da06 100644 --- a/lib/pages/space_tree/view/space_tree_view.dart +++ b/lib/pages/space_tree/view/space_tree_view.dart @@ -34,7 +34,8 @@ class _SpaceTreeViewState extends State { @override Widget build(BuildContext context) { return BlocBuilder(builder: (context, state) { - List list = state.isSearching ? state.filteredCommunity : state.communityList; + List list = + state.searchQuery.isNotEmpty ? state.filteredCommunity : state.communityList; return Container( height: MediaQuery.sizeOf(context).height, decoration: widget.isSide == true @@ -61,7 +62,8 @@ class _SpaceTreeViewState extends State { borderRadius: const BorderRadius.all(Radius.circular(20)), border: Border.all(color: ColorsManager.grayBorder)), child: TextFormField( - style: const TextStyle(color: Colors.black), + style: context.textTheme.bodyMedium + ?.copyWith(color: ColorsManager.blackColor), onChanged: (value) { context.read().add(SearchQueryEvent(value)); }, @@ -94,88 +96,101 @@ class _SpaceTreeViewState extends State { ), const SizedBox(height: 16), Expanded( - child: ListView( - shrinkWrap: true, - scrollDirection: Axis.horizontal, - children: [ - Container( - width: MediaQuery.sizeOf(context).width * 0.5, - padding: const EdgeInsets.all(8.0), - child: list.isEmpty - ? Center( - child: Text( - 'No results found', - style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: ColorsManager.lightGrayColor, - fontWeight: FontWeight.w400, + child: state.isSearching + ? const Center(child: CircularProgressIndicator()) + : ListView( + shrinkWrap: true, + scrollDirection: Axis.horizontal, + children: [ + Container( + width: MediaQuery.sizeOf(context).width * 0.5, + padding: const EdgeInsets.all(8.0), + child: list.isEmpty + ? Center( + child: Text( + 'No results found', + style: Theme.of(context).textTheme.bodySmall!.copyWith( + color: ColorsManager.lightGrayColor, + fontWeight: FontWeight.w400, + ), ), - ), - ) - : Scrollbar( - scrollbarOrientation: ScrollbarOrientation.left, - thumbVisibility: true, - controller: _scrollController, - child: Padding( - padding: const EdgeInsets.only(left: 16), - child: ListView( - controller: _scrollController, - shrinkWrap: true, - children: list - .map( - (community) => CustomExpansionTileSpaceTree( - title: community.name, - isSelected: state.selectedCommunities - .contains(community.uuid), - isSoldCheck: state.selectedCommunities - .contains(community.uuid), - onExpansionChanged: () { - context - .read() - .add(OnCommunityExpanded(community.uuid)); - }, - isExpanded: state.expandedCommunities - .contains(community.uuid), - onItemSelected: () { - context.read().add( - OnCommunitySelected( - community.uuid, community.spaces)); - widget.onSelect(); - }, - children: community.spaces.map((space) { - return CustomExpansionTileSpaceTree( - title: space.name, - isExpanded: - state.expandedSpaces.contains(space.uuid), - onItemSelected: () { - context.read().add( - OnSpaceSelected(community, space.uuid ?? '', - space.children)); - widget.onSelect(); - }, - onExpansionChanged: () { - context.read().add( - OnSpaceExpanded( - community.uuid, space.uuid ?? '')); - }, - isSelected: - state.selectedSpaces.contains(space.uuid) || - state.soldCheck.contains(space.uuid), - isSoldCheck: state.soldCheck.contains(space.uuid), - children: _buildNestedSpaces( - context, state, space, community), - ); - }).toList(), - ), - ) - .toList(), - ), - ), - ), - ), - ], - ), + ) + : Scrollbar( + scrollbarOrientation: ScrollbarOrientation.left, + thumbVisibility: true, + controller: _scrollController, + child: NotificationListener( + onNotification: (notification) { + if (notification is ScrollEndNotification && + notification.metrics.extentAfter == 0) { + // If the user has reached the end of the list Load more data + context.read().add(PaginationEvent( + state.paginationModel, state.communityList)); + } + return false; + }, + child: Padding( + padding: const EdgeInsets.only(left: 16), + child: ListView.builder( + shrinkWrap: true, + itemCount: list.length, + controller: _scrollController, + itemBuilder: (context, index) { + return CustomExpansionTileSpaceTree( + title: list[index].name, + isSelected: state.selectedCommunities + .contains(list[index].uuid), + isSoldCheck: state.selectedCommunities + .contains(list[index].uuid), + onExpansionChanged: () { + context.read().add( + OnCommunityExpanded(list[index].uuid)); + }, + isExpanded: state.expandedCommunities + .contains(list[index].uuid), + onItemSelected: () { + context.read().add( + OnCommunitySelected(list[index].uuid, + list[index].spaces)); + widget.onSelect(); + }, + children: list[index].spaces.map((space) { + return CustomExpansionTileSpaceTree( + title: space.name, + isExpanded: state.expandedSpaces + .contains(space.uuid), + onItemSelected: () { + context.read().add( + OnSpaceSelected( + list[index], + space.uuid ?? '', + space.children)); + widget.onSelect(); + }, + onExpansionChanged: () { + context.read().add( + OnSpaceExpanded(list[index].uuid, + space.uuid ?? '')); + }, + isSelected: state.selectedSpaces + .contains(space.uuid) || + state.soldCheck.contains(space.uuid), + isSoldCheck: + state.soldCheck.contains(space.uuid), + children: _buildNestedSpaces( + context, state, space, list[index]), + ); + }).toList(), + ); + }), + ), + ), + ), + ), + ], + ), ), - + if (state.paginationIsLoading) const CircularProgressIndicator(), // Expanded( // child: Padding( // padding: const EdgeInsets.all(8.0), diff --git a/lib/pages/spaces_management/all_spaces/model/community_model.dart b/lib/pages/spaces_management/all_spaces/model/community_model.dart index 14d9d729..d1e27095 100644 --- a/lib/pages/spaces_management/all_spaces/model/community_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/community_model.dart @@ -22,11 +22,11 @@ class CommunityModel { factory CommunityModel.fromJson(Map json) { return CommunityModel( - uuid: json['uuid'], - createdAt: DateTime.parse(json['createdAt']), - updatedAt: DateTime.parse(json['updatedAt']), - name: json['name'], - description: json['description'], + uuid: json['uuid'] ?? '', + createdAt: DateTime.parse(json['createdAt'] ?? ''), + updatedAt: DateTime.parse(json['updatedAt'] ?? ''), + name: json['name'] ?? '', + description: json['description'] ?? '', region: json['region'] != null ? RegionModel.fromJson(json['region']) : null, spaces: json['spaces'] != null ? (json['spaces'] as List).map((space) => SpaceModel.fromJson(space)).toList() diff --git a/lib/services/devices_mang_api.dart b/lib/services/devices_mang_api.dart index 604abaf4..9fe4a2f6 100644 --- a/lib/services/devices_mang_api.dart +++ b/lib/services/devices_mang_api.dart @@ -23,9 +23,7 @@ class DevicesManagementApi { : ApiEndpoints.getAllDevices.replaceAll('{projectId}', projectId), showServerMessage: true, expectedResponseModel: (json) { - List jsonData = communityId.isNotEmpty && spaceId.isNotEmpty - ? json['data'] - : json; + List jsonData = json['data']; List devicesList = jsonData.map((jsonItem) { return AllDevicesModel.fromJson(jsonItem); }).toList(); @@ -93,8 +91,7 @@ class DevicesManagementApi { } } - Future deviceBatchControl( - List uuids, String code, dynamic value) async { + Future deviceBatchControl(List uuids, String code, dynamic value) async { try { final body = { 'devicesUuid': uuids, @@ -118,8 +115,7 @@ class DevicesManagementApi { } } - static Future> getDevicesByGatewayId( - String gatewayId) async { + static Future> getDevicesByGatewayId(String gatewayId) async { final response = await HTTPService().get( path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId), showServerMessage: false, @@ -153,9 +149,7 @@ class DevicesManagementApi { String code, ) async { final response = await HTTPService().get( - path: ApiEndpoints.getDeviceLogs - .replaceAll('{uuid}', uuid) - .replaceAll('{code}', code), + path: ApiEndpoints.getDeviceLogs.replaceAll('{uuid}', uuid).replaceAll('{code}', code), showServerMessage: false, expectedResponseModel: (json) { return DeviceReport.fromJson(json); @@ -228,8 +222,7 @@ class DevicesManagementApi { } } - Future addScheduleRecord( - ScheduleEntry sendSchedule, String uuid) async { + Future addScheduleRecord(ScheduleEntry sendSchedule, String uuid) async { try { final response = await HTTPService().post( path: ApiEndpoints.scheduleByDeviceId.replaceAll('{deviceUuid}', uuid), @@ -246,8 +239,7 @@ class DevicesManagementApi { } } - Future> getDeviceSchedules( - String uuid, String category) async { + Future> getDeviceSchedules(String uuid, String category) async { try { final response = await HTTPService().get( path: ApiEndpoints.getScheduleByDeviceId @@ -270,9 +262,7 @@ class DevicesManagementApi { } Future updateScheduleRecord( - {required bool enable, - required String uuid, - required String scheduleId}) async { + {required bool enable, required String uuid, required String scheduleId}) async { try { final response = await HTTPService().put( path: ApiEndpoints.updateScheduleByDeviceId @@ -293,8 +283,7 @@ class DevicesManagementApi { } } - Future editScheduleRecord( - String uuid, ScheduleEntry newSchedule) async { + Future editScheduleRecord(String uuid, ScheduleEntry newSchedule) async { try { final response = await HTTPService().put( path: ApiEndpoints.scheduleByDeviceId.replaceAll('{deviceUuid}', uuid), diff --git a/lib/services/space_mana_api.dart b/lib/services/space_mana_api.dart index 629f775c..604c8cae 100644 --- a/lib/services/space_mana_api.dart +++ b/lib/services/space_mana_api.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:syncrow_web/pages/space_tree/model/pagination_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/create_subspace_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; @@ -11,8 +12,7 @@ import 'package:syncrow_web/utils/constants/api_const.dart'; class CommunitySpaceManagementApi { // Community Management APIs - Future> fetchCommunities(String projectId, - {int page = 1, bool includeSpaces = false}) async { + Future> fetchCommunities(String projectId, {int page = 1}) async { try { List allCommunities = []; bool hasNext = true; @@ -20,7 +20,9 @@ class CommunitySpaceManagementApi { while (hasNext) { await HTTPService().get( path: ApiEndpoints.getCommunityList.replaceAll('{projectId}', projectId), - queryParameters: {'page': page, 'includeSpaces': includeSpaces}, + queryParameters: { + 'page': page, + }, expectedResponseModel: (json) { try { List jsonData = json['data'] ?? []; @@ -46,6 +48,38 @@ class CommunitySpaceManagementApi { } } + Future fetchCommunitiesAndSpaces( + {required String projectId, int page = 1, String search = ''}) async { + PaginationModel paginationModel = const PaginationModel.emptyConstructor(); + + try { + bool hasNext = false; + await HTTPService().get( + path: ApiEndpoints.getCommunityList.replaceAll('{projectId}', projectId), + queryParameters: {'page': page, 'includeSpaces': true, 'size': 25, 'search': search}, + expectedResponseModel: (json) { + try { + List jsonData = json['data'] ?? []; + hasNext = json['hasNext'] ?? false; + int currentPage = json['page'] ?? 1; + List communityList = jsonData.map((jsonItem) { + return CommunityModel.fromJson(jsonItem); + }).toList(); + + page = currentPage + 1; + paginationModel = PaginationModel( + pageNum: page, hasNext: hasNext, size: 25, communities: communityList); + return paginationModel; + } catch (_) { + hasNext = false; + return []; + } + }, + ); + } catch (_) {} + return paginationModel; + } + Future getCommunityById(String communityId) async { try { final response = await HTTPService().get(