wip: bloc for files
This commit is contained in:
		| @@ -30,16 +30,17 @@ abstract class LoadableHydratedBloc< | ||||
|         isLoading: state.isLoading, | ||||
|         data: event.state(innerState ?? fromNothing()), | ||||
|         lastFetch: state.lastFetch, | ||||
|         reFetch: retry, | ||||
|         reFetch: fetch, | ||||
|         error: state.error, | ||||
|       )); | ||||
|       if(event.fetch) fetch(); | ||||
|     }); | ||||
|  | ||||
|     on<DataGathered<TState>>((event, emit) => emit(LoadableState( | ||||
|       isLoading: false, | ||||
|       data: event.state(innerState ?? fromNothing()), | ||||
|       lastFetch: DateTime.now().millisecondsSinceEpoch, | ||||
|       reFetch: retry, | ||||
|       reFetch: fetch, | ||||
|       error: null, | ||||
|     ))); | ||||
|  | ||||
| @@ -55,7 +56,7 @@ abstract class LoadableHydratedBloc< | ||||
|         isLoading: false, | ||||
|         data: innerState, | ||||
|         lastFetch: state.lastFetch, | ||||
|         reFetch: retry, | ||||
|         reFetch: fetch, | ||||
|         error: event.error | ||||
|     ))); | ||||
|  | ||||
| @@ -66,19 +67,14 @@ abstract class LoadableHydratedBloc< | ||||
|   TState? get innerState => state.data; | ||||
|   TRepository get repo => _repository; | ||||
|  | ||||
|   void retry() { | ||||
|     log('Fetch retry triggered for ${TState.toString()}'); | ||||
|     add(RefetchStarted<TState>()); | ||||
|     fetch(); | ||||
|   } | ||||
|  | ||||
|   void fetch() { | ||||
|     log('Fetching data for ${TState.toString()}'); | ||||
|     add(RefetchStarted<TState>()); | ||||
|     gatherData().catchError( | ||||
|       (e) { | ||||
|         log('Error while fetching ${TState.toString()}: ${e.toString()}'); | ||||
|         add(Error(LoadingError( | ||||
|           message: e.message ?? e.toString(), | ||||
|           message: e.toString(), | ||||
|           allowRetry: true, | ||||
|         ))); | ||||
|       }, | ||||
| @@ -92,7 +88,7 @@ abstract class LoadableHydratedBloc< | ||||
|     var rawData = LoadableSaveContext.unwrap(json); | ||||
|     return LoadableState( | ||||
|       isLoading: true, | ||||
|       data: fromStorage(rawData.data), | ||||
|       data: fromStorage(rawData.data), // TODO fromStorage in isolate | ||||
|       lastFetch: rawData.meta.timestamp, | ||||
|       reFetch: null, | ||||
|       error: null, | ||||
| @@ -103,7 +99,7 @@ abstract class LoadableHydratedBloc< | ||||
|   Map<String, dynamic>? toJson(LoadableState<TState> state) { | ||||
|     Map<String, dynamic>? data; | ||||
|     try { | ||||
|       data = state.data == null ? null : toStorage(state.data); | ||||
|       data = state.data == null ? null : toStorage(state.data); // TODO toStorage in isolate | ||||
|     } catch(e) { | ||||
|       log('Failed to save state ${TState.toString()}: ${e.toString()}'); | ||||
|     } | ||||
|   | ||||
| @@ -3,7 +3,8 @@ import '../../loadableState/loading_error.dart'; | ||||
| class LoadableHydratedBlocEvent<TState> {} | ||||
| class Emit<TState> extends LoadableHydratedBlocEvent<TState> { | ||||
|   final TState Function(TState state) state; | ||||
|   Emit(this.state); | ||||
|   final bool fetch; | ||||
|   Emit(this.state, {this.fetch = false}); | ||||
| } | ||||
| class DataGathered<TState> extends LoadableHydratedBlocEvent<TState> { | ||||
|   final TState Function(TState state) state; | ||||
|   | ||||
| @@ -9,7 +9,7 @@ part of 'loadable_save_context.dart'; | ||||
| _$LoadableSaveContextImpl _$$LoadableSaveContextImplFromJson( | ||||
|         Map<String, dynamic> json) => | ||||
|     _$LoadableSaveContextImpl( | ||||
|       timestamp: json['timestamp'] as int, | ||||
|       timestamp: (json['timestamp'] as num).toInt(), | ||||
|     ); | ||||
|  | ||||
| Map<String, dynamic> _$$LoadableSaveContextImplToJson( | ||||
|   | ||||
| @@ -0,0 +1,48 @@ | ||||
| import 'dart:async'; | ||||
|  | ||||
| import 'package:bloc/bloc.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
|  | ||||
| import 'bloc_module.dart'; | ||||
|  | ||||
| class SwappingBloc<TBloc> { | ||||
|   final TBloc initialBloc; | ||||
|   final StreamController<TBloc> updater = StreamController<TBloc>(); | ||||
|  | ||||
|   SwappingBloc(this.initialBloc); | ||||
|  | ||||
|   void swap(TBloc bloc) { | ||||
|     updater.add(bloc); | ||||
|   } | ||||
| } | ||||
|  | ||||
| class SwappingBlocModule<TBloc extends StateStreamableSource<TState>, TState> extends StatefulWidget { | ||||
|   final SwappingBloc<TBloc> bloc; | ||||
|   final Widget Function(BuildContext context, TBloc bloc, TState state) child; | ||||
|   const SwappingBlocModule({super.key, required this.bloc, required this.child}); | ||||
|  | ||||
|   @override | ||||
|   State<SwappingBlocModule<TBloc, TState>> createState() => _SwappingBlocModuleState<TBloc, TState>(); | ||||
| } | ||||
|  | ||||
| class _SwappingBlocModuleState<TBloc extends StateStreamableSource<TState>, TState> extends State<SwappingBlocModule<TBloc, TState>> { | ||||
|   late TBloc bloc; | ||||
|  | ||||
|   @override | ||||
|   void initState() { | ||||
|     super.initState(); | ||||
|     bloc = widget.bloc.initialBloc; | ||||
|     widget.bloc.updater.stream.listen((event) { | ||||
|       setState(() { | ||||
|         bloc = event; | ||||
|       }); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) => BlocModule<TBloc, TState>( | ||||
|     autoRebuild: true, | ||||
|     create: (context) => bloc, | ||||
|     child: (context, bloc, state) => widget.child(context, bloc, state), | ||||
|   ); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user