wip: bloc for holidays
This commit is contained in:
@ -35,8 +35,12 @@ abstract class DataLoader<TResult> {
|
||||
}
|
||||
|
||||
class DataLoaderResult {
|
||||
final Map<String, dynamic> json;
|
||||
final dynamic json;
|
||||
final Map<String, String> headers;
|
||||
|
||||
Map<String, dynamic> asMap() => json as Map<String, dynamic>;
|
||||
List<dynamic> asList() => json as List<dynamic>;
|
||||
List<Map<String, dynamic>> asListOfMaps() => asList().map((e) => e as Map<String, dynamic>).toList();
|
||||
|
||||
DataLoaderResult({required this.json, required this.headers});
|
||||
}
|
||||
|
@ -1,9 +0,0 @@
|
||||
import 'package:dio/dio.dart';
|
||||
|
||||
import 'data_loader.dart';
|
||||
|
||||
abstract class MhslDataLoader<TResult> extends DataLoader<TResult> {
|
||||
MhslDataLoader() : super(Dio(BaseOptions(
|
||||
baseUrl: 'https://mhsl.eu/marianum/marianummobile/'
|
||||
)));
|
||||
}
|
@ -9,11 +9,11 @@ class LoadableState<TState> with _$LoadableState {
|
||||
const LoadableState._();
|
||||
|
||||
const factory LoadableState({
|
||||
@Default(true) bool isLoading,
|
||||
@Default(null) TState? data,
|
||||
@Default(null) int? lastFetch,
|
||||
@Default(null) void Function()? reFetch,
|
||||
@Default(null) LoadingError? error,
|
||||
required bool isLoading,
|
||||
required TState? data,
|
||||
required int? lastFetch,
|
||||
required void Function()? reFetch,
|
||||
required LoadingError? error,
|
||||
}) = _LoadableState;
|
||||
|
||||
bool _hasError() => error != null;
|
||||
|
@ -89,4 +89,3 @@ class _LoadableStateErrorBarTextState extends State<LoadableStateErrorBarText> {
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,23 +17,40 @@ abstract class LoadableHydratedBloc<
|
||||
LoadableState<TState>
|
||||
> {
|
||||
late TRepository _repository;
|
||||
LoadableHydratedBloc() : super(const LoadableState()) {
|
||||
LoadableHydratedBloc() : super(const LoadableState(
|
||||
error: null,
|
||||
data: null,
|
||||
isLoading: true,
|
||||
lastFetch: null,
|
||||
reFetch: null,
|
||||
)) {
|
||||
|
||||
on<Emit<TState>>((event, emit) => emit(LoadableState(
|
||||
isLoading: event.loading,
|
||||
on<Emit<TState>>((event, emit) {
|
||||
emit(LoadableState(
|
||||
isLoading: state.isLoading,
|
||||
data: event.state(innerState ?? fromNothing()),
|
||||
lastFetch: DateTime.now().millisecondsSinceEpoch,
|
||||
reFetch: retry
|
||||
lastFetch: state.lastFetch,
|
||||
reFetch: retry,
|
||||
error: state.error,
|
||||
));
|
||||
});
|
||||
|
||||
on<DataGathered<TState>>((event, emit) => emit(LoadableState(
|
||||
isLoading: false,
|
||||
data: event.state(innerState ?? fromNothing()),
|
||||
lastFetch: DateTime.now().millisecondsSinceEpoch,
|
||||
reFetch: retry,
|
||||
error: null,
|
||||
)));
|
||||
|
||||
on<RefetchStarted<TState>>((event, emit) => emit(LoadableState(
|
||||
isLoading: true,
|
||||
data: innerState,
|
||||
lastFetch: state.lastFetch
|
||||
lastFetch: state.lastFetch,
|
||||
reFetch: null,
|
||||
error: null,
|
||||
)));
|
||||
|
||||
on<ClearState<TState>>((event, emit) => emit(const LoadableState()));
|
||||
|
||||
on<Error<TState>>((event, emit) => emit(LoadableState(
|
||||
isLoading: false,
|
||||
data: innerState,
|
||||
@ -61,7 +78,7 @@ abstract class LoadableHydratedBloc<
|
||||
(e) {
|
||||
log('Error while fetching ${TState.toString()}: ${e.toString()}');
|
||||
add(Error(LoadingError(
|
||||
message: e.message,
|
||||
message: e.message ?? e.toString(),
|
||||
allowRetry: true,
|
||||
)));
|
||||
},
|
||||
@ -73,14 +90,30 @@ abstract class LoadableHydratedBloc<
|
||||
@override
|
||||
fromJson(Map<String, dynamic> json) {
|
||||
var rawData = LoadableSaveContext.unwrap(json);
|
||||
return LoadableState(isLoading: true, lastFetch: rawData.meta.timestamp, data: fromStorage(rawData.data));
|
||||
return LoadableState(
|
||||
isLoading: true,
|
||||
data: fromStorage(rawData.data),
|
||||
lastFetch: rawData.meta.timestamp,
|
||||
reFetch: null,
|
||||
error: null,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic>? toJson(LoadableState<TState> state) => LoadableSaveContext.wrap(
|
||||
toStorage(state.data),
|
||||
Map<String, dynamic>? toJson(LoadableState<TState> state) {
|
||||
Map<String, dynamic>? data;
|
||||
try {
|
||||
data = toStorage(state.data);
|
||||
} catch(e) {
|
||||
log('Failed to save state ${TState.toString()}: ${e.toString()}');
|
||||
data = null;
|
||||
}
|
||||
|
||||
return LoadableSaveContext.wrap(
|
||||
data,
|
||||
state.lastFetch ?? DateTime.now().millisecondsSinceEpoch
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> gatherData();
|
||||
TRepository repository();
|
||||
|
@ -3,10 +3,12 @@ import '../../loadableState/loading_error.dart';
|
||||
class LoadableHydratedBlocEvent<TState> {}
|
||||
class Emit<TState> extends LoadableHydratedBlocEvent<TState> {
|
||||
final TState Function(TState state) state;
|
||||
final bool loading;
|
||||
Emit(this.state, {this.loading = false});
|
||||
Emit(this.state);
|
||||
}
|
||||
class DataGathered<TState> extends LoadableHydratedBlocEvent<TState> {
|
||||
final TState Function(TState state) state;
|
||||
DataGathered(this.state);
|
||||
}
|
||||
class ClearState<TState> extends LoadableHydratedBlocEvent<TState> {}
|
||||
class Error<TState> extends LoadableHydratedBlocEvent<TState> {
|
||||
final LoadingError error;
|
||||
Error(this.error);
|
||||
|
@ -21,4 +21,3 @@ class LoadableSaveContext with _$LoadableSaveContext {
|
||||
static ({Map<String, dynamic> data, LoadableSaveContext meta}) unwrap(Map<String, dynamic> data) =>
|
||||
(data: data[dataKey] as Map<String, dynamic>, meta: LoadableSaveContext.fromJson(data[metaKey]));
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user