CRUD: move firestore implementation in his own package #231
							
								
								
									
										2
									
								
								packages/wyatt_crud_bloc/example/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						| @ -44,5 +44,3 @@ app.*.map.json | ||||
| /android/app/debug | ||||
| /android/app/profile | ||||
| /android/app/release | ||||
| 
 | ||||
| /lib/firebase_options.dart | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
| @ -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 {} | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     package="com.example.crud_bloc_example"> | ||||
|     <!-- Flutter needs it to communicate with the running application | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <!-- The INTERNET permission is required for development. Specifically, | ||||
|          the Flutter tool needs it to communicate with the running application | ||||
|          to allow setting breakpoints, to provide hot reload, etc. | ||||
|     --> | ||||
|     <uses-permission android:name="android.permission.INTERNET"/> | ||||
|  | ||||
| @ -1,7 +1,6 @@ | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     package="com.example.crud_bloc_example"> | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <application | ||||
|         android:label="crud_bloc_example" | ||||
|         android:label="example" | ||||
|         android:name="${applicationName}" | ||||
|         android:icon="@mipmap/ic_launcher"> | ||||
|         <activity | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| package com.example.crud_bloc_example | ||||
| package com.example.example | ||||
| 
 | ||||
| import io.flutter.embedding.android.FlutterActivity | ||||
| 
 | ||||
| @ -3,7 +3,7 @@ | ||||
|     <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on --> | ||||
|     <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar"> | ||||
|         <!-- Show a splash screen on the activity. Automatically removed when | ||||
|              Flutter draws its first frame --> | ||||
|              the Flutter engine draws its first frame --> | ||||
|         <item name="android:windowBackground">@drawable/launch_background</item> | ||||
|     </style> | ||||
|     <!-- Theme applied to the Android Window as soon as the process has started. | ||||
|  | ||||
| @ -3,7 +3,7 @@ | ||||
|     <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off --> | ||||
|     <style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar"> | ||||
|         <!-- Show a splash screen on the activity. Automatically removed when | ||||
|              Flutter draws its first frame --> | ||||
|              the Flutter engine draws its first frame --> | ||||
|         <item name="android:windowBackground">@drawable/launch_background</item> | ||||
|     </style> | ||||
|     <!-- Theme applied to the Android Window as soon as the process has started. | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     package="com.example.crud_bloc_example"> | ||||
|     <!-- Flutter needs it to communicate with the running application | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <!-- The INTERNET permission is required for development. Specifically, | ||||
|          the Flutter tool needs it to communicate with the running application | ||||
|          to allow setting breakpoints, to provide hot reload, etc. | ||||
|     --> | ||||
|     <uses-permission android:name="android.permission.INTERNET"/> | ||||
|  | ||||
| @ -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 | ||||
| } | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -1,11 +1,20 @@ | ||||
| include ':app' | ||||
| 
 | ||||
| def localPropertiesFile = new File(rootProject.projectDir, "local.properties") | ||||
| pluginManagement { | ||||
|     def flutterSdkPath = { | ||||
|         def properties = new Properties() | ||||
| 
 | ||||
| assert localPropertiesFile.exists() | ||||
| localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } | ||||
| 
 | ||||
|         file("local.properties").withInputStream { properties.load(it) } | ||||
|         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" | ||||
|         return flutterSdkPath | ||||
|     } | ||||
|     settings.ext.flutterSdkPath = flutterSdkPath() | ||||
| 
 | ||||
|     includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") | ||||
| 
 | ||||
|     plugins { | ||||
|         id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| include ":app" | ||||
| 
 | ||||
| apply from: "${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle/app_plugin_loader.gradle" | ||||
|  | ||||
							
								
								
									
										34
									
								
								packages/wyatt_crud_bloc/example/ios/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						| @ -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 | ||||
| @ -1,26 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||||
| <plist version="1.0"> | ||||
| <dict> | ||||
|   <key>CFBundleDevelopmentRegion</key> | ||||
|   <string>en</string> | ||||
|   <key>CFBundleExecutable</key> | ||||
|   <string>App</string> | ||||
|   <key>CFBundleIdentifier</key> | ||||
|   <string>io.flutter.flutter.app</string> | ||||
|   <key>CFBundleInfoDictionaryVersion</key> | ||||
|   <string>6.0</string> | ||||
|   <key>CFBundleName</key> | ||||
|   <string>App</string> | ||||
|   <key>CFBundlePackageType</key> | ||||
|   <string>FMWK</string> | ||||
|   <key>CFBundleShortVersionString</key> | ||||
|   <string>1.0</string> | ||||
|   <key>CFBundleSignature</key> | ||||
|   <string>????</string> | ||||
|   <key>CFBundleVersion</key> | ||||
|   <string>1.0</string> | ||||
|   <key>MinimumOSVersion</key> | ||||
|   <string>11.0</string> | ||||
| </dict> | ||||
| </plist> | ||||
| @ -1,2 +0,0 @@ | ||||
| #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" | ||||
| #include "Generated.xcconfig" | ||||
| @ -1,2 +0,0 @@ | ||||
| #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" | ||||
| #include "Generated.xcconfig" | ||||
| @ -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 | ||||
| @ -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 | ||||
| @ -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 = "<group>"; }; | ||||
| 		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 = "<group>"; }; | ||||
| 		1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; | ||||
| 		1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; | ||||
| 		3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; | ||||
| 		74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; | ||||
| 		74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; | ||||
| 		7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; | ||||
| 		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 = "<group>"; }; | ||||
| 		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 = "<group>"; }; | ||||
| 		9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; }; | ||||
| 		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 = "<group>"; }; | ||||
| 		97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; | ||||
| 		97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; | ||||
| 		97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; | ||||
| /* 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 = "<group>"; | ||||
| 		}; | ||||
| 		9740EEB11CF90186004384FC /* Flutter */ = { | ||||
| 			isa = PBXGroup; | ||||
| 			children = ( | ||||
| 				3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, | ||||
| 				9740EEB21CF90195004384FC /* Debug.xcconfig */, | ||||
| 				7AFA3C8E1D35360C0083082E /* Release.xcconfig */, | ||||
| 				9740EEB31CF90195004384FC /* Generated.xcconfig */, | ||||
| 			); | ||||
| 			name = Flutter; | ||||
| 			sourceTree = "<group>"; | ||||
| 		}; | ||||
| 		97C146E51CF9000F007C117D = { | ||||
| 			isa = PBXGroup; | ||||
| 			children = ( | ||||
| 				9740EEB11CF90186004384FC /* Flutter */, | ||||
| 				97C146F01CF9000F007C117D /* Runner */, | ||||
| 				97C146EF1CF9000F007C117D /* Products */, | ||||
| 				32816CF134A5ECA965EE4EF3 /* Pods */, | ||||
| 				DF1EDFCBAB38011323A8D81B /* Frameworks */, | ||||
| 			); | ||||
| 			sourceTree = "<group>"; | ||||
| 		}; | ||||
| 		97C146EF1CF9000F007C117D /* Products */ = { | ||||
| 			isa = PBXGroup; | ||||
| 			children = ( | ||||
| 				97C146EE1CF9000F007C117D /* Runner.app */, | ||||
| 			); | ||||
| 			name = Products; | ||||
| 			sourceTree = "<group>"; | ||||
| 		}; | ||||
| 		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 = "<group>"; | ||||
| 		}; | ||||
| 		DF1EDFCBAB38011323A8D81B /* Frameworks */ = { | ||||
| 			isa = PBXGroup; | ||||
| 			children = ( | ||||
| 				9668B7DCB1C084B61D13F13B /* Pods_Runner.framework */, | ||||
| 			); | ||||
| 			name = Frameworks; | ||||
| 			sourceTree = "<group>"; | ||||
| 		}; | ||||
| /* 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 = "<group>"; | ||||
| 		}; | ||||
| 		97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { | ||||
| 			isa = PBXVariantGroup; | ||||
| 			children = ( | ||||
| 				97C147001CF9000F007C117D /* Base */, | ||||
| 			); | ||||
| 			name = LaunchScreen.storyboard; | ||||
| 			sourceTree = "<group>"; | ||||
| 		}; | ||||
| /* 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 */; | ||||
| } | ||||
| @ -1,7 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <Workspace | ||||
|    version = "1.0"> | ||||
|    <FileRef | ||||
|       location = "self:"> | ||||
|    </FileRef> | ||||
| </Workspace> | ||||
| @ -1,8 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||||
| <plist version="1.0"> | ||||
| <dict> | ||||
| 	<key>IDEDidComputeMac32BitWarning</key> | ||||
| 	<true/> | ||||
| </dict> | ||||
| </plist> | ||||
| @ -1,87 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <Scheme | ||||
|    LastUpgradeVersion = "1300" | ||||
|    version = "1.3"> | ||||
|    <BuildAction | ||||
|       parallelizeBuildables = "YES" | ||||
|       buildImplicitDependencies = "YES"> | ||||
|       <BuildActionEntries> | ||||
|          <BuildActionEntry | ||||
|             buildForTesting = "YES" | ||||
|             buildForRunning = "YES" | ||||
|             buildForProfiling = "YES" | ||||
|             buildForArchiving = "YES" | ||||
|             buildForAnalyzing = "YES"> | ||||
|             <BuildableReference | ||||
|                BuildableIdentifier = "primary" | ||||
|                BlueprintIdentifier = "97C146ED1CF9000F007C117D" | ||||
|                BuildableName = "Runner.app" | ||||
|                BlueprintName = "Runner" | ||||
|                ReferencedContainer = "container:Runner.xcodeproj"> | ||||
|             </BuildableReference> | ||||
|          </BuildActionEntry> | ||||
|       </BuildActionEntries> | ||||
|    </BuildAction> | ||||
|    <TestAction | ||||
|       buildConfiguration = "Debug" | ||||
|       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||||
|       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||||
|       shouldUseLaunchSchemeArgsEnv = "YES"> | ||||
|       <MacroExpansion> | ||||
|          <BuildableReference | ||||
|             BuildableIdentifier = "primary" | ||||
|             BlueprintIdentifier = "97C146ED1CF9000F007C117D" | ||||
|             BuildableName = "Runner.app" | ||||
|             BlueprintName = "Runner" | ||||
|             ReferencedContainer = "container:Runner.xcodeproj"> | ||||
|          </BuildableReference> | ||||
|       </MacroExpansion> | ||||
|       <Testables> | ||||
|       </Testables> | ||||
|    </TestAction> | ||||
|    <LaunchAction | ||||
|       buildConfiguration = "Debug" | ||||
|       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||||
|       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||||
|       launchStyle = "0" | ||||
|       useCustomWorkingDirectory = "NO" | ||||
|       ignoresPersistentStateOnLaunch = "NO" | ||||
|       debugDocumentVersioning = "YES" | ||||
|       debugServiceExtension = "internal" | ||||
|       allowLocationSimulation = "YES"> | ||||
|       <BuildableProductRunnable | ||||
|          runnableDebuggingMode = "0"> | ||||
|          <BuildableReference | ||||
|             BuildableIdentifier = "primary" | ||||
|             BlueprintIdentifier = "97C146ED1CF9000F007C117D" | ||||
|             BuildableName = "Runner.app" | ||||
|             BlueprintName = "Runner" | ||||
|             ReferencedContainer = "container:Runner.xcodeproj"> | ||||
|          </BuildableReference> | ||||
|       </BuildableProductRunnable> | ||||
|    </LaunchAction> | ||||
|    <ProfileAction | ||||
|       buildConfiguration = "Profile" | ||||
|       shouldUseLaunchSchemeArgsEnv = "YES" | ||||
|       savedToolIdentifier = "" | ||||
|       useCustomWorkingDirectory = "NO" | ||||
|       debugDocumentVersioning = "YES"> | ||||
|       <BuildableProductRunnable | ||||
|          runnableDebuggingMode = "0"> | ||||
|          <BuildableReference | ||||
|             BuildableIdentifier = "primary" | ||||
|             BlueprintIdentifier = "97C146ED1CF9000F007C117D" | ||||
|             BuildableName = "Runner.app" | ||||
|             BlueprintName = "Runner" | ||||
|             ReferencedContainer = "container:Runner.xcodeproj"> | ||||
|          </BuildableReference> | ||||
|       </BuildableProductRunnable> | ||||
|    </ProfileAction> | ||||
|    <AnalyzeAction | ||||
|       buildConfiguration = "Debug"> | ||||
|    </AnalyzeAction> | ||||
|    <ArchiveAction | ||||
|       buildConfiguration = "Release" | ||||
|       revealArchiveInOrganizer = "YES"> | ||||
|    </ArchiveAction> | ||||
| </Scheme> | ||||
| @ -1,10 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <Workspace | ||||
|    version = "1.0"> | ||||
|    <FileRef | ||||
|       location = "group:Runner.xcodeproj"> | ||||
|    </FileRef> | ||||
|    <FileRef | ||||
|       location = "group:Pods/Pods.xcodeproj"> | ||||
|    </FileRef> | ||||
| </Workspace> | ||||
| @ -1,8 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||||
| <plist version="1.0"> | ||||
| <dict> | ||||
| 	<key>IDEDidComputeMac32BitWarning</key> | ||||
| 	<true/> | ||||
| </dict> | ||||
| </plist> | ||||
| @ -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) | ||||
|   } | ||||
| } | ||||
| @ -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" | ||||
|   } | ||||
| } | ||||
| Before Width: | Height: | Size: 11 KiB | 
| Before Width: | Height: | Size: 564 B | 
| Before Width: | Height: | Size: 1.3 KiB | 
| Before Width: | Height: | Size: 1.6 KiB | 
| Before Width: | Height: | Size: 1.0 KiB | 
| Before Width: | Height: | Size: 1.7 KiB | 
| Before Width: | Height: | Size: 1.9 KiB | 
| Before Width: | Height: | Size: 1.3 KiB | 
| Before Width: | Height: | Size: 1.9 KiB | 
| Before Width: | Height: | Size: 2.6 KiB | 
| Before Width: | Height: | Size: 2.6 KiB | 
| Before Width: | Height: | Size: 3.7 KiB | 
| Before Width: | Height: | Size: 1.8 KiB | 
| Before Width: | Height: | Size: 3.2 KiB | 
| Before Width: | Height: | Size: 3.5 KiB | 
| @ -1,23 +0,0 @@ | ||||
| { | ||||
|   "images" : [ | ||||
|     { | ||||
|       "idiom" : "universal", | ||||
|       "filename" : "LaunchImage.png", | ||||
|       "scale" : "1x" | ||||
|     }, | ||||
|     { | ||||
|       "idiom" : "universal", | ||||
|       "filename" : "LaunchImage@2x.png", | ||||
|       "scale" : "2x" | ||||
|     }, | ||||
|     { | ||||
|       "idiom" : "universal", | ||||
|       "filename" : "LaunchImage@3x.png", | ||||
|       "scale" : "3x" | ||||
|     } | ||||
|   ], | ||||
|   "info" : { | ||||
|     "version" : 1, | ||||
|     "author" : "xcode" | ||||
|   } | ||||
| } | ||||
| Before Width: | Height: | Size: 68 B | 
| Before Width: | Height: | Size: 68 B | 
| Before Width: | Height: | Size: 68 B | 
| @ -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. | ||||
| @ -1,37 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM"> | ||||
|     <dependencies> | ||||
|         <deployment identifier="iOS"/> | ||||
|         <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/> | ||||
|     </dependencies> | ||||
|     <scenes> | ||||
|         <!--View Controller--> | ||||
|         <scene sceneID="EHf-IW-A2E"> | ||||
|             <objects> | ||||
|                 <viewController id="01J-lp-oVM" sceneMemberID="viewController"> | ||||
|                     <layoutGuides> | ||||
|                         <viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/> | ||||
|                         <viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/> | ||||
|                     </layoutGuides> | ||||
|                     <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3"> | ||||
|                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | ||||
|                         <subviews> | ||||
|                             <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4"> | ||||
|                             </imageView> | ||||
|                         </subviews> | ||||
|                         <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> | ||||
|                         <constraints> | ||||
|                             <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/> | ||||
|                             <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/> | ||||
|                         </constraints> | ||||
|                     </view> | ||||
|                 </viewController> | ||||
|                 <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/> | ||||
|             </objects> | ||||
|             <point key="canvasLocation" x="53" y="375"/> | ||||
|         </scene> | ||||
|     </scenes> | ||||
|     <resources> | ||||
|         <image name="LaunchImage" width="168" height="185"/> | ||||
|     </resources> | ||||
| </document> | ||||
| @ -1,26 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r"> | ||||
|     <dependencies> | ||||
|         <deployment identifier="iOS"/> | ||||
|         <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/> | ||||
|     </dependencies> | ||||
|     <scenes> | ||||
|         <!--Flutter View Controller--> | ||||
|         <scene sceneID="tne-QT-ifu"> | ||||
|             <objects> | ||||
|                 <viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController"> | ||||
|                     <layoutGuides> | ||||
|                         <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/> | ||||
|                         <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/> | ||||
|                     </layoutGuides> | ||||
|                     <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC"> | ||||
|                         <rect key="frame" x="0.0" y="0.0" width="600" height="600"/> | ||||
|                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | ||||
|                         <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/> | ||||
|                     </view> | ||||
|                 </viewController> | ||||
|                 <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/> | ||||
|             </objects> | ||||
|         </scene> | ||||
|     </scenes> | ||||
| </document> | ||||
| @ -1,51 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||||
| <plist version="1.0"> | ||||
| <dict> | ||||
| 	<key>CFBundleDevelopmentRegion</key> | ||||
| 	<string>$(DEVELOPMENT_LANGUAGE)</string> | ||||
| 	<key>CFBundleDisplayName</key> | ||||
| 	<string>Example</string> | ||||
| 	<key>CFBundleExecutable</key> | ||||
| 	<string>$(EXECUTABLE_NAME)</string> | ||||
| 	<key>CFBundleIdentifier</key> | ||||
| 	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> | ||||
| 	<key>CFBundleInfoDictionaryVersion</key> | ||||
| 	<string>6.0</string> | ||||
| 	<key>CFBundleName</key> | ||||
| 	<string>example</string> | ||||
| 	<key>CFBundlePackageType</key> | ||||
| 	<string>APPL</string> | ||||
| 	<key>CFBundleShortVersionString</key> | ||||
| 	<string>$(FLUTTER_BUILD_NAME)</string> | ||||
| 	<key>CFBundleSignature</key> | ||||
| 	<string>????</string> | ||||
| 	<key>CFBundleVersion</key> | ||||
| 	<string>$(FLUTTER_BUILD_NUMBER)</string> | ||||
| 	<key>LSRequiresIPhoneOS</key> | ||||
| 	<true/> | ||||
| 	<key>UILaunchStoryboardName</key> | ||||
| 	<string>LaunchScreen</string> | ||||
| 	<key>UIMainStoryboardFile</key> | ||||
| 	<string>Main</string> | ||||
| 	<key>UISupportedInterfaceOrientations</key> | ||||
| 	<array> | ||||
| 		<string>UIInterfaceOrientationPortrait</string> | ||||
| 		<string>UIInterfaceOrientationLandscapeLeft</string> | ||||
| 		<string>UIInterfaceOrientationLandscapeRight</string> | ||||
| 	</array> | ||||
| 	<key>UISupportedInterfaceOrientations~ipad</key> | ||||
| 	<array> | ||||
| 		<string>UIInterfaceOrientationPortrait</string> | ||||
| 		<string>UIInterfaceOrientationPortraitUpsideDown</string> | ||||
| 		<string>UIInterfaceOrientationLandscapeLeft</string> | ||||
| 		<string>UIInterfaceOrientationLandscapeRight</string> | ||||
| 	</array> | ||||
| 	<key>UIViewControllerBasedStatusBarAppearance</key> | ||||
| 	<false/> | ||||
| 	<key>CADisableMinimumFrameDurationOnPhone</key> | ||||
| 	<true/> | ||||
| 	<key>UIApplicationSupportsIndirectInputEvents</key> | ||||
| 	<true/> | ||||
| </dict> | ||||
| </plist> | ||||
| @ -1 +0,0 @@ | ||||
| #import "GeneratedPluginRegistrant.h" | ||||
							
								
								
									
										151
									
								
								packages/wyatt_crud_bloc/example/lib/advanced_cubit_view.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -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 <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| 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<CrudRepository<User>>())..getAll(), | ||||
|         child: Builder(builder: (context) { | ||||
|           return Column( | ||||
|             children: [ | ||||
|               const Text("Data:"), | ||||
|               BlocBuilder<UserAdvancedCubit, CrudState>( | ||||
|                 buildWhen: (previous, current) { | ||||
|                   if (current is CrudLoading && current is! CrudReading) { | ||||
|                     return false; | ||||
|                   } | ||||
|                   return true; | ||||
|                 }, | ||||
|                 builder: (context, state) { | ||||
|                   return Expanded( | ||||
|                     child: CrudBuilder.typed<CrudListLoaded<User?>>( | ||||
|                       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<UserAdvancedCubit>() | ||||
|                                     .delete((user?.id)!); | ||||
|                               }, | ||||
|                               onLongPress: () { | ||||
|                                 context.read<UserAdvancedCubit>().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<UserAdvancedCubit>().create( | ||||
|                         User( | ||||
|                           id: '$r', | ||||
|                           name: 'Wyatt $r', | ||||
|                           email: '$r@wyattapp.io', | ||||
|                           phone: '06$r', | ||||
|                         ), | ||||
|                       ); | ||||
|                 }, | ||||
|                 child: BlocBuilder<UserAdvancedCubit, CrudState>( | ||||
|                   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<UserAdvancedCubit>().getAll(); | ||||
|                 }, | ||||
|                 child: BlocBuilder<UserAdvancedCubit, CrudState>( | ||||
|                   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), | ||||
|             ], | ||||
|           ); | ||||
|         }), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| @ -14,34 +14,37 @@ | ||||
| // You should have received a copy of the GNU General Public License | ||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import '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<User> userLocalDataSource = | ||||
|         CrudInMemoryDataSourceImpl<User>(toMap: (user) => user.toMap()); | ||||
| 
 | ||||
|     final CrudRepository<User> userRepository = | ||||
|         CrudRepositoryImpl(crudDataSource: userLocalDataSource); | ||||
|     final CrudRepository<User> 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<CrudRepository<User>>.value( | ||||
|       value: userRepository, | ||||
|       child: MultiBlocProvider( | ||||
|         providers: [ | ||||
|           BlocProvider<UserCubit>( | ||||
|             create: (context) => UserCubit(userRepository)..read(), | ||||
|           ), | ||||
|         ], | ||||
|       child: MaterialApp( | ||||
|         title: 'Flutter Demo', | ||||
|         theme: ThemeData( | ||||
| @ -49,7 +52,6 @@ class MyApp extends StatelessWidget { | ||||
|         ), | ||||
|         home: const MyHomePage(), | ||||
|       ), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| @ -63,61 +65,33 @@ class MyHomePage extends StatelessWidget { | ||||
|       appBar: AppBar( | ||||
|         title: const Text('Flutter Demo Home Page'), | ||||
|       ), | ||||
|       body: SingleChildScrollView( | ||||
|         child: Column( | ||||
|       body: Column( | ||||
|         children: [ | ||||
|             const SizedBox(height: 20), | ||||
|             const Text("Data:"), | ||||
|             BlocBuilder<UserCubit, CrudState>( | ||||
|               builder: (context, state) { | ||||
|                 return CrudBuilder.typed<CrudListLoaded<User?>>( | ||||
|                   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<UserCubit>().delete(id: (user?.id)!); | ||||
|                           }, | ||||
|                         ); | ||||
|                       }, | ||||
|                     ); | ||||
|                   }), | ||||
|                   initialBuilder: (context, state) => const Text("Loading..."), | ||||
|                   loadingBuilder: (context, state) => const Text("Loading..."), | ||||
|                   errorBuilder: (context, state) => Text("Error: $state"), | ||||
|           ElevatedButton( | ||||
|             onPressed: () { | ||||
|               Navigator.push( | ||||
|                 context, | ||||
|                 MaterialPageRoute( | ||||
|                   builder: (context) => const BasicCubitView(), | ||||
|                 ), | ||||
|               ); | ||||
|             }, | ||||
|             child: const Text('Basic example'), | ||||
|           ), | ||||
|           const SizedBox(height: 20), | ||||
|           ElevatedButton( | ||||
|             onPressed: () { | ||||
|                 final r = Random().nextInt(1000); | ||||
|                 context.read<UserCubit>().create( | ||||
|                       User( | ||||
|                           id: '$r', | ||||
|                           name: 'Wyatt $r', | ||||
|                           email: '$r@wyattapp.io', | ||||
|                           phone: '06$r'), | ||||
|               Navigator.push( | ||||
|                 context, | ||||
|                 MaterialPageRoute( | ||||
|                   builder: (context) => const AdvancedCubitView(), | ||||
|                 ), | ||||
|               ); | ||||
|             }, | ||||
|               child: const Text("Create"), | ||||
|             child: const Text('Advanced example'), | ||||
|           ), | ||||
|             ElevatedButton( | ||||
|               onPressed: () { | ||||
|                 context.read<UserCubit>().read(); | ||||
|               }, | ||||
|               child: const Text("GetAll"), | ||||
|             ), | ||||
|             const SizedBox(height: 20), | ||||
|         ], | ||||
|       ), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
|  | ||||
							
								
								
									
										150
									
								
								packages/wyatt_crud_bloc/example/lib/basic_cubit_view.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -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 <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| 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<CrudRepository<User>>())..read(), | ||||
|         child: Builder(builder: (context) { | ||||
|           return Column( | ||||
|             children: [ | ||||
|               BlocBuilder<UserCubit, CrudState>( | ||||
|                 buildWhen: (previous, current) { | ||||
|                   if (current is CrudLoading && current is! CrudReading) { | ||||
|                     return false; | ||||
|                   } | ||||
|                   return true; | ||||
|                 }, | ||||
|                 builder: (context, state) { | ||||
|                   return Expanded( | ||||
|                     child: CrudBuilder.typed<CrudListLoaded<User?>>( | ||||
|                       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<UserCubit>() | ||||
|                                     .delete(id: (user?.id)!); | ||||
|                               }, | ||||
|                               onLongPress: () { | ||||
|                                 context.read<UserCubit>().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<UserCubit>().create( | ||||
|                         User( | ||||
|                           id: '$r', | ||||
|                           name: 'Wyatt $r', | ||||
|                           email: '$r@wyattapp.io', | ||||
|                           phone: '06$r', | ||||
|                         ), | ||||
|                       ); | ||||
|                 }, | ||||
|                 child: BlocBuilder<UserCubit, CrudState>( | ||||
|                   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<UserCubit>().read(); | ||||
|                 }, | ||||
|                 child: BlocBuilder<UserCubit, CrudState>( | ||||
|                   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), | ||||
|             ], | ||||
|           ); | ||||
|         }), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										63
									
								
								packages/wyatt_crud_bloc/example/lib/firebase_options.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -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', | ||||
|   ); | ||||
| } | ||||
							
								
								
									
										44
									
								
								packages/wyatt_crud_bloc/example/lib/main_firestore.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -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 <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| 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<void> 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, | ||||
|   )); | ||||
| } | ||||
| @ -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<void> main() async { | ||||
|   WidgetsFlutterBinding.ensureInitialized(); | ||||
|   Bloc.observer = AppBlocObserver(); | ||||
| 
 | ||||
|   runApp(const MyApp()); | ||||
|   final CrudDataSource crudDataSource = CrudDataSourceInMemoryImpl( | ||||
|     id: (_, json) => json['id'] as String?, | ||||
|   ); | ||||
| 
 | ||||
|   runApp(MyApp( | ||||
|     crudDataSource: crudDataSource, | ||||
|   )); | ||||
| } | ||||
| @ -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 <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| 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<User> { | ||||
|   final CrudRepository<User> crudRepository; | ||||
| 
 | ||||
|   UserAdvancedCubit(this.crudRepository); | ||||
| 
 | ||||
|   @override | ||||
|   ModelIdentifier<User> get modelIdentifier => ModelIdentifier( | ||||
|         getIdentifier: (user) => user.id ?? '', | ||||
|       ); | ||||
| 
 | ||||
|   @override | ||||
|   Create<User>? get crudCreate => Create(crudRepository); | ||||
| 
 | ||||
|   @override | ||||
|   Delete<User>? get crudDelete => Delete(crudRepository); | ||||
| 
 | ||||
|   @override | ||||
|   DeleteAll<User>? get crudDeleteAll => DeleteAll(crudRepository); | ||||
| 
 | ||||
|   @override | ||||
|   Get<User>? get crudGet => Get(crudRepository); | ||||
| 
 | ||||
|   @override | ||||
|   GetAll<User>? get crudGetAll => GetAll(crudRepository); | ||||
| 
 | ||||
|   @override | ||||
|   Search<User>? get crudSearch => Search(crudRepository); | ||||
| 
 | ||||
|   @override | ||||
|   Update<User>? get crudUpdate => Update(crudRepository); | ||||
| 
 | ||||
|   @override | ||||
|   UpdateAll<User>? get crudUpdateAll => UpdateAll(crudRepository); | ||||
| } | ||||
| @ -14,28 +14,29 @@ | ||||
| // You should have received a copy of the GNU General Public License | ||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import 'package: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<User> { | ||||
|   final CrudRepository<User> _crudRepository; | ||||
|   final CrudRepository<User> crudRepository; | ||||
| 
 | ||||
|   UserCubit(this._crudRepository); | ||||
|   UserCubit(this.crudRepository); | ||||
| 
 | ||||
|   @override | ||||
|   CreateOperation<User, dynamic>? get createOperation => | ||||
|       Create(_crudRepository); | ||||
|   DefaultCreate<User>? get createOperation => Create(crudRepository); | ||||
| 
 | ||||
|   @override | ||||
|   DeleteOperation<User, dynamic>? get deleteOperation => | ||||
|       Delete(_crudRepository); | ||||
|   DefaultDelete? get deleteOperation => Delete(crudRepository); | ||||
| 
 | ||||
|   @override | ||||
|   ReadOperation<User, dynamic, dynamic>? get readOperation => | ||||
|       GetAll(_crudRepository); | ||||
|   DefaultRead? get readOperation => GetAll(crudRepository); | ||||
| 
 | ||||
|   @override | ||||
|   UpdateOperation<User, dynamic>? get updateOperation => | ||||
|       Update(_crudRepository); | ||||
|   DefaultUpdate? get updateOperation => Update(crudRepository); | ||||
| 
 | ||||
|   @override | ||||
|   ModelIdentifier<User> get modelIdentifier => ModelIdentifier( | ||||
|         getIdentifier: (user) => user.id ?? '', | ||||
|       ); | ||||
| } | ||||
|  | ||||
| @ -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 <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| 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<Object?> get props => [id, name, email, phone]; | ||||
| } | ||||
| @ -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 <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| 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<String, Object> toMap() { | ||||
|     return { | ||||
|       'name': name ?? '', | ||||
|       'email': email ?? '', | ||||
|       'phone': phone ?? '', | ||||
|     }; | ||||
|   } | ||||
|   factory UserModel.fromJson(Map<String, dynamic> json) => | ||||
|       _$UserModelFromJson(json); | ||||
| 
 | ||||
|   Map<String, dynamic> toJson() => _$UserModelToJson(this); | ||||
| 
 | ||||
|   @override | ||||
|   String toString() => | ||||
|       'User(id: $id, name: $name, email: $email, phone: $phone)'; | ||||
|       'UserModel(id: $id, name: $name, email: $email, phone: $phone)'; | ||||
| } | ||||
							
								
								
									
										21
									
								
								packages/wyatt_crud_bloc/example/lib/user_model.g.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,21 @@ | ||||
| // GENERATED CODE - DO NOT MODIFY BY HAND | ||||
| 
 | ||||
| part of 'user_model.dart'; | ||||
| 
 | ||||
| // ************************************************************************** | ||||
| // JsonSerializableGenerator | ||||
| // ************************************************************************** | ||||
| 
 | ||||
| UserModel _$UserModelFromJson(Map<String, dynamic> json) => UserModel( | ||||
|       id: json['id'] as String?, | ||||
|       name: json['name'] as String, | ||||
|       email: json['email'] as String, | ||||
|       phone: json['phone'] as String, | ||||
|     ); | ||||
| 
 | ||||
| Map<String, dynamic> _$UserModelToJson(UserModel instance) => <String, dynamic>{ | ||||
|       'id': instance.id, | ||||
|       'name': instance.name, | ||||
|       'email': instance.email, | ||||
|       'phone': instance.phone, | ||||
|     }; | ||||
| @ -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 | ||||
|  | ||||
| @ -1 +0,0 @@ | ||||
| 
 | ||||
| @ -14,5 +14,8 @@ | ||||
| // You should have received a copy of the GNU General Public License | ||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| export 'enums/operation_type.dart'; | ||||
| export 'enums/where_query_type.dart'; | ||||
| export 'mixins/operation.dart'; | ||||
| export 'model_identifier.dart'; | ||||
| export '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,4 +14,10 @@ | ||||
| // You should have received a copy of the GNU General Public License | ||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| export 'crud_data_source.dart'; | ||||
| enum OperationType { | ||||
|   query, | ||||
|   create, | ||||
|   read, | ||||
|   update, | ||||
|   delete, | ||||
| } | ||||
| @ -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,20 +15,28 @@ | ||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| 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<Model extends ObjectModel, Out> | ||||
|     on AsyncUseCase<Model, Out> {} | ||||
| mixin CreateOperation<In, Out> on AsyncUseCase<In, Out> { | ||||
|   /// {@macro create} | ||||
|   OperationType get operationType => OperationType.create; | ||||
| } | ||||
| 
 | ||||
| /// Defines every read operation in CRUD. | ||||
| mixin ReadOperation<Model extends ObjectModel, In, Out> | ||||
|     on AsyncUseCase<In, Out> {} | ||||
| mixin ReadOperation<In, Out> on AsyncUseCase<In, Out> { | ||||
|   /// {@macro read} | ||||
|   OperationType get operationType => OperationType.read; | ||||
| } | ||||
| 
 | ||||
| /// Defines every update operation in CRUD. | ||||
| mixin UpdateOperation<Model extends ObjectModel, In> | ||||
|     on AsyncUseCase<In, void> {} | ||||
| mixin UpdateOperation<In> on AsyncUseCase<In, void> { | ||||
|   /// {@macro update} | ||||
|   OperationType get operationType => OperationType.update; | ||||
| } | ||||
| 
 | ||||
| /// Defines every delete operation in CRUD. | ||||
| mixin DeleteOperation<Model extends ObjectModel, In> | ||||
|     on AsyncUseCase<In, void> {} | ||||
| mixin DeleteOperation<In> on AsyncUseCase<In, void> { | ||||
|   /// {@macro delete} | ||||
|   OperationType get operationType => OperationType.delete; | ||||
| } | ||||
|  | ||||
							
								
								
									
										57
									
								
								packages/wyatt_crud_bloc/lib/src/core/model_identifier.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -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 <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| class ModelIdentifier<Model> { | ||||
|   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); | ||||
|   } | ||||
| } | ||||
| @ -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 <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| export 'local/crud_in_memory_data_source_impl.dart'; | ||||
| export 'remote/crud_firestore_data_source_impl.dart'; | ||||
| class ModelMapper<Model> { | ||||
|   const ModelMapper({ | ||||
|     required this.fromJson, | ||||
|     required this.toJson, | ||||
|   }); | ||||
| 
 | ||||
|   final Model Function(Map<String, dynamic>? json) fromJson; | ||||
|   final Map<String, dynamic> Function(Model model) toJson; | ||||
| } | ||||
| @ -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 <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| 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'; | ||||
|  | ||||
| @ -15,47 +15,54 @@ | ||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| 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<Model> extends BaseDataSource { | ||||
| abstract class CrudDataSource extends BaseDataSource { | ||||
|   /// {@macro crud_data_source} | ||||
|   const CrudDataSource(); | ||||
| 
 | ||||
|   /// Creates a new [Model] object. | ||||
|   Future<void> create(Model object, {String? id}); | ||||
| 
 | ||||
|   /// Gets a [Model] object by its [id]. | ||||
|   Future<Model?> get(String id); | ||||
| 
 | ||||
|   /// Gets all [Model] objects. | ||||
|   Future<List<Model?>> getAll(); | ||||
| 
 | ||||
|   /// Updates a [Model] object by its [id]. | ||||
|   Future<void> update( | ||||
|     String id, { | ||||
|     Model? object, | ||||
|     Map<String, dynamic>? raw, | ||||
|   const CrudDataSource({ | ||||
|     required this.id, | ||||
|   }); | ||||
| 
 | ||||
|   /// Updates all [Model] objects. | ||||
|   final String? Function( | ||||
|     OperationType operationType, | ||||
|     Map<String, dynamic> object, | ||||
|   ) id; | ||||
| 
 | ||||
|   /// Creates a new object. | ||||
|   Future<void> create(Map<String, dynamic> object, {String? id}); | ||||
| 
 | ||||
|   /// Gets a object by its [id]. | ||||
|   Future<Map<String, dynamic>?> get(String id); | ||||
| 
 | ||||
|   /// Gets all objects. | ||||
|   Future<List<dynamic>?> getAll(); | ||||
| 
 | ||||
|   /// Updates a object by its [id]. | ||||
|   Future<void> update( | ||||
|     String id, { | ||||
|     Map<String, dynamic>? object, | ||||
|   }); | ||||
| 
 | ||||
|   /// Updates all objects. | ||||
|   Future<void> updateAll(Map<String, Object?>? data); | ||||
| 
 | ||||
|   /// Deletes a [Model] object by its [id]. | ||||
|   /// Deletes a object by its [id]. | ||||
|   Future<void> delete(String id); | ||||
| 
 | ||||
|   /// Deletes all [Model] objects. | ||||
|   /// Deletes all objects. | ||||
|   Future<void> deleteAll(); | ||||
| 
 | ||||
|   /// Queries [Model] objects by [conditions]. | ||||
|   Future<List<Model?>> query(List<QueryInterface> conditions); | ||||
|   /// Queries objects by [conditions]. | ||||
|   Future<List<dynamic>?> search(List<Query> conditions); | ||||
| 
 | ||||
|   /// Streams [Model] objects by [conditions]. | ||||
|   Stream<List<Model?>> stream({ | ||||
|   /// Streams objects by [conditions]. | ||||
|   Stream<List<dynamic>?> stream({ | ||||
|     String? id, | ||||
|     List<QueryInterface>? conditions, | ||||
|     List<Query>? conditions, | ||||
|     bool includeMetadataChanges = false, | ||||
|   }); | ||||
| } | ||||
| @ -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<String, dynamic> { | ||||
|   Map<String, dynamic> merge( | ||||
|     Map<String, dynamic>? other, { | ||||
|     bool skipNulls = false, | ||||
|   }) { | ||||
|     if (other == null) { | ||||
|       return this; | ||||
|     } | ||||
|     final Map<String, dynamic> 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<Model extends ObjectModel> | ||||
|     extends CrudDataSource<Model> { | ||||
|   /// {@macro crud_in_memory_data_source_impl} | ||||
|   CrudInMemoryDataSourceImpl({required this.toMap, Map<String, Model>? data}) | ||||
|       : _data = data ?? {}; | ||||
|   final Map<String, Model> _data; | ||||
|   final StreamController<List<Model?>> _streamData = StreamController(); | ||||
| class CrudDataSourceInMemoryImpl extends CrudDataSource { | ||||
|   /// {@macro crud_data_source_in_memory_impl} | ||||
|   CrudDataSourceInMemoryImpl({ | ||||
|     required super.id, | ||||
|     Map<String, Map<String, dynamic>>? data, | ||||
|   }) : _data = data ?? {}; | ||||
| 
 | ||||
|   final Map<String, Object?> Function(Model) toMap; | ||||
|   final Map<String, Map<String, dynamic>> _data; | ||||
|   final StreamController<List<Map<String, dynamic>?>> _streamData = | ||||
|       StreamController(); | ||||
| 
 | ||||
|   @override | ||||
|   Future<void> create(Model object, {String? id}) async { | ||||
|     _data[id ?? object.id ?? ''] = object; | ||||
|   Future<void> create(Map<String, dynamic> object, {String? id}) async { | ||||
|     _data[id ?? this.id(OperationType.create, object) ?? ''] = object; | ||||
| 
 | ||||
|     _streamData.add(_data.values.toList()); | ||||
|   } | ||||
| 
 | ||||
| @ -54,14 +81,14 @@ class CrudInMemoryDataSourceImpl<Model extends ObjectModel> | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Future<Model?> get(String id) async => _data[id]; | ||||
|   Future<Map<String, dynamic>?> get(String id) async => _data[id]; | ||||
| 
 | ||||
|   @override | ||||
|   Future<List<Model?>> getAll() async => _data.values.toList(); | ||||
|   Future<List<Map<String, dynamic>?>> getAll() async => _data.values.toList(); | ||||
| 
 | ||||
|   @override | ||||
|   Future<List<Model?>> query(List<QueryInterface> conditions) async { | ||||
|     List<Model> result = _data.values.toList(); | ||||
|   Future<List<Map<String, dynamic>?>> search(List<Query> conditions) async { | ||||
|     List<Map<String, dynamic>> result = _data.values.toList(); | ||||
| 
 | ||||
|     for (final c in conditions) { | ||||
|       if (c is WhereQuery) { | ||||
| @ -81,15 +108,15 @@ class CrudInMemoryDataSourceImpl<Model extends ObjectModel> | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     result.cast<Model>(); | ||||
|     result.cast<Map<String, dynamic>>(); | ||||
| 
 | ||||
|     return result; | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Stream<List<Model?>> stream({ | ||||
|   Stream<List<Map<String, dynamic>?>> stream({ | ||||
|     String? id, | ||||
|     List<QueryInterface>? conditions, | ||||
|     List<Query>? conditions, | ||||
|     bool includeMetadataChanges = false, | ||||
|   }) => | ||||
|       _streamData.stream.map((result) { | ||||
| @ -97,7 +124,7 @@ class CrudInMemoryDataSourceImpl<Model extends ObjectModel> | ||||
|           return result; | ||||
|         } | ||||
| 
 | ||||
|         List<Model?> res = result; | ||||
|         List<Map<String, dynamic>?> res = result; | ||||
| 
 | ||||
|         for (final c in conditions) { | ||||
|           if (c is WhereQuery) { | ||||
| @ -120,56 +147,63 @@ class CrudInMemoryDataSourceImpl<Model extends ObjectModel> | ||||
|   @override | ||||
|   Future<void> update( | ||||
|     String id, { | ||||
|     Model? object, | ||||
|     Map<String, dynamic>? raw, | ||||
|     Map<String, dynamic>? 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<void> updateAll(Map<String, Object?>? 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<String, dynamic>? 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<Object>?) | ||||
|           return (object[condition.field] as List<Object>?) | ||||
|                   ?.contains(condition.value) ?? | ||||
|               false; | ||||
|         case WhereQueryType.arrayContainsAny: | ||||
|           bool res = false; | ||||
|           for (final o in condition.value as List<Object>) { | ||||
|             res = (raw[condition.field] as List<Object>?)?.contains(o) ?? false; | ||||
|             res = (object[condition.field] as List<Object>?)?.contains(o) ?? | ||||
|                 false; | ||||
|           } | ||||
|           return res; | ||||
|         case WhereQueryType.whereIn: | ||||
|           return (condition.value as List<Object>) | ||||
|               .contains(raw[condition.field]); | ||||
|               .contains(object[condition.field]); | ||||
|         case WhereQueryType.whereNotIn: | ||||
|           return !(condition.value as List<Object>) | ||||
|               .contains(raw[condition.field]); | ||||
|               .contains(object[condition.field]); | ||||
|         case WhereQueryType.isNull: | ||||
|           return raw[condition.field] == null; | ||||
|           return object[condition.field] == null; | ||||
|       } | ||||
|     } | ||||
|     return true; | ||||
| @ -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 <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| 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<Model extends ObjectModel> | ||||
|     extends CrudRepository<Model> { | ||||
| class CrudRepositoryImpl<Model> extends CrudRepository<Model> { | ||||
|   /// {@macro crud_repository_impl} | ||||
|   const CrudRepositoryImpl({ | ||||
|     required CrudDataSource<Model> crudDataSource, | ||||
|     required this.modelMapper, | ||||
|     required CrudDataSource crudDataSource, | ||||
|   }) : _crudDataSource = crudDataSource; | ||||
|   final CrudDataSource<Model> _crudDataSource; | ||||
| 
 | ||||
|   final CrudDataSource _crudDataSource; | ||||
| 
 | ||||
|   @override | ||||
|   final ModelMapper<Model> modelMapper; | ||||
| 
 | ||||
|   @override | ||||
|   FutureOrResult<void> create(Model object, {String? id}) => | ||||
|       Result.tryCatchAsync<void, AppException, AppException>( | ||||
|         () async { | ||||
|           await _crudDataSource.create(object, id: id); | ||||
|           await _crudDataSource.create(modelMapper.toJson(object), id: id); | ||||
|         }, | ||||
|         (error) => error, | ||||
|       ); | ||||
| @ -44,14 +48,26 @@ class CrudRepositoryImpl<Model extends ObjectModel> | ||||
|   @override | ||||
|   FutureOrResult<Model?> get(String id) => | ||||
|       Result.tryCatchAsync<Model?, AppException, AppException>( | ||||
|         () async => _crudDataSource.get(id), | ||||
|         () async => modelMapper.fromJson(await _crudDataSource.get(id)), | ||||
|         (error) => error, | ||||
|       ); | ||||
| 
 | ||||
|   @override | ||||
|   FutureOrResult<List<Model?>> getAll() => | ||||
|       Result.tryCatchAsync<List<Model?>, 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<String, dynamic>?); | ||||
|               } catch (e) { | ||||
|                 return null; | ||||
|               } | ||||
|             }).toList(); | ||||
|           } | ||||
|           throw const ServerException(); | ||||
|         }, | ||||
|         (error) => error, | ||||
|       ); | ||||
| 
 | ||||
| @ -62,7 +78,18 @@ class CrudRepositoryImpl<Model extends ObjectModel> | ||||
|     Map<String, dynamic>? raw, | ||||
|   }) => | ||||
|       Result.tryCatchAsync<void, AppException, AppException>( | ||||
|         () 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<Model extends ObjectModel> | ||||
|       ); | ||||
| 
 | ||||
|   @override | ||||
|   FutureOrResult<List<Model?>> query(List<QueryInterface> conditions) => | ||||
|   FutureOrResult<List<Model?>> search(List<Query> conditions) => | ||||
|       Result.tryCatchAsync<List<Model?>, 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<String, dynamic>?); | ||||
|               } catch (e) { | ||||
|                 return null; | ||||
|               } | ||||
|             }).toList(); | ||||
|           } | ||||
|           throw const ServerException(); | ||||
|         }, | ||||
|         (error) => error, | ||||
|       ); | ||||
| 
 | ||||
|   @override | ||||
|   StreamResult<List<Model?>> stream({ | ||||
|     String? id, | ||||
|     List<QueryInterface>? conditions, | ||||
|     List<Query>? conditions, | ||||
|   }) => | ||||
|       _crudDataSource.stream(id: id, conditions: conditions).map((lst) { | ||||
|         if (lst.isNotNull) { | ||||
|           return Ok<List<Model?>, AppException>(lst); | ||||
|           return Ok<List<Model?>, AppException>( | ||||
|             lst!.map((raw) { | ||||
|               try { | ||||
|                 return modelMapper.fromJson(raw as Map<String, dynamic>?); | ||||
|               } catch (e) { | ||||
|                 return null; | ||||
|               } | ||||
|             }).toList(), | ||||
|           ); | ||||
|         } | ||||
|         return Err<List<Model?>, AppException>(const ServerException()); | ||||
|       }); | ||||
|  | ||||
| @ -14,7 +14,6 @@ | ||||
| // You should have received a copy of the GNU General Public License | ||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| 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'; | ||||
|  | ||||
| @ -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 <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| export 'object_model.dart'; | ||||
| export '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> { | ||||
| //   Q parser(QueryInterface condition, Q query); | ||||
| // } | ||||
| 
 | ||||
| typedef QueryParser<Q> = Q Function(QueryInterface condition, Q query); | ||||
| typedef QueryParser<Q> = 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<Value> extends QueryInterface { | ||||
| final class WhereQuery<Value> extends Query { | ||||
|   /// {@macro where_query} | ||||
|   const WhereQuery(this.type, this.field, this.value); | ||||
| 
 | ||||
| @ -52,7 +47,7 @@ class WhereQuery<Value> 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}); | ||||
| 
 | ||||
|  | ||||
| @ -15,17 +15,18 @@ | ||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| 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<Model extends ObjectModel> | ||||
|     extends BaseRepository { | ||||
| abstract class CrudRepository<Model> extends BaseRepository { | ||||
|   /// {@macro crud_repository} | ||||
|   const CrudRepository(); | ||||
| 
 | ||||
|   ModelMapper<Model> get modelMapper; | ||||
| 
 | ||||
|   /// Creates a new object. | ||||
|   FutureOrResult<void> create(Model object, {String? id}); | ||||
| 
 | ||||
| @ -52,11 +53,11 @@ abstract class CrudRepository<Model extends ObjectModel> | ||||
|   FutureOrResult<void> deleteAll(); | ||||
| 
 | ||||
|   /// Queries objects by [conditions]. | ||||
|   FutureOrResult<List<Model?>> query(List<QueryInterface> conditions); | ||||
|   FutureOrResult<List<Model?>> search(List<Query> conditions); | ||||
| 
 | ||||
|   /// Streams objects by [conditions]. | ||||
|   StreamResult<List<Model?>> stream({ | ||||
|     String? id, | ||||
|     List<QueryInterface>? conditions, | ||||
|     List<Query>? conditions, | ||||
|   }); | ||||
| } | ||||
|  | ||||
| @ -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 <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| export 'crud_repository.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 <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| 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<Model extends ObjectModel> extends AsyncUseCase<Model, void> | ||||
| class Create<Model> extends Usecase<Model, void> | ||||
|     with CreateOperation<Model, void> { | ||||
|   /// {@macro create} | ||||
|   const Create(this._crudRepository); | ||||
|   const Create(this.crudRepository); | ||||
| 
 | ||||
|   final CrudRepository<Model> _crudRepository; | ||||
| 
 | ||||
|   @override | ||||
|   FutureOr<void> onStart(Model? params) { | ||||
|     if (params == null) { | ||||
|       throw ClientException('$Model cannot be null.'); | ||||
|     } | ||||
|   } | ||||
|   final CrudRepository<Model> crudRepository; | ||||
| 
 | ||||
|   @override | ||||
|   FutureOrResult<void> execute(Model? params) => | ||||
|       _crudRepository.create(params!); | ||||
|       crudRepository.create(params as Model); | ||||
| } | ||||
|  | ||||
| @ -14,31 +14,21 @@ | ||||
| // You should have received a copy of the GNU General Public License | ||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import '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<Model extends ObjectModel> extends AsyncUseCase<String, void> | ||||
|     with DeleteOperation<Model, String> { | ||||
| class Delete<Model> extends Usecase<String, void> with DeleteOperation<String> { | ||||
|   /// {@macro delete} | ||||
|   const Delete(this._crudRepository); | ||||
|   const Delete(this.crudRepository); | ||||
| 
 | ||||
|   final CrudRepository<Model> _crudRepository; | ||||
| 
 | ||||
|   @override | ||||
|   FutureOr<void> onStart(String? params) { | ||||
|     if (params == null) { | ||||
|       throw const ClientException('Id cannot be null.'); | ||||
|     } | ||||
|   } | ||||
|   final CrudRepository<Model> crudRepository; | ||||
| 
 | ||||
|   @override | ||||
|   FutureOrResult<void> execute(String? params) => | ||||
|       _crudRepository.delete(params!); | ||||
|       crudRepository.delete(params!); | ||||
| } | ||||
|  | ||||
| @ -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<Model extends ObjectModel> extends AsyncUseCase<void, void> | ||||
|     with DeleteOperation<Model, void> { | ||||
| class DeleteAll<Model> extends NoParamUsecase<void> with DeleteOperation<void> { | ||||
|   /// {@macro delete_all} | ||||
|   const DeleteAll(this._crudRepository); | ||||
|   const DeleteAll(this.crudRepository); | ||||
| 
 | ||||
|   final CrudRepository<Model> _crudRepository; | ||||
|   final CrudRepository<Model> crudRepository; | ||||
| 
 | ||||
|   @override | ||||
|   FutureOrResult<void> execute(void params) => _crudRepository.deleteAll(); | ||||
|   FutureOrResult<void> execute(void params) => crudRepository.deleteAll(); | ||||
| } | ||||
|  | ||||
| @ -14,31 +14,21 @@ | ||||
| // You should have received a copy of the GNU General Public License | ||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import '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<Model extends ObjectModel> extends AsyncUseCase<String, Model?> | ||||
|     with ReadOperation<Model, String, Model?> { | ||||
| class Get<Model> extends Usecase<String, Model?> | ||||
|     with ReadOperation<String, Model?> { | ||||
|   /// {@macro get} | ||||
|   Get(this._crudRepository); | ||||
|   Get(this.crudRepository); | ||||
| 
 | ||||
|   final CrudRepository<Model> _crudRepository; | ||||
|   final CrudRepository<Model> crudRepository; | ||||
| 
 | ||||
|   @override | ||||
|   FutureOr<void> onStart(String? params) { | ||||
|     if (params == null) { | ||||
|       throw const ClientException('Id cannot be null.'); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   FutureOrResult<Model?> execute(String? params) => | ||||
|       _crudRepository.get(params!); | ||||
|   FutureOrResult<Model?> execute(String? params) => crudRepository.get(params!); | ||||
| } | ||||
|  | ||||
| @ -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<Model extends ObjectModel> extends AsyncUseCase<void, List<Model?>> | ||||
|     with ReadOperation<Model, void, List<Model?>> { | ||||
| class GetAll<Model> extends NoParamUsecase<List<Model?>> | ||||
|     with ReadOperation<void, List<Model?>> { | ||||
|   /// {@macro get_all} | ||||
|   const GetAll(this._crudRepository); | ||||
|   const GetAll(this.crudRepository); | ||||
| 
 | ||||
|   final CrudRepository<Model> _crudRepository; | ||||
|   final CrudRepository<Model> crudRepository; | ||||
| 
 | ||||
|   @override | ||||
|   FutureOrResult<List<Model?>> execute(void params) => _crudRepository.getAll(); | ||||
|   FutureOrResult<List<Model?>> execute(void params) => crudRepository.getAll(); | ||||
| } | ||||
|  | ||||
| @ -30,5 +30,5 @@ class StreamParameters { | ||||
|   final String? id; | ||||
| 
 | ||||
|   /// The conditions of the query. | ||||
|   final List<QueryInterface>? conditions; | ||||
|   final List<Query>? conditions; | ||||
| } | ||||
|  | ||||
| @ -14,33 +14,23 @@ | ||||
| // You should have received a copy of the GNU General Public License | ||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import '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<Model extends ObjectModel> | ||||
|     extends AsyncUseCase<List<QueryInterface>, List<Model?>> | ||||
|     with ReadOperation<Model, List<QueryInterface>, List<Model?>> { | ||||
|   /// {@macro query} | ||||
|   const Query(this._crudRepository); | ||||
| class Search<Model> extends Usecase<List<Query>, List<Model?>> | ||||
|     with ReadOperation<List<Query>, List<Model?>> { | ||||
|   /// {@macro search} | ||||
|   const Search(this.crudRepository); | ||||
| 
 | ||||
|   final CrudRepository<Model> _crudRepository; | ||||
|   final CrudRepository<Model> crudRepository; | ||||
| 
 | ||||
|   @override | ||||
|   FutureOr<void> onStart(List<QueryInterface>? params) { | ||||
|     if (params == null) { | ||||
|       throw const ClientException('List of conditions cannot be null.'); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   FutureOrResult<List<Model?>> execute(List<QueryInterface>? params) => | ||||
|       _crudRepository.query(params!); | ||||
|   FutureOrResult<List<Model?>> execute(List<Query>? params) => | ||||
|       crudRepository.search(params!); | ||||
| } | ||||
							
								
								
									
										44
									
								
								packages/wyatt_crud_bloc/lib/src/domain/usecases/stream.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -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 <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| 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<Model> | ||||
|     extends Usecase<StreamParameters, StreamResult<List<Model?>>> | ||||
|     with ReadOperation<StreamParameters, StreamResult<List<Model?>>> { | ||||
|   /// {@macro stream} | ||||
|   const Stream(this.crudRepository); | ||||
| 
 | ||||
|   final CrudRepository<Model> crudRepository; | ||||
| 
 | ||||
|   @override | ||||
|   FutureOrResult<StreamResult<List<Model?>>> execute( | ||||
|     StreamParameters? params, | ||||
|   ) async => | ||||
|       Ok( | ||||
|         crudRepository.stream( | ||||
|           id: params!.id, | ||||
|           conditions: params.conditions, | ||||
|         ), | ||||
|       ); | ||||
| } | ||||
| @ -14,35 +14,24 @@ | ||||
| // You should have received a copy of the GNU General Public License | ||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import '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<Model extends ObjectModel> | ||||
|     extends AsyncUseCase<UpdateParameters<Model>, void> | ||||
|     with UpdateOperation<Model, UpdateParameters<Model>> { | ||||
| class Update<Model> extends Usecase<UpdateParameters<Model>, void> | ||||
|     with UpdateOperation<UpdateParameters<Model>> { | ||||
|   /// {@macro update} | ||||
|   const Update(this._crudRepository); | ||||
|   const Update(this.crudRepository); | ||||
| 
 | ||||
|   final CrudRepository<Model> _crudRepository; | ||||
| 
 | ||||
|   @override | ||||
|   FutureOr<void> onStart(UpdateParameters<Model>? params) { | ||||
|     if (params == null) { | ||||
|       throw const ClientException('Update parameters cannot be null.'); | ||||
|     } | ||||
|   } | ||||
|   final CrudRepository<Model> crudRepository; | ||||
| 
 | ||||
|   @override | ||||
|   FutureOrResult<void> execute(UpdateParameters<Model>? params) => | ||||
|       _crudRepository.update( | ||||
|       crudRepository.update( | ||||
|         params!.id, | ||||
|         object: params.object, | ||||
|         raw: params.raw, | ||||
|  | ||||
| @ -14,32 +14,22 @@ | ||||
| // You should have received a copy of the GNU General Public License | ||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import '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<Model extends ObjectModel> | ||||
|     extends AsyncUseCase<Map<String, Object?>, void> | ||||
|     with UpdateOperation<Model, Map<String, Object?>> { | ||||
| class UpdateAll<Model> extends Usecase<Map<String, Object?>, void> | ||||
|     with UpdateOperation<Map<String, Object?>> { | ||||
|   /// {@macro update_all} | ||||
|   const UpdateAll(this._crudRepository); | ||||
|   const UpdateAll(this.crudRepository); | ||||
| 
 | ||||
|   final CrudRepository<Model> _crudRepository; | ||||
| 
 | ||||
|   @override | ||||
|   FutureOr<void> onStart(Map<String, Object?>? params) { | ||||
|     if (params == null) { | ||||
|       throw const ClientException('Data cannot be null.'); | ||||
|     } | ||||
|   } | ||||
|   final CrudRepository<Model> crudRepository; | ||||
| 
 | ||||
|   @override | ||||
|   FutureOrResult<void> execute(Map<String, Object?>? params) => | ||||
|       _crudRepository.updateAll(params!); | ||||
|       crudRepository.updateAll(params!); | ||||
| } | ||||
|  | ||||
| @ -14,12 +14,36 @@ | ||||
| // You should have received a copy of the GNU General Public License | ||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import '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<In, Out> extends AsyncUseCase<In, Out> { | ||||
|   const Usecase(); | ||||
| 
 | ||||
|   @override | ||||
|   FutureOr<void> onStart(In? params) { | ||||
|     if (params == null) { | ||||
|       throw ClientException('$In cannot be null.'); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   OperationType get operationType; | ||||
| } | ||||
| 
 | ||||
| abstract class NoParamUsecase<Out> extends AsyncUseCase<void, Out> { | ||||
|   const NoParamUsecase(); | ||||
| 
 | ||||
|   OperationType get operationType; | ||||
| } | ||||
|  | ||||
| @ -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<Model extends ObjectModel> | ||||
|     extends CrudBaseCubit { | ||||
| abstract class CrudAdvancedCubit<Model> extends CrudBaseCubit { | ||||
|   /// {@macro crud_cubit} | ||||
|   CrudAdvancedCubit() : super(); | ||||
| 
 | ||||
| @ -43,10 +42,14 @@ abstract class CrudAdvancedCubit<Model extends ObjectModel> | ||||
|   Delete<Model>? get crudDelete; | ||||
|   GetAll<Model>? get crudGetAll; | ||||
|   Get<Model>? get crudGet; | ||||
|   Query<Model>? get crudQuery; | ||||
|   Search<Model>? get crudSearch; | ||||
|   UpdateAll<Model>? get crudUpdateAll; | ||||
|   Update<Model>? get crudUpdate; | ||||
| 
 | ||||
|   /// Model identifier. | ||||
|   /// Used to identify a model. | ||||
|   ModelIdentifier<Model> get modelIdentifier; | ||||
| 
 | ||||
|   FutureOr<void> create(Model model) async { | ||||
|     final crud = crudCreate; | ||||
|     if (crud == null) { | ||||
| @ -54,7 +57,7 @@ abstract class CrudAdvancedCubit<Model extends ObjectModel> | ||||
|     } | ||||
| 
 | ||||
|     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<Model extends ObjectModel> | ||||
|             if (stateCopy.data == null) { | ||||
|               return CrudLoaded<Model?>(model); | ||||
|             } | ||||
|             if (stateCopy.data!.id == model.id) { | ||||
|             if (modelIdentifier.areEqual(stateCopy.data, model)) { | ||||
|               return CrudLoaded<Model?>(model); | ||||
|             } | ||||
| 
 | ||||
| @ -78,7 +81,7 @@ abstract class CrudAdvancedCubit<Model extends ObjectModel> | ||||
|             return CrudListLoaded<Model?>(lst); | ||||
|           } | ||||
| 
 | ||||
|           return const CrudOkReturn(); | ||||
|           return const CrudCreated(); | ||||
|         }, | ||||
|         (error) => CrudError(error.toString()), | ||||
|       ), | ||||
| @ -92,13 +95,16 @@ abstract class CrudAdvancedCubit<Model extends ObjectModel> | ||||
|     } | ||||
| 
 | ||||
|     final stateCopy = state; | ||||
|     emit(const CrudLoading()); | ||||
|     emit(const CrudDeleting()); | ||||
|     final result = await crud.call(id); | ||||
|     emit( | ||||
|       result.fold( | ||||
|         (_) { | ||||
|           if (stateCopy is CrudLoaded<Model?>) { | ||||
|             if (stateCopy.data?.id == id) { | ||||
|             if (modelIdentifier.isIdentifier( | ||||
|               model: stateCopy.data, | ||||
|               identifier: id, | ||||
|             )) { | ||||
|               return CrudLoaded<Model?>(null); | ||||
|             } | ||||
| 
 | ||||
| @ -106,11 +112,19 @@ abstract class CrudAdvancedCubit<Model extends ObjectModel> | ||||
|           } | ||||
|           if (stateCopy is CrudListLoaded<Model?>) { | ||||
|             return CrudListLoaded<Model?>( | ||||
|               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<Model extends ObjectModel> | ||||
|       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<Model extends ObjectModel> | ||||
|     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<Model extends ObjectModel> | ||||
|     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<Model extends ObjectModel> | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   FutureOr<void> query(List<QueryInterface> conditions) async { | ||||
|     final crud = crudQuery; | ||||
|   FutureOr<void> search(List<Query> 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<Model extends ObjectModel> | ||||
|     } | ||||
| 
 | ||||
|     final stateCopy = state; | ||||
|     emit(const CrudLoading()); | ||||
|     emit(const CrudUpdating()); | ||||
|     final result = await crud.call(param); | ||||
|     emit( | ||||
|       await result.foldAsync( | ||||
|         (_) async { | ||||
|           if (stateCopy is CrudLoaded<Model?>) { | ||||
|             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<Model extends ObjectModel> | ||||
|             return stateCopy; | ||||
|           } | ||||
|           if (stateCopy is CrudListLoaded<Model?>) { | ||||
|             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<Model extends ObjectModel> | ||||
|               } | ||||
|               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<Model?>(newList + [newVersion.ok]); | ||||
|               } | ||||
|             } | ||||
|             return stateCopy; | ||||
|           } | ||||
|           return const CrudOkReturn(); | ||||
|           return const CrudUpdated(); | ||||
|         }, | ||||
|         (error) async => CrudError(error.toString()), | ||||
|       ), | ||||
| @ -252,7 +282,7 @@ abstract class CrudAdvancedCubit<Model extends ObjectModel> | ||||
|     } | ||||
| 
 | ||||
|     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<Model extends ObjectModel> | ||||
|               // 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<Model?>(newVersion.ok); | ||||
| @ -272,8 +303,8 @@ abstract class CrudAdvancedCubit<Model extends ObjectModel> | ||||
|             return stateCopy; | ||||
|           } | ||||
|           if (stateCopy is CrudListLoaded<Model?>) { | ||||
|             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<Model extends ObjectModel> | ||||
|             // (not all because previous stateCopy can be a query result) | ||||
|             final List<String?> 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<Model extends ObjectModel> | ||||
|             } | ||||
|             return stateCopy; | ||||
|           } | ||||
|           return const CrudOkReturn(); | ||||
|           return const CrudUpdated(); | ||||
|         }, | ||||
|         (error) async => CrudError(error.toString()), | ||||
|       ), | ||||
|  | ||||
| @ -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. | ||||
|  | ||||
| @ -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<Model> = CreateOperation<Model, void>; | ||||
| typedef DefaultRead = ReadOperation<dynamic, dynamic>; | ||||
| typedef DefaultUpdate = UpdateOperation<dynamic>; | ||||
| typedef DefaultDelete = DeleteOperation<dynamic>; | ||||
| 
 | ||||
| /// {@template crud_cubit} | ||||
| /// Cubit that handles CRUD operations. | ||||
| /// Cubit that handles SCRUD operations. | ||||
| /// {@endtemplate} | ||||
| abstract class CrudCubit<Model extends ObjectModel> extends CrudBaseCubit { | ||||
| abstract class CrudCubit<Model> extends CrudBaseCubit { | ||||
|   /// {@macro crud_cubit} | ||||
|   CrudCubit() : super(); | ||||
| 
 | ||||
|   /// Create operation. | ||||
|   /// Can be create. | ||||
|   CreateOperation<Model, dynamic>? get createOperation; | ||||
|   CreateOperation<Model, void>? get createOperation; | ||||
| 
 | ||||
|   /// Read operation. | ||||
|   /// Can be get, getAll, query. | ||||
|   ReadOperation<Model, dynamic, dynamic>? get readOperation; | ||||
|   /// Can be get, getAll, search or stream. | ||||
|   ReadOperation<dynamic, dynamic>? get readOperation; | ||||
| 
 | ||||
|   /// Update operation. | ||||
|   /// Can be update, updateAll. | ||||
|   UpdateOperation<Model, dynamic>? get updateOperation; | ||||
|   UpdateOperation<dynamic>? get updateOperation; | ||||
| 
 | ||||
|   /// Delete operation. | ||||
|   /// Can be delete or deleteAll. | ||||
|   DeleteOperation<Model, dynamic>? get deleteOperation; | ||||
|   DeleteOperation<dynamic>? get deleteOperation; | ||||
| 
 | ||||
|   /// Model identifier. | ||||
|   /// Used to identify a model. | ||||
|   ModelIdentifier<Model> get modelIdentifier; | ||||
| 
 | ||||
|   Expected? _checkOperation<Expected>(dynamic operation) { | ||||
|     if (operation == null) { | ||||
| @ -70,27 +79,27 @@ abstract class CrudCubit<Model extends ObjectModel> extends CrudBaseCubit { | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   FutureOr<void> read({String? id, List<QueryInterface>? conditions}) async { | ||||
|   FutureOr<void> read({String? id, List<Query>? conditions}) async { | ||||
|     if (_checkOperation<Get<Model>>(readOperation) != null && id != null) { | ||||
|       return _get(id); | ||||
|     } | ||||
|     if (_checkOperation<GetAll<Model>>(readOperation) != null) { | ||||
|       return _getAll(); | ||||
|     } | ||||
|     if (_checkOperation<Query<Model>>(readOperation) != null && | ||||
|     if (_checkOperation<Search<Model>>(readOperation) != null && | ||||
|         conditions != null) { | ||||
|       return _query(conditions); | ||||
|       return _search(conditions); | ||||
|     } | ||||
|     if (_checkOperation<Query<Model>>(readOperation) != null && | ||||
|     if (_checkOperation<Stream<Model>>(readOperation) != null && | ||||
|         conditions == null) { | ||||
|       return _getAll(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   FutureOr<void> update( | ||||
|   FutureOr<void> update({ | ||||
|     UpdateParameters<Model>? single, | ||||
|     Map<String, dynamic>? all, | ||||
|   ) async { | ||||
|   }) async { | ||||
|     if (_checkOperation<Update<Model>>(updateOperation) != null && | ||||
|         single != null) { | ||||
|       return _update(single); | ||||
| @ -118,7 +127,7 @@ abstract class CrudCubit<Model extends ObjectModel> 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<Model extends ObjectModel> extends CrudBaseCubit { | ||||
|             if (stateCopy.data == null) { | ||||
|               return CrudLoaded<Model?>(model); | ||||
|             } | ||||
|             if (stateCopy.data!.id == model.id) { | ||||
|             if (stateCopy.data == model) { | ||||
|               return CrudLoaded<Model?>(model); | ||||
|             } | ||||
| 
 | ||||
| @ -142,7 +151,7 @@ abstract class CrudCubit<Model extends ObjectModel> extends CrudBaseCubit { | ||||
|             return CrudListLoaded<Model?>(lst); | ||||
|           } | ||||
| 
 | ||||
|           return const CrudOkReturn(); | ||||
|           return const CrudCreated(); | ||||
|         }, | ||||
|         (error) => CrudError(error.toString()), | ||||
|       ), | ||||
| @ -156,13 +165,16 @@ abstract class CrudCubit<Model extends ObjectModel> extends CrudBaseCubit { | ||||
|     } | ||||
| 
 | ||||
|     final stateCopy = state; | ||||
|     emit(const CrudLoading()); | ||||
|     emit(const CrudDeleting()); | ||||
|     final result = await crud.call(id); | ||||
|     emit( | ||||
|       result.fold( | ||||
|         (_) { | ||||
|           if (stateCopy is CrudLoaded<Model?>) { | ||||
|             if (stateCopy.data?.id == id) { | ||||
|             if (modelIdentifier.isIdentifier( | ||||
|               model: stateCopy.data, | ||||
|               identifier: id, | ||||
|             )) { | ||||
|               return CrudLoaded<Model?>(null); | ||||
|             } | ||||
| 
 | ||||
| @ -170,11 +182,19 @@ abstract class CrudCubit<Model extends ObjectModel> extends CrudBaseCubit { | ||||
|           } | ||||
|           if (stateCopy is CrudListLoaded<Model?>) { | ||||
|             return CrudListLoaded<Model?>( | ||||
|               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<Model extends ObjectModel> 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<Model extends ObjectModel> extends CrudBaseCubit { | ||||
|             return CrudListLoaded<Model?>(const []); | ||||
|           } | ||||
| 
 | ||||
|           return const CrudOkReturn(); | ||||
|           return const CrudDeleted(); | ||||
|         }, | ||||
|         (error) => CrudError(error.toString()), | ||||
|       ), | ||||
| @ -211,7 +231,7 @@ abstract class CrudCubit<Model extends ObjectModel> 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<Model extends ObjectModel> 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<Model extends ObjectModel> extends CrudBaseCubit { | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   FutureOr<void> _query(List<QueryInterface> conditions) async { | ||||
|     final crud = _checkOperation<Query<Model>>(readOperation); | ||||
|   FutureOr<void> _search(List<Query> conditions) async { | ||||
|     final crud = _checkOperation<Search<Model>>(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<Model extends ObjectModel> 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<Model?>) { | ||||
|             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<Get<Model>>(readOperation); | ||||
|               if (crudGet == null) { | ||||
| @ -280,29 +303,48 @@ abstract class CrudCubit<Model extends ObjectModel> extends CrudBaseCubit { | ||||
|             return stateCopy; | ||||
|           } | ||||
|           if (stateCopy is CrudListLoaded<Model?>) { | ||||
|             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<Get<Model>>(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) => 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<Model?>(newList + [newVersion.ok]); | ||||
|                 } | ||||
|               } | ||||
| 
 | ||||
|               // If get operation is not available, just reload all objects. | ||||
|               final crudGetAll = _checkOperation<GetAll<Model>>(readOperation); | ||||
|               if (crudGetAll != null) { | ||||
|                 final newVersion = await crudGetAll.call(null); | ||||
|                 if (newVersion.isOk) { | ||||
|                   return CrudListLoaded<Model?>(newVersion.ok ?? []); | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|             return stateCopy; | ||||
|           } | ||||
|           return const CrudOkReturn(); | ||||
|           return const CrudUpdated(); | ||||
|         }, | ||||
|         (error) async => CrudError(error.toString()), | ||||
|       ), | ||||
| @ -316,7 +358,7 @@ abstract class CrudCubit<Model extends ObjectModel> 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<Model extends ObjectModel> 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<Model?>(newVersion.ok); | ||||
| @ -336,7 +379,7 @@ abstract class CrudCubit<Model extends ObjectModel> extends CrudBaseCubit { | ||||
|             return stateCopy; | ||||
|           } | ||||
|           if (stateCopy is CrudListLoaded<Model?>) { | ||||
|             final crudQuery = _checkOperation<Query<Model>>(readOperation); | ||||
|             final crudQuery = _checkOperation<Search<Model>>(readOperation); | ||||
|             if (crudQuery == null) { | ||||
|               // No read operation, can't update stateCopy. | ||||
|               return stateCopy; | ||||
| @ -345,8 +388,9 @@ abstract class CrudCubit<Model extends ObjectModel> extends CrudBaseCubit { | ||||
|             // (not all because previous stateCopy can be a query result) | ||||
|             final List<String?> 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<Model extends ObjectModel> extends CrudBaseCubit { | ||||
|             } | ||||
|             return stateCopy; | ||||
|           } | ||||
|           return const CrudOkReturn(); | ||||
|           return const CrudUpdated(); | ||||
|         }, | ||||
|         (error) async => CrudError(error.toString()), | ||||
|       ), | ||||
|  | ||||
| @ -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 <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| export 'crud_builder.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'; | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
							
								
								
									
										1
									
								
								packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.gitignore
									
									
									
									
										vendored
									
									
										Symbolic link
									
								
							
							
						
						| @ -0,0 +1 @@ | ||||
| ../../../.gitignore | ||||
							
								
								
									
										10
									
								
								packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.metadata
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -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 | ||||
							
								
								
									
										1
									
								
								packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.pubignore
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						| @ -0,0 +1 @@ | ||||
| ../../../.pubignore | ||||
							
								
								
									
										1
									
								
								packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/AUTHORS
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						| @ -0,0 +1 @@ | ||||
| ../../../AUTHORS | ||||