From 754f919cdcc8a5954b4bba03b0255bcce4dfc507 Mon Sep 17 00:00:00 2001 From: Vaibhav Surve Date: Wed, 6 Aug 2025 16:18:50 +0530 Subject: [PATCH] added infinite loading --- .../expense/expense_screen_controller.dart | 38 ++++++++++++++++++- lib/view/expense/expense_screen.dart | 36 ++++++++++++------ 2 files changed, 61 insertions(+), 13 deletions(-) diff --git a/lib/controller/expense/expense_screen_controller.dart b/lib/controller/expense/expense_screen_controller.dart index a0a012a..0790ba5 100644 --- a/lib/controller/expense/expense_screen_controller.dart +++ b/lib/controller/expense/expense_screen_controller.dart @@ -32,7 +32,7 @@ class ExpenseController extends GetxController { final RxList selectedCreatedByEmployees = [].obs; final RxString selectedDateType = 'Transaction Date'.obs; - + final employeeSearchController = TextEditingController(); final isSearchingEmployees = false.obs; final employeeSearchResults = [].obs; @@ -283,6 +283,42 @@ class ExpenseController extends GetxController { update(); } + Future loadMoreExpenses() async { + if (isLoading.value) return; + + _pageNumber += 1; + isLoading.value = true; + + final Map filterMap = { + "projectIds": selectedProject.value.isEmpty + ? [] + : [projectsMap[selectedProject.value] ?? ''], + "statusIds": selectedStatus.value.isEmpty ? [] : [selectedStatus.value], + "createdByIds": selectedCreatedByEmployees.map((e) => e.id).toList(), + "paidByIds": selectedPaidByEmployees.map((e) => e.id).toList(), + "startDate": startDate.value?.toIso8601String(), + "endDate": endDate.value?.toIso8601String(), + "isTransactionDate": selectedDateType.value == 'Transaction Date', + }; + + try { + final result = await ApiService.getExpenseListApi( + filter: jsonEncode(filterMap), + pageSize: _pageSize, + pageNumber: _pageNumber, + ); + + if (result != null) { + final expenseResponse = ExpenseResponse.fromJson(result); + expenses.addAll(expenseResponse.data.data); + } + } catch (e) { + logSafe("Error in loadMoreExpenses: $e", level: LogLevel.error); + } finally { + isLoading.value = false; + } + } + /// Update expense status Future updateExpenseStatus(String expenseId, String statusId) async { isLoading.value = true; diff --git a/lib/view/expense/expense_screen.dart b/lib/view/expense/expense_screen.dart index d9bfd53..0309b3c 100644 --- a/lib/view/expense/expense_screen.dart +++ b/lib/view/expense/expense_screen.dart @@ -90,7 +90,8 @@ class _ExpenseMainScreenState extends State { ), Expanded( child: Obx(() { - if (expenseController.isLoading.value) { + if (expenseController.isLoading.value && + expenseController.expenses.isEmpty) { return SkeletonLoaders.expenseListSkeletonLoader(); } @@ -104,9 +105,20 @@ class _ExpenseMainScreenState extends State { } final filteredList = _getFilteredExpenses(); - return ExpenseList( - expenseList: filteredList, - onViewDetail: () => expenseController.fetchExpenses(), + + return NotificationListener( + onNotification: (ScrollNotification scrollInfo) { + if (scrollInfo.metrics.pixels == + scrollInfo.metrics.maxScrollExtent && + !expenseController.isLoading.value) { + expenseController.loadMoreExpenses(); + } + return false; + }, + child: ExpenseList( + expenseList: filteredList, + onViewDetail: () => expenseController.fetchExpenses(), + ), ); }), ), @@ -115,14 +127,14 @@ class _ExpenseMainScreenState extends State { ), // ✅ FAB only if user has expenseUpload permission - floatingActionButton: permissionController - .hasPermission(Permissions.expenseUpload) - ? FloatingActionButton( - backgroundColor: Colors.red, - onPressed: showAddExpenseBottomSheet, - child: const Icon(Icons.add, color: Colors.white), - ) - : null, + floatingActionButton: + permissionController.hasPermission(Permissions.expenseUpload) + ? FloatingActionButton( + backgroundColor: Colors.red, + onPressed: showAddExpenseBottomSheet, + child: const Icon(Icons.add, color: Colors.white), + ) + : null, ); } }