feat(crud)!: move crud firestore implementation into his own package

This commit is contained in:
Hugo Pointcheval 2023-11-13 18:03:10 +01:00
parent af841baefb
commit 74593fa9fc
Signed by: hugo
GPG Key ID: 3AAC487E131E00BC
107 changed files with 1392 additions and 2410 deletions

View File

@ -44,5 +44,3 @@ app.*.map.json
/android/app/debug
/android/app/profile
/android/app/release
/lib/firebase_options.dart

View File

@ -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

View File

@ -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 {}

View File

@ -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"/>

View File

@ -1,7 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.crud_bloc_example">
<application
android:label="crud_bloc_example"
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:label="example"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity

View File

@ -1,4 +1,4 @@
package com.example.crud_bloc_example
package com.example.example
import io.flutter.embedding.android.FlutterActivity

View File

@ -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.

View File

@ -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.

View File

@ -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"/>

View File

@ -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
}

View File

@ -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

View File

@ -1,11 +1,20 @@
include ':app'
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}
settings.ext.flutterSdkPath = flutterSdkPath()
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
plugins {
id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false
}
}
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
include ":app"
apply from: "${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle/app_plugin_loader.gradle"

View File

@ -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

View File

@ -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>

View File

@ -1,2 +0,0 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

View File

@ -1,2 +0,0 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

View File

@ -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

View File

@ -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

View File

@ -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 */;
}

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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)
}
}

View File

@ -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"
}
}

View File

@ -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"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 B

View File

@ -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.

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -1 +0,0 @@
#import "GeneratedPluginRegistrant.h"

View 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),
],
);
}),
),
);
}
}

View File

@ -14,41 +14,43 @@
// 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(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
),
);
}
@ -63,60 +65,32 @@ class MyHomePage extends StatelessWidget {
appBar: AppBar(
title: const Text('Flutter Demo Home Page'),
),
body: SingleChildScrollView(
child: Column(
children: [
const SizedBox(height: 20),
const Text("Data:"),
BlocBuilder<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"),
);
},
),
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: const Text("Create"),
),
ElevatedButton(
onPressed: () {
context.read<UserCubit>().read();
},
child: const Text("GetAll"),
),
const SizedBox(height: 20),
],
),
body: Column(
children: [
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const BasicCubitView(),
),
);
},
child: const Text('Basic example'),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const AdvancedCubitView(),
),
);
},
child: const Text('Advanced example'),
),
],
),
);
}

View 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),
],
);
}),
),
);
}
}

View 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',
);
}

View 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,
));
}

View File

@ -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,
));
}

View File

@ -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);
}

View File

@ -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 ?? '',
);
}

View File

@ -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];
}

View File

@ -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)';
}

View 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,
};

View File

@ -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

View File

@ -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';

View File

@ -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,
}

View File

@ -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

View File

@ -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;
}

View 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);
}
}

View File

@ -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;
}

View File

@ -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';

View File

@ -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,
});
}

View File

@ -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;

View File

@ -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());
});

View File

@ -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';

View File

@ -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';

View File

@ -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});

View File

@ -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,
});
}

View File

@ -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';

View File

@ -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);
}

View File

@ -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!);
}

View File

@ -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();
}

View File

@ -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!);
}

View File

@ -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();
}

View File

@ -30,5 +30,5 @@ class StreamParameters {
final String? id;
/// The conditions of the query.
final List<QueryInterface>? conditions;
final List<Query>? conditions;
}

View File

@ -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!);
}

View 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,
),
);
}

View File

@ -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,

View File

@ -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!);
}

View File

@ -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;
}

View File

@ -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()),
),

View File

@ -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.

View File

@ -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) {
if (element == null) {
return false;
}
return !modelIdentifier.isIdentifier(
model: element,
identifier: param.id,
);
},
).toList();
return CrudListLoaded<Model?>(newList + [newVersion.ok]);
}
}
final newVersion = await crudGet.call(param.id);
if (newVersion.isOk) {
final newList = stateCopy.data
.where(
(element) => element?.id != param.id,
)
.toList();
return CrudListLoaded<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()),
),

View File

@ -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';

View File

@ -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';

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
../../../.gitignore

View 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

View File

@ -0,0 +1 @@
../../../.pubignore

View File

@ -0,0 +1 @@
../../../AUTHORS

Some files were not shown because too many files have changed in this diff Show More