feat(bloc): add init function and multi provider
This commit is contained in:
parent
b99664856d
commit
2807582a16
@ -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