import 'package:bloc/bloc.dart'; import 'package:dartz/dartz.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:injectable/injectable.dart'; import '../../../domain/outlet/outlet.dart'; part 'outlet_loader_event.dart'; part 'outlet_loader_state.dart'; part 'outlet_loader_bloc.freezed.dart'; @injectable class OutletLoaderBloc extends Bloc { final IOutletRepository _outletRepository; OutletLoaderBloc(this._outletRepository) : super(OutletLoaderState.initial()) { on(_onOutletLoaderEvent); } Future _onOutletLoaderEvent( OutletLoaderEvent event, Emitter emit, ) { return event.map( fetched: (e) async { var newState = state; if (e.isRefresh) { newState = state.copyWith(isFetching: true); emit(newState); } newState = await _mapFetchedToState(state, isRefresh: e.isRefresh); emit(newState); }, ); } Future _mapFetchedToState( OutletLoaderState state, { bool isRefresh = false, }) async { state = state.copyWith(isFetching: false); if (state.hasReachedMax && state.outlets.isNotEmpty && !isRefresh) { return state; } if (isRefresh) { state = state.copyWith( page: 1, failureOptionOutlet: none(), hasReachedMax: false, outlets: [], ); } final failureOrOutlet = await _outletRepository.getOutlets( page: state.page, ); state = failureOrOutlet.fold( (f) { if (state.outlets.isNotEmpty) { return state.copyWith(hasReachedMax: true); } return state.copyWith(failureOptionOutlet: optionOf(f)); }, (outlets) { return state.copyWith( outlets: List.from(state.outlets)..addAll(outlets), failureOptionOutlet: none(), page: state.page + 1, hasReachedMax: outlets.length < 10, ); }, ); return state; } }