119 lines
3.3 KiB
Dart
119 lines
3.3 KiB
Dart
import 'dart:async';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import '../data/models.dart';
|
|
import 'providers.dart';
|
|
|
|
class PaginatedTransactionState {
|
|
final List<Transaction> transactions;
|
|
final bool isLoading;
|
|
final bool hasMore;
|
|
final String? type;
|
|
final int? walletId;
|
|
final int? categoryId;
|
|
final String? search;
|
|
|
|
PaginatedTransactionState({
|
|
required this.transactions,
|
|
this.isLoading = false,
|
|
this.hasMore = true,
|
|
this.type,
|
|
this.walletId,
|
|
this.categoryId,
|
|
this.search,
|
|
});
|
|
|
|
PaginatedTransactionState copyWith({
|
|
List<Transaction>? transactions,
|
|
bool? isLoading,
|
|
bool? hasMore,
|
|
String? type,
|
|
int? walletId,
|
|
int? categoryId,
|
|
String? search,
|
|
}) {
|
|
return PaginatedTransactionState(
|
|
transactions: transactions ?? this.transactions,
|
|
isLoading: isLoading ?? this.isLoading,
|
|
hasMore: hasMore ?? this.hasMore,
|
|
type: type != null ? (type == 'ALL' ? null : type) : this.type,
|
|
walletId: walletId != null ? (walletId == -1 ? null : walletId) : this.walletId,
|
|
categoryId: categoryId != null ? (categoryId == -1 ? null : categoryId) : this.categoryId,
|
|
search: search != null ? (search == '' ? null : search) : this.search,
|
|
);
|
|
}
|
|
}
|
|
|
|
class PaginatedTransactionNotifier extends Notifier<PaginatedTransactionState> {
|
|
int _currentPage = 0;
|
|
|
|
@override
|
|
PaginatedTransactionState build() {
|
|
_currentPage = 0;
|
|
Future.microtask(() => loadMore());
|
|
return PaginatedTransactionState(transactions: []);
|
|
}
|
|
|
|
void updateFilters({String? type, int? walletId, int? categoryId, String? search}) {
|
|
state = state.copyWith(
|
|
type: type,
|
|
walletId: walletId,
|
|
categoryId: categoryId,
|
|
search: search,
|
|
transactions: [], // reset
|
|
hasMore: true,
|
|
);
|
|
_currentPage = 0;
|
|
loadMore();
|
|
}
|
|
|
|
void clearFilters() {
|
|
state = PaginatedTransactionState(transactions: []);
|
|
_currentPage = 0;
|
|
loadMore();
|
|
}
|
|
|
|
Future<void> loadMore() async {
|
|
if (state.isLoading || !state.hasMore) return;
|
|
|
|
state = state.copyWith(isLoading: true);
|
|
try {
|
|
final repository = ref.read(apiRepositoryProvider);
|
|
final response = await repository.searchTransactions(
|
|
page: _currentPage,
|
|
size: 20,
|
|
type: state.type,
|
|
walletId: state.walletId,
|
|
categoryId: state.categoryId,
|
|
search: state.search,
|
|
);
|
|
|
|
final newContent = response['content'] as List<Transaction>;
|
|
final totalPages = response['totalPages'] as int;
|
|
|
|
_currentPage++;
|
|
|
|
state = state.copyWith(
|
|
transactions: [...state.transactions, ...newContent],
|
|
isLoading: false,
|
|
hasMore: _currentPage < totalPages,
|
|
);
|
|
} catch (_) {
|
|
state = state.copyWith(isLoading: false);
|
|
}
|
|
}
|
|
|
|
void removeTransactionFromState(int id) {
|
|
final updatedList = state.transactions.where((t) => t.id != id).toList();
|
|
state = state.copyWith(transactions: updatedList);
|
|
}
|
|
|
|
void updateTransactionInState(Transaction tx) {
|
|
final updatedList = state.transactions.map((t) => t.id == tx.id ? tx : t).toList();
|
|
state = state.copyWith(transactions: updatedList);
|
|
}
|
|
}
|
|
|
|
final paginatedTransactionProvider = NotifierProvider<PaginatedTransactionNotifier, PaginatedTransactionState>(() {
|
|
return PaginatedTransactionNotifier();
|
|
});
|