+
+BloC Pattern utilities for Flutter.
+
+## Using
+
+### Mixin Helper
+
+In any custom screen you can get quick access to bloc or repository by using the mixin helper.
+
+```dart
+add(context, CounterIncrement());
+
+// or, if you want to use Cubit
+
+bloc(context).increment();
+```
+
+> Note: in this context `bloc` returns a Cubit instance.
+
+```dart
+final repository = repo(context);
+```
+
+### Only BlocProvider
+
+If you want to use only `BlocProvider` you have to extends `BlocProviderScreen` or `CubitProviderScreen` depending on your use case.
+
+```dart
+class CounterPage extends BlocProviderScreen {
+ const CounterPage({super.key});
+ //...
+}
+
+// or, if you want to use Cubit
+
+class CounterPage extends CubitProviderScreen {
+ const CounterPage({super.key});
+ //...
+}
+```
+
+Then, create a Bloc or Cubit instance by implementing the `create` method.
+
+```dart
+@override
+CounterBloc create(BuildContext context) => CounterBloc();
+
+// or, if you want to use Cubit
+
+@override
+CounterCubit create(BuildContext context) => CounterCubit();
+```
+
+Finaly, you have to implement the `buildChild` method to build your screen.
+
+```dart
+@override
+Widget buildChild(BuildContext context) {
+ // return ...
+}
+```
+
+> Note: here, you can use BlocBuilder, BlocListener,... and access Bloc and Repository instance with the mixin helper.
+
+### Only BlocConsumer
+
+If you want to use only `BlocConsumer` you have to extends `BlocConsumerScreen` or `CubitConsumerScreen` depending on your use case.
+
+> Note: using directly `BlocConsumer` assumes you have already provided a Bloc or Cubit instance.
+
+```dart
+class CounterPage extends BlocConsumerScreen {
+ const CounterPage({super.key});
+}
+
+// or, if you want to use Cubit
+
+class CounterPage extends CubitConsumerScreen {
+ const CounterPage({super.key});
+}
+```
+
+Then, just implement the `onBuild` method to build your screen.
+
+```dart
+@override
+Widget onBuild(BuildContext context, CounterState state) {
+ return Text(state.count.toString());
+ // or... more complex widgets
+}
+```
+
+> Note: you can override `onBuild`, but also `onListen`, `shouldBuildWhen` and `shouldListenWhen` methods.
+
+### Both BlocProvider and BlocConsumer
+
+You can use both `BlocProvider` and `BlocConsumer` in the same screen, with the `BlocScreen` or `CubitScreen` depending on your use case.
+
+```dart
+class CounterPage extends BlocScreen {
+ const CounterPage({super.key});
+}
+
+// or, if you want to use Cubit
+
+class CounterPage extends CubitScreen {
+ const CounterPage({super.key});
+}
+```
+
+Then, you can create a Bloc or Cubit instance by implementing the `create` method.
+
+```dart
+@override
+CounterBloc create(BuildContext context) => CounterBloc();
+
+// or, if you want to use Cubit
+
+@override
+CounterCubit create(BuildContext context) => CounterCubit();
+```
+
+And, finally, just implement the `onBuild` method to build your screen.
+
+```dart
+@override
+Widget onBuild(BuildContext context, CounterState state) {
+ return Text(state.count.toString());
+ // or... more complex widgets
+}
+```
+
+> Note: check **BlocProvider** and **BlocConsumer** documentation for more information.
+
+You'll find a more examples in the `example/lib/counter/` directory.
\ No newline at end of file
diff --git a/packages/wyatt_bloc_helper/example/.gitignore b/packages/wyatt_bloc_helper/example/.gitignore
new file mode 100644
index 00000000..a8e938c0
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/.gitignore
@@ -0,0 +1,47 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+migrate_working_dir/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+#.vscode/
+
+# Flutter/Dart/Pub related
+**/doc/api/
+**/ios/Flutter/.last_build_id
+.dart_tool/
+.flutter-plugins
+.flutter-plugins-dependencies
+.packages
+.pub-cache/
+.pub/
+/build/
+
+# Web related
+lib/generated_plugin_registrant.dart
+
+# Symbolication related
+app.*.symbols
+
+# Obfuscation related
+app.*.map.json
+
+# Android Studio will place build artifacts here
+/android/app/debug
+/android/app/profile
+/android/app/release
diff --git a/packages/wyatt_bloc_helper/example/.metadata b/packages/wyatt_bloc_helper/example/.metadata
new file mode 100644
index 00000000..8bb66d20
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/.metadata
@@ -0,0 +1,30 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled.
+
+version:
+ revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
+ channel: stable
+
+project_type: app
+
+# Tracks metadata for the flutter migrate command
+migration:
+ platforms:
+ - platform: root
+ create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
+ base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
+ - platform: android
+ create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
+ base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
+
+ # User provided section
+
+ # List of Local paths (relative to this file) that should be
+ # ignored by the migrate tool.
+ #
+ # Files that are not part of the templates will be ignored by default.
+ unmanaged_files:
+ - 'lib/main.dart'
+ - 'ios/Runner.xcodeproj/project.pbxproj'
diff --git a/packages/wyatt_bloc_helper/example/README.md b/packages/wyatt_bloc_helper/example/README.md
new file mode 100644
index 00000000..36a52159
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/README.md
@@ -0,0 +1,16 @@
+# bloc_helper_example
+
+A new Flutter project.
+
+## Getting Started
+
+This project is a starting point for a Flutter application.
+
+A few resources to get you started if this is your first Flutter project:
+
+- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
+- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
+
+For help getting started with Flutter development, view the
+[online documentation](https://docs.flutter.dev/), which offers tutorials,
+samples, guidance on mobile development, and a full API reference.
diff --git a/packages/wyatt_bloc_helper/example/analysis_options.yaml b/packages/wyatt_bloc_helper/example/analysis_options.yaml
new file mode 100644
index 00000000..61b6c4de
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/analysis_options.yaml
@@ -0,0 +1,29 @@
+# This file configures the analyzer, which statically analyzes Dart code to
+# check for errors, warnings, and lints.
+#
+# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
+# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
+# invoked from the command line by running `flutter analyze`.
+
+# The following line activates a set of recommended lints for Flutter apps,
+# packages, and plugins designed to encourage good coding practices.
+include: package:flutter_lints/flutter.yaml
+
+linter:
+ # The lint rules applied to this project can be customized in the
+ # section below to disable rules from the `package:flutter_lints/flutter.yaml`
+ # included above or to enable additional rules. A list of all available lints
+ # and their documentation is published at
+ # https://dart-lang.github.io/linter/lints/index.html.
+ #
+ # Instead of disabling a lint rule for the entire project in the
+ # section below, it can also be suppressed for a single line of code
+ # or a specific dart file by using the `// ignore: name_of_lint` and
+ # `// ignore_for_file: name_of_lint` syntax on the line or in the file
+ # producing the lint.
+ rules:
+ # avoid_print: false # Uncomment to disable the `avoid_print` rule
+ # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
+
+# Additional information about this file can be found at
+# https://dart.dev/guides/language/analysis-options
diff --git a/packages/wyatt_bloc_helper/example/android/.gitignore b/packages/wyatt_bloc_helper/example/android/.gitignore
new file mode 100644
index 00000000..6f568019
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/android/.gitignore
@@ -0,0 +1,13 @@
+gradle-wrapper.jar
+/.gradle
+/captures/
+/gradlew
+/gradlew.bat
+/local.properties
+GeneratedPluginRegistrant.java
+
+# Remember to never publicly share your keystore.
+# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
+key.properties
+**/*.keystore
+**/*.jks
diff --git a/packages/wyatt_bloc_helper/example/android/app/build.gradle b/packages/wyatt_bloc_helper/example/android/app/build.gradle
new file mode 100644
index 00000000..e4bb4908
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/android/app/build.gradle
@@ -0,0 +1,71 @@
+def localProperties = new Properties()
+def localPropertiesFile = rootProject.file('local.properties')
+if (localPropertiesFile.exists()) {
+ localPropertiesFile.withReader('UTF-8') { reader ->
+ localProperties.load(reader)
+ }
+}
+
+def flutterRoot = localProperties.getProperty('flutter.sdk')
+if (flutterRoot == null) {
+ throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
+}
+
+def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
+if (flutterVersionCode == null) {
+ flutterVersionCode = '1'
+}
+
+def flutterVersionName = localProperties.getProperty('flutter.versionName')
+if (flutterVersionName == null) {
+ flutterVersionName = '1.0'
+}
+
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
+
+android {
+ compileSdkVersion flutter.compileSdkVersion
+ ndkVersion flutter.ndkVersion
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+
+ sourceSets {
+ main.java.srcDirs += 'src/main/kotlin'
+ }
+
+ defaultConfig {
+ // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
+ applicationId "com.example.bloc_helper_example"
+ // You can update the following values to match your application needs.
+ // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
+ minSdkVersion flutter.minSdkVersion
+ targetSdkVersion flutter.targetSdkVersion
+ versionCode flutterVersionCode.toInteger()
+ versionName flutterVersionName
+ }
+
+ buildTypes {
+ release {
+ // TODO: Add your own signing config for the release build.
+ // Signing with the debug keys for now, so `flutter run --release` works.
+ signingConfig signingConfigs.debug
+ }
+ }
+}
+
+flutter {
+ source '../..'
+}
+
+dependencies {
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+}
diff --git a/packages/wyatt_bloc_helper/example/android/app/src/debug/AndroidManifest.xml b/packages/wyatt_bloc_helper/example/android/app/src/debug/AndroidManifest.xml
new file mode 100644
index 00000000..a4cfdda7
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/android/app/src/debug/AndroidManifest.xml
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/packages/wyatt_bloc_helper/example/android/app/src/main/AndroidManifest.xml b/packages/wyatt_bloc_helper/example/android/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..c0f5fe63
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/wyatt_bloc_helper/example/android/app/src/main/kotlin/com/example/bloc_helper_example/MainActivity.kt b/packages/wyatt_bloc_helper/example/android/app/src/main/kotlin/com/example/bloc_helper_example/MainActivity.kt
new file mode 100644
index 00000000..46dfde89
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/android/app/src/main/kotlin/com/example/bloc_helper_example/MainActivity.kt
@@ -0,0 +1,6 @@
+package com.example.bloc_helper_example
+
+import io.flutter.embedding.android.FlutterActivity
+
+class MainActivity: FlutterActivity() {
+}
diff --git a/packages/wyatt_bloc_helper/example/android/app/src/main/res/drawable-v21/launch_background.xml b/packages/wyatt_bloc_helper/example/android/app/src/main/res/drawable-v21/launch_background.xml
new file mode 100644
index 00000000..f74085f3
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/android/app/src/main/res/drawable-v21/launch_background.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/packages/wyatt_bloc_helper/example/android/app/src/main/res/drawable/launch_background.xml b/packages/wyatt_bloc_helper/example/android/app/src/main/res/drawable/launch_background.xml
new file mode 100644
index 00000000..304732f8
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/android/app/src/main/res/drawable/launch_background.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/packages/wyatt_bloc_helper/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/packages/wyatt_bloc_helper/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 00000000..db77bb4b
Binary files /dev/null and b/packages/wyatt_bloc_helper/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/packages/wyatt_bloc_helper/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/packages/wyatt_bloc_helper/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 00000000..17987b79
Binary files /dev/null and b/packages/wyatt_bloc_helper/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/packages/wyatt_bloc_helper/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/packages/wyatt_bloc_helper/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 00000000..09d43914
Binary files /dev/null and b/packages/wyatt_bloc_helper/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/packages/wyatt_bloc_helper/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/packages/wyatt_bloc_helper/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 00000000..d5f1c8d3
Binary files /dev/null and b/packages/wyatt_bloc_helper/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/packages/wyatt_bloc_helper/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/packages/wyatt_bloc_helper/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 00000000..4d6372ee
Binary files /dev/null and b/packages/wyatt_bloc_helper/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/packages/wyatt_bloc_helper/example/android/app/src/main/res/values-night/styles.xml b/packages/wyatt_bloc_helper/example/android/app/src/main/res/values-night/styles.xml
new file mode 100644
index 00000000..06952be7
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/android/app/src/main/res/values-night/styles.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/packages/wyatt_bloc_helper/example/android/app/src/main/res/values/styles.xml b/packages/wyatt_bloc_helper/example/android/app/src/main/res/values/styles.xml
new file mode 100644
index 00000000..cb1ef880
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/android/app/src/main/res/values/styles.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/packages/wyatt_bloc_helper/example/android/app/src/profile/AndroidManifest.xml b/packages/wyatt_bloc_helper/example/android/app/src/profile/AndroidManifest.xml
new file mode 100644
index 00000000..a4cfdda7
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/android/app/src/profile/AndroidManifest.xml
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/packages/wyatt_bloc_helper/example/android/build.gradle b/packages/wyatt_bloc_helper/example/android/build.gradle
new file mode 100644
index 00000000..83ae2200
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/android/build.gradle
@@ -0,0 +1,31 @@
+buildscript {
+ ext.kotlin_version = '1.6.10'
+ repositories {
+ google()
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:7.1.2'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+rootProject.buildDir = '../build'
+subprojects {
+ project.buildDir = "${rootProject.buildDir}/${project.name}"
+}
+subprojects {
+ project.evaluationDependsOn(':app')
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/packages/wyatt_bloc_helper/example/android/gradle.properties b/packages/wyatt_bloc_helper/example/android/gradle.properties
new file mode 100644
index 00000000..94adc3a3
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/android/gradle.properties
@@ -0,0 +1,3 @@
+org.gradle.jvmargs=-Xmx1536M
+android.useAndroidX=true
+android.enableJetifier=true
diff --git a/packages/wyatt_bloc_helper/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/wyatt_bloc_helper/example/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..cc5527d7
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Jun 23 08:50:38 CEST 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
diff --git a/packages/wyatt_bloc_helper/example/android/settings.gradle b/packages/wyatt_bloc_helper/example/android/settings.gradle
new file mode 100644
index 00000000..44e62bcf
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/android/settings.gradle
@@ -0,0 +1,11 @@
+include ':app'
+
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
+
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
+
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
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
new file mode 100644
index 00000000..0a99298b
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/lib/counter/bloc/counter_bloc.dart
@@ -0,0 +1,34 @@
+// 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:equatable/equatable.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+part 'counter_event.dart';
+part 'counter_state.dart';
+
+class CounterBloc extends Bloc {
+ CounterBloc() : super(const CounterInitial()) {
+
+ on((event, emit) {
+ emit(CounterModified(state.count + 1));
+ });
+
+ on((event, emit) {
+ emit(CounterModified(state.count - 1));
+ });
+ }
+}
diff --git a/packages/wyatt_bloc_helper/example/lib/counter/bloc/counter_event.dart b/packages/wyatt_bloc_helper/example/lib/counter/bloc/counter_event.dart
new file mode 100644
index 00000000..c9d38554
--- /dev/null
+++ b/packages/wyatt_bloc_helper/example/lib/counter/bloc/counter_event.dart
@@ -0,0 +1,28 @@
+// 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 .
+
+part of 'counter_bloc.dart';
+
+abstract class CounterEvent extends Equatable {
+ const CounterEvent();
+
+ @override
+ List