From 4d3fcfcc1c4b2cd0fef41da93068afc4115feebb Mon Sep 17 00:00:00 2001 From: kimwest00 Date: Tue, 17 Oct 2023 17:35:24 +0900 Subject: [PATCH] =?UTF-8?q?feat:#35=20add=20pagination=20+=20search=20api?= =?UTF-8?q?=20=EA=B2=80=EC=83=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../donation_search_controller.dart | 30 ++++++- .../view/donation_search_view.dart | 87 +++++++++++-------- lib/provider/api/project_api.dart | 7 +- 3 files changed, 83 insertions(+), 41 deletions(-) diff --git a/lib/modules/donation_search/controller/donation_search_controller.dart b/lib/modules/donation_search/controller/donation_search_controller.dart index 45b0265a..03692542 100644 --- a/lib/modules/donation_search/controller/donation_search_controller.dart +++ b/lib/modules/donation_search/controller/donation_search_controller.dart @@ -11,20 +11,24 @@ import 'package:match/util/method/get_storage.dart'; import '../../../model/enum/search_statu.dart'; import '../../../model/search/search.dart'; import '../../../model/today_project/today_project.dart'; +import '../../../provider/api/project_api.dart'; import '../../../provider/api/search_api.dart'; +import '../../../provider/api/util/global_api_field.dart'; import '../../../util/const/style/global_logger.dart'; class DonationSearchController extends GetxController { //검색 필드 controller Rx searchTextController = TextEditingController().obs; - //최근 검색어 위젯 활성화 여부 Rx searchStatus = SEARCH_STATUS.INIT.obs; + + ///* 검색 결과 리스트 RxList projectList = [].obs; + RxInt totalSearchLength = 0.obs; ///* 추천 검색어 리스트 - RxList recommendSearchList = [].obs; + RxList recommendSearchList = List.generate(10, (index) => "").obs; ///* 아래 함수에서 사용하는 1초를 측정하는 Timer Timer? _timer; @@ -56,6 +60,28 @@ class DonationSearchController extends GetxController { }); } + Future getSearchList({required String content}) async { + projectList.assignAll(await ProjectApi.getProjectList(content: content)); + totalSearchLength.value = ProjectApi.project.totalCnt; + + searchStatus.value = SEARCH_STATUS.SEARCH; + } + + Future getMoreSearchList( + {required String content, required int index}) async { + logger.d( + "2: 총 페이지수 : ${ProjectApi.project.totalCnt ~/ PAGINATION_SIZE}, 불러오고자 하는 페이지: ${index}"); + if (!(ProjectApi.project.totalCnt ~/ PAGINATION_SIZE >= index) && + !ProjectApi.project.isLast) { + ProjectApi.project.currentpage = index; + searchStatus.value = SEARCH_STATUS.SEARCH; + projectList.addAll(await ProjectApi.getProjectList( + getMore: true, + content: content, + )); + } + } + @override Future dispose() async { searchTextController.value.dispose(); diff --git a/lib/modules/donation_search/view/donation_search_view.dart b/lib/modules/donation_search/view/donation_search_view.dart index 7e763fb8..b0b8806c 100644 --- a/lib/modules/donation_search/view/donation_search_view.dart +++ b/lib/modules/donation_search/view/donation_search_view.dart @@ -11,9 +11,11 @@ import 'package:match/util/method/get_storage.dart'; import '../../../model/enum/search_statu.dart'; import '../../../model/recent_search/recent_search.dart'; import '../../../provider/api/search_api.dart'; +import '../../../provider/api/util/global_api_field.dart'; import '../../../util/components/gloabl_text_field.dart'; import '../../../util/const/global_variable.dart'; import '../../../util/const/style/global_color.dart'; +import '../../../util/const/style/global_logger.dart'; import '../../../util/const/style/global_text_styles.dart'; import '../../donate/widget/donate_widget.dart'; import '../controller/donation_search_controller.dart'; @@ -39,9 +41,7 @@ class DonationSearchScreen extends GetView { textStatus: controller.searchStatus, suffixOnTap: () async {}, onSubmitted: (value) async { - //TODO: add search api - // controller.projectList.addAll( - // await SearchApi.getSearchResult(content: value)); + await controller.getSearchList(content: value); }, onChanged: (value) async {}), ), @@ -76,8 +76,14 @@ class DonationSearchScreen extends GetView { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - recentSearchList(startIdx: 1,keywords: controller.recommendSearchList.sublist(0,5)), - recentSearchList(startIdx: 6,keywords: controller.recommendSearchList.sublist(5,10)), + recentSearchList( + startIdx: 1, + keywords: controller.recommendSearchList + .sublist(0, 5)), + recentSearchList( + startIdx: 6, + keywords: controller.recommendSearchList + .sublist(5, 10)), ], ), ], @@ -88,7 +94,7 @@ class DonationSearchScreen extends GetView { ? Padding( padding: EdgeInsets.only(left: 33.w), child: Text( - "총 ${controller.projectList.length}개의 검색결과", + "총 ${controller.totalSearchLength.value}개의 검색결과", style: AppTextStyles.T1Bold13.copyWith( color: AppColors.grey5, fontWeight: FontWeight.w600), @@ -98,42 +104,48 @@ class DonationSearchScreen extends GetView { SizedBox( height: 20.h, ), - // 검색 field 밑의 contents - //*4.프로젝트 리스트 - controller.searchStatus.value == SEARCH_STATUS.SEARCH - ? controller.searchStatus.value == SEARCH_STATUS.SEARCH - ? Expanded( - child: ListView.separated( - shrinkWrap: true, - separatorBuilder: (context, index) => - SizedBox(height: 14.h), - itemCount: controller.projectList.length, - itemBuilder: (context, index) { - final project = controller.projectList[index]; - return Container( - padding: EdgeInsets.symmetric(horizontal: 20.w), - margin: EdgeInsets.only( - bottom: - index == controller.projectList.length - 1 + + Expanded( + child: // 검색 field 밑의 contents + //*4.프로젝트 리스트 + controller.searchStatus.value == SEARCH_STATUS.SEARCH + ? controller.projectList.isNotEmpty + ? ListView.builder( + shrinkWrap: true, + itemCount: controller.projectList.length, + itemBuilder: (context, index) { + if (index % (PAGINATION_SIZE - 1) == 0 && + index != 0) { + logger.d("1. getMoreFlame 호출!"); + Future.wait({ + controller.getMoreSearchList( + content: controller + .searchTextController.value.text, + index: index ~/ (PAGINATION_SIZE - 1)) + }); + } + final project = controller.projectList[index]; + return Container( + padding: + EdgeInsets.symmetric(horizontal: 20.w,vertical: 8.h).copyWith(top: 0), + margin: EdgeInsets.only( + bottom: index == + controller.projectList.length - 1 ? 14.h : 0.h), - child: ProjectWidget(project: project)); - }, - ), - ) - : Center( - child: Text( - "최근 검색 결과가 없습니다", - style: AppTextStyles.T1Bold18, - ), - ) - : SizedBox.shrink(), + child: ProjectWidget(project: project)); + }, + ) + : Center(child: emptyWidget()) + : const SizedBox.shrink(), + ) ], ), )); } - Widget recentSearchList({required int startIdx, required List keywords }) { + Widget recentSearchList( + {required int startIdx, required List keywords}) { return Wrap( direction: Axis.vertical, spacing: 12.h, @@ -147,10 +159,9 @@ class DonationSearchScreen extends GetView { Widget _recentSearchItem({required int priority, required String keyword}) { return GestureDetector( - onTap: (){ + onTap: () async { controller.searchTextController.value.text = keyword; - //TODO: add search api - controller.searchStatus.value = SEARCH_STATUS.SEARCH; + await controller.getSearchList(content: keyword); }, child: SizedBox( width: 120.w, diff --git a/lib/provider/api/project_api.dart b/lib/provider/api/project_api.dart index e9ad2155..9ce3d32f 100644 --- a/lib/provider/api/project_api.dart +++ b/lib/provider/api/project_api.dart @@ -2,6 +2,7 @@ import 'package:dio/dio.dart'; import 'package:match/model/enum/project_type.dart'; import 'package:match/model/project_detail/project_detail.dart'; import 'package:match/model/project_history.dart/project_history.dart'; +import 'package:match/modules/donate/view/donate_view.dart'; import 'package:match/provider/api/util/dio_services.dart'; import 'package:match/provider/api/util/global_api_field.dart'; @@ -15,6 +16,8 @@ class ProjectApi { static Pagination projectHistory = Pagination(isLast: false, totalCnt: 0); ///

3-5 API | 프로젝트 리스트

+ ///* search탭에서 공통으로 사용 + ///* [DonateScreen] , [DonationSearchScreen] 에서 사용 ///* pagination static Future> getProjectList({ ProjectType? type, @@ -23,7 +26,6 @@ class ProjectApi { }) async { if (!getMore) { project.currentpage = 0; - } var queryParameters = { "page": project.currentpage, @@ -33,6 +35,9 @@ class ProjectApi { if (type != null) { queryParameters['projectKind'] = type.name; } + if (content != null) { + queryParameters['content'] = content; + } try { Response response = await DioServices() .to()