import 'package:bloc/bloc.dart'; import 'package:flutter/foundation.dart'; import 'package:logging/logging.dart'; import 'package:nc_photos/account.dart'; import 'package:nc_photos/di_container.dart'; import 'package:nc_photos/entity/person.dart'; import 'package:nc_photos/use_case/list_location_group.dart'; import 'package:nc_photos/use_case/list_person.dart'; import 'package:np_codegen/np_codegen.dart'; import 'package:to_string/to_string.dart'; part 'search_landing.g.dart'; abstract class SearchLandingBlocEvent { const SearchLandingBlocEvent(); } @toString class SearchLandingBlocQuery extends SearchLandingBlocEvent { const SearchLandingBlocQuery(this.account); @override String toString() => _$toString(); final Account account; } @toString abstract class SearchLandingBlocState { const SearchLandingBlocState(this.account, this.persons, this.locations); @override String toString() => _$toString(); final Account? account; final List persons; final LocationGroupResult locations; } class SearchLandingBlocInit extends SearchLandingBlocState { SearchLandingBlocInit() : super(null, const [], const LocationGroupResult([], [], [], [])); } class SearchLandingBlocLoading extends SearchLandingBlocState { const SearchLandingBlocLoading( Account? account, List persons, LocationGroupResult locations) : super(account, persons, locations); } class SearchLandingBlocSuccess extends SearchLandingBlocState { const SearchLandingBlocSuccess( Account? account, List persons, LocationGroupResult locations) : super(account, persons, locations); } @toString class SearchLandingBlocFailure extends SearchLandingBlocState { const SearchLandingBlocFailure(Account? account, List persons, LocationGroupResult locations, this.exception) : super(account, persons, locations); @override String toString() => _$toString(); final Object exception; } @npLog class SearchLandingBloc extends Bloc { SearchLandingBloc(this._c) : assert(require(_c)), assert(ListPerson.require(_c)), super(SearchLandingBlocInit()) { on(_onEvent); } static bool require(DiContainer c) => true; Future _onEvent(SearchLandingBlocEvent event, Emitter emit) async { _log.info("[_onEvent] $event"); if (event is SearchLandingBlocQuery) { await _onEventQuery(event, emit); } } Future _onEventQuery( SearchLandingBlocQuery ev, Emitter emit) async { try { emit( SearchLandingBlocLoading(ev.account, state.persons, state.locations)); List? persons; try { persons = await _queryPeople(ev); } catch (e, stackTrace) { _log.shout("[_onEventQuery] Failed while _queryPeople", e, stackTrace); } LocationGroupResult? locations; try { locations = await _queryLocations(ev); } catch (e, stackTrace) { _log.shout( "[_onEventQuery] Failed while _queryLocations", e, stackTrace); } emit(SearchLandingBlocSuccess(ev.account, persons ?? [], locations ?? const LocationGroupResult([], [], [], []))); } catch (e, stackTrace) { _log.severe("[_onEventQuery] Exception while request", e, stackTrace); emit(SearchLandingBlocFailure( ev.account, state.persons, state.locations, e)); } } Future> _queryPeople(SearchLandingBlocQuery ev) => ListPerson(_c.withLocalRepo())(ev.account); Future _queryLocations(SearchLandingBlocQuery ev) => ListLocationGroup(_c.withLocalRepo())(ev.account); final DiContainer _c; }