diff --git a/CHANGELOG.md b/CHANGELOG.md index 09a90c3e..c9a9c1d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,47 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## 2023-11-14 + +### Changes + +--- + +Packages with breaking changes: + + - [`wyatt_crud_bloc` - `v0.2.0`](#wyatt_crud_bloc---v020) + - [`wyatt_crud_bloc_firestore` - `v0.2.0`](#wyatt_crud_bloc_firestore---v020) + +Packages with other changes: + + - [`wyatt_bloc_layout` - `v0.1.2+4`](#wyatt_bloc_layout---v0124) + +Packages with dependency updates only: + +> Packages listed below depend on other packages in this workspace that have had changes. Their versions have been incremented to bump the minimum dependency versions of the packages they depend upon in this project. + + - `wyatt_bloc_layout` - `v0.1.2+4` + +--- + +#### `wyatt_crud_bloc` - `v0.2.0` + + - **REFACTOR**: make CrudLoading instanciable. + - **FIX**: rename wyatt_bruc_bloc_firestore main package file. + - **FIX**: apply dart format. + - **FIX**: apply dart fix --apply. + - **FEAT**(crud): add streaming usecase (closes #180). + - **DOCS**(crud): update readme. + - **BREAKING** **FEAT**(crud): make crudbuilder integration more easy by integrating blocbuilder (closes #181). + - **BREAKING** **FEAT**(crud): move crud firestore implementation into his own package. + +#### `wyatt_crud_bloc_firestore` - `v0.2.0` + + - **FIX**: rename wyatt_bruc_bloc_firestore main package file. + - **DOCS**(crud): update readme. + - **BREAKING** **FEAT**(crud): move crud firestore implementation into his own package. + + ## 2023-10-04 ### Changes diff --git a/packages/wyatt_bloc_layout/CHANGELOG.md b/packages/wyatt_bloc_layout/CHANGELOG.md index 95ead937..b04ce841 100644 --- a/packages/wyatt_bloc_layout/CHANGELOG.md +++ b/packages/wyatt_bloc_layout/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.2+4 + + - Update a dependency to the latest release. + ## 0.1.2+3 - Update a dependency to the latest release. diff --git a/packages/wyatt_bloc_layout/example/pubspec.yaml b/packages/wyatt_bloc_layout/example/pubspec.yaml index 561efbaa..2ec7576e 100644 --- a/packages/wyatt_bloc_layout/example/pubspec.yaml +++ b/packages/wyatt_bloc_layout/example/pubspec.yaml @@ -42,7 +42,7 @@ dependencies: version: ^0.1.2+3 wyatt_crud_bloc: hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub - version: ^0.1.1+1 + version: ^0.2.0 wyatt_ui_components: hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub version: ^0.3.0+2 diff --git a/packages/wyatt_bloc_layout/lib/src/core/crud_cubit_consumer_screen_mixin.dart b/packages/wyatt_bloc_layout/lib/src/core/crud_cubit_consumer_screen_mixin.dart index a549af5b..b5798454 100644 --- a/packages/wyatt_bloc_layout/lib/src/core/crud_cubit_consumer_screen_mixin.dart +++ b/packages/wyatt_bloc_layout/lib/src/core/crud_cubit_consumer_screen_mixin.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify @@ -16,11 +16,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart' as bloc_base; - import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; import 'package:wyatt_ui_components/wyatt_ui_components.dart'; -mixin CrudMixin, +mixin CrudMixin, SuccessState extends CrudSuccess> { String? get loaderComponentId => null; String? get errorComponentId => null; @@ -40,11 +39,10 @@ mixin CrudMixin, Widget successBuilder(BuildContext context, SuccessState state); Widget crudBuilder(BuildContext context, CrudState state) => - CrudBuilder( + CrudBuilder( errorBuilder: errorBuilder, loadingBuilder: loadingBuilder, initialBuilder: initialBuilder, - state: state, builder: successBuilder, ); } diff --git a/packages/wyatt_bloc_layout/pubspec.yaml b/packages/wyatt_bloc_layout/pubspec.yaml index 002ff776..7488bd3a 100644 --- a/packages/wyatt_bloc_layout/pubspec.yaml +++ b/packages/wyatt_bloc_layout/pubspec.yaml @@ -1,7 +1,7 @@ name: wyatt_bloc_layout description: Layouts based on bloc helper library repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_bloc_layout -version: 0.1.2+3 +version: 0.1.2+4 publish_to: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub @@ -23,7 +23,7 @@ dependencies: wyatt_crud_bloc: hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub - version: ^0.1.1+1 + version: ^0.2.0 wyatt_ui_components: hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub diff --git a/packages/wyatt_crud_bloc/CHANGELOG.md b/packages/wyatt_crud_bloc/CHANGELOG.md index 4cea9759..020f78cf 100644 --- a/packages/wyatt_crud_bloc/CHANGELOG.md +++ b/packages/wyatt_crud_bloc/CHANGELOG.md @@ -1,3 +1,16 @@ +## 0.2.0 + +> Note: This release has breaking changes. + + - **REFACTOR**: make CrudLoading instanciable. + - **FIX**: rename wyatt_bruc_bloc_firestore main package file. + - **FIX**: apply dart format. + - **FIX**: apply dart fix --apply. + - **FEAT**(crud): add streaming usecase (closes #180). + - **DOCS**(crud): update readme. + - **BREAKING** **FEAT**(crud): make crudbuilder integration more easy by integrating blocbuilder (closes #181). + - **BREAKING** **FEAT**(crud): move crud firestore implementation into his own package. + ## 0.1.1+1 - **FIX**: apply dart format. diff --git a/packages/wyatt_crud_bloc/README.md b/packages/wyatt_crud_bloc/README.md index 4f483186..f5932c72 100644 --- a/packages/wyatt_crud_bloc/README.md +++ b/packages/wyatt_crud_bloc/README.md @@ -27,10 +27,7 @@ CRUD Bloc Pattern utilities for Flutter. This package defines a set of classes that can be used to implement the CRUD Bloc Pattern. -* Model * Data Source - + In Memory - + Firestore * Repository * Use Case + Create @@ -40,128 +37,207 @@ This package defines a set of classes that can be used to implement the CRUD Blo + Update All + Delete + Delete All - + Query + + Search * Bloc + Standard (C R U D), you have to choose the responsiblity of the bloc for each use case. For example, you can have a cubit that only handles the creation of an entity, and another cubit that only handles the deletion of an entity. Each cubit can only have one operation responsibility of each type, for example you can't have a cubit that handles get and get all. + Advanced, you can set every use case to be handled by the bloc. This is useful if you want to have a single bloc that handles all the operations of an entity. ## Usage -Create a model class that extends the `ObjectModel` class. +Create your entity using Wyatt Architecture and Equatable ```dart -class User extends ObjectModel { - @override +import 'package:equatable/equatable.dart'; +import 'package:wyatt_architecture/wyatt_architecture.dart'; + +class User extends Entity with EquatableMixin { final String? id; - final String? name; - + final String name; + final String email; + final String phone; + const User({ required this.name, + required this.email, + required this.phone, this.id, }); - Map toMap() { - return { - 'name': name ?? '', - }; - } - @override - String toString() => 'User(id: $id, name: $name)'; + List get props => [id, name, email, phone]; } ``` -You have to implement a bloc. +Then, you can create your model for this entity with Freezed, JsonSerializable or any other library. ```dart +import 'package:crud_bloc_example/user_entity.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'user_model.g.dart'; + +@JsonSerializable() +class UserModel extends User { + UserModel({ + super.id, + required super.name, + required super.email, + required super.phone, + }); + + factory UserModel.fromJson(Map json) => + _$UserModelFromJson(json); + + Map toJson() => _$UserModelToJson(this); + + @override + String toString() => + 'UserModel(id: $id, name: $name, email: $email, phone: $phone)'; +} +``` + +> This exemple uses JsonSerializable to generate the model, but you can use any other library. Or you can even create your own model without any library. + +Then you have to create a **CRUD** Cubit. Each Crud cubit can only handle one operation of each type. For example, you can't have a cubit that handles get and get all. (See the `CrudAdvancedCubit` for this use case). + +You also have to create a `modelIdentifier` that will be used to identify your model. This is used to identify the model in the state of the cubit. For example, if you have a list of users, you can use the id of the user to identify it in the state. **It's up to you to choose how you want to identify your model.** + +```dart +import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; + /// A [CrudCubit] for [User]. class UserCubit extends CrudCubit { - final CrudRepository _crudRepository; + final CrudRepository crudRepository; - UserCubit(this._crudRepository); + UserCubit(this.crudRepository); @override - CreateOperation? get createOperation => - Create(_crudRepository); + DefaultCreate? get createOperation => Create(crudRepository); @override - DeleteOperation? get deleteOperation => - Delete(_crudRepository); + DefaultDelete? get deleteOperation => Delete(crudRepository); @override - ReadOperation? get readOperation => - GetAll(_crudRepository); + DefaultRead? get readOperation => GetAll(crudRepository); @override - UpdateOperation? get updateOperation => - Update(_crudRepository); + DefaultUpdate? get updateOperation => Update(crudRepository); + + @override + ModelIdentifier get modelIdentifier => ModelIdentifier( + getIdentifier: (user) => user.id ?? '', + ); } ``` -> You can also use the `CrudAdvancedCubit` class to implement a bloc that handles all the use cases. +> In this example, the `modelIdentifier` is the id of the user. But you can use any other property of the user to identify it. But make sure that the property you use is unique. -Then you can use the bloc in your widget with a data source and a repository. +> In this example, the `CrudCubit` handles `Create`, `Delete`, `GetAll` and `Update` operations. But you can choose which operation you want to handle. For example, you can have a cubit that only handles the creation of an entity, and another cubit that only handles the deletion of an entity. + +Then you can configure the data source and the repository. + +### In Memory + +The base implementation of the data source is the `CrudInMemoryDataSourceImpl`. This data source stores the data in memory. This is useful for testing. ```dart -class MyApp extends StatelessWidget { - const MyApp({Key? key}) : super(key: key); - - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - final CrudDataSource userLocalDataSource = - CrudInMemoryDataSourceImpl(toMap: (user) => user.toMap()); - - final CrudRepository userRepository = - CrudRepositoryImpl(crudDataSource: userLocalDataSource); - - return RepositoryProvider>.value( - value: userRepository, - child: BlocProvider( - create: (context) => UserCubit(userRepository)..read(), - child: MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: const MyHomePage(), - ), - ), - ); - } -} +final CrudDataSource crudDataSource = CrudDataSourceInMemoryImpl( + id: (operation, json) => json['id'] as String?, +); ``` -And anywhere in your widget tree you can use the BlocBuilder to build your widget. +> The `id` parameter is used to get the id of the raw data. You can use the `operation` parameter to get the operation that is being performed. This is useful if you want to have different ids for each operation. For example, you can have a different id for the creation and the update of an entity. + +### Firestore + +You can use the `CrudFirestoreDataSourceImpl` to store your data in Firestore. + +Make sure to add the `wyatt_crud_bloc_firestore` package to your dependencies. + +```dart +final CrudDataSource crudDataSource = CrudDataSourceFirestoreImpl( + 'users', + id: (_, json) => json['id'] as String, + fromFirestore: (document, snapshot) => document.data() ?? {}, + toFirestore: (object, options) => object, +); +``` + +> The `id` parameter is used to get the id of the raw data. You can use the `operation` parameter to get the operation that is being performed. This is useful if you want to have different ids for each operation. For example, you can have a different id for the creation and the update of an entity. + +> The `fromFirestore` and `toFirestore` parameters are used to convert the data from and to Firestore. + +Finally, you can use the `CrudRepositoryImpl` to create your repository. + +```dart +final CrudRepository userRepository = CrudRepositoryImpl( + crudDataSource: crudDataSource, + modelMapper: ModelMapper( + fromJson: (json) => UserModel.fromJson(json ?? {}), + toJson: (user) => UserModel( + id: user.id, + name: user.name, + email: user.email, + phone: user.phone, + ).toJson(), + ), +); +``` + +> The `modelMapper` parameter is used to convert the data from and to the model. In the `toJson` make sure to use the same data structure as the one used in the data source. For example the previous `id()` function is used to get the id of the raw data, if `id` is missing from the raw data, the `id()` function will not works. + +And in your widget tree you can use the `CrudBuilder` to build your UI. ```dart ... BlocBuilder( + buildWhen: (previous, current) { + if (current is CrudLoading && current is! CrudReading) { + return false; + } + return true; + }, builder: (context, state) { - return CrudBuilder.typed>( - state: state, - builder: ((context, state) { - return ListView.builder( - shrinkWrap: true, - itemCount: state.data.length, - itemBuilder: (context, index) { - final user = state.data.elementAt(index); - return ListTile( - title: Text(user?.name ?? 'Error'), - subtitle: Text(user?.id ?? 'Error'), - onTap: () { - context.read().delete(id: (user?.id)!); - }, - ); - }, - ); - }), - initialBuilder: (context, state) => const Text("Loading..."), - loadingBuilder: (context, state) => const Text("Loading..."), - errorBuilder: (context, state) => Text("Error: $state"), + return Expanded( + child: CrudBuilder.typed>( + state: state, + builder: ((context, state) { + return ListView.builder( + itemCount: state.data.length, + itemBuilder: (context, index) { + final user = state.data.elementAt(index); + return ListTile( + title: Text(user?.name ?? 'Error'), + subtitle: Text(user?.email ?? 'Error'), + onTap: () { + context + .read() + .delete(id: (user?.id)!); + }, + onLongPress: () { + context.read().update( + single: UpdateParameters( + id: user?.id ?? '', + raw: { + 'email': '${user?.id}@updated.io', + }), + ); + }, + ); + }, + ); + }), + initialBuilder: (context, state) => + const Center(child: CircularProgressIndicator()), + loadingBuilder: (context, state) => + const Center(child: CircularProgressIndicator()), + errorBuilder: (context, state) => Text("Error: $state"), + ), ); }, ), ... ``` + +> This piece of code is used to build a list of users. When you tap on a user, it will delete it. When you long press on a user, it will update it. Also, the loading state is not always displayed, it will only be displayed when the state is `CrudReading`, so when the state is `CrudUpdating` or `CrudDeleting`, the loading state will not be displayed. diff --git a/packages/wyatt_crud_bloc/example/.gitignore b/packages/wyatt_crud_bloc/example/.gitignore index c3b6d4c7..0fa6b675 100644 --- a/packages/wyatt_crud_bloc/example/.gitignore +++ b/packages/wyatt_crud_bloc/example/.gitignore @@ -44,5 +44,3 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release - -/lib/firebase_options.dart \ No newline at end of file diff --git a/packages/wyatt_crud_bloc/example/.metadata b/packages/wyatt_crud_bloc/example/.metadata index 56512842..a072c7d9 100644 --- a/packages/wyatt_crud_bloc/example/.metadata +++ b/packages/wyatt_crud_bloc/example/.metadata @@ -1,11 +1,11 @@ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # -# This file should be version controlled. +# This file should be version controlled and should not be manually edited. version: - revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 - channel: stable + revision: "d211f42860350d914a5ad8102f9ec32764dc6d06" + channel: "stable" project_type: app @@ -13,11 +13,11 @@ project_type: app migration: platforms: - platform: root - create_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 - base_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 - - platform: ios - create_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 - base_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 + create_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 + base_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 + - platform: android + create_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 + base_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 # User provided section diff --git a/packages/wyatt_crud_bloc/example/android/app/build.gradle b/packages/wyatt_crud_bloc/example/android/app/build.gradle index 8ddaae13..0b93b1c2 100644 --- a/packages/wyatt_crud_bloc/example/android/app/build.gradle +++ b/packages/wyatt_crud_bloc/example/android/app/build.gradle @@ -1,3 +1,9 @@ +plugins { + id "com.android.application" + id "kotlin-android" + id "dev.flutter.flutter-gradle-plugin" +} + def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { @@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) { } } -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' @@ -21,15 +22,10 @@ if (flutterVersionName == null) { flutterVersionName = '1.0' } -apply plugin: 'com.android.application' -// START: FlutterFire Configuration -apply plugin: 'com.google.gms.google-services' -// END: FlutterFire Configuration -apply plugin: 'kotlin-android' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - android { + namespace "com.example.example" compileSdkVersion flutter.compileSdkVersion + ndkVersion flutter.ndkVersion compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 @@ -47,6 +43,8 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.crud_bloc_example" + // You can update the following values to match your application needs. + // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. minSdkVersion 21 targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() @@ -66,6 +64,4 @@ flutter { source '../..' } -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" -} +dependencies {} diff --git a/packages/wyatt_crud_bloc/example/android/app/src/debug/AndroidManifest.xml b/packages/wyatt_crud_bloc/example/android/app/src/debug/AndroidManifest.xml index e9dd957b..399f6981 100644 --- a/packages/wyatt_crud_bloc/example/android/app/src/debug/AndroidManifest.xml +++ b/packages/wyatt_crud_bloc/example/android/app/src/debug/AndroidManifest.xml @@ -1,6 +1,6 @@ - - diff --git a/packages/wyatt_crud_bloc/example/android/app/src/main/AndroidManifest.xml b/packages/wyatt_crud_bloc/example/android/app/src/main/AndroidManifest.xml index 082c9cb4..19b862ec 100644 --- a/packages/wyatt_crud_bloc/example/android/app/src/main/AndroidManifest.xml +++ b/packages/wyatt_crud_bloc/example/android/app/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ - - + diff --git a/packages/wyatt_crud_bloc/example/android/build.gradle b/packages/wyatt_crud_bloc/example/android/build.gradle index 111a0724..0391438f 100644 --- a/packages/wyatt_crud_bloc/example/android/build.gradle +++ b/packages/wyatt_crud_bloc/example/android/build.gradle @@ -1,12 +1,12 @@ buildscript { - ext.kotlin_version = '1.6.10' + ext.kotlin_version = '1.7.10' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:4.1.0' + classpath 'com.android.tools.build:gradle:7.3.0' // START: FlutterFire Configuration classpath 'com.google.gms:google-services:4.3.10' // END: FlutterFire Configuration @@ -29,6 +29,6 @@ subprojects { project.evaluationDependsOn(':app') } -task clean(type: Delete) { +tasks.register("clean", Delete) { delete rootProject.buildDir } diff --git a/packages/wyatt_crud_bloc/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/wyatt_crud_bloc/example/android/gradle/wrapper/gradle-wrapper.properties index bc6a58af..3c472b99 100644 --- a/packages/wyatt_crud_bloc/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/wyatt_crud_bloc/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip diff --git a/packages/wyatt_crud_bloc/example/android/settings.gradle b/packages/wyatt_crud_bloc/example/android/settings.gradle index 44e62bcf..55c4ca8b 100644 --- a/packages/wyatt_crud_bloc/example/android/settings.gradle +++ b/packages/wyatt_crud_bloc/example/android/settings.gradle @@ -1,11 +1,20 @@ -include ':app' +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + } + settings.ext.flutterSdkPath = flutterSdkPath() -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() + includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + plugins { + id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false + } +} -def flutterSdkPath = properties.getProperty("flutter.sdk") -assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" +include ":app" + +apply from: "${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/packages/wyatt_crud_bloc/example/ios/.gitignore b/packages/wyatt_crud_bloc/example/ios/.gitignore deleted file mode 100644 index 7a7f9873..00000000 --- a/packages/wyatt_crud_bloc/example/ios/.gitignore +++ /dev/null @@ -1,34 +0,0 @@ -**/dgph -*.mode1v3 -*.mode2v3 -*.moved-aside -*.pbxuser -*.perspectivev3 -**/*sync/ -.sconsign.dblite -.tags* -**/.vagrant/ -**/DerivedData/ -Icon? -**/Pods/ -**/.symlinks/ -profile -xcuserdata -**/.generated/ -Flutter/App.framework -Flutter/Flutter.framework -Flutter/Flutter.podspec -Flutter/Generated.xcconfig -Flutter/ephemeral/ -Flutter/app.flx -Flutter/app.zip -Flutter/flutter_assets/ -Flutter/flutter_export_environment.sh -ServiceDefinitions.json -Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!default.mode1v3 -!default.mode2v3 -!default.pbxuser -!default.perspectivev3 diff --git a/packages/wyatt_crud_bloc/example/ios/Flutter/AppFrameworkInfo.plist b/packages/wyatt_crud_bloc/example/ios/Flutter/AppFrameworkInfo.plist deleted file mode 100644 index 9625e105..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Flutter/AppFrameworkInfo.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - MinimumOSVersion - 11.0 - - diff --git a/packages/wyatt_crud_bloc/example/ios/Flutter/Debug.xcconfig b/packages/wyatt_crud_bloc/example/ios/Flutter/Debug.xcconfig deleted file mode 100644 index ec97fc6f..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" -#include "Generated.xcconfig" diff --git a/packages/wyatt_crud_bloc/example/ios/Flutter/Release.xcconfig b/packages/wyatt_crud_bloc/example/ios/Flutter/Release.xcconfig deleted file mode 100644 index c4855bfe..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" -#include "Generated.xcconfig" diff --git a/packages/wyatt_crud_bloc/example/ios/Podfile b/packages/wyatt_crud_bloc/example/ios/Podfile deleted file mode 100644 index 88359b22..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Podfile +++ /dev/null @@ -1,41 +0,0 @@ -# Uncomment this line to define a global platform for your project -# platform :ios, '11.0' - -# CocoaPods analytics sends network stats synchronously affecting flutter build latency. -ENV['COCOAPODS_DISABLE_STATS'] = 'true' - -project 'Runner', { - 'Debug' => :debug, - 'Profile' => :release, - 'Release' => :release, -} - -def flutter_root - generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) - unless File.exist?(generated_xcode_build_settings_path) - raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" - end - - File.foreach(generated_xcode_build_settings_path) do |line| - matches = line.match(/FLUTTER_ROOT\=(.*)/) - return matches[1].strip if matches - end - raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" -end - -require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) - -flutter_ios_podfile_setup - -target 'Runner' do - use_frameworks! - use_modular_headers! - - flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) -end - -post_install do |installer| - installer.pods_project.targets.each do |target| - flutter_additional_ios_build_settings(target) - end -end diff --git a/packages/wyatt_crud_bloc/example/ios/Podfile.lock b/packages/wyatt_crud_bloc/example/ios/Podfile.lock deleted file mode 100644 index 8339868b..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Podfile.lock +++ /dev/null @@ -1,757 +0,0 @@ -PODS: - - abseil/algorithm (1.20211102.0): - - abseil/algorithm/algorithm (= 1.20211102.0) - - abseil/algorithm/container (= 1.20211102.0) - - abseil/algorithm/algorithm (1.20211102.0): - - abseil/base/config - - abseil/algorithm/container (1.20211102.0): - - abseil/algorithm/algorithm - - abseil/base/core_headers - - abseil/meta/type_traits - - abseil/base (1.20211102.0): - - abseil/base/atomic_hook (= 1.20211102.0) - - abseil/base/base (= 1.20211102.0) - - abseil/base/base_internal (= 1.20211102.0) - - abseil/base/config (= 1.20211102.0) - - abseil/base/core_headers (= 1.20211102.0) - - abseil/base/dynamic_annotations (= 1.20211102.0) - - abseil/base/endian (= 1.20211102.0) - - abseil/base/errno_saver (= 1.20211102.0) - - abseil/base/fast_type_id (= 1.20211102.0) - - abseil/base/log_severity (= 1.20211102.0) - - abseil/base/malloc_internal (= 1.20211102.0) - - abseil/base/pretty_function (= 1.20211102.0) - - abseil/base/raw_logging_internal (= 1.20211102.0) - - abseil/base/spinlock_wait (= 1.20211102.0) - - abseil/base/strerror (= 1.20211102.0) - - abseil/base/throw_delegate (= 1.20211102.0) - - abseil/base/atomic_hook (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/base (1.20211102.0): - - abseil/base/atomic_hook - - abseil/base/base_internal - - abseil/base/config - - abseil/base/core_headers - - abseil/base/dynamic_annotations - - abseil/base/log_severity - - abseil/base/raw_logging_internal - - abseil/base/spinlock_wait - - abseil/meta/type_traits - - abseil/base/base_internal (1.20211102.0): - - abseil/base/config - - abseil/meta/type_traits - - abseil/base/config (1.20211102.0) - - abseil/base/core_headers (1.20211102.0): - - abseil/base/config - - abseil/base/dynamic_annotations (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/endian (1.20211102.0): - - abseil/base/base - - abseil/base/config - - abseil/base/core_headers - - abseil/base/errno_saver (1.20211102.0): - - abseil/base/config - - abseil/base/fast_type_id (1.20211102.0): - - abseil/base/config - - abseil/base/log_severity (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/malloc_internal (1.20211102.0): - - abseil/base/base - - abseil/base/base_internal - - abseil/base/config - - abseil/base/core_headers - - abseil/base/dynamic_annotations - - abseil/base/raw_logging_internal - - abseil/base/pretty_function (1.20211102.0) - - abseil/base/raw_logging_internal (1.20211102.0): - - abseil/base/atomic_hook - - abseil/base/config - - abseil/base/core_headers - - abseil/base/log_severity - - abseil/base/spinlock_wait (1.20211102.0): - - abseil/base/base_internal - - abseil/base/core_headers - - abseil/base/errno_saver - - abseil/base/strerror (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/errno_saver - - abseil/base/throw_delegate (1.20211102.0): - - abseil/base/config - - abseil/base/raw_logging_internal - - abseil/container/common (1.20211102.0): - - abseil/meta/type_traits - - abseil/types/optional - - abseil/container/compressed_tuple (1.20211102.0): - - abseil/utility/utility - - abseil/container/container_memory (1.20211102.0): - - abseil/base/config - - abseil/memory/memory - - abseil/meta/type_traits - - abseil/utility/utility - - abseil/container/fixed_array (1.20211102.0): - - abseil/algorithm/algorithm - - abseil/base/config - - abseil/base/core_headers - - abseil/base/dynamic_annotations - - abseil/base/throw_delegate - - abseil/container/compressed_tuple - - abseil/memory/memory - - abseil/container/flat_hash_map (1.20211102.0): - - abseil/algorithm/container - - abseil/container/container_memory - - abseil/container/hash_function_defaults - - abseil/container/raw_hash_map - - abseil/memory/memory - - abseil/container/hash_function_defaults (1.20211102.0): - - abseil/base/config - - abseil/hash/hash - - abseil/strings/cord - - abseil/strings/strings - - abseil/container/hash_policy_traits (1.20211102.0): - - abseil/meta/type_traits - - abseil/container/hashtable_debug_hooks (1.20211102.0): - - abseil/base/config - - abseil/container/hashtablez_sampler (1.20211102.0): - - abseil/base/base - - abseil/base/core_headers - - abseil/container/have_sse - - abseil/debugging/stacktrace - - abseil/memory/memory - - abseil/profiling/exponential_biased - - abseil/profiling/sample_recorder - - abseil/synchronization/synchronization - - abseil/utility/utility - - abseil/container/have_sse (1.20211102.0) - - abseil/container/inlined_vector (1.20211102.0): - - abseil/algorithm/algorithm - - abseil/base/core_headers - - abseil/base/throw_delegate - - abseil/container/inlined_vector_internal - - abseil/memory/memory - - abseil/container/inlined_vector_internal (1.20211102.0): - - abseil/base/core_headers - - abseil/container/compressed_tuple - - abseil/memory/memory - - abseil/meta/type_traits - - abseil/types/span - - abseil/container/layout (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/meta/type_traits - - abseil/strings/strings - - abseil/types/span - - abseil/utility/utility - - abseil/container/raw_hash_map (1.20211102.0): - - abseil/base/throw_delegate - - abseil/container/container_memory - - abseil/container/raw_hash_set - - abseil/container/raw_hash_set (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/endian - - abseil/container/common - - abseil/container/compressed_tuple - - abseil/container/container_memory - - abseil/container/hash_policy_traits - - abseil/container/hashtable_debug_hooks - - abseil/container/hashtablez_sampler - - abseil/container/have_sse - - abseil/memory/memory - - abseil/meta/type_traits - - abseil/numeric/bits - - abseil/utility/utility - - abseil/debugging/debugging_internal (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/dynamic_annotations - - abseil/base/errno_saver - - abseil/base/raw_logging_internal - - abseil/debugging/demangle_internal (1.20211102.0): - - abseil/base/base - - abseil/base/config - - abseil/base/core_headers - - abseil/debugging/stacktrace (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/debugging/debugging_internal - - abseil/debugging/symbolize (1.20211102.0): - - abseil/base/base - - abseil/base/config - - abseil/base/core_headers - - abseil/base/dynamic_annotations - - abseil/base/malloc_internal - - abseil/base/raw_logging_internal - - abseil/debugging/debugging_internal - - abseil/debugging/demangle_internal - - abseil/strings/strings - - abseil/functional/bind_front (1.20211102.0): - - abseil/base/base_internal - - abseil/container/compressed_tuple - - abseil/meta/type_traits - - abseil/utility/utility - - abseil/functional/function_ref (1.20211102.0): - - abseil/base/base_internal - - abseil/base/core_headers - - abseil/meta/type_traits - - abseil/hash/city (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/endian - - abseil/hash/hash (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/endian - - abseil/container/fixed_array - - abseil/hash/city - - abseil/hash/low_level_hash - - abseil/meta/type_traits - - abseil/numeric/int128 - - abseil/strings/strings - - abseil/types/optional - - abseil/types/variant - - abseil/utility/utility - - abseil/hash/low_level_hash (1.20211102.0): - - abseil/base/config - - abseil/base/endian - - abseil/numeric/bits - - abseil/numeric/int128 - - abseil/memory (1.20211102.0): - - abseil/memory/memory (= 1.20211102.0) - - abseil/memory/memory (1.20211102.0): - - abseil/base/core_headers - - abseil/meta/type_traits - - abseil/meta (1.20211102.0): - - abseil/meta/type_traits (= 1.20211102.0) - - abseil/meta/type_traits (1.20211102.0): - - abseil/base/config - - abseil/numeric/bits (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/numeric/int128 (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/numeric/bits - - abseil/numeric/representation (1.20211102.0): - - abseil/base/config - - abseil/profiling/exponential_biased (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/profiling/sample_recorder (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/synchronization/synchronization - - abseil/time/time - - abseil/random/distributions (1.20211102.0): - - abseil/base/base_internal - - abseil/base/config - - abseil/base/core_headers - - abseil/meta/type_traits - - abseil/numeric/bits - - abseil/random/internal/distribution_caller - - abseil/random/internal/fast_uniform_bits - - abseil/random/internal/fastmath - - abseil/random/internal/generate_real - - abseil/random/internal/iostream_state_saver - - abseil/random/internal/traits - - abseil/random/internal/uniform_helper - - abseil/random/internal/wide_multiply - - abseil/strings/strings - - abseil/random/internal/distribution_caller (1.20211102.0): - - abseil/base/config - - abseil/base/fast_type_id - - abseil/utility/utility - - abseil/random/internal/fast_uniform_bits (1.20211102.0): - - abseil/base/config - - abseil/meta/type_traits - - abseil/random/internal/fastmath (1.20211102.0): - - abseil/numeric/bits - - abseil/random/internal/generate_real (1.20211102.0): - - abseil/meta/type_traits - - abseil/numeric/bits - - abseil/random/internal/fastmath - - abseil/random/internal/traits - - abseil/random/internal/iostream_state_saver (1.20211102.0): - - abseil/meta/type_traits - - abseil/numeric/int128 - - abseil/random/internal/nonsecure_base (1.20211102.0): - - abseil/base/core_headers - - abseil/meta/type_traits - - abseil/random/internal/pool_urbg - - abseil/random/internal/salted_seed_seq - - abseil/random/internal/seed_material - - abseil/types/optional - - abseil/types/span - - abseil/random/internal/pcg_engine (1.20211102.0): - - abseil/base/config - - abseil/meta/type_traits - - abseil/numeric/bits - - abseil/numeric/int128 - - abseil/random/internal/fastmath - - abseil/random/internal/iostream_state_saver - - abseil/random/internal/platform (1.20211102.0): - - abseil/base/config - - abseil/random/internal/pool_urbg (1.20211102.0): - - abseil/base/base - - abseil/base/config - - abseil/base/core_headers - - abseil/base/endian - - abseil/base/raw_logging_internal - - abseil/random/internal/randen - - abseil/random/internal/seed_material - - abseil/random/internal/traits - - abseil/random/seed_gen_exception - - abseil/types/span - - abseil/random/internal/randen (1.20211102.0): - - abseil/base/raw_logging_internal - - abseil/random/internal/platform - - abseil/random/internal/randen_hwaes - - abseil/random/internal/randen_slow - - abseil/random/internal/randen_engine (1.20211102.0): - - abseil/base/endian - - abseil/meta/type_traits - - abseil/random/internal/iostream_state_saver - - abseil/random/internal/randen - - abseil/random/internal/randen_hwaes (1.20211102.0): - - abseil/base/config - - abseil/random/internal/platform - - abseil/random/internal/randen_hwaes_impl - - abseil/random/internal/randen_hwaes_impl (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/numeric/int128 - - abseil/random/internal/platform - - abseil/random/internal/randen_slow (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/endian - - abseil/numeric/int128 - - abseil/random/internal/platform - - abseil/random/internal/salted_seed_seq (1.20211102.0): - - abseil/container/inlined_vector - - abseil/meta/type_traits - - abseil/random/internal/seed_material - - abseil/types/optional - - abseil/types/span - - abseil/random/internal/seed_material (1.20211102.0): - - abseil/base/core_headers - - abseil/base/dynamic_annotations - - abseil/base/raw_logging_internal - - abseil/random/internal/fast_uniform_bits - - abseil/strings/strings - - abseil/types/optional - - abseil/types/span - - abseil/random/internal/traits (1.20211102.0): - - abseil/base/config - - abseil/random/internal/uniform_helper (1.20211102.0): - - abseil/base/config - - abseil/meta/type_traits - - abseil/random/internal/traits - - abseil/random/internal/wide_multiply (1.20211102.0): - - abseil/base/config - - abseil/numeric/bits - - abseil/numeric/int128 - - abseil/random/internal/traits - - abseil/random/random (1.20211102.0): - - abseil/random/distributions - - abseil/random/internal/nonsecure_base - - abseil/random/internal/pcg_engine - - abseil/random/internal/pool_urbg - - abseil/random/internal/randen_engine - - abseil/random/seed_sequences - - abseil/random/seed_gen_exception (1.20211102.0): - - abseil/base/config - - abseil/random/seed_sequences (1.20211102.0): - - abseil/container/inlined_vector - - abseil/random/internal/nonsecure_base - - abseil/random/internal/pool_urbg - - abseil/random/internal/salted_seed_seq - - abseil/random/internal/seed_material - - abseil/random/seed_gen_exception - - abseil/types/span - - abseil/status/status (1.20211102.0): - - abseil/base/atomic_hook - - abseil/base/config - - abseil/base/core_headers - - abseil/base/raw_logging_internal - - abseil/container/inlined_vector - - abseil/debugging/stacktrace - - abseil/debugging/symbolize - - abseil/functional/function_ref - - abseil/strings/cord - - abseil/strings/str_format - - abseil/strings/strings - - abseil/types/optional - - abseil/status/statusor (1.20211102.0): - - abseil/base/base - - abseil/base/core_headers - - abseil/base/raw_logging_internal - - abseil/meta/type_traits - - abseil/status/status - - abseil/strings/strings - - abseil/types/variant - - abseil/utility/utility - - abseil/strings/cord (1.20211102.0): - - abseil/base/base - - abseil/base/config - - abseil/base/core_headers - - abseil/base/endian - - abseil/base/raw_logging_internal - - abseil/container/fixed_array - - abseil/container/inlined_vector - - abseil/functional/function_ref - - abseil/meta/type_traits - - abseil/strings/cord_internal - - abseil/strings/cordz_functions - - abseil/strings/cordz_info - - abseil/strings/cordz_statistics - - abseil/strings/cordz_update_scope - - abseil/strings/cordz_update_tracker - - abseil/strings/internal - - abseil/strings/str_format - - abseil/strings/strings - - abseil/types/optional - - abseil/strings/cord_internal (1.20211102.0): - - abseil/base/base_internal - - abseil/base/config - - abseil/base/core_headers - - abseil/base/endian - - abseil/base/raw_logging_internal - - abseil/base/throw_delegate - - abseil/container/compressed_tuple - - abseil/container/inlined_vector - - abseil/container/layout - - abseil/functional/function_ref - - abseil/meta/type_traits - - abseil/strings/strings - - abseil/types/span - - abseil/strings/cordz_functions (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/raw_logging_internal - - abseil/profiling/exponential_biased - - abseil/strings/cordz_handle (1.20211102.0): - - abseil/base/base - - abseil/base/config - - abseil/base/raw_logging_internal - - abseil/synchronization/synchronization - - abseil/strings/cordz_info (1.20211102.0): - - abseil/base/base - - abseil/base/config - - abseil/base/core_headers - - abseil/base/raw_logging_internal - - abseil/container/inlined_vector - - abseil/debugging/stacktrace - - abseil/strings/cord_internal - - abseil/strings/cordz_functions - - abseil/strings/cordz_handle - - abseil/strings/cordz_statistics - - abseil/strings/cordz_update_tracker - - abseil/synchronization/synchronization - - abseil/types/span - - abseil/strings/cordz_statistics (1.20211102.0): - - abseil/base/config - - abseil/strings/cordz_update_tracker - - abseil/strings/cordz_update_scope (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/strings/cord_internal - - abseil/strings/cordz_info - - abseil/strings/cordz_update_tracker - - abseil/strings/cordz_update_tracker (1.20211102.0): - - abseil/base/config - - abseil/strings/internal (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/endian - - abseil/base/raw_logging_internal - - abseil/meta/type_traits - - abseil/strings/str_format (1.20211102.0): - - abseil/strings/str_format_internal - - abseil/strings/str_format_internal (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/functional/function_ref - - abseil/meta/type_traits - - abseil/numeric/bits - - abseil/numeric/int128 - - abseil/numeric/representation - - abseil/strings/strings - - abseil/types/optional - - abseil/types/span - - abseil/strings/strings (1.20211102.0): - - abseil/base/base - - abseil/base/config - - abseil/base/core_headers - - abseil/base/endian - - abseil/base/raw_logging_internal - - abseil/base/throw_delegate - - abseil/memory/memory - - abseil/meta/type_traits - - abseil/numeric/bits - - abseil/numeric/int128 - - abseil/strings/internal - - abseil/synchronization/graphcycles_internal (1.20211102.0): - - abseil/base/base - - abseil/base/base_internal - - abseil/base/config - - abseil/base/core_headers - - abseil/base/malloc_internal - - abseil/base/raw_logging_internal - - abseil/synchronization/kernel_timeout_internal (1.20211102.0): - - abseil/base/core_headers - - abseil/base/raw_logging_internal - - abseil/time/time - - abseil/synchronization/synchronization (1.20211102.0): - - abseil/base/atomic_hook - - abseil/base/base - - abseil/base/base_internal - - abseil/base/config - - abseil/base/core_headers - - abseil/base/dynamic_annotations - - abseil/base/malloc_internal - - abseil/base/raw_logging_internal - - abseil/debugging/stacktrace - - abseil/debugging/symbolize - - abseil/synchronization/graphcycles_internal - - abseil/synchronization/kernel_timeout_internal - - abseil/time/time - - abseil/time (1.20211102.0): - - abseil/time/internal (= 1.20211102.0) - - abseil/time/time (= 1.20211102.0) - - abseil/time/internal (1.20211102.0): - - abseil/time/internal/cctz (= 1.20211102.0) - - abseil/time/internal/cctz (1.20211102.0): - - abseil/time/internal/cctz/civil_time (= 1.20211102.0) - - abseil/time/internal/cctz/time_zone (= 1.20211102.0) - - abseil/time/internal/cctz/civil_time (1.20211102.0): - - abseil/base/config - - abseil/time/internal/cctz/time_zone (1.20211102.0): - - abseil/base/config - - abseil/time/internal/cctz/civil_time - - abseil/time/time (1.20211102.0): - - abseil/base/base - - abseil/base/core_headers - - abseil/base/raw_logging_internal - - abseil/numeric/int128 - - abseil/strings/strings - - abseil/time/internal/cctz/civil_time - - abseil/time/internal/cctz/time_zone - - abseil/types (1.20211102.0): - - abseil/types/any (= 1.20211102.0) - - abseil/types/bad_any_cast (= 1.20211102.0) - - abseil/types/bad_any_cast_impl (= 1.20211102.0) - - abseil/types/bad_optional_access (= 1.20211102.0) - - abseil/types/bad_variant_access (= 1.20211102.0) - - abseil/types/compare (= 1.20211102.0) - - abseil/types/optional (= 1.20211102.0) - - abseil/types/span (= 1.20211102.0) - - abseil/types/variant (= 1.20211102.0) - - abseil/types/any (1.20211102.0): - - abseil/base/config - - abseil/base/core_headers - - abseil/base/fast_type_id - - abseil/meta/type_traits - - abseil/types/bad_any_cast - - abseil/utility/utility - - abseil/types/bad_any_cast (1.20211102.0): - - abseil/base/config - - abseil/types/bad_any_cast_impl - - abseil/types/bad_any_cast_impl (1.20211102.0): - - abseil/base/config - - abseil/base/raw_logging_internal - - abseil/types/bad_optional_access (1.20211102.0): - - abseil/base/config - - abseil/base/raw_logging_internal - - abseil/types/bad_variant_access (1.20211102.0): - - abseil/base/config - - abseil/base/raw_logging_internal - - abseil/types/compare (1.20211102.0): - - abseil/base/core_headers - - abseil/meta/type_traits - - abseil/types/optional (1.20211102.0): - - abseil/base/base_internal - - abseil/base/config - - abseil/base/core_headers - - abseil/memory/memory - - abseil/meta/type_traits - - abseil/types/bad_optional_access - - abseil/utility/utility - - abseil/types/span (1.20211102.0): - - abseil/algorithm/algorithm - - abseil/base/core_headers - - abseil/base/throw_delegate - - abseil/meta/type_traits - - abseil/types/variant (1.20211102.0): - - abseil/base/base_internal - - abseil/base/config - - abseil/base/core_headers - - abseil/meta/type_traits - - abseil/types/bad_variant_access - - abseil/utility/utility - - abseil/utility/utility (1.20211102.0): - - abseil/base/base_internal - - abseil/base/config - - abseil/meta/type_traits - - BoringSSL-GRPC (0.0.24): - - BoringSSL-GRPC/Implementation (= 0.0.24) - - BoringSSL-GRPC/Interface (= 0.0.24) - - BoringSSL-GRPC/Implementation (0.0.24): - - BoringSSL-GRPC/Interface (= 0.0.24) - - BoringSSL-GRPC/Interface (0.0.24) - - cloud_firestore (4.0.5): - - Firebase/Firestore (= 10.1.0) - - firebase_core - - Flutter - - nanopb (< 2.30910.0, >= 2.30908.0) - - Firebase/CoreOnly (10.1.0): - - FirebaseCore (= 10.1.0) - - Firebase/Firestore (10.1.0): - - Firebase/CoreOnly - - FirebaseFirestore (~> 10.1.0) - - firebase_core (2.2.0): - - Firebase/CoreOnly (= 10.1.0) - - Flutter - - FirebaseCore (10.1.0): - - FirebaseCoreInternal (~> 10.0) - - GoogleUtilities/Environment (~> 7.8) - - GoogleUtilities/Logger (~> 7.8) - - FirebaseCoreInternal (10.1.0): - - "GoogleUtilities/NSData+zlib (~> 7.8)" - - FirebaseFirestore (10.1.0): - - abseil/algorithm (~> 1.20211102.0) - - abseil/base (~> 1.20211102.0) - - abseil/container/flat_hash_map (~> 1.20211102.0) - - abseil/memory (~> 1.20211102.0) - - abseil/meta (~> 1.20211102.0) - - abseil/strings/strings (~> 1.20211102.0) - - abseil/time (~> 1.20211102.0) - - abseil/types (~> 1.20211102.0) - - FirebaseCore (~> 10.0) - - "gRPC-C++ (~> 1.44.0)" - - leveldb-library (~> 1.22) - - nanopb (< 2.30910.0, >= 2.30908.0) - - Flutter (1.0.0) - - GoogleUtilities/Environment (7.8.0): - - PromisesObjC (< 3.0, >= 1.2) - - GoogleUtilities/Logger (7.8.0): - - GoogleUtilities/Environment - - "GoogleUtilities/NSData+zlib (7.8.0)" - - "gRPC-C++ (1.44.0)": - - "gRPC-C++/Implementation (= 1.44.0)" - - "gRPC-C++/Interface (= 1.44.0)" - - "gRPC-C++/Implementation (1.44.0)": - - abseil/base/base (= 1.20211102.0) - - abseil/base/core_headers (= 1.20211102.0) - - abseil/container/flat_hash_map (= 1.20211102.0) - - abseil/container/inlined_vector (= 1.20211102.0) - - abseil/functional/bind_front (= 1.20211102.0) - - abseil/hash/hash (= 1.20211102.0) - - abseil/memory/memory (= 1.20211102.0) - - abseil/random/random (= 1.20211102.0) - - abseil/status/status (= 1.20211102.0) - - abseil/status/statusor (= 1.20211102.0) - - abseil/strings/cord (= 1.20211102.0) - - abseil/strings/str_format (= 1.20211102.0) - - abseil/strings/strings (= 1.20211102.0) - - abseil/synchronization/synchronization (= 1.20211102.0) - - abseil/time/time (= 1.20211102.0) - - abseil/types/optional (= 1.20211102.0) - - abseil/types/variant (= 1.20211102.0) - - abseil/utility/utility (= 1.20211102.0) - - "gRPC-C++/Interface (= 1.44.0)" - - gRPC-Core (= 1.44.0) - - "gRPC-C++/Interface (1.44.0)" - - gRPC-Core (1.44.0): - - gRPC-Core/Implementation (= 1.44.0) - - gRPC-Core/Interface (= 1.44.0) - - gRPC-Core/Implementation (1.44.0): - - abseil/base/base (= 1.20211102.0) - - abseil/base/core_headers (= 1.20211102.0) - - abseil/container/flat_hash_map (= 1.20211102.0) - - abseil/container/inlined_vector (= 1.20211102.0) - - abseil/functional/bind_front (= 1.20211102.0) - - abseil/hash/hash (= 1.20211102.0) - - abseil/memory/memory (= 1.20211102.0) - - abseil/random/random (= 1.20211102.0) - - abseil/status/status (= 1.20211102.0) - - abseil/status/statusor (= 1.20211102.0) - - abseil/strings/cord (= 1.20211102.0) - - abseil/strings/str_format (= 1.20211102.0) - - abseil/strings/strings (= 1.20211102.0) - - abseil/synchronization/synchronization (= 1.20211102.0) - - abseil/time/time (= 1.20211102.0) - - abseil/types/optional (= 1.20211102.0) - - abseil/types/variant (= 1.20211102.0) - - abseil/utility/utility (= 1.20211102.0) - - BoringSSL-GRPC (= 0.0.24) - - gRPC-Core/Interface (= 1.44.0) - - Libuv-gRPC (= 0.0.10) - - gRPC-Core/Interface (1.44.0) - - leveldb-library (1.22.1) - - Libuv-gRPC (0.0.10): - - Libuv-gRPC/Implementation (= 0.0.10) - - Libuv-gRPC/Interface (= 0.0.10) - - Libuv-gRPC/Implementation (0.0.10): - - Libuv-gRPC/Interface (= 0.0.10) - - Libuv-gRPC/Interface (0.0.10) - - nanopb (2.30909.0): - - nanopb/decode (= 2.30909.0) - - nanopb/encode (= 2.30909.0) - - nanopb/decode (2.30909.0) - - nanopb/encode (2.30909.0) - - PromisesObjC (2.1.1) - -DEPENDENCIES: - - cloud_firestore (from `.symlinks/plugins/cloud_firestore/ios`) - - firebase_core (from `.symlinks/plugins/firebase_core/ios`) - - Flutter (from `Flutter`) - -SPEC REPOS: - trunk: - - abseil - - BoringSSL-GRPC - - Firebase - - FirebaseCore - - FirebaseCoreInternal - - FirebaseFirestore - - GoogleUtilities - - "gRPC-C++" - - gRPC-Core - - leveldb-library - - Libuv-gRPC - - nanopb - - PromisesObjC - -EXTERNAL SOURCES: - cloud_firestore: - :path: ".symlinks/plugins/cloud_firestore/ios" - firebase_core: - :path: ".symlinks/plugins/firebase_core/ios" - Flutter: - :path: Flutter - -SPEC CHECKSUMS: - abseil: ebe5b5529fb05d93a8bdb7951607be08b7fa71bc - BoringSSL-GRPC: 3175b25143e648463a56daeaaa499c6cb86dad33 - cloud_firestore: 345ab5f423db6ae492abb648372156bdccb9df42 - Firebase: 444b35a9c568a516666213c2f6cccd10cb12559f - firebase_core: d2242c6f318db1d0dcecfbfa491e943337b0d755 - FirebaseCore: 55e7ae35991ccca4db03ff8d8df6ed5f17a3e4c7 - FirebaseCoreInternal: 96d75228e10fd369564da51bd898414eb0f54df5 - FirebaseFirestore: d482e5e0f95dba8ef5d499a7efa87ba2f56ef0c0 - Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 - GoogleUtilities: 1d20a6ad97ef46f67bbdec158ce00563a671ebb7 - "gRPC-C++": 9675f953ace2b3de7c506039d77be1f2e77a8db2 - gRPC-Core: 943e491cb0d45598b0b0eb9e910c88080369290b - leveldb-library: 50c7b45cbd7bf543c81a468fe557a16ae3db8729 - Libuv-gRPC: 55e51798e14ef436ad9bc45d12d43b77b49df378 - nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431 - PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb - -PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 - -COCOAPODS: 1.11.3 diff --git a/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/project.pbxproj b/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index a4705413..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,552 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 50; - objects = { - -/* Begin PBXBuildFile section */ - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 2D3BF4E90FD3D66E6379652C /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9668B7DCB1C084B61D13F13B /* Pods_Runner.framework */; }; - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 04335B06475E8C2B1917681C /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - 0A79DE27E9F9DDADA3D915D2 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 8D3EFC6842916D850020C95C /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; - 9668B7DCB1C084B61D13F13B /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; - 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 97C146EB1CF9000F007C117D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 2D3BF4E90FD3D66E6379652C /* Pods_Runner.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 32816CF134A5ECA965EE4EF3 /* Pods */ = { - isa = PBXGroup; - children = ( - 0A79DE27E9F9DDADA3D915D2 /* Pods-Runner.debug.xcconfig */, - 04335B06475E8C2B1917681C /* Pods-Runner.release.xcconfig */, - 8D3EFC6842916D850020C95C /* Pods-Runner.profile.xcconfig */, - ); - name = Pods; - path = Pods; - sourceTree = ""; - }; - 9740EEB11CF90186004384FC /* Flutter */ = { - isa = PBXGroup; - children = ( - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 9740EEB31CF90195004384FC /* Generated.xcconfig */, - ); - name = Flutter; - sourceTree = ""; - }; - 97C146E51CF9000F007C117D = { - isa = PBXGroup; - children = ( - 9740EEB11CF90186004384FC /* Flutter */, - 97C146F01CF9000F007C117D /* Runner */, - 97C146EF1CF9000F007C117D /* Products */, - 32816CF134A5ECA965EE4EF3 /* Pods */, - DF1EDFCBAB38011323A8D81B /* Frameworks */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 97C147021CF9000F007C117D /* Info.plist */, - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, - 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, - ); - path = Runner; - sourceTree = ""; - }; - DF1EDFCBAB38011323A8D81B /* Frameworks */ = { - isa = PBXGroup; - children = ( - 9668B7DCB1C084B61D13F13B /* Pods_Runner.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 97C146ED1CF9000F007C117D /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - C454F828EEBC86C10B4E163A /* [CP] Check Pods Manifest.lock */, - 9740EEB61CF901F6004384FC /* Run Script */, - 97C146EA1CF9000F007C117D /* Sources */, - 97C146EB1CF9000F007C117D /* Frameworks */, - 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, - 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 897D29AE5A72F625B86D7F66 /* [CP] Embed Pods Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Runner; - productName = Runner; - productReference = 97C146EE1CF9000F007C117D /* Runner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 97C146E61CF9000F007C117D /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1300; - ORGANIZATIONNAME = ""; - TargetAttributes = { - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - LastSwiftMigration = 1100; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 97C146EC1CF9000F007C117D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; - }; - 897D29AE5A72F625B86D7F66 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; - }; - C454F828EEBC86C10B4E163A /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 97C146FA1CF9000F007C117D /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C146FB1CF9000F007C117D /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C147001CF9000F007C117D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 249021D3217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Profile; - }; - 249021D4217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 6Z5P8GG96U; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.example; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Profile; - }; - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 97C147061CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 6Z5P8GG96U; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.example; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Debug; - }; - 97C147071CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 6Z5P8GG96U; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.example; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - 249021D3217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - 249021D4217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} diff --git a/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a6..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d98100..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index c87d15a3..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/wyatt_crud_bloc/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/wyatt_crud_bloc/example/ios/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 21a3cc14..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/packages/wyatt_crud_bloc/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/wyatt_crud_bloc/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d98100..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/AppDelegate.swift b/packages/wyatt_crud_bloc/example/ios/Runner/AppDelegate.swift deleted file mode 100644 index 70693e4a..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner/AppDelegate.swift +++ /dev/null @@ -1,13 +0,0 @@ -import UIKit -import Flutter - -@UIApplicationMain -@objc class AppDelegate: FlutterAppDelegate { - override func application( - _ application: UIApplication, - didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? - ) -> Bool { - GeneratedPluginRegistrant.register(with: self) - return super.application(application, didFinishLaunchingWithOptions: launchOptions) - } -} diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d36b1fab..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@1x.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@1x.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@1x.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "Icon-App-83.5x83.5@2x.png", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", - "filename" : "Icon-App-1024x1024@1x.png", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png deleted file mode 100644 index dc9ada47..00000000 Binary files a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and /dev/null differ diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png deleted file mode 100644 index 28c6bf03..00000000 Binary files a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and /dev/null differ diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png deleted file mode 100644 index 2ccbfd96..00000000 Binary files a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and /dev/null differ diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index f091b6b0..00000000 Binary files a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and /dev/null differ diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png deleted file mode 100644 index 4cde1211..00000000 Binary files a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and /dev/null differ diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index d0ef06e7..00000000 Binary files a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and /dev/null differ diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png deleted file mode 100644 index dcdc2306..00000000 Binary files a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and /dev/null differ diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png deleted file mode 100644 index 2ccbfd96..00000000 Binary files a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and /dev/null differ diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index c8f9ed8f..00000000 Binary files a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and /dev/null differ diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100644 index a6d6b860..00000000 Binary files a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and /dev/null differ diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index a6d6b860..00000000 Binary files a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and /dev/null differ diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index 75b2d164..00000000 Binary files a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and /dev/null differ diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100644 index c4df70d3..00000000 Binary files a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and /dev/null differ diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png deleted file mode 100644 index 6a84f41e..00000000 Binary files a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and /dev/null differ diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png deleted file mode 100644 index d0e1f585..00000000 Binary files a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and /dev/null differ diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json deleted file mode 100644 index 0bedcf2f..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +++ /dev/null @@ -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" - } -} diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png deleted file mode 100644 index 9da19eac..00000000 Binary files a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png and /dev/null differ diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png deleted file mode 100644 index 9da19eac..00000000 Binary files a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png and /dev/null differ diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png deleted file mode 100644 index 9da19eac..00000000 Binary files a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png and /dev/null differ diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md deleted file mode 100644 index 89c2725b..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Launch Screen Assets - -You can customize the launch screen with your own desired assets by replacing the image files in this directory. - -You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/packages/wyatt_crud_bloc/example/ios/Runner/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index f2e259c7..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Base.lproj/Main.storyboard b/packages/wyatt_crud_bloc/example/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100644 index f3c28516..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Info.plist b/packages/wyatt_crud_bloc/example/ios/Runner/Info.plist deleted file mode 100644 index 7f553465..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner/Info.plist +++ /dev/null @@ -1,51 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleDisplayName - Example - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - example - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleSignature - ???? - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - CADisableMinimumFrameDurationOnPhone - - UIApplicationSupportsIndirectInputEvents - - - diff --git a/packages/wyatt_crud_bloc/example/ios/Runner/Runner-Bridging-Header.h b/packages/wyatt_crud_bloc/example/ios/Runner/Runner-Bridging-Header.h deleted file mode 100644 index 308a2a56..00000000 --- a/packages/wyatt_crud_bloc/example/ios/Runner/Runner-Bridging-Header.h +++ /dev/null @@ -1 +0,0 @@ -#import "GeneratedPluginRegistrant.h" diff --git a/packages/wyatt_crud_bloc/example/lib/advanced_cubit_view.dart b/packages/wyatt_crud_bloc/example/lib/advanced_cubit_view.dart new file mode 100644 index 00000000..f6bc82fd --- /dev/null +++ b/packages/wyatt_crud_bloc/example/lib/advanced_cubit_view.dart @@ -0,0 +1,116 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'dart:math'; + +import 'package:crud_bloc_example/user_advanced_cubit.dart'; +import 'package:crud_bloc_example/user_entity.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; + +class AdvancedCubitView extends StatelessWidget { + const AdvancedCubitView({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text("Advanced Cubit"), + ), + body: BlocProvider( + create: (context) => + UserAdvancedCubit(context.read>()) + ..streaming(), + child: Builder( + builder: (context) { + return Column( + children: [ + Expanded( + child: + CrudBuilder.typed>( + buildWhen: (previous, current) { + if (current is CrudLoading && current is! CrudReading) { + return false; + } + return true; + }, + builder: ((context, state) { + return ListView.builder( + itemCount: state.data.length, + itemBuilder: (context, index) { + final user = state.data.elementAt(index); + return ListTile( + title: Text(user?.name ?? 'Error'), + subtitle: Text(user?.email ?? 'Error'), + onTap: () { + context.read().delete((user?.id)!); + }, + onLongPress: () { + context.read().update( + UpdateParameters(id: user?.id ?? '', raw: { + 'email': '${user?.id}@updated.io', + }), + ); + }, + ); + }, + ); + }), + initialBuilder: (context, state) => + const Center(child: CircularProgressIndicator()), + loadingBuilder: (context, state) => + const Center(child: CircularProgressIndicator()), + errorBuilder: (context, state) => Text("Error: $state"), + ), + ), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () { + final r = Random().nextInt(1000); + context.read().create( + User( + id: '$r', + name: 'Wyatt $r', + email: '$r@wyattapp.io', + phone: '06$r', + ), + ); + }, + child: CrudBuilder.onLoading( + builder: (context, state) { + if (state is CrudCreating) { + return const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + color: Colors.white, + ), + ); + } + return null; + }, + otherBuilder: (context, state) => const Text("Create"), + ), + ), + ], + ); + } + ), + ), + ); + } +} diff --git a/packages/wyatt_crud_bloc/example/lib/app.dart b/packages/wyatt_crud_bloc/example/lib/app.dart index d5339343..088f1324 100644 --- a/packages/wyatt_crud_bloc/example/lib/app.dart +++ b/packages/wyatt_crud_bloc/example/lib/app.dart @@ -14,41 +14,44 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import 'dart:math'; - -import 'package:crud_bloc_example/models.dart'; -import 'package:crud_bloc_example/user_cubit.dart'; +import 'package:crud_bloc_example/advanced_cubit_view.dart'; +import 'package:crud_bloc_example/basic_cubit_view.dart'; +import 'package:crud_bloc_example/streaming_cubit_view.dart'; +import 'package:crud_bloc_example/user_entity.dart'; +import 'package:crud_bloc_example/user_model.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; class MyApp extends StatelessWidget { - const MyApp({Key? key}) : super(key: key); + const MyApp({required this.crudDataSource, Key? key}) : super(key: key); + + final CrudDataSource crudDataSource; // This widget is the root of your application. @override Widget build(BuildContext context) { - final CrudDataSource userLocalDataSource = - CrudInMemoryDataSourceImpl(toMap: (user) => user.toMap()); - - final CrudRepository userRepository = - CrudRepositoryImpl(crudDataSource: userLocalDataSource); + final CrudRepository userRepository = CrudRepositoryImpl( + crudDataSource: crudDataSource, + modelMapper: ModelMapper( + fromJson: (json) => UserModel.fromJson(json ?? {}), + toJson: (user) => UserModel( + id: user.id, + name: user.name, + email: user.email, + phone: user.phone, + ).toJson(), + ), + ); return RepositoryProvider>.value( value: userRepository, - child: MultiBlocProvider( - providers: [ - BlocProvider( - create: (context) => UserCubit(userRepository)..read(), - ), - ], - child: MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: const MyHomePage(), + child: MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, ), + home: const MyHomePage(), ), ); } @@ -63,58 +66,45 @@ class MyHomePage extends StatelessWidget { appBar: AppBar( title: const Text('Flutter Demo Home Page'), ), - body: SingleChildScrollView( + body: Center( child: Column( + mainAxisAlignment: MainAxisAlignment.center, children: [ - const SizedBox(height: 20), - const Text("Data:"), - BlocBuilder( - builder: (context, state) { - return CrudBuilder.typed>( - state: state, - builder: ((context, state) { - return ListView.builder( - shrinkWrap: true, - itemCount: state.data.length, - itemBuilder: (context, index) { - final user = state.data.elementAt(index); - return ListTile( - title: Text(user?.name ?? 'Error'), - subtitle: Text(user?.id ?? 'Error'), - onTap: () { - context.read().delete(id: (user?.id)!); - }, - ); - }, - ); - }), - initialBuilder: (context, state) => const Text("Loading..."), - loadingBuilder: (context, state) => const Text("Loading..."), - errorBuilder: (context, state) => Text("Error: $state"), + ElevatedButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const BasicCubitView(), + ), ); }, + child: const Text('Basic example'), ), const SizedBox(height: 20), ElevatedButton( onPressed: () { - final r = Random().nextInt(1000); - context.read().create( - User( - id: '$r', - name: 'Wyatt $r', - email: '$r@wyattapp.io', - phone: '06$r'), - ); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const StreamingCubitView(), + ), + ); }, - child: const Text("Create"), - ), - ElevatedButton( - onPressed: () { - context.read().read(); - }, - child: const Text("GetAll"), + child: const Text('Streaming example'), ), const SizedBox(height: 20), + ElevatedButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const AdvancedCubitView(), + ), + ); + }, + child: const Text('Advanced example'), + ), ], ), ), diff --git a/packages/wyatt_crud_bloc/example/lib/basic_cubit_view.dart b/packages/wyatt_crud_bloc/example/lib/basic_cubit_view.dart new file mode 100644 index 00000000..cb9759af --- /dev/null +++ b/packages/wyatt_crud_bloc/example/lib/basic_cubit_view.dart @@ -0,0 +1,135 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'dart:math'; + +import 'package:crud_bloc_example/user_cubit.dart'; +import 'package:crud_bloc_example/user_entity.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; + +class BasicCubitView extends StatelessWidget { + const BasicCubitView({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text("Basic Cubit"), + ), + body: BlocProvider( + create: (context) => + UserCubit(context.read>())..read(), + child: Builder(builder: (context) { + return Column( + children: [ + Expanded( + child: CrudBuilder.typed>( + buildWhen: (previous, current) { + if (current is CrudLoading && current is! CrudReading) { + return false; + } + return true; + }, + builder: ((context, state) { + return ListView.builder( + itemCount: state.data.length, + itemBuilder: (context, index) { + final user = state.data.elementAt(index); + return ListTile( + title: Text(user?.name ?? 'Error'), + subtitle: Text(user?.email ?? 'Error'), + onTap: () { + context.read().delete(id: (user?.id)!); + }, + onLongPress: () { + context.read().update( + single: UpdateParameters( + id: user?.id ?? '', + raw: { + 'email': '${user?.id}@updated.io', + }), + ); + }, + ); + }, + ); + }), + initialBuilder: (context, state) => + const Center(child: CircularProgressIndicator()), + loadingBuilder: (context, state) => + const Center(child: CircularProgressIndicator()), + errorBuilder: (context, state) => Text("Error: $state"), + ), + ), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () { + final r = Random().nextInt(1000); + context.read().create( + User( + id: '$r', + name: 'Wyatt $r', + email: '$r@wyattapp.io', + phone: '06$r', + ), + ); + }, + child: CrudBuilder.onLoading( + builder: (context, state) { + if (state is CrudCreating) { + return const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + color: Colors.white, + ), + ); + } + return null; + }, + otherBuilder: (context, state) => const Text("Create"), + ), + ), + ElevatedButton( + onPressed: () { + context.read().read(); + }, + child: CrudBuilder.onLoading( + builder: (context, state) { + if (state is CrudReading) { + return const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + color: Colors.white, + ), + ); + } + return null; + }, + otherBuilder: (context, state) => const Text("Read"), + ), + ), + const SizedBox(height: 20), + ], + ); + }), + ), + ); + } +} diff --git a/packages/wyatt_crud_bloc/example/lib/firebase_options.dart b/packages/wyatt_crud_bloc/example/lib/firebase_options.dart new file mode 100644 index 00000000..66033168 --- /dev/null +++ b/packages/wyatt_crud_bloc/example/lib/firebase_options.dart @@ -0,0 +1,63 @@ +// File generated by FlutterFire CLI. +// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; +import 'package:flutter/foundation.dart' + show defaultTargetPlatform, kIsWeb, TargetPlatform; + +/// Default [FirebaseOptions] for use with your Firebase apps. +/// +/// Example: +/// ```dart +/// import 'firebase_options.dart'; +/// // ... +/// await Firebase.initializeApp( +/// options: DefaultFirebaseOptions.currentPlatform, +/// ); +/// ``` +class DefaultFirebaseOptions { + static FirebaseOptions get currentPlatform { + if (kIsWeb) { + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for web - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + } + switch (defaultTargetPlatform) { + case TargetPlatform.android: + return android; + case TargetPlatform.iOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for ios - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.macOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for macos - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.windows: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for windows - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.linux: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for linux - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + default: + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + } + + static const FirebaseOptions android = FirebaseOptions( + apiKey: 'AIzaSyAYS14uXupkS158Q5QAFP1864UrUN_yDSk', + appId: '1:136771801992:android:8482c9b90bc29de697203d', + messagingSenderId: '136771801992', + projectId: 'tchat-beta', + databaseURL: 'https://tchat-beta.firebaseio.com', + storageBucket: 'tchat-beta.appspot.com', + ); +} diff --git a/packages/wyatt_crud_bloc/example/lib/main_firestore.dart b/packages/wyatt_crud_bloc/example/lib/main_firestore.dart new file mode 100644 index 00000000..924e0cdb --- /dev/null +++ b/packages/wyatt_crud_bloc/example/lib/main_firestore.dart @@ -0,0 +1,44 @@ +// Copyright (C) 2022 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'package:crud_bloc_example/app.dart'; +import 'package:crud_bloc_example/app_bloc_observer.dart'; +import 'package:crud_bloc_example/firebase_options.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; +import 'package:wyatt_crud_bloc_firestore/wyatt_crud_bloc_firestore.dart'; + +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + Bloc.observer = AppBlocObserver(); + + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); + + final CrudDataSource crudDataSource = CrudDataSourceFirestoreImpl( + 'users', + id: (_, json) => json['id'] as String, + fromFirestore: (document, snapshot) => document.data() ?? {}, + toFirestore: (object, options) => object, + ); + + runApp(MyApp( + crudDataSource: crudDataSource, + )); +} diff --git a/packages/wyatt_crud_bloc/example/lib/main.dart b/packages/wyatt_crud_bloc/example/lib/main_memory.dart similarity index 81% rename from packages/wyatt_crud_bloc/example/lib/main.dart rename to packages/wyatt_crud_bloc/example/lib/main_memory.dart index beb692a1..d36a0c3f 100644 --- a/packages/wyatt_crud_bloc/example/lib/main.dart +++ b/packages/wyatt_crud_bloc/example/lib/main_memory.dart @@ -18,10 +18,17 @@ import 'package:crud_bloc_example/app.dart'; import 'package:crud_bloc_example/app_bloc_observer.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); Bloc.observer = AppBlocObserver(); - runApp(const MyApp()); + final CrudDataSource crudDataSource = CrudDataSourceInMemoryImpl( + id: (_, json) => json['id'] as String?, + ); + + runApp(MyApp( + crudDataSource: crudDataSource, + )); } diff --git a/packages/wyatt_crud_bloc/example/lib/streaming_cubit_view.dart b/packages/wyatt_crud_bloc/example/lib/streaming_cubit_view.dart new file mode 100644 index 00000000..e6f93d92 --- /dev/null +++ b/packages/wyatt_crud_bloc/example/lib/streaming_cubit_view.dart @@ -0,0 +1,117 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'dart:math'; + +import 'package:crud_bloc_example/user_entity.dart'; +import 'package:crud_bloc_example/user_streaming_cubit.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; + +class StreamingCubitView extends StatelessWidget { + const StreamingCubitView({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text("Streaming Cubit"), + ), + body: BlocProvider( + create: (context) => + UserStreamingCubit(context.read>())..read(), + child: Builder(builder: (context) { + return Column( + children: [ + Expanded( + child: CrudBuilder.typed>( + buildWhen: (previous, current) { + if (current is CrudLoading && current is! CrudReading) { + return false; + } + return true; + }, + builder: ((context, state) { + return ListView.builder( + itemCount: state.data.length, + itemBuilder: (context, index) { + final user = state.data.elementAt(index); + return ListTile( + title: Text(user?.name ?? 'Error'), + subtitle: Text(user?.email ?? 'Error'), + onTap: () { + context + .read() + .delete(id: (user?.id)!); + }, + onLongPress: () { + context.read().update( + single: UpdateParameters( + id: user?.id ?? '', + raw: { + 'email': '${user?.id}@updated.io', + }), + ); + }, + ); + }, + ); + }), + initialBuilder: (context, state) => + const Center(child: CircularProgressIndicator()), + loadingBuilder: (context, state) => + const Center(child: CircularProgressIndicator()), + errorBuilder: (context, state) => Text("Error: $state"), + ), + ), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () { + final r = Random().nextInt(1000); + context.read().create( + User( + id: '$r', + name: 'Wyatt $r', + email: '$r@wyattapp.io', + phone: '06$r', + ), + ); + }, + child: CrudBuilder.onLoading( + builder: (context, state) { + if (state is CrudCreating) { + return const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + color: Colors.white, + ), + ); + } + return null; + }, + otherBuilder: (context, state) => const Text("Create"), + ), + ), + ], + ); + }), + ), + ); + } +} diff --git a/packages/wyatt_crud_bloc/example/lib/user_advanced_cubit.dart b/packages/wyatt_crud_bloc/example/lib/user_advanced_cubit.dart new file mode 100644 index 00000000..b61c3144 --- /dev/null +++ b/packages/wyatt_crud_bloc/example/lib/user_advanced_cubit.dart @@ -0,0 +1,57 @@ +// Copyright (C) 2022 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'package:crud_bloc_example/user_entity.dart'; +import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; + +/// A [CrudAdvancedCubit] for [User]. +class UserAdvancedCubit extends CrudAdvancedCubit { + final CrudRepository crudRepository; + + UserAdvancedCubit(this.crudRepository); + + @override + ModelIdentifier get modelIdentifier => ModelIdentifier( + getIdentifier: (user) => user.id ?? '', + ); + + @override + Create? get crudCreate => Create(crudRepository); + + @override + Delete? get crudDelete => Delete(crudRepository); + + @override + DeleteAll? get crudDeleteAll => DeleteAll(crudRepository); + + @override + Get? get crudGet => Get(crudRepository); + + @override + GetAll? get crudGetAll => GetAll(crudRepository); + + @override + Search? get crudSearch => Search(crudRepository); + + @override + Streaming? get crudStreaming => Streaming(crudRepository); + + @override + Update? get crudUpdate => Update(crudRepository); + + @override + UpdateAll? get crudUpdateAll => UpdateAll(crudRepository); +} diff --git a/packages/wyatt_crud_bloc/example/lib/user_cubit.dart b/packages/wyatt_crud_bloc/example/lib/user_cubit.dart index cc34df6c..5a4fa336 100644 --- a/packages/wyatt_crud_bloc/example/lib/user_cubit.dart +++ b/packages/wyatt_crud_bloc/example/lib/user_cubit.dart @@ -14,28 +14,29 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import 'package:crud_bloc_example/models.dart'; +import 'package:crud_bloc_example/user_entity.dart'; import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; /// A [CrudCubit] for [User]. class UserCubit extends CrudCubit { - final CrudRepository _crudRepository; + final CrudRepository crudRepository; - UserCubit(this._crudRepository); + UserCubit(this.crudRepository); @override - CreateOperation? get createOperation => - Create(_crudRepository); + DefaultCreate? get createOperation => Create(crudRepository); @override - DeleteOperation? get deleteOperation => - Delete(_crudRepository); + DefaultDelete? get deleteOperation => Delete(crudRepository); @override - ReadOperation? get readOperation => - GetAll(_crudRepository); + DefaultRead? get readOperation => GetAll(crudRepository); @override - UpdateOperation? get updateOperation => - Update(_crudRepository); + DefaultUpdate? get updateOperation => Update(crudRepository); + + @override + ModelIdentifier get modelIdentifier => ModelIdentifier( + getIdentifier: (user) => user.id ?? '', + ); } diff --git a/packages/wyatt_crud_bloc/lib/src/domain/entities/object_model.dart b/packages/wyatt_crud_bloc/example/lib/user_entity.dart similarity index 65% rename from packages/wyatt_crud_bloc/lib/src/domain/entities/object_model.dart rename to packages/wyatt_crud_bloc/example/lib/user_entity.dart index 10dc5a25..9964f1ca 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/entities/object_model.dart +++ b/packages/wyatt_crud_bloc/example/lib/user_entity.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify @@ -14,15 +14,23 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +import 'package:equatable/equatable.dart'; import 'package:wyatt_architecture/wyatt_architecture.dart'; -/// {@template object_model} -/// An abstract class that represents an object model. -/// {@endtemplate} -abstract class ObjectModel extends Entity { - /// {@macro object_model} - const ObjectModel(); +class User extends Entity with EquatableMixin { + final String? id; - /// The id of the object model. - String? get id; + final String name; + final String email; + final String phone; + + const User({ + required this.name, + required this.email, + required this.phone, + this.id, + }); + + @override + List get props => [id, name, email, phone]; } diff --git a/packages/wyatt_crud_bloc/example/lib/models.dart b/packages/wyatt_crud_bloc/example/lib/user_model.dart similarity index 56% rename from packages/wyatt_crud_bloc/example/lib/models.dart rename to packages/wyatt_crud_bloc/example/lib/user_model.dart index e9ed1c7f..f5723736 100644 --- a/packages/wyatt_crud_bloc/example/lib/models.dart +++ b/packages/wyatt_crud_bloc/example/lib/user_model.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify @@ -14,32 +14,26 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; +import 'package:crud_bloc_example/user_entity.dart'; +import 'package:json_annotation/json_annotation.dart'; -class User extends ObjectModel { - @override - final String? id; +part 'user_model.g.dart'; - final String? name; - final String? email; - final String? phone; - - const User({ - required this.name, - required this.email, - required this.phone, - this.id, +@JsonSerializable() +class UserModel extends User { + UserModel({ + super.id, + required super.name, + required super.email, + required super.phone, }); - Map toMap() { - return { - 'name': name ?? '', - 'email': email ?? '', - 'phone': phone ?? '', - }; - } + factory UserModel.fromJson(Map json) => + _$UserModelFromJson(json); + + Map toJson() => _$UserModelToJson(this); @override String toString() => - 'User(id: $id, name: $name, email: $email, phone: $phone)'; + 'UserModel(id: $id, name: $name, email: $email, phone: $phone)'; } diff --git a/packages/wyatt_crud_bloc/example/lib/user_model.g.dart b/packages/wyatt_crud_bloc/example/lib/user_model.g.dart new file mode 100644 index 00000000..439e5eb0 --- /dev/null +++ b/packages/wyatt_crud_bloc/example/lib/user_model.g.dart @@ -0,0 +1,21 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'user_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +UserModel _$UserModelFromJson(Map json) => UserModel( + id: json['id'] as String?, + name: json['name'] as String, + email: json['email'] as String, + phone: json['phone'] as String, + ); + +Map _$UserModelToJson(UserModel instance) => { + 'id': instance.id, + 'name': instance.name, + 'email': instance.email, + 'phone': instance.phone, + }; diff --git a/packages/wyatt_crud_bloc/example/lib/user_streaming_cubit.dart b/packages/wyatt_crud_bloc/example/lib/user_streaming_cubit.dart new file mode 100644 index 00000000..45387137 --- /dev/null +++ b/packages/wyatt_crud_bloc/example/lib/user_streaming_cubit.dart @@ -0,0 +1,42 @@ +// Copyright (C) 2022 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'package:crud_bloc_example/user_entity.dart'; +import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; + +/// A [CrudCubit] for [User]. +class UserStreamingCubit extends CrudCubit { + final CrudRepository crudRepository; + + UserStreamingCubit(this.crudRepository); + + @override + DefaultCreate? get createOperation => Create(crudRepository); + + @override + DefaultDelete? get deleteOperation => Delete(crudRepository); + + @override + DefaultRead? get readOperation => Streaming(crudRepository); + + @override + DefaultUpdate? get updateOperation => Update(crudRepository); + + @override + ModelIdentifier get modelIdentifier => ModelIdentifier( + getIdentifier: (user) => user.id ?? '', + ); +} diff --git a/packages/wyatt_crud_bloc/example/pubspec.yaml b/packages/wyatt_crud_bloc/example/pubspec.yaml index 8275fb19..992e0738 100644 --- a/packages/wyatt_crud_bloc/example/pubspec.yaml +++ b/packages/wyatt_crud_bloc/example/pubspec.yaml @@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ">=2.17.0 <3.0.0" + sdk: ">=3.0.0 <4.0.0" # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions @@ -30,13 +30,23 @@ dependencies: flutter: sdk: flutter - flutter_bloc: ^8.1.1 + equatable: ^2.0.5 + firebase_core: ^2.22.0 + cloud_firestore: ^4.13.0 + flutter_bloc: ^8.1.3 wyatt_crud_bloc: path: "../" + wyatt_crud_bloc_firestore: + path: "../wyatt_crud_bloc_firestore" + + wyatt_architecture: + hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + version: ^0.2.0+1 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 + json_annotation: ^4.8.1 dev_dependencies: flutter_test: @@ -48,6 +58,8 @@ dev_dependencies: # package. See that file for information about deactivating specific lint # rules and activating additional ones. flutter_lints: ^2.0.0 + json_serializable: ^6.7.1 + build_runner: ^2.4.6 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/packages/wyatt_crud_bloc/example/test/widget_test.dart b/packages/wyatt_crud_bloc/example/test/widget_test.dart deleted file mode 100644 index 8b137891..00000000 --- a/packages/wyatt_crud_bloc/example/test/widget_test.dart +++ /dev/null @@ -1 +0,0 @@ - diff --git a/packages/wyatt_crud_bloc/lib/src/core/core.dart b/packages/wyatt_crud_bloc/lib/src/core/core.dart index 12ebcadf..daa34ab6 100644 --- a/packages/wyatt_crud_bloc/lib/src/core/core.dart +++ b/packages/wyatt_crud_bloc/lib/src/core/core.dart @@ -14,5 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +export 'enums/operation_type.dart'; export 'enums/where_query_type.dart'; export 'mixins/operation.dart'; +export 'model_identifier.dart'; +export 'model_mapper.dart'; diff --git a/packages/wyatt_crud_bloc/lib/src/domain/data_sources/data_sources.dart b/packages/wyatt_crud_bloc/lib/src/core/enums/operation_type.dart similarity index 86% rename from packages/wyatt_crud_bloc/lib/src/domain/data_sources/data_sources.dart rename to packages/wyatt_crud_bloc/lib/src/core/enums/operation_type.dart index 925fd22f..3405aa63 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/data_sources/data_sources.dart +++ b/packages/wyatt_crud_bloc/lib/src/core/enums/operation_type.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify @@ -14,4 +14,10 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -export 'crud_data_source.dart'; +enum OperationType { + query, + create, + read, + update, + delete, +} diff --git a/packages/wyatt_crud_bloc/lib/src/core/enums/where_query_type.dart b/packages/wyatt_crud_bloc/lib/src/core/enums/where_query_type.dart index 6a7c9bfe..aaeb0779 100644 --- a/packages/wyatt_crud_bloc/lib/src/core/enums/where_query_type.dart +++ b/packages/wyatt_crud_bloc/lib/src/core/enums/where_query_type.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify diff --git a/packages/wyatt_crud_bloc/lib/src/core/mixins/operation.dart b/packages/wyatt_crud_bloc/lib/src/core/mixins/operation.dart index dbfc08ff..513e17ba 100644 --- a/packages/wyatt_crud_bloc/lib/src/core/mixins/operation.dart +++ b/packages/wyatt_crud_bloc/lib/src/core/mixins/operation.dart @@ -15,20 +15,28 @@ // along with this program. If not, see . import 'package:wyatt_architecture/wyatt_architecture.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; +import 'package:wyatt_crud_bloc/src/core/enums/operation_type.dart'; /// Defines every write operation in CRUD. -mixin CreateOperation - on AsyncUseCase {} +mixin CreateOperation on AsyncUseCase { + /// {@macro create} + OperationType get operationType => OperationType.create; +} /// Defines every read operation in CRUD. -mixin ReadOperation - on AsyncUseCase {} +mixin ReadOperation on AsyncUseCase { + /// {@macro read} + OperationType get operationType => OperationType.read; +} /// Defines every update operation in CRUD. -mixin UpdateOperation - on AsyncUseCase {} +mixin UpdateOperation on AsyncUseCase { + /// {@macro update} + OperationType get operationType => OperationType.update; +} /// Defines every delete operation in CRUD. -mixin DeleteOperation - on AsyncUseCase {} +mixin DeleteOperation on AsyncUseCase { + /// {@macro delete} + OperationType get operationType => OperationType.delete; +} diff --git a/packages/wyatt_crud_bloc/lib/src/core/model_identifier.dart b/packages/wyatt_crud_bloc/lib/src/core/model_identifier.dart new file mode 100644 index 00000000..b294090c --- /dev/null +++ b/packages/wyatt_crud_bloc/lib/src/core/model_identifier.dart @@ -0,0 +1,57 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +class ModelIdentifier { + const ModelIdentifier({ + required this.getIdentifier, + }); + + final String Function(Model model) getIdentifier; + + String? getIdentifierOrNull(Model? model) { + if (model == null) { + return null; + } + + return getIdentifier(model); + } + + bool isIdentifier({ + required Model? model, + required String identifier, + }) { + if (model == null) { + return false; + } + + return getIdentifier(model) == identifier; + } + + bool areEqual( + Model? model1, + Model? model2, + ) { + if (model1 == null && model2 == null) { + return true; + } + + if (model1 == null || model2 == null) { + return false; + } + + return getIdentifier(model1) == getIdentifier(model2); + } +} diff --git a/packages/wyatt_crud_bloc/lib/src/data/data_sources/data_sources.dart b/packages/wyatt_crud_bloc/lib/src/core/model_mapper.dart similarity index 71% rename from packages/wyatt_crud_bloc/lib/src/data/data_sources/data_sources.dart rename to packages/wyatt_crud_bloc/lib/src/core/model_mapper.dart index 845ccb50..af2666c2 100644 --- a/packages/wyatt_crud_bloc/lib/src/data/data_sources/data_sources.dart +++ b/packages/wyatt_crud_bloc/lib/src/core/model_mapper.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify @@ -14,5 +14,12 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -export 'local/crud_in_memory_data_source_impl.dart'; -export 'remote/crud_firestore_data_source_impl.dart'; +class ModelMapper { + const ModelMapper({ + required this.fromJson, + required this.toJson, + }); + + final Model Function(Map? json) fromJson; + final Map Function(Model model) toJson; +} diff --git a/packages/wyatt_crud_bloc/lib/src/data/data.dart b/packages/wyatt_crud_bloc/lib/src/data/data.dart index 2fbca202..31207a5b 100644 --- a/packages/wyatt_crud_bloc/lib/src/data/data.dart +++ b/packages/wyatt_crud_bloc/lib/src/data/data.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify @@ -14,5 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -export 'data_sources/data_sources.dart'; -export 'repositories/repositories.dart'; +export 'data_sources/crud_data_source.dart'; +export 'data_sources/crud_data_source_in_memory_impl.dart'; +export 'repositories/crud_repository_impl.dart'; diff --git a/packages/wyatt_crud_bloc/lib/src/domain/data_sources/crud_data_source.dart b/packages/wyatt_crud_bloc/lib/src/data/data_sources/crud_data_source.dart similarity index 58% rename from packages/wyatt_crud_bloc/lib/src/domain/data_sources/crud_data_source.dart rename to packages/wyatt_crud_bloc/lib/src/data/data_sources/crud_data_source.dart index b6d0ba30..6d77eaf6 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/data_sources/crud_data_source.dart +++ b/packages/wyatt_crud_bloc/lib/src/data/data_sources/crud_data_source.dart @@ -15,47 +15,54 @@ // along with this program. If not, see . import 'package:wyatt_architecture/wyatt_architecture.dart'; +import 'package:wyatt_crud_bloc/src/core/enums/operation_type.dart'; import 'package:wyatt_crud_bloc/src/domain/entities/query.dart'; /// {@template crud_data_source} /// A [BaseDataSource] that provides SCRUD operations. /// {@endtemplate} -abstract class CrudDataSource extends BaseDataSource { +abstract class CrudDataSource extends BaseDataSource { /// {@macro crud_data_source} - const CrudDataSource(); - - /// Creates a new [Model] object. - Future create(Model object, {String? id}); - - /// Gets a [Model] object by its [id]. - Future get(String id); - - /// Gets all [Model] objects. - Future> getAll(); - - /// Updates a [Model] object by its [id]. - Future update( - String id, { - Model? object, - Map? raw, + const CrudDataSource({ + required this.id, }); - /// Updates all [Model] objects. + final String? Function( + OperationType operationType, + Map object, + ) id; + + /// Creates a new object. + Future create(Map object, {String? id}); + + /// Gets a object by its [id]. + Future?> get(String id); + + /// Gets all objects. + Future?> getAll(); + + /// Updates a object by its [id]. + Future update( + String id, { + Map? object, + }); + + /// Updates all objects. Future updateAll(Map? data); - /// Deletes a [Model] object by its [id]. + /// Deletes a object by its [id]. Future delete(String id); - /// Deletes all [Model] objects. + /// Deletes all objects. Future deleteAll(); - /// Queries [Model] objects by [conditions]. - Future> query(List conditions); + /// Queries objects by [conditions]. + Future?> search(List conditions); - /// Streams [Model] objects by [conditions]. - Stream> stream({ + /// Streams objects by [conditions]. + Stream?> stream({ String? id, - List? conditions, + List? conditions, bool includeMetadataChanges = false, }); } diff --git a/packages/wyatt_crud_bloc/lib/src/data/data_sources/local/crud_in_memory_data_source_impl.dart b/packages/wyatt_crud_bloc/lib/src/data/data_sources/crud_data_source_in_memory_impl.dart similarity index 53% rename from packages/wyatt_crud_bloc/lib/src/data/data_sources/local/crud_in_memory_data_source_impl.dart rename to packages/wyatt_crud_bloc/lib/src/data/data_sources/crud_data_source_in_memory_impl.dart index 7c2f706b..c5bff608 100644 --- a/packages/wyatt_crud_bloc/lib/src/data/data_sources/local/crud_in_memory_data_source_impl.dart +++ b/packages/wyatt_crud_bloc/lib/src/data/data_sources/crud_data_source_in_memory_impl.dart @@ -16,28 +16,56 @@ import 'dart:async'; +import 'package:rxdart/subjects.dart'; +import 'package:wyatt_crud_bloc/src/core/enums/operation_type.dart'; import 'package:wyatt_crud_bloc/src/core/enums/where_query_type.dart'; -import 'package:wyatt_crud_bloc/src/domain/data_sources/data_sources.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; +import 'package:wyatt_crud_bloc/src/data/data_sources/crud_data_source.dart'; import 'package:wyatt_crud_bloc/src/domain/entities/query.dart'; import 'package:wyatt_type_utils/wyatt_type_utils.dart'; -/// {@template crud_in_memory_data_source_impl} +extension _ModelExtension on Map { + Map merge( + Map? other, { + bool skipNulls = false, + }) { + if (other == null) { + return this; + } + final Map result = {}; + for (final key in keys) { + result[key] = other[key] ?? this[key]; + } + for (final key in other.keys) { + if (!containsKey(key)) { + result[key] = other[key]; + } + } + + if (skipNulls) { + result.removeWhere((key, value) => other[key] == null); + } + return result; + } +} + +/// {@template crud_data_source_in_memory_impl} /// A [CrudDataSource] that stores data in memory. /// {@endtemplate} -class CrudInMemoryDataSourceImpl - extends CrudDataSource { - /// {@macro crud_in_memory_data_source_impl} - CrudInMemoryDataSourceImpl({required this.toMap, Map? data}) - : _data = data ?? {}; - final Map _data; - final StreamController> _streamData = StreamController(); +class CrudDataSourceInMemoryImpl extends CrudDataSource { + /// {@macro crud_data_source_in_memory_impl} + CrudDataSourceInMemoryImpl({ + required super.id, + Map>? data, + }) : _data = data ?? {}; - final Map Function(Model) toMap; + final Map> _data; + final BehaviorSubject?>> _streamData = + BehaviorSubject?>>.seeded([]); @override - Future create(Model object, {String? id}) async { - _data[id ?? object.id ?? ''] = object; + Future create(Map object, {String? id}) async { + _data[id ?? this.id(OperationType.create, object) ?? ''] = object; + _streamData.add(_data.values.toList()); } @@ -54,14 +82,14 @@ class CrudInMemoryDataSourceImpl } @override - Future get(String id) async => _data[id]; + Future?> get(String id) async => _data[id]; @override - Future> getAll() async => _data.values.toList(); + Future?>> getAll() async => _data.values.toList(); @override - Future> query(List conditions) async { - List result = _data.values.toList(); + Future?>> search(List conditions) async { + List> result = _data.values.toList(); for (final c in conditions) { if (c is WhereQuery) { @@ -81,15 +109,15 @@ class CrudInMemoryDataSourceImpl } } - result.cast(); + result.cast>(); return result; } @override - Stream> stream({ + Stream?>> stream({ String? id, - List? conditions, + List? conditions, bool includeMetadataChanges = false, }) => _streamData.stream.map((result) { @@ -97,7 +125,7 @@ class CrudInMemoryDataSourceImpl return result; } - List res = result; + List?> res = result; for (final c in conditions) { if (c is WhereQuery) { @@ -115,61 +143,68 @@ class CrudInMemoryDataSourceImpl } return res; - }).asBroadcastStream(); + }); @override Future update( String id, { - Model? object, - Map? raw, + Map? object, }) { - // TODO(hpcl): implement update - throw UnimplementedError(); + if (object != null && _data.containsKey(id)) { + _data[id] = _data[id]!.merge(object); + _streamData.add(_data.values.toList()); + } + return Future.value(); } @override Future updateAll(Map? data) { - // TODO(hcpl): implement updateAll - throw UnimplementedError(); + if (data != null) { + for (final entry in _data.entries) { + _data[entry.key] = entry.value.merge(data); + } + _streamData.add(_data.values.toList()); + } + return Future.value(); } - bool _whereQuery(QueryInterface condition, Model? object) { + bool _whereQuery(Query condition, Map? object) { if (object == null) { return false; } - final raw = toMap.call(object); if (condition is WhereQuery) { switch (condition.type) { case WhereQueryType.isEqualTo: - return raw[condition.field] == condition.value; + return object[condition.field] == condition.value; case WhereQueryType.isNotEqualTo: - return raw[condition.field] != condition.value; + return object[condition.field] != condition.value; case WhereQueryType.isLessThan: - return (raw[condition.field] as num?) < (condition.value as num?); + return (object[condition.field] as num?) < (condition.value as num?); case WhereQueryType.isLessThanOrEqualTo: - return (raw[condition.field] as num?) <= (condition.value as num?); + return (object[condition.field] as num?) <= (condition.value as num?); case WhereQueryType.isGreaterThan: - return (raw[condition.field] as num?) > (condition.value as num?); + return (object[condition.field] as num?) > (condition.value as num?); case WhereQueryType.isGreaterThanOrEqualTo: - return (raw[condition.field] as num?) >= (condition.value as num?); + return (object[condition.field] as num?) >= (condition.value as num?); case WhereQueryType.arrayContains: - return (raw[condition.field] as List?) + return (object[condition.field] as List?) ?.contains(condition.value) ?? false; case WhereQueryType.arrayContainsAny: bool res = false; for (final o in condition.value as List) { - res = (raw[condition.field] as List?)?.contains(o) ?? false; + res = (object[condition.field] as List?)?.contains(o) ?? + false; } return res; case WhereQueryType.whereIn: return (condition.value as List) - .contains(raw[condition.field]); + .contains(object[condition.field]); case WhereQueryType.whereNotIn: return !(condition.value as List) - .contains(raw[condition.field]); + .contains(object[condition.field]); case WhereQueryType.isNull: - return raw[condition.field] == null; + return object[condition.field] == null; } } return true; diff --git a/packages/wyatt_crud_bloc/lib/src/data/repositories/crud_repository_impl.dart b/packages/wyatt_crud_bloc/lib/src/data/repositories/crud_repository_impl.dart index 7f068be2..e43e04fc 100644 --- a/packages/wyatt_crud_bloc/lib/src/data/repositories/crud_repository_impl.dart +++ b/packages/wyatt_crud_bloc/lib/src/data/repositories/crud_repository_impl.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify @@ -15,8 +15,8 @@ // along with this program. If not, see . import 'package:wyatt_architecture/wyatt_architecture.dart'; -import 'package:wyatt_crud_bloc/src/domain/data_sources/crud_data_source.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; +import 'package:wyatt_crud_bloc/src/core/model_mapper.dart'; +import 'package:wyatt_crud_bloc/src/data/data_sources/crud_data_source.dart'; import 'package:wyatt_crud_bloc/src/domain/entities/query.dart'; import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; import 'package:wyatt_type_utils/wyatt_type_utils.dart'; @@ -24,19 +24,23 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart'; /// {@template crud_repository_impl} /// A repository that implements the [CrudRepository] interface. /// {@endtemplate} -class CrudRepositoryImpl - extends CrudRepository { +class CrudRepositoryImpl extends CrudRepository { /// {@macro crud_repository_impl} const CrudRepositoryImpl({ - required CrudDataSource crudDataSource, + required this.modelMapper, + required CrudDataSource crudDataSource, }) : _crudDataSource = crudDataSource; - final CrudDataSource _crudDataSource; + + final CrudDataSource _crudDataSource; + + @override + final ModelMapper modelMapper; @override FutureOrResult create(Model object, {String? id}) => Result.tryCatchAsync( () async { - await _crudDataSource.create(object, id: id); + await _crudDataSource.create(modelMapper.toJson(object), id: id); }, (error) => error, ); @@ -44,14 +48,26 @@ class CrudRepositoryImpl @override FutureOrResult get(String id) => Result.tryCatchAsync( - () async => _crudDataSource.get(id), + () async => modelMapper.fromJson(await _crudDataSource.get(id)), (error) => error, ); @override FutureOrResult> getAll() => Result.tryCatchAsync, AppException, AppException>( - () async => _crudDataSource.getAll(), + () async { + final lst = await _crudDataSource.getAll(); + if (lst.isNotNull) { + return lst!.map((raw) { + try { + return modelMapper.fromJson(raw as Map?); + } catch (e) { + return null; + } + }).toList(); + } + throw const ServerException(); + }, (error) => error, ); @@ -62,7 +78,18 @@ class CrudRepositoryImpl Map? raw, }) => Result.tryCatchAsync( - () async => _crudDataSource.update(id, object: object, raw: raw), + () async { + if (object != null) { + await _crudDataSource.update( + id, + object: modelMapper.toJson(object), + ); + } else if (raw != null) { + await _crudDataSource.update(id, object: raw); + } else { + throw const ServerException(); + } + }, (error) => error, ); @@ -88,20 +115,40 @@ class CrudRepositoryImpl ); @override - FutureOrResult> query(List conditions) => + FutureOrResult> search(List conditions) => Result.tryCatchAsync, AppException, AppException>( - () async => _crudDataSource.query(conditions), + () async { + final lst = await _crudDataSource.search(conditions); + if (lst.isNotNull) { + return lst!.map((raw) { + try { + return modelMapper.fromJson(raw as Map?); + } catch (e) { + return null; + } + }).toList(); + } + throw const ServerException(); + }, (error) => error, ); @override StreamResult> stream({ String? id, - List? conditions, + List? conditions, }) => _crudDataSource.stream(id: id, conditions: conditions).map((lst) { if (lst.isNotNull) { - return Ok, AppException>(lst); + return Ok, AppException>( + lst!.map((raw) { + try { + return modelMapper.fromJson(raw as Map?); + } catch (e) { + return null; + } + }).toList(), + ); } return Err, AppException>(const ServerException()); }); diff --git a/packages/wyatt_crud_bloc/lib/src/domain/domain.dart b/packages/wyatt_crud_bloc/lib/src/domain/domain.dart index 35c41307..b6f71ff4 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/domain.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/domain.dart @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -export 'data_sources/data_sources.dart'; -export 'entities/entities.dart'; -export 'repositories/repositories.dart'; +export 'entities/query.dart'; +export 'repositories/crud_repository.dart'; export 'usecases/usecases.dart'; diff --git a/packages/wyatt_crud_bloc/lib/src/domain/entities/entities.dart b/packages/wyatt_crud_bloc/lib/src/domain/entities/entities.dart deleted file mode 100644 index bb2a29f7..00000000 --- a/packages/wyatt_crud_bloc/lib/src/domain/entities/entities.dart +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (C) 2022 WYATT GROUP -// Please see the AUTHORS file for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -export 'object_model.dart'; -export 'query.dart'; diff --git a/packages/wyatt_crud_bloc/lib/src/domain/entities/query.dart b/packages/wyatt_crud_bloc/lib/src/domain/entities/query.dart index 5fe8908f..e7f3c2b7 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/entities/query.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/entities/query.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify @@ -17,25 +17,20 @@ import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_crud_bloc/src/core/enums/where_query_type.dart'; -// // ignore: one_member_abstracts -// abstract class QueryParser { -// Q parser(QueryInterface condition, Q query); -// } - -typedef QueryParser = Q Function(QueryInterface condition, Q query); +typedef QueryParser = Q Function(Query condition, Q query); /// {@template query} /// An abstract class that represents a query. /// {@endtemplate} -abstract class QueryInterface extends Entity { +base class Query extends Entity { /// {@macro query} - const QueryInterface(); + const Query(); } /// {@template where_query} /// Represents a where query. /// {@endtemplate} -class WhereQuery extends QueryInterface { +final class WhereQuery extends Query { /// {@macro where_query} const WhereQuery(this.type, this.field, this.value); @@ -52,7 +47,7 @@ class WhereQuery extends QueryInterface { /// {@template limit_query} /// Represents a limit query. /// {@endtemplate} -class LimitQuery extends QueryInterface { +final class LimitQuery extends Query { /// {@macro limit_query} const LimitQuery(this.limit); @@ -63,7 +58,7 @@ class LimitQuery extends QueryInterface { /// {@template offset_query} /// Represents an offset query. /// {@endtemplate} -class OrderByQuery extends QueryInterface { +final class OrderByQuery extends Query { /// {@macro offset_query} const OrderByQuery(this.field, {this.ascending = true}); diff --git a/packages/wyatt_crud_bloc/lib/src/domain/repositories/crud_repository.dart b/packages/wyatt_crud_bloc/lib/src/domain/repositories/crud_repository.dart index 95b52190..0f6c0050 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/repositories/crud_repository.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/repositories/crud_repository.dart @@ -15,17 +15,18 @@ // along with this program. If not, see . import 'package:wyatt_architecture/wyatt_architecture.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; +import 'package:wyatt_crud_bloc/src/core/model_mapper.dart'; import 'package:wyatt_crud_bloc/src/domain/entities/query.dart'; /// {@template crud_repository} /// An abstract class that represents a SCRUD repository. /// {@endtemplate} -abstract class CrudRepository - extends BaseRepository { +abstract class CrudRepository extends BaseRepository { /// {@macro crud_repository} const CrudRepository(); + ModelMapper get modelMapper; + /// Creates a new object. FutureOrResult create(Model object, {String? id}); @@ -52,11 +53,11 @@ abstract class CrudRepository FutureOrResult deleteAll(); /// Queries objects by [conditions]. - FutureOrResult> query(List conditions); + FutureOrResult> search(List conditions); /// Streams objects by [conditions]. StreamResult> stream({ String? id, - List? conditions, + List? conditions, }); } diff --git a/packages/wyatt_crud_bloc/lib/src/domain/repositories/repositories.dart b/packages/wyatt_crud_bloc/lib/src/domain/repositories/repositories.dart deleted file mode 100644 index fb45fc62..00000000 --- a/packages/wyatt_crud_bloc/lib/src/domain/repositories/repositories.dart +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2022 WYATT GROUP -// Please see the AUTHORS file for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -export 'crud_repository.dart'; diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/create.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/create.dart index ff88a046..9ff3db82 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/usecases/create.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/create.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify @@ -14,31 +14,22 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import 'dart:async'; - import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart'; /// {@template create} /// A use case that creates an object model. /// {@endtemplate} -class Create extends AsyncUseCase +class Create extends Usecase with CreateOperation { /// {@macro create} - const Create(this._crudRepository); + const Create(this.crudRepository); - final CrudRepository _crudRepository; - - @override - FutureOr onStart(Model? params) { - if (params == null) { - throw ClientException('$Model cannot be null.'); - } - } + final CrudRepository crudRepository; @override FutureOrResult execute(Model? params) => - _crudRepository.create(params!); + crudRepository.create(params as Model); } diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/delete.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/delete.dart index d8ffb17d..be09ef82 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/usecases/delete.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/delete.dart @@ -14,31 +14,21 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import 'dart:async'; - import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart'; /// {@template delete} /// A use case that deletes an object model. /// {@endtemplate} -class Delete extends AsyncUseCase - with DeleteOperation { +class Delete extends Usecase with DeleteOperation { /// {@macro delete} - const Delete(this._crudRepository); + const Delete(this.crudRepository); - final CrudRepository _crudRepository; - - @override - FutureOr onStart(String? params) { - if (params == null) { - throw const ClientException('Id cannot be null.'); - } - } + final CrudRepository crudRepository; @override FutureOrResult execute(String? params) => - _crudRepository.delete(params!); + crudRepository.delete(params!); } diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/delete_all.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/delete_all.dart index ae1935d7..0fa348b4 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/usecases/delete_all.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/delete_all.dart @@ -16,19 +16,18 @@ import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart'; /// {@template delete_all} /// A use case that deletes all the object models. /// {@endtemplate} -class DeleteAll extends AsyncUseCase - with DeleteOperation { +class DeleteAll extends NoParamUsecase with DeleteOperation { /// {@macro delete_all} - const DeleteAll(this._crudRepository); + const DeleteAll(this.crudRepository); - final CrudRepository _crudRepository; + final CrudRepository crudRepository; @override - FutureOrResult execute(void params) => _crudRepository.deleteAll(); + FutureOrResult execute(void params) => crudRepository.deleteAll(); } diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/get.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/get.dart index 08850936..f74fbb0f 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/usecases/get.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/get.dart @@ -14,31 +14,21 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import 'dart:async'; - import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart'; /// {@template get} /// A use case that gets an object model. /// {@endtemplate} -class Get extends AsyncUseCase - with ReadOperation { +class Get extends Usecase + with ReadOperation { /// {@macro get} - Get(this._crudRepository); + Get(this.crudRepository); - final CrudRepository _crudRepository; + final CrudRepository crudRepository; @override - FutureOr onStart(String? params) { - if (params == null) { - throw const ClientException('Id cannot be null.'); - } - } - - @override - FutureOrResult execute(String? params) => - _crudRepository.get(params!); + FutureOrResult execute(String? params) => crudRepository.get(params!); } diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/get_all.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/get_all.dart index 63379212..1a2d9527 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/usecases/get_all.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/get_all.dart @@ -16,19 +16,19 @@ import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart'; /// {@template get_all} /// A use case that gets all the object models. /// {@endtemplate} -class GetAll extends AsyncUseCase> - with ReadOperation> { +class GetAll extends NoParamUsecase> + with ReadOperation> { /// {@macro get_all} - const GetAll(this._crudRepository); + const GetAll(this.crudRepository); - final CrudRepository _crudRepository; + final CrudRepository crudRepository; @override - FutureOrResult> execute(void params) => _crudRepository.getAll(); + FutureOrResult> execute(void params) => crudRepository.getAll(); } diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/params/stream_parameters.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/params/stream_parameters.dart index 0b2d178b..263c54f3 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/usecases/params/stream_parameters.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/params/stream_parameters.dart @@ -30,5 +30,5 @@ class StreamParameters { final String? id; /// The conditions of the query. - final List? conditions; + final List? conditions; } diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/query.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/search.dart similarity index 61% rename from packages/wyatt_crud_bloc/lib/src/domain/usecases/query.dart rename to packages/wyatt_crud_bloc/lib/src/domain/usecases/search.dart index 4869fa0d..512a4a46 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/usecases/query.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/search.dart @@ -14,33 +14,23 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import 'dart:async'; - import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; import 'package:wyatt_crud_bloc/src/domain/entities/query.dart'; import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart'; -/// {@template query} +/// {@template search} /// A use case that queries the object models. /// {@endtemplate} -class Query - extends AsyncUseCase, List> - with ReadOperation, List> { - /// {@macro query} - const Query(this._crudRepository); +class Search extends Usecase, List> + with ReadOperation, List> { + /// {@macro search} + const Search(this.crudRepository); - final CrudRepository _crudRepository; + final CrudRepository crudRepository; @override - FutureOr onStart(List? params) { - if (params == null) { - throw const ClientException('List of conditions cannot be null.'); - } - } - - @override - FutureOrResult> execute(List? params) => - _crudRepository.query(params!); + FutureOrResult> execute(List? params) => + crudRepository.search(params!); } diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/streaming.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/streaming.dart new file mode 100644 index 00000000..0a8184d6 --- /dev/null +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/streaming.dart @@ -0,0 +1,44 @@ +// Copyright (C) 2022 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'package:wyatt_architecture/wyatt_architecture.dart'; +import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart'; +import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart'; +import 'package:wyatt_type_utils/wyatt_type_utils.dart'; + +/// {@template streaming} +/// A use case that streams the object models. +/// {@endtemplate} +class Streaming + extends Usecase>> + with ReadOperation>> { + /// {@macro streaming} + const Streaming(this.crudRepository); + + final CrudRepository crudRepository; + + @override + FutureOrResult>> execute( + StreamParameters? params, + ) async => + Ok( + crudRepository.stream( + id: params!.id, + conditions: params.conditions, + ), + ); +} diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/update.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/update.dart index 237e3e9d..5d20e49e 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/usecases/update.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/update.dart @@ -14,35 +14,24 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import 'dart:async'; - import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; -import 'package:wyatt_crud_bloc/src/domain/usecases/params/update_parameters.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart'; /// {@template update} /// A use case that updates an object model. /// {@endtemplate} -class Update - extends AsyncUseCase, void> - with UpdateOperation> { +class Update extends Usecase, void> + with UpdateOperation> { /// {@macro update} - const Update(this._crudRepository); + const Update(this.crudRepository); - final CrudRepository _crudRepository; - - @override - FutureOr onStart(UpdateParameters? params) { - if (params == null) { - throw const ClientException('Update parameters cannot be null.'); - } - } + final CrudRepository crudRepository; @override FutureOrResult execute(UpdateParameters? params) => - _crudRepository.update( + crudRepository.update( params!.id, object: params.object, raw: params.raw, diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/update_all.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/update_all.dart index 22c32181..76dcef70 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/usecases/update_all.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/update_all.dart @@ -14,32 +14,22 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import 'dart:async'; - import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart'; /// {@template update_all} /// A use case that updates all the object models. /// {@endtemplate} -class UpdateAll - extends AsyncUseCase, void> - with UpdateOperation> { +class UpdateAll extends Usecase, void> + with UpdateOperation> { /// {@macro update_all} - const UpdateAll(this._crudRepository); + const UpdateAll(this.crudRepository); - final CrudRepository _crudRepository; - - @override - FutureOr onStart(Map? params) { - if (params == null) { - throw const ClientException('Data cannot be null.'); - } - } + final CrudRepository crudRepository; @override FutureOrResult execute(Map? params) => - _crudRepository.updateAll(params!); + crudRepository.updateAll(params!); } diff --git a/packages/wyatt_crud_bloc/lib/src/domain/usecases/usecases.dart b/packages/wyatt_crud_bloc/lib/src/domain/usecases/usecases.dart index 4a8d8467..6f292edd 100644 --- a/packages/wyatt_crud_bloc/lib/src/domain/usecases/usecases.dart +++ b/packages/wyatt_crud_bloc/lib/src/domain/usecases/usecases.dart @@ -14,12 +14,37 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +import 'dart:async'; + +import 'package:wyatt_architecture/wyatt_architecture.dart'; +import 'package:wyatt_crud_bloc/src/core/enums/operation_type.dart'; + export 'create.dart'; export 'delete.dart'; export 'delete_all.dart'; export 'get.dart'; export 'get_all.dart'; export 'params/params.dart'; -export 'query.dart'; +export 'search.dart'; +export 'streaming.dart'; export 'update.dart'; export 'update_all.dart'; + +abstract class Usecase extends AsyncUseCase { + const Usecase(); + + @override + FutureOr onStart(In? params) { + if (params == null) { + throw ClientException('$In cannot be null.'); + } + } + + OperationType get operationType; +} + +abstract class NoParamUsecase extends AsyncUseCase { + const NoParamUsecase(); + + OperationType get operationType; +} diff --git a/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_advanced_cubit.dart b/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_advanced_cubit.dart index 85546422..8c6fe57f 100644 --- a/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_advanced_cubit.dart +++ b/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_advanced_cubit.dart @@ -16,25 +16,28 @@ import 'dart:async'; +import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_crud_bloc/src/core/enums/where_query_type.dart'; -import 'package:wyatt_crud_bloc/src/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'; import 'package:wyatt_crud_bloc/src/domain/usecases/delete_all.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/get.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/get_all.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/params/stream_parameters.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/params/update_parameters.dart'; -import 'package:wyatt_crud_bloc/src/domain/usecases/query.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/search.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/streaming.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/update.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/update_all.dart'; import 'package:wyatt_crud_bloc/src/features/crud/blocs/crud_base_cubit/crud_base_cubit.dart'; +import 'package:wyatt_type_utils/wyatt_type_utils.dart'; /// {@template crud_cubit_advanced} /// Cubit that handles CRUD operations with more granularity. /// {@endtemplate} -abstract class CrudAdvancedCubit - extends CrudBaseCubit { +abstract class CrudAdvancedCubit extends CrudBaseCubit { /// {@macro crud_cubit} CrudAdvancedCubit() : super(); @@ -43,10 +46,17 @@ abstract class CrudAdvancedCubit Delete? get crudDelete; GetAll? get crudGetAll; Get? get crudGet; - Query? get crudQuery; + Search? get crudSearch; + Streaming? get crudStreaming; UpdateAll? get crudUpdateAll; Update? get crudUpdate; + /// Model identifier. + /// Used to identify a model. + ModelIdentifier get modelIdentifier; + + StreamSubscription, AppException>>? _streamSubscription; + FutureOr create(Model model) async { final crud = crudCreate; if (crud == null) { @@ -54,8 +64,12 @@ abstract class CrudAdvancedCubit } final stateCopy = state; - emit(const CrudLoading()); + emit(const CrudCreating()); final result = await crud.call(model); + if (crudStreaming != null && _streamSubscription != null && result.isOk) { + // If streaming is available, we don't need to update stateCopy. + return; + } emit( result.fold( (_) { @@ -63,7 +77,7 @@ abstract class CrudAdvancedCubit if (stateCopy.data == null) { return CrudLoaded(model); } - if (stateCopy.data!.id == model.id) { + if (modelIdentifier.areEqual(stateCopy.data, model)) { return CrudLoaded(model); } @@ -78,7 +92,7 @@ abstract class CrudAdvancedCubit return CrudListLoaded(lst); } - return const CrudOkReturn(); + return const CrudCreated(); }, (error) => CrudError(error.toString()), ), @@ -92,13 +106,20 @@ abstract class CrudAdvancedCubit } final stateCopy = state; - emit(const CrudLoading()); + emit(const CrudDeleting()); final result = await crud.call(id); + if (crudStreaming != null && _streamSubscription != null && result.isOk) { + // If streaming is available, we don't need to update stateCopy. + return; + } emit( result.fold( (_) { if (stateCopy is CrudLoaded) { - if (stateCopy.data?.id == id) { + if (modelIdentifier.isIdentifier( + model: stateCopy.data, + identifier: id, + )) { return CrudLoaded(null); } @@ -106,11 +127,19 @@ abstract class CrudAdvancedCubit } if (stateCopy is CrudListLoaded) { return CrudListLoaded( - stateCopy.data.where((element) => element?.id != id).toList(), + stateCopy.data.where((element) { + if (element == null) { + return false; + } + return !modelIdentifier.isIdentifier( + model: element, + identifier: id, + ); + }).toList(), ); } - return const CrudOkReturn(); + return const CrudDeleted(); }, (error) => CrudError(error.toString()), ), @@ -123,8 +152,12 @@ abstract class CrudAdvancedCubit return; } final stateCopy = state; - emit(const CrudLoading()); + emit(const CrudDeleting()); final result = await crud.call(null); + if (crudStreaming != null && _streamSubscription != null && result.isOk) { + // If streaming is available, we don't need to update stateCopy. + return; + } emit( result.fold( (_) { @@ -147,7 +180,7 @@ abstract class CrudAdvancedCubit if (crud == null) { return; } - emit(const CrudLoading()); + emit(const CrudReading()); final result = await crud.call(id); emit( result.fold( @@ -162,7 +195,7 @@ abstract class CrudAdvancedCubit if (crud == null) { return; } - emit(const CrudLoading()); + emit(const CrudReading()); final result = await crud.call(null); emit( result.fold( @@ -172,13 +205,13 @@ abstract class CrudAdvancedCubit ); } - FutureOr query(List conditions) async { - final crud = crudQuery; + FutureOr search(List conditions) async { + final crud = crudSearch; if (crud == null) { return; } - emit(const CrudLoading()); + emit(const CrudReading()); final result = await crud.call(conditions); emit( result.fold( @@ -188,6 +221,31 @@ abstract class CrudAdvancedCubit ); } + FutureOr streaming({ + String? id, + List? conditions, + }) async { + final crud = crudStreaming; + if (crud == null) { + return; + } + final result = await crud.call( + StreamParameters( + id: id, + conditions: conditions, + ), + ); + + _streamSubscription = result.ok?.listen((event) { + emit( + event.fold( + CrudListLoaded.new, + (error) => CrudError(error.toString()), + ), + ); + }); + } + FutureOr update(UpdateParameters param) async { final crud = crudUpdate; if (crud == null) { @@ -195,13 +253,20 @@ abstract class CrudAdvancedCubit } final stateCopy = state; - emit(const CrudLoading()); + emit(const CrudUpdating()); final result = await crud.call(param); + if (crudStreaming != null && _streamSubscription != null && result.isOk) { + // If streaming is available, we don't need to update stateCopy. + return; + } emit( await result.foldAsync( (_) async { if (stateCopy is CrudLoaded) { - if (stateCopy.data?.id == param.id) { + if (modelIdentifier.isIdentifier( + model: stateCopy.data, + identifier: param.id, + )) { // Same object, need to update actual stateCopy final crudGet = this.crudGet; if (crudGet == null) { @@ -216,8 +281,15 @@ abstract class CrudAdvancedCubit return stateCopy; } if (stateCopy is CrudListLoaded) { - final bool listContains = - stateCopy.data.any((element) => element?.id == param.id); + final bool listContains = stateCopy.data.any((element) { + if (element == null) { + return false; + } + return modelIdentifier.isIdentifier( + model: element, + identifier: param.id, + ); + }); if (listContains) { // Loaded objects contains the modified object. @@ -228,17 +300,23 @@ abstract class CrudAdvancedCubit } final newVersion = await crudGet.call(param.id); if (newVersion.isOk) { - final newList = stateCopy.data - .where( - (element) => element?.id != param.id, - ) - .toList(); + final newList = stateCopy.data.where( + (element) { + if (element == null) { + return false; + } + return !modelIdentifier.isIdentifier( + model: element, + identifier: param.id, + ); + }, + ).toList(); return CrudListLoaded(newList + [newVersion.ok]); } } return stateCopy; } - return const CrudOkReturn(); + return const CrudUpdated(); }, (error) async => CrudError(error.toString()), ), @@ -252,8 +330,12 @@ abstract class CrudAdvancedCubit } final stateCopy = state; - emit(const CrudLoading()); + emit(const CrudUpdating()); final result = await crud.call(param); + if (crudStreaming != null && _streamSubscription != null && result.isOk) { + // If streaming is available, we don't need to update stateCopy. + return; + } emit( await result.foldAsync( (_) async { @@ -264,7 +346,8 @@ abstract class CrudAdvancedCubit // No read operation, can't update stateCopy. return stateCopy; } - final actualId = stateCopy.data?.id; + final actualId = + modelIdentifier.getIdentifierOrNull(stateCopy.data); final newVersion = await crudGet.call(actualId ?? ''); if (newVersion.isOk) { return CrudLoaded(newVersion.ok); @@ -272,8 +355,8 @@ abstract class CrudAdvancedCubit return stateCopy; } if (stateCopy is CrudListLoaded) { - final crudQuery = this.crudQuery; - if (crudQuery == null) { + final crudSearch = this.crudSearch; + if (crudSearch == null) { // No read operation, can't update stateCopy. return stateCopy; } @@ -281,10 +364,11 @@ abstract class CrudAdvancedCubit // (not all because previous stateCopy can be a query result) final List ids = stateCopy.data .map( - (e) => e?.id, + (e) => modelIdentifier.getIdentifierOrNull(e), ) + .where((element) => element != null) .toList(); - final result = await crudQuery.call([ + final result = await crudSearch.call([ WhereQuery( WhereQueryType.whereIn, 'id', @@ -296,10 +380,16 @@ abstract class CrudAdvancedCubit } return stateCopy; } - return const CrudOkReturn(); + return const CrudUpdated(); }, (error) async => CrudError(error.toString()), ), ); } + + @override + Future close() async { + await _streamSubscription?.cancel(); + return super.close(); + } } diff --git a/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_base_cubit/crud_state.dart b/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_base_cubit/crud_state.dart index 64f2479a..2e473b90 100644 --- a/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_base_cubit/crud_state.dart +++ b/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_base_cubit/crud_state.dart @@ -16,7 +16,7 @@ part of 'crud_base_cubit.dart'; -abstract class CrudState extends Equatable { +sealed class CrudState extends Equatable { const CrudState(); @override @@ -33,6 +33,22 @@ class CrudLoading extends CrudState { const CrudLoading(); } +class CrudCreating extends CrudLoading { + const CrudCreating(); +} + +class CrudReading extends CrudLoading { + const CrudReading(); +} + +class CrudUpdating extends CrudLoading { + const CrudUpdating(); +} + +class CrudDeleting extends CrudLoading { + const CrudDeleting(); +} + /// Error state of the CrudBaseCubit. class CrudError extends CrudState { const CrudError(this.message); @@ -57,6 +73,18 @@ class CrudOkReturn extends CrudSuccess { const CrudOkReturn(); } +class CrudCreated extends CrudOkReturn { + const CrudCreated(); +} + +class CrudUpdated extends CrudOkReturn { + const CrudUpdated(); +} + +class CrudDeleted extends CrudOkReturn { + const CrudDeleted(); +} + /// Loaded state of the CrudBaseCubit. /// This state is used to indicate that the operation was successful. /// Contains one object. diff --git a/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_cubit.dart b/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_cubit.dart index 97265465..6495abba 100644 --- a/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_cubit.dart +++ b/packages/wyatt_crud_bloc/lib/src/features/crud/blocs/crud_cubit.dart @@ -16,43 +16,58 @@ import 'dart:async'; +import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_crud_bloc/src/core/enums/where_query_type.dart'; import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart'; -import 'package:wyatt_crud_bloc/src/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'; import 'package:wyatt_crud_bloc/src/domain/usecases/delete_all.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/get.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/get_all.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/params/stream_parameters.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/params/update_parameters.dart'; -import 'package:wyatt_crud_bloc/src/domain/usecases/query.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/search.dart'; +import 'package:wyatt_crud_bloc/src/domain/usecases/streaming.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/update.dart'; import 'package:wyatt_crud_bloc/src/domain/usecases/update_all.dart'; import 'package:wyatt_crud_bloc/src/features/crud/blocs/crud_base_cubit/crud_base_cubit.dart'; +import 'package:wyatt_type_utils/wyatt_type_utils.dart'; + +typedef DefaultCreate = CreateOperation; +typedef DefaultRead = ReadOperation; +typedef DefaultUpdate = UpdateOperation; +typedef DefaultDelete = DeleteOperation; /// {@template crud_cubit} -/// Cubit that handles CRUD operations. +/// Cubit that handles SCRUD operations. /// {@endtemplate} -abstract class CrudCubit extends CrudBaseCubit { +abstract class CrudCubit extends CrudBaseCubit { /// {@macro crud_cubit} CrudCubit() : super(); /// Create operation. /// Can be create. - CreateOperation? get createOperation; + CreateOperation? get createOperation; /// Read operation. - /// Can be get, getAll, query. - ReadOperation? get readOperation; + /// Can be get, getAll, search or stream. + ReadOperation? get readOperation; /// Update operation. /// Can be update, updateAll. - UpdateOperation? get updateOperation; + UpdateOperation? get updateOperation; /// Delete operation. /// Can be delete or deleteAll. - DeleteOperation? get deleteOperation; + DeleteOperation? get deleteOperation; + + /// Model identifier. + /// Used to identify a model. + ModelIdentifier get modelIdentifier; + + StreamSubscription, AppException>>? _streamSubscription; Expected? _checkOperation(dynamic operation) { if (operation == null) { @@ -70,27 +85,29 @@ abstract class CrudCubit extends CrudBaseCubit { } } - FutureOr read({String? id, List? conditions}) async { + FutureOr read({String? id, List? conditions}) async { if (_checkOperation>(readOperation) != null && id != null) { return _get(id); } if (_checkOperation>(readOperation) != null) { return _getAll(); } - if (_checkOperation>(readOperation) != null && + if (_checkOperation>(readOperation) != null && conditions != null) { - return _query(conditions); + return _search(conditions); } - if (_checkOperation>(readOperation) != null && - conditions == null) { - return _getAll(); + if (_checkOperation>(readOperation) != null) { + return _streaming( + id: id, + conditions: conditions, + ); } } - FutureOr update( + FutureOr update({ UpdateParameters? single, Map? all, - ) async { + }) async { if (_checkOperation>(updateOperation) != null && single != null) { return _update(single); @@ -118,8 +135,13 @@ abstract class CrudCubit extends CrudBaseCubit { } final stateCopy = state; - emit(const CrudLoading()); + emit(const CrudCreating()); final result = await crud.call(model); + final crudStreaming = _checkOperation>(readOperation); + if (crudStreaming != null && _streamSubscription != null && result.isOk) { + // If streaming is available, we don't need to update stateCopy. + return; + } emit( result.fold( (_) { @@ -127,7 +149,7 @@ abstract class CrudCubit extends CrudBaseCubit { if (stateCopy.data == null) { return CrudLoaded(model); } - if (stateCopy.data!.id == model.id) { + if (stateCopy.data == model) { return CrudLoaded(model); } @@ -142,7 +164,7 @@ abstract class CrudCubit extends CrudBaseCubit { return CrudListLoaded(lst); } - return const CrudOkReturn(); + return const CrudCreated(); }, (error) => CrudError(error.toString()), ), @@ -156,13 +178,21 @@ abstract class CrudCubit extends CrudBaseCubit { } final stateCopy = state; - emit(const CrudLoading()); + emit(const CrudDeleting()); final result = await crud.call(id); + final crudStreaming = _checkOperation>(readOperation); + if (crudStreaming != null && _streamSubscription != null && result.isOk) { + // If streaming is available, we don't need to update stateCopy. + return; + } emit( result.fold( (_) { if (stateCopy is CrudLoaded) { - if (stateCopy.data?.id == id) { + if (modelIdentifier.isIdentifier( + model: stateCopy.data, + identifier: id, + )) { return CrudLoaded(null); } @@ -170,11 +200,19 @@ abstract class CrudCubit extends CrudBaseCubit { } if (stateCopy is CrudListLoaded) { return CrudListLoaded( - stateCopy.data.where((element) => element?.id != id).toList(), + stateCopy.data.where((element) { + if (element == null) { + return false; + } + return !modelIdentifier.isIdentifier( + model: element, + identifier: id, + ); + }).toList(), ); } - return const CrudOkReturn(); + return const CrudDeleted(); }, (error) => CrudError(error.toString()), ), @@ -187,8 +225,13 @@ abstract class CrudCubit extends CrudBaseCubit { return; } final stateCopy = state; - emit(const CrudLoading()); + emit(const CrudDeleting()); final result = await crud.call(null); + final crudStreaming = _checkOperation>(readOperation); + if (crudStreaming != null && _streamSubscription != null && result.isOk) { + // If streaming is available, we don't need to update stateCopy. + return; + } emit( result.fold( (_) { @@ -199,7 +242,7 @@ abstract class CrudCubit extends CrudBaseCubit { return CrudListLoaded(const []); } - return const CrudOkReturn(); + return const CrudDeleted(); }, (error) => CrudError(error.toString()), ), @@ -211,7 +254,7 @@ abstract class CrudCubit extends CrudBaseCubit { if (crud == null) { return; } - emit(const CrudLoading()); + emit(const CrudReading()); final result = await crud.call(id); emit( result.fold( @@ -226,7 +269,7 @@ abstract class CrudCubit extends CrudBaseCubit { if (crud == null) { return; } - emit(const CrudLoading()); + emit(const CrudReading()); final result = await crud.call(null); emit( result.fold( @@ -236,13 +279,38 @@ abstract class CrudCubit extends CrudBaseCubit { ); } - FutureOr _query(List conditions) async { - final crud = _checkOperation>(readOperation); + FutureOr _streaming({ + String? id, + List? conditions, + }) async { + final crud = _checkOperation>(readOperation); + if (crud == null) { + return; + } + final result = await crud.call( + StreamParameters( + id: id, + conditions: conditions, + ), + ); + + _streamSubscription = result.ok?.listen((event) { + emit( + event.fold( + CrudListLoaded.new, + (error) => CrudError(error.toString()), + ), + ); + }); + } + + FutureOr _search(List conditions) async { + final crud = _checkOperation>(readOperation); if (crud == null) { return; } - emit(const CrudLoading()); + emit(const CrudReading()); final result = await crud.call(conditions); emit( result.fold( @@ -259,13 +327,21 @@ abstract class CrudCubit extends CrudBaseCubit { } final stateCopy = state; - emit(const CrudLoading()); + emit(const CrudUpdating()); final result = await crud.call(param); + final crudStreaming = _checkOperation>(readOperation); + if (crudStreaming != null && _streamSubscription != null && result.isOk) { + // If streaming is available, we don't need to update stateCopy. + return; + } emit( await result.foldAsync( (_) async { if (stateCopy is CrudLoaded) { - if (stateCopy.data?.id == param.id) { + if (modelIdentifier.isIdentifier( + model: stateCopy.data, + identifier: param.id, + )) { // Same object, need to update actual stateCopy final crudGet = _checkOperation>(readOperation); if (crudGet == null) { @@ -280,29 +356,48 @@ abstract class CrudCubit extends CrudBaseCubit { return stateCopy; } if (stateCopy is CrudListLoaded) { - final bool listContains = - stateCopy.data.any((element) => element?.id == param.id); + final bool listContains = stateCopy.data.any((element) { + if (element == null) { + return false; + } + return modelIdentifier.isIdentifier( + model: element, + identifier: param.id, + ); + }); if (listContains) { // Loaded objects contains the modified object. - final crudGet = _checkOperation>(readOperation); - if (crudGet == null) { - // No read operation, can't update stateCopy. - return stateCopy; + if (crudGet != null) { + final newVersion = await crudGet.call(param.id); + if (newVersion.isOk) { + final newList = stateCopy.data.where( + (element) { + if (element == null) { + return false; + } + return !modelIdentifier.isIdentifier( + model: element, + identifier: param.id, + ); + }, + ).toList(); + return CrudListLoaded(newList + [newVersion.ok]); + } } - final newVersion = await crudGet.call(param.id); - if (newVersion.isOk) { - final newList = stateCopy.data - .where( - (element) => element?.id != param.id, - ) - .toList(); - return CrudListLoaded(newList + [newVersion.ok]); + + // If get operation is not available, just reload all objects. + final crudGetAll = _checkOperation>(readOperation); + if (crudGetAll != null) { + final newVersion = await crudGetAll.call(null); + if (newVersion.isOk) { + return CrudListLoaded(newVersion.ok ?? []); + } } } return stateCopy; } - return const CrudOkReturn(); + return const CrudUpdated(); }, (error) async => CrudError(error.toString()), ), @@ -316,8 +411,13 @@ abstract class CrudCubit extends CrudBaseCubit { } final stateCopy = state; - emit(const CrudLoading()); + emit(const CrudUpdating()); final result = await crud.call(param); + final crudStreaming = _checkOperation>(readOperation); + if (crudStreaming != null && _streamSubscription != null && result.isOk) { + // If streaming is available, we don't need to update stateCopy. + return; + } emit( await result.foldAsync( (_) async { @@ -328,7 +428,8 @@ abstract class CrudCubit extends CrudBaseCubit { // No read operation, can't update stateCopy. return stateCopy; } - final actualId = stateCopy.data?.id; + final actualId = + modelIdentifier.getIdentifierOrNull(stateCopy.data); final newVersion = await crudGet.call(actualId ?? ''); if (newVersion.isOk) { return CrudLoaded(newVersion.ok); @@ -336,7 +437,7 @@ abstract class CrudCubit extends CrudBaseCubit { return stateCopy; } if (stateCopy is CrudListLoaded) { - final crudQuery = _checkOperation>(readOperation); + final crudQuery = _checkOperation>(readOperation); if (crudQuery == null) { // No read operation, can't update stateCopy. return stateCopy; @@ -345,8 +446,9 @@ abstract class CrudCubit extends CrudBaseCubit { // (not all because previous stateCopy can be a query result) final List ids = stateCopy.data .map( - (e) => e?.id, + (e) => modelIdentifier.getIdentifierOrNull(e), ) + .where((element) => element != null) .toList(); final result = await crudQuery.call([ WhereQuery( @@ -360,10 +462,16 @@ abstract class CrudCubit extends CrudBaseCubit { } return stateCopy; } - return const CrudOkReturn(); + return const CrudUpdated(); }, (error) async => CrudError(error.toString()), ), ); } + + @override + Future close() async { + await _streamSubscription?.cancel(); + return super.close(); + } } diff --git a/packages/wyatt_crud_bloc/lib/src/features/crud/builder/builder.dart b/packages/wyatt_crud_bloc/lib/src/features/crud/builder/builder.dart deleted file mode 100644 index 52cf109d..00000000 --- a/packages/wyatt_crud_bloc/lib/src/features/crud/builder/builder.dart +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2022 WYATT GROUP -// Please see the AUTHORS file for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -export 'crud_builder.dart'; diff --git a/packages/wyatt_crud_bloc/lib/src/features/crud/builder/crud_builder.dart b/packages/wyatt_crud_bloc/lib/src/features/crud/builder/crud_builder.dart index d864ce7a..5789d599 100644 --- a/packages/wyatt_crud_bloc/lib/src/features/crud/builder/crud_builder.dart +++ b/packages/wyatt_crud_bloc/lib/src/features/crud/builder/crud_builder.dart @@ -15,26 +15,27 @@ // along with this program. If not, see . import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:wyatt_crud_bloc/src/features/crud/blocs/crud_base_cubit/crud_base_cubit.dart'; /// {@template crud_builder} /// A widget that builds itself based on the latest snapshot of interaction /// with a [CrudBaseCubit]. -/// -/// * I = Initial State -/// * L = Loading State -/// * S = Success State -/// * E = Error State /// {@endtemplate} -class CrudBuilder extends StatelessWidget { +class CrudBuilder< + Bloc extends StateStreamable, + Initial extends CrudState, + Loading extends CrudState, + Success extends CrudState, + Error extends CrudState> extends StatelessWidget { /// {@macro crud_builder} const CrudBuilder({ - required this.state, required this.builder, required this.initialBuilder, required this.loadingBuilder, required this.errorBuilder, this.unknownBuilder, + this.buildWhen, super.key, }); @@ -43,50 +44,121 @@ class CrudBuilder extends StatelessWidget { /// This factory constructor is used to create a [CrudBuilder] with /// [CrudState]s. `S` is the Success State, and it must be a subtype of /// [CrudSuccess]. It the only type that you have to specify. - static CrudBuilder - typed({ - required CrudState state, - required Widget Function(BuildContext, S) builder, + static CrudBuilder + typed, + Success extends CrudSuccess>({ + required Widget Function(BuildContext, Success) builder, required Widget Function(BuildContext, CrudInitial) initialBuilder, required Widget Function(BuildContext, CrudLoading) loadingBuilder, required Widget Function(BuildContext, CrudError) errorBuilder, - Widget Function(BuildContext, Object)? unknownBuilder, + Widget Function(BuildContext, CrudState)? unknownBuilder, + BlocBuilderCondition? buildWhen, }) => - CrudBuilder( - state: state, + CrudBuilder( builder: builder, initialBuilder: initialBuilder, loadingBuilder: loadingBuilder, errorBuilder: errorBuilder, unknownBuilder: unknownBuilder, + buildWhen: buildWhen, ); - final Object state; - final Widget Function(BuildContext context, S state) builder; - final Widget Function(BuildContext context, I state) initialBuilder; - final Widget Function(BuildContext context, L state) loadingBuilder; - final Widget Function(BuildContext context, E state) errorBuilder; - final Widget Function(BuildContext context, Object state)? unknownBuilder; + /// {@macro crud_builder} + /// + /// This factory constructor is used to create a [CrudBuilder] wich reacts + /// only to [CrudLoading] states. + static CrudBuilder + onLoading>({ + required Widget? Function(BuildContext, CrudLoading) builder, + Widget Function(BuildContext, CrudState)? otherBuilder, + BlocBuilderCondition? buildWhen, + }) => + CrudBuilder( + loadingBuilder: (context, state) => + builder.call(context, state) ?? + otherBuilder?.call(context, state) ?? + const SizedBox.shrink(), + builder: (context, state) => + otherBuilder?.call(context, state) ?? const SizedBox.shrink(), + initialBuilder: (context, state) => + otherBuilder?.call(context, state) ?? const SizedBox.shrink(), + errorBuilder: (context, state) => + otherBuilder?.call(context, state) ?? const SizedBox.shrink(), + unknownBuilder: otherBuilder, + buildWhen: buildWhen, + ); + + /// {@macro crud_builder} + /// + /// This factory constructor is used to create a [CrudBuilder] wich reacts + /// only to [CrudInitial] states. + static CrudBuilder + onInitial>({ + required Widget? Function(BuildContext, CrudInitial) builder, + Widget Function(BuildContext, CrudState)? otherBuilder, + BlocBuilderCondition? buildWhen, + }) => + CrudBuilder( + initialBuilder: (context, state) => + builder.call(context, state) ?? + otherBuilder?.call(context, state) ?? + const SizedBox.shrink(), + builder: (context, state) => + otherBuilder?.call(context, state) ?? const SizedBox.shrink(), + loadingBuilder: (context, state) => + otherBuilder?.call(context, state) ?? const SizedBox.shrink(), + errorBuilder: (context, state) => + otherBuilder?.call(context, state) ?? const SizedBox.shrink(), + unknownBuilder: otherBuilder, + buildWhen: buildWhen, + ); + + /// {@macro crud_builder} + /// + /// This factory constructor is used to create a [CrudBuilder] wich reacts + /// only to [CrudError] states. + static CrudBuilder + onError>({ + required Widget? Function(BuildContext, CrudError) builder, + Widget Function(BuildContext, CrudState)? otherBuilder, + BlocBuilderCondition? buildWhen, + }) => + CrudBuilder( + errorBuilder: (context, state) => + builder.call(context, state) ?? + otherBuilder?.call(context, state) ?? + const SizedBox.shrink(), + builder: (context, state) => + otherBuilder?.call(context, state) ?? const SizedBox.shrink(), + loadingBuilder: (context, state) => + otherBuilder?.call(context, state) ?? const SizedBox.shrink(), + initialBuilder: (context, state) => + otherBuilder?.call(context, state) ?? const SizedBox.shrink(), + unknownBuilder: otherBuilder, + buildWhen: buildWhen, + ); + + final BlocBuilderCondition? buildWhen; + final Widget Function(BuildContext context, Success state) builder; + final Widget Function(BuildContext context, Initial state) initialBuilder; + final Widget Function(BuildContext context, Loading state) loadingBuilder; + final Widget Function(BuildContext context, Error state) errorBuilder; + final Widget Function(BuildContext context, CrudState state)? unknownBuilder; @override - Widget build(BuildContext context) => Builder( - builder: (context) { - if (state is S) { - return builder(context, state as S); - } else if (state is E) { - return errorBuilder(context, state as E); - } else if (state is L) { - return loadingBuilder(context, state as L); - } else if (state is I) { - return initialBuilder(context, state as I); - } else { - return unknownBuilder?.call(context, state) ?? - Center( - child: Text( - 'Unknown state: $state', - ), - ); - } + Widget build(BuildContext context) => BlocBuilder( + buildWhen: buildWhen, + builder: (context, state) => switch (state) { + Success() => builder(context, state), + Initial() => initialBuilder(context, state), + Loading() => loadingBuilder(context, state), + Error() => errorBuilder(context, state), + _ => unknownBuilder?.call(context, state) ?? + Center( + child: Text( + 'Unknown state: $state', + ), + ), }, ); } diff --git a/packages/wyatt_crud_bloc/lib/src/features/crud/crud.dart b/packages/wyatt_crud_bloc/lib/src/features/crud/crud.dart index 16113197..7027e5ec 100644 --- a/packages/wyatt_crud_bloc/lib/src/features/crud/crud.dart +++ b/packages/wyatt_crud_bloc/lib/src/features/crud/crud.dart @@ -17,4 +17,4 @@ export 'blocs/crud_advanced_cubit.dart'; export 'blocs/crud_base_cubit/crud_base_cubit.dart'; export 'blocs/crud_cubit.dart'; -export 'builder/builder.dart'; +export 'builder/crud_builder.dart'; diff --git a/packages/wyatt_crud_bloc/lib/wyatt_crud_bloc.dart b/packages/wyatt_crud_bloc/lib/wyatt_crud_bloc.dart index 2656783e..ceabcacd 100644 --- a/packages/wyatt_crud_bloc/lib/wyatt_crud_bloc.dart +++ b/packages/wyatt_crud_bloc/lib/wyatt_crud_bloc.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify diff --git a/packages/wyatt_crud_bloc/pubspec.yaml b/packages/wyatt_crud_bloc/pubspec.yaml index 39c1d03d..c66385f2 100644 --- a/packages/wyatt_crud_bloc/pubspec.yaml +++ b/packages/wyatt_crud_bloc/pubspec.yaml @@ -1,20 +1,18 @@ name: wyatt_crud_bloc description: Create/Read/Update/Delete BLoC for Flutter repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_crud_bloc -version: 0.1.1+1 +version: 0.2.0 publish_to: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub 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/ @@ -23,10 +21,11 @@ dependencies: wyatt_type_utils: hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ version: ^0.0.5 + rxdart: ^0.27.7 dev_dependencies: flutter_test: { sdk: flutter } bloc_test: ^9.1.0 wyatt_analysis: hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub - version: ^2.5.0 + version: ^2.6.1 diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.gitignore b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.gitignore new file mode 120000 index 00000000..00e03899 --- /dev/null +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.gitignore @@ -0,0 +1 @@ +../../../.gitignore \ No newline at end of file diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.metadata b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.metadata new file mode 100644 index 00000000..6176c000 --- /dev/null +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "d211f42860350d914a5ad8102f9ec32764dc6d06" + channel: "stable" + +project_type: package diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.pubignore b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.pubignore new file mode 120000 index 00000000..353b763d --- /dev/null +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/.pubignore @@ -0,0 +1 @@ +../../../.pubignore \ No newline at end of file diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/AUTHORS b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/AUTHORS new file mode 120000 index 00000000..d776b73d --- /dev/null +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/AUTHORS @@ -0,0 +1 @@ +../../../AUTHORS \ No newline at end of file diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/CHANGELOG.md b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/CHANGELOG.md new file mode 100644 index 00000000..c6517991 --- /dev/null +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/CHANGELOG.md @@ -0,0 +1,11 @@ +## 0.2.0 + +> Note: This release has breaking changes. + + - **FIX**: rename wyatt_bruc_bloc_firestore main package file. + - **DOCS**(crud): update readme. + - **BREAKING** **FEAT**(crud): move crud firestore implementation into his own package. + +## 0.0.1 + +* TODO: Describe initial release. diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/LICENSE b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/LICENSE new file mode 120000 index 00000000..5853aaea --- /dev/null +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/LICENSE @@ -0,0 +1 @@ +../../../LICENSE \ No newline at end of file diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/README.md b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/README.md new file mode 100644 index 00000000..02fe8eca --- /dev/null +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/README.md @@ -0,0 +1,39 @@ + + +TODO: Put a short description of the package here that helps potential users +know whether this package might be useful for them. + +## Features + +TODO: List what your package can do. Maybe include images, gifs, or videos. + +## Getting started + +TODO: List prerequisites and provide or point to information on how to +start using the package. + +## Usage + +TODO: Include short and useful examples for package users. Add longer examples +to `/example` folder. + +```dart +const like = 'sample'; +``` + +## Additional information + +TODO: Tell users more about the package: where to find more information, how to +contribute to the package, how to file issues, what response they can expect +from the package authors, and more. diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/analysis_options.yaml b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/analysis_options.yaml new file mode 100644 index 00000000..8c9daa4e --- /dev/null +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/analysis_options.yaml @@ -0,0 +1 @@ +include: package:wyatt_analysis/analysis_options.flutter.yaml diff --git a/packages/wyatt_crud_bloc/lib/src/data/data_sources/remote/crud_firestore_data_source_impl.dart b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/lib/src/data/crud_data_source_firestore_impl.dart similarity index 70% rename from packages/wyatt_crud_bloc/lib/src/data/data_sources/remote/crud_firestore_data_source_impl.dart rename to packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/lib/src/data/crud_data_source_firestore_impl.dart index 7b4f793a..e8d5ef24 100644 --- a/packages/wyatt_crud_bloc/lib/src/data/data_sources/remote/crud_firestore_data_source_impl.dart +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/lib/src/data/crud_data_source_firestore_impl.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify @@ -15,49 +15,51 @@ // along with this program. If not, see . import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:wyatt_crud_bloc/src/core/enums/where_query_type.dart'; -import 'package:wyatt_crud_bloc/src/domain/data_sources/crud_data_source.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart'; -import 'package:wyatt_crud_bloc/src/domain/entities/query.dart'; +import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart' hide Query; +import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart' as crud show Query; -/// {@template crud_firestore_data_source_impl} +/// {@template crud_data_source_firestore_impl} /// A concrete implementation of [CrudDataSource] that uses /// [FirebaseFirestore] as the data source. /// {@endtemplate} -class CrudFirestoreDataSourceImpl - extends CrudDataSource { - /// {@macro crud_firestore_data_source_impl} - CrudFirestoreDataSourceImpl( +class CrudDataSourceFirestoreImpl extends CrudDataSource { + /// {@macro crud_data_source_firestore_impl} + CrudDataSourceFirestoreImpl( String collection, { - /// The function that converts a [DocumentSnapshot] to a [Model]. - required Model Function( + required super.id, + + /// The function that converts a [DocumentSnapshot] to a Model. + required Map Function( DocumentSnapshot>, SnapshotOptions?, ) fromFirestore, - /// The function that converts a [Model] to a [Map]. - required Map Function(Model, SetOptions?) toFirestore, + /// The function that converts a Model to a [Map]. + required Map Function(Map, SetOptions?) + toFirestore, FirebaseFirestore? firestore, - }) : _firestore = firestore ?? FirebaseFirestore.instance, - _toFirestore = toFirestore { + }) : _firestore = firestore ?? FirebaseFirestore.instance { _collectionReference = - _firestore.collection(collection).withConverter( + _firestore.collection(collection).withConverter>( fromFirestore: fromFirestore, toFirestore: toFirestore, ); } final FirebaseFirestore _firestore; - - final Map Function(Model, SetOptions?) _toFirestore; - late CollectionReference _collectionReference; + late CollectionReference> _collectionReference; @override - Future create(Model object, {String? id}) { + Future create(Map object, {String? id}) { if (id != null) { return _collectionReference.doc(id).set(object); } else { - if (object.id != null) { - return _collectionReference.doc(object.id).set(object); + final String? id = this.id( + OperationType.create, + object, + ); + + if (id != null) { + return _collectionReference.doc(id).set(object); } return _collectionReference.add(object); } @@ -77,32 +79,35 @@ class CrudFirestoreDataSourceImpl } @override - Future get(String id) async { - final DocumentSnapshot snapshot = + Future?> get(String id) async { + final DocumentSnapshot> snapshot = await _collectionReference.doc(id).get(); return snapshot.data(); } @override - Future> getAll() async { - final QuerySnapshot snapshots = await _collectionReference.get(); + Future?>> getAll() async { + final QuerySnapshot> snapshots = + await _collectionReference.get(); return snapshots.docs.map((snapshot) => snapshot.data()).toList(); } @override - Future> query(List conditions) async { - Query query = _collectionReference; + Future?>> search( + List conditions, + ) async { + Query> query = _collectionReference; for (final condition in conditions) { query = _queryParser(condition, query); } - final QuerySnapshot snapshots = await query.get(); + final QuerySnapshot> snapshots = await query.get(); return snapshots.docs.map((snapshot) => snapshot.data()).toList(); } @override - Stream> stream({ + Stream?>> stream({ String? id, - List? conditions, + List? conditions, bool includeMetadataChanges = false, }) { if (id != null) { @@ -111,12 +116,12 @@ class CrudFirestoreDataSourceImpl .snapshots( includeMetadataChanges: includeMetadataChanges, ) - .map>( + .map?>>( (snapshot) => [snapshot.data()], ); } else { if (conditions != null) { - Query query = _collectionReference; + Query> query = _collectionReference; for (final condition in conditions) { query = _queryParser(condition, query); } @@ -146,19 +151,12 @@ class CrudFirestoreDataSourceImpl @override Future update( String id, { - Model? object, - Map? raw, + Map? object, }) { if (object != null) { - return _collectionReference - .doc(id) - .update(_toFirestore.call(object, null)); + return _collectionReference.doc(id).update(object); } else { - if (raw != null) { - return _collectionReference.doc(id).update(raw); - } else { - throw Exception('You must provide an object or a raw map'); - } + throw Exception('You must provide data to update'); } } @@ -168,15 +166,16 @@ class CrudFirestoreDataSourceImpl throw Exception('You must provide data to update'); } final batch = _firestore.batch(); - final QuerySnapshot snapshots = await _collectionReference.get(); + final QuerySnapshot> snapshots = + await _collectionReference.get(); for (final DocumentSnapshot snapshot in snapshots.docs) { batch.update(snapshot.reference, data); } return batch.commit(); } - Query _queryParser(QueryInterface condition, Object query) { - query as Query; + Query> _queryParser(crud.Query condition, Object query) { + query as Query>; if (condition is WhereQuery) { switch (condition.type) { case WhereQueryType.isEqualTo: diff --git a/packages/wyatt_crud_bloc/lib/src/data/repositories/repositories.dart b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/lib/wyatt_crud_bloc_firestore.dart similarity index 78% rename from packages/wyatt_crud_bloc/lib/src/data/repositories/repositories.dart rename to packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/lib/wyatt_crud_bloc_firestore.dart index f31c2358..9467c9f7 100644 --- a/packages/wyatt_crud_bloc/lib/src/data/repositories/repositories.dart +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/lib/wyatt_crud_bloc_firestore.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify @@ -14,4 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -export 'crud_repository_impl.dart'; +/// Create/Read/Update/Delete BLoC implementation for Firestore +library wyatt_crud_bloc_firestore; + +export 'src/data/crud_data_source_firestore_impl.dart'; diff --git a/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/pubspec.yaml b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/pubspec.yaml new file mode 100644 index 00000000..aa1bac63 --- /dev/null +++ b/packages/wyatt_crud_bloc/wyatt_crud_bloc_firestore/pubspec.yaml @@ -0,0 +1,35 @@ +name: wyatt_crud_bloc_firestore +description: Create/Read/Update/Delete implementation for Cloud Firestore +repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_crud_bloc +version: 0.2.0 + +publish_to: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub + +environment: + sdk: ">=3.0.0 <4.0.0" + +dependencies: + flutter: { sdk: flutter } + + flutter_bloc: ^8.1.1 + equatable: ^2.0.5 + cloud_firestore: ^4.0.5 + + wyatt_architecture: + hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + version: ^0.2.0+1 + + wyatt_type_utils: + hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + version: ^0.0.5 + + wyatt_crud_bloc: + hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + version: ^0.2.0 + +dev_dependencies: + flutter_test: { sdk: flutter } + bloc_test: ^9.1.0 + wyatt_analysis: + hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub + version: ^2.6.1