diff --git a/packages/wyatt_bloc_helper/analysis_options.yaml b/packages/wyatt_bloc_helper/analysis_options.yaml
index 8c9daa4e..b0c6aced 100644
--- a/packages/wyatt_bloc_helper/analysis_options.yaml
+++ b/packages/wyatt_bloc_helper/analysis_options.yaml
@@ -1 +1,4 @@
include: package:wyatt_analysis/analysis_options.flutter.yaml
+
+analyzer:
+ exclude: "!example/**"
\ No newline at end of file
diff --git a/packages/wyatt_bloc_helper/example/.metadata b/packages/wyatt_bloc_helper/example/.metadata
index 8bb66d20..2112298c 100644
--- a/packages/wyatt_bloc_helper/example/.metadata
+++ b/packages/wyatt_bloc_helper/example/.metadata
@@ -4,7 +4,7 @@
# This file should be version controlled.
version:
- revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
+ revision: f1875d570e39de09040c8f79aa13cc56baab8db1
channel: stable
project_type: app
@@ -13,11 +13,11 @@ project_type: app
migration:
platforms:
- platform: root
- create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
- base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
- - platform: android
- create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
- base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
+ create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
+ base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
+ - platform: web
+ create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
+ base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
# User provided section
diff --git a/packages/wyatt_bloc_helper/example/lib/counter/bloc/counter_bloc.dart b/packages/wyatt_bloc_helper/example/lib/counter/bloc/counter_bloc.dart
index 0a99298b..5bbd3d8e 100644
--- a/packages/wyatt_bloc_helper/example/lib/counter/bloc/counter_bloc.dart
+++ b/packages/wyatt_bloc_helper/example/lib/counter/bloc/counter_bloc.dart
@@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+import 'package:bloc_helper_example/counter/repository/counter_repository.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -21,14 +22,16 @@ part 'counter_event.dart';
part 'counter_state.dart';
class CounterBloc extends Bloc {
- CounterBloc() : super(const CounterInitial()) {
+ final CounterRepository counterRepository;
+
+ CounterBloc(this.counterRepository) : super(const CounterInitial()) {
on((event, emit) {
- emit(CounterModified(state.count + 1));
+ emit(CounterModified(counterRepository.increment(state.count)));
});
on((event, emit) {
- emit(CounterModified(state.count - 1));
+ emit(CounterModified(counterRepository.decrement(state.count)));
});
}
}
diff --git a/packages/wyatt_bloc_helper/example/lib/counter/counter_bloc_page.dart b/packages/wyatt_bloc_helper/example/lib/counter/counter_bloc_page.dart
index 62dd1fe1..2cb6f1d5 100644
--- a/packages/wyatt_bloc_helper/example/lib/counter/counter_bloc_page.dart
+++ b/packages/wyatt_bloc_helper/example/lib/counter/counter_bloc_page.dart
@@ -15,6 +15,7 @@
// along with this program. If not, see .
import 'package:bloc_helper_example/counter/bloc/counter_bloc.dart';
+import 'package:bloc_helper_example/counter/repository/counter_repository.dart';
import 'package:flutter/material.dart';
import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart';
@@ -23,7 +24,7 @@ class CounterBlocPage
const CounterBlocPage({super.key});
@override
- CounterBloc create(BuildContext context) => CounterBloc();
+ CounterBloc create(BuildContext context) => CounterBloc(repo(context));
@override
Widget onBuild(BuildContext context, CounterState state) {
diff --git a/packages/wyatt_bloc_helper/example/lib/counter/counter_consumer_page.dart b/packages/wyatt_bloc_helper/example/lib/counter/counter_consumer_page.dart
index b5c138b2..9a4a3005 100644
--- a/packages/wyatt_bloc_helper/example/lib/counter/counter_consumer_page.dart
+++ b/packages/wyatt_bloc_helper/example/lib/counter/counter_consumer_page.dart
@@ -35,14 +35,16 @@ class CounterConsumerPage
children: [
FloatingActionButton(
heroTag: null,
- key: const Key('counterConsumerView_increment_floatingActionButton'),
+ key:
+ const Key('counterConsumerView_increment_floatingActionButton'),
child: const Icon(Icons.add),
onPressed: () => bloc(context).increment(),
),
const SizedBox(height: 8),
FloatingActionButton(
heroTag: null,
- key: const Key('counterConsumerView_decrement_floatingActionButton'),
+ key:
+ const Key('counterConsumerView_decrement_floatingActionButton'),
child: const Icon(Icons.remove),
onPressed: () => bloc(context).decrement(),
),
diff --git a/packages/wyatt_bloc_helper/example/lib/counter/counter_cubit_page.dart b/packages/wyatt_bloc_helper/example/lib/counter/counter_cubit_page.dart
index 1776139d..5e04d72a 100644
--- a/packages/wyatt_bloc_helper/example/lib/counter/counter_cubit_page.dart
+++ b/packages/wyatt_bloc_helper/example/lib/counter/counter_cubit_page.dart
@@ -15,6 +15,7 @@
// along with this program. If not, see .
import 'package:bloc_helper_example/counter/cubit/counter_cubit.dart';
+import 'package:bloc_helper_example/counter/repository/counter_repository.dart';
import 'package:flutter/material.dart';
import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart';
@@ -23,7 +24,7 @@ class CounterCubitPage
const CounterCubitPage({super.key});
@override
- CounterCubit create(BuildContext context) => CounterCubit();
+ CounterCubit create(BuildContext context) => CounterCubit(repo(context));
@override
Widget onBuild(BuildContext context, CounterState state) {
diff --git a/packages/wyatt_bloc_helper/example/lib/counter/counter_provider_page.dart b/packages/wyatt_bloc_helper/example/lib/counter/counter_provider_page.dart
index beac5f1a..7a6c3d8c 100644
--- a/packages/wyatt_bloc_helper/example/lib/counter/counter_provider_page.dart
+++ b/packages/wyatt_bloc_helper/example/lib/counter/counter_provider_page.dart
@@ -15,6 +15,7 @@
// along with this program. If not, see .
import 'package:bloc_helper_example/counter/bloc/counter_bloc.dart';
+import 'package:bloc_helper_example/counter/repository/counter_repository.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart';
@@ -24,7 +25,11 @@ class CounterProviderPage
const CounterProviderPage({super.key});
@override
- Widget buildChild(BuildContext context) {
+ CounterBloc create(BuildContext context) =>
+ CounterBloc(repo(context));
+
+ @override
+ Widget builder(BuildContext context) {
final textTheme = Theme.of(context).textTheme;
return Scaffold(
appBar: AppBar(title: const Text('Counter with Provider')),
@@ -39,14 +44,16 @@ class CounterProviderPage
children: [
FloatingActionButton(
heroTag: null,
- key: const Key('counterProviderView_increment_floatingActionButton'),
+ key:
+ const Key('counterProviderView_increment_floatingActionButton'),
child: const Icon(Icons.add),
onPressed: () => add(context, CounterIncrement()),
),
const SizedBox(height: 8),
FloatingActionButton(
heroTag: null,
- key: const Key('counterProviderView_decrement_floatingActionButton'),
+ key:
+ const Key('counterProviderView_decrement_floatingActionButton'),
child: const Icon(Icons.remove),
onPressed: () => add(context, CounterDecrement()),
),
@@ -54,7 +61,4 @@ class CounterProviderPage
),
);
}
-
- @override
- CounterBloc create(BuildContext context) => CounterBloc();
}
diff --git a/packages/wyatt_bloc_helper/example/lib/counter/cubit/counter_cubit.dart b/packages/wyatt_bloc_helper/example/lib/counter/cubit/counter_cubit.dart
index 12759e12..13ee8b4d 100644
--- a/packages/wyatt_bloc_helper/example/lib/counter/cubit/counter_cubit.dart
+++ b/packages/wyatt_bloc_helper/example/lib/counter/cubit/counter_cubit.dart
@@ -1,32 +1,35 @@
// 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 .
+import 'package:bloc_helper_example/counter/repository/counter_repository.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
part 'counter_state.dart';
class CounterCubit extends Cubit {
- CounterCubit() : super(const CounterInitial());
+ final CounterRepository counterRepository;
+
+ CounterCubit(this.counterRepository) : super(const CounterInitial());
void increment() {
- emit(CounterModified(state.count + 1));
+ emit(CounterModified(counterRepository.increment(state.count)));
}
void decrement() {
- emit(CounterModified(state.count - 1));
+ emit(CounterModified(counterRepository.decrement(state.count)));
}
}
diff --git a/packages/wyatt_bloc_helper/example/lib/counter/repository/counter_repository.dart b/packages/wyatt_bloc_helper/example/lib/counter/repository/counter_repository.dart
new file mode 100644
index 00000000..132414e9
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/lib/counter/repository/counter_repository.dart
@@ -0,0 +1,27 @@
+// 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 .
+
+class CounterRepository {
+ int increment(int before) {
+ final after = before + 1;
+ return after;
+ }
+
+ int decrement(int before) {
+ final after = before - 1;
+ return after;
+ }
+}
diff --git a/packages/wyatt_bloc_helper/example/lib/counter_repository_provider_page.dart b/packages/wyatt_bloc_helper/example/lib/counter_repository_provider_page.dart
new file mode 100644
index 00000000..06b69b4f
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/lib/counter_repository_provider_page.dart
@@ -0,0 +1,37 @@
+// 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 .
+
+import 'package:bloc_helper_example/counter/repository/counter_repository.dart';
+import 'package:bloc_helper_example/main_page.dart';
+import 'package:flutter/material.dart';
+import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart';
+
+class CounterRepositoryProviderPage
+ extends RepositoryProviderScreen {
+ const CounterRepositoryProviderPage({super.key});
+
+ @override
+ CounterRepository create(BuildContext context) => CounterRepository();
+
+ @override
+ Widget builder(BuildContext context) => MaterialApp(
+ title: 'Flutter Demo',
+ theme: ThemeData(
+ primarySwatch: Colors.blue,
+ ),
+ home: const MainPage(),
+ );
+}
diff --git a/packages/wyatt_bloc_helper/example/lib/main.dart b/packages/wyatt_bloc_helper/example/lib/main.dart
index 14d1b2a9..a707077c 100644
--- a/packages/wyatt_bloc_helper/example/lib/main.dart
+++ b/packages/wyatt_bloc_helper/example/lib/main.dart
@@ -14,77 +14,12 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-import 'package:bloc_helper_example/counter/counter_bloc_page.dart';
-import 'package:bloc_helper_example/counter/counter_consumer_page.dart';
-import 'package:bloc_helper_example/counter/counter_cubit_page.dart';
-import 'package:bloc_helper_example/counter/counter_provider_page.dart';
-import 'package:bloc_helper_example/counter/cubit/counter_cubit.dart';
import 'package:bloc_helper_example/counter_observer.dart';
+import 'package:bloc_helper_example/counter_repository_provider_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
void main() {
- BlocOverrides.runZoned(() => runApp(const MyApp()),
+ BlocOverrides.runZoned(() => runApp(const CounterRepositoryProviderPage()),
blocObserver: CounterObserver());
}
-
-class MyApp extends StatelessWidget {
- const MyApp({Key? key}) : super(key: key);
-
- // This widget is the root of your application.
- @override
- Widget build(BuildContext context) {
- return MaterialApp(
- title: 'Flutter Demo',
- theme: ThemeData(
- primarySwatch: Colors.blue,
- ),
- home: const MainPage(),
- );
- }
-}
-
-class MainPage extends StatelessWidget {
- const MainPage({Key? key}) : super(key: key);
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: const Text('Main Page'),
- ),
- body: Center(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- ElevatedButton(
- child: const Text('Counter with BlocScreen'),
- onPressed: () => Navigator.of(context).push(
- MaterialPageRoute(builder: (_) => const CounterBlocPage())),
- ),
- ElevatedButton(
- child: const Text('Counter with CubitScreen'),
- onPressed: () => Navigator.of(context).push(
- MaterialPageRoute(builder: (_) => const CounterCubitPage())),
- ),
- ElevatedButton(
- child: const Text('Counter with BlocProviderScreen'),
- onPressed: () => Navigator.of(context).push(MaterialPageRoute(
- builder: (_) => const CounterProviderPage())),
- ),
- ElevatedButton(
- child: const Text('Counter with BlocConsumerScreen'),
- onPressed: () => Navigator.of(context)
- .push(MaterialPageRoute(builder: (context) {
- return BlocProvider(
- create: (context) => CounterCubit(),
- child: const CounterConsumerPage(),
- );
- })),
- ),
- ],
- ),
- ),
- );
- }
-}
diff --git a/packages/wyatt_bloc_helper/example/lib/main_page.dart b/packages/wyatt_bloc_helper/example/lib/main_page.dart
new file mode 100644
index 00000000..2a82d039
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/lib/main_page.dart
@@ -0,0 +1,69 @@
+// 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 .
+
+import 'package:bloc_helper_example/counter/counter_bloc_page.dart';
+import 'package:bloc_helper_example/counter/counter_consumer_page.dart';
+import 'package:bloc_helper_example/counter/counter_cubit_page.dart';
+import 'package:bloc_helper_example/counter/counter_provider_page.dart';
+import 'package:bloc_helper_example/counter/cubit/counter_cubit.dart';
+import 'package:bloc_helper_example/counter/repository/counter_repository.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+class MainPage extends StatelessWidget {
+ const MainPage({Key? key}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: const Text('Main Page'),
+ ),
+ body: Center(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ ElevatedButton(
+ child: const Text('Counter with BlocScreen'),
+ onPressed: () => Navigator.of(context).push(
+ MaterialPageRoute(builder: (_) => const CounterBlocPage())),
+ ),
+ ElevatedButton(
+ child: const Text('Counter with CubitScreen'),
+ onPressed: () => Navigator.of(context).push(
+ MaterialPageRoute(builder: (_) => const CounterCubitPage())),
+ ),
+ ElevatedButton(
+ child: const Text('Counter with BlocProviderScreen'),
+ onPressed: () => Navigator.of(context).push(MaterialPageRoute(
+ builder: (_) => const CounterProviderPage())),
+ ),
+ ElevatedButton(
+ child: const Text('Counter with BlocConsumerScreen'),
+ onPressed: () => Navigator.of(context)
+ .push(MaterialPageRoute(builder: (context) {
+ return BlocProvider(
+ create: (context) => CounterCubit(context.read()),
+ child: const CounterConsumerPage(),
+ );
+ })),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/packages/wyatt_bloc_helper/example/test/widget_test.dart b/packages/wyatt_bloc_helper/example/test/widget_test.dart
index 9cd92fe5..7349f1b3 100644
--- a/packages/wyatt_bloc_helper/example/test/widget_test.dart
+++ b/packages/wyatt_bloc_helper/example/test/widget_test.dart
@@ -5,15 +5,14 @@
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
+import 'package:bloc_helper_example/counter_repository_provider_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
-import 'package:bloc_helper_example/main.dart';
-
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
- await tester.pumpWidget(const MyApp());
+ await tester.pumpWidget(const CounterRepositoryProviderPage());
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
diff --git a/packages/wyatt_bloc_helper/example/web/favicon.png b/packages/wyatt_bloc_helper/example/web/favicon.png
new file mode 100644
index 00000000..8aaa46ac
Binary files /dev/null and b/packages/wyatt_bloc_helper/example/web/favicon.png differ
diff --git a/packages/wyatt_bloc_helper/example/web/icons/Icon-192.png b/packages/wyatt_bloc_helper/example/web/icons/Icon-192.png
new file mode 100644
index 00000000..b749bfef
Binary files /dev/null and b/packages/wyatt_bloc_helper/example/web/icons/Icon-192.png differ
diff --git a/packages/wyatt_bloc_helper/example/web/icons/Icon-512.png b/packages/wyatt_bloc_helper/example/web/icons/Icon-512.png
new file mode 100644
index 00000000..88cfd48d
Binary files /dev/null and b/packages/wyatt_bloc_helper/example/web/icons/Icon-512.png differ
diff --git a/packages/wyatt_bloc_helper/example/web/icons/Icon-maskable-192.png b/packages/wyatt_bloc_helper/example/web/icons/Icon-maskable-192.png
new file mode 100644
index 00000000..eb9b4d76
Binary files /dev/null and b/packages/wyatt_bloc_helper/example/web/icons/Icon-maskable-192.png differ
diff --git a/packages/wyatt_bloc_helper/example/web/icons/Icon-maskable-512.png b/packages/wyatt_bloc_helper/example/web/icons/Icon-maskable-512.png
new file mode 100644
index 00000000..d69c5669
Binary files /dev/null and b/packages/wyatt_bloc_helper/example/web/icons/Icon-maskable-512.png differ
diff --git a/packages/wyatt_bloc_helper/example/web/index.html b/packages/wyatt_bloc_helper/example/web/index.html
new file mode 100644
index 00000000..41b3bc33
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/web/index.html
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ example
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/wyatt_bloc_helper/example/web/manifest.json b/packages/wyatt_bloc_helper/example/web/manifest.json
new file mode 100644
index 00000000..096edf8f
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/web/manifest.json
@@ -0,0 +1,35 @@
+{
+ "name": "example",
+ "short_name": "example",
+ "start_url": ".",
+ "display": "standalone",
+ "background_color": "#0175C2",
+ "theme_color": "#0175C2",
+ "description": "A new Flutter project.",
+ "orientation": "portrait-primary",
+ "prefer_related_applications": false,
+ "icons": [
+ {
+ "src": "icons/Icon-192.png",
+ "sizes": "192x192",
+ "type": "image/png"
+ },
+ {
+ "src": "icons/Icon-512.png",
+ "sizes": "512x512",
+ "type": "image/png"
+ },
+ {
+ "src": "icons/Icon-maskable-192.png",
+ "sizes": "192x192",
+ "type": "image/png",
+ "purpose": "maskable"
+ },
+ {
+ "src": "icons/Icon-maskable-512.png",
+ "sizes": "512x512",
+ "type": "image/png",
+ "purpose": "maskable"
+ }
+ ]
+}
diff --git a/packages/wyatt_bloc_helper/lib/src/bloc.dart b/packages/wyatt_bloc_helper/lib/src/bloc.dart
index 2ef9c3c1..7113c132 100644
--- a/packages/wyatt_bloc_helper/lib/src/bloc.dart
+++ b/packages/wyatt_bloc_helper/lib/src/bloc.dart
@@ -14,27 +14,79 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_bloc/flutter_bloc.dart' as blocbase;
import 'package:wyatt_bloc_helper/src/bloc_base/bloc_base_consumer_screen.dart';
import 'package:wyatt_bloc_helper/src/bloc_base/bloc_base_provider_screen.dart';
import 'package:wyatt_bloc_helper/src/bloc_base/bloc_base_screen.dart';
import 'package:wyatt_bloc_helper/src/mixins/bloc_base_provider_mixin.dart';
import 'package:wyatt_bloc_helper/src/mixins/bloc_provider_mixin.dart';
+import 'package:wyatt_bloc_helper/src/mixins/repository_base_provider_mixin.dart';
-abstract class BlocProviderScreen, E, S extends Object>
- extends BlocBaseProviderScreen
- with BlocBaseProviderMixin, BlocProviderMixin {
- const BlocProviderScreen({super.key});
+/// {@template bloc_provider}
+/// Need to implement a [create] function that is responsible for
+/// creating the [Bloc] and a [builder] which will return a child
+/// that have access to the instance via `context.read()`.
+/// It is used as a dependency injection (DI) widget so that a single instance
+/// of a [Bloc] can be provided to multiple widgets within a subtree.
+///
+/// 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}
+abstract class BlocProviderScreen,
+ Event, State extends Object> extends BlocBaseProviderScreen
+ with
+ BlocBaseProviderMixin,
+ RepositoryProviderMixin,
+ BlocProviderMixin {
+ /// {@macro bloc_provider}
+ const BlocProviderScreen({super.key, super.lazy = true, super.smart = true});
}
-abstract class BlocConsumerScreen, E, S extends Object>
- extends BlocBaseConsumerScreen
- with BlocBaseProviderMixin, BlocProviderMixin {
+/// {@template bloc_consumer}
+/// [BlocConsumerScreen] exposes [onBuild] and [onListen] in order react
+/// to new states.
+///
+/// An optional [shouldBuildWhen] and [shouldListenWhen] can be implemented
+/// for more granular control over when [onListen] and [onBuild] are called.
+/// The [shouldListenWhen] and [shouldBuildWhen] will be invoked on
+/// each [Bloc] or `state` change.
+/// They each take the previous `state` and current `state` and must return
+/// a [bool] which determines whether or not the [onBuild] and/or [onListen]
+/// function will be invoked.
+/// The previous `state` will be initialized to the `state` of the [Bloc] when
+/// the BlocConsumer is initialized.
+/// [shouldListenWhen] and [shouldBuildWhen] are optional and if they
+/// aren't implemented, they will default to `true`.
+///
+/// An optional [onWrap] can also be implemented. This build a wrapper arround
+/// the built BlocConsumer that is **not** rebuild on each state.
+/// {@endtemplate}
+abstract class BlocConsumerScreen,
+ Event, State extends Object> extends BlocBaseConsumerScreen
+ with
+ BlocBaseProviderMixin,
+ RepositoryProviderMixin,
+ BlocProviderMixin {
+ /// {@macro bloc_consumer}
const BlocConsumerScreen({super.key});
}
-abstract class BlocScreen, E, S extends Object>
- extends BlocBaseScreen
- with BlocBaseProviderMixin, BlocProviderMixin {
- const BlocScreen({super.key});
+/// {@template bloc_screen}
+/// Provide AND access to a [Bloc].
+///
+/// This extends [BlocConsumerScreen] with the methods
+/// of [BlocBaseScreen].
+/// {@endtemplate}
+abstract class BlocScreen, Event,
+ State extends Object> extends BlocBaseScreen
+ with
+ BlocBaseProviderMixin,
+ RepositoryProviderMixin,
+ BlocProviderMixin {
+ /// {@macro bloc_screen}
+ const BlocScreen({super.key, super.lazy = true, super.smart = true});
}
diff --git a/packages/wyatt_bloc_helper/lib/src/bloc_base/bloc_base_consumer_screen.dart b/packages/wyatt_bloc_helper/lib/src/bloc_base/bloc_base_consumer_screen.dart
index 3fc8e6e2..13c25367 100644
--- a/packages/wyatt_bloc_helper/lib/src/bloc_base/bloc_base_consumer_screen.dart
+++ b/packages/wyatt_bloc_helper/lib/src/bloc_base/bloc_base_consumer_screen.dart
@@ -17,39 +17,62 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
-abstract class BlocBaseConsumerScreen, S extends Object>
- extends StatelessWidget {
+/// {@template bloc_base_consumer}
+/// [BlocBaseConsumerScreen] exposes [onBuild] and [onListen] in order react
+/// to new states.
+///
+/// An optional [shouldBuildWhen] and [shouldListenWhen] can be implemented
+/// for more granular control over when [onListen] and [onBuild] are called.
+/// The [shouldListenWhen] and [shouldBuildWhen] will be invoked on
+/// each [Bloc] or `state` change.
+/// They each take the previous `state` and current `state` and must return
+/// a [bool] which determines whether or not the [onBuild] and/or [onListen]
+/// function will be invoked.
+/// The previous `state` will be initialized to the `state` of the [Bloc] when
+/// the [BlocConsumer] is initialized.
+/// [shouldListenWhen] and [shouldBuildWhen] are optional and if they
+/// aren't implemented, they will default to `true`.
+///
+/// An optional [onWrap] can also be implemented. This build a wrapper arround
+/// the built [BlocConsumer] that is **not** rebuild on each state.
+/// {@endtemplate}
+abstract class BlocBaseConsumerScreen,
+ State extends Object> extends StatelessWidget {
+ /// {@macro bloc_base_consumer}
const BlocBaseConsumerScreen({super.key});
/// Takes the previous `state` and the current `state` and is responsible for
/// returning a [bool] which determines whether or not to trigger
/// [onBuild] with the current `state`.
- bool shouldBuildWhen(S previous, S current) => true;
+ bool shouldBuildWhen(State previous, State current) => true;
/// Takes the previous `state` and the current `state` and is responsible for
/// returning a [bool] which determines whether or not to trigger
/// [onListen] with the current `state`.
- bool shouldListenWhen(S previous, S current) => true;
+ bool shouldListenWhen(State previous, State current) => true;
+
+ /// The [onWrap] function which will be invoked on build.
+ /// The [onWrap] takes a `BuildContext` that **doesn't have** access
+ /// to the [Bloc] or [Cubit].
+ Widget onWrap(BuildContext context, Widget child) => child;
/// The [onBuild] function which will be invoked on each widget build.
/// The [onBuild] takes the `BuildContext` and current `state` and
/// must return a widget.
- Widget onBuild(BuildContext context, S state);
-
- /// The [onWrap] function which will be invoked on each widget build.
- /// The [onWrap] takes the `BuildContext`
- /// Used to wrap which depends on the state.
- Widget onWrap(BuildContext context, Widget child) => child;
+ Widget onBuild(BuildContext context, State state);
/// Takes the `BuildContext` along with the `state`
/// and is responsible for executing in response to `state` changes.
- void onListen(BuildContext context, S state) {}
+ void onListen(BuildContext context, State state) {}
@override
- Widget build(BuildContext context) => BlocConsumer(
- listenWhen: shouldListenWhen,
- listener: onListen,
- buildWhen: shouldBuildWhen,
- builder: (context, state) => onWrap(context, onBuild(context, state)),
+ Widget build(BuildContext context) => onWrap(
+ context,
+ BlocConsumer(
+ listenWhen: shouldListenWhen,
+ listener: onListen,
+ buildWhen: shouldBuildWhen,
+ builder: onBuild,
+ ),
);
}
diff --git a/packages/wyatt_bloc_helper/lib/src/bloc_base/bloc_base_provider_screen.dart b/packages/wyatt_bloc_helper/lib/src/bloc_base/bloc_base_provider_screen.dart
index 3a9bae5f..26c656e2 100644
--- a/packages/wyatt_bloc_helper/lib/src/bloc_base/bloc_base_provider_screen.dart
+++ b/packages/wyatt_bloc_helper/lib/src/bloc_base/bloc_base_provider_screen.dart
@@ -16,20 +16,53 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:wyatt_bloc_helper/src/utils/smart_provider.dart';
-abstract class BlocBaseProviderScreen, S extends Object>
- extends StatelessWidget {
- const BlocBaseProviderScreen({super.key});
+/// {@template bloc_base_provider}
+/// Need to implement a [create] function that is responsible for
+/// creating the [Bloc] or [Cubit] and a [builder] which will return a child
+/// that have access to the instance via `context.read()`.
+/// It is used as a dependency injection (DI) widget so that a single instance
+/// of a [Bloc] or [Cubit] can be provided to multiple widgets within a subtree.
+///
+/// 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}
+abstract class BlocBaseProviderScreen,
+ State extends Object> extends StatelessWidget {
+ /// {@macro bloc_base_provider}
+ const BlocBaseProviderScreen({
+ super.key,
+ this.lazy = true,
+ this.smart = true,
+ });
- /// Creates the [Cubit] or [Bloc] to be used.
- B create(BuildContext context);
+ /// Whether the [Bloc] or [Cubit] should be created lazily.
+ /// Defaults to `true` which means the [Bloc] or [Cubit] is created only when
+ /// 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] 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);
/// Creates the child [Widget] to be used.
- Widget buildChild(BuildContext context);
+ Widget builder(BuildContext context);
@override
- Widget build(BuildContext context) => BlocProvider(
+ Widget build(BuildContext context) => SmartProvider.bloc(
+ context,
+ lazy: lazy,
+ enable: smart,
create: (_) => create(context),
- child: Builder(builder: buildChild),
+ child: Builder(builder: builder),
);
}
diff --git a/packages/wyatt_bloc_helper/lib/src/bloc_base/bloc_base_screen.dart b/packages/wyatt_bloc_helper/lib/src/bloc_base/bloc_base_screen.dart
index 4916b725..4c853af6 100644
--- a/packages/wyatt_bloc_helper/lib/src/bloc_base/bloc_base_screen.dart
+++ b/packages/wyatt_bloc_helper/lib/src/bloc_base/bloc_base_screen.dart
@@ -17,17 +17,44 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:wyatt_bloc_helper/src/bloc_base/bloc_base_consumer_screen.dart';
+import 'package:wyatt_bloc_helper/src/utils/smart_provider.dart';
-abstract class BlocBaseScreen, S extends Object>
- extends BlocBaseConsumerScreen {
- const BlocBaseScreen({super.key});
+/// {@template bloc_base_screen}
+/// Provide AND access to a [Bloc] or [Cubit].
+///
+/// This extends [BlocBaseConsumerScreen] with the methods
+// ignore: comment_references
+/// of [BlocBaseProviderScreen].
+/// {@endtemplate}
+abstract class BlocBaseScreen,
+ State extends Object> extends BlocBaseConsumerScreen {
+ /// {@macro bloc_base_screen}
+ const BlocBaseScreen({
+ super.key,
+ this.lazy = true,
+ this.smart = true,
+ });
+
+ /// Whether the [Bloc] or [Cubit] should be created lazily.
+ /// Defaults to `true` which means the [Bloc] is created only when
+ /// 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.
+ final bool smart;
/// Creates the [Cubit] or [Bloc] to be used.
- B create(BuildContext context);
+ Bloc create(BuildContext context);
@override
- Widget build(BuildContext context) => BlocProvider(
- create: (_) => create(context),
- child: super.build(context),
- );
+ Widget build(BuildContext context) => SmartProvider.bloc(
+ context,
+ lazy: lazy,
+ enable: smart,
+ create: (_) => create(context),
+ child: super.build(context),
+ );
}
diff --git a/packages/wyatt_bloc_helper/lib/src/cubit.dart b/packages/wyatt_bloc_helper/lib/src/cubit.dart
index f3abacf0..8f740a6e 100644
--- a/packages/wyatt_bloc_helper/lib/src/cubit.dart
+++ b/packages/wyatt_bloc_helper/lib/src/cubit.dart
@@ -14,23 +14,70 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_bloc/flutter_bloc.dart' as blocbase;
import 'package:wyatt_bloc_helper/src/bloc_base/bloc_base_consumer_screen.dart';
import 'package:wyatt_bloc_helper/src/bloc_base/bloc_base_provider_screen.dart';
import 'package:wyatt_bloc_helper/src/bloc_base/bloc_base_screen.dart';
import 'package:wyatt_bloc_helper/src/mixins/bloc_base_provider_mixin.dart';
+import 'package:wyatt_bloc_helper/src/mixins/repository_base_provider_mixin.dart';
-abstract class CubitProviderScreen, S extends Object>
- extends BlocBaseProviderScreen with BlocBaseProviderMixin {
- const CubitProviderScreen({super.key});
+/// {@template cubit_provider}
+/// Need to implement a [create] function that is responsible for
+/// creating the [Cubit] and a [builder] which will return a child
+/// that have access to the instance via `context.read()`.
+/// It is used as a dependency injection (DI) widget so that a single instance
+/// of a [Cubit] can be provided to multiple widgets within a subtree.
+///
+/// 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 in found in the tree.
+/// To override this behavior, set [smart] to `false`.
+/// {@endtemplate}
+abstract class CubitProviderScreen,
+ State extends Object> extends BlocBaseProviderScreen
+ with BlocBaseProviderMixin, RepositoryProviderMixin {
+ /// {@macro cubit_provider}
+ const CubitProviderScreen({super.key, super.lazy = true, super.smart = true});
}
-abstract class CubitConsumerScreen, S extends Object>
- extends BlocBaseConsumerScreen with BlocBaseProviderMixin {
+/// {@template cubit_consumer}
+/// [CubitConsumerScreen] exposes [onBuild] and [onListen] in order react
+/// to new states.
+///
+/// An optional [shouldBuildWhen] and [shouldListenWhen] can be implemented
+/// for more granular control over when [onListen] and [onBuild] are called.
+/// The [shouldListenWhen] and [shouldBuildWhen] will be invoked on
+/// each [Cubit] or `state` change.
+/// They each take the previous `state` and current `state` and must return
+/// a [bool] which determines whether or not the [onBuild] and/or [onListen]
+/// function will be invoked.
+/// The previous `state` will be initialized to the `state` of the [Cubit] when
+/// the BlocConsumer is initialized.
+/// [shouldListenWhen] and [shouldBuildWhen] are optional and if they
+/// aren't implemented, they will default to `true`.
+///
+/// An optional [onWrap] can also be implemented. This build a wrapper arround
+/// the built BlocConsumer that is **not** rebuild on each state.
+/// {@endtemplate}
+abstract class CubitConsumerScreen,
+ State extends Object> extends BlocBaseConsumerScreen
+ with BlocBaseProviderMixin, RepositoryProviderMixin {
+ /// {@macro cubit_consumer}
const CubitConsumerScreen({super.key});
}
-abstract class CubitScreen, S extends Object>
- extends BlocBaseScreen with BlocBaseProviderMixin {
- const CubitScreen({super.key});
+/// {@template cubit_screen}
+/// Provide AND access to a [Cubit].
+///
+/// This extends [CubitConsumerScreen] with the methods
+// ignore: comment_references
+/// of [CubitProviderScreen].
+/// {@endtemplate}
+abstract class CubitScreen,
+ State extends Object> extends BlocBaseScreen
+ with BlocBaseProviderMixin, RepositoryProviderMixin {
+ /// {@macro cubit_screen}
+ const CubitScreen({super.key, super.lazy = true, super.smart = true});
}
diff --git a/packages/wyatt_bloc_helper/lib/src/mixins/bloc_base_provider_mixin.dart b/packages/wyatt_bloc_helper/lib/src/mixins/bloc_base_provider_mixin.dart
index 3ae13e26..6c2cf006 100644
--- a/packages/wyatt_bloc_helper/lib/src/mixins/bloc_base_provider_mixin.dart
+++ b/packages/wyatt_bloc_helper/lib/src/mixins/bloc_base_provider_mixin.dart
@@ -19,10 +19,14 @@ import 'package:flutter_bloc/flutter_bloc.dart';
/// A mixin that provides implementation of helper methods for
/// [Bloc] and [Cubit] widgets.
-mixin BlocBaseProviderMixin> {
+mixin BlocBaseProviderMixin> {
/// Returns the [BlocBase] used by this [BlocBaseProviderMixin].
- B bloc(BuildContext context) => context.read();
+ Bloc bloc(BuildContext context) => context.read();
- /// Returns the [BlocBase] used by this [BlocBaseProviderMixin].
- R repo(BuildContext context) => context.read();
+ /// Returns another [BlocBase] **not** used by this [BlocBaseProviderMixin].
+ /// Short hand for `context.read();`
+ ///
+ /// To get [BlocBase] used by by this [BlocBaseProviderMixin] see `bloc()`
+ AnotherBloc anotherBloc(BuildContext context) =>
+ context.read();
}
diff --git a/packages/wyatt_bloc_helper/lib/src/mixins/bloc_provider_mixin.dart b/packages/wyatt_bloc_helper/lib/src/mixins/bloc_provider_mixin.dart
index 547dd6ca..0680a048 100644
--- a/packages/wyatt_bloc_helper/lib/src/mixins/bloc_provider_mixin.dart
+++ b/packages/wyatt_bloc_helper/lib/src/mixins/bloc_provider_mixin.dart
@@ -15,10 +15,14 @@
// along with this program. If not, see .
import 'package:flutter/widgets.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_bloc/flutter_bloc.dart' as blocbase;
/// [Bloc] specific mixin that provides implementation
/// of helper methods for events.
-mixin BlocProviderMixin, E> {
- void add(BuildContext context, E event) => context.read().add(event);
+mixin BlocProviderMixin, Event> {
+ /// Add an event to the [Bloc].
+ ///
+ /// Short hand for `context.read().add(event)`.
+ void add(BuildContext context, Event event) =>
+ context.read().add(event);
}
diff --git a/packages/wyatt_bloc_helper/lib/src/mixins/repository_base_provider_mixin.dart b/packages/wyatt_bloc_helper/lib/src/mixins/repository_base_provider_mixin.dart
new file mode 100644
index 00000000..06f08afc
--- /dev/null
+++ b/packages/wyatt_bloc_helper/lib/src/mixins/repository_base_provider_mixin.dart
@@ -0,0 +1,26 @@
+// 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 .
+
+import 'package:flutter/widgets.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+/// A mixin that provides implementation of helper methods for
+/// Repository widgets.
+mixin RepositoryProviderMixin {
+ /// Returns the [Repository] used by this [Widget].
+ Repository repo(BuildContext context) =>
+ context.read();
+}
diff --git a/packages/wyatt_bloc_helper/lib/src/repo.dart b/packages/wyatt_bloc_helper/lib/src/repo.dart
new file mode 100644
index 00000000..c6e32540
--- /dev/null
+++ b/packages/wyatt_bloc_helper/lib/src/repo.dart
@@ -0,0 +1,39 @@
+// 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 .
+
+import 'package:wyatt_bloc_helper/src/mixins/repository_base_provider_mixin.dart';
+import 'package:wyatt_bloc_helper/src/repository/repository_provider_screen.dart';
+
+/// {@template repository_provider}
+/// Need to implement a [create] function that is responsible for
+/// creating the [Repository] and a [builder] which will return a child
+/// that have access to the instance via `context.read()`.
+/// It is used as a dependency injection (DI) widget so that a single instance
+/// of a [Repository] can be provided to multiple widgets within a subtree.
+///
+/// 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}
+abstract class RepositoryProviderScreen
+ extends RepositoryBaseProviderScreen
+ with RepositoryProviderMixin {
+ /// {@macro repository_provider}
+ const RepositoryProviderScreen({super.key});
+}
diff --git a/packages/wyatt_bloc_helper/lib/src/repository/repository_provider_screen.dart b/packages/wyatt_bloc_helper/lib/src/repository/repository_provider_screen.dart
new file mode 100644
index 00000000..e7a8c5ce
--- /dev/null
+++ b/packages/wyatt_bloc_helper/lib/src/repository/repository_provider_screen.dart
@@ -0,0 +1,67 @@
+// 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 .
+
+import 'package:flutter/material.dart';
+import 'package:wyatt_bloc_helper/src/utils/smart_provider.dart';
+
+/// {@template repository_base_provider}
+/// Need to implement a [create] function that is responsible for
+/// creating the [Repository] and a [builder] which will return a child
+/// that have access to the instance via `context.read()`.
+/// It is used as a dependency injection (DI) widget so that a single instance
+/// of a [Repository] can be provided to multiple widgets within a subtree.
+///
+/// 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}
+abstract class RepositoryBaseProviderScreen
+ extends StatelessWidget {
+ /// {@macro repository_base_provider}
+ const RepositoryBaseProviderScreen({
+ super.key,
+ this.lazy = true,
+ this.smart = true,
+ });
+
+ /// Whether the [Repository] should be created lazily.
+ /// Defaults to `true` which means the [Repository] is created only when
+ /// accessed the first time, not when provided.
+ final bool lazy;
+
+ /// Whether this uses [SmartProvider].
+ /// 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);
+
+ /// Creates the child [Widget] to be used.
+ Widget builder(BuildContext context);
+
+ @override
+ Widget build(BuildContext context) => SmartProvider.repo(
+ context,
+ lazy: lazy,
+ enable: smart,
+ create: (_) => create(context),
+ child: Builder(builder: builder),
+ );
+}
diff --git a/packages/wyatt_bloc_helper/lib/src/utils/smart_provider.dart b/packages/wyatt_bloc_helper/lib/src/utils/smart_provider.dart
new file mode 100644
index 00000000..5fdb959a
--- /dev/null
+++ b/packages/wyatt_bloc_helper/lib/src/utils/smart_provider.dart
@@ -0,0 +1,69 @@
+// 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 .
+
+import 'package:flutter/widgets.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+abstract class SmartProvider {
+ static BlocProvider
+ bloc, State extends Object>(
+ BuildContext context, {
+ required Bloc Function(BuildContext) create,
+ Widget? child,
+ bool lazy = true,
+ bool enable = true,
+ }) {
+ if (enable) {
+ final bloc = context.read();
+ if (bloc != null) {
+ return BlocProvider.value(
+ value: bloc,
+ child: child,
+ );
+ }
+ }
+
+ return BlocProvider(
+ lazy: lazy,
+ create: (_) => create(context),
+ child: child,
+ );
+ }
+
+ static RepositoryProvider repo(
+ BuildContext context, {
+ required Repository Function(BuildContext) create,
+ Widget? child,
+ bool lazy = true,
+ bool enable = true,
+ }) {
+ if (enable) {
+ final repo = context.read();
+ if (repo != null) {
+ return RepositoryProvider.value(
+ value: repo,
+ child: child,
+ );
+ }
+ }
+
+ return RepositoryProvider(
+ lazy: lazy,
+ create: (_) => create(context),
+ child: child,
+ );
+ }
+}
diff --git a/packages/wyatt_bloc_helper/lib/wyatt_bloc_helper.dart b/packages/wyatt_bloc_helper/lib/wyatt_bloc_helper.dart
index 83be0be2..cb9a6bcf 100644
--- a/packages/wyatt_bloc_helper/lib/wyatt_bloc_helper.dart
+++ b/packages/wyatt_bloc_helper/lib/wyatt_bloc_helper.dart
@@ -18,3 +18,4 @@ library wyatt_bloc_helper;
export 'src/bloc.dart';
export 'src/cubit.dart';
+export 'src/repo.dart';