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."));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
abstract class SearchEvent extends Equatable {
|
||||
const SearchEvent();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class SearchQueryChanged extends SearchEvent {
|
||||
final String query;
|
||||
|
||||
const SearchQueryChanged(this.query);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [query];
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:finlytic_app/features/search/models/search_result_model.dart';
|
||||
|
||||
abstract class SearchState extends Equatable {
|
||||
const SearchState();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class SearchInitial extends SearchState {}
|
||||
|
||||
class SearchLoading extends SearchState {}
|
||||
|
||||
class SearchLoaded extends SearchState {
|
||||
final List<SearchResultModel> results;
|
||||
|
||||
const SearchLoaded(this.results);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [results];
|
||||
}
|
||||
|
||||
class SearchError extends SearchState {
|
||||
final String message;
|
||||
|
||||
const SearchError(this.message);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [message];
|
||||
}
|
||||
Reference in New Issue
Block a user