import 'package:bloc/bloc.dart'; import 'package:dartz/dartz.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:injectable/injectable.dart'; import '../../../domain/customer/customer.dart'; part 'customer_loader_event.dart'; part 'customer_loader_state.dart'; part 'customer_loader_bloc.freezed.dart'; @injectable class CustomerLoaderBloc extends Bloc { final ICustomerRepository _repository; CustomerLoaderBloc(this._repository) : super(CustomerLoaderState.initial()) { on(_onCustomerLoaderEvent); } Future _onCustomerLoaderEvent( CustomerLoaderEvent event, Emitter emit, ) { return event.map( fetched: (e) async { var newState = state; if (e.isRefresh) { newState = newState.copyWith(isFetching: true); emit(newState); } newState = await _mapFetchedToState(newState, isRefresh: e.isRefresh); emit(newState); }, setSelectedCustomer: (e) async { emit(state.copyWith(selectedCustomer: e.customer)); }, ); } Future _mapFetchedToState( CustomerLoaderState state, { bool isRefresh = false, }) async { state = state.copyWith(isFetching: false); if (state.hasReachedMax && state.customers.isNotEmpty && !isRefresh) { return state; } if (isRefresh) { state = state.copyWith( page: 1, failureOrOption: none(), hasReachedMax: false, customers: [], ); } final failureOrCustomer = await _repository.getCustomer(page: state.page); state = failureOrCustomer.fold( (f) { if (state.customers.isNotEmpty) { return state.copyWith(hasReachedMax: true); } return state.copyWith(failureOrOption: optionOf(f)); }, (customers) { return state.copyWith( customers: List.from(state.customers)..addAll(customers.customers), failureOrOption: none(), page: state.page + 1, hasReachedMax: customers.customers.length < 10, ); }, ); return state; } }