feat(App): update Finlytic Flutter app UI and blocs
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
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."));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user