From 74593fa9fcb19805223cd9e2017a05b6e2e4c9ee Mon Sep 17 00:00:00 2001 From: Hugo Pointcheval Date: Mon, 13 Nov 2023 18:03:10 +0100 Subject: [PATCH 1/9] feat(crud)!: move crud firestore implementation into his own package --- packages/wyatt_crud_bloc/example/.gitignore | 2 - packages/wyatt_crud_bloc/example/.metadata | 16 +- .../example/android/app/build.gradle | 26 +- .../android/app/src/debug/AndroidManifest.xml | 6 +- .../android/app/src/main/AndroidManifest.xml | 7 +- .../MainActivity.kt | 2 +- .../app/src/main/res/values-night/styles.xml | 2 +- .../app/src/main/res/values/styles.xml | 2 +- .../app/src/profile/AndroidManifest.xml | 6 +- .../example/android/build.gradle | 6 +- .../gradle/wrapper/gradle-wrapper.properties | 3 +- .../example/android/settings.gradle | 25 +- .../wyatt_crud_bloc/example/ios/.gitignore | 34 - .../ios/Flutter/AppFrameworkInfo.plist | 26 - .../example/ios/Flutter/Debug.xcconfig | 2 - .../example/ios/Flutter/Release.xcconfig | 2 - packages/wyatt_crud_bloc/example/ios/Podfile | 41 - .../wyatt_crud_bloc/example/ios/Podfile.lock | 757 ------------------ .../ios/Runner.xcodeproj/project.pbxproj | 552 ------------- .../contents.xcworkspacedata | 7 - .../xcshareddata/IDEWorkspaceChecks.plist | 8 - .../xcshareddata/xcschemes/Runner.xcscheme | 87 -- .../contents.xcworkspacedata | 10 - .../xcshareddata/IDEWorkspaceChecks.plist | 8 - .../example/ios/Runner/AppDelegate.swift | 13 - .../AppIcon.appiconset/Contents.json | 122 --- .../Icon-App-1024x1024@1x.png | Bin 10932 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 564 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 1588 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 1025 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 1716 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 1920 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 1895 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 3831 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 1888 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 3294 -> 0 bytes .../Icon-App-83.5x83.5@2x.png | Bin 3612 -> 0 bytes .../LaunchImage.imageset/Contents.json | 23 - .../LaunchImage.imageset/LaunchImage.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/LaunchImage@2x.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/LaunchImage@3x.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/README.md | 5 - .../Runner/Base.lproj/LaunchScreen.storyboard | 37 - .../ios/Runner/Base.lproj/Main.storyboard | 26 - .../example/ios/Runner/Info.plist | 51 -- .../ios/Runner/Runner-Bridging-Header.h | 1 - .../example/lib/advanced_cubit_view.dart | 151 ++++ packages/wyatt_crud_bloc/example/lib/app.dart | 126 ++- .../example/lib/basic_cubit_view.dart | 150 ++++ .../example/lib/firebase_options.dart | 63 ++ .../example/lib/main_firestore.dart | 44 + .../lib/{main.dart => main_memory.dart} | 9 +- .../example/lib/user_advanced_cubit.dart | 54 ++ .../example/lib/user_cubit.dart | 23 +- .../lib/user_entity.dart} | 26 +- .../lib/{models.dart => user_model.dart} | 38 +- .../example/lib/user_model.g.dart | 21 + packages/wyatt_crud_bloc/example/pubspec.yaml | 16 +- .../example/test/widget_test.dart | 1 - .../wyatt_crud_bloc/lib/src/core/core.dart | 3 + .../enums/operation_type.dart} | 10 +- .../lib/src/core/enums/where_query_type.dart | 2 +- .../lib/src/core/mixins/operation.dart | 26 +- .../lib/src/core/model_identifier.dart | 57 ++ .../model_mapper.dart} | 13 +- .../wyatt_crud_bloc/lib/src/data/data.dart | 7 +- .../data_sources/crud_data_source.dart | 57 +- ...t => crud_data_source_in_memory_impl.dart} | 114 ++- .../repositories/crud_repository_impl.dart | 77 +- .../lib/src/domain/domain.dart | 5 +- .../lib/src/domain/entities/entities.dart | 18 - .../lib/src/domain/entities/query.dart | 19 +- .../domain/repositories/crud_repository.dart | 11 +- .../src/domain/repositories/repositories.dart | 17 - .../lib/src/domain/usecases/create.dart | 21 +- .../lib/src/domain/usecases/delete.dart | 20 +- .../lib/src/domain/usecases/delete_all.dart | 11 +- .../lib/src/domain/usecases/get.dart | 22 +- .../lib/src/domain/usecases/get_all.dart | 12 +- .../usecases/params/stream_parameters.dart | 2 +- .../usecases/{query.dart => search.dart} | 28 +- .../lib/src/domain/usecases/stream.dart | 44 + .../lib/src/domain/usecases/update.dart | 23 +- .../lib/src/domain/usecases/update_all.dart | 22 +- .../lib/src/domain/usecases/usecases.dart | 26 +- .../crud/blocs/crud_advanced_cubit.dart | 102 ++- .../blocs/crud_base_cubit/crud_state.dart | 32 +- .../src/features/crud/blocs/crud_cubit.dart | 146 ++-- .../src/features/crud/builder/builder.dart | 17 - .../lib/src/features/crud/crud.dart | 2 +- .../wyatt_crud_bloc/lib/wyatt_crud_bloc.dart | 2 +- packages/wyatt_crud_bloc/pubspec.yaml | 6 +- .../wyatt_crud_bloc_firestore/.gitignore | 1 + .../wyatt_crud_bloc_firestore/.metadata | 10 + .../wyatt_crud_bloc_firestore/.pubignore | 1 + .../wyatt_crud_bloc_firestore/AUTHORS | 1 + .../wyatt_crud_bloc_firestore/CHANGELOG.md | 3 + .../wyatt_crud_bloc_firestore/LICENSE | 1 + .../wyatt_crud_bloc_firestore/README.md | 39 + .../analysis_options.yaml | 1 + .../crud_data_source_firestore_impl.dart} | 93 ++- .../lib/wyatt_crud_firestore.dart} | 7 +- .../wyatt_crud_bloc_firestore/pubspec.yaml | 34 + 107 files changed, 1392 insertions(+), 2410 deletions(-) rename packages/wyatt_crud_bloc/example/android/app/src/main/kotlin/com/example/{crud_bloc_example => example}/MainActivity.kt (71%) delete mode 100644 packages/wyatt_crud_bloc/example/ios/.gitignore delete mode 100644 packages/wyatt_crud_bloc/example/ios/Flutter/AppFrameworkInfo.plist delete mode 100644 packages/wyatt_crud_bloc/example/ios/Flutter/Debug.xcconfig delete mode 100644 packages/wyatt_crud_bloc/example/ios/Flutter/Release.xcconfig delete mode 100644 packages/wyatt_crud_bloc/example/ios/Podfile delete mode 100644 packages/wyatt_crud_bloc/example/ios/Podfile.lock delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/project.pbxproj delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner.xcworkspace/contents.xcworkspacedata delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/AppDelegate.swift delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Base.lproj/LaunchScreen.storyboard delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Base.lproj/Main.storyboard delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Info.plist delete mode 100644 packages/wyatt_crud_bloc/example/ios/Runner/Runner-Bridging-Header.h create mode 100644 packages/wyatt_crud_bloc/example/lib/advanced_cubit_view.dart create mode 100644 packages/wyatt_crud_bloc/example/lib/basic_cubit_view.dart create mode 100644 packages/wyatt_crud_bloc/example/lib/firebase_options.dart create mode 100644 packages/wyatt_crud_bloc/example/lib/main_firestore.dart rename packages/wyatt_crud_bloc/example/lib/{main.dart => main_memory.dart} (81%) create mode 100644 packages/wyatt_crud_bloc/example/lib/user_advanced_cubit.dart rename packages/wyatt_crud_bloc/{lib/src/domain/entities/object_model.dart => example/lib/user_entity.dart} (65%) rename packages/wyatt_crud_bloc/example/lib/{models.dart => user_model.dart} (56%) create mode 100644 packages/wyatt_crud_bloc/example/lib/user_model.g.dart delete mode 100644 packages/wyatt_crud_bloc/example/test/widget_test.dart rename packages/wyatt_crud_bloc/lib/src/{domain/data_sources/data_sources.dart => core/enums/operation_type.dart} (86%) create mode 100644 packages/wyatt_crud_bloc/lib/src/core/model_identifier.dart rename packages/wyatt_crud_bloc/lib/src/{data/data_sources/data_sources.dart => core/model_mapper.dart} (71%) rename packages/wyatt_crud_bloc/lib/src/{domain => data}/data_sources/crud_data_source.dart (58%) rename packages/wyatt_crud_bloc/lib/src/data/data_sources/{local/crud_in_memory_data_source_impl.dart => crud_data_source_in_memory_impl.dart} (54%) delete mode 100644 packages/wyatt_crud_bloc/lib/src/domain/entities/entities.dart delete mode 100644 packages/wyatt_crud_bloc/lib/src/domain/repositories/repositories.dart rename packages/wyatt_crud_bloc/lib/src/domain/usecases/{query.dart => search.dart} (61%) create mode 100644 packages/wyatt_crud_bloc/lib/src/domain/usecases/stream.dart delete mode 100644 packages/wyatt_crud_bloc/lib/src/features/crud/builder/builder.dart create mode 120000 packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.gitignore create mode 100644 packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.metadata create mode 120000 packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.pubignore create mode 120000 packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/AUTHORS create mode 100644 packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/CHANGELOG.md create mode 120000 packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/LICENSE create mode 100644 packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/README.md create mode 100644 packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/analysis_options.yaml rename packages/wyatt_crud_bloc/{lib/src/data/data_sources/remote/crud_firestore_data_source_impl.dart => wyatt_crud_bloc_firestore/lib/src/data/crud_data_source_firestore_impl.dart} (70%) rename packages/wyatt_crud_bloc/{lib/src/data/repositories/repositories.dart => wyatt_crud_bloc_firestore/lib/wyatt_crud_firestore.dart} (78%) create mode 100644 packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/pubspec.yaml diff --git a/packages/wyatt_crud_bloc/example/.gitignore b/packages/wyatt_crud_bloc/example/.gitignore index c3b6d4c7..0fa6b675 100644 --- a/packages/wyatt_crud_bloc/example/.gitignore +++ b/packages/wyatt_crud_bloc/example/.gitignore @@ -44,5 +44,3 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release - -/lib/firebase_options.dart \ No newline at end of file diff --git a/packages/wyatt_crud_bloc/example/.metadata b/packages/wyatt_crud_bloc/example/.metadata index 56512842..a072c7d9 100644 --- a/packages/wyatt_crud_bloc/example/.metadata +++ b/packages/wyatt_crud_bloc/example/.metadata @@ -1,11 +1,11 @@ # 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. +# This file should be version controlled and should not be manually edited. version: - revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 - channel: stable + revision: "d211f42860350d914a5ad8102f9ec32764dc6d06" + channel: "stable" project_type: app @@ -13,11 +13,11 @@ project_type: app migration: platforms: - platform: root - create_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 - base_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 - - platform: ios - create_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 - base_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 + create_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 + base_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 + - platform: android + create_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 + base_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 # User provided section diff --git a/packages/wyatt_crud_bloc/example/android/app/build.gradle b/packages/wyatt_crud_bloc/example/android/app/build.gradle index 8ddaae13..0b93b1c2 100644 --- a/packages/wyatt_crud_bloc/example/android/app/build.gradle +++ b/packages/wyatt_crud_bloc/example/android/app/build.gradle @@ -1,3 +1,9 @@ +plugins { + id "com.android.application" + id "kotlin-android" + id "dev.flutter.flutter-gradle-plugin" +} + def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { @@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) { } } -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' @@ -21,15 +22,10 @@ if (flutterVersionName == null) { flutterVersionName = '1.0' } -apply plugin: 'com.android.application' -// START: FlutterFire Configuration -apply plugin: 'com.google.gms.google-services' -// END: FlutterFire Configuration -apply plugin: 'kotlin-android' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - android { + namespace "com.example.example" compileSdkVersion flutter.compileSdkVersion + ndkVersion flutter.ndkVersion compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 @@ -47,6 +43,8 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.crud_bloc_example" + // You can update the following values to match your application needs. + // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. minSdkVersion 21 targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() @@ -66,6 +64,4 @@ flutter { source '../..' } -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" -} +dependencies {} diff --git a/packages/wyatt_crud_bloc/example/android/app/src/debug/AndroidManifest.xml b/packages/wyatt_crud_bloc/example/android/app/src/debug/AndroidManifest.xml index e9dd957b..399f6981 100644 --- a/packages/wyatt_crud_bloc/example/android/app/src/debug/AndroidManifest.xml +++ b/packages/wyatt_crud_bloc/example/android/app/src/debug/AndroidManifest.xml @@ -1,6 +1,6 @@ - - diff --git a/packages/wyatt_crud_bloc/example/android/app/src/main/AndroidManifest.xml b/packages/wyatt_crud_bloc/example/android/app/src/main/AndroidManifest.xml index 082c9cb4..19b862ec 100644 --- a/packages/wyatt_crud_bloc/example/android/app/src/main/AndroidManifest.xml +++ b/packages/wyatt_crud_bloc/example/android/app/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ - - + diff --git a/packages/wyatt_crud_bloc/example/android/build.gradle b/packages/wyatt_crud_bloc/example/android/build.gradle index 111a0724..0391438f 100644 --- a/packages/wyatt_crud_bloc/example/android/build.gradle +++ b/packages/wyatt_crud_bloc/example/android/build.gradle @@ -1,12 +1,12 @@ buildscript { - ext.kotlin_version = '1.6.10' + ext.kotlin_version = '1.7.10' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:4.1.0' + classpath 'com.android.tools.build:gradle:7.3.0' // START: FlutterFire Configuration classpath 'com.google.gms:google-services:4.3.10' // END: FlutterFire Configuration @@ -29,6 +29,6 @@ subprojects { project.evaluationDependsOn(':app') } -task clean(type: Delete) { +tasks.register("clean", Delete) { delete rootProject.buildDir } diff --git a/packages/wyatt_crud_bloc/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/wyatt_crud_bloc/example/android/gradle/wrapper/gradle-wrapper.properties index bc6a58af..3c472b99 100644 --- a/packages/wyatt_crud_bloc/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/wyatt_crud_bloc/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#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-6.7-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip diff --git a/packages/wyatt_crud_bloc/example/android/settings.gradle b/packages/wyatt_crud_bloc/example/android/settings.gradle index 44e62bcf..55c4ca8b 100644 --- a/packages/wyatt_crud_bloc/example/android/settings.gradle +++ b/packages/wyatt_crud_bloc/example/android/settings.gradle @@ -1,11 +1,20 @@ -include ':app' +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + } + settings.ext.flutterSdkPath = flutterSdkPath() -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() + includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + plugins { + id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false + } +} -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" +include ":app" + +apply from: "${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/packages/wyatt_crud_bloc/example/ios/.gitignore b/packages/wyatt_crud_bloc/example/ios/.gitignore deleted file mode 100644 index 7a7f9873..00000000 --- a/packages/wyatt_crud_bloc/example/ios/.gitignore +++ /dev/null @@ -1,34 +0,0 @@ -**/dgph -*.mode1v3 -*.mode2v3 -*.moved-aside -*.pbxuser -*.perspectivev3 -**/*sync/ -.sconsign.dblite -.tags* -**/.vagrant/ -**/DerivedData/ -Icon? -**/Pods/ -**/.symlinks/ -profile -xcuserdata -**/.generated/ -Flutter/App.framework -Flutter/Flutter.framework -Flutter/Flutter.podspec -Flutter/Generated.xcconfig -Flutter/ephemeral/ -Flutter/app.flx -Flutter/app.zip -Flutter/flutter_assets/ -Flutter/flutter_export_environment.sh -ServiceDefinitions.json -Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!default.mode1v3 -!default.mode2v3 -!default.pbxuser -!default.perspectivev3 diff --git a/packages/wyatt_crud_bloc/example/ios/Flutter/AppFrameworkInfo.plist b/packages/wyatt_crud_bloc/example/ios/Flutter/AppFrameworkInfo.plist deleted file mode 100644 index 9625e105..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Flutter/AppFrameworkInfo.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - MinimumOSVersion - 11.0 - - diff --git a/packages/wyatt_crud_bloc/example/ios/Flutter/Debug.xcconfig b/packages/wyatt_crud_bloc/example/ios/Flutter/Debug.xcconfig deleted file mode 100644 index ec97fc6f..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" -#include "Generated.xcconfig" diff --git a/packages/wyatt_crud_bloc/example/ios/Flutter/Release.xcconfig b/packages/wyatt_crud_bloc/example/ios/Flutter/Release.xcconfig deleted file mode 100644 index c4855bfe..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" -#include "Generated.xcconfig" diff --git a/packages/wyatt_crud_bloc/example/ios/Podfile b/packages/wyatt_crud_bloc/example/ios/Podfile deleted file mode 100644 index 88359b22..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Podfile +++ /dev/null @@ -1,41 +0,0 @@ -# Uncomment this line to define a global platform for your project -# platform :ios, '11.0' - -# CocoaPods analytics sends network stats synchronously affecting flutter build latency. -ENV['COCOAPODS_DISABLE_STATS'] = 'true' - -project 'Runner', { - 'Debug' => :debug, - 'Profile' => :release, - 'Release' => :release, -} - -def flutter_root - generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) - unless File.exist?(generated_xcode_build_settings_path) - raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" - end - - File.foreach(generated_xcode_build_settings_path) do |line| - matches = line.match(/FLUTTER_ROOT\=(.*)/) - return matches[1].strip if matches - end - raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" -end - -require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) - -flutter_ios_podfile_setup - -target 'Runner' do - use_frameworks! - use_modular_headers! - - flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) -end - -post_install do |installer| - installer.pods_project.targets.each do |target| - flutter_additional_ios_build_settings(target) - end -end diff --git a/packages/wyatt_crud_bloc/example/ios/Podfile.lock b/packages/wyatt_crud_bloc/example/ios/Podfile.lock deleted file mode 100644 index 8339868b..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Podfile.lock +++ /dev/null @@ -1,757 +0,0 @@ -PODS: - - abseil/algorithm (1.20211102.0): - - abseil/algorithm/algorithm (= 1.20211102.0) - - abseil/algorithm/container (= 1.20211102.0) - - abseil/algorithm/algorithm (1.20211102.0): - - abseil/base/config - - abseil/algorithm/container (1.20211102.0): - - abseil/algorithm/algorithm - - abseil/base/core_headers - - abseil/meta/type_traits - - abseil/base (1.20211102.0): - - abseil/base/atomic_hook (= 1.20211102.0) - - abseil/base/base (= 1.20211102.0) - - abseil/base/base_internal (= 1.20211102.0) - - abseil/base/config (= 1.20211102.0) - - abseil/base/core_headers (= 1.20211102.0) - - abseil/base/dynamic_annotations (= 1.20211102.0) - - abseil/base/endian (= 1.20211102.0) - - abseil/base/errno_saver (= 1.20211102.0) - - abseil/base/fast_type_id (= 1.20211102.0) - - abseil/base/log_severity (= 1.20211102.0) - - abseil/base/malloc_internal (= 1.20211102.0) - - abseil/base/pretty_function (= 1.20211102.0) - - abseil/base/raw_logging_internal (= 1.20211102.0) - - abseil/base/spinlock_wait (= 1.20211102.0) - - abseil/base/strerror (= 1.20211102.0) - - abseil/base/throw_delegate (= 1.20211102.0) - - abseil/base/atomic_hook (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/base (1.20211102.0): - - abseil/base/atomic_hook - - abseil/base/base_internal - - abseil/base/config - - abseil/base/core_headers - - abseil/base/dynamic_annotations - - abseil/base/log_severity - - abseil/base/raw_logging_internal - - abseil/base/spinlock_wait - - abseil/meta/type_traits - - abseil/base/base_internal (1.20211102.0): - - abseil/base/config - - abseil/meta/type_traits - - abseil/base/config (1.20211102.0) - - abseil/base/core_headers (1.20211102.0): - - abseil/base/config - - abseil/base/dynamic_annotations (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/endian (1.20211102.0): - - abseil/base/base - - abseil/base/config - - abseil/base/core_headers - - abseil/base/errno_saver (1.20211102.0): - - abseil/base/config - - abseil/base/fast_type_id (1.20211102.0): - - abseil/base/config - - abseil/base/log_severity (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/malloc_internal (1.20211102.0): - - abseil/base/base - - abseil/base/base_internal - - abseil/base/config - - abseil/base/core_headers - - abseil/base/dynamic_annotations - - abseil/base/raw_logging_internal - - abseil/base/pretty_function (1.20211102.0) - - abseil/base/raw_logging_internal (1.20211102.0): - - abseil/base/atomic_hook - - abseil/base/config - - abseil/base/core_headers - - abseil/base/log_severity - - abseil/base/spinlock_wait (1.20211102.0): - - abseil/base/base_internal - - abseil/base/core_headers - - abseil/base/errno_saver - - abseil/base/strerror (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/errno_saver - - abseil/base/throw_delegate (1.20211102.0): - - abseil/base/config - - abseil/base/raw_logging_internal - - abseil/container/common (1.20211102.0): - - abseil/meta/type_traits - - abseil/types/optional - - abseil/container/compressed_tuple (1.20211102.0): - - abseil/utility/utility - - abseil/container/container_memory (1.20211102.0): - - abseil/base/config - - abseil/memory/memory - - abseil/meta/type_traits - - abseil/utility/utility - - abseil/container/fixed_array (1.20211102.0): - - abseil/algorithm/algorithm - - abseil/base/config - - abseil/base/core_headers - - abseil/base/dynamic_annotations - - abseil/base/throw_delegate - - abseil/container/compressed_tuple - - abseil/memory/memory - - abseil/container/flat_hash_map (1.20211102.0): - - abseil/algorithm/container - - abseil/container/container_memory - - abseil/container/hash_function_defaults - - abseil/container/raw_hash_map - - abseil/memory/memory - - abseil/container/hash_function_defaults (1.20211102.0): - - abseil/base/config - - abseil/hash/hash - - abseil/strings/cord - - abseil/strings/strings - - abseil/container/hash_policy_traits (1.20211102.0): - - abseil/meta/type_traits - - abseil/container/hashtable_debug_hooks (1.20211102.0): - - abseil/base/config - - abseil/container/hashtablez_sampler (1.20211102.0): - - abseil/base/base - - abseil/base/core_headers - - abseil/container/have_sse - - abseil/debugging/stacktrace - - abseil/memory/memory - - abseil/profiling/exponential_biased - - abseil/profiling/sample_recorder - - abseil/synchronization/synchronization - - abseil/utility/utility - - abseil/container/have_sse (1.20211102.0) - - abseil/container/inlined_vector (1.20211102.0): - - abseil/algorithm/algorithm - - abseil/base/core_headers - - abseil/base/throw_delegate - - abseil/container/inlined_vector_internal - - abseil/memory/memory - - abseil/container/inlined_vector_internal (1.20211102.0): - - abseil/base/core_headers - - abseil/container/compressed_tuple - - abseil/memory/memory - - abseil/meta/type_traits - - abseil/types/span - - abseil/container/layout (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/meta/type_traits - - abseil/strings/strings - - abseil/types/span - - abseil/utility/utility - - abseil/container/raw_hash_map (1.20211102.0): - - abseil/base/throw_delegate - - abseil/container/container_memory - - abseil/container/raw_hash_set - - abseil/container/raw_hash_set (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/endian - - abseil/container/common - - abseil/container/compressed_tuple - - abseil/container/container_memory - - abseil/container/hash_policy_traits - - abseil/container/hashtable_debug_hooks - - abseil/container/hashtablez_sampler - - abseil/container/have_sse - - abseil/memory/memory - - abseil/meta/type_traits - - abseil/numeric/bits - - abseil/utility/utility - - abseil/debugging/debugging_internal (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/dynamic_annotations - - abseil/base/errno_saver - - abseil/base/raw_logging_internal - - abseil/debugging/demangle_internal (1.20211102.0): - - abseil/base/base - - abseil/base/config - - abseil/base/core_headers - - abseil/debugging/stacktrace (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/debugging/debugging_internal - - abseil/debugging/symbolize (1.20211102.0): - - abseil/base/base - - abseil/base/config - - abseil/base/core_headers - - abseil/base/dynamic_annotations - - abseil/base/malloc_internal - - abseil/base/raw_logging_internal - - abseil/debugging/debugging_internal - - abseil/debugging/demangle_internal - - abseil/strings/strings - - abseil/functional/bind_front (1.20211102.0): - - abseil/base/base_internal - - abseil/container/compressed_tuple - - abseil/meta/type_traits - - abseil/utility/utility - - abseil/functional/function_ref (1.20211102.0): - - abseil/base/base_internal - - abseil/base/core_headers - - abseil/meta/type_traits - - abseil/hash/city (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/endian - - abseil/hash/hash (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/endian - - abseil/container/fixed_array - - abseil/hash/city - - abseil/hash/low_level_hash - - abseil/meta/type_traits - - abseil/numeric/int128 - - abseil/strings/strings - - abseil/types/optional - - abseil/types/variant - - abseil/utility/utility - - abseil/hash/low_level_hash (1.20211102.0): - - abseil/base/config - - abseil/base/endian - - abseil/numeric/bits - - abseil/numeric/int128 - - abseil/memory (1.20211102.0): - - abseil/memory/memory (= 1.20211102.0) - - abseil/memory/memory (1.20211102.0): - - abseil/base/core_headers - - abseil/meta/type_traits - - abseil/meta (1.20211102.0): - - abseil/meta/type_traits (= 1.20211102.0) - - abseil/meta/type_traits (1.20211102.0): - - abseil/base/config - - abseil/numeric/bits (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/numeric/int128 (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/numeric/bits - - abseil/numeric/representation (1.20211102.0): - - abseil/base/config - - abseil/profiling/exponential_biased (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/profiling/sample_recorder (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/synchronization/synchronization - - abseil/time/time - - abseil/random/distributions (1.20211102.0): - - abseil/base/base_internal - - abseil/base/config - - abseil/base/core_headers - - abseil/meta/type_traits - - abseil/numeric/bits - - abseil/random/internal/distribution_caller - - abseil/random/internal/fast_uniform_bits - - abseil/random/internal/fastmath - - abseil/random/internal/generate_real - - abseil/random/internal/iostream_state_saver - - abseil/random/internal/traits - - abseil/random/internal/uniform_helper - - abseil/random/internal/wide_multiply - - abseil/strings/strings - - abseil/random/internal/distribution_caller (1.20211102.0): - - abseil/base/config - - abseil/base/fast_type_id - - abseil/utility/utility - - abseil/random/internal/fast_uniform_bits (1.20211102.0): - - abseil/base/config - - abseil/meta/type_traits - - abseil/random/internal/fastmath (1.20211102.0): - - abseil/numeric/bits - - abseil/random/internal/generate_real (1.20211102.0): - - abseil/meta/type_traits - - abseil/numeric/bits - - abseil/random/internal/fastmath - - abseil/random/internal/traits - - abseil/random/internal/iostream_state_saver (1.20211102.0): - - abseil/meta/type_traits - - abseil/numeric/int128 - - abseil/random/internal/nonsecure_base (1.20211102.0): - - abseil/base/core_headers - - abseil/meta/type_traits - - abseil/random/internal/pool_urbg - - abseil/random/internal/salted_seed_seq - - abseil/random/internal/seed_material - - abseil/types/optional - - abseil/types/span - - abseil/random/internal/pcg_engine (1.20211102.0): - - abseil/base/config - - abseil/meta/type_traits - - abseil/numeric/bits - - abseil/numeric/int128 - - abseil/random/internal/fastmath - - abseil/random/internal/iostream_state_saver - - abseil/random/internal/platform (1.20211102.0): - - abseil/base/config - - abseil/random/internal/pool_urbg (1.20211102.0): - - abseil/base/base - - abseil/base/config - - abseil/base/core_headers - - abseil/base/endian - - abseil/base/raw_logging_internal - - abseil/random/internal/randen - - abseil/random/internal/seed_material - - abseil/random/internal/traits - - abseil/random/seed_gen_exception - - abseil/types/span - - abseil/random/internal/randen (1.20211102.0): - - abseil/base/raw_logging_internal - - abseil/random/internal/platform - - abseil/random/internal/randen_hwaes - - abseil/random/internal/randen_slow - - abseil/random/internal/randen_engine (1.20211102.0): - - abseil/base/endian - - abseil/meta/type_traits - - abseil/random/internal/iostream_state_saver - - abseil/random/internal/randen - - abseil/random/internal/randen_hwaes (1.20211102.0): - - abseil/base/config - - abseil/random/internal/platform - - abseil/random/internal/randen_hwaes_impl - - abseil/random/internal/randen_hwaes_impl (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/numeric/int128 - - abseil/random/internal/platform - - abseil/random/internal/randen_slow (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/endian - - abseil/numeric/int128 - - abseil/random/internal/platform - - abseil/random/internal/salted_seed_seq (1.20211102.0): - - abseil/container/inlined_vector - - abseil/meta/type_traits - - abseil/random/internal/seed_material - - abseil/types/optional - - abseil/types/span - - abseil/random/internal/seed_material (1.20211102.0): - - abseil/base/core_headers - - abseil/base/dynamic_annotations - - abseil/base/raw_logging_internal - - abseil/random/internal/fast_uniform_bits - - abseil/strings/strings - - abseil/types/optional - - abseil/types/span - - abseil/random/internal/traits (1.20211102.0): - - abseil/base/config - - abseil/random/internal/uniform_helper (1.20211102.0): - - abseil/base/config - - abseil/meta/type_traits - - abseil/random/internal/traits - - abseil/random/internal/wide_multiply (1.20211102.0): - - abseil/base/config - - abseil/numeric/bits - - abseil/numeric/int128 - - abseil/random/internal/traits - - abseil/random/random (1.20211102.0): - - abseil/random/distributions - - abseil/random/internal/nonsecure_base - - abseil/random/internal/pcg_engine - - abseil/random/internal/pool_urbg - - abseil/random/internal/randen_engine - - abseil/random/seed_sequences - - abseil/random/seed_gen_exception (1.20211102.0): - - abseil/base/config - - abseil/random/seed_sequences (1.20211102.0): - - abseil/container/inlined_vector - - abseil/random/internal/nonsecure_base - - abseil/random/internal/pool_urbg - - abseil/random/internal/salted_seed_seq - - abseil/random/internal/seed_material - - abseil/random/seed_gen_exception - - abseil/types/span - - abseil/status/status (1.20211102.0): - - abseil/base/atomic_hook - - abseil/base/config - - abseil/base/core_headers - - abseil/base/raw_logging_internal - - abseil/container/inlined_vector - - abseil/debugging/stacktrace - - abseil/debugging/symbolize - - abseil/functional/function_ref - - abseil/strings/cord - - abseil/strings/str_format - - abseil/strings/strings - - abseil/types/optional - - abseil/status/statusor (1.20211102.0): - - abseil/base/base - - abseil/base/core_headers - - abseil/base/raw_logging_internal - - abseil/meta/type_traits - - abseil/status/status - - abseil/strings/strings - - abseil/types/variant - - abseil/utility/utility - - abseil/strings/cord (1.20211102.0): - - abseil/base/base - - abseil/base/config - - abseil/base/core_headers - - abseil/base/endian - - abseil/base/raw_logging_internal - - abseil/container/fixed_array - - abseil/container/inlined_vector - - abseil/functional/function_ref - - abseil/meta/type_traits - - abseil/strings/cord_internal - - abseil/strings/cordz_functions - - abseil/strings/cordz_info - - abseil/strings/cordz_statistics - - abseil/strings/cordz_update_scope - - abseil/strings/cordz_update_tracker - - abseil/strings/internal - - abseil/strings/str_format - - abseil/strings/strings - - abseil/types/optional - - abseil/strings/cord_internal (1.20211102.0): - - abseil/base/base_internal - - abseil/base/config - - abseil/base/core_headers - - abseil/base/endian - - abseil/base/raw_logging_internal - - abseil/base/throw_delegate - - abseil/container/compressed_tuple - - abseil/container/inlined_vector - - abseil/container/layout - - abseil/functional/function_ref - - abseil/meta/type_traits - - abseil/strings/strings - - abseil/types/span - - abseil/strings/cordz_functions (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/raw_logging_internal - - abseil/profiling/exponential_biased - - abseil/strings/cordz_handle (1.20211102.0): - - abseil/base/base - - abseil/base/config - - abseil/base/raw_logging_internal - - abseil/synchronization/synchronization - - abseil/strings/cordz_info (1.20211102.0): - - abseil/base/base - - abseil/base/config - - abseil/base/core_headers - - abseil/base/raw_logging_internal - - abseil/container/inlined_vector - - abseil/debugging/stacktrace - - abseil/strings/cord_internal - - abseil/strings/cordz_functions - - abseil/strings/cordz_handle - - abseil/strings/cordz_statistics - - abseil/strings/cordz_update_tracker - - abseil/synchronization/synchronization - - abseil/types/span - - abseil/strings/cordz_statistics (1.20211102.0): - - abseil/base/config - - abseil/strings/cordz_update_tracker - - abseil/strings/cordz_update_scope (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/strings/cord_internal - - abseil/strings/cordz_info - - abseil/strings/cordz_update_tracker - - abseil/strings/cordz_update_tracker (1.20211102.0): - - abseil/base/config - - abseil/strings/internal (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/endian - - abseil/base/raw_logging_internal - - abseil/meta/type_traits - - abseil/strings/str_format (1.20211102.0): - - abseil/strings/str_format_internal - - abseil/strings/str_format_internal (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/functional/function_ref - - abseil/meta/type_traits - - abseil/numeric/bits - - abseil/numeric/int128 - - abseil/numeric/representation - - abseil/strings/strings - - abseil/types/optional - - abseil/types/span - - abseil/strings/strings (1.20211102.0): - - abseil/base/base - - abseil/base/config - - abseil/base/core_headers - - abseil/base/endian - - abseil/base/raw_logging_internal - - abseil/base/throw_delegate - - abseil/memory/memory - - abseil/meta/type_traits - - abseil/numeric/bits - - abseil/numeric/int128 - - abseil/strings/internal - - abseil/synchronization/graphcycles_internal (1.20211102.0): - - abseil/base/base - - abseil/base/base_internal - - abseil/base/config - - abseil/base/core_headers - - abseil/base/malloc_internal - - abseil/base/raw_logging_internal - - abseil/synchronization/kernel_timeout_internal (1.20211102.0): - - abseil/base/core_headers - - abseil/base/raw_logging_internal - - abseil/time/time - - abseil/synchronization/synchronization (1.20211102.0): - - abseil/base/atomic_hook - - abseil/base/base - - abseil/base/base_internal - - abseil/base/config - - abseil/base/core_headers - - abseil/base/dynamic_annotations - - abseil/base/malloc_internal - - abseil/base/raw_logging_internal - - abseil/debugging/stacktrace - - abseil/debugging/symbolize - - abseil/synchronization/graphcycles_internal - - abseil/synchronization/kernel_timeout_internal - - abseil/time/time - - abseil/time (1.20211102.0): - - abseil/time/internal (= 1.20211102.0) - - abseil/time/time (= 1.20211102.0) - - abseil/time/internal (1.20211102.0): - - abseil/time/internal/cctz (= 1.20211102.0) - - abseil/time/internal/cctz (1.20211102.0): - - abseil/time/internal/cctz/civil_time (= 1.20211102.0) - - abseil/time/internal/cctz/time_zone (= 1.20211102.0) - - abseil/time/internal/cctz/civil_time (1.20211102.0): - - abseil/base/config - - abseil/time/internal/cctz/time_zone (1.20211102.0): - - abseil/base/config - - abseil/time/internal/cctz/civil_time - - abseil/time/time (1.20211102.0): - - abseil/base/base - - abseil/base/core_headers - - abseil/base/raw_logging_internal - - abseil/numeric/int128 - - abseil/strings/strings - - abseil/time/internal/cctz/civil_time - - abseil/time/internal/cctz/time_zone - - abseil/types (1.20211102.0): - - abseil/types/any (= 1.20211102.0) - - abseil/types/bad_any_cast (= 1.20211102.0) - - abseil/types/bad_any_cast_impl (= 1.20211102.0) - - abseil/types/bad_optional_access (= 1.20211102.0) - - abseil/types/bad_variant_access (= 1.20211102.0) - - abseil/types/compare (= 1.20211102.0) - - abseil/types/optional (= 1.20211102.0) - - abseil/types/span (= 1.20211102.0) - - abseil/types/variant (= 1.20211102.0) - - abseil/types/any (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/fast_type_id - - abseil/meta/type_traits - - abseil/types/bad_any_cast - - abseil/utility/utility - - abseil/types/bad_any_cast (1.20211102.0): - - abseil/base/config - - abseil/types/bad_any_cast_impl - - abseil/types/bad_any_cast_impl (1.20211102.0): - - abseil/base/config - - abseil/base/raw_logging_internal - - abseil/types/bad_optional_access (1.20211102.0): - - abseil/base/config - - abseil/base/raw_logging_internal - - abseil/types/bad_variant_access (1.20211102.0): - - abseil/base/config - - abseil/base/raw_logging_internal - - abseil/types/compare (1.20211102.0): - - abseil/base/core_headers - - abseil/meta/type_traits - - abseil/types/optional (1.20211102.0): - - abseil/base/base_internal - - abseil/base/config - - abseil/base/core_headers - - abseil/memory/memory - - abseil/meta/type_traits - - abseil/types/bad_optional_access - - abseil/utility/utility - - abseil/types/span (1.20211102.0): - - abseil/algorithm/algorithm - - abseil/base/core_headers - - abseil/base/throw_delegate - - abseil/meta/type_traits - - abseil/types/variant (1.20211102.0): - - abseil/base/base_internal - - abseil/base/config - - abseil/base/core_headers - - abseil/meta/type_traits - - abseil/types/bad_variant_access - - abseil/utility/utility - - abseil/utility/utility (1.20211102.0): - - abseil/base/base_internal - - abseil/base/config - - abseil/meta/type_traits - - BoringSSL-GRPC (0.0.24): - - BoringSSL-GRPC/Implementation (= 0.0.24) - - BoringSSL-GRPC/Interface (= 0.0.24) - - BoringSSL-GRPC/Implementation (0.0.24): - - BoringSSL-GRPC/Interface (= 0.0.24) - - BoringSSL-GRPC/Interface (0.0.24) - - cloud_firestore (4.0.5): - - Firebase/Firestore (= 10.1.0) - - firebase_core - - Flutter - - nanopb (< 2.30910.0, >= 2.30908.0) - - Firebase/CoreOnly (10.1.0): - - FirebaseCore (= 10.1.0) - - Firebase/Firestore (10.1.0): - - Firebase/CoreOnly - - FirebaseFirestore (~> 10.1.0) - - firebase_core (2.2.0): - - Firebase/CoreOnly (= 10.1.0) - - Flutter - - FirebaseCore (10.1.0): - - FirebaseCoreInternal (~> 10.0) - - GoogleUtilities/Environment (~> 7.8) - - GoogleUtilities/Logger (~> 7.8) - - FirebaseCoreInternal (10.1.0): - - "GoogleUtilities/NSData+zlib (~> 7.8)" - - FirebaseFirestore (10.1.0): - - abseil/algorithm (~> 1.20211102.0) - - abseil/base (~> 1.20211102.0) - - abseil/container/flat_hash_map (~> 1.20211102.0) - - abseil/memory (~> 1.20211102.0) - - abseil/meta (~> 1.20211102.0) - - abseil/strings/strings (~> 1.20211102.0) - - abseil/time (~> 1.20211102.0) - - abseil/types (~> 1.20211102.0) - - FirebaseCore (~> 10.0) - - "gRPC-C++ (~> 1.44.0)" - - leveldb-library (~> 1.22) - - nanopb (< 2.30910.0, >= 2.30908.0) - - Flutter (1.0.0) - - GoogleUtilities/Environment (7.8.0): - - PromisesObjC (< 3.0, >= 1.2) - - GoogleUtilities/Logger (7.8.0): - - GoogleUtilities/Environment - - "GoogleUtilities/NSData+zlib (7.8.0)" - - "gRPC-C++ (1.44.0)": - - "gRPC-C++/Implementation (= 1.44.0)" - - "gRPC-C++/Interface (= 1.44.0)" - - "gRPC-C++/Implementation (1.44.0)": - - abseil/base/base (= 1.20211102.0) - - abseil/base/core_headers (= 1.20211102.0) - - abseil/container/flat_hash_map (= 1.20211102.0) - - abseil/container/inlined_vector (= 1.20211102.0) - - abseil/functional/bind_front (= 1.20211102.0) - - abseil/hash/hash (= 1.20211102.0) - - abseil/memory/memory (= 1.20211102.0) - - abseil/random/random (= 1.20211102.0) - - abseil/status/status (= 1.20211102.0) - - abseil/status/statusor (= 1.20211102.0) - - abseil/strings/cord (= 1.20211102.0) - - abseil/strings/str_format (= 1.20211102.0) - - abseil/strings/strings (= 1.20211102.0) - - abseil/synchronization/synchronization (= 1.20211102.0) - - abseil/time/time (= 1.20211102.0) - - abseil/types/optional (= 1.20211102.0) - - abseil/types/variant (= 1.20211102.0) - - abseil/utility/utility (= 1.20211102.0) - - "gRPC-C++/Interface (= 1.44.0)" - - gRPC-Core (= 1.44.0) - - "gRPC-C++/Interface (1.44.0)" - - gRPC-Core (1.44.0): - - gRPC-Core/Implementation (= 1.44.0) - - gRPC-Core/Interface (= 1.44.0) - - gRPC-Core/Implementation (1.44.0): - - abseil/base/base (= 1.20211102.0) - - abseil/base/core_headers (= 1.20211102.0) - - abseil/container/flat_hash_map (= 1.20211102.0) - - abseil/container/inlined_vector (= 1.20211102.0) - - abseil/functional/bind_front (= 1.20211102.0) - - abseil/hash/hash (= 1.20211102.0) - - abseil/memory/memory (= 1.20211102.0) - - abseil/random/random (= 1.20211102.0) - - abseil/status/status (= 1.20211102.0) - - abseil/status/statusor (= 1.20211102.0) - - abseil/strings/cord (= 1.20211102.0) - - abseil/strings/str_format (= 1.20211102.0) - - abseil/strings/strings (= 1.20211102.0) - - abseil/synchronization/synchronization (= 1.20211102.0) - - abseil/time/time (= 1.20211102.0) - - abseil/types/optional (= 1.20211102.0) - - abseil/types/variant (= 1.20211102.0) - - abseil/utility/utility (= 1.20211102.0) - - BoringSSL-GRPC (= 0.0.24) - - gRPC-Core/Interface (= 1.44.0) - - Libuv-gRPC (= 0.0.10) - - gRPC-Core/Interface (1.44.0) - - leveldb-library (1.22.1) - - Libuv-gRPC (0.0.10): - - Libuv-gRPC/Implementation (= 0.0.10) - - Libuv-gRPC/Interface (= 0.0.10) - - Libuv-gRPC/Implementation (0.0.10): - - Libuv-gRPC/Interface (= 0.0.10) - - Libuv-gRPC/Interface (0.0.10) - - nanopb (2.30909.0): - - nanopb/decode (= 2.30909.0) - - nanopb/encode (= 2.30909.0) - - nanopb/decode (2.30909.0) - - nanopb/encode (2.30909.0) - - PromisesObjC (2.1.1) - -DEPENDENCIES: - - cloud_firestore (from `.symlinks/plugins/cloud_firestore/ios`) - - firebase_core (from `.symlinks/plugins/firebase_core/ios`) - - Flutter (from `Flutter`) - -SPEC REPOS: - trunk: - - abseil - - BoringSSL-GRPC - - Firebase - - FirebaseCore - - FirebaseCoreInternal - - FirebaseFirestore - - GoogleUtilities - - "gRPC-C++" - - gRPC-Core - - leveldb-library - - Libuv-gRPC - - nanopb - - PromisesObjC - -EXTERNAL SOURCES: - cloud_firestore: - :path: ".symlinks/plugins/cloud_firestore/ios" - firebase_core: - :path: ".symlinks/plugins/firebase_core/ios" - Flutter: - :path: Flutter - -SPEC CHECKSUMS: - abseil: ebe5b5529fb05d93a8bdb7951607be08b7fa71bc - BoringSSL-GRPC: 3175b25143e648463a56daeaaa499c6cb86dad33 - cloud_firestore: 345ab5f423db6ae492abb648372156bdccb9df42 - Firebase: 444b35a9c568a516666213c2f6cccd10cb12559f - firebase_core: d2242c6f318db1d0dcecfbfa491e943337b0d755 - FirebaseCore: 55e7ae35991ccca4db03ff8d8df6ed5f17a3e4c7 - FirebaseCoreInternal: 96d75228e10fd369564da51bd898414eb0f54df5 - FirebaseFirestore: d482e5e0f95dba8ef5d499a7efa87ba2f56ef0c0 - Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 - GoogleUtilities: 1d20a6ad97ef46f67bbdec158ce00563a671ebb7 - "gRPC-C++": 9675f953ace2b3de7c506039d77be1f2e77a8db2 - gRPC-Core: 943e491cb0d45598b0b0eb9e910c88080369290b - leveldb-library: 50c7b45cbd7bf543c81a468fe557a16ae3db8729 - Libuv-gRPC: 55e51798e14ef436ad9bc45d12d43b77b49df378 - nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431 - PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb - -PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 - -COCOAPODS: 1.11.3 diff --git a/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/project.pbxproj b/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index a4705413..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,552 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 50; - objects = { - -/* Begin PBXBuildFile section */ - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 2D3BF4E90FD3D66E6379652C /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9668B7DCB1C084B61D13F13B /* Pods_Runner.framework */; }; - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 04335B06475E8C2B1917681C /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - 0A79DE27E9F9DDADA3D915D2 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 8D3EFC6842916D850020C95C /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; - 9668B7DCB1C084B61D13F13B /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; - 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 97C146EB1CF9000F007C117D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 2D3BF4E90FD3D66E6379652C /* Pods_Runner.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 32816CF134A5ECA965EE4EF3 /* Pods */ = { - isa = PBXGroup; - children = ( - 0A79DE27E9F9DDADA3D915D2 /* Pods-Runner.debug.xcconfig */, - 04335B06475E8C2B1917681C /* Pods-Runner.release.xcconfig */, - 8D3EFC6842916D850020C95C /* Pods-Runner.profile.xcconfig */, - ); - name = Pods; - path = Pods; - sourceTree = ""; - }; - 9740EEB11CF90186004384FC /* Flutter */ = { - isa = PBXGroup; - children = ( - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 9740EEB31CF90195004384FC /* Generated.xcconfig */, - ); - name = Flutter; - sourceTree = ""; - }; - 97C146E51CF9000F007C117D = { - isa = PBXGroup; - children = ( - 9740EEB11CF90186004384FC /* Flutter */, - 97C146F01CF9000F007C117D /* Runner */, - 97C146EF1CF9000F007C117D /* Products */, - 32816CF134A5ECA965EE4EF3 /* Pods */, - DF1EDFCBAB38011323A8D81B /* Frameworks */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 97C147021CF9000F007C117D /* Info.plist */, - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, - 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, - ); - path = Runner; - sourceTree = ""; - }; - DF1EDFCBAB38011323A8D81B /* Frameworks */ = { - isa = PBXGroup; - children = ( - 9668B7DCB1C084B61D13F13B /* Pods_Runner.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 97C146ED1CF9000F007C117D /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - C454F828EEBC86C10B4E163A /* [CP] Check Pods Manifest.lock */, - 9740EEB61CF901F6004384FC /* Run Script */, - 97C146EA1CF9000F007C117D /* Sources */, - 97C146EB1CF9000F007C117D /* Frameworks */, - 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, - 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 897D29AE5A72F625B86D7F66 /* [CP] Embed Pods Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Runner; - productName = Runner; - productReference = 97C146EE1CF9000F007C117D /* Runner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 97C146E61CF9000F007C117D /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1300; - ORGANIZATIONNAME = ""; - TargetAttributes = { - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - LastSwiftMigration = 1100; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 97C146EC1CF9000F007C117D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; - }; - 897D29AE5A72F625B86D7F66 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; - }; - C454F828EEBC86C10B4E163A /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 97C146FA1CF9000F007C117D /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C146FB1CF9000F007C117D /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C147001CF9000F007C117D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 249021D3217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Profile; - }; - 249021D4217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 6Z5P8GG96U; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.example; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Profile; - }; - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 97C147061CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 6Z5P8GG96U; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.example; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Debug; - }; - 97C147071CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 6Z5P8GG96U; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.example; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - 249021D3217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - 249021D4217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} diff --git a/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a6..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d98100..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index c87d15a3..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/wyatt_crud_bloc/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/wyatt_crud_bloc/example/ios/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 21a3cc14..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/packages/wyatt_crud_bloc/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/wyatt_crud_bloc/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d98100..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/AppDelegate.swift b/packages/wyatt_crud_bloc/example/ios/Runner/AppDelegate.swift deleted file mode 100644 index 70693e4a..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner/AppDelegate.swift +++ /dev/null @@ -1,13 +0,0 @@ -import UIKit -import Flutter - -@UIApplicationMain -@objc class AppDelegate: FlutterAppDelegate { - override func application( - _ application: UIApplication, - didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? - ) -> Bool { - GeneratedPluginRegistrant.register(with: self) - return super.application(application, didFinishLaunchingWithOptions: launchOptions) - } -} diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d36b1fab..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@1x.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@1x.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@1x.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "Icon-App-83.5x83.5@2x.png", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", - "filename" : "Icon-App-1024x1024@1x.png", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png deleted file mode 100644 index dc9ada4725e9b0ddb1deab583e5b5102493aa332..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10932 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 diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index f091b6b0bca859a3f474b03065bef75ba58a9e4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1588 zcmV-42Fv-0P)C1SqPt}wig>|5Crh^=oyX$BK<}M8eLU3e2hGT;=G|!_SP)7zNI6fqUMB=)y zRAZ>eDe#*r`yDAVgB_R*LB*MAc)8(b{g{9McCXW!lq7r(btRoB9!8B-#AI6JMb~YFBEvdsV)`mEQO^&#eRKx@b&x- z5lZm*!WfD8oCLzfHGz#u7sT0^VLMI1MqGxF^v+`4YYnVYgk*=kU?HsSz{v({E3lb9 z>+xILjBN)t6`=g~IBOelGQ(O990@BfXf(DRI5I$qN$0Gkz-FSc$3a+2fX$AedL4u{ z4V+5Ong(9LiGcIKW?_352sR;LtDPmPJXI{YtT=O8=76o9;*n%_m|xo!i>7$IrZ-{l z-x3`7M}qzHsPV@$v#>H-TpjDh2UE$9g6sysUREDy_R(a)>=eHw-WAyfIN z*qb!_hW>G)Tu8nSw9yn#3wFMiLcfc4pY0ek1}8(NqkBR@t4{~oC>ryc-h_ByH(Cg5 z>ao-}771+xE3um9lWAY1FeQFxowa1(!J(;Jg*wrg!=6FdRX+t_<%z&d&?|Bn){>zm zZQj(aA_HeBY&OC^jj*)N`8fa^ePOU72VpInJoI1?`ty#lvlNzs(&MZX+R%2xS~5Kh zX*|AU4QE#~SgPzOXe9>tRj>hjU@c1k5Y_mW*Jp3fI;)1&g3j|zDgC+}2Q_v%YfDax z!?umcN^n}KYQ|a$Lr+51Nf9dkkYFSjZZjkma$0KOj+;aQ&721~t7QUKx61J3(P4P1 zstI~7-wOACnWP4=8oGOwz%vNDqD8w&Q`qcNGGrbbf&0s9L0De{4{mRS?o0MU+nR_! zrvshUau0G^DeMhM_v{5BuLjb#Hh@r23lDAk8oF(C+P0rsBpv85EP>4CVMx#04MOfG z;P%vktHcXwTj~+IE(~px)3*MY77e}p#|c>TD?sMatC0Tu4iKKJ0(X8jxQY*gYtxsC z(zYC$g|@+I+kY;dg_dE>scBf&bP1Nc@Hz<3R)V`=AGkc;8CXqdi=B4l2k|g;2%#m& z*jfX^%b!A8#bI!j9-0Fi0bOXl(-c^AB9|nQaE`*)Hw+o&jS9@7&Gov#HbD~#d{twV zXd^Tr^mWLfFh$@Dr$e;PBEz4(-2q1FF0}c;~B5sA}+Q>TOoP+t>wf)V9Iy=5ruQa;z)y zI9C9*oUga6=hxw6QasLPnee@3^Rr*M{CdaL5=R41nLs(AHk_=Y+A9$2&H(B7!_pURs&8aNw7?`&Z&xY_Ye z)~D5Bog^td-^QbUtkTirdyK^mTHAOuptDflut!#^lnKqU md>ggs(5nOWAqO?umG&QVYK#ibz}*4>0000U6E9hRK9^#O7(mu>ETqrXGsduA8$)?`v2seloOCza43C{NQ$$gAOH**MCn0Q?+L7dl7qnbRdqZ8LSVp1ItDxhxD?t@5_yHg6A8yI zC*%Wgg22K|8E#!~cTNYR~@Y9KepMPrrB8cABapAFa=`H+UGhkXUZV1GnwR1*lPyZ;*K(i~2gp|@bzp8}og7e*#% zEnr|^CWdVV!-4*Y_7rFvlww2Ze+>j*!Z!pQ?2l->4q#nqRu9`ELo6RMS5=br47g_X zRw}P9a7RRYQ%2Vsd0Me{_(EggTnuN6j=-?uFS6j^u69elMypu?t>op*wBx<=Wx8?( ztpe^(fwM6jJX7M-l*k3kEpWOl_Vk3@(_w4oc}4YF4|Rt=2V^XU?#Yz`8(e?aZ@#li0n*=g^qOcVpd-Wbok=@b#Yw zqn8u9a)z>l(1kEaPYZ6hwubN6i<8QHgsu0oE) ziJ(p;Wxm>sf!K+cw>R-(^Y2_bahB+&KI9y^);#0qt}t-$C|Bo71lHi{_+lg#f%RFy z0um=e3$K3i6K{U_4K!EX?F&rExl^W|G8Z8;`5z-k}OGNZ0#WVb$WCpQu-_YsiqKP?BB# vzVHS-CTUF4Ozn5G+mq_~Qqto~ahA+K`|lyv3(-e}00000NkvXXu0mjfd`9t{ diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index d0ef06e7edb86cdfe0d15b4b0d98334a86163658..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1716 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 diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index c8f9ed8f5cee1c98386d13b17e89f719e83555b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1895 zcmV-t2blPYP)FQtfgmafE#=YDCq`qUBt#QpG%*H6QHY765~R=q zZ6iudfM}q!Pz#~9JgOi8QJ|DSu?1-*(kSi1K4#~5?#|rh?sS)(-JQqX*}ciXJ56_H zdw=^s_srbAdqxlvGyrgGet#6T7_|j;95sL%MtM;q86vOxKM$f#puR)Bjv9Zvz9-di zXOTSsZkM83)E9PYBXC<$6(|>lNLVBb&&6y{NByFCp%6+^ALR@NCTse_wqvNmSWI-m z!$%KlHFH2omF!>#%1l3LTZg(s7eof$7*xB)ZQ0h?ejh?Ta9fDv59+u#MokW+1t8Zb zgHv%K(u9G^Lv`lh#f3<6!JVTL3(dCpxHbnbA;kKqQyd1~^Xe0VIaYBSWm6nsr;dFj z4;G-RyL?cYgsN1{L4ZFFNa;8)Rv0fM0C(~Tkit94 zz#~A)59?QjD&pAPSEQ)p8gP|DS{ng)j=2ux)_EzzJ773GmQ_Cic%3JJhC0t2cx>|v zJcVusIB!%F90{+}8hG3QU4KNeKmK%T>mN57NnCZ^56=0?&3@!j>a>B43pi{!u z7JyDj7`6d)qVp^R=%j>UIY6f+3`+qzIc!Y_=+uN^3BYV|o+$vGo-j-Wm<10%A=(Yk^beI{t%ld@yhKjq0iNjqN4XMGgQtbKubPM$JWBz}YA65k%dm*awtC^+f;a-x4+ddbH^7iDWGg&N0n#MW{kA|=8iMUiFYvMoDY@sPC#t$55gn6ykUTPAr`a@!(;np824>2xJthS z*ZdmT`g5-`BuJs`0LVhz+D9NNa3<=6m;cQLaF?tCv8)zcRSh66*Z|vXhG@$I%U~2l z?`Q zykI#*+rQ=z6Jm=Bui-SfpDYLA=|vzGE(dYm=OC8XM&MDo7ux4UF1~0J1+i%aCUpRe zt3L_uNyQ*cE(38Uy03H%I*)*Bh=Lb^Xj3?I^Hnbeq72(EOK^Y93CNp*uAA{5Lc=ky zx=~RKa4{iTm{_>_vSCm?$Ej=i6@=m%@VvAITnigVg{&@!7CDgs908761meDK5azA} z4?=NOH|PdvabgJ&fW2{Mo$Q0CcD8Qc84%{JPYt5EiG{MdLIAeX%T=D7NIP4%Hw}p9 zg)==!2Lbp#j{u_}hMiao9=!VSyx0gHbeCS`;q&vzeq|fs`y&^X-lso(Ls@-706qmA z7u*T5PMo_w3{se1t2`zWeO^hOvTsohG_;>J0wVqVe+n)AbQCx)yh9;w+J6?NF5Lmo zecS@ieAKL8%bVd@+-KT{yI|S}O>pYckUFs;ry9Ow$CD@ztz5K-*D$^{i(_1llhSh^ zEkL$}tsQt5>QA^;QgjgIfBDmcOgi5YDyu?t6vSnbp=1+@6D& z5MJ}B8q;bRlVoxasyhcUF1+)o`&3r0colr}QJ3hcSdLu;9;td>kf@Tcn<@9sIx&=m z;AD;SCh95=&p;$r{Xz3iWCO^MX83AGJ(yH&eTXgv|0=34#-&WAmw{)U7OU9!Wz^!7 zZ%jZFi@JR;>Mhi7S>V7wQ176|FdW2m?&`qa(ScO^CFPR80HucLHOTy%5s*HR0^8)i h0WYBP*#0Ks^FNSabJA*5${_#%002ovPDHLkV1oKhTl@e3 diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100644 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index 75b2d164a5a98e212cca15ea7bf2ab5de5108680..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3831 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 diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100644 index c4df70d39da7941ef3f6dcb7f06a192d8dcb308d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 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 iW8Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png deleted file mode 100644 index 9da19eacad3b03bb08bbddbbf4ac48dd78b3d838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png deleted file mode 100644 index 9da19eacad3b03bb08bbddbbf4ac48dd78b3d838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md deleted file mode 100644 index 89c2725b..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Launch Screen Assets - -You can customize the launch screen with your own desired assets by replacing the image files in this directory. - -You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/packages/wyatt_crud_bloc/example/ios/Runner/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index f2e259c7..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Base.lproj/Main.storyboard b/packages/wyatt_crud_bloc/example/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100644 index f3c28516..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Info.plist b/packages/wyatt_crud_bloc/example/ios/Runner/Info.plist deleted file mode 100644 index 7f553465..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner/Info.plist +++ /dev/null @@ -1,51 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleDisplayName - Example - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - example - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleSignature - ???? - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - CADisableMinimumFrameDurationOnPhone - - UIApplicationSupportsIndirectInputEvents - - - diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Runner-Bridging-Header.h b/packages/wyatt_crud_bloc/example/ios/Runner/Runner-Bridging-Header.h deleted file mode 100644 index 308a2a56..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner/Runner-Bridging-Header.h +++ /dev/null @@ -1 +0,0 @@ -#import "GeneratedPluginRegistrant.h" diff --git a/packages/wyatt_crud_bloc/example/lib/advanced_cubit_view.dart b/packages/wyatt_crud_bloc/example/lib/advanced_cubit_view.dart new file mode 100644 index 00000000..1cee2df2 --- /dev/null +++ b/packages/wyatt_crud_bloc/example/lib/advanced_cubit_view.dart @@ -0,0 +1,151 @@ +// Copyright (C) 2023 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 'dart:math'; + +import 'package:crud_bloc_example/user_advanced_cubit.dart'; +import 'package:crud_bloc_example/user_entity.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; + +class AdvancedCubitView extends StatelessWidget { + const AdvancedCubitView({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text("Advanced Cubit"), + ), + body: BlocProvider( + create: (context) => + UserAdvancedCubit(context.read>())..getAll(), + child: Builder(builder: (context) { + return Column( + children: [ + const Text("Data:"), + BlocBuilder( + buildWhen: (previous, current) { + if (current is CrudLoading && current is! CrudReading) { + return false; + } + return true; + }, + builder: (context, state) { + return Expanded( + child: CrudBuilder.typed>( + state: state, + builder: ((context, state) { + return ListView.builder( + itemCount: state.data.length, + itemBuilder: (context, index) { + final user = state.data.elementAt(index); + return ListTile( + title: Text(user?.name ?? 'Error'), + subtitle: Text(user?.email ?? 'Error'), + onTap: () { + context + .read() + .delete((user?.id)!); + }, + onLongPress: () { + context.read().update( + UpdateParameters( + id: user?.id ?? '', + raw: { + 'email': '${user?.id}@updated.io', + }), + ); + }, + ); + }, + ); + }), + initialBuilder: (context, state) => + const Center(child: CircularProgressIndicator()), + loadingBuilder: (context, state) => + const Center(child: CircularProgressIndicator()), + errorBuilder: (context, state) => Text("Error: $state"), + ), + ); + }, + ), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () { + final r = Random().nextInt(1000); + context.read().create( + User( + id: '$r', + name: 'Wyatt $r', + email: '$r@wyattapp.io', + phone: '06$r', + ), + ); + }, + child: BlocBuilder( + buildWhen: (previous, current) { + if (current is CrudLoading && current is! CrudCreating) { + return false; + } + return true; + }, + builder: (context, state) { + return state is CrudCreating + ? const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + color: Colors.white, + ), + ) + : const Text("Create"); + }, + ), + ), + ElevatedButton( + onPressed: () { + context.read().getAll(); + }, + child: BlocBuilder( + buildWhen: (previous, current) { + if (current is CrudLoading && current is! CrudReading) { + return false; + } + return true; + }, + builder: (context, state) { + return state is CrudReading + ? const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + color: Colors.white, + ), + ) + : const Text("GetAll"); + }, + ), + ), + const SizedBox(height: 20), + ], + ); + }), + ), + ); + } +} diff --git a/packages/wyatt_crud_bloc/example/lib/app.dart b/packages/wyatt_crud_bloc/example/lib/app.dart index d5339343..51e6a7d6 100644 --- a/packages/wyatt_crud_bloc/example/lib/app.dart +++ b/packages/wyatt_crud_bloc/example/lib/app.dart @@ -14,41 +14,43 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import 'dart:math'; - -import 'package:crud_bloc_example/models.dart'; -import 'package:crud_bloc_example/user_cubit.dart'; +import 'package:crud_bloc_example/advanced_cubit_view.dart'; +import 'package:crud_bloc_example/basic_cubit_view.dart'; +import 'package:crud_bloc_example/user_entity.dart'; +import 'package:crud_bloc_example/user_model.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; class MyApp extends StatelessWidget { - const MyApp({Key? key}) : super(key: key); + const MyApp({required this.crudDataSource, Key? key}) : super(key: key); + + final CrudDataSource crudDataSource; // This widget is the root of your application. @override Widget build(BuildContext context) { - final CrudDataSource userLocalDataSource = - CrudInMemoryDataSourceImpl(toMap: (user) => user.toMap()); - - final CrudRepository userRepository = - CrudRepositoryImpl(crudDataSource: userLocalDataSource); + final CrudRepository userRepository = CrudRepositoryImpl( + crudDataSource: crudDataSource, + modelMapper: ModelMapper( + fromJson: (json) => UserModel.fromJson(json ?? {}), + toJson: (user) => UserModel( + id: user.id, + name: user.name, + email: user.email, + phone: user.phone, + ).toJson(), + ), + ); return RepositoryProvider>.value( value: userRepository, - child: MultiBlocProvider( - providers: [ - BlocProvider( - create: (context) => UserCubit(userRepository)..read(), - ), - ], - child: MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: const MyHomePage(), + child: MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, ), + home: const MyHomePage(), ), ); } @@ -63,60 +65,32 @@ class MyHomePage extends StatelessWidget { appBar: AppBar( title: const Text('Flutter Demo Home Page'), ), - body: SingleChildScrollView( - child: Column( - children: [ - const SizedBox(height: 20), - const Text("Data:"), - BlocBuilder( - builder: (context, state) { - return CrudBuilder.typed>( - state: state, - builder: ((context, state) { - return ListView.builder( - shrinkWrap: true, - itemCount: state.data.length, - itemBuilder: (context, index) { - final user = state.data.elementAt(index); - return ListTile( - title: Text(user?.name ?? 'Error'), - subtitle: Text(user?.id ?? 'Error'), - onTap: () { - context.read().delete(id: (user?.id)!); - }, - ); - }, - ); - }), - initialBuilder: (context, state) => const Text("Loading..."), - loadingBuilder: (context, state) => const Text("Loading..."), - errorBuilder: (context, state) => Text("Error: $state"), - ); - }, - ), - const SizedBox(height: 20), - ElevatedButton( - onPressed: () { - final r = Random().nextInt(1000); - context.read().create( - User( - id: '$r', - name: 'Wyatt $r', - email: '$r@wyattapp.io', - phone: '06$r'), - ); - }, - child: const Text("Create"), - ), - ElevatedButton( - onPressed: () { - context.read().read(); - }, - child: const Text("GetAll"), - ), - const SizedBox(height: 20), - ], - ), + body: Column( + children: [ + ElevatedButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const BasicCubitView(), + ), + ); + }, + child: const Text('Basic example'), + ), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const AdvancedCubitView(), + ), + ); + }, + child: const Text('Advanced example'), + ), + ], ), ); } diff --git a/packages/wyatt_crud_bloc/example/lib/basic_cubit_view.dart b/packages/wyatt_crud_bloc/example/lib/basic_cubit_view.dart new file mode 100644 index 00000000..5f2ee88b --- /dev/null +++ b/packages/wyatt_crud_bloc/example/lib/basic_cubit_view.dart @@ -0,0 +1,150 @@ +// Copyright (C) 2023 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 'dart:math'; + +import 'package:crud_bloc_example/user_cubit.dart'; +import 'package:crud_bloc_example/user_entity.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; + +class BasicCubitView extends StatelessWidget { + const BasicCubitView({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text("Basic Cubit"), + ), + body: BlocProvider( + create: (context) => + UserCubit(context.read>())..read(), + child: Builder(builder: (context) { + return Column( + children: [ + BlocBuilder( + buildWhen: (previous, current) { + if (current is CrudLoading && current is! CrudReading) { + return false; + } + return true; + }, + builder: (context, state) { + return Expanded( + child: CrudBuilder.typed>( + state: state, + builder: ((context, state) { + return ListView.builder( + itemCount: state.data.length, + itemBuilder: (context, index) { + final user = state.data.elementAt(index); + return ListTile( + title: Text(user?.name ?? 'Error'), + subtitle: Text(user?.email ?? 'Error'), + onTap: () { + context + .read() + .delete(id: (user?.id)!); + }, + onLongPress: () { + context.read().update( + single: UpdateParameters( + id: user?.id ?? '', + raw: { + 'email': '${user?.id}@updated.io', + }), + ); + }, + ); + }, + ); + }), + initialBuilder: (context, state) => + const Center(child: CircularProgressIndicator()), + loadingBuilder: (context, state) => + const Center(child: CircularProgressIndicator()), + errorBuilder: (context, state) => Text("Error: $state"), + ), + ); + }, + ), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () { + final r = Random().nextInt(1000); + context.read().create( + User( + id: '$r', + name: 'Wyatt $r', + email: '$r@wyattapp.io', + phone: '06$r', + ), + ); + }, + child: BlocBuilder( + buildWhen: (previous, current) { + if (current is CrudLoading && current is! CrudCreating) { + return false; + } + return true; + }, + builder: (context, state) { + return state is CrudCreating + ? const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + color: Colors.white, + ), + ) + : const Text("Create"); + }, + ), + ), + ElevatedButton( + onPressed: () { + context.read().read(); + }, + child: BlocBuilder( + buildWhen: (previous, current) { + if (current is CrudLoading && current is! CrudReading) { + return false; + } + return true; + }, + builder: (context, state) { + return state is CrudReading + ? const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + color: Colors.white, + ), + ) + : const Text("Read"); + }, + ), + ), + const SizedBox(height: 20), + ], + ); + }), + ), + ); + } +} diff --git a/packages/wyatt_crud_bloc/example/lib/firebase_options.dart b/packages/wyatt_crud_bloc/example/lib/firebase_options.dart new file mode 100644 index 00000000..66033168 --- /dev/null +++ b/packages/wyatt_crud_bloc/example/lib/firebase_options.dart @@ -0,0 +1,63 @@ +// File generated by FlutterFire CLI. +// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; +import 'package:flutter/foundation.dart' + show defaultTargetPlatform, kIsWeb, TargetPlatform; + +/// Default [FirebaseOptions] for use with your Firebase apps. +/// +/// Example: +/// ```dart +/// import 'firebase_options.dart'; +/// // ... +/// await Firebase.initializeApp( +/// options: DefaultFirebaseOptions.currentPlatform, +/// ); +/// ``` +class DefaultFirebaseOptions { + static FirebaseOptions get currentPlatform { + if (kIsWeb) { + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for web - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + } + switch (defaultTargetPlatform) { + case TargetPlatform.android: + return android; + case TargetPlatform.iOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for ios - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.macOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for macos - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.windows: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for windows - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.linux: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for linux - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + default: + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + } + + static const FirebaseOptions android = FirebaseOptions( + apiKey: 'AIzaSyAYS14uXupkS158Q5QAFP1864UrUN_yDSk', + appId: '1:136771801992:android:8482c9b90bc29de697203d', + messagingSenderId: '136771801992', + projectId: 'tchat-beta', + databaseURL: 'https://tchat-beta.firebaseio.com', + storageBucket: 'tchat-beta.appspot.com', + ); +} diff --git a/packages/wyatt_crud_bloc/example/lib/main_firestore.dart b/packages/wyatt_crud_bloc/example/lib/main_firestore.dart new file mode 100644 index 00000000..7b40e29a --- /dev/null +++ b/packages/wyatt_crud_bloc/example/lib/main_firestore.dart @@ -0,0 +1,44 @@ +// 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:crud_bloc_example/app.dart'; +import 'package:crud_bloc_example/app_bloc_observer.dart'; +import 'package:crud_bloc_example/firebase_options.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; +import 'package:wyatt_crud_bloc_firestore/wyatt_crud_firestore.dart'; + +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + Bloc.observer = AppBlocObserver(); + + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); + + final CrudDataSource crudDataSource = CrudDataSourceFirestoreImpl( + 'users', + id: (_, json) => json['id'] as String, + fromFirestore: (document, snapshot) => document.data() ?? {}, + toFirestore: (object, options) => object, + ); + + runApp(MyApp( + crudDataSource: crudDataSource, + )); +} diff --git a/packages/wyatt_crud_bloc/example/lib/main.dart b/packages/wyatt_crud_bloc/example/lib/main_memory.dart similarity index 81% rename from packages/wyatt_crud_bloc/example/lib/main.dart rename to packages/wyatt_crud_bloc/example/lib/main_memory.dart index beb692a1..d36a0c3f 100644 --- a/packages/wyatt_crud_bloc/example/lib/main.dart +++ b/packages/wyatt_crud_bloc/example/lib/main_memory.dart @@ -18,10 +18,17 @@ import 'package:crud_bloc_example/app.dart'; import 'package:crud_bloc_example/app_bloc_observer.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); Bloc.observer = AppBlocObserver(); - runApp(const MyApp()); + final CrudDataSource crudDataSource = CrudDataSourceInMemoryImpl( + id: (_, json) => json['id'] as String?, + ); + + runApp(MyApp( + crudDataSource: crudDataSource, + )); } diff --git a/packages/wyatt_crud_bloc/example/lib/user_advanced_cubit.dart b/packages/wyatt_crud_bloc/example/lib/user_advanced_cubit.dart new file mode 100644 index 00000000..5ebbf0df --- /dev/null +++ b/packages/wyatt_crud_bloc/example/lib/user_advanced_cubit.dart @@ -0,0 +1,54 @@ +// 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:crud_bloc_example/user_entity.dart'; +import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; + +/// A [CrudAdvancedCubit] for [User]. +class UserAdvancedCubit extends CrudAdvancedCubit { + final CrudRepository crudRepository; + + UserAdvancedCubit(this.crudRepository); + + @override + ModelIdentifier get modelIdentifier => ModelIdentifier( + getIdentifier: (user) => user.id ?? '', + ); + + @override + Create? get crudCreate => Create(crudRepository); + + @override + Delete? get crudDelete => Delete(crudRepository); + + @override + DeleteAll? get crudDeleteAll => DeleteAll(crudRepository); + + @override + Get? get crudGet => Get(crudRepository); + + @override + GetAll? get crudGetAll => GetAll(crudRepository); + + @override + Search? get crudSearch => Search(crudRepository); + + @override + Update? get crudUpdate => Update(crudRepository); + + @override + UpdateAll? get crudUpdateAll => UpdateAll(crudRepository); +} diff --git a/packages/wyatt_crud_bloc/example/lib/user_cubit.dart b/packages/wyatt_crud_bloc/example/lib/user_cubit.dart index cc34df6c..5a4fa336 100644 --- a/packages/wyatt_crud_bloc/example/lib/user_cubit.dart +++ b/packages/wyatt_crud_bloc/example/lib/user_cubit.dart @@ -14,28 +14,29 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import 'package:crud_bloc_example/models.dart'; +import 'package:crud_bloc_example/user_entity.dart'; import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; /// A [CrudCubit] for [User]. class UserCubit extends CrudCubit { - final CrudRepository _crudRepository; + final CrudRepository crudRepository; - UserCubit(this._crudRepository); + UserCubit(this.crudRepository); @override - CreateOperation? get createOperation => - Create(_crudRepository); + DefaultCreate? get createOperation => Create(crudRepository); @override - DeleteOperation? get deleteOperation => - Delete(_crudRepository); + DefaultDelete? get deleteOperation => Delete(crudRepository); @override - ReadOperation? get readOperation => - GetAll(_crudRepository); + DefaultRead? get readOperation => GetAll(crudRepository); @override - UpdateOperation? get updateOperation => - Update(_crudRepository); + DefaultUpdate? get updateOperation => Update(crudRepository); + + @override + ModelIdentifier get modelIdentifier => ModelIdentifier( + getIdentifier: (user) => user.id ?? '', + ); } diff --git a/packages/wyatt_crud_bloc/lib/src/domain/entities/object_model.dart b/packages/wyatt_crud_bloc/example/lib/user_entity.dart similarity index 65% rename from packages/wyatt_crud_bloc/lib/src/domain/entities/object_model.dart rename to packages/wyatt_crud_bloc/example/lib/user_entity.dart index 10dc5a25..9964f1ca 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/entities/object_model.dart +++ b/packages/wyatt_crud_bloc/example/lib/user_entity.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify @@ -14,15 +14,23 @@ // 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:wyatt_architecture/wyatt_architecture.dart'; -/// {@template object_model} -/// An abstract class that represents an object model. -/// {@endtemplate} -abstract class ObjectModel extends Entity { - /// {@macro object_model} - const ObjectModel(); +class User extends Entity with EquatableMixin { + final String? id; - /// The id of the object model. - String? get id; + final String name; + final String email; + final String phone; + + const User({ + required this.name, + required this.email, + required this.phone, + this.id, + }); + + @override + List get props => [id, name, email, phone]; } diff --git a/packages/wyatt_crud_bloc/example/lib/models.dart b/packages/wyatt_crud_bloc/example/lib/user_model.dart similarity index 56% rename from packages/wyatt_crud_bloc/example/lib/models.dart rename to packages/wyatt_crud_bloc/example/lib/user_model.dart index e9ed1c7f..f5723736 100644 --- a/packages/wyatt_crud_bloc/example/lib/models.dart +++ b/packages/wyatt_crud_bloc/example/lib/user_model.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify @@ -14,32 +14,26 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; +import 'package:crud_bloc_example/user_entity.dart'; +import 'package:json_annotation/json_annotation.dart'; -class User extends ObjectModel { - @override - final String? id; +part 'user_model.g.dart'; - final String? name; - final String? email; - final String? phone; - - const User({ - required this.name, - required this.email, - required this.phone, - this.id, +@JsonSerializable() +class UserModel extends User { + UserModel({ + super.id, + required super.name, + required super.email, + required super.phone, }); - Map toMap() { - return { - 'name': name ?? '', - 'email': email ?? '', - 'phone': phone ?? '', - }; - } + factory UserModel.fromJson(Map json) => + _$UserModelFromJson(json); + + Map toJson() => _$UserModelToJson(this); @override String toString() => - 'User(id: $id, name: $name, email: $email, phone: $phone)'; + 'UserModel(id: $id, name: $name, email: $email, phone: $phone)'; } diff --git a/packages/wyatt_crud_bloc/example/lib/user_model.g.dart b/packages/wyatt_crud_bloc/example/lib/user_model.g.dart new file mode 100644 index 00000000..439e5eb0 --- /dev/null +++ b/packages/wyatt_crud_bloc/example/lib/user_model.g.dart @@ -0,0 +1,21 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'user_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +UserModel _$UserModelFromJson(Map json) => UserModel( + id: json['id'] as String?, + name: json['name'] as String, + email: json['email'] as String, + phone: json['phone'] as String, + ); + +Map _$UserModelToJson(UserModel instance) => { + 'id': instance.id, + 'name': instance.name, + 'email': instance.email, + 'phone': instance.phone, + }; diff --git a/packages/wyatt_crud_bloc/example/pubspec.yaml b/packages/wyatt_crud_bloc/example/pubspec.yaml index 8275fb19..992e0738 100644 --- a/packages/wyatt_crud_bloc/example/pubspec.yaml +++ b/packages/wyatt_crud_bloc/example/pubspec.yaml @@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ">=2.17.0 <3.0.0" + sdk: ">=3.0.0 <4.0.0" # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions @@ -30,13 +30,23 @@ dependencies: flutter: sdk: flutter - flutter_bloc: ^8.1.1 + equatable: ^2.0.5 + firebase_core: ^2.22.0 + cloud_firestore: ^4.13.0 + flutter_bloc: ^8.1.3 wyatt_crud_bloc: path: "../" + wyatt_crud_bloc_firestore: + path: "../wyatt_crud_bloc_firestore" + + wyatt_architecture: + hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + version: ^0.2.0+1 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 + json_annotation: ^4.8.1 dev_dependencies: flutter_test: @@ -48,6 +58,8 @@ dev_dependencies: # package. See that file for information about deactivating specific lint # rules and activating additional ones. flutter_lints: ^2.0.0 + json_serializable: ^6.7.1 + build_runner: ^2.4.6 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/packages/wyatt_crud_bloc/example/test/widget_test.dart b/packages/wyatt_crud_bloc/example/test/widget_test.dart deleted file mode 100644 index 8b137891..00000000 --- a/packages/wyatt_crud_bloc/example/test/widget_test.dart +++ /dev/null @@ -1 +0,0 @@ - diff --git a/packages/wyatt_crud_bloc/lib/src/core/core.dart b/packages/wyatt_crud_bloc/lib/src/core/core.dart index 12ebcadf..daa34ab6 100644 --- a/packages/wyatt_crud_bloc/lib/src/core/core.dart +++ b/packages/wyatt_crud_bloc/lib/src/core/core.dart @@ -14,5 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +export 'enums/operation_type.dart'; export 'enums/where_query_type.dart'; export 'mixins/operation.dart'; +export 'model_identifier.dart'; +export 'model_mapper.dart'; diff --git a/packages/wyatt_crud_bloc/lib/src/domain/data_sources/data_sources.dart b/packages/wyatt_crud_bloc/lib/src/core/enums/operation_type.dart similarity index 86% rename from packages/wyatt_crud_bloc/lib/src/domain/data_sources/data_sources.dart rename to packages/wyatt_crud_bloc/lib/src/core/enums/operation_type.dart index 925fd22f..3405aa63 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/data_sources/data_sources.dart +++ b/packages/wyatt_crud_bloc/lib/src/core/enums/operation_type.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify @@ -14,4 +14,10 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -export 'crud_data_source.dart'; +enum OperationType { + query, + create, + read, + update, + delete, +} diff --git a/packages/wyatt_crud_bloc/lib/src/core/enums/where_query_type.dart b/packages/wyatt_crud_bloc/lib/src/core/enums/where_query_type.dart index 6a7c9bfe..aaeb0779 100644 --- a/packages/wyatt_crud_bloc/lib/src/core/enums/where_query_type.dart +++ b/packages/wyatt_crud_bloc/lib/src/core/enums/where_query_type.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify diff --git a/packages/wyatt_crud_bloc/lib/src/core/mixins/operation.dart b/packages/wyatt_crud_bloc/lib/src/core/mixins/operation.dart index dbfc08ff..513e17ba 100644 --- a/packages/wyatt_crud_bloc/lib/src/core/mixins/operation.dart +++ b/packages/wyatt_crud_bloc/lib/src/core/mixins/operation.dart @@ -15,20 +15,28 @@ // along with this program. If not, see . import 'package:wyatt_architecture/wyatt_architecture.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; +import 'package:wyatt_crud_bloc/src/core/enums/operation_type.dart'; /// Defines every write operation in CRUD. -mixin CreateOperation - on AsyncUseCase {} +mixin CreateOperation on AsyncUseCase { + /// {@macro create} + OperationType get operationType => OperationType.create; +} /// Defines every read operation in CRUD. -mixin ReadOperation - on AsyncUseCase {} +mixin ReadOperation on AsyncUseCase { + /// {@macro read} + OperationType get operationType => OperationType.read; +} /// Defines every update operation in CRUD. -mixin UpdateOperation - on AsyncUseCase {} +mixin UpdateOperation on AsyncUseCase { + /// {@macro update} + OperationType get operationType => OperationType.update; +} /// Defines every delete operation in CRUD. -mixin DeleteOperation - on AsyncUseCase {} +mixin DeleteOperation on AsyncUseCase { + /// {@macro delete} + OperationType get operationType => OperationType.delete; +} diff --git a/packages/wyatt_crud_bloc/lib/src/core/model_identifier.dart b/packages/wyatt_crud_bloc/lib/src/core/model_identifier.dart new file mode 100644 index 00000000..b294090c --- /dev/null +++ b/packages/wyatt_crud_bloc/lib/src/core/model_identifier.dart @@ -0,0 +1,57 @@ +// Copyright (C) 2023 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 ModelIdentifier { + const ModelIdentifier({ + required this.getIdentifier, + }); + + final String Function(Model model) getIdentifier; + + String? getIdentifierOrNull(Model? model) { + if (model == null) { + return null; + } + + return getIdentifier(model); + } + + bool isIdentifier({ + required Model? model, + required String identifier, + }) { + if (model == null) { + return false; + } + + return getIdentifier(model) == identifier; + } + + bool areEqual( + Model? model1, + Model? model2, + ) { + if (model1 == null && model2 == null) { + return true; + } + + if (model1 == null || model2 == null) { + return false; + } + + return getIdentifier(model1) == getIdentifier(model2); + } +} diff --git a/packages/wyatt_crud_bloc/lib/src/data/data_sources/data_sources.dart b/packages/wyatt_crud_bloc/lib/src/core/model_mapper.dart similarity index 71% rename from packages/wyatt_crud_bloc/lib/src/data/data_sources/data_sources.dart rename to packages/wyatt_crud_bloc/lib/src/core/model_mapper.dart index 845ccb50..af2666c2 100644 --- a/packages/wyatt_crud_bloc/lib/src/data/data_sources/data_sources.dart +++ b/packages/wyatt_crud_bloc/lib/src/core/model_mapper.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify @@ -14,5 +14,12 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -export 'local/crud_in_memory_data_source_impl.dart'; -export 'remote/crud_firestore_data_source_impl.dart'; +class ModelMapper { + const ModelMapper({ + required this.fromJson, + required this.toJson, + }); + + final Model Function(Map? json) fromJson; + final Map Function(Model model) toJson; +} diff --git a/packages/wyatt_crud_bloc/lib/src/data/data.dart b/packages/wyatt_crud_bloc/lib/src/data/data.dart index 2fbca202..31207a5b 100644 --- a/packages/wyatt_crud_bloc/lib/src/data/data.dart +++ b/packages/wyatt_crud_bloc/lib/src/data/data.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify @@ -14,5 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -export 'data_sources/data_sources.dart'; -export 'repositories/repositories.dart'; +export 'data_sources/crud_data_source.dart'; +export 'data_sources/crud_data_source_in_memory_impl.dart'; +export 'repositories/crud_repository_impl.dart'; diff --git a/packages/wyatt_crud_bloc/lib/src/domain/data_sources/crud_data_source.dart b/packages/wyatt_crud_bloc/lib/src/data/data_sources/crud_data_source.dart similarity index 58% rename from packages/wyatt_crud_bloc/lib/src/domain/data_sources/crud_data_source.dart rename to packages/wyatt_crud_bloc/lib/src/data/data_sources/crud_data_source.dart index b6d0ba30..6d77eaf6 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/data_sources/crud_data_source.dart +++ b/packages/wyatt_crud_bloc/lib/src/data/data_sources/crud_data_source.dart @@ -15,47 +15,54 @@ // along with this program. If not, see . import 'package:wyatt_architecture/wyatt_architecture.dart'; +import 'package:wyatt_crud_bloc/src/core/enums/operation_type.dart'; import 'package:wyatt_crud_bloc/src/domain/entities/query.dart'; /// {@template crud_data_source} /// A [BaseDataSource] that provides SCRUD operations. /// {@endtemplate} -abstract class CrudDataSource extends BaseDataSource { +abstract class CrudDataSource extends BaseDataSource { /// {@macro crud_data_source} - const CrudDataSource(); - - /// Creates a new [Model] object. - Future create(Model object, {String? id}); - - /// Gets a [Model] object by its [id]. - Future get(String id); - - /// Gets all [Model] objects. - Future> getAll(); - - /// Updates a [Model] object by its [id]. - Future update( - String id, { - Model? object, - Map? raw, + const CrudDataSource({ + required this.id, }); - /// Updates all [Model] objects. + final String? Function( + OperationType operationType, + Map object, + ) id; + + /// Creates a new object. + Future create(Map object, {String? id}); + + /// Gets a object by its [id]. + Future?> get(String id); + + /// Gets all objects. + Future?> getAll(); + + /// Updates a object by its [id]. + Future update( + String id, { + Map? object, + }); + + /// Updates all objects. Future updateAll(Map? data); - /// Deletes a [Model] object by its [id]. + /// Deletes a object by its [id]. Future delete(String id); - /// Deletes all [Model] objects. + /// Deletes all objects. Future deleteAll(); - /// Queries [Model] objects by [conditions]. - Future> query(List conditions); + /// Queries objects by [conditions]. + Future?> search(List conditions); - /// Streams [Model] objects by [conditions]. - Stream> stream({ + /// Streams objects by [conditions]. + Stream?> stream({ String? id, - List? conditions, + List? conditions, bool includeMetadataChanges = false, }); } diff --git a/packages/wyatt_crud_bloc/lib/src/data/data_sources/local/crud_in_memory_data_source_impl.dart b/packages/wyatt_crud_bloc/lib/src/data/data_sources/crud_data_source_in_memory_impl.dart similarity index 54% rename from packages/wyatt_crud_bloc/lib/src/data/data_sources/local/crud_in_memory_data_source_impl.dart rename to packages/wyatt_crud_bloc/lib/src/data/data_sources/crud_data_source_in_memory_impl.dart index 7c2f706b..d5ebd3f0 100644 --- a/packages/wyatt_crud_bloc/lib/src/data/data_sources/local/crud_in_memory_data_source_impl.dart +++ b/packages/wyatt_crud_bloc/lib/src/data/data_sources/crud_data_source_in_memory_impl.dart @@ -16,28 +16,55 @@ import 'dart:async'; +import 'package:wyatt_crud_bloc/src/core/enums/operation_type.dart'; import 'package:wyatt_crud_bloc/src/core/enums/where_query_type.dart'; -import 'package:wyatt_crud_bloc/src/domain/data_sources/data_sources.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; +import 'package:wyatt_crud_bloc/src/data/data_sources/crud_data_source.dart'; import 'package:wyatt_crud_bloc/src/domain/entities/query.dart'; import 'package:wyatt_type_utils/wyatt_type_utils.dart'; -/// {@template crud_in_memory_data_source_impl} +extension _ModelExtension on Map { + Map merge( + Map? other, { + bool skipNulls = false, + }) { + if (other == null) { + return this; + } + final Map result = {}; + for (final key in keys) { + result[key] = other[key] ?? this[key]; + } + for (final key in other.keys) { + if (!containsKey(key)) { + result[key] = other[key]; + } + } + + if (skipNulls) { + result.removeWhere((key, value) => other[key] == null); + } + return result; + } +} + +/// {@template crud_data_source_in_memory_impl} /// A [CrudDataSource] that stores data in memory. /// {@endtemplate} -class CrudInMemoryDataSourceImpl - extends CrudDataSource { - /// {@macro crud_in_memory_data_source_impl} - CrudInMemoryDataSourceImpl({required this.toMap, Map? data}) - : _data = data ?? {}; - final Map _data; - final StreamController> _streamData = StreamController(); +class CrudDataSourceInMemoryImpl extends CrudDataSource { + /// {@macro crud_data_source_in_memory_impl} + CrudDataSourceInMemoryImpl({ + required super.id, + Map>? data, + }) : _data = data ?? {}; - final Map Function(Model) toMap; + final Map> _data; + final StreamController?>> _streamData = + StreamController(); @override - Future create(Model object, {String? id}) async { - _data[id ?? object.id ?? ''] = object; + Future create(Map object, {String? id}) async { + _data[id ?? this.id(OperationType.create, object) ?? ''] = object; + _streamData.add(_data.values.toList()); } @@ -54,14 +81,14 @@ class CrudInMemoryDataSourceImpl } @override - Future get(String id) async => _data[id]; + Future?> get(String id) async => _data[id]; @override - Future> getAll() async => _data.values.toList(); + Future?>> getAll() async => _data.values.toList(); @override - Future> query(List conditions) async { - List result = _data.values.toList(); + Future?>> search(List conditions) async { + List> result = _data.values.toList(); for (final c in conditions) { if (c is WhereQuery) { @@ -81,15 +108,15 @@ class CrudInMemoryDataSourceImpl } } - result.cast(); + result.cast>(); return result; } @override - Stream> stream({ + Stream?>> stream({ String? id, - List? conditions, + List? conditions, bool includeMetadataChanges = false, }) => _streamData.stream.map((result) { @@ -97,7 +124,7 @@ class CrudInMemoryDataSourceImpl return result; } - List res = result; + List?> res = result; for (final c in conditions) { if (c is WhereQuery) { @@ -120,56 +147,63 @@ class CrudInMemoryDataSourceImpl @override Future update( String id, { - Model? object, - Map? raw, + Map? object, }) { - // TODO(hpcl): implement update - throw UnimplementedError(); + if (object != null && _data.containsKey(id)) { + _data[id] = _data[id]!.merge(object); + _streamData.add(_data.values.toList()); + } + return Future.value(); } @override Future updateAll(Map? data) { - // TODO(hcpl): implement updateAll - throw UnimplementedError(); + if (data != null) { + for (final entry in _data.entries) { + _data[entry.key] = entry.value.merge(data); + } + _streamData.add(_data.values.toList()); + } + return Future.value(); } - bool _whereQuery(QueryInterface condition, Model? object) { + bool _whereQuery(Query condition, Map? object) { if (object == null) { return false; } - final raw = toMap.call(object); if (condition is WhereQuery) { switch (condition.type) { case WhereQueryType.isEqualTo: - return raw[condition.field] == condition.value; + return object[condition.field] == condition.value; case WhereQueryType.isNotEqualTo: - return raw[condition.field] != condition.value; + return object[condition.field] != condition.value; case WhereQueryType.isLessThan: - return (raw[condition.field] as num?) < (condition.value as num?); + return (object[condition.field] as num?) < (condition.value as num?); case WhereQueryType.isLessThanOrEqualTo: - return (raw[condition.field] as num?) <= (condition.value as num?); + return (object[condition.field] as num?) <= (condition.value as num?); case WhereQueryType.isGreaterThan: - return (raw[condition.field] as num?) > (condition.value as num?); + return (object[condition.field] as num?) > (condition.value as num?); case WhereQueryType.isGreaterThanOrEqualTo: - return (raw[condition.field] as num?) >= (condition.value as num?); + return (object[condition.field] as num?) >= (condition.value as num?); case WhereQueryType.arrayContains: - return (raw[condition.field] as List?) + return (object[condition.field] as List?) ?.contains(condition.value) ?? false; case WhereQueryType.arrayContainsAny: bool res = false; for (final o in condition.value as List) { - res = (raw[condition.field] as List?)?.contains(o) ?? false; + res = (object[condition.field] as List?)?.contains(o) ?? + false; } return res; case WhereQueryType.whereIn: return (condition.value as List) - .contains(raw[condition.field]); + .contains(object[condition.field]); case WhereQueryType.whereNotIn: return !(condition.value as List) - .contains(raw[condition.field]); + .contains(object[condition.field]); case WhereQueryType.isNull: - return raw[condition.field] == null; + return object[condition.field] == null; } } return true; diff --git a/packages/wyatt_crud_bloc/lib/src/data/repositories/crud_repository_impl.dart b/packages/wyatt_crud_bloc/lib/src/data/repositories/crud_repository_impl.dart index 7f068be2..e43e04fc 100644 --- a/packages/wyatt_crud_bloc/lib/src/data/repositories/crud_repository_impl.dart +++ b/packages/wyatt_crud_bloc/lib/src/data/repositories/crud_repository_impl.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify @@ -15,8 +15,8 @@ // along with this program. If not, see . import 'package:wyatt_architecture/wyatt_architecture.dart'; -import 'package:wyatt_crud_bloc/src/domain/data_sources/crud_data_source.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; +import 'package:wyatt_crud_bloc/src/core/model_mapper.dart'; +import 'package:wyatt_crud_bloc/src/data/data_sources/crud_data_source.dart'; import 'package:wyatt_crud_bloc/src/domain/entities/query.dart'; import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; import 'package:wyatt_type_utils/wyatt_type_utils.dart'; @@ -24,19 +24,23 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart'; /// {@template crud_repository_impl} /// A repository that implements the [CrudRepository] interface. /// {@endtemplate} -class CrudRepositoryImpl - extends CrudRepository { +class CrudRepositoryImpl extends CrudRepository { /// {@macro crud_repository_impl} const CrudRepositoryImpl({ - required CrudDataSource crudDataSource, + required this.modelMapper, + required CrudDataSource crudDataSource, }) : _crudDataSource = crudDataSource; - final CrudDataSource _crudDataSource; + + final CrudDataSource _crudDataSource; + + @override + final ModelMapper modelMapper; @override FutureOrResult create(Model object, {String? id}) => Result.tryCatchAsync( () async { - await _crudDataSource.create(object, id: id); + await _crudDataSource.create(modelMapper.toJson(object), id: id); }, (error) => error, ); @@ -44,14 +48,26 @@ class CrudRepositoryImpl @override FutureOrResult get(String id) => Result.tryCatchAsync( - () async => _crudDataSource.get(id), + () async => modelMapper.fromJson(await _crudDataSource.get(id)), (error) => error, ); @override FutureOrResult> getAll() => Result.tryCatchAsync, AppException, AppException>( - () async => _crudDataSource.getAll(), + () async { + final lst = await _crudDataSource.getAll(); + if (lst.isNotNull) { + return lst!.map((raw) { + try { + return modelMapper.fromJson(raw as Map?); + } catch (e) { + return null; + } + }).toList(); + } + throw const ServerException(); + }, (error) => error, ); @@ -62,7 +78,18 @@ class CrudRepositoryImpl Map? raw, }) => Result.tryCatchAsync( - () async => _crudDataSource.update(id, object: object, raw: raw), + () async { + if (object != null) { + await _crudDataSource.update( + id, + object: modelMapper.toJson(object), + ); + } else if (raw != null) { + await _crudDataSource.update(id, object: raw); + } else { + throw const ServerException(); + } + }, (error) => error, ); @@ -88,20 +115,40 @@ class CrudRepositoryImpl ); @override - FutureOrResult> query(List conditions) => + FutureOrResult> search(List conditions) => Result.tryCatchAsync, AppException, AppException>( - () async => _crudDataSource.query(conditions), + () async { + final lst = await _crudDataSource.search(conditions); + if (lst.isNotNull) { + return lst!.map((raw) { + try { + return modelMapper.fromJson(raw as Map?); + } catch (e) { + return null; + } + }).toList(); + } + throw const ServerException(); + }, (error) => error, ); @override StreamResult> stream({ String? id, - List? conditions, + List? conditions, }) => _crudDataSource.stream(id: id, conditions: conditions).map((lst) { if (lst.isNotNull) { - return Ok, AppException>(lst); + return Ok, AppException>( + lst!.map((raw) { + try { + return modelMapper.fromJson(raw as Map?); + } catch (e) { + return null; + } + }).toList(), + ); } return Err, AppException>(const ServerException()); }); diff --git a/packages/wyatt_crud_bloc/lib/src/domain/domain.dart b/packages/wyatt_crud_bloc/lib/src/domain/domain.dart index 35c41307..b6f71ff4 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/domain.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/domain.dart @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -export 'data_sources/data_sources.dart'; -export 'entities/entities.dart'; -export 'repositories/repositories.dart'; +export 'entities/query.dart'; +export 'repositories/crud_repository.dart'; export 'usecases/usecases.dart'; diff --git a/packages/wyatt_crud_bloc/lib/src/domain/entities/entities.dart b/packages/wyatt_crud_bloc/lib/src/domain/entities/entities.dart deleted file mode 100644 index bb2a29f7..00000000 --- a/packages/wyatt_crud_bloc/lib/src/domain/entities/entities.dart +++ /dev/null @@ -1,18 +0,0 @@ -// 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 . - -export 'object_model.dart'; -export 'query.dart'; diff --git a/packages/wyatt_crud_bloc/lib/src/domain/entities/query.dart b/packages/wyatt_crud_bloc/lib/src/domain/entities/query.dart index 5fe8908f..e7f3c2b7 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/entities/query.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/entities/query.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify @@ -17,25 +17,20 @@ import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_crud_bloc/src/core/enums/where_query_type.dart'; -// // ignore: one_member_abstracts -// abstract class QueryParser { -// Q parser(QueryInterface condition, Q query); -// } - -typedef QueryParser = Q Function(QueryInterface condition, Q query); +typedef QueryParser = Q Function(Query condition, Q query); /// {@template query} /// An abstract class that represents a query. /// {@endtemplate} -abstract class QueryInterface extends Entity { +base class Query extends Entity { /// {@macro query} - const QueryInterface(); + const Query(); } /// {@template where_query} /// Represents a where query. /// {@endtemplate} -class WhereQuery extends QueryInterface { +final class WhereQuery extends Query { /// {@macro where_query} const WhereQuery(this.type, this.field, this.value); @@ -52,7 +47,7 @@ class WhereQuery extends QueryInterface { /// {@template limit_query} /// Represents a limit query. /// {@endtemplate} -class LimitQuery extends QueryInterface { +final class LimitQuery extends Query { /// {@macro limit_query} const LimitQuery(this.limit); @@ -63,7 +58,7 @@ class LimitQuery extends QueryInterface { /// {@template offset_query} /// Represents an offset query. /// {@endtemplate} -class OrderByQuery extends QueryInterface { +final class OrderByQuery extends Query { /// {@macro offset_query} const OrderByQuery(this.field, {this.ascending = true}); diff --git a/packages/wyatt_crud_bloc/lib/src/domain/repositories/crud_repository.dart b/packages/wyatt_crud_bloc/lib/src/domain/repositories/crud_repository.dart index 95b52190..0f6c0050 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/repositories/crud_repository.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/repositories/crud_repository.dart @@ -15,17 +15,18 @@ // along with this program. If not, see . import 'package:wyatt_architecture/wyatt_architecture.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; +import 'package:wyatt_crud_bloc/src/core/model_mapper.dart'; import 'package:wyatt_crud_bloc/src/domain/entities/query.dart'; /// {@template crud_repository} /// An abstract class that represents a SCRUD repository. /// {@endtemplate} -abstract class CrudRepository - extends BaseRepository { +abstract class CrudRepository extends BaseRepository { /// {@macro crud_repository} const CrudRepository(); + ModelMapper get modelMapper; + /// Creates a new object. FutureOrResult create(Model object, {String? id}); @@ -52,11 +53,11 @@ abstract class CrudRepository FutureOrResult deleteAll(); /// Queries objects by [conditions]. - FutureOrResult> query(List conditions); + FutureOrResult> search(List conditions); /// Streams objects by [conditions]. StreamResult> stream({ String? id, - List? conditions, + List? conditions, }); } diff --git a/packages/wyatt_crud_bloc/lib/src/domain/repositories/repositories.dart b/packages/wyatt_crud_bloc/lib/src/domain/repositories/repositories.dart deleted file mode 100644 index fb45fc62..00000000 --- a/packages/wyatt_crud_bloc/lib/src/domain/repositories/repositories.dart +++ /dev/null @@ -1,17 +0,0 @@ -// 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 . - -export 'crud_repository.dart'; diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/create.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/create.dart index ff88a046..9ff3db82 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/usecases/create.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/create.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify @@ -14,31 +14,22 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import 'dart:async'; - import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart'; /// {@template create} /// A use case that creates an object model. /// {@endtemplate} -class Create extends AsyncUseCase +class Create extends Usecase with CreateOperation { /// {@macro create} - const Create(this._crudRepository); + const Create(this.crudRepository); - final CrudRepository _crudRepository; - - @override - FutureOr onStart(Model? params) { - if (params == null) { - throw ClientException('$Model cannot be null.'); - } - } + final CrudRepository crudRepository; @override FutureOrResult execute(Model? params) => - _crudRepository.create(params!); + crudRepository.create(params as Model); } diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/delete.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/delete.dart index d8ffb17d..be09ef82 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/usecases/delete.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/delete.dart @@ -14,31 +14,21 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import 'dart:async'; - import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart'; /// {@template delete} /// A use case that deletes an object model. /// {@endtemplate} -class Delete extends AsyncUseCase - with DeleteOperation { +class Delete extends Usecase with DeleteOperation { /// {@macro delete} - const Delete(this._crudRepository); + const Delete(this.crudRepository); - final CrudRepository _crudRepository; - - @override - FutureOr onStart(String? params) { - if (params == null) { - throw const ClientException('Id cannot be null.'); - } - } + final CrudRepository crudRepository; @override FutureOrResult execute(String? params) => - _crudRepository.delete(params!); + crudRepository.delete(params!); } diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/delete_all.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/delete_all.dart index ae1935d7..0fa348b4 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/usecases/delete_all.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/delete_all.dart @@ -16,19 +16,18 @@ import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart'; /// {@template delete_all} /// A use case that deletes all the object models. /// {@endtemplate} -class DeleteAll extends AsyncUseCase - with DeleteOperation { +class DeleteAll extends NoParamUsecase with DeleteOperation { /// {@macro delete_all} - const DeleteAll(this._crudRepository); + const DeleteAll(this.crudRepository); - final CrudRepository _crudRepository; + final CrudRepository crudRepository; @override - FutureOrResult execute(void params) => _crudRepository.deleteAll(); + FutureOrResult execute(void params) => crudRepository.deleteAll(); } diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/get.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/get.dart index 08850936..f74fbb0f 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/usecases/get.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/get.dart @@ -14,31 +14,21 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import 'dart:async'; - import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart'; /// {@template get} /// A use case that gets an object model. /// {@endtemplate} -class Get extends AsyncUseCase - with ReadOperation { +class Get extends Usecase + with ReadOperation { /// {@macro get} - Get(this._crudRepository); + Get(this.crudRepository); - final CrudRepository _crudRepository; + final CrudRepository crudRepository; @override - FutureOr onStart(String? params) { - if (params == null) { - throw const ClientException('Id cannot be null.'); - } - } - - @override - FutureOrResult execute(String? params) => - _crudRepository.get(params!); + FutureOrResult execute(String? params) => crudRepository.get(params!); } diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/get_all.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/get_all.dart index 63379212..1a2d9527 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/usecases/get_all.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/get_all.dart @@ -16,19 +16,19 @@ import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart'; /// {@template get_all} /// A use case that gets all the object models. /// {@endtemplate} -class GetAll extends AsyncUseCase> - with ReadOperation> { +class GetAll extends NoParamUsecase> + with ReadOperation> { /// {@macro get_all} - const GetAll(this._crudRepository); + const GetAll(this.crudRepository); - final CrudRepository _crudRepository; + final CrudRepository crudRepository; @override - FutureOrResult> execute(void params) => _crudRepository.getAll(); + FutureOrResult> execute(void params) => crudRepository.getAll(); } diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/params/stream_parameters.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/params/stream_parameters.dart index 0b2d178b..263c54f3 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/usecases/params/stream_parameters.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/params/stream_parameters.dart @@ -30,5 +30,5 @@ class StreamParameters { final String? id; /// The conditions of the query. - final List? conditions; + final List? conditions; } diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/query.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/search.dart similarity index 61% rename from packages/wyatt_crud_bloc/lib/src/domain/usecases/query.dart rename to packages/wyatt_crud_bloc/lib/src/domain/usecases/search.dart index 4869fa0d..512a4a46 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/usecases/query.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/search.dart @@ -14,33 +14,23 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import 'dart:async'; - import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; import 'package:wyatt_crud_bloc/src/domain/entities/query.dart'; import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart'; -/// {@template query} +/// {@template search} /// A use case that queries the object models. /// {@endtemplate} -class Query - extends AsyncUseCase, List> - with ReadOperation, List> { - /// {@macro query} - const Query(this._crudRepository); +class Search extends Usecase, List> + with ReadOperation, List> { + /// {@macro search} + const Search(this.crudRepository); - final CrudRepository _crudRepository; + final CrudRepository crudRepository; @override - FutureOr onStart(List? params) { - if (params == null) { - throw const ClientException('List of conditions cannot be null.'); - } - } - - @override - FutureOrResult> execute(List? params) => - _crudRepository.query(params!); + FutureOrResult> execute(List? params) => + crudRepository.search(params!); } diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/stream.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/stream.dart new file mode 100644 index 00000000..68fcec8c --- /dev/null +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/stream.dart @@ -0,0 +1,44 @@ +// 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_architecture/wyatt_architecture.dart'; +import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart'; +import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart'; +import 'package:wyatt_type_utils/wyatt_type_utils.dart'; + +/// {@template stream} +/// A use case that streams the object models. +/// {@endtemplate} +class Stream + extends Usecase>> + with ReadOperation>> { + /// {@macro stream} + const Stream(this.crudRepository); + + final CrudRepository crudRepository; + + @override + FutureOrResult>> execute( + StreamParameters? params, + ) async => + Ok( + crudRepository.stream( + id: params!.id, + conditions: params.conditions, + ), + ); +} diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/update.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/update.dart index 237e3e9d..5d20e49e 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/usecases/update.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/update.dart @@ -14,35 +14,24 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import 'dart:async'; - import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; -import 'package:wyatt_crud_bloc/src/domain/usecases/params/update_parameters.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart'; /// {@template update} /// A use case that updates an object model. /// {@endtemplate} -class Update - extends AsyncUseCase, void> - with UpdateOperation> { +class Update extends Usecase, void> + with UpdateOperation> { /// {@macro update} - const Update(this._crudRepository); + const Update(this.crudRepository); - final CrudRepository _crudRepository; - - @override - FutureOr onStart(UpdateParameters? params) { - if (params == null) { - throw const ClientException('Update parameters cannot be null.'); - } - } + final CrudRepository crudRepository; @override FutureOrResult execute(UpdateParameters? params) => - _crudRepository.update( + crudRepository.update( params!.id, object: params.object, raw: params.raw, diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/update_all.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/update_all.dart index 22c32181..76dcef70 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/usecases/update_all.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/update_all.dart @@ -14,32 +14,22 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import 'dart:async'; - import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart'; /// {@template update_all} /// A use case that updates all the object models. /// {@endtemplate} -class UpdateAll - extends AsyncUseCase, void> - with UpdateOperation> { +class UpdateAll extends Usecase, void> + with UpdateOperation> { /// {@macro update_all} - const UpdateAll(this._crudRepository); + const UpdateAll(this.crudRepository); - final CrudRepository _crudRepository; - - @override - FutureOr onStart(Map? params) { - if (params == null) { - throw const ClientException('Data cannot be null.'); - } - } + final CrudRepository crudRepository; @override FutureOrResult execute(Map? params) => - _crudRepository.updateAll(params!); + crudRepository.updateAll(params!); } diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/usecases.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/usecases.dart index 4a8d8467..cc0bc9d6 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/usecases/usecases.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/usecases.dart @@ -14,12 +14,36 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +import 'dart:async'; + +import 'package:wyatt_architecture/wyatt_architecture.dart'; +import 'package:wyatt_crud_bloc/src/core/enums/operation_type.dart'; + export 'create.dart'; export 'delete.dart'; export 'delete_all.dart'; export 'get.dart'; export 'get_all.dart'; export 'params/params.dart'; -export 'query.dart'; +export 'search.dart'; export 'update.dart'; export 'update_all.dart'; + +abstract class Usecase extends AsyncUseCase { + const Usecase(); + + @override + FutureOr onStart(In? params) { + if (params == null) { + throw ClientException('$In cannot be null.'); + } + } + + OperationType get operationType; +} + +abstract class NoParamUsecase extends AsyncUseCase { + const NoParamUsecase(); + + OperationType get operationType; +} diff --git a/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_advanced_cubit.dart b/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_advanced_cubit.dart index 85546422..3f2d3bda 100644 --- a/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_advanced_cubit.dart +++ b/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_advanced_cubit.dart @@ -17,7 +17,7 @@ import 'dart:async'; import 'package:wyatt_crud_bloc/src/core/enums/where_query_type.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; +import 'package:wyatt_crud_bloc/src/core/model_identifier.dart'; import 'package:wyatt_crud_bloc/src/domain/entities/query.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/create.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/delete.dart'; @@ -25,7 +25,7 @@ import 'package:wyatt_crud_bloc/src/domain/usecases/delete_all.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/get.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/get_all.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/params/update_parameters.dart'; -import 'package:wyatt_crud_bloc/src/domain/usecases/query.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/search.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/update.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/update_all.dart'; import 'package:wyatt_crud_bloc/src/features/crud/blocs/crud_base_cubit/crud_base_cubit.dart'; @@ -33,8 +33,7 @@ import 'package:wyatt_crud_bloc/src/features/crud/blocs/crud_base_cubit/crud_bas /// {@template crud_cubit_advanced} /// Cubit that handles CRUD operations with more granularity. /// {@endtemplate} -abstract class CrudAdvancedCubit - extends CrudBaseCubit { +abstract class CrudAdvancedCubit extends CrudBaseCubit { /// {@macro crud_cubit} CrudAdvancedCubit() : super(); @@ -43,10 +42,14 @@ abstract class CrudAdvancedCubit Delete? get crudDelete; GetAll? get crudGetAll; Get? get crudGet; - Query? get crudQuery; + Search? get crudSearch; UpdateAll? get crudUpdateAll; Update? get crudUpdate; + /// Model identifier. + /// Used to identify a model. + ModelIdentifier get modelIdentifier; + FutureOr create(Model model) async { final crud = crudCreate; if (crud == null) { @@ -54,7 +57,7 @@ abstract class CrudAdvancedCubit } final stateCopy = state; - emit(const CrudLoading()); + emit(const CrudCreating()); final result = await crud.call(model); emit( result.fold( @@ -63,7 +66,7 @@ abstract class CrudAdvancedCubit if (stateCopy.data == null) { return CrudLoaded(model); } - if (stateCopy.data!.id == model.id) { + if (modelIdentifier.areEqual(stateCopy.data, model)) { return CrudLoaded(model); } @@ -78,7 +81,7 @@ abstract class CrudAdvancedCubit return CrudListLoaded(lst); } - return const CrudOkReturn(); + return const CrudCreated(); }, (error) => CrudError(error.toString()), ), @@ -92,13 +95,16 @@ abstract class CrudAdvancedCubit } final stateCopy = state; - emit(const CrudLoading()); + emit(const CrudDeleting()); final result = await crud.call(id); emit( result.fold( (_) { if (stateCopy is CrudLoaded) { - if (stateCopy.data?.id == id) { + if (modelIdentifier.isIdentifier( + model: stateCopy.data, + identifier: id, + )) { return CrudLoaded(null); } @@ -106,11 +112,19 @@ abstract class CrudAdvancedCubit } if (stateCopy is CrudListLoaded) { return CrudListLoaded( - stateCopy.data.where((element) => element?.id != id).toList(), + stateCopy.data.where((element) { + if (element == null) { + return false; + } + return !modelIdentifier.isIdentifier( + model: element, + identifier: id, + ); + }).toList(), ); } - return const CrudOkReturn(); + return const CrudDeleted(); }, (error) => CrudError(error.toString()), ), @@ -123,7 +137,7 @@ abstract class CrudAdvancedCubit return; } final stateCopy = state; - emit(const CrudLoading()); + emit(const CrudDeleting()); final result = await crud.call(null); emit( result.fold( @@ -147,7 +161,7 @@ abstract class CrudAdvancedCubit if (crud == null) { return; } - emit(const CrudLoading()); + emit(const CrudReading()); final result = await crud.call(id); emit( result.fold( @@ -162,7 +176,7 @@ abstract class CrudAdvancedCubit if (crud == null) { return; } - emit(const CrudLoading()); + emit(const CrudReading()); final result = await crud.call(null); emit( result.fold( @@ -172,13 +186,13 @@ abstract class CrudAdvancedCubit ); } - FutureOr query(List conditions) async { - final crud = crudQuery; + FutureOr search(List conditions) async { + final crud = crudSearch; if (crud == null) { return; } - emit(const CrudLoading()); + emit(const CrudReading()); final result = await crud.call(conditions); emit( result.fold( @@ -195,13 +209,16 @@ abstract class CrudAdvancedCubit } final stateCopy = state; - emit(const CrudLoading()); + emit(const CrudUpdating()); final result = await crud.call(param); emit( await result.foldAsync( (_) async { if (stateCopy is CrudLoaded) { - if (stateCopy.data?.id == param.id) { + if (modelIdentifier.isIdentifier( + model: stateCopy.data, + identifier: param.id, + )) { // Same object, need to update actual stateCopy final crudGet = this.crudGet; if (crudGet == null) { @@ -216,8 +233,15 @@ abstract class CrudAdvancedCubit return stateCopy; } if (stateCopy is CrudListLoaded) { - final bool listContains = - stateCopy.data.any((element) => element?.id == param.id); + final bool listContains = stateCopy.data.any((element) { + if (element == null) { + return false; + } + return modelIdentifier.isIdentifier( + model: element, + identifier: param.id, + ); + }); if (listContains) { // Loaded objects contains the modified object. @@ -228,17 +252,23 @@ abstract class CrudAdvancedCubit } final newVersion = await crudGet.call(param.id); if (newVersion.isOk) { - final newList = stateCopy.data - .where( - (element) => element?.id != param.id, - ) - .toList(); + final newList = stateCopy.data.where( + (element) { + if (element == null) { + return false; + } + return !modelIdentifier.isIdentifier( + model: element, + identifier: param.id, + ); + }, + ).toList(); return CrudListLoaded(newList + [newVersion.ok]); } } return stateCopy; } - return const CrudOkReturn(); + return const CrudUpdated(); }, (error) async => CrudError(error.toString()), ), @@ -252,7 +282,7 @@ abstract class CrudAdvancedCubit } final stateCopy = state; - emit(const CrudLoading()); + emit(const CrudUpdating()); final result = await crud.call(param); emit( await result.foldAsync( @@ -264,7 +294,8 @@ abstract class CrudAdvancedCubit // No read operation, can't update stateCopy. return stateCopy; } - final actualId = stateCopy.data?.id; + final actualId = + modelIdentifier.getIdentifierOrNull(stateCopy.data); final newVersion = await crudGet.call(actualId ?? ''); if (newVersion.isOk) { return CrudLoaded(newVersion.ok); @@ -272,8 +303,8 @@ abstract class CrudAdvancedCubit return stateCopy; } if (stateCopy is CrudListLoaded) { - final crudQuery = this.crudQuery; - if (crudQuery == null) { + final crudSearch = this.crudSearch; + if (crudSearch == null) { // No read operation, can't update stateCopy. return stateCopy; } @@ -281,10 +312,11 @@ abstract class CrudAdvancedCubit // (not all because previous stateCopy can be a query result) final List ids = stateCopy.data .map( - (e) => e?.id, + (e) => modelIdentifier.getIdentifierOrNull(e), ) + .where((element) => element != null) .toList(); - final result = await crudQuery.call([ + final result = await crudSearch.call([ WhereQuery( WhereQueryType.whereIn, 'id', @@ -296,7 +328,7 @@ abstract class CrudAdvancedCubit } return stateCopy; } - return const CrudOkReturn(); + return const CrudUpdated(); }, (error) async => CrudError(error.toString()), ), diff --git a/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_base_cubit/crud_state.dart b/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_base_cubit/crud_state.dart index 64f2479a..81fd22a9 100644 --- a/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_base_cubit/crud_state.dart +++ b/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_base_cubit/crud_state.dart @@ -16,7 +16,7 @@ part of 'crud_base_cubit.dart'; -abstract class CrudState extends Equatable { +sealed class CrudState extends Equatable { const CrudState(); @override @@ -29,10 +29,26 @@ class CrudInitial extends CrudState { } /// Loading state of the CrudBaseCubit. -class CrudLoading extends CrudState { +abstract class CrudLoading extends CrudState { const CrudLoading(); } +class CrudCreating extends CrudLoading { + const CrudCreating(); +} + +class CrudReading extends CrudLoading { + const CrudReading(); +} + +class CrudUpdating extends CrudLoading { + const CrudUpdating(); +} + +class CrudDeleting extends CrudLoading { + const CrudDeleting(); +} + /// Error state of the CrudBaseCubit. class CrudError extends CrudState { const CrudError(this.message); @@ -57,6 +73,18 @@ class CrudOkReturn extends CrudSuccess { const CrudOkReturn(); } +class CrudCreated extends CrudOkReturn { + const CrudCreated(); +} + +class CrudUpdated extends CrudOkReturn { + const CrudUpdated(); +} + +class CrudDeleted extends CrudOkReturn { + const CrudDeleted(); +} + /// Loaded state of the CrudBaseCubit. /// This state is used to indicate that the operation was successful. /// Contains one object. diff --git a/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_cubit.dart b/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_cubit.dart index 97265465..80c8b19f 100644 --- a/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_cubit.dart +++ b/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_cubit.dart @@ -18,7 +18,7 @@ import 'dart:async'; import 'package:wyatt_crud_bloc/src/core/enums/where_query_type.dart'; import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; +import 'package:wyatt_crud_bloc/src/core/model_identifier.dart'; import 'package:wyatt_crud_bloc/src/domain/entities/query.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/create.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/delete.dart'; @@ -26,33 +26,42 @@ import 'package:wyatt_crud_bloc/src/domain/usecases/delete_all.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/get.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/get_all.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/params/update_parameters.dart'; -import 'package:wyatt_crud_bloc/src/domain/usecases/query.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/search.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/update.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/update_all.dart'; import 'package:wyatt_crud_bloc/src/features/crud/blocs/crud_base_cubit/crud_base_cubit.dart'; +typedef DefaultCreate = CreateOperation; +typedef DefaultRead = ReadOperation; +typedef DefaultUpdate = UpdateOperation; +typedef DefaultDelete = DeleteOperation; + /// {@template crud_cubit} -/// Cubit that handles CRUD operations. +/// Cubit that handles SCRUD operations. /// {@endtemplate} -abstract class CrudCubit extends CrudBaseCubit { +abstract class CrudCubit extends CrudBaseCubit { /// {@macro crud_cubit} CrudCubit() : super(); /// Create operation. /// Can be create. - CreateOperation? get createOperation; + CreateOperation? get createOperation; /// Read operation. - /// Can be get, getAll, query. - ReadOperation? get readOperation; + /// Can be get, getAll, search or stream. + ReadOperation? get readOperation; /// Update operation. /// Can be update, updateAll. - UpdateOperation? get updateOperation; + UpdateOperation? get updateOperation; /// Delete operation. /// Can be delete or deleteAll. - DeleteOperation? get deleteOperation; + DeleteOperation? get deleteOperation; + + /// Model identifier. + /// Used to identify a model. + ModelIdentifier get modelIdentifier; Expected? _checkOperation(dynamic operation) { if (operation == null) { @@ -70,27 +79,27 @@ abstract class CrudCubit extends CrudBaseCubit { } } - FutureOr read({String? id, List? conditions}) async { + FutureOr read({String? id, List? conditions}) async { if (_checkOperation>(readOperation) != null && id != null) { return _get(id); } if (_checkOperation>(readOperation) != null) { return _getAll(); } - if (_checkOperation>(readOperation) != null && + if (_checkOperation>(readOperation) != null && conditions != null) { - return _query(conditions); + return _search(conditions); } - if (_checkOperation>(readOperation) != null && + if (_checkOperation>(readOperation) != null && conditions == null) { return _getAll(); } } - FutureOr update( + FutureOr update({ UpdateParameters? single, Map? all, - ) async { + }) async { if (_checkOperation>(updateOperation) != null && single != null) { return _update(single); @@ -118,7 +127,7 @@ abstract class CrudCubit extends CrudBaseCubit { } final stateCopy = state; - emit(const CrudLoading()); + emit(const CrudCreating()); final result = await crud.call(model); emit( result.fold( @@ -127,7 +136,7 @@ abstract class CrudCubit extends CrudBaseCubit { if (stateCopy.data == null) { return CrudLoaded(model); } - if (stateCopy.data!.id == model.id) { + if (stateCopy.data == model) { return CrudLoaded(model); } @@ -142,7 +151,7 @@ abstract class CrudCubit extends CrudBaseCubit { return CrudListLoaded(lst); } - return const CrudOkReturn(); + return const CrudCreated(); }, (error) => CrudError(error.toString()), ), @@ -156,13 +165,16 @@ abstract class CrudCubit extends CrudBaseCubit { } final stateCopy = state; - emit(const CrudLoading()); + emit(const CrudDeleting()); final result = await crud.call(id); emit( result.fold( (_) { if (stateCopy is CrudLoaded) { - if (stateCopy.data?.id == id) { + if (modelIdentifier.isIdentifier( + model: stateCopy.data, + identifier: id, + )) { return CrudLoaded(null); } @@ -170,11 +182,19 @@ abstract class CrudCubit extends CrudBaseCubit { } if (stateCopy is CrudListLoaded) { return CrudListLoaded( - stateCopy.data.where((element) => element?.id != id).toList(), + stateCopy.data.where((element) { + if (element == null) { + return false; + } + return !modelIdentifier.isIdentifier( + model: element, + identifier: id, + ); + }).toList(), ); } - return const CrudOkReturn(); + return const CrudDeleted(); }, (error) => CrudError(error.toString()), ), @@ -187,7 +207,7 @@ abstract class CrudCubit extends CrudBaseCubit { return; } final stateCopy = state; - emit(const CrudLoading()); + emit(const CrudDeleting()); final result = await crud.call(null); emit( result.fold( @@ -199,7 +219,7 @@ abstract class CrudCubit extends CrudBaseCubit { return CrudListLoaded(const []); } - return const CrudOkReturn(); + return const CrudDeleted(); }, (error) => CrudError(error.toString()), ), @@ -211,7 +231,7 @@ abstract class CrudCubit extends CrudBaseCubit { if (crud == null) { return; } - emit(const CrudLoading()); + emit(const CrudReading()); final result = await crud.call(id); emit( result.fold( @@ -226,7 +246,7 @@ abstract class CrudCubit extends CrudBaseCubit { if (crud == null) { return; } - emit(const CrudLoading()); + emit(const CrudReading()); final result = await crud.call(null); emit( result.fold( @@ -236,13 +256,13 @@ abstract class CrudCubit extends CrudBaseCubit { ); } - FutureOr _query(List conditions) async { - final crud = _checkOperation>(readOperation); + FutureOr _search(List conditions) async { + final crud = _checkOperation>(readOperation); if (crud == null) { return; } - emit(const CrudLoading()); + emit(const CrudReading()); final result = await crud.call(conditions); emit( result.fold( @@ -259,13 +279,16 @@ abstract class CrudCubit extends CrudBaseCubit { } final stateCopy = state; - emit(const CrudLoading()); + emit(const CrudUpdating()); final result = await crud.call(param); emit( await result.foldAsync( (_) async { if (stateCopy is CrudLoaded) { - if (stateCopy.data?.id == param.id) { + if (modelIdentifier.isIdentifier( + model: stateCopy.data, + identifier: param.id, + )) { // Same object, need to update actual stateCopy final crudGet = _checkOperation>(readOperation); if (crudGet == null) { @@ -280,29 +303,48 @@ abstract class CrudCubit extends CrudBaseCubit { return stateCopy; } if (stateCopy is CrudListLoaded) { - final bool listContains = - stateCopy.data.any((element) => element?.id == param.id); + final bool listContains = stateCopy.data.any((element) { + if (element == null) { + return false; + } + return modelIdentifier.isIdentifier( + model: element, + identifier: param.id, + ); + }); if (listContains) { // Loaded objects contains the modified object. - final crudGet = _checkOperation>(readOperation); - if (crudGet == null) { - // No read operation, can't update stateCopy. - return stateCopy; + if (crudGet != null) { + final newVersion = await crudGet.call(param.id); + if (newVersion.isOk) { + final newList = stateCopy.data.where( + (element) { + if (element == null) { + return false; + } + return !modelIdentifier.isIdentifier( + model: element, + identifier: param.id, + ); + }, + ).toList(); + return CrudListLoaded(newList + [newVersion.ok]); + } } - final newVersion = await crudGet.call(param.id); - if (newVersion.isOk) { - final newList = stateCopy.data - .where( - (element) => element?.id != param.id, - ) - .toList(); - return CrudListLoaded(newList + [newVersion.ok]); + + // If get operation is not available, just reload all objects. + final crudGetAll = _checkOperation>(readOperation); + if (crudGetAll != null) { + final newVersion = await crudGetAll.call(null); + if (newVersion.isOk) { + return CrudListLoaded(newVersion.ok ?? []); + } } } return stateCopy; } - return const CrudOkReturn(); + return const CrudUpdated(); }, (error) async => CrudError(error.toString()), ), @@ -316,7 +358,7 @@ abstract class CrudCubit extends CrudBaseCubit { } final stateCopy = state; - emit(const CrudLoading()); + emit(const CrudUpdating()); final result = await crud.call(param); emit( await result.foldAsync( @@ -328,7 +370,8 @@ abstract class CrudCubit extends CrudBaseCubit { // No read operation, can't update stateCopy. return stateCopy; } - final actualId = stateCopy.data?.id; + final actualId = + modelIdentifier.getIdentifierOrNull(stateCopy.data); final newVersion = await crudGet.call(actualId ?? ''); if (newVersion.isOk) { return CrudLoaded(newVersion.ok); @@ -336,7 +379,7 @@ abstract class CrudCubit extends CrudBaseCubit { return stateCopy; } if (stateCopy is CrudListLoaded) { - final crudQuery = _checkOperation>(readOperation); + final crudQuery = _checkOperation>(readOperation); if (crudQuery == null) { // No read operation, can't update stateCopy. return stateCopy; @@ -345,8 +388,9 @@ abstract class CrudCubit extends CrudBaseCubit { // (not all because previous stateCopy can be a query result) final List ids = stateCopy.data .map( - (e) => e?.id, + (e) => modelIdentifier.getIdentifierOrNull(e), ) + .where((element) => element != null) .toList(); final result = await crudQuery.call([ WhereQuery( @@ -360,7 +404,7 @@ abstract class CrudCubit extends CrudBaseCubit { } return stateCopy; } - return const CrudOkReturn(); + return const CrudUpdated(); }, (error) async => CrudError(error.toString()), ), diff --git a/packages/wyatt_crud_bloc/lib/src/features/crud/builder/builder.dart b/packages/wyatt_crud_bloc/lib/src/features/crud/builder/builder.dart deleted file mode 100644 index 52cf109d..00000000 --- a/packages/wyatt_crud_bloc/lib/src/features/crud/builder/builder.dart +++ /dev/null @@ -1,17 +0,0 @@ -// 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 . - -export 'crud_builder.dart'; diff --git a/packages/wyatt_crud_bloc/lib/src/features/crud/crud.dart b/packages/wyatt_crud_bloc/lib/src/features/crud/crud.dart index 16113197..7027e5ec 100644 --- a/packages/wyatt_crud_bloc/lib/src/features/crud/crud.dart +++ b/packages/wyatt_crud_bloc/lib/src/features/crud/crud.dart @@ -17,4 +17,4 @@ export 'blocs/crud_advanced_cubit.dart'; export 'blocs/crud_base_cubit/crud_base_cubit.dart'; export 'blocs/crud_cubit.dart'; -export 'builder/builder.dart'; +export 'builder/crud_builder.dart'; diff --git a/packages/wyatt_crud_bloc/lib/wyatt_crud_bloc.dart b/packages/wyatt_crud_bloc/lib/wyatt_crud_bloc.dart index 2656783e..ceabcacd 100644 --- a/packages/wyatt_crud_bloc/lib/wyatt_crud_bloc.dart +++ b/packages/wyatt_crud_bloc/lib/wyatt_crud_bloc.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify diff --git a/packages/wyatt_crud_bloc/pubspec.yaml b/packages/wyatt_crud_bloc/pubspec.yaml index 39c1d03d..6f0174ae 100644 --- a/packages/wyatt_crud_bloc/pubspec.yaml +++ b/packages/wyatt_crud_bloc/pubspec.yaml @@ -6,15 +6,13 @@ version: 0.1.1+1 publish_to: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub environment: - sdk: ">=2.17.0 <3.0.0" - flutter: ">=1.17.0" + sdk: ">=3.0.0 <4.0.0" dependencies: flutter: { sdk: flutter } flutter_bloc: ^8.1.1 equatable: ^2.0.5 - cloud_firestore: ^4.0.5 wyatt_architecture: hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ @@ -29,4 +27,4 @@ dev_dependencies: bloc_test: ^9.1.0 wyatt_analysis: hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub - version: ^2.5.0 + version: ^2.6.1 diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.gitignore b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.gitignore new file mode 120000 index 00000000..00e03899 --- /dev/null +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.gitignore @@ -0,0 +1 @@ +../../../.gitignore \ No newline at end of file diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.metadata b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.metadata new file mode 100644 index 00000000..6176c000 --- /dev/null +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.metadata @@ -0,0 +1,10 @@ +# 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 and should not be manually edited. + +version: + revision: "d211f42860350d914a5ad8102f9ec32764dc6d06" + channel: "stable" + +project_type: package diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.pubignore b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.pubignore new file mode 120000 index 00000000..353b763d --- /dev/null +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.pubignore @@ -0,0 +1 @@ +../../../.pubignore \ No newline at end of file diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/AUTHORS b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/AUTHORS new file mode 120000 index 00000000..d776b73d --- /dev/null +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/AUTHORS @@ -0,0 +1 @@ +../../../AUTHORS \ No newline at end of file diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/CHANGELOG.md b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/CHANGELOG.md new file mode 100644 index 00000000..41cc7d81 --- /dev/null +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* TODO: Describe initial release. diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/LICENSE b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/LICENSE new file mode 120000 index 00000000..5853aaea --- /dev/null +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/LICENSE @@ -0,0 +1 @@ +../../../LICENSE \ No newline at end of file diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/README.md b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/README.md new file mode 100644 index 00000000..02fe8eca --- /dev/null +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/README.md @@ -0,0 +1,39 @@ + + +TODO: Put a short description of the package here that helps potential users +know whether this package might be useful for them. + +## Features + +TODO: List what your package can do. Maybe include images, gifs, or videos. + +## Getting started + +TODO: List prerequisites and provide or point to information on how to +start using the package. + +## Usage + +TODO: Include short and useful examples for package users. Add longer examples +to `/example` folder. + +```dart +const like = 'sample'; +``` + +## Additional information + +TODO: Tell users more about the package: where to find more information, how to +contribute to the package, how to file issues, what response they can expect +from the package authors, and more. diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/analysis_options.yaml b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/analysis_options.yaml new file mode 100644 index 00000000..8c9daa4e --- /dev/null +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/analysis_options.yaml @@ -0,0 +1 @@ +include: package:wyatt_analysis/analysis_options.flutter.yaml diff --git a/packages/wyatt_crud_bloc/lib/src/data/data_sources/remote/crud_firestore_data_source_impl.dart b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/lib/src/data/crud_data_source_firestore_impl.dart similarity index 70% rename from packages/wyatt_crud_bloc/lib/src/data/data_sources/remote/crud_firestore_data_source_impl.dart rename to packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/lib/src/data/crud_data_source_firestore_impl.dart index 7b4f793a..e8d5ef24 100644 --- a/packages/wyatt_crud_bloc/lib/src/data/data_sources/remote/crud_firestore_data_source_impl.dart +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/lib/src/data/crud_data_source_firestore_impl.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify @@ -15,49 +15,51 @@ // along with this program. If not, see . import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:wyatt_crud_bloc/src/core/enums/where_query_type.dart'; -import 'package:wyatt_crud_bloc/src/domain/data_sources/crud_data_source.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/query.dart'; +import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart' hide Query; +import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart' as crud show Query; -/// {@template crud_firestore_data_source_impl} +/// {@template crud_data_source_firestore_impl} /// A concrete implementation of [CrudDataSource] that uses /// [FirebaseFirestore] as the data source. /// {@endtemplate} -class CrudFirestoreDataSourceImpl - extends CrudDataSource { - /// {@macro crud_firestore_data_source_impl} - CrudFirestoreDataSourceImpl( +class CrudDataSourceFirestoreImpl extends CrudDataSource { + /// {@macro crud_data_source_firestore_impl} + CrudDataSourceFirestoreImpl( String collection, { - /// The function that converts a [DocumentSnapshot] to a [Model]. - required Model Function( + required super.id, + + /// The function that converts a [DocumentSnapshot] to a Model. + required Map Function( DocumentSnapshot>, SnapshotOptions?, ) fromFirestore, - /// The function that converts a [Model] to a [Map]. - required Map Function(Model, SetOptions?) toFirestore, + /// The function that converts a Model to a [Map]. + required Map Function(Map, SetOptions?) + toFirestore, FirebaseFirestore? firestore, - }) : _firestore = firestore ?? FirebaseFirestore.instance, - _toFirestore = toFirestore { + }) : _firestore = firestore ?? FirebaseFirestore.instance { _collectionReference = - _firestore.collection(collection).withConverter( + _firestore.collection(collection).withConverter>( fromFirestore: fromFirestore, toFirestore: toFirestore, ); } final FirebaseFirestore _firestore; - - final Map Function(Model, SetOptions?) _toFirestore; - late CollectionReference _collectionReference; + late CollectionReference> _collectionReference; @override - Future create(Model object, {String? id}) { + Future create(Map object, {String? id}) { if (id != null) { return _collectionReference.doc(id).set(object); } else { - if (object.id != null) { - return _collectionReference.doc(object.id).set(object); + final String? id = this.id( + OperationType.create, + object, + ); + + if (id != null) { + return _collectionReference.doc(id).set(object); } return _collectionReference.add(object); } @@ -77,32 +79,35 @@ class CrudFirestoreDataSourceImpl } @override - Future get(String id) async { - final DocumentSnapshot snapshot = + Future?> get(String id) async { + final DocumentSnapshot> snapshot = await _collectionReference.doc(id).get(); return snapshot.data(); } @override - Future> getAll() async { - final QuerySnapshot snapshots = await _collectionReference.get(); + Future?>> getAll() async { + final QuerySnapshot> snapshots = + await _collectionReference.get(); return snapshots.docs.map((snapshot) => snapshot.data()).toList(); } @override - Future> query(List conditions) async { - Query query = _collectionReference; + Future?>> search( + List conditions, + ) async { + Query> query = _collectionReference; for (final condition in conditions) { query = _queryParser(condition, query); } - final QuerySnapshot snapshots = await query.get(); + final QuerySnapshot> snapshots = await query.get(); return snapshots.docs.map((snapshot) => snapshot.data()).toList(); } @override - Stream> stream({ + Stream?>> stream({ String? id, - List? conditions, + List? conditions, bool includeMetadataChanges = false, }) { if (id != null) { @@ -111,12 +116,12 @@ class CrudFirestoreDataSourceImpl .snapshots( includeMetadataChanges: includeMetadataChanges, ) - .map>( + .map?>>( (snapshot) => [snapshot.data()], ); } else { if (conditions != null) { - Query query = _collectionReference; + Query> query = _collectionReference; for (final condition in conditions) { query = _queryParser(condition, query); } @@ -146,19 +151,12 @@ class CrudFirestoreDataSourceImpl @override Future update( String id, { - Model? object, - Map? raw, + Map? object, }) { if (object != null) { - return _collectionReference - .doc(id) - .update(_toFirestore.call(object, null)); + return _collectionReference.doc(id).update(object); } else { - if (raw != null) { - return _collectionReference.doc(id).update(raw); - } else { - throw Exception('You must provide an object or a raw map'); - } + throw Exception('You must provide data to update'); } } @@ -168,15 +166,16 @@ class CrudFirestoreDataSourceImpl throw Exception('You must provide data to update'); } final batch = _firestore.batch(); - final QuerySnapshot snapshots = await _collectionReference.get(); + final QuerySnapshot> snapshots = + await _collectionReference.get(); for (final DocumentSnapshot snapshot in snapshots.docs) { batch.update(snapshot.reference, data); } return batch.commit(); } - Query _queryParser(QueryInterface condition, Object query) { - query as Query; + Query> _queryParser(crud.Query condition, Object query) { + query as Query>; if (condition is WhereQuery) { switch (condition.type) { case WhereQueryType.isEqualTo: diff --git a/packages/wyatt_crud_bloc/lib/src/data/repositories/repositories.dart b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/lib/wyatt_crud_firestore.dart similarity index 78% rename from packages/wyatt_crud_bloc/lib/src/data/repositories/repositories.dart rename to packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/lib/wyatt_crud_firestore.dart index f31c2358..9467c9f7 100644 --- a/packages/wyatt_crud_bloc/lib/src/data/repositories/repositories.dart +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/lib/wyatt_crud_firestore.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify @@ -14,4 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -export 'crud_repository_impl.dart'; +/// Create/Read/Update/Delete BLoC implementation for Firestore +library wyatt_crud_bloc_firestore; + +export 'src/data/crud_data_source_firestore_impl.dart'; diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/pubspec.yaml b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/pubspec.yaml new file mode 100644 index 00000000..bbc0a393 --- /dev/null +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/pubspec.yaml @@ -0,0 +1,34 @@ +name: wyatt_crud_bloc_firestore +description: Create/Read/Update/Delete implementation for Cloud Firestore +repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_crud_bloc +version: 0.1.1+1 + +publish_to: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub + +environment: + sdk: ">=3.0.0 <4.0.0" + +dependencies: + flutter: { sdk: flutter } + + flutter_bloc: ^8.1.1 + equatable: ^2.0.5 + cloud_firestore: ^4.0.5 + + wyatt_architecture: + hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + version: ^0.2.0+1 + + wyatt_type_utils: + hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + version: ^0.0.5 + + wyatt_crud_bloc: + path: ../ + +dev_dependencies: + flutter_test: { sdk: flutter } + bloc_test: ^9.1.0 + wyatt_analysis: + hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub + version: ^2.6.1 -- 2.47.2 From bd80934196e15d4a1c563edfe8b376ba500a6e95 Mon Sep 17 00:00:00 2001 From: Hugo Pointcheval Date: Mon, 13 Nov 2023 18:25:25 +0100 Subject: [PATCH 2/9] docs(crud): update readme --- packages/wyatt_crud_bloc/README.md | 232 ++++++++++++------ .../wyatt_crud_bloc_firestore/pubspec.yaml | 3 +- 2 files changed, 156 insertions(+), 79 deletions(-) diff --git a/packages/wyatt_crud_bloc/README.md b/packages/wyatt_crud_bloc/README.md index 4f483186..f5932c72 100644 --- a/packages/wyatt_crud_bloc/README.md +++ b/packages/wyatt_crud_bloc/README.md @@ -27,10 +27,7 @@ CRUD Bloc Pattern utilities for Flutter. This package defines a set of classes that can be used to implement the CRUD Bloc Pattern. -* Model * Data Source - + In Memory - + Firestore * Repository * Use Case + Create @@ -40,128 +37,207 @@ This package defines a set of classes that can be used to implement the CRUD Blo + Update All + Delete + Delete All - + Query + + Search * Bloc + Standard (C R U D), you have to choose the responsiblity of the bloc for each use case. For example, you can have a cubit that only handles the creation of an entity, and another cubit that only handles the deletion of an entity. Each cubit can only have one operation responsibility of each type, for example you can't have a cubit that handles get and get all. + Advanced, you can set every use case to be handled by the bloc. This is useful if you want to have a single bloc that handles all the operations of an entity. ## Usage -Create a model class that extends the `ObjectModel` class. +Create your entity using Wyatt Architecture and Equatable ```dart -class User extends ObjectModel { - @override +import 'package:equatable/equatable.dart'; +import 'package:wyatt_architecture/wyatt_architecture.dart'; + +class User extends Entity with EquatableMixin { final String? id; - final String? name; - + final String name; + final String email; + final String phone; + const User({ required this.name, + required this.email, + required this.phone, this.id, }); - Map toMap() { - return { - 'name': name ?? '', - }; - } - @override - String toString() => 'User(id: $id, name: $name)'; + List get props => [id, name, email, phone]; } ``` -You have to implement a bloc. +Then, you can create your model for this entity with Freezed, JsonSerializable or any other library. ```dart +import 'package:crud_bloc_example/user_entity.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'user_model.g.dart'; + +@JsonSerializable() +class UserModel extends User { + UserModel({ + super.id, + required super.name, + required super.email, + required super.phone, + }); + + factory UserModel.fromJson(Map json) => + _$UserModelFromJson(json); + + Map toJson() => _$UserModelToJson(this); + + @override + String toString() => + 'UserModel(id: $id, name: $name, email: $email, phone: $phone)'; +} +``` + +> This exemple uses JsonSerializable to generate the model, but you can use any other library. Or you can even create your own model without any library. + +Then you have to create a **CRUD** Cubit. Each Crud cubit can only handle one operation of each type. For example, you can't have a cubit that handles get and get all. (See the `CrudAdvancedCubit` for this use case). + +You also have to create a `modelIdentifier` that will be used to identify your model. This is used to identify the model in the state of the cubit. For example, if you have a list of users, you can use the id of the user to identify it in the state. **It's up to you to choose how you want to identify your model.** + +```dart +import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; + /// A [CrudCubit] for [User]. class UserCubit extends CrudCubit { - final CrudRepository _crudRepository; + final CrudRepository crudRepository; - UserCubit(this._crudRepository); + UserCubit(this.crudRepository); @override - CreateOperation? get createOperation => - Create(_crudRepository); + DefaultCreate? get createOperation => Create(crudRepository); @override - DeleteOperation? get deleteOperation => - Delete(_crudRepository); + DefaultDelete? get deleteOperation => Delete(crudRepository); @override - ReadOperation? get readOperation => - GetAll(_crudRepository); + DefaultRead? get readOperation => GetAll(crudRepository); @override - UpdateOperation? get updateOperation => - Update(_crudRepository); + DefaultUpdate? get updateOperation => Update(crudRepository); + + @override + ModelIdentifier get modelIdentifier => ModelIdentifier( + getIdentifier: (user) => user.id ?? '', + ); } ``` -> You can also use the `CrudAdvancedCubit` class to implement a bloc that handles all the use cases. +> In this example, the `modelIdentifier` is the id of the user. But you can use any other property of the user to identify it. But make sure that the property you use is unique. -Then you can use the bloc in your widget with a data source and a repository. +> In this example, the `CrudCubit` handles `Create`, `Delete`, `GetAll` and `Update` operations. But you can choose which operation you want to handle. For example, you can have a cubit that only handles the creation of an entity, and another cubit that only handles the deletion of an entity. + +Then you can configure the data source and the repository. + +### In Memory + +The base implementation of the data source is the `CrudInMemoryDataSourceImpl`. This data source stores the data in memory. This is useful for testing. ```dart -class MyApp extends StatelessWidget { - const MyApp({Key? key}) : super(key: key); - - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - final CrudDataSource userLocalDataSource = - CrudInMemoryDataSourceImpl(toMap: (user) => user.toMap()); - - final CrudRepository userRepository = - CrudRepositoryImpl(crudDataSource: userLocalDataSource); - - return RepositoryProvider>.value( - value: userRepository, - child: BlocProvider( - create: (context) => UserCubit(userRepository)..read(), - child: MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: const MyHomePage(), - ), - ), - ); - } -} +final CrudDataSource crudDataSource = CrudDataSourceInMemoryImpl( + id: (operation, json) => json['id'] as String?, +); ``` -And anywhere in your widget tree you can use the BlocBuilder to build your widget. +> The `id` parameter is used to get the id of the raw data. You can use the `operation` parameter to get the operation that is being performed. This is useful if you want to have different ids for each operation. For example, you can have a different id for the creation and the update of an entity. + +### Firestore + +You can use the `CrudFirestoreDataSourceImpl` to store your data in Firestore. + +Make sure to add the `wyatt_crud_bloc_firestore` package to your dependencies. + +```dart +final CrudDataSource crudDataSource = CrudDataSourceFirestoreImpl( + 'users', + id: (_, json) => json['id'] as String, + fromFirestore: (document, snapshot) => document.data() ?? {}, + toFirestore: (object, options) => object, +); +``` + +> The `id` parameter is used to get the id of the raw data. You can use the `operation` parameter to get the operation that is being performed. This is useful if you want to have different ids for each operation. For example, you can have a different id for the creation and the update of an entity. + +> The `fromFirestore` and `toFirestore` parameters are used to convert the data from and to Firestore. + +Finally, you can use the `CrudRepositoryImpl` to create your repository. + +```dart +final CrudRepository userRepository = CrudRepositoryImpl( + crudDataSource: crudDataSource, + modelMapper: ModelMapper( + fromJson: (json) => UserModel.fromJson(json ?? {}), + toJson: (user) => UserModel( + id: user.id, + name: user.name, + email: user.email, + phone: user.phone, + ).toJson(), + ), +); +``` + +> The `modelMapper` parameter is used to convert the data from and to the model. In the `toJson` make sure to use the same data structure as the one used in the data source. For example the previous `id()` function is used to get the id of the raw data, if `id` is missing from the raw data, the `id()` function will not works. + +And in your widget tree you can use the `CrudBuilder` to build your UI. ```dart ... BlocBuilder( + buildWhen: (previous, current) { + if (current is CrudLoading && current is! CrudReading) { + return false; + } + return true; + }, builder: (context, state) { - return CrudBuilder.typed>( - state: state, - builder: ((context, state) { - return ListView.builder( - shrinkWrap: true, - itemCount: state.data.length, - itemBuilder: (context, index) { - final user = state.data.elementAt(index); - return ListTile( - title: Text(user?.name ?? 'Error'), - subtitle: Text(user?.id ?? 'Error'), - onTap: () { - context.read().delete(id: (user?.id)!); - }, - ); - }, - ); - }), - initialBuilder: (context, state) => const Text("Loading..."), - loadingBuilder: (context, state) => const Text("Loading..."), - errorBuilder: (context, state) => Text("Error: $state"), + return Expanded( + child: CrudBuilder.typed>( + state: state, + builder: ((context, state) { + return ListView.builder( + itemCount: state.data.length, + itemBuilder: (context, index) { + final user = state.data.elementAt(index); + return ListTile( + title: Text(user?.name ?? 'Error'), + subtitle: Text(user?.email ?? 'Error'), + onTap: () { + context + .read() + .delete(id: (user?.id)!); + }, + onLongPress: () { + context.read().update( + single: UpdateParameters( + id: user?.id ?? '', + raw: { + 'email': '${user?.id}@updated.io', + }), + ); + }, + ); + }, + ); + }), + initialBuilder: (context, state) => + const Center(child: CircularProgressIndicator()), + loadingBuilder: (context, state) => + const Center(child: CircularProgressIndicator()), + errorBuilder: (context, state) => Text("Error: $state"), + ), ); }, ), ... ``` + +> This piece of code is used to build a list of users. When you tap on a user, it will delete it. When you long press on a user, it will update it. Also, the loading state is not always displayed, it will only be displayed when the state is `CrudReading`, so when the state is `CrudUpdating` or `CrudDeleting`, the loading state will not be displayed. diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/pubspec.yaml b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/pubspec.yaml index bbc0a393..fcb9d5d9 100644 --- a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/pubspec.yaml +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/pubspec.yaml @@ -24,7 +24,8 @@ dependencies: version: ^0.0.5 wyatt_crud_bloc: - path: ../ + hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + version: 0.1.1+1 dev_dependencies: flutter_test: { sdk: flutter } -- 2.47.2 From c19bb76d5c4bec42c3d2c90674c0de3bda76413c Mon Sep 17 00:00:00 2001 From: Hugo Pointcheval Date: Mon, 13 Nov 2023 18:31:09 +0100 Subject: [PATCH 3/9] refactor: make CrudLoading instanciable --- .../lib/src/features/crud/blocs/crud_base_cubit/crud_state.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_base_cubit/crud_state.dart b/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_base_cubit/crud_state.dart index 81fd22a9..2e473b90 100644 --- a/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_base_cubit/crud_state.dart +++ b/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_base_cubit/crud_state.dart @@ -29,7 +29,7 @@ class CrudInitial extends CrudState { } /// Loading state of the CrudBaseCubit. -abstract class CrudLoading extends CrudState { +class CrudLoading extends CrudState { const CrudLoading(); } -- 2.47.2 From 54bff3e72ed33a385e6c9990b7e87b9d525a84dd Mon Sep 17 00:00:00 2001 From: Hugo Pointcheval Date: Tue, 14 Nov 2023 10:35:41 +0100 Subject: [PATCH 4/9] fix: rename wyatt_bruc_bloc_firestore main package file --- packages/wyatt_crud_bloc/example/lib/main_firestore.dart | 2 +- ...wyatt_crud_firestore.dart => wyatt_crud_bloc_firestore.dart} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/lib/{wyatt_crud_firestore.dart => wyatt_crud_bloc_firestore.dart} (100%) diff --git a/packages/wyatt_crud_bloc/example/lib/main_firestore.dart b/packages/wyatt_crud_bloc/example/lib/main_firestore.dart index 7b40e29a..924e0cdb 100644 --- a/packages/wyatt_crud_bloc/example/lib/main_firestore.dart +++ b/packages/wyatt_crud_bloc/example/lib/main_firestore.dart @@ -21,7 +21,7 @@ import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; -import 'package:wyatt_crud_bloc_firestore/wyatt_crud_firestore.dart'; +import 'package:wyatt_crud_bloc_firestore/wyatt_crud_bloc_firestore.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/lib/wyatt_crud_firestore.dart b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/lib/wyatt_crud_bloc_firestore.dart similarity index 100% rename from packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/lib/wyatt_crud_firestore.dart rename to packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/lib/wyatt_crud_bloc_firestore.dart -- 2.47.2 From ff0f76d9104d45ae992dae563015990721375203 Mon Sep 17 00:00:00 2001 From: Hugo Pointcheval Date: Tue, 14 Nov 2023 10:36:07 +0100 Subject: [PATCH 5/9] build: add version caret on crud bloc dependency --- packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/pubspec.yaml b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/pubspec.yaml index fcb9d5d9..eb9dc7dc 100644 --- a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/pubspec.yaml +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/pubspec.yaml @@ -25,7 +25,7 @@ dependencies: wyatt_crud_bloc: hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ - version: 0.1.1+1 + version: ^0.1.1+1 dev_dependencies: flutter_test: { sdk: flutter } -- 2.47.2 From 3a7b7dfd1d406cd36b12bf1fe71ccc6b45f98861 Mon Sep 17 00:00:00 2001 From: Hugo Pointcheval Date: Tue, 14 Nov 2023 14:04:57 +0100 Subject: [PATCH 6/9] feat(crud): add streaming usecase (closes #180) --- .../example/lib/advanced_cubit_view.dart | 29 +--- packages/wyatt_crud_bloc/example/lib/app.dart | 68 ++++++---- .../example/lib/streaming_cubit_view.dart | 125 ++++++++++++++++++ .../example/lib/user_advanced_cubit.dart | 3 + .../example/lib/user_streaming_cubit.dart | 42 ++++++ .../crud_data_source_in_memory_impl.dart | 7 +- .../usecases/{stream.dart => streaming.dart} | 8 +- .../lib/src/domain/usecases/usecases.dart | 1 + .../crud/blocs/crud_advanced_cubit.dart | 58 ++++++++ .../src/features/crud/blocs/crud_cubit.dart | 70 +++++++++- packages/wyatt_crud_bloc/pubspec.yaml | 1 + 11 files changed, 349 insertions(+), 63 deletions(-) create mode 100644 packages/wyatt_crud_bloc/example/lib/streaming_cubit_view.dart create mode 100644 packages/wyatt_crud_bloc/example/lib/user_streaming_cubit.dart rename packages/wyatt_crud_bloc/lib/src/domain/usecases/{stream.dart => streaming.dart} (93%) diff --git a/packages/wyatt_crud_bloc/example/lib/advanced_cubit_view.dart b/packages/wyatt_crud_bloc/example/lib/advanced_cubit_view.dart index 1cee2df2..9671663e 100644 --- a/packages/wyatt_crud_bloc/example/lib/advanced_cubit_view.dart +++ b/packages/wyatt_crud_bloc/example/lib/advanced_cubit_view.dart @@ -33,11 +33,11 @@ class AdvancedCubitView extends StatelessWidget { ), body: BlocProvider( create: (context) => - UserAdvancedCubit(context.read>())..getAll(), + UserAdvancedCubit(context.read>()) + ..streaming(), child: Builder(builder: (context) { return Column( children: [ - const Text("Data:"), BlocBuilder( buildWhen: (previous, current) { if (current is CrudLoading && current is! CrudReading) { @@ -117,31 +117,6 @@ class AdvancedCubitView extends StatelessWidget { }, ), ), - ElevatedButton( - onPressed: () { - context.read().getAll(); - }, - child: BlocBuilder( - buildWhen: (previous, current) { - if (current is CrudLoading && current is! CrudReading) { - return false; - } - return true; - }, - builder: (context, state) { - return state is CrudReading - ? const SizedBox( - width: 20, - height: 20, - child: CircularProgressIndicator( - color: Colors.white, - ), - ) - : const Text("GetAll"); - }, - ), - ), - const SizedBox(height: 20), ], ); }), diff --git a/packages/wyatt_crud_bloc/example/lib/app.dart b/packages/wyatt_crud_bloc/example/lib/app.dart index 51e6a7d6..088f1324 100644 --- a/packages/wyatt_crud_bloc/example/lib/app.dart +++ b/packages/wyatt_crud_bloc/example/lib/app.dart @@ -16,6 +16,7 @@ import 'package:crud_bloc_example/advanced_cubit_view.dart'; import 'package:crud_bloc_example/basic_cubit_view.dart'; +import 'package:crud_bloc_example/streaming_cubit_view.dart'; import 'package:crud_bloc_example/user_entity.dart'; import 'package:crud_bloc_example/user_model.dart'; import 'package:flutter/material.dart'; @@ -65,32 +66,47 @@ class MyHomePage extends StatelessWidget { appBar: AppBar( title: const Text('Flutter Demo Home Page'), ), - body: Column( - children: [ - ElevatedButton( - onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const BasicCubitView(), - ), - ); - }, - child: const Text('Basic example'), - ), - const SizedBox(height: 20), - ElevatedButton( - onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const AdvancedCubitView(), - ), - ); - }, - child: const Text('Advanced example'), - ), - ], + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const BasicCubitView(), + ), + ); + }, + child: const Text('Basic example'), + ), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const StreamingCubitView(), + ), + ); + }, + child: const Text('Streaming example'), + ), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const AdvancedCubitView(), + ), + ); + }, + child: const Text('Advanced example'), + ), + ], + ), ), ); } diff --git a/packages/wyatt_crud_bloc/example/lib/streaming_cubit_view.dart b/packages/wyatt_crud_bloc/example/lib/streaming_cubit_view.dart new file mode 100644 index 00000000..8f1df40d --- /dev/null +++ b/packages/wyatt_crud_bloc/example/lib/streaming_cubit_view.dart @@ -0,0 +1,125 @@ +// Copyright (C) 2023 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 'dart:math'; + +import 'package:crud_bloc_example/user_entity.dart'; +import 'package:crud_bloc_example/user_streaming_cubit.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; + +class StreamingCubitView extends StatelessWidget { + const StreamingCubitView({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text("Streaming Cubit"), + ), + body: BlocProvider( + create: (context) => + UserStreamingCubit(context.read>())..read(), + child: Builder(builder: (context) { + return Column( + children: [ + BlocBuilder( + buildWhen: (previous, current) { + if (current is CrudLoading && current is! CrudReading) { + return false; + } + return true; + }, + builder: (context, state) { + return Expanded( + child: CrudBuilder.typed>( + state: state, + builder: ((context, state) { + return ListView.builder( + itemCount: state.data.length, + itemBuilder: (context, index) { + final user = state.data.elementAt(index); + return ListTile( + title: Text(user?.name ?? 'Error'), + subtitle: Text(user?.email ?? 'Error'), + onTap: () { + context + .read() + .delete(id: (user?.id)!); + }, + onLongPress: () { + context.read().update( + single: UpdateParameters( + id: user?.id ?? '', + raw: { + 'email': '${user?.id}@updated.io', + }), + ); + }, + ); + }, + ); + }), + initialBuilder: (context, state) => + const Center(child: CircularProgressIndicator()), + loadingBuilder: (context, state) => + const Center(child: CircularProgressIndicator()), + errorBuilder: (context, state) => Text("Error: $state"), + ), + ); + }, + ), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () { + final r = Random().nextInt(1000); + context.read().create( + User( + id: '$r', + name: 'Wyatt $r', + email: '$r@wyattapp.io', + phone: '06$r', + ), + ); + }, + child: BlocBuilder( + buildWhen: (previous, current) { + if (current is CrudLoading && current is! CrudCreating) { + return false; + } + return true; + }, + builder: (context, state) { + return state is CrudCreating + ? const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + color: Colors.white, + ), + ) + : const Text("Create"); + }, + ), + ), + ], + ); + }), + ), + ); + } +} diff --git a/packages/wyatt_crud_bloc/example/lib/user_advanced_cubit.dart b/packages/wyatt_crud_bloc/example/lib/user_advanced_cubit.dart index 5ebbf0df..b61c3144 100644 --- a/packages/wyatt_crud_bloc/example/lib/user_advanced_cubit.dart +++ b/packages/wyatt_crud_bloc/example/lib/user_advanced_cubit.dart @@ -46,6 +46,9 @@ class UserAdvancedCubit extends CrudAdvancedCubit { @override Search? get crudSearch => Search(crudRepository); + @override + Streaming? get crudStreaming => Streaming(crudRepository); + @override Update? get crudUpdate => Update(crudRepository); diff --git a/packages/wyatt_crud_bloc/example/lib/user_streaming_cubit.dart b/packages/wyatt_crud_bloc/example/lib/user_streaming_cubit.dart new file mode 100644 index 00000000..45387137 --- /dev/null +++ b/packages/wyatt_crud_bloc/example/lib/user_streaming_cubit.dart @@ -0,0 +1,42 @@ +// 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:crud_bloc_example/user_entity.dart'; +import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; + +/// A [CrudCubit] for [User]. +class UserStreamingCubit extends CrudCubit { + final CrudRepository crudRepository; + + UserStreamingCubit(this.crudRepository); + + @override + DefaultCreate? get createOperation => Create(crudRepository); + + @override + DefaultDelete? get deleteOperation => Delete(crudRepository); + + @override + DefaultRead? get readOperation => Streaming(crudRepository); + + @override + DefaultUpdate? get updateOperation => Update(crudRepository); + + @override + ModelIdentifier get modelIdentifier => ModelIdentifier( + getIdentifier: (user) => user.id ?? '', + ); +} diff --git a/packages/wyatt_crud_bloc/lib/src/data/data_sources/crud_data_source_in_memory_impl.dart b/packages/wyatt_crud_bloc/lib/src/data/data_sources/crud_data_source_in_memory_impl.dart index d5ebd3f0..c5bff608 100644 --- a/packages/wyatt_crud_bloc/lib/src/data/data_sources/crud_data_source_in_memory_impl.dart +++ b/packages/wyatt_crud_bloc/lib/src/data/data_sources/crud_data_source_in_memory_impl.dart @@ -16,6 +16,7 @@ import 'dart:async'; +import 'package:rxdart/subjects.dart'; import 'package:wyatt_crud_bloc/src/core/enums/operation_type.dart'; import 'package:wyatt_crud_bloc/src/core/enums/where_query_type.dart'; import 'package:wyatt_crud_bloc/src/data/data_sources/crud_data_source.dart'; @@ -58,8 +59,8 @@ class CrudDataSourceInMemoryImpl extends CrudDataSource { }) : _data = data ?? {}; final Map> _data; - final StreamController?>> _streamData = - StreamController(); + final BehaviorSubject?>> _streamData = + BehaviorSubject?>>.seeded([]); @override Future create(Map object, {String? id}) async { @@ -142,7 +143,7 @@ class CrudDataSourceInMemoryImpl extends CrudDataSource { } return res; - }).asBroadcastStream(); + }); @override Future update( diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/stream.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/streaming.dart similarity index 93% rename from packages/wyatt_crud_bloc/lib/src/domain/usecases/stream.dart rename to packages/wyatt_crud_bloc/lib/src/domain/usecases/streaming.dart index 68fcec8c..0a8184d6 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/usecases/stream.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/streaming.dart @@ -20,14 +20,14 @@ import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart'; import 'package:wyatt_type_utils/wyatt_type_utils.dart'; -/// {@template stream} +/// {@template streaming} /// A use case that streams the object models. /// {@endtemplate} -class Stream +class Streaming extends Usecase>> with ReadOperation>> { - /// {@macro stream} - const Stream(this.crudRepository); + /// {@macro streaming} + const Streaming(this.crudRepository); final CrudRepository crudRepository; diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/usecases.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/usecases.dart index cc0bc9d6..6f292edd 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/usecases/usecases.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/usecases.dart @@ -26,6 +26,7 @@ export 'get.dart'; export 'get_all.dart'; export 'params/params.dart'; export 'search.dart'; +export 'streaming.dart'; export 'update.dart'; export 'update_all.dart'; diff --git a/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_advanced_cubit.dart b/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_advanced_cubit.dart index 3f2d3bda..8c6fe57f 100644 --- a/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_advanced_cubit.dart +++ b/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_advanced_cubit.dart @@ -16,6 +16,7 @@ import 'dart:async'; +import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_crud_bloc/src/core/enums/where_query_type.dart'; import 'package:wyatt_crud_bloc/src/core/model_identifier.dart'; import 'package:wyatt_crud_bloc/src/domain/entities/query.dart'; @@ -24,11 +25,14 @@ import 'package:wyatt_crud_bloc/src/domain/usecases/delete.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/delete_all.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/get.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/get_all.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/params/stream_parameters.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/params/update_parameters.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/search.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/streaming.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/update.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/update_all.dart'; import 'package:wyatt_crud_bloc/src/features/crud/blocs/crud_base_cubit/crud_base_cubit.dart'; +import 'package:wyatt_type_utils/wyatt_type_utils.dart'; /// {@template crud_cubit_advanced} /// Cubit that handles CRUD operations with more granularity. @@ -43,6 +47,7 @@ abstract class CrudAdvancedCubit extends CrudBaseCubit { GetAll? get crudGetAll; Get? get crudGet; Search? get crudSearch; + Streaming? get crudStreaming; UpdateAll? get crudUpdateAll; Update? get crudUpdate; @@ -50,6 +55,8 @@ abstract class CrudAdvancedCubit extends CrudBaseCubit { /// Used to identify a model. ModelIdentifier get modelIdentifier; + StreamSubscription, AppException>>? _streamSubscription; + FutureOr create(Model model) async { final crud = crudCreate; if (crud == null) { @@ -59,6 +66,10 @@ abstract class CrudAdvancedCubit extends CrudBaseCubit { final stateCopy = state; emit(const CrudCreating()); final result = await crud.call(model); + if (crudStreaming != null && _streamSubscription != null && result.isOk) { + // If streaming is available, we don't need to update stateCopy. + return; + } emit( result.fold( (_) { @@ -97,6 +108,10 @@ abstract class CrudAdvancedCubit extends CrudBaseCubit { final stateCopy = state; emit(const CrudDeleting()); final result = await crud.call(id); + if (crudStreaming != null && _streamSubscription != null && result.isOk) { + // If streaming is available, we don't need to update stateCopy. + return; + } emit( result.fold( (_) { @@ -139,6 +154,10 @@ abstract class CrudAdvancedCubit extends CrudBaseCubit { final stateCopy = state; emit(const CrudDeleting()); final result = await crud.call(null); + if (crudStreaming != null && _streamSubscription != null && result.isOk) { + // If streaming is available, we don't need to update stateCopy. + return; + } emit( result.fold( (_) { @@ -202,6 +221,31 @@ abstract class CrudAdvancedCubit extends CrudBaseCubit { ); } + FutureOr streaming({ + String? id, + List? conditions, + }) async { + final crud = crudStreaming; + if (crud == null) { + return; + } + final result = await crud.call( + StreamParameters( + id: id, + conditions: conditions, + ), + ); + + _streamSubscription = result.ok?.listen((event) { + emit( + event.fold( + CrudListLoaded.new, + (error) => CrudError(error.toString()), + ), + ); + }); + } + FutureOr update(UpdateParameters param) async { final crud = crudUpdate; if (crud == null) { @@ -211,6 +255,10 @@ abstract class CrudAdvancedCubit extends CrudBaseCubit { final stateCopy = state; emit(const CrudUpdating()); final result = await crud.call(param); + if (crudStreaming != null && _streamSubscription != null && result.isOk) { + // If streaming is available, we don't need to update stateCopy. + return; + } emit( await result.foldAsync( (_) async { @@ -284,6 +332,10 @@ abstract class CrudAdvancedCubit extends CrudBaseCubit { final stateCopy = state; emit(const CrudUpdating()); final result = await crud.call(param); + if (crudStreaming != null && _streamSubscription != null && result.isOk) { + // If streaming is available, we don't need to update stateCopy. + return; + } emit( await result.foldAsync( (_) async { @@ -334,4 +386,10 @@ abstract class CrudAdvancedCubit extends CrudBaseCubit { ), ); } + + @override + Future close() async { + await _streamSubscription?.cancel(); + return super.close(); + } } diff --git a/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_cubit.dart b/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_cubit.dart index 80c8b19f..6495abba 100644 --- a/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_cubit.dart +++ b/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_cubit.dart @@ -16,6 +16,7 @@ import 'dart:async'; +import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_crud_bloc/src/core/enums/where_query_type.dart'; import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart'; import 'package:wyatt_crud_bloc/src/core/model_identifier.dart'; @@ -25,11 +26,14 @@ import 'package:wyatt_crud_bloc/src/domain/usecases/delete.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/delete_all.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/get.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/get_all.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/params/stream_parameters.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/params/update_parameters.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/search.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/streaming.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/update.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/update_all.dart'; import 'package:wyatt_crud_bloc/src/features/crud/blocs/crud_base_cubit/crud_base_cubit.dart'; +import 'package:wyatt_type_utils/wyatt_type_utils.dart'; typedef DefaultCreate = CreateOperation; typedef DefaultRead = ReadOperation; @@ -63,6 +67,8 @@ abstract class CrudCubit extends CrudBaseCubit { /// Used to identify a model. ModelIdentifier get modelIdentifier; + StreamSubscription, AppException>>? _streamSubscription; + Expected? _checkOperation(dynamic operation) { if (operation == null) { return null; @@ -90,9 +96,11 @@ abstract class CrudCubit extends CrudBaseCubit { conditions != null) { return _search(conditions); } - if (_checkOperation>(readOperation) != null && - conditions == null) { - return _getAll(); + if (_checkOperation>(readOperation) != null) { + return _streaming( + id: id, + conditions: conditions, + ); } } @@ -129,6 +137,11 @@ abstract class CrudCubit extends CrudBaseCubit { final stateCopy = state; emit(const CrudCreating()); final result = await crud.call(model); + final crudStreaming = _checkOperation>(readOperation); + if (crudStreaming != null && _streamSubscription != null && result.isOk) { + // If streaming is available, we don't need to update stateCopy. + return; + } emit( result.fold( (_) { @@ -167,6 +180,11 @@ abstract class CrudCubit extends CrudBaseCubit { final stateCopy = state; emit(const CrudDeleting()); final result = await crud.call(id); + final crudStreaming = _checkOperation>(readOperation); + if (crudStreaming != null && _streamSubscription != null && result.isOk) { + // If streaming is available, we don't need to update stateCopy. + return; + } emit( result.fold( (_) { @@ -209,6 +227,11 @@ abstract class CrudCubit extends CrudBaseCubit { final stateCopy = state; emit(const CrudDeleting()); final result = await crud.call(null); + final crudStreaming = _checkOperation>(readOperation); + if (crudStreaming != null && _streamSubscription != null && result.isOk) { + // If streaming is available, we don't need to update stateCopy. + return; + } emit( result.fold( (_) { @@ -256,6 +279,31 @@ abstract class CrudCubit extends CrudBaseCubit { ); } + FutureOr _streaming({ + String? id, + List? conditions, + }) async { + final crud = _checkOperation>(readOperation); + if (crud == null) { + return; + } + final result = await crud.call( + StreamParameters( + id: id, + conditions: conditions, + ), + ); + + _streamSubscription = result.ok?.listen((event) { + emit( + event.fold( + CrudListLoaded.new, + (error) => CrudError(error.toString()), + ), + ); + }); + } + FutureOr _search(List conditions) async { final crud = _checkOperation>(readOperation); if (crud == null) { @@ -281,6 +329,11 @@ abstract class CrudCubit extends CrudBaseCubit { final stateCopy = state; emit(const CrudUpdating()); final result = await crud.call(param); + final crudStreaming = _checkOperation>(readOperation); + if (crudStreaming != null && _streamSubscription != null && result.isOk) { + // If streaming is available, we don't need to update stateCopy. + return; + } emit( await result.foldAsync( (_) async { @@ -360,6 +413,11 @@ abstract class CrudCubit extends CrudBaseCubit { final stateCopy = state; emit(const CrudUpdating()); final result = await crud.call(param); + final crudStreaming = _checkOperation>(readOperation); + if (crudStreaming != null && _streamSubscription != null && result.isOk) { + // If streaming is available, we don't need to update stateCopy. + return; + } emit( await result.foldAsync( (_) async { @@ -410,4 +468,10 @@ abstract class CrudCubit extends CrudBaseCubit { ), ); } + + @override + Future close() async { + await _streamSubscription?.cancel(); + return super.close(); + } } diff --git a/packages/wyatt_crud_bloc/pubspec.yaml b/packages/wyatt_crud_bloc/pubspec.yaml index 6f0174ae..cd9ec7eb 100644 --- a/packages/wyatt_crud_bloc/pubspec.yaml +++ b/packages/wyatt_crud_bloc/pubspec.yaml @@ -21,6 +21,7 @@ dependencies: wyatt_type_utils: hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ version: ^0.0.5 + rxdart: ^0.27.7 dev_dependencies: flutter_test: { sdk: flutter } -- 2.47.2 From 12568b3ada150343f341c5d31765a8a1f156f26b Mon Sep 17 00:00:00 2001 From: Hugo Pointcheval Date: Tue, 14 Nov 2023 14:42:16 +0100 Subject: [PATCH 7/9] feat(crud)!: make crudbuilder integration more easy by integrating blocbuilder (closes #181) --- .../example/lib/advanced_cubit_view.dart | 156 ++++++++---------- .../example/lib/basic_cubit_view.dart | 135 +++++++-------- .../example/lib/streaming_cubit_view.dart | 110 ++++++------ .../features/crud/builder/crud_builder.dart | 148 ++++++++++++----- 4 files changed, 294 insertions(+), 255 deletions(-) diff --git a/packages/wyatt_crud_bloc/example/lib/advanced_cubit_view.dart b/packages/wyatt_crud_bloc/example/lib/advanced_cubit_view.dart index 9671663e..f6bc82fd 100644 --- a/packages/wyatt_crud_bloc/example/lib/advanced_cubit_view.dart +++ b/packages/wyatt_crud_bloc/example/lib/advanced_cubit_view.dart @@ -35,91 +35,81 @@ class AdvancedCubitView extends StatelessWidget { create: (context) => UserAdvancedCubit(context.read>()) ..streaming(), - child: Builder(builder: (context) { - return Column( - children: [ - BlocBuilder( - buildWhen: (previous, current) { - if (current is CrudLoading && current is! CrudReading) { - return false; - } - return true; - }, - builder: (context, state) { - return Expanded( - child: CrudBuilder.typed>( - state: state, - builder: ((context, state) { - return ListView.builder( - itemCount: state.data.length, - itemBuilder: (context, index) { - final user = state.data.elementAt(index); - return ListTile( - title: Text(user?.name ?? 'Error'), - subtitle: Text(user?.email ?? 'Error'), - onTap: () { - context - .read() - .delete((user?.id)!); - }, - onLongPress: () { - context.read().update( - UpdateParameters( - id: user?.id ?? '', - raw: { - 'email': '${user?.id}@updated.io', - }), - ); - }, - ); - }, - ); - }), - initialBuilder: (context, state) => - const Center(child: CircularProgressIndicator()), - loadingBuilder: (context, state) => - const Center(child: CircularProgressIndicator()), - errorBuilder: (context, state) => Text("Error: $state"), - ), - ); - }, - ), - const SizedBox(height: 20), - ElevatedButton( - onPressed: () { - final r = Random().nextInt(1000); - context.read().create( - User( - id: '$r', - name: 'Wyatt $r', - email: '$r@wyattapp.io', - phone: '06$r', - ), + child: Builder( + builder: (context) { + return Column( + children: [ + Expanded( + child: + CrudBuilder.typed>( + buildWhen: (previous, current) { + if (current is CrudLoading && current is! CrudReading) { + return false; + } + return true; + }, + builder: ((context, state) { + return ListView.builder( + itemCount: state.data.length, + itemBuilder: (context, index) { + final user = state.data.elementAt(index); + return ListTile( + title: Text(user?.name ?? 'Error'), + subtitle: Text(user?.email ?? 'Error'), + onTap: () { + context.read().delete((user?.id)!); + }, + onLongPress: () { + context.read().update( + UpdateParameters(id: user?.id ?? '', raw: { + 'email': '${user?.id}@updated.io', + }), + ); + }, + ); + }, ); - }, - child: BlocBuilder( - buildWhen: (previous, current) { - if (current is CrudLoading && current is! CrudCreating) { - return false; - } - return true; - }, - builder: (context, state) { - return state is CrudCreating - ? const SizedBox( - width: 20, - height: 20, - child: CircularProgressIndicator( - color: Colors.white, - ), - ) - : const Text("Create"); - }, + }), + initialBuilder: (context, state) => + const Center(child: CircularProgressIndicator()), + loadingBuilder: (context, state) => + const Center(child: CircularProgressIndicator()), + errorBuilder: (context, state) => Text("Error: $state"), + ), ), - ), - ], - ); - }), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () { + final r = Random().nextInt(1000); + context.read().create( + User( + id: '$r', + name: 'Wyatt $r', + email: '$r@wyattapp.io', + phone: '06$r', + ), + ); + }, + child: CrudBuilder.onLoading( + builder: (context, state) { + if (state is CrudCreating) { + return const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + color: Colors.white, + ), + ); + } + return null; + }, + otherBuilder: (context, state) => const Text("Create"), + ), + ), + ], + ); + } + ), ), ); } diff --git a/packages/wyatt_crud_bloc/example/lib/basic_cubit_view.dart b/packages/wyatt_crud_bloc/example/lib/basic_cubit_view.dart index 5f2ee88b..cb9759af 100644 --- a/packages/wyatt_crud_bloc/example/lib/basic_cubit_view.dart +++ b/packages/wyatt_crud_bloc/example/lib/basic_cubit_view.dart @@ -37,51 +37,44 @@ class BasicCubitView extends StatelessWidget { child: Builder(builder: (context) { return Column( children: [ - BlocBuilder( - buildWhen: (previous, current) { - if (current is CrudLoading && current is! CrudReading) { - return false; - } - return true; - }, - builder: (context, state) { - return Expanded( - child: CrudBuilder.typed>( - state: state, - builder: ((context, state) { - return ListView.builder( - itemCount: state.data.length, - itemBuilder: (context, index) { - final user = state.data.elementAt(index); - return ListTile( - title: Text(user?.name ?? 'Error'), - subtitle: Text(user?.email ?? 'Error'), - onTap: () { - context - .read() - .delete(id: (user?.id)!); - }, - onLongPress: () { - context.read().update( - single: UpdateParameters( - id: user?.id ?? '', - raw: { - 'email': '${user?.id}@updated.io', - }), - ); - }, - ); + Expanded( + child: CrudBuilder.typed>( + buildWhen: (previous, current) { + if (current is CrudLoading && current is! CrudReading) { + return false; + } + return true; + }, + builder: ((context, state) { + return ListView.builder( + itemCount: state.data.length, + itemBuilder: (context, index) { + final user = state.data.elementAt(index); + return ListTile( + title: Text(user?.name ?? 'Error'), + subtitle: Text(user?.email ?? 'Error'), + onTap: () { + context.read().delete(id: (user?.id)!); + }, + onLongPress: () { + context.read().update( + single: UpdateParameters( + id: user?.id ?? '', + raw: { + 'email': '${user?.id}@updated.io', + }), + ); }, ); - }), - initialBuilder: (context, state) => - const Center(child: CircularProgressIndicator()), - loadingBuilder: (context, state) => - const Center(child: CircularProgressIndicator()), - errorBuilder: (context, state) => Text("Error: $state"), - ), - ); - }, + }, + ); + }), + initialBuilder: (context, state) => + const Center(child: CircularProgressIndicator()), + loadingBuilder: (context, state) => + const Center(child: CircularProgressIndicator()), + errorBuilder: (context, state) => Text("Error: $state"), + ), ), const SizedBox(height: 20), ElevatedButton( @@ -96,48 +89,40 @@ class BasicCubitView extends StatelessWidget { ), ); }, - child: BlocBuilder( - buildWhen: (previous, current) { - if (current is CrudLoading && current is! CrudCreating) { - return false; - } - return true; - }, + child: CrudBuilder.onLoading( builder: (context, state) { - return state is CrudCreating - ? const SizedBox( - width: 20, - height: 20, - child: CircularProgressIndicator( - color: Colors.white, - ), - ) - : const Text("Create"); + if (state is CrudCreating) { + return const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + color: Colors.white, + ), + ); + } + return null; }, + otherBuilder: (context, state) => const Text("Create"), ), ), ElevatedButton( onPressed: () { context.read().read(); }, - child: BlocBuilder( - buildWhen: (previous, current) { - if (current is CrudLoading && current is! CrudReading) { - return false; - } - return true; - }, + child: CrudBuilder.onLoading( builder: (context, state) { - return state is CrudReading - ? const SizedBox( - width: 20, - height: 20, - child: CircularProgressIndicator( - color: Colors.white, - ), - ) - : const Text("Read"); + if (state is CrudReading) { + return const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + color: Colors.white, + ), + ); + } + return null; }, + otherBuilder: (context, state) => const Text("Read"), ), ), const SizedBox(height: 20), diff --git a/packages/wyatt_crud_bloc/example/lib/streaming_cubit_view.dart b/packages/wyatt_crud_bloc/example/lib/streaming_cubit_view.dart index 8f1df40d..e6f93d92 100644 --- a/packages/wyatt_crud_bloc/example/lib/streaming_cubit_view.dart +++ b/packages/wyatt_crud_bloc/example/lib/streaming_cubit_view.dart @@ -37,51 +37,47 @@ class StreamingCubitView extends StatelessWidget { child: Builder(builder: (context) { return Column( children: [ - BlocBuilder( - buildWhen: (previous, current) { - if (current is CrudLoading && current is! CrudReading) { - return false; - } - return true; - }, - builder: (context, state) { - return Expanded( - child: CrudBuilder.typed>( - state: state, - builder: ((context, state) { - return ListView.builder( - itemCount: state.data.length, - itemBuilder: (context, index) { - final user = state.data.elementAt(index); - return ListTile( - title: Text(user?.name ?? 'Error'), - subtitle: Text(user?.email ?? 'Error'), - onTap: () { - context - .read() - .delete(id: (user?.id)!); - }, - onLongPress: () { - context.read().update( - single: UpdateParameters( - id: user?.id ?? '', - raw: { - 'email': '${user?.id}@updated.io', - }), - ); - }, - ); + Expanded( + child: CrudBuilder.typed>( + buildWhen: (previous, current) { + if (current is CrudLoading && current is! CrudReading) { + return false; + } + return true; + }, + builder: ((context, state) { + return ListView.builder( + itemCount: state.data.length, + itemBuilder: (context, index) { + final user = state.data.elementAt(index); + return ListTile( + title: Text(user?.name ?? 'Error'), + subtitle: Text(user?.email ?? 'Error'), + onTap: () { + context + .read() + .delete(id: (user?.id)!); + }, + onLongPress: () { + context.read().update( + single: UpdateParameters( + id: user?.id ?? '', + raw: { + 'email': '${user?.id}@updated.io', + }), + ); }, ); - }), - initialBuilder: (context, state) => - const Center(child: CircularProgressIndicator()), - loadingBuilder: (context, state) => - const Center(child: CircularProgressIndicator()), - errorBuilder: (context, state) => Text("Error: $state"), - ), - ); - }, + }, + ); + }), + initialBuilder: (context, state) => + const Center(child: CircularProgressIndicator()), + loadingBuilder: (context, state) => + const Center(child: CircularProgressIndicator()), + errorBuilder: (context, state) => Text("Error: $state"), + ), ), const SizedBox(height: 20), ElevatedButton( @@ -96,24 +92,20 @@ class StreamingCubitView extends StatelessWidget { ), ); }, - child: BlocBuilder( - buildWhen: (previous, current) { - if (current is CrudLoading && current is! CrudCreating) { - return false; - } - return true; - }, + child: CrudBuilder.onLoading( builder: (context, state) { - return state is CrudCreating - ? const SizedBox( - width: 20, - height: 20, - child: CircularProgressIndicator( - color: Colors.white, - ), - ) - : const Text("Create"); + if (state is CrudCreating) { + return const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + color: Colors.white, + ), + ); + } + return null; }, + otherBuilder: (context, state) => const Text("Create"), ), ), ], diff --git a/packages/wyatt_crud_bloc/lib/src/features/crud/builder/crud_builder.dart b/packages/wyatt_crud_bloc/lib/src/features/crud/builder/crud_builder.dart index d864ce7a..5789d599 100644 --- a/packages/wyatt_crud_bloc/lib/src/features/crud/builder/crud_builder.dart +++ b/packages/wyatt_crud_bloc/lib/src/features/crud/builder/crud_builder.dart @@ -15,26 +15,27 @@ // along with this program. If not, see . import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:wyatt_crud_bloc/src/features/crud/blocs/crud_base_cubit/crud_base_cubit.dart'; /// {@template crud_builder} /// A widget that builds itself based on the latest snapshot of interaction /// with a [CrudBaseCubit]. -/// -/// * I = Initial State -/// * L = Loading State -/// * S = Success State -/// * E = Error State /// {@endtemplate} -class CrudBuilder extends StatelessWidget { +class CrudBuilder< + Bloc extends StateStreamable, + Initial extends CrudState, + Loading extends CrudState, + Success extends CrudState, + Error extends CrudState> extends StatelessWidget { /// {@macro crud_builder} const CrudBuilder({ - required this.state, required this.builder, required this.initialBuilder, required this.loadingBuilder, required this.errorBuilder, this.unknownBuilder, + this.buildWhen, super.key, }); @@ -43,50 +44,121 @@ class CrudBuilder extends StatelessWidget { /// This factory constructor is used to create a [CrudBuilder] with /// [CrudState]s. `S` is the Success State, and it must be a subtype of /// [CrudSuccess]. It the only type that you have to specify. - static CrudBuilder - typed({ - required CrudState state, - required Widget Function(BuildContext, S) builder, + static CrudBuilder + typed, + Success extends CrudSuccess>({ + required Widget Function(BuildContext, Success) builder, required Widget Function(BuildContext, CrudInitial) initialBuilder, required Widget Function(BuildContext, CrudLoading) loadingBuilder, required Widget Function(BuildContext, CrudError) errorBuilder, - Widget Function(BuildContext, Object)? unknownBuilder, + Widget Function(BuildContext, CrudState)? unknownBuilder, + BlocBuilderCondition? buildWhen, }) => - CrudBuilder( - state: state, + CrudBuilder( builder: builder, initialBuilder: initialBuilder, loadingBuilder: loadingBuilder, errorBuilder: errorBuilder, unknownBuilder: unknownBuilder, + buildWhen: buildWhen, ); - final Object state; - final Widget Function(BuildContext context, S state) builder; - final Widget Function(BuildContext context, I state) initialBuilder; - final Widget Function(BuildContext context, L state) loadingBuilder; - final Widget Function(BuildContext context, E state) errorBuilder; - final Widget Function(BuildContext context, Object state)? unknownBuilder; + /// {@macro crud_builder} + /// + /// This factory constructor is used to create a [CrudBuilder] wich reacts + /// only to [CrudLoading] states. + static CrudBuilder + onLoading>({ + required Widget? Function(BuildContext, CrudLoading) builder, + Widget Function(BuildContext, CrudState)? otherBuilder, + BlocBuilderCondition? buildWhen, + }) => + CrudBuilder( + loadingBuilder: (context, state) => + builder.call(context, state) ?? + otherBuilder?.call(context, state) ?? + const SizedBox.shrink(), + builder: (context, state) => + otherBuilder?.call(context, state) ?? const SizedBox.shrink(), + initialBuilder: (context, state) => + otherBuilder?.call(context, state) ?? const SizedBox.shrink(), + errorBuilder: (context, state) => + otherBuilder?.call(context, state) ?? const SizedBox.shrink(), + unknownBuilder: otherBuilder, + buildWhen: buildWhen, + ); + + /// {@macro crud_builder} + /// + /// This factory constructor is used to create a [CrudBuilder] wich reacts + /// only to [CrudInitial] states. + static CrudBuilder + onInitial>({ + required Widget? Function(BuildContext, CrudInitial) builder, + Widget Function(BuildContext, CrudState)? otherBuilder, + BlocBuilderCondition? buildWhen, + }) => + CrudBuilder( + initialBuilder: (context, state) => + builder.call(context, state) ?? + otherBuilder?.call(context, state) ?? + const SizedBox.shrink(), + builder: (context, state) => + otherBuilder?.call(context, state) ?? const SizedBox.shrink(), + loadingBuilder: (context, state) => + otherBuilder?.call(context, state) ?? const SizedBox.shrink(), + errorBuilder: (context, state) => + otherBuilder?.call(context, state) ?? const SizedBox.shrink(), + unknownBuilder: otherBuilder, + buildWhen: buildWhen, + ); + + /// {@macro crud_builder} + /// + /// This factory constructor is used to create a [CrudBuilder] wich reacts + /// only to [CrudError] states. + static CrudBuilder + onError>({ + required Widget? Function(BuildContext, CrudError) builder, + Widget Function(BuildContext, CrudState)? otherBuilder, + BlocBuilderCondition? buildWhen, + }) => + CrudBuilder( + errorBuilder: (context, state) => + builder.call(context, state) ?? + otherBuilder?.call(context, state) ?? + const SizedBox.shrink(), + builder: (context, state) => + otherBuilder?.call(context, state) ?? const SizedBox.shrink(), + loadingBuilder: (context, state) => + otherBuilder?.call(context, state) ?? const SizedBox.shrink(), + initialBuilder: (context, state) => + otherBuilder?.call(context, state) ?? const SizedBox.shrink(), + unknownBuilder: otherBuilder, + buildWhen: buildWhen, + ); + + final BlocBuilderCondition? buildWhen; + final Widget Function(BuildContext context, Success state) builder; + final Widget Function(BuildContext context, Initial state) initialBuilder; + final Widget Function(BuildContext context, Loading state) loadingBuilder; + final Widget Function(BuildContext context, Error state) errorBuilder; + final Widget Function(BuildContext context, CrudState state)? unknownBuilder; @override - Widget build(BuildContext context) => Builder( - builder: (context) { - if (state is S) { - return builder(context, state as S); - } else if (state is E) { - return errorBuilder(context, state as E); - } else if (state is L) { - return loadingBuilder(context, state as L); - } else if (state is I) { - return initialBuilder(context, state as I); - } else { - return unknownBuilder?.call(context, state) ?? - Center( - child: Text( - 'Unknown state: $state', - ), - ); - } + Widget build(BuildContext context) => BlocBuilder( + buildWhen: buildWhen, + builder: (context, state) => switch (state) { + Success() => builder(context, state), + Initial() => initialBuilder(context, state), + Loading() => loadingBuilder(context, state), + Error() => errorBuilder(context, state), + _ => unknownBuilder?.call(context, state) ?? + Center( + child: Text( + 'Unknown state: $state', + ), + ), }, ); } -- 2.47.2 From 088d4bb1841bbd7f7a919ad94d84a4c0abdb99a3 Mon Sep 17 00:00:00 2001 From: Hugo Pointcheval Date: Tue, 14 Nov 2023 14:47:49 +0100 Subject: [PATCH 8/9] fix(bloc_layout): using new crud_builder --- .../lib/src/core/crud_cubit_consumer_screen_mixin.dart | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/wyatt_bloc_layout/lib/src/core/crud_cubit_consumer_screen_mixin.dart b/packages/wyatt_bloc_layout/lib/src/core/crud_cubit_consumer_screen_mixin.dart index a549af5b..b5798454 100644 --- a/packages/wyatt_bloc_layout/lib/src/core/crud_cubit_consumer_screen_mixin.dart +++ b/packages/wyatt_bloc_layout/lib/src/core/crud_cubit_consumer_screen_mixin.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify @@ -16,11 +16,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart' as bloc_base; - import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; import 'package:wyatt_ui_components/wyatt_ui_components.dart'; -mixin CrudMixin, +mixin CrudMixin, SuccessState extends CrudSuccess> { String? get loaderComponentId => null; String? get errorComponentId => null; @@ -40,11 +39,10 @@ mixin CrudMixin, Widget successBuilder(BuildContext context, SuccessState state); Widget crudBuilder(BuildContext context, CrudState state) => - CrudBuilder( + CrudBuilder( errorBuilder: errorBuilder, loadingBuilder: loadingBuilder, initialBuilder: initialBuilder, - state: state, builder: successBuilder, ); } -- 2.47.2 From 31350762c51aec8e5dc5361d567207c06c79ba39 Mon Sep 17 00:00:00 2001 From: Hugo Pointcheval Date: Tue, 14 Nov 2023 14:49:46 +0100 Subject: [PATCH 9/9] chore(release): publish packages - wyatt_crud_bloc@0.2.0 - wyatt_crud_bloc_firestore@0.2.0 - wyatt_bloc_layout@0.1.2+4 --- CHANGELOG.md | 41 +++++++++++++++++++ packages/wyatt_bloc_layout/CHANGELOG.md | 4 ++ .../wyatt_bloc_layout/example/pubspec.yaml | 2 +- packages/wyatt_bloc_layout/pubspec.yaml | 4 +- packages/wyatt_crud_bloc/CHANGELOG.md | 13 ++++++ packages/wyatt_crud_bloc/pubspec.yaml | 2 +- .../wyatt_crud_bloc_firestore/CHANGELOG.md | 8 ++++ .../wyatt_crud_bloc_firestore/pubspec.yaml | 4 +- 8 files changed, 72 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09a90c3e..c9a9c1d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,47 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## 2023-11-14 + +### Changes + +--- + +Packages with breaking changes: + + - [`wyatt_crud_bloc` - `v0.2.0`](#wyatt_crud_bloc---v020) + - [`wyatt_crud_bloc_firestore` - `v0.2.0`](#wyatt_crud_bloc_firestore---v020) + +Packages with other changes: + + - [`wyatt_bloc_layout` - `v0.1.2+4`](#wyatt_bloc_layout---v0124) + +Packages with dependency updates only: + +> Packages listed below depend on other packages in this workspace that have had changes. Their versions have been incremented to bump the minimum dependency versions of the packages they depend upon in this project. + + - `wyatt_bloc_layout` - `v0.1.2+4` + +--- + +#### `wyatt_crud_bloc` - `v0.2.0` + + - **REFACTOR**: make CrudLoading instanciable. + - **FIX**: rename wyatt_bruc_bloc_firestore main package file. + - **FIX**: apply dart format. + - **FIX**: apply dart fix --apply. + - **FEAT**(crud): add streaming usecase (closes #180). + - **DOCS**(crud): update readme. + - **BREAKING** **FEAT**(crud): make crudbuilder integration more easy by integrating blocbuilder (closes #181). + - **BREAKING** **FEAT**(crud): move crud firestore implementation into his own package. + +#### `wyatt_crud_bloc_firestore` - `v0.2.0` + + - **FIX**: rename wyatt_bruc_bloc_firestore main package file. + - **DOCS**(crud): update readme. + - **BREAKING** **FEAT**(crud): move crud firestore implementation into his own package. + + ## 2023-10-04 ### Changes diff --git a/packages/wyatt_bloc_layout/CHANGELOG.md b/packages/wyatt_bloc_layout/CHANGELOG.md index 95ead937..b04ce841 100644 --- a/packages/wyatt_bloc_layout/CHANGELOG.md +++ b/packages/wyatt_bloc_layout/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.2+4 + + - Update a dependency to the latest release. + ## 0.1.2+3 - Update a dependency to the latest release. diff --git a/packages/wyatt_bloc_layout/example/pubspec.yaml b/packages/wyatt_bloc_layout/example/pubspec.yaml index 561efbaa..2ec7576e 100644 --- a/packages/wyatt_bloc_layout/example/pubspec.yaml +++ b/packages/wyatt_bloc_layout/example/pubspec.yaml @@ -42,7 +42,7 @@ dependencies: version: ^0.1.2+3 wyatt_crud_bloc: hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub - version: ^0.1.1+1 + version: ^0.2.0 wyatt_ui_components: hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub version: ^0.3.0+2 diff --git a/packages/wyatt_bloc_layout/pubspec.yaml b/packages/wyatt_bloc_layout/pubspec.yaml index 002ff776..7488bd3a 100644 --- a/packages/wyatt_bloc_layout/pubspec.yaml +++ b/packages/wyatt_bloc_layout/pubspec.yaml @@ -1,7 +1,7 @@ name: wyatt_bloc_layout description: Layouts based on bloc helper library repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_bloc_layout -version: 0.1.2+3 +version: 0.1.2+4 publish_to: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub @@ -23,7 +23,7 @@ dependencies: wyatt_crud_bloc: hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub - version: ^0.1.1+1 + version: ^0.2.0 wyatt_ui_components: hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub diff --git a/packages/wyatt_crud_bloc/CHANGELOG.md b/packages/wyatt_crud_bloc/CHANGELOG.md index 4cea9759..020f78cf 100644 --- a/packages/wyatt_crud_bloc/CHANGELOG.md +++ b/packages/wyatt_crud_bloc/CHANGELOG.md @@ -1,3 +1,16 @@ +## 0.2.0 + +> Note: This release has breaking changes. + + - **REFACTOR**: make CrudLoading instanciable. + - **FIX**: rename wyatt_bruc_bloc_firestore main package file. + - **FIX**: apply dart format. + - **FIX**: apply dart fix --apply. + - **FEAT**(crud): add streaming usecase (closes #180). + - **DOCS**(crud): update readme. + - **BREAKING** **FEAT**(crud): make crudbuilder integration more easy by integrating blocbuilder (closes #181). + - **BREAKING** **FEAT**(crud): move crud firestore implementation into his own package. + ## 0.1.1+1 - **FIX**: apply dart format. diff --git a/packages/wyatt_crud_bloc/pubspec.yaml b/packages/wyatt_crud_bloc/pubspec.yaml index cd9ec7eb..c66385f2 100644 --- a/packages/wyatt_crud_bloc/pubspec.yaml +++ b/packages/wyatt_crud_bloc/pubspec.yaml @@ -1,7 +1,7 @@ name: wyatt_crud_bloc description: Create/Read/Update/Delete BLoC for Flutter repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_crud_bloc -version: 0.1.1+1 +version: 0.2.0 publish_to: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/CHANGELOG.md b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/CHANGELOG.md index 41cc7d81..c6517991 100644 --- a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/CHANGELOG.md +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.2.0 + +> Note: This release has breaking changes. + + - **FIX**: rename wyatt_bruc_bloc_firestore main package file. + - **DOCS**(crud): update readme. + - **BREAKING** **FEAT**(crud): move crud firestore implementation into his own package. + ## 0.0.1 * TODO: Describe initial release. diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/pubspec.yaml b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/pubspec.yaml index eb9dc7dc..aa1bac63 100644 --- a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/pubspec.yaml +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/pubspec.yaml @@ -1,7 +1,7 @@ name: wyatt_crud_bloc_firestore description: Create/Read/Update/Delete implementation for Cloud Firestore repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_crud_bloc -version: 0.1.1+1 +version: 0.2.0 publish_to: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub @@ -25,7 +25,7 @@ dependencies: wyatt_crud_bloc: hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ - version: ^0.1.1+1 + version: ^0.2.0 dev_dependencies: flutter_test: { sdk: flutter } -- 2.47.2