loadable error screen, reload actions, autoreload
This commit is contained in:
@ -3,9 +3,20 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class BlocModule<TBloc extends StateStreamableSource<TState>, TState> extends StatelessWidget {
|
||||
final TBloc Function(BuildContext context) create;
|
||||
final Widget Function(BuildContext context, TState state) child;
|
||||
const BlocModule({required this.create, required this.child, super.key});
|
||||
final Widget Function(BuildContext context, TBloc bloc, TState state) child;
|
||||
final bool autoRebuild;
|
||||
const BlocModule({required this.create, required this.child, this.autoRebuild = false, super.key});
|
||||
|
||||
Widget rebuildChild(BuildContext context) => child(context, context.watch<TBloc>(), context.watch<TBloc>().state);
|
||||
Widget staticChild(BuildContext context) => child(context, context.read<TBloc>(), context.read<TBloc>().state);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => BlocProvider<TBloc>(create: create, child: BlocBuilder<TBloc, TState>(builder: child));
|
||||
Widget build(BuildContext context) => BlocProvider<TBloc>(
|
||||
create: create,
|
||||
child: Builder(
|
||||
builder: (context) => autoRebuild
|
||||
? rebuildChild(context)
|
||||
: staticChild(context)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -1,28 +1,58 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:hydrated_bloc/hydrated_bloc.dart';
|
||||
|
||||
import '../../loadableState/loading_error.dart';
|
||||
import '../../repository/repository.dart';
|
||||
import 'loadable_hydrated_bloc_event.dart';
|
||||
import '../../loadableState/loadable_state.dart';
|
||||
|
||||
abstract class LoadableHydratedBloc<TEvent extends LoadableHydratedBlocEvent<TState>, TState, TRepository extends Repository<TState>> extends HydratedBloc<LoadableHydratedBlocEvent<TState>, LoadableState<TState>> {
|
||||
abstract class LoadableHydratedBloc<
|
||||
TEvent extends LoadableHydratedBlocEvent<TState>,
|
||||
TState,
|
||||
TRepository extends Repository<TState>
|
||||
> extends HydratedBloc<
|
||||
LoadableHydratedBlocEvent<TState>,
|
||||
LoadableState<TState>
|
||||
> {
|
||||
late TRepository _repository;
|
||||
LoadableHydratedBloc() : super(const LoadableState()) {
|
||||
on<Emit<TState>>((event, emit) => emit(LoadableState(isLoading: event.loading, data: event.state(innerState ?? fromNothing()))));
|
||||
on<Reload<TState>>((event, emit) => emit(LoadableState(isLoading: true, data: innerState)));
|
||||
on<ClearState<TState>>((event, emit) => emit(const LoadableState()));
|
||||
|
||||
on<Error<TState>>((event, emit) => emit(LoadableState(isLoading: false, data: innerState, error: event.error)));
|
||||
|
||||
_repository = repository();
|
||||
loadState();
|
||||
fetch();
|
||||
}
|
||||
|
||||
TState? get innerState => state.data;
|
||||
TRepository get repo => _repository;
|
||||
|
||||
void fetch() {
|
||||
gatherData().catchError(
|
||||
(e) => add(
|
||||
Error(
|
||||
LoadingError(
|
||||
message: e.toString(),
|
||||
enableRetry: true,
|
||||
retry: () {
|
||||
log('Fetch retry on ${TState.toString()}');
|
||||
add(Reload<TState>());
|
||||
fetch();
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
fromJson(Map<String, dynamic> json) => LoadableState(isLoading: true, data: fromStorage(json));
|
||||
@override
|
||||
Map<String, dynamic>? toJson(LoadableState<TState> state) => state.data == null ? {} : state.data.toJson();
|
||||
|
||||
Future<void> loadState();
|
||||
Future<void> gatherData();
|
||||
TRepository repository();
|
||||
|
||||
TState fromNothing();
|
||||
|
@ -1,7 +1,14 @@
|
||||
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});
|
||||
}
|
||||
class ClearState<TState> extends LoadableHydratedBlocEvent<TState> {}
|
||||
class ClearState<TState> extends LoadableHydratedBlocEvent<TState> {}
|
||||
class Error<TState> extends LoadableHydratedBlocEvent<TState> {
|
||||
final LoadingError error;
|
||||
Error(this.error);
|
||||
}
|
||||
class Reload<TState> extends LoadableHydratedBlocEvent<TState> {}
|
||||
|
Reference in New Issue
Block a user