Compare commits

..
Author SHA1 Message Date
hugo c2f588d96e feat(deferred): (wip) add generator package 2023-02-10 14:40:31 +01:00
hugo 4441ddeb33 feat(deferred): (wip) add annotations package 2023-02-10 14:40:14 +01:00
malo a563bd1fe3 style(ui_kit): add macos platform in example
continuous-integration/drone/push Build is failing
2023-02-10 14:19:32 +01:00
malo 5464cd1d40 feat(ui_kit): implement information card (#126)
continuous-integration/drone/push Build is failing
2023-02-10 14:08:04 +01:00
malo ba1c1016e5 style(ui_kit): remove default files 2023-02-10 11:35:51 +01:00
malo 23b608ed10 feat(ui_components): add gradient attribut to text wrapper
continuous-integration/drone/push Build is failing
2023-02-10 11:25:39 +01:00
hugo 44b2b7c27d chore(ui_kit): create package template
continuous-integration/drone/push Build is failing
2023-02-09 18:10:11 +01:00
hugo 6bad9a8a05 fix(ui_layout): fix textwrapper 2023-02-09 18:09:45 +01:00
hugo 5d8f94bee8 fix(cw_gen): fix textwrapper 2023-02-09 18:09:14 +01:00
hugo 75cb341447 fix(bloc_layout): fix textwrapper 2023-02-09 18:08:49 +01:00
hugo efa7ca09dd feat(ui_component): add string extension to easely wrap text 2023-02-09 18:08:03 +01:00
malo ac432f6dc8 feat(ui_components): export cards #126
continuous-integration/drone/push Build is failing
2023-02-09 16:50:48 +00:00
malo 6c85faba82 feat(ui_components): add portfolio & skill cards #126 2023-02-09 16:50:48 +00:00
malo dd75ecfc7a feat: make text wrapper constructor constant 2023-02-09 16:50:48 +00:00
malo 0132771e17 feat(ui_components): add text wrapper instead of String/Widget for Texts 2023-02-09 16:50:48 +00:00
malo 5d5ae145aa feat(ui_components): make fields nullable and not required in quote card 2023-02-09 16:50:48 +00:00
malo 07428a5215 fix(ui_components): remove darkmode enable field in cards 2023-02-09 16:50:48 +00:00
malo c994c822b0 feat(ui_components): export components and add license header 2023-02-09 16:50:48 +00:00
malo bde54e0cf5 feat(ui_components): add information_card & quote_card (#126) 2023-02-09 16:50:48 +00:00
malo f3c3939ba1 docs: update readme
continuous-integration/drone/push Build is failing
2023-02-07 14:26:53 +00:00
hugo 9339100399 chore(release): publish packages
continuous-integration/drone/push Build is failing
- wyatt_analysis@2.4.0
2023-02-07 14:46:21 +01:00
hugo 03725c25c7 feat(analysis): add new lint rules 2023-02-07 14:44:57 +01:00
hugo 588a09e0a1 docs(analysis): add instructions to create a new version (closes #104) 2023-02-07 14:43:52 +01:00
malo bd53d11e0d refactor(bloc_layout): migrate bloc layouts using copywith component method (close #121)
continuous-integration/drone/push Build is failing
2023-02-07 11:46:50 +01:00
malo ee8f08cc32 refactor(ui_layout): update exemple (close #116)
continuous-integration/drone/push Build is failing
2023-02-07 10:49:56 +01:00
malo 413589462b refactor(ui_layout): migrate layouts using copywith component method (#116) 2023-02-07 10:49:09 +01:00
malo ff3f2008de fix(ui_components): generate new files after generator fixes (close #118)
continuous-integration/drone/push Build is failing
2023-02-07 10:25:58 +01:00
malo 0b27a62669 fix(component_copy_with_gen): update example (#118) 2023-02-07 10:24:00 +01:00
malo 6c9b6e239b fix(component_copy_with_gen): copywith method takes non nullable fields too (#118) 2023-02-07 10:22:32 +01:00
malo 576a01512b refactor(ui_components): update example (close #115)
continuous-integration/drone/push Build is failing
2023-02-07 09:44:34 +01:00
malo cd3ed0fe69 refactor(ui_components): migrate components using code generator packages (#115) 2023-02-07 09:44:03 +01:00
AN12345 46c51525e8 feat: add generators for components proxy and mixins to enable copywith methods
continuous-integration/drone/push Build is failing
2023-02-06 18:42:34 +01:00
AN12345 b025247002 feat: add class annotation for component code generators 2023-02-06 18:41:54 +01:00
AN12345 c70d4c6650 build: update mason file to add new tempalte 2023-02-06 18:40:35 +01:00
AN12345 04a87fe32a feat(bloc_layout): make package compatible with crud cubit (close #111)
continuous-integration/drone/push Build is passing
2022-12-19 19:21:38 -05:00
AN12345 f8f367baf6 (feat): rething conception and add missing layouts (close #97)
continuous-integration/drone/push Build is passing
2022-12-13 18:50:47 -05:00
AN12345 e667aa06d0 feat(ui_layout): make field nullable & add new app bar fields (#97) 2022-12-13 18:49:28 -05:00
hugo f6ef5828bb chore(release): publish packages
continuous-integration/drone/push Build is passing
- wyatt_authentication_bloc@0.4.1
2022-12-13 17:29:38 -05:00
Malo Léon f22ba300cb Merge pull request 'authentication/feature/google_signin' (#105) from authentication/feature/google_signin into master
continuous-integration/drone/push Build is passing
Reviewed-on: #105
Reviewed-by: Malo Léon <malo.leon@wyattapp.io>
2022-12-13 22:07:16 +00:00
hugo 5f52b2fc3d refactor(authentication): use fromFirebaseUser factory to parse user 2022-12-13 17:00:26 -05:00
hugo f46707f5c1 style(authentication): Merge 'origin/master' into authentication/feature/google_signin 2022-12-13 16:42:50 -05:00
AN12345 17ff0f8ba1 clean(packages): apply dart fix (close #106)
continuous-integration/drone/push Build is passing
2022-12-13 13:52:49 -05:00
hugo 1a3631f691 feat(authentication): add google sign in in signIn cubit 2022-12-13 00:36:20 -05:00
hugo 197c5d54e6 feat(authentication): add google sign in parameter in firebase data source constructor 2022-12-12 23:47:29 -05:00
hugo c7b241de2d feat(authentication): add google sign_in support (closes #59) 2022-12-12 23:16:10 -05:00
hugo 94d573a584 refactor(authentication): update deps and re-export them 2022-12-12 23:14:55 -05:00
hugo 37e00fe9c4 style(analysis): dart format + follows wyatt analysis 2.3.0 2022-12-12 22:43:54 -05:00
398 changed files with 9367 additions and 1208 deletions
+50
View File
@@ -3,6 +3,56 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## 2023-02-07
### Changes
---
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- [`wyatt_analysis` - `v2.4.0`](#wyatt_analysis---v240)
---
#### `wyatt_analysis` - `v2.4.0`
- **FEAT**: add new lint rules.
- **DOCS**: add instructions to create a new version (closes #104).
## 2022-12-13
### Changes
---
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- [`wyatt_authentication_bloc` - `v0.4.1`](#wyatt_authentication_bloc---v041)
---
#### `wyatt_authentication_bloc` - `v0.4.1`
- **REFACTOR**: use fromFirebaseUser factory to parse user.
- **REFACTOR**: update deps and re-export them.
- **FIX**: fix mock on register.
- **FEAT**: add google sign in in signIn cubit.
- **FEAT**: add google sign in parameter in firebase data source constructor.
- **FEAT**: add google sign_in support (closes #59).
- **FEAT**: add reauthenticate, updateEmail and updatePassword.
- **DOCS**: add correct header.
## 2022-12-12 ## 2022-12-12
### Changes ### Changes
+44 -50
View File
@@ -17,11 +17,7 @@
--> -->
<p align="center"> <p align="center">
<a href="https://wyatt-studio.fr">
<a href="https://wyattapp.io">
<img width="150px" src="resources/wyatt-campus-logo.png">
</a>
<a href="https://wyatt-studio.fr">
<img width="150px" src="resources/wyatt-studio-logo.png"> <img width="150px" src="resources/wyatt-studio-logo.png">
</a> </a>
<h1 align="center">Wyatt Packages</h1> <h1 align="center">Wyatt Packages</h1>
@@ -44,10 +40,9 @@
## About ## About
Here is it a set of [Flutter plugins](https://flutter.io/platform-plugins/) that power up your applications. Here is a set of [Flutter plugins](https://flutter.io/platform-plugins/) that enhance your applications.
[Flutter](https://flutter.dev) is Google's UI toolkit for building beautiful, natively compiled applications for mobile, web, and desktop from a single codebase. Flutter is used by developers and organizations around the world, and is free [Flutter](https://flutter.dev) is Google's UI toolkit for building beautiful, natively compiled applications for mobile, web, and desktop using a single codebase. It is used by developers and organizations worldwide and is free and open-source.
and open source.
--- ---
@@ -61,21 +56,21 @@ git clone ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-packages.git
### Prerequisite ### Prerequisite
- [Flutter](https://github.com/flutter/flutter). 1. [Flutter](https://github.com/flutter/flutter). It is a UI toolkit developed by Google for building beautiful and natively compiled applications for mobile, web, and desktop from a single codebase.
- [Melos](https://github.com/invertase/melos). Used to manage Dart projects with multiple packages. 2. [Melos](https://github.com/invertase/melos). Melos is a tool that helps in managing Dart projects that have multiple packages. It can be installed using the following command:
```shell ```shell
dart pub global activate melos dart pub global activate melos
``` ```
- [Mason](https://github.com/felangel/mason). Used for code generation. 3. [Mason](https://github.com/felangel/mason). Mason is used for code generation purposes. It can be installed by running the following command:
```shell ```shell
dart pub global activate mason_cli dart pub global activate mason_cli
``` ```
- [Lcov](https://github.com/linux-test-project/lcov). Used to generate coverage data. 4. [Lcov](https://github.com/linux-test-project/lcov). Lcov is a tool used to generate coverage data. It can be installed on macOS by running the following command:
```shell ```shell
# on macos # on macos
@@ -84,38 +79,39 @@ brew install lcov
- genhtml. Used to convert coverage data into html pages. - genhtml. Used to convert coverage data into html pages.
After installing all these packages, bootstrap with `melos bs`. After installation of all these packages, the project can be bootstrapped using the command `melos bs`.
### Create a new package ### Create a new package
Create a new package in `packages/` folder. Create a new package in `packages/` folder.
To create a new package in the packages/ folder, run the following command in the terminal:
```shell ```shell
mason make wyatt_package --package_name wyatt_<name> --description A new Wyatt package --flutter_only false mason make wyatt_package --package_name wyatt_<name> --description A new Wyatt package --flutter_only false
``` ```
Then bootstrap project with `melos bs` command. The <name> variable in the above command is important and must be clear and understandable.
After creating the package, bootstrap the project with the `melos bs` command.
#### Naming #### Naming
In the previous instructions `<name>` variable is important. In the previous instructions `<name>` variable is important.
It have to be clear and intelligible. It have to be clear and intelligible.
You **MUST** use underscores. 1. You must use underscores in the name.
2. You must use the wyatt prefix for the package name.
3. You must name the example with a specific name.
You **MUST** use `wyatt` prefix for package. For example, if the name is "CRUD BLOC," the following naming conventions should be used:
You **MUST** name example with specific name. 1. name: crud_bloc
2. package name: wyatt_crud_bloc
For example, if name is CRUD BLOC 3. example name: crud_bloc_example
- name will be crud_bloc
- so the package will be: `wyatt_crud_bloc`
- and the example will be: `crud_bloc_example`
### Create issues ### Create issues
Add the issues directly related to what you want to develop and label them correctly. Create an issue for each specific feature or task you want to work on and label it correctly using the following format:
``` ```
Type(scope): issue. Type(scope): issue.
@@ -128,18 +124,18 @@ For example, on notification bloc package :
### Branches ### Branches
Master is protected. You can't push on it. Please develop your feature on another branch. The name of your branch has to match with the issue opened. The master branch is protected and cannot be pushed to directly. Please create a separate branch for each feature or task, with a name that corresponds to the related issue. The branch name should follow this format:
`type(scope):issue` `type(scope):issue`
Example : Example :
Issue : For the issue:
- `Feature(notification_bloc): add firebase messaging data source.` - `Feature(notification_bloc): add firebase messaging data source.`
Branch related to this issue : The related branch should be named:
- `feature(notification_bloc)/add_firebase_messaging_data_source` - `notification_bloc/feat/add_firebase_messaging_data_source`
### Commits ### Commits
@@ -163,12 +159,11 @@ Some examples :
- `docs: update readme.` = update **this** readme file. - `docs: update readme.` = update **this** readme file.
- `fix(crud)!: fix bug in awesome() function. (#32)` = fix a bug, `!` is important and indicate `BREAKING CHANGES` linked with the 32nd issue. - `fix(crud)!: fix bug in awesome() function. (#32)` = fix a bug, `!` is important and indicate `BREAKING CHANGES` linked with the 32nd issue.
When you have finished developing, and are ready to close the issue, close it via your commit : When you have completed your development work and are ready to resolve the related issue, you can close it via your commit message by including (close #issue_number). For example:
`feat(auth): add AWS support. (close #31)` ```shell
feat(auth): add AWS support. (close #31)
Note that your issue will be close after merging on master. ```
Before closing the issue, please check tests and update coverage. You might run :
```shell ```shell
melos run test:all # this will run all tests in this project melos run test:all # this will run all tests in this project
@@ -179,45 +174,44 @@ melos run publish:validate # this will run a validation before publish packages
melos run publish # this will publish packages melos run publish # this will publish packages
``` ```
> Note that only modified package will be verified and published. Please note that the issue will only be closed after it has been merged into the master branch. Before closing the issue, it is important to verify that all tests have been run and that coverage has been updated.
#### Merge your work #### Merge your work
After closing your issue, some work may have been done on master in the meantime. To keep a clean git history, please rebase before opening a change request. When you have completed your work and closed the related issue, it's possible that some changes may have been made to the master branch in the meantime. To maintain a clean Git history, it's recommended to rebase before creating a change request (pull request).
Two situations : Two situations :
- You have not yet created your branch and have committed locally : - You haven't created a branch yet and have made local commits:
```shell ```shell
git pull --rebase git pull --rebase
``` ```
- You are already working on your branch : - You are already working on a branch:
```shell ```shell
git rebase -i master git rebase -i master
``` ```
If possible, please use `--fixup` on your commit in interactive rebase. It's recommended to use the `--fixup` option during the interactive rebase to keep the Git history clean.
Then, opend your PR, get the necessary approval and merge your work. Then you're done ✅. Once you have rebased, you can create a pull request, receive the necessary approvals, and then merge your work. And with that, you're done! 🎉
#### Update version. #### Update version.
Once your work is on the master, you can update your package version. Please filter packages to update only your package. `--scope` is used to do it. When your work has been merged into the master branch, it's time to update the package version. To update only your specific package, use the --scope option. For example, after merging changes into the `wyatt_notification_bloc` package, you can run the following command:
For example, after merging changes on `wyatt_otification_bloc` package, you might run :
```shell ```shell
melos version --scope="*wyatt_notification_bloc*" melos version --scope="*wyatt_notification_bloc*"
``` ```
In fact, melos will filter all packages that match the `wyatt_notification_block` pattern. This will filter all packages that match the `wyatt_notification_bloc` pattern and update only that package.
You can update check all packages tests by running : You can then verify that all packages and their tests are working correctly by running:
```shell ```shell
melos run test melos run test:all
``` ```
#### Publish your package #### Publish your package
@@ -265,14 +259,14 @@ Here you can change `package name` and `package version`.
--- ---
## Status
![Status: Experimental](https://img.shields.io/badge/Status-WIP-red?style=flat-square)
This repository is maintained by Wyatt Studio but work is in progress.
## Simple work flow diagramm ## Simple work flow diagramm
To sum up, here a simple work flow diagramm. To sum up, here a simple work flow diagramm.
![Dev Wokflow](doc/workflow.svg) ![Dev Wokflow](doc/workflow.svg)
## Status
![Status: Experimental](https://img.shields.io/badge/Status-WIP-red?style=flat-square)
This repository is maintained by Wyatt Studio but work is in progress.
+1 -1
View File
@@ -1 +1 @@
{"bricks":{"wyatt_clean_code":{"git":{"url":"ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-bricks.git","path":"bricks/wyatt_clean_code","ref":"033baa65408ec6b68e6a2ef43e64c24708ef16a1"}},"wyatt_feature_brick":{"git":{"url":"ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-bricks.git","path":"bricks/wyatt_feature_brick","ref":"033baa65408ec6b68e6a2ef43e64c24708ef16a1"}},"wyatt_package":{"git":{"url":"ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-bricks.git","path":"bricks/wyatt_package","ref":"033baa65408ec6b68e6a2ef43e64c24708ef16a1"}}}} {"bricks":{"wyatt_clean_code":{"git":{"url":"ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-bricks.git","path":"bricks/wyatt_clean_code","ref":"5009f1ef21d8531b773298c0fc08704d8f69afd1"}},"wyatt_feature_brick":{"git":{"url":"ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-bricks.git","path":"bricks/wyatt_feature_brick","ref":"5009f1ef21d8531b773298c0fc08704d8f69afd1"}},"wyatt_package_template":{"git":{"url":"ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-bricks.git","path":"bricks/wyatt_package_template","ref":"5009f1ef21d8531b773298c0fc08704d8f69afd1"}}}}
+5 -5
View File
@@ -1,13 +1,13 @@
bricks: bricks:
wyatt_clean_code: wyatt_clean_code:
git: git:
url: ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-bricks.git url: "ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-bricks.git"
path: bricks/wyatt_clean_code path: bricks/wyatt_clean_code
wyatt_feature_brick: wyatt_feature_brick:
git: git:
url: ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-bricks.git url: "ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-bricks.git"
path: bricks/wyatt_feature_brick path: bricks/wyatt_feature_brick
wyatt_package: wyatt_package_template:
git: git:
url: ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-bricks.git url: "ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-bricks.git"
path: bricks/wyatt_package path: bricks/wyatt_package_template
+5
View File
@@ -1,3 +1,8 @@
## 2.4.0
- **FEAT**: add new lint rules.
- **DOCS**: add instructions to create a new version (closes #104).
## 2.3.0 ## 2.3.0
- **REFACTOR**: follow melos versioning. - **REFACTOR**: follow melos versioning.
+20 -10
View File
@@ -1,5 +1,5 @@
<!-- <!--
* Copyright (C) 2022 WYATT GROUP * Copyright (C) 2023 WYATT GROUP
* Please see the AUTHORS file for details. * Please see the AUTHORS file for details.
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@@ -7,7 +7,7 @@
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* any later version. * any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
@@ -20,21 +20,21 @@
![SDK: Dart & Flutter](https://img.shields.io/badge/SDK-Dart%20%7C%20Flutter-blue?style=flat-square) ![SDK: Dart & Flutter](https://img.shields.io/badge/SDK-Dart%20%7C%20Flutter-blue?style=flat-square)
This package provides lint rules for Dart and Flutter which are used at [Wyatt](https://wyattapp.io) and [Wyatt Studio](https://wyatt-studio.fr). For more information, see the complete list of options in **lib/analysis_options.2.3.0.yaml**. This package provides lint rules for Dart and Flutter which are used at [Wyatt](https://wyattapp.io) and [Wyatt Studio](https://wyatt-studio.fr). For more information, see the complete list of options in **lib/analysis_options.2.4.0.yaml**.
**Note**: This package was heavily inspired by [pedantic](https://github.com/dart-lang/pedantic), [Very Good Analysis](https://github.com/VeryGoodOpenSource/very_good_analysis) and the official [flutter_lints](https://pub.dev/packages/flutter_lints). **Note**: This package was heavily inspired by [pedantic](https://github.com/dart-lang/pedantic), [Very Good Analysis](https://github.com/VeryGoodOpenSource/very_good_analysis) and the official [flutter_lints](https://pub.dev/packages/flutter_lints).
## Usage ## Usage
To use the lints, add a dependency in your `pubspec.yaml`: To use the lints, add a dependency in your `pubspec.yaml` :
```yaml ```yaml
wyatt_analysis: wyatt_analysis:
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
version: 2.3.0 version: 2.4.0
``` ```
Then, add an include in `analysis_options.yaml`: Then, add an include in `analysis_options.yaml` :
```yaml ```yaml
include: package:wyatt_analysis/analysis_options.yaml include: package:wyatt_analysis/analysis_options.yaml
@@ -49,13 +49,13 @@ include: package:wyatt_analysis/analysis_options.flutter.yaml
If you wish to restrict the lint version, specify a version of `analysis_options.yaml` instead: If you wish to restrict the lint version, specify a version of `analysis_options.yaml` instead:
```yaml ```yaml
include: package:wyatt_analysis/analysis_options.flutter.2.3.0.yaml include: package:wyatt_analysis/analysis_options.flutter.2.4.0.yaml
``` ```
If you just want **Dart** version: If you just want **Dart** version:
```yaml ```yaml
include: package:wyatt_analysis/analysis_options.2.3.0.yaml include: package:wyatt_analysis/analysis_options.2.4.0.yaml
``` ```
## Suppressing Lints ## Suppressing Lints
@@ -87,7 +87,7 @@ class B {}
### Project Level ### Project Level
To surpress a specific lint rule for an entire project, modify `analysis_options.yaml`: To surpress a specific lint rule for an entire project, modify `analysis_options.yaml` :
```yaml ```yaml
include: package:wyatt_analysis/analysis_options.yaml include: package:wyatt_analysis/analysis_options.yaml
@@ -104,6 +104,16 @@ To indicate your project is using `wyatt_analysis` → [![style: wyatt analysis]
[![style: wyatt analysis](https://img.shields.io/badge/Style-Wyatt%20Analysis-blue)](https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_analysis) [![style: wyatt analysis](https://img.shields.io/badge/Style-Wyatt%20Analysis-blue)](https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_analysis)
``` ```
## Development
When you want to create a new version of the plugin. Before any modification, execute the following command to create new files:
```sh
./new_version.sh <previous_version> <new_version>
```
> Where `<previous_version>` is 2.4.0
## Notes ## Notes
You can explore every lint rules [here](https://dart-lang.github.io/linter/lints/). You can explore every lint rules [here](https://dart-lang.github.io/linter/lints/).
@@ -0,0 +1,217 @@
# Copyright (C) 2023 WYATT GROUP
# Please see the AUTHORS file for details.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
analyzer:
language:
strict-casts: true
strict-inference: true
strict-raw-types: true
errors:
todo: info
close_sinks: ignore
missing_required_param: error
missing_return: error
exclude:
- lib/l10n/**
- lib/generated/**
- lib/gen/**
- lib/generated_plugin_registrant.dart
- test/.test_coverage.dart
- '**/*.g.dart'
- '**/*.freezed.dart'
linter:
rules:
- always_declare_return_types
- always_put_control_body_on_new_line
- always_put_required_named_parameters_first
- always_require_non_null_named_parameters
- always_use_package_imports
- annotate_overrides
- avoid_bool_literals_in_conditional_expressions
- avoid_catching_errors
- avoid_double_and_int_checks
- avoid_dynamic_calls
- avoid_empty_else
- avoid_equals_and_hash_code_on_mutable_classes
- avoid_escaping_inner_quotes
- avoid_field_initializers_in_const_classes
- avoid_final_parameters
- avoid_function_literals_in_foreach_calls
- avoid_init_to_null
- avoid_js_rounded_ints
- avoid_multiple_declarations_per_line
- avoid_null_checks_in_equality_operators
- avoid_positional_boolean_parameters
- avoid_private_typedef_functions
- avoid_redundant_argument_values
- avoid_relative_lib_imports
- avoid_renaming_method_parameters
- avoid_return_types_on_setters
- avoid_returning_null
- avoid_returning_null_for_future
- avoid_returning_null_for_void
- avoid_returning_this
- avoid_setters_without_getters
- avoid_shadowing_type_parameters
- avoid_single_cascade_in_expression_statements
- avoid_slow_async_io
- avoid_type_to_string
- avoid_types_as_parameter_names
- avoid_types_on_closure_parameters
- avoid_unused_constructor_parameters
- avoid_void_async
- await_only_futures
- camel_case_extensions
- camel_case_types
- cancel_subscriptions
- cascade_invocations
- cast_nullable_to_non_nullable
- collection_methods_unrelated_type
- combinators_ordering
- comment_references
- conditional_uri_does_not_exist
- constant_identifier_names
- control_flow_in_finally
- curly_braces_in_flow_control_structures
- depend_on_referenced_packages
- deprecated_consistency
- directives_ordering
- empty_catches
- empty_constructor_bodies
- empty_statements
- eol_at_end_of_file
- exhaustive_cases
- file_names
- flutter_style_todos
- hash_and_equals
- implementation_imports
- implicit_call_tearoffs
- iterable_contains_unrelated_type
- join_return_with_assignment
- leading_newlines_in_multiline_strings
- library_names
- library_prefixes
- library_private_types_in_public_api
- lines_longer_than_80_chars
- list_remove_unrelated_type
- literal_only_boolean_expressions
- missing_whitespace_between_adjacent_strings
- no_adjacent_strings_in_list
- no_default_cases
- no_duplicate_case_values
- no_leading_underscores_for_library_prefixes
- no_leading_underscores_for_local_identifiers
- no_runtimeType_toString
- non_constant_identifier_names
- noop_primitive_operations
- null_check_on_nullable_type_parameter
- null_closures
- one_member_abstracts
- only_throw_errors
- overridden_fields
- package_api_docs
- package_names
- package_prefixed_library_names
- parameter_assignments
- prefer_adjacent_string_concatenation
- prefer_asserts_in_initializer_lists
- prefer_asserts_with_message
- prefer_collection_literals
- prefer_conditional_assignment
- prefer_const_constructors
- prefer_const_constructors_in_immutables
- prefer_const_declarations
- prefer_const_literals_to_create_immutables
- prefer_constructors_over_static_methods
- prefer_contains
- prefer_equal_for_default_values
- prefer_expression_function_bodies
- prefer_final_fields
- prefer_final_in_for_each
- prefer_final_locals
- prefer_for_elements_to_map_fromIterable
- prefer_function_declarations_over_variables
- prefer_generic_function_type_aliases
- prefer_if_elements_to_conditional_expressions
- prefer_if_null_operators
- prefer_initializing_formals
- prefer_inlined_adds
- prefer_int_literals
- prefer_interpolation_to_compose_strings
- prefer_is_empty
- prefer_is_not_empty
- prefer_is_not_operator
- prefer_iterable_whereType
- prefer_mixin
- prefer_null_aware_method_calls
- prefer_null_aware_operators
- prefer_single_quotes
- prefer_spread_collections
- prefer_typing_uninitialized_variables
- prefer_void_to_null
- provide_deprecation_message
- recursive_getters
- require_trailing_commas
- slash_for_doc_comments
- sort_constructors_first
- sort_unnamed_constructors_first
- test_types_in_equals
- throw_in_finally
- tighten_type_of_initializing_formals
- type_annotate_public_apis
- type_init_formals
- unawaited_futures
- unnecessary_await_in_return
- unnecessary_brace_in_string_interps
- unnecessary_const
- unnecessary_constructor_name
- unnecessary_getters_setters
- unnecessary_lambdas
- unnecessary_late
- unnecessary_new
- unnecessary_null_aware_assignments
- unnecessary_null_checks
- unnecessary_null_in_if_null_operators
- unnecessary_nullable_for_final_variable_declarations
- unnecessary_overrides
- unnecessary_parenthesis
- unnecessary_raw_strings
- unnecessary_statements
- unnecessary_string_escapes
- unnecessary_string_interpolations
- unnecessary_this
- unnecessary_to_list_in_spreads
- unrelated_type_equality_checks
- unsafe_html
- use_enums
- use_function_type_syntax_for_parameters
- use_if_null_to_convert_nulls_to_bools
- use_is_even_rather_than_modulo
- use_late_for_private_fields_and_variables
- use_named_constants
- use_raw_strings
- use_rethrow_when_possible
- use_setters_to_change_properties
- use_string_buffers
- use_string_in_part_of_directives
- use_super_parameters
- use_test_throws_matchers
- use_to_and_as_if_applicable
- valid_regexps
- void_checks
@@ -0,0 +1,32 @@
# Copyright (C) 2023 WYATT GROUP
# Please see the AUTHORS file for details.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
include: package:wyatt_analysis/analysis_options.2.4.0.yaml
linter:
rules:
- avoid_print
- avoid_unnecessary_containers
- avoid_web_libraries_in_flutter
- no_logic_in_create_state
- sized_box_for_whitespace
- sized_box_shrink_expand
- sort_child_properties_last
- use_build_context_synchronously
- use_colored_box
- use_decorated_box
- use_full_hex_values_for_flutter_colors
- use_key_in_widget_constructors
@@ -1,5 +1,4 @@
# Copyright (C) 2023 WYATT GROUP
# Copyright (C) 2022 WYATT GROUP
# Please see the AUTHORS file for details. # Please see the AUTHORS file for details.
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
@@ -15,5 +14,5 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
include: package:wyatt_analysis/analysis_options.flutter.2.3.0.yaml include: package:wyatt_analysis/analysis_options.flutter.2.4.0.yaml
@@ -1,5 +1,4 @@
# Copyright (C) 2023 WYATT GROUP
# Copyright (C) 2022 WYATT GROUP
# Please see the AUTHORS file for details. # Please see the AUTHORS file for details.
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
@@ -15,5 +14,5 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
include: package:wyatt_analysis/analysis_options.2.3.0.yaml include: package:wyatt_analysis/analysis_options.2.4.0.yaml
@@ -1,4 +1,4 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
@@ -18,4 +18,4 @@
/// used internally at [Wyatt Studio](https://wyatt-studio.fr). /// used internally at [Wyatt Studio](https://wyatt-studio.fr).
library wyatt_analysis; library wyatt_analysis;
const String wyattAnalysisVersion = '2.3.0'; const String wyattAnalysisVersion = '2.4.0';
+17 -1
View File
@@ -1,7 +1,23 @@
# Copyright (C) 2023 WYATT GROUP
# Please see the AUTHORS file for details.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
name: wyatt_analysis name: wyatt_analysis
description: Lint rules for Dart and Flutter used internally at Wyatt Studio. description: Lint rules for Dart and Flutter used internally at Wyatt Studio.
repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_analysis repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_analysis
version: 2.3.0 version: 2.4.0
publish_to: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub publish_to: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub
@@ -24,9 +24,8 @@ import 'package:wyatt_http_client/wyatt_http_client.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart'; import 'package:wyatt_type_utils/wyatt_type_utils.dart';
class AlbumApiDataSourceImpl extends AlbumRemoteDataSource { class AlbumApiDataSourceImpl extends AlbumRemoteDataSource {
final MiddlewareClient _client;
AlbumApiDataSourceImpl(this._client); AlbumApiDataSourceImpl(this._client);
final MiddlewareClient _client;
@override @override
Future<Album> getAlbum(int id) async { Future<Album> getAlbum(int id) async {
@@ -24,9 +24,8 @@ import 'package:wyatt_http_client/wyatt_http_client.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart'; import 'package:wyatt_type_utils/wyatt_type_utils.dart';
class PhotoApiDataSourceImpl extends PhotoRemoteDataSource { class PhotoApiDataSourceImpl extends PhotoRemoteDataSource {
final MiddlewareClient _client;
PhotoApiDataSourceImpl(this._client); PhotoApiDataSourceImpl(this._client);
final MiddlewareClient _client;
@override @override
Future<Photo> getPhoto(int id) async { Future<Photo> getPhoto(int id) async {
@@ -24,15 +24,15 @@ import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart'; import 'package:wyatt_type_utils/wyatt_type_utils.dart';
class PhotoRepositoryImpl extends PhotoRepository { class PhotoRepositoryImpl extends PhotoRepository {
final PhotoRemoteDataSource _photoRemoteDataSource;
final AlbumRemoteDataSource _albumRemoteDataSource;
final FavoriteLocalDataSource _favoriteLocalDataSource;
PhotoRepositoryImpl( PhotoRepositoryImpl(
this._photoRemoteDataSource, this._photoRemoteDataSource,
this._albumRemoteDataSource, this._albumRemoteDataSource,
this._favoriteLocalDataSource, this._favoriteLocalDataSource,
); );
final PhotoRemoteDataSource _photoRemoteDataSource;
final AlbumRemoteDataSource _albumRemoteDataSource;
final FavoriteLocalDataSource _favoriteLocalDataSource;
@override @override
FutureOrResult<void> addPhotoToFavorites(Photo photo) => Result.tryCatchAsync( FutureOrResult<void> addPhotoToFavorites(Photo photo) => Result.tryCatchAsync(
@@ -21,9 +21,9 @@ import 'package:architecture_example/domain/repositories/photo_repository.dart';
import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_architecture/wyatt_architecture.dart';
class AddPhotoToFavorites extends AsyncUseCase<Photo, List<Photo>> { class AddPhotoToFavorites extends AsyncUseCase<Photo, List<Photo>> {
final PhotoRepository _photoRepository;
AddPhotoToFavorites(this._photoRepository); AddPhotoToFavorites(this._photoRepository);
final PhotoRepository _photoRepository;
@override @override
FutureOrResult<List<Photo>> execute(Photo? params) async { FutureOrResult<List<Photo>> execute(Photo? params) async {
@@ -20,9 +20,9 @@ import 'package:architecture_example/domain/repositories/photo_repository.dart';
import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_architecture/wyatt_architecture.dart';
class CheckIfPhotoIsInFavorites extends AsyncUseCase<int, bool> { class CheckIfPhotoIsInFavorites extends AsyncUseCase<int, bool> {
final PhotoRepository _photoRepository;
CheckIfPhotoIsInFavorites(this._photoRepository); CheckIfPhotoIsInFavorites(this._photoRepository);
final PhotoRepository _photoRepository;
@override @override
FutureOrResult<bool> execute(int? params) async => FutureOrResult<bool> execute(int? params) async =>
@@ -19,9 +19,9 @@ import 'package:architecture_example/domain/repositories/photo_repository.dart';
import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_architecture/wyatt_architecture.dart';
class DisplayFavorites extends AsyncUseCase<NoParam, List<Photo>> { class DisplayFavorites extends AsyncUseCase<NoParam, List<Photo>> {
final PhotoRepository _photoRepository;
DisplayFavorites(this._photoRepository); DisplayFavorites(this._photoRepository);
final PhotoRepository _photoRepository;
@override @override
FutureOrResult<List<Photo>> execute(void params) { FutureOrResult<List<Photo>> execute(void params) {
@@ -21,9 +21,9 @@ import 'package:architecture_example/domain/repositories/photo_repository.dart';
import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_architecture/wyatt_architecture.dart';
class DisplayPhoto extends AsyncUseCase<int, Photo> { class DisplayPhoto extends AsyncUseCase<int, Photo> {
final PhotoRepository _photoRepository;
DisplayPhoto(this._photoRepository); DisplayPhoto(this._photoRepository);
final PhotoRepository _photoRepository;
@override @override
FutureOrResult<Photo> execute(int? params) { FutureOrResult<Photo> execute(int? params) {
@@ -22,9 +22,9 @@ import 'package:architecture_example/domain/usecases/photos/params/query_paramet
import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_architecture/wyatt_architecture.dart';
class OpenAlbum extends AsyncUseCase<QueryParameters, List<Photo>> { class OpenAlbum extends AsyncUseCase<QueryParameters, List<Photo>> {
final PhotoRepository _photoRepository;
OpenAlbum(this._photoRepository); OpenAlbum(this._photoRepository);
final PhotoRepository _photoRepository;
@override @override
FutureOrResult<List<Photo>> execute(QueryParameters? params) { FutureOrResult<List<Photo>> execute(QueryParameters? params) {
@@ -15,9 +15,9 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
class QueryParameters { class QueryParameters {
QueryParameters(this.start, this.limit, {this.albumId = -1});
final int albumId; final int albumId;
final int? start; final int? start;
final int? limit; final int? limit;
QueryParameters(this.start, this.limit, {this.albumId = -1});
} }
@@ -21,9 +21,9 @@ import 'package:architecture_example/domain/repositories/photo_repository.dart';
import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_architecture/wyatt_architecture.dart';
class RemovePhotoFromFavorites extends AsyncUseCase<int, List<Photo>> { class RemovePhotoFromFavorites extends AsyncUseCase<int, List<Photo>> {
final PhotoRepository _photoRepository;
RemovePhotoFromFavorites(this._photoRepository); RemovePhotoFromFavorites(this._photoRepository);
final PhotoRepository _photoRepository;
@override @override
FutureOrResult<List<Photo>> execute(int? params) async { FutureOrResult<List<Photo>> execute(int? params) async {
@@ -22,9 +22,9 @@ import 'package:architecture_example/domain/usecases/photos/params/query_paramet
import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_architecture/wyatt_architecture.dart';
class RetrieveAllAlbums extends AsyncUseCase<QueryParameters, List<Album>> { class RetrieveAllAlbums extends AsyncUseCase<QueryParameters, List<Album>> {
final PhotoRepository _photoRepository;
RetrieveAllAlbums(this._photoRepository); RetrieveAllAlbums(this._photoRepository);
final PhotoRepository _photoRepository;
@override @override
FutureOrResult<List<Album>> execute(QueryParameters? params) { FutureOrResult<List<Album>> execute(QueryParameters? params) {
@@ -33,7 +33,6 @@ EventTransformer<E> throttleDroppable<E>(Duration duration) =>
(events, mapper) => droppable<E>().call(events.throttle(duration), mapper); (events, mapper) => droppable<E>().call(events.throttle(duration), mapper);
class AlbumBloc extends Bloc<AlbumEvent, AlbumState> { class AlbumBloc extends Bloc<AlbumEvent, AlbumState> {
final RetrieveAllAlbums _retrieveAllAlbums;
AlbumBloc(this._retrieveAllAlbums) : super(const AlbumState()) { AlbumBloc(this._retrieveAllAlbums) : super(const AlbumState()) {
on<AlbumFetched>( on<AlbumFetched>(
@@ -41,6 +40,7 @@ class AlbumBloc extends Bloc<AlbumEvent, AlbumState> {
transformer: throttleDroppable(throttleDuration), transformer: throttleDroppable(throttleDuration),
); );
} }
final RetrieveAllAlbums _retrieveAllAlbums;
Future<void> _onAlbumFetched( Future<void> _onAlbumFetched(
AlbumFetched event, AlbumFetched event,
@@ -26,19 +26,19 @@ abstract class PhotoDetailsState extends Equatable {
class PhotoDetailsInitial extends PhotoDetailsState {} class PhotoDetailsInitial extends PhotoDetailsState {}
class PhotoDetailsSuccess extends PhotoDetailsState { class PhotoDetailsSuccess extends PhotoDetailsState {
final Photo photo;
final bool isFavorite;
const PhotoDetailsSuccess(this.photo, {required this.isFavorite}); const PhotoDetailsSuccess(this.photo, {required this.isFavorite});
final Photo photo;
final bool isFavorite;
@override @override
List<Object> get props => [photo, isFavorite]; List<Object> get props => [photo, isFavorite];
} }
class PhotoDetailsFailure extends PhotoDetailsState { class PhotoDetailsFailure extends PhotoDetailsState {
final String error;
const PhotoDetailsFailure(this.error); const PhotoDetailsFailure(this.error);
final String error;
@override @override
List<Object> get props => [error]; List<Object> get props => [error];
@@ -23,10 +23,10 @@ import 'package:flutter_bloc/flutter_bloc.dart';
part 'favorite_checker_state.dart'; part 'favorite_checker_state.dart';
class FavoriteCheckerCubit extends Cubit<FavoriteCheckerState> { class FavoriteCheckerCubit extends Cubit<FavoriteCheckerState> {
final CheckIfPhotoIsInFavorites _checkIfPhotoIsInFavorites;
FavoriteCheckerCubit(this._checkIfPhotoIsInFavorites) FavoriteCheckerCubit(this._checkIfPhotoIsInFavorites)
: super(FavoriteCheckerInitial()); : super(FavoriteCheckerInitial());
final CheckIfPhotoIsInFavorites _checkIfPhotoIsInFavorites;
FutureOr<void> checkIfPhotoIsInFavorites(int photoId) async { FutureOr<void> checkIfPhotoIsInFavorites(int photoId) async {
final response = await _checkIfPhotoIsInFavorites.call(photoId); final response = await _checkIfPhotoIsInFavorites.call(photoId);
@@ -10,19 +10,19 @@ abstract class FavoriteCheckerState extends Equatable {
class FavoriteCheckerInitial extends FavoriteCheckerState {} class FavoriteCheckerInitial extends FavoriteCheckerState {}
class FavoriteCheckerSuccess extends FavoriteCheckerState { class FavoriteCheckerSuccess extends FavoriteCheckerState {
final int photoId;
final bool isFavorite;
const FavoriteCheckerSuccess(this.photoId, {required this.isFavorite}); const FavoriteCheckerSuccess(this.photoId, {required this.isFavorite});
final int photoId;
final bool isFavorite;
@override @override
List<Object> get props => [photoId, isFavorite]; List<Object> get props => [photoId, isFavorite];
} }
class FavoriteCheckerFailure extends FavoriteCheckerState { class FavoriteCheckerFailure extends FavoriteCheckerState {
final String error;
const FavoriteCheckerFailure(this.error); const FavoriteCheckerFailure(this.error);
final String error;
@override @override
List<Object> get props => [error]; List<Object> get props => [error];
@@ -33,7 +33,6 @@ EventTransformer<E> throttleDroppable<E>(Duration duration) =>
(events, mapper) => droppable<E>().call(events.throttle(duration), mapper); (events, mapper) => droppable<E>().call(events.throttle(duration), mapper);
class PhotoBloc extends Bloc<PhotoEvent, PhotoState> { class PhotoBloc extends Bloc<PhotoEvent, PhotoState> {
final OpenAlbum _openAlbum;
PhotoBloc(this._openAlbum) : super(const PhotoState()) { PhotoBloc(this._openAlbum) : super(const PhotoState()) {
on<PhotoFetched>( on<PhotoFetched>(
@@ -41,6 +40,7 @@ class PhotoBloc extends Bloc<PhotoEvent, PhotoState> {
transformer: throttleDroppable(throttleDuration), transformer: throttleDroppable(throttleDuration),
); );
} }
final OpenAlbum _openAlbum;
Future<void> _onPhotoFetched( Future<void> _onPhotoFetched(
PhotoFetched event, PhotoFetched event,
@@ -24,7 +24,7 @@ abstract class PhotoEvent extends Equatable {
} }
class PhotoFetched extends PhotoEvent { class PhotoFetched extends PhotoEvent {
final int albumId;
const PhotoFetched(this.albumId); const PhotoFetched(this.albumId);
final int albumId;
} }
@@ -67,7 +67,7 @@ dev_dependencies:
wyatt_analysis: wyatt_analysis:
git: git:
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
ref: wyatt_analysis-v2.3.0 ref: wyatt_analysis-v2.4.0
path: packages/wyatt_analysis path: packages/wyatt_analysis
# For information on the generic Dart part of this file, see the # For information on the generic Dart part of this file, see the
@@ -17,9 +17,9 @@
import 'package:wyatt_type_utils/wyatt_type_utils.dart'; import 'package:wyatt_type_utils/wyatt_type_utils.dart';
abstract class AppException implements Exception { abstract class AppException implements Exception {
final String? message;
AppException([this.message]); AppException([this.message]);
final String? message;
@override @override
String toString() { String toString() {
+1 -1
View File
@@ -24,4 +24,4 @@ dev_dependencies:
wyatt_analysis: wyatt_analysis:
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub
version: ^2.3.0 version: ^2.4.0
@@ -1,3 +1,14 @@
## 0.4.1
- **REFACTOR**: use fromFirebaseUser factory to parse user.
- **REFACTOR**: update deps and re-export them.
- **FIX**: fix mock on register.
- **FEAT**: add google sign in in signIn cubit.
- **FEAT**: add google sign in parameter in firebase data source constructor.
- **FEAT**: add google sign_in support (closes #59).
- **FEAT**: add reauthenticate, updateEmail and updatePassword.
- **DOCS**: add correct header.
## 0.4.0+3 ## 0.4.0+3
- Update a dependency to the latest release. - Update a dependency to the latest release.
@@ -1,4 +1 @@
include: package:wyatt_analysis/analysis_options.flutter.yaml include: package:wyatt_analysis/analysis_options.flutter.yaml
analyzer:
exclude: "!example/**"
@@ -44,6 +44,4 @@ app.*.map.json
# Android Studio will place build artifacts here # Android Studio will place build artifacts here
/android/app/debug /android/app/debug
/android/app/profile /android/app/profile
/android/app/release /android/app/release
firebase_options.dart
@@ -4,7 +4,7 @@
* ----- * -----
* File: launch.json * File: launch.json
* Created Date: 19/08/2022 15:12:25 * Created Date: 19/08/2022 15:12:25
* Last Modified: 19/08/2022 15:22:02 * Last Modified: Tue Dec 13 2022
* ----- * -----
* Copyright (c) 2022 * Copyright (c) 2022
*/ */
@@ -15,11 +15,18 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "example_router", "name": "Mock",
"request": "launch", "request": "launch",
"type": "dart", "type": "dart",
"program": "lib/main.dart", "program": "lib/main.dart",
"flutterMode": "debug" "flutterMode": "debug"
},
{
"name": "Firebase",
"request": "launch",
"type": "dart",
"program": "lib/main_firebase.dart",
"flutterMode": "debug"
} }
] ]
} }
@@ -5,41 +5,30 @@ PODS:
- AppAuth/Core (1.6.0) - AppAuth/Core (1.6.0)
- AppAuth/ExternalUserAgent (1.6.0): - AppAuth/ExternalUserAgent (1.6.0):
- AppAuth/Core - AppAuth/Core
- FBAEMKit (14.1.0): - Firebase/Auth (10.3.0):
- FBSDKCoreKit_Basics (= 14.1.0)
- FBSDKCoreKit (14.1.0):
- FBAEMKit (= 14.1.0)
- FBSDKCoreKit_Basics (= 14.1.0)
- FBSDKCoreKit_Basics (14.1.0)
- FBSDKLoginKit (14.1.0):
- FBSDKCoreKit (= 14.1.0)
- Firebase/Auth (10.0.0):
- Firebase/CoreOnly - Firebase/CoreOnly
- FirebaseAuth (~> 10.0.0) - FirebaseAuth (~> 10.3.0)
- Firebase/CoreOnly (10.0.0): - Firebase/CoreOnly (10.3.0):
- FirebaseCore (= 10.0.0) - FirebaseCore (= 10.3.0)
- firebase_auth (4.1.1): - firebase_auth (4.2.0):
- Firebase/Auth (= 10.0.0) - Firebase/Auth (= 10.3.0)
- firebase_core - firebase_core
- Flutter - Flutter
- firebase_core (2.1.1): - firebase_core (2.4.0):
- Firebase/CoreOnly (= 10.0.0) - Firebase/CoreOnly (= 10.3.0)
- Flutter - Flutter
- FirebaseAuth (10.0.0): - FirebaseAuth (10.3.0):
- FirebaseCore (~> 10.0) - FirebaseCore (~> 10.0)
- GoogleUtilities/AppDelegateSwizzler (~> 7.8) - GoogleUtilities/AppDelegateSwizzler (~> 7.8)
- GoogleUtilities/Environment (~> 7.8) - GoogleUtilities/Environment (~> 7.8)
- GTMSessionFetcher/Core (~> 2.1) - GTMSessionFetcher/Core (< 4.0, >= 2.1)
- FirebaseCore (10.0.0): - FirebaseCore (10.3.0):
- FirebaseCoreInternal (~> 10.0) - FirebaseCoreInternal (~> 10.0)
- GoogleUtilities/Environment (~> 7.8) - GoogleUtilities/Environment (~> 7.8)
- GoogleUtilities/Logger (~> 7.8) - GoogleUtilities/Logger (~> 7.8)
- FirebaseCoreInternal (10.1.0): - FirebaseCoreInternal (10.3.0):
- "GoogleUtilities/NSData+zlib (~> 7.8)" - "GoogleUtilities/NSData+zlib (~> 7.8)"
- Flutter (1.0.0) - Flutter (1.0.0)
- flutter_facebook_auth (4.4.1):
- FBSDKLoginKit (= 14.1.0)
- Flutter
- google_sign_in_ios (0.0.1): - google_sign_in_ios (0.0.1):
- Flutter - Flutter
- GoogleSignIn (~> 6.2) - GoogleSignIn (~> 6.2)
@@ -47,47 +36,36 @@ PODS:
- AppAuth (~> 1.5) - AppAuth (~> 1.5)
- GTMAppAuth (~> 1.3) - GTMAppAuth (~> 1.3)
- GTMSessionFetcher/Core (< 3.0, >= 1.1) - GTMSessionFetcher/Core (< 3.0, >= 1.1)
- GoogleUtilities/AppDelegateSwizzler (7.8.0): - GoogleUtilities/AppDelegateSwizzler (7.10.0):
- GoogleUtilities/Environment - GoogleUtilities/Environment
- GoogleUtilities/Logger - GoogleUtilities/Logger
- GoogleUtilities/Network - GoogleUtilities/Network
- GoogleUtilities/Environment (7.8.0): - GoogleUtilities/Environment (7.10.0):
- PromisesObjC (< 3.0, >= 1.2) - PromisesObjC (< 3.0, >= 1.2)
- GoogleUtilities/Logger (7.8.0): - GoogleUtilities/Logger (7.10.0):
- GoogleUtilities/Environment - GoogleUtilities/Environment
- GoogleUtilities/Network (7.8.0): - GoogleUtilities/Network (7.10.0):
- GoogleUtilities/Logger - GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib" - "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Reachability - GoogleUtilities/Reachability
- "GoogleUtilities/NSData+zlib (7.8.0)" - "GoogleUtilities/NSData+zlib (7.10.0)"
- GoogleUtilities/Reachability (7.8.0): - GoogleUtilities/Reachability (7.10.0):
- GoogleUtilities/Logger - GoogleUtilities/Logger
- GTMAppAuth (1.3.1): - GTMAppAuth (1.3.1):
- AppAuth/Core (~> 1.6) - AppAuth/Core (~> 1.6)
- GTMSessionFetcher/Core (< 3.0, >= 1.5) - GTMSessionFetcher/Core (< 3.0, >= 1.5)
- GTMSessionFetcher/Core (2.1.0) - GTMSessionFetcher/Core (2.3.0)
- PromisesObjC (2.1.1) - PromisesObjC (2.1.1)
- sign_in_with_apple (0.0.1):
- Flutter
- twitter_login (0.0.1):
- Flutter
DEPENDENCIES: DEPENDENCIES:
- firebase_auth (from `.symlinks/plugins/firebase_auth/ios`) - firebase_auth (from `.symlinks/plugins/firebase_auth/ios`)
- firebase_core (from `.symlinks/plugins/firebase_core/ios`) - firebase_core (from `.symlinks/plugins/firebase_core/ios`)
- Flutter (from `Flutter`) - Flutter (from `Flutter`)
- flutter_facebook_auth (from `.symlinks/plugins/flutter_facebook_auth/ios`)
- google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/ios`) - google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/ios`)
- sign_in_with_apple (from `.symlinks/plugins/sign_in_with_apple/ios`)
- twitter_login (from `.symlinks/plugins/twitter_login/ios`)
SPEC REPOS: SPEC REPOS:
trunk: trunk:
- AppAuth - AppAuth
- FBAEMKit
- FBSDKCoreKit
- FBSDKCoreKit_Basics
- FBSDKLoginKit
- Firebase - Firebase
- FirebaseAuth - FirebaseAuth
- FirebaseCore - FirebaseCore
@@ -105,37 +83,24 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/firebase_core/ios" :path: ".symlinks/plugins/firebase_core/ios"
Flutter: Flutter:
:path: Flutter :path: Flutter
flutter_facebook_auth:
:path: ".symlinks/plugins/flutter_facebook_auth/ios"
google_sign_in_ios: google_sign_in_ios:
:path: ".symlinks/plugins/google_sign_in_ios/ios" :path: ".symlinks/plugins/google_sign_in_ios/ios"
sign_in_with_apple:
:path: ".symlinks/plugins/sign_in_with_apple/ios"
twitter_login:
:path: ".symlinks/plugins/twitter_login/ios"
SPEC CHECKSUMS: SPEC CHECKSUMS:
AppAuth: 8fca6b5563a5baef2c04bee27538025e4ceb2add AppAuth: 8fca6b5563a5baef2c04bee27538025e4ceb2add
FBAEMKit: a899515e45476027f73aef377b5cffadcd56ca3a Firebase: f92fc551ead69c94168d36c2b26188263860acd9
FBSDKCoreKit: 24f8bc8d3b5b2a8c5c656a1329492a12e8efa792 firebase_auth: 579a0dc15451491cc83fccaa5102296635f24938
FBSDKCoreKit_Basics: 6e578c9bdc7aa1365dbbbde633c9ebb536bcaa98 firebase_core: 6f2f753e316765799d88568232ed59e300ff53db
FBSDKLoginKit: 787de205d524c3a4b17d527916f1d066e4361660 FirebaseAuth: 0e415d29d846c1dce2fb641e46f35e9888d9bec6
Firebase: 1b810f3d0c0532e27a48f1961f8c0400a668a2cf FirebaseCore: 988754646ab3bd4bdcb740f1bfe26b9f6c0d5f2a
firebase_auth: dd33e93fce72a1c72040f7380dacf06e89db5705 FirebaseCoreInternal: 29b76f784d607df8b2a1259d73c3f04f1210137b
firebase_core: 5c0bb0ca7d0e70480a68a6e9ad9bf55d1edd5305
FirebaseAuth: 493382cf533cc45e2862b00e9aa4cfe4c98daf71
FirebaseCore: 97f48a3a567a72b8d4daa0f03c3aadb78df4e995
FirebaseCoreInternal: 96d75228e10fd369564da51bd898414eb0f54df5
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_facebook_auth: 361ac7a57263ebf327f26089507ead0d66558ee8
google_sign_in_ios: 4f85eb9f937450765c8573bb85fd8cd6a5af675c google_sign_in_ios: 4f85eb9f937450765c8573bb85fd8cd6a5af675c
GoogleSignIn: 5651ce3a61e56ca864160e79b484cd9ed3f49b7a GoogleSignIn: 5651ce3a61e56ca864160e79b484cd9ed3f49b7a
GoogleUtilities: 1d20a6ad97ef46f67bbdec158ce00563a671ebb7 GoogleUtilities: bad72cb363809015b1f7f19beb1f1cd23c589f95
GTMAppAuth: 0ff230db599948a9ad7470ca667337803b3fc4dd GTMAppAuth: 0ff230db599948a9ad7470ca667337803b3fc4dd
GTMSessionFetcher: ffbb25ec00ebcb5201adab0a56d808f6f1902d9f GTMSessionFetcher: 3a63d75eecd6aa32c2fc79f578064e1214dfdec2
PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb
sign_in_with_apple: f3bf75217ea4c2c8b91823f225d70230119b8440
twitter_login: 2794db69b7640681171b17b3c2c84ad9dfb4a57f
PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3
@@ -28,6 +28,17 @@
<string>LaunchScreen</string> <string>LaunchScreen</string>
<key>UIMainStoryboardFile</key> <key>UIMainStoryboardFile</key>
<string>Main</string> <string>Main</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>com.googleusercontent.apps.405351917235-2jv4ff02kovoim58f8d6d0rsa14apgkj</string>
</array>
</dict>
</array>
<key>UISupportedInterfaceOrientations</key> <key>UISupportedInterfaceOrientations</key>
<array> <array>
<string>UIInterfaceOrientationPortrait</string> <string>UIInterfaceOrientationPortrait</string>
@@ -1,7 +1,7 @@
{ {
"file_generated_by": "FlutterFire CLI", "file_generated_by": "FlutterFire CLI",
"purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory",
"GOOGLE_APP_ID": "1:136771801992:ios:bcdca68d2b7d227097203d", "GOOGLE_APP_ID": "1:405351917235:ios:869f0ad8ace08db899f2c6",
"FIREBASE_PROJECT_ID": "tchat-beta", "FIREBASE_PROJECT_ID": "meerabel-dev",
"GCM_SENDER_ID": "136771801992" "GCM_SENDER_ID": "405351917235"
} }
@@ -1,16 +1,16 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -18,9 +18,47 @@ import 'dart:async';
import 'package:example_router/core/dependency_injection/get_it.dart'; import 'package:example_router/core/dependency_injection/get_it.dart';
import 'package:example_router/core/utils/app_bloc_observer.dart'; import 'package:example_router/core/utils/app_bloc_observer.dart';
import 'package:example_router/firebase_options.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
class MockSettings {
static MockSettings? _instance;
/// Data source mode
late bool enable = false;
MockSettings._(this.enable);
factory MockSettings.enable() {
_instance ??= MockSettings._(true);
if (_instance!.enable != true) {
throw Exception('Mock already initialized in: ${_instance!.enable}');
}
return _instance!;
}
factory MockSettings.disable() {
_instance ??= MockSettings._(false);
if (_instance!.enable != false) {
throw Exception('Mock already initialized in: ${_instance!.enable}');
}
return _instance!;
}
static bool isEnable() {
if (_instance == null) {
throw Exception('MockSettings not initialized!');
}
return _instance!.enable == true;
}
static bool isDisable() {
return !isEnable();
}
}
Future<void> bootstrap(FutureOr<Widget> Function() builder) async { Future<void> bootstrap(FutureOr<Widget> Function() builder) async {
await runZonedGuarded( await runZonedGuarded(
() async { () async {
@@ -30,6 +68,12 @@ Future<void> bootstrap(FutureOr<Widget> Function() builder) async {
FlutterError.onError = (details) { FlutterError.onError = (details) {
debugPrint(details.toString()); debugPrint(details.toString());
}; };
if (MockSettings.isDisable()) {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
}
await GetItInitializer.init(); await GetItInitializer.init();
runApp(await builder()); runApp(await builder());
@@ -1,16 +1,16 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -1,16 +1,16 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:example_router/bootstrap.dart';
import 'package:example_router/firebase_options.dart';
import 'package:get_it/get_it.dart'; import 'package:get_it/get_it.dart';
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart'; import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart'; import 'package:wyatt_type_utils/wyatt_type_utils.dart';
@@ -24,28 +26,32 @@ abstract class GetItInitializer {
static Future<void> init() async { static Future<void> init() async {
getIt getIt
..registerLazySingleton<AuthenticationRemoteDataSource>( ..registerLazySingleton<AuthenticationRemoteDataSource>(
() => AuthenticationMockDataSourceImpl(registeredAccounts: [ MockSettings.isEnable()
Pair( ? () => AuthenticationMockDataSourceImpl(registeredAccounts: [
AccountModel( Pair(
uid: '1', AccountModel(
emailVerified: true, uid: '1',
isAnonymous: false, emailVerified: true,
providerId: 'wyatt', isAnonymous: false,
email: 'toto@test.fr', providerId: 'wyatt',
), email: 'toto@test.fr',
'toto1234', ),
), 'toto1234',
Pair( ),
AccountModel( Pair(
uid: '2', AccountModel(
emailVerified: false, uid: '2',
isAnonymous: false, emailVerified: false,
providerId: 'wyatt', isAnonymous: false,
email: 'tata@test.fr', providerId: 'wyatt',
), email: 'tata@test.fr',
'tata1234', ),
), 'tata1234',
]), ),
])
: () => AuthenticationFirebaseDataSourceImpl(
googleSignIn: GoogleSignIn(
clientId: DefaultFirebaseOptions.ios.iosClientId)),
) )
..registerLazySingleton<AuthenticationCacheDataSource<int>>( ..registerLazySingleton<AuthenticationCacheDataSource<int>>(
() => AuthenticationCacheDataSourceImpl<int>(), () => AuthenticationCacheDataSourceImpl<int>(),
@@ -1,16 +1,16 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -1,16 +1,16 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -0,0 +1,67 @@
// 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:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for android - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.iOS:
return ios;
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 ios = FirebaseOptions(
apiKey: 'AIzaSyDDmtf0KN7Xw12_pqUsxoBfAxMuvCMmMmk',
appId: '1:405351917235:ios:869f0ad8ace08db899f2c6',
messagingSenderId: '405351917235',
projectId: 'meerabel-dev',
storageBucket: 'meerabel-dev.appspot.com',
androidClientId:
'405351917235-4g1dh3475tq6t1sa2qoh7ol60nf4ta05.apps.googleusercontent.com',
iosClientId:
'405351917235-2jv4ff02kovoim58f8d6d0rsa14apgkj.apps.googleusercontent.com',
iosBundleId: 'com.example.exampleRouter',
);
}
@@ -1,16 +1,16 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -18,5 +18,6 @@ import 'package:example_router/bootstrap.dart';
import 'package:example_router/presentation/features/app/app.dart'; import 'package:example_router/presentation/features/app/app.dart';
void main() { void main() {
MockSettings.enable();
bootstrap(App.new); bootstrap(App.new);
} }
@@ -14,26 +14,10 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'dart:convert'; import 'package:example_router/bootstrap.dart';
import 'dart:math'; import 'package:example_router/presentation/features/app/app.dart';
import 'package:crypto/crypto.dart'; void main() {
MockSettings.disable();
class Cryptography { bootstrap(App.new);
/// Generates a cryptographically secure random nonce, to be included in a
/// credential request.
static String generateNonce([int length = 32]) {
const charset =
'0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._';
final random = Random.secure();
return List.generate(length, (_) => charset[random.nextInt(charset.length)])
.join();
}
/// Returns the sha256 hash of [input] in hex notation.
static String sha256ofString(String input) {
final bytes = utf8.encode(input);
final digest = sha256.convert(bytes);
return digest.toString();
}
} }
@@ -1,16 +1,16 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -71,4 +71,4 @@ class EditProfileCubit extends FormDataCubitImpl {
} }
emit(state.copyWith(status: FormStatus.submissionSuccess)); emit(state.copyWith(status: FormStatus.submissionSuccess));
} }
} }
@@ -1,16 +1,16 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -1,16 +1,16 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -94,6 +94,22 @@ class _SignInAnonymouslyButton extends StatelessWidget {
} }
} }
class _SignInWithGoogleButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SubmitBuilder<SignInCubit<int>>(
builder: ((context, cubit, status) {
return status.isSubmissionInProgress
? const CircularProgressIndicator()
: ElevatedButton(
onPressed: () => cubit.signInWithGoogle(),
child: const Text('Sign in Google'),
);
}),
);
}
}
class SignInForm extends StatelessWidget { class SignInForm extends StatelessWidget {
const SignInForm({Key? key}) : super(key: key); const SignInForm({Key? key}) : super(key: key);
@@ -116,6 +132,8 @@ class SignInForm extends StatelessWidget {
_SignInButton(), _SignInButton(),
const SizedBox(height: 16), const SizedBox(height: 16),
_SignInAnonymouslyButton(), _SignInAnonymouslyButton(),
const SizedBox(height: 16),
_SignInWithGoogleButton(),
], ],
), ),
), ),
@@ -1,16 +1,16 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -1,16 +1,16 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -1,16 +1,16 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -30,10 +30,12 @@ class SubPage extends StatelessWidget {
title: const Text('Sub'), title: const Text('Sub'),
actions: [ actions: [
IconButton( IconButton(
onPressed: () => context.read<AuthenticationCubit<int>>().signOut(), onPressed: () =>
context.read<AuthenticationCubit<int>>().signOut(),
icon: const Icon(Icons.logout_rounded)), icon: const Icon(Icons.logout_rounded)),
IconButton( IconButton(
onPressed: () => context.read<AuthenticationRepository<int>>().refresh(), onPressed: () =>
context.read<AuthenticationRepository<int>>().refresh(),
icon: const Icon(Icons.refresh)) icon: const Icon(Icons.refresh))
], ],
), ),
@@ -1,16 +1,16 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -18,4 +18,3 @@ export 'constants/form_field.dart';
export 'constants/form_name.dart'; export 'constants/form_name.dart';
export 'enums/enums.dart'; export 'enums/enums.dart';
export 'exceptions/exceptions.dart'; export 'exceptions/exceptions.dart';
export 'utils/utils.dart';
@@ -1,16 +1,16 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -1,16 +1,16 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -20,15 +20,14 @@ part 'exceptions_firebase.dart';
abstract class AuthenticationFailureInterface extends AppException abstract class AuthenticationFailureInterface extends AppException
implements Exception { implements Exception {
AuthenticationFailureInterface(this.code, this.msg);
AuthenticationFailureInterface.fromCode(this.code)
: msg = 'An unknown error occurred.';
String code; String code;
String msg; String msg;
@override @override
String get message => msg; String get message => msg;
AuthenticationFailureInterface(this.code, this.msg);
AuthenticationFailureInterface.fromCode(this.code)
: msg = 'An unknown error occurred.';
} }
/// {@template apply_action_code_failure} /// {@template apply_action_code_failure}
@@ -277,3 +276,10 @@ abstract class UpdatePasswordFailureInterface
UpdatePasswordFailureInterface.fromCode(super.code) : super.fromCode(); UpdatePasswordFailureInterface.fromCode(super.code) : super.fromCode();
} }
abstract class ModelParsingFailureInterface
extends AuthenticationFailureInterface {
ModelParsingFailureInterface(super.code, super.msg);
ModelParsingFailureInterface.fromCode(super.code) : super.fromCode();
}
@@ -349,3 +349,10 @@ class UpdatePasswordFailureFirebase extends UpdatePasswordFailureInterface {
} }
} }
} }
class ModelParsingFailureFirebase extends ModelParsingFailureInterface {
ModelParsingFailureFirebase([String? code, String? msg])
: super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
ModelParsingFailureFirebase.fromCode(super.code) : super.fromCode();
}
@@ -1,16 +1,16 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -20,11 +20,10 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
class AuthenticationCacheDataSourceImpl<T extends Object> class AuthenticationCacheDataSourceImpl<T extends Object>
extends AuthenticationCacheDataSource<T> { extends AuthenticationCacheDataSource<T> {
AuthenticationCacheDataSourceImpl();
Account? _account; Account? _account;
T? _data; T? _data;
AuthenticationCacheDataSourceImpl();
@override @override
Future<void> storeAccount(Account? account) async { Future<void> storeAccount(Account? account) async {
_account = account; _account = account;
@@ -14,34 +14,22 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:firebase_auth/firebase_auth.dart'; import 'package:wyatt_authentication_bloc/src/data/models/account_model_firebase.dart';
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart'; import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart'; import 'package:wyatt_type_utils/wyatt_type_utils.dart';
class AuthenticationFirebaseDataSourceImpl class AuthenticationFirebaseDataSourceImpl
extends AuthenticationRemoteDataSource { extends AuthenticationRemoteDataSource {
AuthenticationFirebaseDataSourceImpl({
FirebaseAuth? firebaseAuth,
GoogleSignIn? googleSignIn,
}) : _firebaseAuth = firebaseAuth ?? FirebaseAuth.instance,
_googleSignIn = googleSignIn ?? GoogleSignIn();
final FirebaseAuth _firebaseAuth; final FirebaseAuth _firebaseAuth;
final GoogleSignIn _googleSignIn;
UserCredential? _latestCreds; UserCredential? _latestCreds;
AuthenticationFirebaseDataSourceImpl({FirebaseAuth? firebaseAuth})
: _firebaseAuth = firebaseAuth ?? FirebaseAuth.instance;
Account _mapper(User user) => AccountModel(
uid: user.uid,
emailVerified: user.emailVerified,
isAnonymous: user.isAnonymous,
providerId: user.providerData.first.providerId,
creationTime: user.metadata.creationTime,
lastSignInTime: user.metadata.lastSignInTime,
isNewUser: (user.metadata.creationTime != null &&
user.metadata.lastSignInTime != null)
? user.metadata.lastSignInTime! == user.metadata.creationTime!
: null,
email: user.email,
phoneNumber: user.phoneNumber,
photoURL: user.photoURL,
);
@override @override
Future<Account> signInWithEmailAndPassword({ Future<Account> signInWithEmailAndPassword({
required String email, required String email,
@@ -54,11 +42,7 @@ class AuthenticationFirebaseDataSourceImpl
); );
_latestCreds = userCredential; _latestCreds = userCredential;
final user = userCredential.user; final user = userCredential.user;
if (user.isNotNull) { return AccountModelFirebase.fromFirebaseUser(user);
return _mapper(user!);
} else {
throw Exception(); // Get caught just after.
}
} on FirebaseAuthException catch (e) { } on FirebaseAuthException catch (e) {
throw SignInWithEmailAndPasswordFailureFirebase.fromCode(e.code); throw SignInWithEmailAndPasswordFailureFirebase.fromCode(e.code);
} catch (_) { } catch (_) {
@@ -80,11 +64,7 @@ class AuthenticationFirebaseDataSourceImpl
); );
_latestCreds = userCredential; _latestCreds = userCredential;
final user = userCredential.user; final user = userCredential.user;
if (user.isNotNull) { return AccountModelFirebase.fromFirebaseUser(user);
return _mapper(user!);
} else {
throw Exception(); // Get caught just after.
}
} on FirebaseAuthException catch (e) { } on FirebaseAuthException catch (e) {
throw SignUpWithEmailAndPasswordFailureFirebase.fromCode(e.code); throw SignUpWithEmailAndPasswordFailureFirebase.fromCode(e.code);
} catch (_) { } catch (_) {
@@ -121,8 +101,11 @@ class AuthenticationFirebaseDataSourceImpl
@override @override
Stream<Account?> streamAccount() => Stream<Account?> streamAccount() =>
_firebaseAuth.userChanges().map<Account?>((user) { _firebaseAuth.userChanges().map<Account?>((user) {
final Account? account = (user.isNotNull) ? _mapper(user!) : null; try {
return account; return AccountModelFirebase.fromFirebaseUser(user);
} on FirebaseAuthException {
return null;
}
}); });
@override @override
@@ -170,11 +153,7 @@ class AuthenticationFirebaseDataSourceImpl
final userCredential = await _firebaseAuth.signInAnonymously(); final userCredential = await _firebaseAuth.signInAnonymously();
_latestCreds = userCredential; _latestCreds = userCredential;
final user = userCredential.user; final user = userCredential.user;
if (user.isNotNull) { return AccountModelFirebase.fromFirebaseUser(user);
return _mapper(user!);
} else {
throw Exception(); // Get caught just after.
}
} on FirebaseAuthException catch (e) { } on FirebaseAuthException catch (e) {
throw SignInAnonymouslyFailureFirebase.fromCode(e.code); throw SignInAnonymouslyFailureFirebase.fromCode(e.code);
} catch (_) { } catch (_) {
@@ -182,6 +161,35 @@ class AuthenticationFirebaseDataSourceImpl
} }
} }
@override
Future<Account> signInWithGoogle() async {
try {
// Trigger the authentication flow
final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
// Obtain the auth details from the request
final GoogleSignInAuthentication? googleAuth =
await googleUser?.authentication;
// Create a new credential
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth?.accessToken,
idToken: googleAuth?.idToken,
);
final userCredential =
await _firebaseAuth.signInWithCredential(credential);
_latestCreds = userCredential;
final user = userCredential.user;
return AccountModelFirebase.fromFirebaseUser(user);
} on FirebaseAuthException catch (e) {
throw SignInWithGoogleFailureFirebase.fromCode(e.code);
} catch (_) {
throw SignInWithGoogleFailureFirebase();
}
}
@override @override
Future<bool> verifyPasswordResetCode({required String code}) async { Future<bool> verifyPasswordResetCode({required String code}) async {
try { try {
@@ -215,11 +223,7 @@ class AuthenticationFirebaseDataSourceImpl
throw Exception(); // Get caught just after. throw Exception(); // Get caught just after.
} }
final user = _firebaseAuth.currentUser; final user = _firebaseAuth.currentUser;
if (user.isNotNull) { return AccountModelFirebase.fromFirebaseUser(user);
return _mapper(user!);
} else {
throw Exception(); // Get caught just after.
}
} on FirebaseAuthException catch (e) { } on FirebaseAuthException catch (e) {
throw ReauthenticateFailureFirebase.fromCode(e.code); throw ReauthenticateFailureFirebase.fromCode(e.code);
} catch (_) { } catch (_) {
@@ -232,11 +236,7 @@ class AuthenticationFirebaseDataSourceImpl
try { try {
await _firebaseAuth.currentUser!.updateEmail(email); await _firebaseAuth.currentUser!.updateEmail(email);
final user = _firebaseAuth.currentUser; final user = _firebaseAuth.currentUser;
if (user.isNotNull) { return AccountModelFirebase.fromFirebaseUser(user);
return _mapper(user!);
} else {
throw Exception(); // Get caught just after.
}
} on FirebaseAuthException catch (e) { } on FirebaseAuthException catch (e) {
throw UpdateEmailFailureFirebase.fromCode(e.code); throw UpdateEmailFailureFirebase.fromCode(e.code);
} catch (_) { } catch (_) {
@@ -249,11 +249,7 @@ class AuthenticationFirebaseDataSourceImpl
try { try {
await _firebaseAuth.currentUser!.updatePassword(password); await _firebaseAuth.currentUser!.updatePassword(password);
final user = _firebaseAuth.currentUser; final user = _firebaseAuth.currentUser;
if (user.isNotNull) { return AccountModelFirebase.fromFirebaseUser(user);
return _mapper(user!);
} else {
throw Exception(); // Get caught just after.
}
} on FirebaseAuthException catch (e) { } on FirebaseAuthException catch (e) {
throw UpdatePasswordFailureFirebase.fromCode(e.code); throw UpdatePasswordFailureFirebase.fromCode(e.code);
} catch (_) { } catch (_) {
@@ -21,6 +21,10 @@ import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart'; import 'package:wyatt_type_utils/wyatt_type_utils.dart';
class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource { class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource {
AuthenticationMockDataSourceImpl({
this.idToken = 'fake-id-token',
this.registeredAccounts,
});
Pair<Account, String>? _connectedMock; Pair<Account, String>? _connectedMock;
Pair<Account, String>? _registeredMock; Pair<Account, String>? _registeredMock;
DateTime _lastSignInTime = DateTime.now(); DateTime _lastSignInTime = DateTime.now();
@@ -30,11 +34,6 @@ class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource {
final List<Pair<Account, String>>? registeredAccounts; final List<Pair<Account, String>>? registeredAccounts;
final String idToken; final String idToken;
AuthenticationMockDataSourceImpl({
this.idToken = 'fake-id-token',
this.registeredAccounts,
});
Future<void> _randomDelay() async { Future<void> _randomDelay() async {
await Future<void>.delayed( await Future<void>.delayed(
Duration(milliseconds: Random().nextInt(400) + 200), Duration(milliseconds: Random().nextInt(400) + 200),
@@ -112,7 +111,26 @@ class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource {
uid: 'mock-id-anom', uid: 'mock-id-anom',
emailVerified: false, emailVerified: false,
isAnonymous: true, isAnonymous: true,
providerId: 'wyatt', providerId: 'wyatt-studio.fr',
creationTime: creation,
lastSignInTime: creation,
isNewUser: creation == creation,
);
_streamAccount.add(mock);
_connectedMock = _connectedMock?.copyWith(left: mock);
_lastSignInTime = DateTime.now();
return Future.value(mock);
}
@override
Future<Account> signInWithGoogle() async {
await _randomDelay();
final creation = DateTime.now();
final mock = AccountModel(
uid: 'mock-id-google',
emailVerified: true,
isAnonymous: false,
providerId: 'google.com',
creationTime: creation, creationTime: creation,
lastSignInTime: creation, lastSignInTime: creation,
isNewUser: creation == creation, isNewUser: creation == creation,
@@ -72,16 +72,17 @@ class AccountModel extends Account {
String? phoneNumber, String? phoneNumber,
String? photoURL, String? photoURL,
String? providerId, String? providerId,
}) => AccountModel( }) =>
uid: uid ?? this.uid, AccountModel(
email: email ?? this.email, uid: uid ?? this.uid,
creationTime: creationTime ?? this.creationTime, email: email ?? this.email,
emailVerified: emailVerified ?? this.emailVerified, creationTime: creationTime ?? this.creationTime,
isAnonymous: isAnonymous ?? this.isAnonymous, emailVerified: emailVerified ?? this.emailVerified,
isNewUser: isNewUser ?? this.isNewUser, isAnonymous: isAnonymous ?? this.isAnonymous,
lastSignInTime: lastSignInTime ?? this.lastSignInTime, isNewUser: isNewUser ?? this.isNewUser,
phoneNumber: phoneNumber ?? this.phoneNumber, lastSignInTime: lastSignInTime ?? this.lastSignInTime,
photoURL: photoURL ?? this.photoURL, phoneNumber: phoneNumber ?? this.phoneNumber,
providerId: providerId ?? this.providerId, photoURL: photoURL ?? this.photoURL,
); providerId: providerId ?? this.providerId,
);
} }
@@ -0,0 +1,55 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
class AccountModelFirebase extends AccountModel {
AccountModelFirebase._({
required super.uid,
required super.emailVerified,
required super.isAnonymous,
required super.providerId,
super.lastSignInTime,
super.creationTime,
super.isNewUser,
super.email,
super.phoneNumber,
super.photoURL,
});
factory AccountModelFirebase.fromFirebaseUser(User? user) {
if (user != null) {
return AccountModelFirebase._(
uid: user.uid,
emailVerified: user.emailVerified,
isAnonymous: user.isAnonymous,
providerId: user.providerData.first.providerId,
creationTime: user.metadata.creationTime,
lastSignInTime: user.metadata.lastSignInTime,
isNewUser: (user.metadata.creationTime != null &&
user.metadata.lastSignInTime != null)
? user.metadata.lastSignInTime! == user.metadata.creationTime!
: null,
email: user.email,
phoneNumber: user.phoneNumber,
photoURL: user.photoURL,
);
} else {
throw ModelParsingFailureFirebase('null-user', 'User cannot be null!');
}
}
}
@@ -29,8 +29,9 @@ class AccountWrapperModel<T> extends AccountWrapper<T> {
AccountWrapperModel<T> copyWith({ AccountWrapperModel<T> copyWith({
Account? account, Account? account,
T? data, T? data,
}) => AccountWrapperModel<T>( }) =>
account ?? this.account, AccountWrapperModel<T>(
data ?? this.data, account ?? this.account,
); data ?? this.data,
);
} }
@@ -1,16 +1,16 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -42,19 +42,6 @@ typedef OnAuthChange<T> = FutureOrResult<T?> Function(
class AuthenticationRepositoryImpl<T extends Object> class AuthenticationRepositoryImpl<T extends Object>
extends AuthenticationRepository<T> { extends AuthenticationRepository<T> {
final AuthenticationCacheDataSource<T> _authenticationLocalDataSource;
final AuthenticationRemoteDataSource _authenticationRemoteDataSource;
late FormRepository _formRepository;
final OnSignUpSuccess<T>? _onSignUpSuccess;
final OnAuthChange<T>? _onAccountChanges;
final StreamController<FutureOrResult<AccountWrapper<T>>> _signUpStream =
StreamController();
bool _pause = false; // Semaphore
AuthenticationRepositoryImpl({ AuthenticationRepositoryImpl({
required AuthenticationCacheDataSource<T> authenticationCacheDataSource, required AuthenticationCacheDataSource<T> authenticationCacheDataSource,
required AuthenticationRemoteDataSource authenticationRemoteDataSource, required AuthenticationRemoteDataSource authenticationRemoteDataSource,
@@ -106,6 +93,18 @@ class AuthenticationRepositoryImpl<T extends Object>
), ),
); );
} }
final AuthenticationCacheDataSource<T> _authenticationLocalDataSource;
final AuthenticationRemoteDataSource _authenticationRemoteDataSource;
late FormRepository _formRepository;
final OnSignUpSuccess<T>? _onSignUpSuccess;
final OnAuthChange<T>? _onAccountChanges;
final StreamController<FutureOrResult<AccountWrapper<T>>> _signUpStream =
StreamController();
bool _pause = false;
@override @override
FormRepository get formRepository => _formRepository; FormRepository get formRepository => _formRepository;
@@ -295,6 +294,17 @@ class AuthenticationRepositoryImpl<T extends Object>
(error) => error, (error) => error,
); );
@override
FutureOrResult<Account> signInWithGoogle() =>
Result.tryCatchAsync<Account, AppException, AppException>(
() async {
final account =
await _authenticationRemoteDataSource.signInWithGoogle();
return account;
},
(error) => error,
);
@override @override
FutureOrResult<bool> verifyPasswordResetCode({required String code}) => FutureOrResult<bool> verifyPasswordResetCode({required String code}) =>
Result.tryCatchAsync<bool, AppException, AppException>( Result.tryCatchAsync<bool, AppException, AppException>(
@@ -1,16 +1,16 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -49,6 +49,8 @@ abstract class AuthenticationRemoteDataSource extends BaseRemoteDataSource {
Future<Account> signInAnonymously(); Future<Account> signInAnonymously();
Future<Account> signInWithGoogle();
Future<Account> updateEmail({required String email}); Future<Account> updateEmail({required String email});
Future<Account> updatePassword({required String password}); Future<Account> updatePassword({required String password});
@@ -1,16 +1,16 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -1,16 +1,16 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -73,6 +73,13 @@ abstract class AuthenticationRepository<T> extends BaseRepository {
/// {@endtemplate} /// {@endtemplate}
FutureOrResult<Account> signInAnonymously(); FutureOrResult<Account> signInAnonymously();
/// {@template signin_google}
/// Starts the Sign In with Google Flow.
///
/// Throws a SignInWithGoogleFailureInterface if an exception occurs.
/// {@endtemplate}
FutureOrResult<Account> signInWithGoogle();
/// {@template signin_pwd} /// {@template signin_pwd}
/// Signs in with the provided [email] and [password]. /// Signs in with the provided [email] and [password].
/// ///
@@ -105,8 +112,8 @@ abstract class AuthenticationRepository<T> extends BaseRepository {
}); });
/// {@template reauthenticate} /// {@template reauthenticate}
/// Some security-sensitive actions—such as deleting an account, /// Some security-sensitive actions—such as deleting an account,
/// setting a primary email address, and changing a password—require that /// setting a primary email address, and changing a password—require that
/// the user has recently signed in. /// the user has recently signed in.
/// ///
/// Throws a ReauthenticateFailureInterface if /// Throws a ReauthenticateFailureInterface if
@@ -129,7 +136,7 @@ abstract class AuthenticationRepository<T> extends BaseRepository {
/// Stream of [AccountWrapper] which will emit the current account when /// Stream of [AccountWrapper] which will emit the current account when
/// the authentication state changes. /// the authentication state changes.
/// ///
/// Emits [AccountWrapper] with null [Account] if the user is not /// Emits [AccountWrapper] with null [Account] if the user is not
/// authenticated. /// authenticated.
/// {@endtemplate} /// {@endtemplate}
Stream<FutureOrResult<AccountWrapper<T>>> streamAccount(); Stream<FutureOrResult<AccountWrapper<T>>> streamAccount();
@@ -1,16 +1,16 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -26,14 +26,13 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
part 'authentication_state.dart'; part 'authentication_state.dart';
class AuthenticationCubit<Extra> extends Cubit<AuthenticationState<Extra>> { class AuthenticationCubit<Extra> extends Cubit<AuthenticationState<Extra>> {
final AuthenticationRepository<Extra> _authenticationRepository;
AuthenticationCubit({ AuthenticationCubit({
required AuthenticationRepository<Extra> authenticationRepository, required AuthenticationRepository<Extra> authenticationRepository,
}) : _authenticationRepository = authenticationRepository, }) : _authenticationRepository = authenticationRepository,
super(const AuthenticationState.unknown()) { super(const AuthenticationState.unknown()) {
_listenForAuthenticationChanges(); _listenForAuthenticationChanges();
} }
final AuthenticationRepository<Extra> _authenticationRepository;
void _listenForAuthenticationChanges() { void _listenForAuthenticationChanges() {
_authenticationRepository.streamAccount().listen((accountFutureResult) { _authenticationRepository.streamAccount().listen((accountFutureResult) {
@@ -17,13 +17,8 @@
part of 'authentication_cubit.dart'; part of 'authentication_cubit.dart';
class AuthenticationState<Extra> extends Equatable { class AuthenticationState<Extra> extends Equatable {
final AuthenticationStatus status; const AuthenticationState.unauthenticated()
final AccountWrapper<Extra>? accountWrapper; : this._(status: AuthenticationStatus.unauthenticated);
const AuthenticationState._({required this.status, this.accountWrapper});
const AuthenticationState.unknown()
: this._(status: AuthenticationStatus.unknown);
const AuthenticationState.authenticated(AccountWrapper<Extra> accountWrapper) const AuthenticationState.authenticated(AccountWrapper<Extra> accountWrapper)
: this._( : this._(
@@ -31,8 +26,12 @@ class AuthenticationState<Extra> extends Equatable {
accountWrapper: accountWrapper, accountWrapper: accountWrapper,
); );
const AuthenticationState.unauthenticated() const AuthenticationState.unknown()
: this._(status: AuthenticationStatus.unauthenticated); : this._(status: AuthenticationStatus.unknown);
const AuthenticationState._({required this.status, this.accountWrapper});
final AuthenticationStatus status;
final AccountWrapper<Extra>? accountWrapper;
@override @override
List<Object?> get props => [status, accountWrapper]; List<Object?> get props => [status, accountWrapper];
@@ -24,12 +24,11 @@ import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
part 'email_verification_state.dart'; part 'email_verification_state.dart';
class EmailVerificationCubit<Extra> extends Cubit<EmailVerificationState> { class EmailVerificationCubit<Extra> extends Cubit<EmailVerificationState> {
final AuthenticationRepository<Extra> _authenticationRepository;
EmailVerificationCubit({ EmailVerificationCubit({
required AuthenticationRepository<Extra> authenticationRepository, required AuthenticationRepository<Extra> authenticationRepository,
}) : _authenticationRepository = authenticationRepository, }) : _authenticationRepository = authenticationRepository,
super(const EmailVerificationState()); super(const EmailVerificationState());
final AuthenticationRepository<Extra> _authenticationRepository;
FutureOr<void> sendEmailVerification() async { FutureOr<void> sendEmailVerification() async {
emit(state.copyWith(status: FormStatus.submissionInProgress)); emit(state.copyWith(status: FormStatus.submissionInProgress));
@@ -25,10 +25,6 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
part 'password_reset_state.dart'; part 'password_reset_state.dart';
class PasswordResetCubit<Extra> extends FormDataCubit<PasswordResetState> { class PasswordResetCubit<Extra> extends FormDataCubit<PasswordResetState> {
final AuthenticationRepository<Extra> _authenticationRepository;
FormRepository get _formRepository =>
_authenticationRepository.formRepository;
PasswordResetCubit({ PasswordResetCubit({
required AuthenticationRepository<Extra> authenticationRepository, required AuthenticationRepository<Extra> authenticationRepository,
}) : _authenticationRepository = authenticationRepository, }) : _authenticationRepository = authenticationRepository,
@@ -38,6 +34,9 @@ class PasswordResetCubit<Extra> extends FormDataCubit<PasswordResetState> {
.accessForm(AuthFormName.passwordResetForm), .accessForm(AuthFormName.passwordResetForm),
), ),
); );
final AuthenticationRepository<Extra> _authenticationRepository;
FormRepository get _formRepository =>
_authenticationRepository.formRepository;
@override @override
String get formName => AuthFormName.passwordResetForm; String get formName => AuthFormName.passwordResetForm;
@@ -17,13 +17,12 @@
part of 'password_reset_cubit.dart'; part of 'password_reset_cubit.dart';
class PasswordResetState extends FormDataState { class PasswordResetState extends FormDataState {
Email get email => form.validatorOf(AuthFormField.email);
const PasswordResetState({ const PasswordResetState({
required super.form, required super.form,
super.status = FormStatus.pure, super.status = FormStatus.pure,
super.errorMessage, super.errorMessage,
}); });
Email get email => form.validatorOf(AuthFormField.email);
PasswordResetState copyWith({ PasswordResetState copyWith({
WyattForm? form, WyattForm? form,
@@ -23,10 +23,6 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
part 'sign_in_state.dart'; part 'sign_in_state.dart';
class SignInCubit<Extra> extends FormDataCubit<SignInState> { class SignInCubit<Extra> extends FormDataCubit<SignInState> {
final AuthenticationRepository<Extra> _authenticationRepository;
FormRepository get _formRepository =>
_authenticationRepository.formRepository;
SignInCubit({ SignInCubit({
required AuthenticationRepository<Extra> authenticationRepository, required AuthenticationRepository<Extra> authenticationRepository,
}) : _authenticationRepository = authenticationRepository, }) : _authenticationRepository = authenticationRepository,
@@ -36,6 +32,9 @@ class SignInCubit<Extra> extends FormDataCubit<SignInState> {
.accessForm(AuthFormName.signInForm), .accessForm(AuthFormName.signInForm),
), ),
); );
final AuthenticationRepository<Extra> _authenticationRepository;
FormRepository get _formRepository =>
_authenticationRepository.formRepository;
@override @override
String get formName => AuthFormName.signInForm; String get formName => AuthFormName.signInForm;
@@ -206,4 +205,24 @@ class SignInCubit<Extra> extends FormDataCubit<SignInState> {
), ),
); );
} }
FutureOr<void> signInWithGoogle() async {
if (state.status.isSubmissionInProgress) {
return;
}
// TODO(wyatt): maybe emit new state (to not carry an old errorMessage)
emit(state.copyWith(status: FormStatus.submissionInProgress));
final uid = await _authenticationRepository.signInWithGoogle();
emit(
uid.fold(
(value) => state.copyWith(status: FormStatus.submissionSuccess),
(error) => state.copyWith(
errorMessage: error.message,
status: FormStatus.submissionFailure,
),
),
);
}
} }
@@ -17,16 +17,15 @@
part of 'sign_in_cubit.dart'; part of 'sign_in_cubit.dart';
class SignInState extends FormDataState { class SignInState extends FormDataState {
FormInputValidator<String?, ValidationError> get email =>
form.validatorOf(AuthFormField.email);
FormInputValidator<String?, ValidationError> get password =>
form.validatorOf(AuthFormField.password);
const SignInState({ const SignInState({
required super.form, required super.form,
super.status = FormStatus.pure, super.status = FormStatus.pure,
super.errorMessage, super.errorMessage,
}); });
FormInputValidator<String?, ValidationError> get email =>
form.validatorOf(AuthFormField.email);
FormInputValidator<String?, ValidationError> get password =>
form.validatorOf(AuthFormField.password);
SignInState copyWith({ SignInState copyWith({
WyattForm? form, WyattForm? form,
@@ -25,10 +25,6 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
part 'sign_up_state.dart'; part 'sign_up_state.dart';
class SignUpCubit<Extra> extends FormDataCubit<SignUpState> { class SignUpCubit<Extra> extends FormDataCubit<SignUpState> {
final AuthenticationRepository<Extra> _authenticationRepository;
FormRepository get _formRepository =>
_authenticationRepository.formRepository;
SignUpCubit({ SignUpCubit({
required AuthenticationRepository<Extra> authenticationRepository, required AuthenticationRepository<Extra> authenticationRepository,
}) : _authenticationRepository = authenticationRepository, }) : _authenticationRepository = authenticationRepository,
@@ -38,6 +34,9 @@ class SignUpCubit<Extra> extends FormDataCubit<SignUpState> {
.accessForm(AuthFormName.signUpForm), .accessForm(AuthFormName.signUpForm),
), ),
); );
final AuthenticationRepository<Extra> _authenticationRepository;
FormRepository get _formRepository =>
_authenticationRepository.formRepository;
@override @override
String get formName => AuthFormName.signUpForm; String get formName => AuthFormName.signUpForm;
@@ -17,16 +17,15 @@
part of 'sign_up_cubit.dart'; part of 'sign_up_cubit.dart';
class SignUpState extends FormDataState { class SignUpState extends FormDataState {
FormInputValidator<String?, ValidationError> get email =>
form.validatorOf(AuthFormField.email);
FormInputValidator<String?, ValidationError> get password =>
form.validatorOf(AuthFormField.password);
const SignUpState({ const SignUpState({
required super.form, required super.form,
super.status = FormStatus.pure, super.status = FormStatus.pure,
super.errorMessage, super.errorMessage,
}); });
FormInputValidator<String?, ValidationError> get email =>
form.validatorOf(AuthFormField.email);
FormInputValidator<String?, ValidationError> get password =>
form.validatorOf(AuthFormField.password);
SignUpState copyWith({ SignUpState copyWith({
WyattForm? form, WyattForm? form,
@@ -1,16 +1,16 @@
// Copyright (C) 2022 WYATT GROUP // Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details. // Please see the AUTHORS file for details.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -17,4 +17,7 @@
/// An authentication library for BLoC. /// An authentication library for BLoC.
library wyatt_authentication_bloc; library wyatt_authentication_bloc;
export 'package:firebase_auth/firebase_auth.dart';
export 'package:google_sign_in/google_sign_in.dart';
export 'src/src.dart'; export 'src/src.dart';
@@ -1,7 +1,7 @@
name: wyatt_authentication_bloc name: wyatt_authentication_bloc
description: Authentication BLoC for Flutter description: Authentication BLoC for Flutter
repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_authentication_bloc repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_authentication_bloc
version: 0.4.0+3 version: 0.4.1
publish_to: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub publish_to: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub
@@ -10,17 +10,12 @@ environment:
flutter: ">=1.17.0" flutter: ">=1.17.0"
dependencies: dependencies:
flutter: flutter: { sdk: flutter }
sdk: flutter
crypto: ^3.0.2 crypto: ^3.0.2
flutter_bloc: ^8.1.1 flutter_bloc: ^8.1.1
equatable: ^2.0.5 equatable: ^2.0.5
firebase_auth: ^4.1.1 firebase_auth: ^4.2.0
google_sign_in: ^5.3.0 google_sign_in: ^5.4.2
flutter_facebook_auth: ^4.3.0
sign_in_with_apple: ^3.3.0
twitter_login: ^4.2.3
rxdart: ^0.27.7 rxdart: ^0.27.7
wyatt_form_bloc: wyatt_form_bloc:
@@ -36,11 +31,10 @@ dependencies:
version: ^0.0.4 version: ^0.0.4
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: { sdk: flutter }
sdk: flutter
bloc_test: ^9.1.0 bloc_test: ^9.1.0
mocktail: ^0.3.0 mocktail: ^0.3.0
wyatt_analysis: wyatt_analysis:
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
version: 2.3.0 version: 2.4.0
+1 -1
View File
@@ -22,4 +22,4 @@ dev_dependencies:
wyatt_analysis: wyatt_analysis:
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub
version: ^2.3.0 version: ^2.4.0
@@ -0,0 +1,14 @@
import 'package:flutter/material.dart';
import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart';
import 'package:wyatt_component_copy_with_extension/component_copy_with_extension.dart';
part 'custom_app_bar.g.dart';
@ComponentCopyWithExtension()
class CustomAppBar extends AppBarComponent with $CustomAppBarCWMixin {
const CustomAppBar({super.title});
@override
Widget build(BuildContext context) => AppBar(
title: Text(title?.text ?? 'Title'),
);
}
@@ -0,0 +1,35 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'custom_app_bar.dart';
// **************************************************************************
// ComponentCopyWithGenerator
// **************************************************************************
class $CustomAppBarCWProxyImpl implements $AppBarComponentCWProxy {
const $CustomAppBarCWProxyImpl(this._value);
final CustomAppBar _value;
@override
CustomAppBar title(TextWrapper? title) => this(title: title);
@override
CustomAppBar leading(Widget? leading) => this(leading: leading);
@override
CustomAppBar actions(List<Widget>? actions) => this(actions: actions);
@override
CustomAppBar key(Key? key) => this(key: key);
@override
CustomAppBar call({
TextWrapper? title,
Widget? leading,
List<Widget>? actions,
Key? key,
}) =>
CustomAppBar(
title: title ?? _value.title,
);
}
mixin $CustomAppBarCWMixin on Component {
$AppBarComponentCWProxy get copyWith =>
$CustomAppBarCWProxyImpl(this as CustomAppBar);
}
@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart';
import 'package:wyatt_component_copy_with_extension/component_copy_with_extension.dart';
part 'custom_bottom_bar.g.dart';
@ComponentCopyWithExtension()
class CustomBottomBar extends BottomNavigationBarComponent
with $CustomBottomBarCWMixin {
@override
Widget build(BuildContext context) => BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(
Icons.e_mobiledata,
),
label: 'Icon 1'),
BottomNavigationBarItem(
icon: Icon(
Icons.do_not_disturb_off,
),
label: 'Icon 2'),
],
backgroundColor: Colors.blue,
);
}
@@ -0,0 +1,33 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'custom_bottom_bar.dart';
// **************************************************************************
// ComponentCopyWithGenerator
// **************************************************************************
class $CustomBottomBarCWProxyImpl
implements $BottomNavigationBarComponentCWProxy {
const $CustomBottomBarCWProxyImpl(this._value);
final CustomBottomBar _value;
@override
CustomBottomBar onTap(void Function(BuildContext, int)? onTap) =>
this(onTap: onTap);
@override
CustomBottomBar currentIndex(int? currentIndex) =>
this(currentIndex: currentIndex);
@override
CustomBottomBar key(Key? key) => this(key: key);
@override
CustomBottomBar call({
void Function(BuildContext, int)? onTap,
int? currentIndex,
Key? key,
}) =>
CustomBottomBar();
}
mixin $CustomBottomBarCWMixin on Component {
$BottomNavigationBarComponentCWProxy get copyWith =>
$CustomBottomBarCWProxyImpl(this as CustomBottomBar);
}
@@ -0,0 +1,17 @@
import 'package:flutter/material.dart';
import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart';
import 'package:wyatt_component_copy_with_extension/component_copy_with_extension.dart';
part 'custom_error_widget.g.dart';
@ComponentCopyWithExtension()
class CustomErrorWidget extends ErrorWidgetComponent
with $CustomErrorWidgetCWMixin {
CustomErrorWidget({super.error});
@override
Widget build(BuildContext context) => ColoredBox(
color: Colors.red,
child: Center(child: Text(error?.text ?? 'Error')),
);
}
@@ -0,0 +1,29 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'custom_error_widget.dart';
// **************************************************************************
// ComponentCopyWithGenerator
// **************************************************************************
class $CustomErrorWidgetCWProxyImpl implements $ErrorWidgetComponentCWProxy {
const $CustomErrorWidgetCWProxyImpl(this._value);
final CustomErrorWidget _value;
@override
CustomErrorWidget error(TextWrapper? error) => this(error: error);
@override
CustomErrorWidget key(Key? key) => this(key: key);
@override
CustomErrorWidget call({
TextWrapper? error,
Key? key,
}) =>
CustomErrorWidget(
error: error ?? _value.error,
);
}
mixin $CustomErrorWidgetCWMixin on Component {
$ErrorWidgetComponentCWProxy get copyWith =>
$CustomErrorWidgetCWProxyImpl(this as CustomErrorWidget);
}
@@ -0,0 +1,15 @@
import 'package:flutter/material.dart';
import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart';
import 'package:wyatt_component_copy_with_extension/component_copy_with_extension.dart';
part 'custom_loading_widget.g.dart';
@ComponentCopyWithExtension()
class CustomLoadingWidget extends LoadingWidgetComponent
with $CustomLoadingWidgetCWMixin {
CustomLoadingWidget({super.color});
@override
Widget build(BuildContext context) =>
Center(child: CircularProgressIndicator(color: color));
}
@@ -0,0 +1,30 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'custom_loading_widget.dart';
// **************************************************************************
// ComponentCopyWithGenerator
// **************************************************************************
class $CustomLoadingWidgetCWProxyImpl
implements $LoadingWidgetComponentCWProxy {
const $CustomLoadingWidgetCWProxyImpl(this._value);
final CustomLoadingWidget _value;
@override
CustomLoadingWidget color(Color? color) => this(color: color);
@override
CustomLoadingWidget key(Key? key) => this(key: key);
@override
CustomLoadingWidget call({
Color? color,
Key? key,
}) =>
CustomLoadingWidget(
color: color ?? _value.color,
);
}
mixin $CustomLoadingWidgetCWMixin on Component {
$LoadingWidgetComponentCWProxy get copyWith =>
$CustomLoadingWidgetCWProxyImpl(this as CustomLoadingWidget);
}
@@ -1,4 +1,7 @@
import 'package:flutter/material.dart'; import 'package:bloc_layout_example/components/custom_app_bar.dart';
import 'package:bloc_layout_example/components/custom_bottom_bar.dart';
import 'package:bloc_layout_example/components/custom_error_widget.dart';
import 'package:bloc_layout_example/components/custom_loading_widget.dart';
import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart'; import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart';
class AppThemeComponent { class AppThemeComponent {
@@ -9,71 +12,3 @@ class AppThemeComponent {
errorWidget: CustomErrorWidget(), errorWidget: CustomErrorWidget(),
); );
} }
class CustomAppBar extends AppBarComponent {
const CustomAppBar({super.title});
@override
Widget build(BuildContext context) => AppBar(
title: Text(title ?? 'Title'),
);
@override
AppBarComponent? configure(
{String? title, Widget? leading, List<Widget>? actions}) =>
CustomAppBar(
title: title ?? this.title,
);
}
class CustomBottomBar extends BottomNavigationBarComponent {
@override
Widget build(BuildContext context) => BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(
Icons.e_mobiledata,
),
label: 'Icon 1'),
BottomNavigationBarItem(
icon: Icon(
Icons.do_not_disturb_off,
),
label: 'Icon 2'),
],
backgroundColor: Colors.blue,
);
@override
BottomNavigationBarComponent? configure(
{void Function(BuildContext p1, int p2)? onTap,
int currentIndex = 0}) =>
this;
}
class CustomLoadingWidget extends LoadingWidgetComponent {
CustomLoadingWidget({super.color});
@override
Widget build(BuildContext context) =>
Center(child: CircularProgressIndicator(color: color));
@override
LoadingWidgetComponent? configure({Color? color}) => CustomLoadingWidget(
color: color ?? this.color,
);
}
class CustomErrorWidget extends ErrorWidgetComponent {
CustomErrorWidget({super.error});
@override
Widget build(BuildContext context) => ColoredBox(
color: Colors.red,
child: Center(child: Text(error ?? 'Error')),
);
@override
ErrorWidgetComponent? configure({String? error}) => CustomErrorWidget(
error: error ?? this.error,
);
}
@@ -105,7 +105,7 @@ class ExampleListCrudStateManagement
} }
class ExampleFrameLayoutCrudConsumer class ExampleFrameLayoutCrudConsumer
extends FrameLayoutCrudConsumerScreen<ExampleCubit, String> { extends FrameLayoutCrudCubitConsumerScreen<ExampleCubit, String> {
const ExampleFrameLayoutCrudConsumer() const ExampleFrameLayoutCrudConsumer()
: super( : super(
title: 'Example Title', title: 'Example Title',
@@ -118,7 +118,7 @@ class ExampleFrameLayoutCrudConsumer
} }
class ExampleFrameLayoutCrudListConsumer class ExampleFrameLayoutCrudListConsumer
extends FrameLayoutCrudListConsumerScreen<ExampleCubit, String> { extends FrameLayoutCrudListCubitConsumerScreen<ExampleCubit, String> {
const ExampleFrameLayoutCrudListConsumer() const ExampleFrameLayoutCrudListConsumer()
: super( : super(
title: 'Example Title', title: 'Example Title',
@@ -3,7 +3,7 @@ description: A new Flutter project.
# The following line prevents the package from being accidentally published to # The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages. # pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev publish_to: "none" # Remove this line if you wish to publish to pub.dev
# The following defines the version and build number for your application. # The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43 # A version number is three numbers separated by dots, like 1.2.43
@@ -27,33 +27,38 @@ environment:
# the latest version available on pub.dev. To see which dependencies have newer # the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`. # versions available, run `flutter pub outdated`.
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
wyatt_bloc_layout: wyatt_bloc_layout:
path: "../" path: "../"
wyatt_component_copy_with_extension:
git:
url: ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-packages.git
path: packages/wyatt_component_copy_with_extension
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
build_runner: ^2.3.3
wyatt_component_copy_with_gen:
git:
url: ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-packages.git
path: packages/wyatt_component_copy_with_gen
wyatt_analysis: wyatt_analysis:
git: git:
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
ref: wyatt_analysis-v2.3.0 ref: wyatt_analysis-v2.4.0
path: packages/wyatt_analysis path: packages/wyatt_analysis
# For information on the generic Dart part of this file, see the # For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec # following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter. # The following section is specific to Flutter.
flutter: flutter:
# The following line ensures that the Material Icons font is # The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in # included with your application, so that you can use the icons in
# the material Icons class. # the material Icons class.

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