bloc/feature/fix_and_repo #24
| @ -54,6 +54,14 @@ abstract class BlocBaseProviderScreen<Bloc extends BlocBase<State>, | |||||||
|   /// Creates the [Bloc] or [Cubit] to be used. |   /// Creates the [Bloc] or [Cubit] to be used. | ||||||
|   Bloc create(BuildContext context); |   Bloc create(BuildContext context); | ||||||
| 
 | 
 | ||||||
|  |   /// Initialize the [Bloc] or [Cubit]. | ||||||
|  |   /// | ||||||
|  |   /// This function is useful when using with [SmartProvider], because | ||||||
|  |   /// if you want to pass an initial event to your bloc you can pass it in | ||||||
|  |   /// `create` function but if you re-use the bloc below in the tree this event | ||||||
|  |   /// will never be re-pass. | ||||||
|  |   Bloc init(BuildContext context, Bloc bloc) => bloc; | ||||||
|  | 
 | ||||||
|   /// Creates the child [Widget] to be used. |   /// Creates the child [Widget] to be used. | ||||||
|   Widget builder(BuildContext context); |   Widget builder(BuildContext context); | ||||||
| 
 | 
 | ||||||
| @ -63,6 +71,7 @@ abstract class BlocBaseProviderScreen<Bloc extends BlocBase<State>, | |||||||
|         lazy: lazy, |         lazy: lazy, | ||||||
|         enable: smart, |         enable: smart, | ||||||
|         create: (_) => create(context), |         create: (_) => create(context), | ||||||
|  |         init: (_, bloc) => init(context, bloc), | ||||||
|         child: Builder(builder: builder), |         child: Builder(builder: builder), | ||||||
|       ); |       ); | ||||||
| } | } | ||||||
|  | |||||||
| @ -40,7 +40,6 @@ abstract class BlocBaseScreen<Bloc extends BlocBase<State>, | |||||||
|   /// accessed the first time, not when provided. |   /// accessed the first time, not when provided. | ||||||
|   final bool lazy; |   final bool lazy; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|   /// Whether this uses [SmartProvider]. |   /// Whether this uses [SmartProvider]. | ||||||
|   /// Defaults to `true`. But if you want to provide new Bloc of a same type, |   /// Defaults to `true`. But if you want to provide new Bloc of a same type, | ||||||
|   /// in a sub-tree you may have to disable this. |   /// in a sub-tree you may have to disable this. | ||||||
| @ -49,12 +48,21 @@ abstract class BlocBaseScreen<Bloc extends BlocBase<State>, | |||||||
|   /// Creates the [Cubit] or [Bloc] to be used. |   /// Creates the [Cubit] or [Bloc] to be used. | ||||||
|   Bloc create(BuildContext context); |   Bloc create(BuildContext context); | ||||||
| 
 | 
 | ||||||
|  |   /// Initialize the [Bloc] or [Cubit]. | ||||||
|  |   /// | ||||||
|  |   /// This function is useful when using with [SmartProvider], because | ||||||
|  |   /// if you want to pass an initial event to your bloc you can pass it in | ||||||
|  |   /// `create` function but if you re-use the bloc below in the tree this event | ||||||
|  |   /// will never be re-pass. | ||||||
|  |   Bloc init(BuildContext context, Bloc bloc) => bloc; | ||||||
|  | 
 | ||||||
|   @override |   @override | ||||||
|   Widget build(BuildContext context) => SmartProvider.bloc<Bloc, State>( |   Widget build(BuildContext context) => SmartProvider.bloc<Bloc, State>( | ||||||
|         context, |         context, | ||||||
|         lazy: lazy, |         lazy: lazy, | ||||||
|         enable: smart, |         enable: smart, | ||||||
|         create: (_) => create(context), |         create: (_) => create(context), | ||||||
|  |         init: (_, bloc) => init(context, bloc), | ||||||
|         child: super.build(context), |         child: super.build(context), | ||||||
|       ); |       ); | ||||||
| } | } | ||||||
|  | |||||||
| @ -53,6 +53,14 @@ abstract class RepositoryBaseProviderScreen<Repository> | |||||||
|   /// Creates the [Repository] to be used. |   /// Creates the [Repository] to be used. | ||||||
|   Repository create(BuildContext context); |   Repository create(BuildContext context); | ||||||
| 
 | 
 | ||||||
|  |   /// Initialize the [Repository]. | ||||||
|  |   /// | ||||||
|  |   /// This function is useful when using with [SmartProvider], because | ||||||
|  |   /// if you want to pass an initial call on your repository you can | ||||||
|  |   /// call it in `create` function but if you re-provide the repo below in the | ||||||
|  |   /// tree this action will never be call again. | ||||||
|  |   Repository init(BuildContext context, Repository repository) => repository; | ||||||
|  | 
 | ||||||
|   /// Creates the child [Widget] to be used. |   /// Creates the child [Widget] to be used. | ||||||
|   Widget builder(BuildContext context); |   Widget builder(BuildContext context); | ||||||
| 
 | 
 | ||||||
| @ -62,6 +70,7 @@ abstract class RepositoryBaseProviderScreen<Repository> | |||||||
|         lazy: lazy, |         lazy: lazy, | ||||||
|         enable: smart, |         enable: smart, | ||||||
|         create: (_) => create(context), |         create: (_) => create(context), | ||||||
|  |         init: (_, repository) => init(context, repository), | ||||||
|         child: Builder(builder: builder), |         child: Builder(builder: builder), | ||||||
|       ); |       ); | ||||||
| } | } | ||||||
|  | |||||||
| @ -22,6 +22,7 @@ abstract class SmartProvider { | |||||||
|       bloc<Bloc extends BlocBase<State>, State extends Object>( |       bloc<Bloc extends BlocBase<State>, State extends Object>( | ||||||
|     BuildContext context, { |     BuildContext context, { | ||||||
|     required Bloc Function(BuildContext) create, |     required Bloc Function(BuildContext) create, | ||||||
|  |     required Bloc Function(BuildContext, Bloc) init, | ||||||
|     Widget? child, |     Widget? child, | ||||||
|     bool lazy = true, |     bool lazy = true, | ||||||
|     bool enable = true, |     bool enable = true, | ||||||
| @ -29,8 +30,9 @@ abstract class SmartProvider { | |||||||
|     if (enable) { |     if (enable) { | ||||||
|       final bloc = context.read<Bloc?>(); |       final bloc = context.read<Bloc?>(); | ||||||
|       if (bloc != null) { |       if (bloc != null) { | ||||||
|  |         final b = bloc; | ||||||
|         return BlocProvider<Bloc>.value( |         return BlocProvider<Bloc>.value( | ||||||
|           value: bloc, |           value: init(context, b), | ||||||
|           child: child, |           child: child, | ||||||
|         ); |         ); | ||||||
|       } |       } | ||||||
| @ -38,7 +40,7 @@ abstract class SmartProvider { | |||||||
| 
 | 
 | ||||||
|     return BlocProvider<Bloc>( |     return BlocProvider<Bloc>( | ||||||
|       lazy: lazy, |       lazy: lazy, | ||||||
|       create: (_) => create(context), |       create: (_) => init(context, create(context)), | ||||||
|       child: child, |       child: child, | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
| @ -46,6 +48,7 @@ abstract class SmartProvider { | |||||||
|   static RepositoryProvider<Repository> repo<Repository>( |   static RepositoryProvider<Repository> repo<Repository>( | ||||||
|     BuildContext context, { |     BuildContext context, { | ||||||
|     required Repository Function(BuildContext) create, |     required Repository Function(BuildContext) create, | ||||||
|  |     required Repository Function(BuildContext, Repository) init, | ||||||
|     Widget? child, |     Widget? child, | ||||||
|     bool lazy = true, |     bool lazy = true, | ||||||
|     bool enable = true, |     bool enable = true, | ||||||
| @ -53,8 +56,9 @@ abstract class SmartProvider { | |||||||
|     if (enable) { |     if (enable) { | ||||||
|       final repo = context.read<Repository?>(); |       final repo = context.read<Repository?>(); | ||||||
|       if (repo != null) { |       if (repo != null) { | ||||||
|  |         final r = repo; | ||||||
|         return RepositoryProvider<Repository>.value( |         return RepositoryProvider<Repository>.value( | ||||||
|           value: repo, |           value: init(context, r), | ||||||
|           child: child, |           child: child, | ||||||
|         ); |         ); | ||||||
|       } |       } | ||||||
| @ -62,7 +66,7 @@ abstract class SmartProvider { | |||||||
| 
 | 
 | ||||||
|     return RepositoryProvider<Repository>( |     return RepositoryProvider<Repository>( | ||||||
|       lazy: lazy, |       lazy: lazy, | ||||||
|       create: (_) => create(context), |       create: (_) => init(context, create(context)), | ||||||
|       child: child, |       child: child, | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -0,0 +1,98 @@ | |||||||
|  | // Copyright (C) 2022 WYATT GROUP | ||||||
|  | // Please see the AUTHORS file for details. | ||||||
|  | // | ||||||
|  | // This program is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // any later version. | ||||||
|  | // | ||||||
|  | // This program is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU General Public License | ||||||
|  | // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||||
|  | 
 | ||||||
|  | import 'package:flutter/widgets.dart'; | ||||||
|  | import 'package:flutter_bloc/flutter_bloc.dart'; | ||||||
|  | 
 | ||||||
|  | /// {@template multi_provider} | ||||||
|  | /// Merges [MultiRepositoryProvider] and [MultiBlocProvider] widgets into  | ||||||
|  | /// one widget tree. | ||||||
|  | /// | ||||||
|  | /// [MultiProvider] improves the readability and eliminates the need | ||||||
|  | /// to nest multiple providers. | ||||||
|  | /// | ||||||
|  | /// By using [MultiProvider] we can go from: | ||||||
|  | ///  | ||||||
|  | /// ```dart | ||||||
|  | /// MultiRepositoryProvider( | ||||||
|  | ///   providers: [ | ||||||
|  | ///     RepositoryProvider<RepositoryA>(create: (context) => RepositoryA()), | ||||||
|  | ///     RepositoryProvider<RepositoryB>(create: (context) => RepositoryB()), | ||||||
|  | ///     RepositoryProvider<RepositoryC>(create: (context) => RepositoryC()), | ||||||
|  | ///   ], | ||||||
|  | ///   child: | ||||||
|  | ///     MultiBlocProvider( | ||||||
|  | ///       providers: [ | ||||||
|  | ///         BlocProvider<BlocA>( | ||||||
|  | ///           create: (BuildContext context) => BlocA(), | ||||||
|  | ///         ), | ||||||
|  | ///         BlocProvider<BlocB>( | ||||||
|  | ///           create: (BuildContext context) => BlocB(), | ||||||
|  | ///         ), | ||||||
|  | ///         BlocProvider<BlocC>( | ||||||
|  | ///           create: (BuildContext context) => BlocC(), | ||||||
|  | ///         ), | ||||||
|  | ///       ], | ||||||
|  | ///       child: ChildA(), | ||||||
|  | ///     ), | ||||||
|  | /// ) | ||||||
|  | /// ``` | ||||||
|  | /// | ||||||
|  | /// to: | ||||||
|  | /// | ||||||
|  | /// ```dart | ||||||
|  | /// MultiRepositoryProvider( | ||||||
|  | ///   repositoryProviders: [ | ||||||
|  | ///     RepositoryProvider<RepositoryA>(create: (context) => RepositoryA()), | ||||||
|  | ///     RepositoryProvider<RepositoryB>(create: (context) => RepositoryB()), | ||||||
|  | ///     RepositoryProvider<RepositoryC>(create: (context) => RepositoryC()), | ||||||
|  | ///   ], | ||||||
|  | ///   providers: [ | ||||||
|  | ///     BlocProvider<BlocA>(create: (context) => BlocA()), | ||||||
|  | ///     BlocProvider<BlocB>(create: (context) => BlocB()), | ||||||
|  | ///     BlocProvider<BlocC>(create: (context) => BlocC()), | ||||||
|  | ///   ], | ||||||
|  | ///   child: ChildA(), | ||||||
|  | /// ) | ||||||
|  | /// ``` | ||||||
|  | /// | ||||||
|  | /// [MultiProvider] converts the [RepositoryProvider] and [BlocProvider] lists  | ||||||
|  | /// into a tree of nested provider widgets. | ||||||
|  | /// As a result, the only advantage of using [MultiProvider] is | ||||||
|  | /// improved readability due to the reduction in nesting and boilerplate. | ||||||
|  | /// {@endtemplate} | ||||||
|  | class MultiProvider extends StatelessWidget { | ||||||
|  |   /// {@macro multi_provider} | ||||||
|  |   const MultiProvider({ | ||||||
|  |     required this.repositoryProviders, | ||||||
|  |     required this.blocProviders, | ||||||
|  |     required this.child, | ||||||
|  |     super.key, | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   final List<RepositoryProvider<dynamic>> repositoryProviders; | ||||||
|  |   final List<BlocProvider> blocProviders; | ||||||
|  |   final Widget child; | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) => MultiRepositoryProvider( | ||||||
|  |         providers: repositoryProviders, | ||||||
|  |         child: MultiBlocProvider( | ||||||
|  |           providers: blocProviders, | ||||||
|  |           child: child, | ||||||
|  |         ), | ||||||
|  |       ); | ||||||
|  | } | ||||||
| @ -14,8 +14,10 @@ | |||||||
| // You should have received a copy of the GNU General Public License | // You should have received a copy of the GNU General Public License | ||||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||||
| 
 | 
 | ||||||
|  | /// Your best friend for BLoC in Flutter | ||||||
| library wyatt_bloc_helper; | library wyatt_bloc_helper; | ||||||
| 
 | 
 | ||||||
| export 'src/bloc.dart'; | export 'src/bloc.dart'; | ||||||
| export 'src/cubit.dart'; | export 'src/cubit.dart'; | ||||||
| export 'src/repo.dart'; | export 'src/repo.dart'; | ||||||
|  | export 'src/widgets/multi_provider.dart'; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user