feat(bloc): add init function and multi provider
This commit is contained in:
parent
b99664856d
commit
2807582a16
@ -28,7 +28,7 @@ import 'package:wyatt_bloc_helper/src/utils/smart_provider.dart';
|
||||
/// It automatically handles closing the instance when used with [create].
|
||||
/// By default, [create] is called only when the instance is accessed.
|
||||
/// To override this behavior, set [lazy] to `false`.
|
||||
///
|
||||
///
|
||||
/// By default, it provide already provided instance found in the tree.
|
||||
/// To override this behavior, set [smart] to `false`.
|
||||
/// {@endtemplate}
|
||||
@ -47,13 +47,21 @@ abstract class BlocBaseProviderScreen<Bloc extends BlocBase<State>,
|
||||
final bool lazy;
|
||||
|
||||
/// Whether this uses [SmartProvider].
|
||||
/// Defaults to `true`. But if you want to provide new [Bloc] or [Cubit]
|
||||
/// Defaults to `true`. But if you want to provide new [Bloc] or [Cubit]
|
||||
/// of a same type in a sub-tree you may have to disable this.
|
||||
final bool smart;
|
||||
|
||||
/// Creates the [Bloc] or [Cubit] to be used.
|
||||
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.
|
||||
Widget builder(BuildContext context);
|
||||
|
||||
@ -63,6 +71,7 @@ abstract class BlocBaseProviderScreen<Bloc extends BlocBase<State>,
|
||||
lazy: lazy,
|
||||
enable: smart,
|
||||
create: (_) => create(context),
|
||||
init: (_, bloc) => init(context, bloc),
|
||||
child: Builder(builder: builder),
|
||||
);
|
||||
}
|
||||
|
@ -40,7 +40,6 @@ abstract class BlocBaseScreen<Bloc extends BlocBase<State>,
|
||||
/// accessed the first time, not when provided.
|
||||
final bool lazy;
|
||||
|
||||
|
||||
/// Whether this uses [SmartProvider].
|
||||
/// 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.
|
||||
@ -49,12 +48,21 @@ abstract class BlocBaseScreen<Bloc extends BlocBase<State>,
|
||||
/// Creates the [Cubit] or [Bloc] to be used.
|
||||
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
|
||||
Widget build(BuildContext context) => SmartProvider.bloc<Bloc, State>(
|
||||
context,
|
||||
lazy: lazy,
|
||||
enable: smart,
|
||||
create: (_) => create(context),
|
||||
child: super.build(context),
|
||||
);
|
||||
context,
|
||||
lazy: lazy,
|
||||
enable: smart,
|
||||
create: (_) => create(context),
|
||||
init: (_, bloc) => init(context, bloc),
|
||||
child: super.build(context),
|
||||
);
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ import 'package:wyatt_bloc_helper/src/utils/smart_provider.dart';
|
||||
/// It automatically handles closing the instance when used with [create].
|
||||
/// By default, [create] is called only when the instance is accessed.
|
||||
/// To override this behavior, set [lazy] to `false`.
|
||||
///
|
||||
///
|
||||
/// By default, it provide already provided instance found in the tree.
|
||||
/// To override this behavior, set [smart] to `false`.
|
||||
/// {@endtemplate}
|
||||
@ -46,13 +46,21 @@ abstract class RepositoryBaseProviderScreen<Repository>
|
||||
final bool lazy;
|
||||
|
||||
/// Whether this uses [SmartProvider].
|
||||
/// Defaults to `true`. But if you want to provide new [Repository] of a
|
||||
/// Defaults to `true`. But if you want to provide new [Repository] of a
|
||||
/// same type in a sub-tree you may have to disable this.
|
||||
final bool smart;
|
||||
|
||||
/// Creates the [Repository] to be used.
|
||||
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.
|
||||
Widget builder(BuildContext context);
|
||||
|
||||
@ -62,6 +70,7 @@ abstract class RepositoryBaseProviderScreen<Repository>
|
||||
lazy: lazy,
|
||||
enable: smart,
|
||||
create: (_) => create(context),
|
||||
init: (_, repository) => init(context, repository),
|
||||
child: Builder(builder: builder),
|
||||
);
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ abstract class SmartProvider {
|
||||
bloc<Bloc extends BlocBase<State>, State extends Object>(
|
||||
BuildContext context, {
|
||||
required Bloc Function(BuildContext) create,
|
||||
required Bloc Function(BuildContext, Bloc) init,
|
||||
Widget? child,
|
||||
bool lazy = true,
|
||||
bool enable = true,
|
||||
@ -29,8 +30,9 @@ abstract class SmartProvider {
|
||||
if (enable) {
|
||||
final bloc = context.read<Bloc?>();
|
||||
if (bloc != null) {
|
||||
final b = bloc;
|
||||
return BlocProvider<Bloc>.value(
|
||||
value: bloc,
|
||||
value: init(context, b),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
@ -38,7 +40,7 @@ abstract class SmartProvider {
|
||||
|
||||
return BlocProvider<Bloc>(
|
||||
lazy: lazy,
|
||||
create: (_) => create(context),
|
||||
create: (_) => init(context, create(context)),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
@ -46,6 +48,7 @@ abstract class SmartProvider {
|
||||
static RepositoryProvider<Repository> repo<Repository>(
|
||||
BuildContext context, {
|
||||
required Repository Function(BuildContext) create,
|
||||
required Repository Function(BuildContext, Repository) init,
|
||||
Widget? child,
|
||||
bool lazy = true,
|
||||
bool enable = true,
|
||||
@ -53,8 +56,9 @@ abstract class SmartProvider {
|
||||
if (enable) {
|
||||
final repo = context.read<Repository?>();
|
||||
if (repo != null) {
|
||||
final r = repo;
|
||||
return RepositoryProvider<Repository>.value(
|
||||
value: repo,
|
||||
value: init(context, r),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
@ -62,7 +66,7 @@ abstract class SmartProvider {
|
||||
|
||||
return RepositoryProvider<Repository>(
|
||||
lazy: lazy,
|
||||
create: (_) => create(context),
|
||||
create: (_) => init(context, create(context)),
|
||||
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
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
/// Your best friend for BLoC in Flutter
|
||||
library wyatt_bloc_helper;
|
||||
|
||||
export 'src/bloc.dart';
|
||||
export 'src/cubit.dart';
|
||||
export 'src/repo.dart';
|
||||
export 'src/widgets/multi_provider.dart';
|
||||
|
Loading…
x
Reference in New Issue
Block a user