58 lines
1.6 KiB
Dart
58 lines
1.6 KiB
Dart
import 'dart:async';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import 'package:finlytic_app/features/search/repositories/search_repository.dart';
|
|
import 'search_event.dart';
|
|
import 'search_state.dart';
|
|
|
|
export 'search_event.dart';
|
|
export 'search_state.dart';
|
|
|
|
EventTransformer<Event> debounce<Event>(Duration duration) {
|
|
return (events, mapper) => events.switchMap((event) => Stream.value(event).asyncExpand(mapper));
|
|
}
|
|
|
|
extension SwitchMapExtension<T> on Stream<T> {
|
|
Stream<R> switchMap<R>(Stream<R> Function(T event) mapper) {
|
|
StreamController<R>? controller;
|
|
StreamSubscription<T>? inputSub;
|
|
StreamSubscription<R>? outputSub;
|
|
|
|
controller = StreamController<R>(
|
|
onListen: () {
|
|
inputSub = listen((event) {
|
|
outputSub?.cancel();
|
|
outputSub = mapper(event).listen(
|
|
controller?.add,
|
|
onError: controller?.addError,
|
|
);
|
|
}, onDone: () {
|
|
// Wait for last sub to finish or close
|
|
});
|
|
},
|
|
onCancel: () {
|
|
outputSub?.cancel();
|
|
inputSub?.cancel();
|
|
},
|
|
);
|
|
return controller.stream;
|
|
}
|
|
}
|
|
|
|
class SearchBloc extends Bloc<SearchEvent, SearchState> {
|
|
final SearchRepository repository;
|
|
|
|
SearchBloc({required this.repository}) : super(SearchInitial()) {
|
|
on<SearchQueryChanged>(_onSearchQueryChanged);
|
|
}
|
|
|
|
Future<void> _onSearchQueryChanged(SearchQueryChanged event, Emitter<SearchState> emit) async {
|
|
emit(SearchLoading());
|
|
try {
|
|
final results = await repository.searchAssets(event.query);
|
|
emit(SearchLoaded(results));
|
|
} catch (e) {
|
|
emit(const SearchError("Fehler bei der Suche."));
|
|
}
|
|
}
|
|
}
|