import 'package:bloc/bloc.dart'; import 'package:dartz/dartz.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:injectable/injectable.dart'; import '../../../domain/table/table.dart'; part 'table_loader_event.dart'; part 'table_loader_state.dart'; part 'table_loader_bloc.freezed.dart'; @injectable class TableLoaderBloc extends Bloc { final ITableRepository _repository; TableLoaderBloc(this._repository) : super(TableLoaderState.initial()) { on(_onTableLoadedEvent); } Future _onTableLoadedEvent( TableLoaderEvent 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); }, ); } Future _mapFetchedToState( TableLoaderState state, { bool isRefresh = false, }) async { state = state.copyWith(isFetching: false); if (state.hasReachedMax && state.tables.isNotEmpty && !isRefresh) { return state; } if (isRefresh) { state = state.copyWith( page: 1, failureOption: none(), hasReachedMax: false, tables: [], ); } final failureOrTable = await _repository.fetchTables(page: state.page); state = failureOrTable.fold( (f) { if (state.tables.isNotEmpty) { return state.copyWith(hasReachedMax: true); } return state.copyWith(failureOption: optionOf(f)); }, (tables) { return state.copyWith( tables: List.from(state.tables)..addAll(tables.tables), failureOption: none(), page: state.page + 1, hasReachedMax: tables.tables.length < 10, ); }, ); return state; } }