Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c8ff373a1
|
||
|
|
640cfaf118
|
||
|
|
7fc3736854
|
||
|
|
29d8ec640f
|
||
|
|
7f9621b4f6
|
||
|
|
7b61f3f08a
|
||
|
|
75a5facfdc
|
||
|
|
c93b7fb5f7 | ||
|
|
aee7060a0b
|
||
|
|
4f49f4931c | ||
|
|
e8172004a3 | ||
|
|
c6d8ca37fe | ||
|
|
e01f47d41a | ||
|
|
7a24a36af0 | ||
|
|
244a286509 | ||
|
|
81a7ca5a1f | ||
|
|
45c7bd6fca | ||
|
|
cd2806b07b | ||
|
|
dd275460f6 | ||
|
|
dc0f0c61c6 | ||
|
|
1e305c75bd
|
||
|
|
9af76b8e1f | ||
|
|
5593620181 | ||
|
|
a19d4bc5ce | ||
|
|
21b18054ba | ||
|
|
ff90af47cd | ||
|
|
3bb57e65f8 | ||
|
|
9d0aac7894 | ||
|
|
a561cbff23 | ||
|
|
fafec78546 | ||
|
|
feca378131 | ||
|
|
f223811f4b
|
||
|
|
ed65489316
|
||
|
|
33797e4dbf | ||
|
|
3aa6d03dd6 | ||
|
|
bf03324fd0 | ||
|
|
5e83c9e74e
|
||
|
|
672aba7084
|
||
|
|
94d7efbe8c
|
||
|
|
5298bd99ed
|
||
|
|
d792f4cbe9 | ||
|
|
098ec9715e | ||
|
|
6d3c64d17c | ||
|
|
c615186f19 | ||
|
|
55e24fb23b | ||
|
|
4d04c3f446 | ||
|
|
a20e4a1715 | ||
|
|
cf9f1ddb65 | ||
|
|
0c141c715e | ||
|
|
d0f59bbf29 | ||
|
|
562f84dd33 | ||
|
|
771f600eb7 | ||
|
|
7fcb9e8ac3
|
@@ -0,0 +1,36 @@
|
|||||||
|
# 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/>.
|
||||||
|
|
||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: default
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: quality-check
|
||||||
|
image: git.wyatt-studio.fr/wyatt-foss/flutter-melos:2.9.0
|
||||||
|
commands:
|
||||||
|
- melos run quality-check
|
||||||
|
- melos run publish:validate
|
||||||
|
- name: publish
|
||||||
|
image: git.wyatt-studio.fr/wyatt-foss/flutter-melos:2.9.0
|
||||||
|
commands:
|
||||||
|
- melos run publish:validate
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
branch:
|
||||||
|
- master
|
||||||
|
event:
|
||||||
|
- push
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
repos:
|
||||||
|
- repo: https://github.com/compilerla/conventional-pre-commit
|
||||||
|
rev: v2.1.1
|
||||||
|
hooks:
|
||||||
|
- id: conventional-pre-commit
|
||||||
|
stages: [commit-msg]
|
||||||
|
args: [build, ci, docs, feat, fix, perf, refactor, style, test, chore]
|
||||||
@@ -3,6 +3,70 @@
|
|||||||
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.
|
||||||
|
|
||||||
|
## 2022-12-12
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Packages with breaking changes:
|
||||||
|
|
||||||
|
- There are no breaking changes in this release.
|
||||||
|
|
||||||
|
Packages with other changes:
|
||||||
|
|
||||||
|
- [`wyatt_analysis` - `v2.3.0`](#wyatt_analysis---v230)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### `wyatt_analysis` - `v2.3.0`
|
||||||
|
|
||||||
|
- **REFACTOR**: follow melos versioning.
|
||||||
|
- **FIX**: change file include to keep coherence.
|
||||||
|
- **FEAT**: exclude generated code, and add dart>2.16 rules.
|
||||||
|
- **FEAT**: add overwrite protection.
|
||||||
|
- **FEAT**: add 2.2.2 files for archive.
|
||||||
|
- **FEAT**: add utils script to easely bump version.
|
||||||
|
|
||||||
|
|
||||||
|
## 2022-12-04
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Packages with breaking changes:
|
||||||
|
|
||||||
|
- [`wyatt_bloc_helper` - `v2.0.0`](#wyatt_bloc_helper---v200)
|
||||||
|
|
||||||
|
Packages with other changes:
|
||||||
|
|
||||||
|
- [`wyatt_type_utils` - `v0.0.4`](#wyatt_type_utils---v004)
|
||||||
|
- [`wyatt_authentication_bloc` - `v0.4.0+3`](#wyatt_authentication_bloc---v0403)
|
||||||
|
- [`wyatt_crud_bloc` - `v0.1.0+2`](#wyatt_crud_bloc---v0102)
|
||||||
|
- [`wyatt_architecture` - `v0.1.0+1`](#wyatt_architecture---v0101)
|
||||||
|
- [`wyatt_form_bloc` - `v0.2.0+2`](#wyatt_form_bloc---v0202)
|
||||||
|
|
||||||
|
Packages with dependency updates only:
|
||||||
|
|
||||||
|
> Packages listed below depend on other packages in this workspace that have had changes. Their versions have been incremented to bump the minimum dependency versions of the packages they depend upon in this project.
|
||||||
|
|
||||||
|
- `wyatt_authentication_bloc` - `v0.4.0+3`
|
||||||
|
- `wyatt_crud_bloc` - `v0.1.0+2`
|
||||||
|
- `wyatt_architecture` - `v0.1.0+1`
|
||||||
|
- `wyatt_form_bloc` - `v0.2.0+2`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### `wyatt_bloc_helper` - `v2.0.0`
|
||||||
|
|
||||||
|
- **BREAKING** **REFACTOR**: update onWrap label (close #46).
|
||||||
|
|
||||||
|
#### `wyatt_type_utils` - `v0.0.4`
|
||||||
|
|
||||||
|
- **FEAT**: add Result extension on FutureOr type (close #40).
|
||||||
|
|
||||||
|
|
||||||
## 2022-12-03
|
## 2022-12-03
|
||||||
|
|
||||||
### Changes
|
### Changes
|
||||||
|
|||||||
@@ -171,10 +171,16 @@ Note that your issue will be close after merging on master.
|
|||||||
Before closing the issue, please check tests and update coverage. You might run :
|
Before closing the issue, please check tests and update coverage. You might run :
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
melos run test
|
melos run test:all # this will run all tests in this project
|
||||||
melos run gen_coverage
|
melos run gen-coverage # this will generate coverage report
|
||||||
|
melos run gen-class-models # this will generate plantuml class diagrams
|
||||||
|
melos run quality-check # this will run all targets generally expected in CI
|
||||||
|
melos run publish:validate # this will run a validation before publish packages
|
||||||
|
melos run publish # this will publish packages
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that only modified package will be verified and published.
|
||||||
|
|
||||||
#### 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.
|
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.
|
||||||
|
|||||||
@@ -21,8 +21,7 @@ scripts:
|
|||||||
|
|
||||||
analyze:
|
analyze:
|
||||||
run: |
|
run: |
|
||||||
melos exec -c 10 -- \
|
melos exec -c 1 -- flutter analyze --fatal-infos
|
||||||
flutter analyze --fatal-infos
|
|
||||||
description: Run `flutter analyze` for all packages.
|
description: Run `flutter analyze` for all packages.
|
||||||
|
|
||||||
format:
|
format:
|
||||||
@@ -38,18 +37,38 @@ scripts:
|
|||||||
description: Clean things very deeply with `git clean`.
|
description: Clean things very deeply with `git clean`.
|
||||||
|
|
||||||
test:selective_unit_test:
|
test:selective_unit_test:
|
||||||
run: melos exec --dir-exists="test" -- flutter test --no-pub --coverage
|
run: melos exec -- flutter test --no-pub --coverage
|
||||||
description: Run Flutter tests for a specific package in this project.
|
description: Run Flutter tests for a specific package in this project.
|
||||||
select-package:
|
select-package:
|
||||||
flutter: true
|
dir-exists:
|
||||||
|
- test
|
||||||
|
ignore:
|
||||||
|
- '*example*'
|
||||||
|
|
||||||
test:
|
test:all:
|
||||||
run: melos run test:selective_unit_test --no-select
|
run: melos run test:selective_unit_test --no-select
|
||||||
description: Run all Flutter tests in this project.
|
description: Run all Flutter tests in this project.
|
||||||
|
|
||||||
gen-coverage: melos exec -- sh "\$MELOS_ROOT_PATH/combine_coverage.sh" && genhtml coverage/lcov.info -o coverage/html
|
gen-coverage: melos exec -- sh "\$MELOS_ROOT_PATH/combine_coverage.sh" && genhtml coverage/lcov.info -o coverage/html
|
||||||
|
|
||||||
gen-class-models: melos exec --scope="*wyatt_*" -- dart pub global run dcdg -o models/class-models.puml
|
gen-class-models:
|
||||||
|
run: melos exec -- dart pub global run dcdg -o models/class-models.puml
|
||||||
|
select-package:
|
||||||
|
ignore:
|
||||||
|
- '*example*'
|
||||||
|
|
||||||
|
quality-check:
|
||||||
|
run: |
|
||||||
|
melos clean && \
|
||||||
|
melos bootstrap && \
|
||||||
|
melos run test:all
|
||||||
|
description: Run all targets generally expected in CI for a full local quality check.
|
||||||
|
|
||||||
|
publish:validate:
|
||||||
|
run: melos publish --diff="origin/$DRONE_COMMIT_BRANCH...HEAD" --yes
|
||||||
|
|
||||||
|
# publish:
|
||||||
|
# run: melos publish --diff="origin/$DRONE_COMMIT_BRANCH...HEAD" --no-dry-run --yes
|
||||||
|
|
||||||
# Additional cleanup lifecycle script, executed when `melos clean` is run.
|
# Additional cleanup lifecycle script, executed when `melos clean` is run.
|
||||||
postclean: >
|
postclean: >
|
||||||
|
|||||||
@@ -1,3 +1,12 @@
|
|||||||
|
## 2.3.0
|
||||||
|
|
||||||
|
- **REFACTOR**: follow melos versioning.
|
||||||
|
- **FIX**: change file include to keep coherence.
|
||||||
|
- **FEAT**: exclude generated code, and add dart>2.16 rules.
|
||||||
|
- **FEAT**: add overwrite protection.
|
||||||
|
- **FEAT**: add 2.2.2 files for archive.
|
||||||
|
- **FEAT**: add utils script to easely bump version.
|
||||||
|
|
||||||
## 2.2.2
|
## 2.2.2
|
||||||
|
|
||||||
- **DOCS**: add publish_to self hosted pub server.
|
- **DOCS**: add publish_to self hosted pub server.
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
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.0.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.3.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).
|
||||||
|
|
||||||
@@ -29,12 +29,9 @@ This package provides lint rules for Dart and Flutter which are used at [Wyatt](
|
|||||||
To use the lints, add a dependency in your `pubspec.yaml`:
|
To use the lints, add a dependency in your `pubspec.yaml`:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
dev_dependencies:
|
wyatt_analysis:
|
||||||
wyatt_analysis:
|
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
|
||||||
git:
|
version: 2.3.0
|
||||||
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
|
|
||||||
ref: wyatt_analysis-v2.0.0
|
|
||||||
path: packages/wyatt_analysis
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, add an include in `analysis_options.yaml`:
|
Then, add an include in `analysis_options.yaml`:
|
||||||
@@ -52,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.0.0.yaml
|
include: package:wyatt_analysis/analysis_options.flutter.2.3.0.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
If you just want **Dart** version:
|
If you just want **Dart** version:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
include: package:wyatt_analysis/analysis_options.2.0.0.yaml
|
include: package:wyatt_analysis/analysis_options.2.3.0.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
## Suppressing Lints
|
## Suppressing Lints
|
||||||
|
|||||||
@@ -0,0 +1,206 @@
|
|||||||
|
# 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/>.
|
||||||
|
|
||||||
|
analyzer:
|
||||||
|
language:
|
||||||
|
strict-casts: true
|
||||||
|
strict-inference: true
|
||||||
|
strict-raw-types: true
|
||||||
|
|
||||||
|
errors:
|
||||||
|
todo: ignore
|
||||||
|
close_sinks: ignore
|
||||||
|
missing_required_param: error
|
||||||
|
missing_return: error
|
||||||
|
|
||||||
|
exclude:
|
||||||
|
- example/**
|
||||||
|
- lib/l10n/**
|
||||||
|
- lib/generated/**
|
||||||
|
- lib/generated_plugin_registrant.dart
|
||||||
|
- test/.test_coverage.dart
|
||||||
|
|
||||||
|
linter:
|
||||||
|
rules:
|
||||||
|
- always_declare_return_types
|
||||||
|
- always_require_non_null_named_parameters
|
||||||
|
- always_put_control_body_on_new_line
|
||||||
|
- always_put_required_named_parameters_first
|
||||||
|
- 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_function_literals_in_foreach_calls
|
||||||
|
- avoid_init_to_null
|
||||||
|
- avoid_js_rounded_ints
|
||||||
|
- 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
|
||||||
|
- 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
|
||||||
|
- 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_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_operators
|
||||||
|
- prefer_null_aware_method_calls
|
||||||
|
- 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_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
|
||||||
|
- 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_super_parameters
|
||||||
|
- use_test_throws_matchers
|
||||||
|
- use_to_and_as_if_applicable
|
||||||
|
- valid_regexps
|
||||||
|
- void_checks
|
||||||
@@ -0,0 +1,213 @@
|
|||||||
|
# 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/>.
|
||||||
|
|
||||||
|
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
|
||||||
|
- 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
|
||||||
|
- 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_super_parameters
|
||||||
|
- use_test_throws_matchers
|
||||||
|
- use_to_and_as_if_applicable
|
||||||
|
- valid_regexps
|
||||||
|
- void_checks
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
# 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.1.1.yaml
|
include: package:wyatt_analysis/analysis_options.2.2.0.yaml
|
||||||
|
|
||||||
linter:
|
linter:
|
||||||
rules:
|
rules:
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# 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/>.
|
||||||
|
|
||||||
|
include: package:wyatt_analysis/analysis_options.2.2.2.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
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# 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/>.
|
||||||
|
|
||||||
|
include: package:wyatt_analysis/analysis_options.2.3.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,3 +1,4 @@
|
|||||||
|
|
||||||
# Copyright (C) 2022 WYATT GROUP
|
# Copyright (C) 2022 WYATT GROUP
|
||||||
# Please see the AUTHORS file for details.
|
# Please see the AUTHORS file for details.
|
||||||
#
|
#
|
||||||
@@ -14,4 +15,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.2.1.yaml
|
include: package:wyatt_analysis/analysis_options.flutter.2.3.0.yaml
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
# Copyright (C) 2022 WYATT GROUP
|
# Copyright (C) 2022 WYATT GROUP
|
||||||
# Please see the AUTHORS file for details.
|
# Please see the AUTHORS file for details.
|
||||||
#
|
#
|
||||||
@@ -14,4 +15,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.2.1.yaml
|
include: package:wyatt_analysis/analysis_options.2.3.0.yaml
|
||||||
|
|
||||||
|
|||||||
@@ -15,8 +15,7 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
/// Wyatt analyzer settings and best practices
|
/// Wyatt analyzer settings and best practices
|
||||||
/// used internally at [Wyatt](https://wyattapp.io)
|
/// used internally at [Wyatt Studio](https://wyatt-studio.fr).
|
||||||
/// and [Wyatt Studio](https://wyatt-studio.fr).
|
|
||||||
library wyatt_analysis;
|
library wyatt_analysis;
|
||||||
|
|
||||||
const String wyattAnalysisVersion = '2.2.1';
|
const String wyattAnalysisVersion = '2.3.0';
|
||||||
|
|||||||
@@ -0,0 +1,133 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# 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/>.
|
||||||
|
|
||||||
|
usage="
|
||||||
|
usage:
|
||||||
|
$(basename "$0") <previous_version> <new_version> -- create new analyzer files.
|
||||||
|
|
||||||
|
where:
|
||||||
|
previous_version: last version, for example \`2.3.0\`
|
||||||
|
new_version: new version, for example \`2.4.0\`"
|
||||||
|
|
||||||
|
old=$1
|
||||||
|
new=$2
|
||||||
|
|
||||||
|
if [ -z "$old" ]; then
|
||||||
|
echo "previous_version cannot be null"
|
||||||
|
echo "${usage}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$new" ]; then
|
||||||
|
echo "new_version cannot be null"
|
||||||
|
echo "${usage}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
SCRIPT_PATH="${BASH_SOURCE:-$0}"
|
||||||
|
ABS_SCRIPT_PATH="$(realpath "${SCRIPT_PATH}")"
|
||||||
|
ABS_DIRECTORY="$(dirname "${ABS_SCRIPT_PATH}")"
|
||||||
|
|
||||||
|
LIB="${ABS_DIRECTORY}/lib/wyatt_analysis.dart"
|
||||||
|
OPTIONS="${ABS_DIRECTORY}/lib/analysis_options.yaml"
|
||||||
|
OLD_OPTIONS="${ABS_DIRECTORY}/lib/analysis_options.${old}.yaml"
|
||||||
|
NEW_OPTIONS="${ABS_DIRECTORY}/lib/analysis_options.${new}.yaml"
|
||||||
|
|
||||||
|
OPTIONS_FLUTTER="${ABS_DIRECTORY}/lib/analysis_options.flutter.yaml"
|
||||||
|
OLD_OPTIONS_FLUTTER="${ABS_DIRECTORY}/lib/analysis_options.flutter.${old}.yaml"
|
||||||
|
NEW_OPTIONS_FLUTTER="${ABS_DIRECTORY}/lib/analysis_options.flutter.${new}.yaml"
|
||||||
|
|
||||||
|
if [ ! -e "$OLD_OPTIONS" ]; then
|
||||||
|
echo "analysis_options.${old}.yaml doesn't exists"
|
||||||
|
echo "${usage}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -e "$OLD_OPTIONS_FLUTTER" ]; then
|
||||||
|
echo "analysis_options.flutter.${old}.yaml doesn't exists"
|
||||||
|
echo "${usage}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -e "$NEW_OPTIONS" ]; then
|
||||||
|
echo "analysis_options.${new}.yaml already exists"
|
||||||
|
echo "${usage}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -e "$NEW_OPTIONS_FLUTTER" ]; then
|
||||||
|
echo "analysis_options.flutter.${old}.yaml already exists"
|
||||||
|
echo "${usage}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Copy previous version files
|
||||||
|
cp "${OLD_OPTIONS}" "${NEW_OPTIONS}"
|
||||||
|
cp "${OLD_OPTIONS_FLUTTER}" "${NEW_OPTIONS_FLUTTER}"
|
||||||
|
|
||||||
|
# Search and replace old version string occurences in new files
|
||||||
|
sed -e "s/${old}/${new}/g" "${NEW_OPTIONS_FLUTTER}" > tempfile.tmp
|
||||||
|
mv -f tempfile.tmp "${NEW_OPTIONS_FLUTTER}"
|
||||||
|
|
||||||
|
sed -e "s/${old}/${new}/g" "${LIB}" > tempfile.tmp
|
||||||
|
mv -f tempfile.tmp "${LIB}"
|
||||||
|
|
||||||
|
sed -e "s/${old}/${new}/g" "README.md" > tempfile.tmp
|
||||||
|
mv -f tempfile.tmp "README.md"
|
||||||
|
|
||||||
|
echo "
|
||||||
|
# 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/>.
|
||||||
|
|
||||||
|
include: package:wyatt_analysis/analysis_options.${new}.yaml
|
||||||
|
" > "${OPTIONS}"
|
||||||
|
|
||||||
|
echo "
|
||||||
|
# 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/>.
|
||||||
|
|
||||||
|
include: package:wyatt_analysis/analysis_options.flutter.${new}.yaml
|
||||||
|
" > "${OPTIONS_FLUTTER}"
|
||||||
|
|
||||||
|
exit 0
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
name: wyatt_analysis
|
name: wyatt_analysis
|
||||||
description: Lint rules for Dart and Flutter used internally at Wyatt and 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.2.2
|
version: 2.3.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
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
## 0.1.0+1
|
||||||
|
|
||||||
|
- Update a dependency to the latest release.
|
||||||
|
|
||||||
## 0.1.0
|
## 0.1.0
|
||||||
|
|
||||||
> Note: This release has breaking changes.
|
> Note: This release has breaking changes.
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ dependencies:
|
|||||||
|
|
||||||
wyatt_type_utils:
|
wyatt_type_utils:
|
||||||
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub
|
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub
|
||||||
version: ^0.0.3+1
|
version: ^0.0.4
|
||||||
|
|
||||||
wyatt_http_client:
|
wyatt_http_client:
|
||||||
git:
|
git:
|
||||||
@@ -49,7 +49,7 @@ dependencies:
|
|||||||
|
|
||||||
wyatt_bloc_helper:
|
wyatt_bloc_helper:
|
||||||
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
|
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
|
||||||
version: ^1.2.0
|
version: ^2.0.0
|
||||||
equatable: ^2.0.5
|
equatable: ^2.0.5
|
||||||
stream_transform: ^2.1.0
|
stream_transform: ^2.1.0
|
||||||
bloc_concurrency: ^0.2.0
|
bloc_concurrency: ^0.2.0
|
||||||
@@ -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.2.2
|
ref: wyatt_analysis-v2.3.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
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: wyatt_architecture
|
name: wyatt_architecture
|
||||||
description: A new Wyatt package
|
description: A new Wyatt package
|
||||||
repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_architecture
|
repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_architecture
|
||||||
version: 0.1.0
|
version: 0.1.0+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
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ dependencies:
|
|||||||
|
|
||||||
wyatt_type_utils:
|
wyatt_type_utils:
|
||||||
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub
|
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub
|
||||||
version: ^0.0.3+1
|
version: ^0.0.4
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|
||||||
@@ -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.2.2
|
version: ^2.3.0
|
||||||
@@ -1,3 +1,7 @@
|
|||||||
|
## 0.4.0+3
|
||||||
|
|
||||||
|
- Update a dependency to the latest release.
|
||||||
|
|
||||||
## 0.4.0+2
|
## 0.4.0+2
|
||||||
|
|
||||||
- Update a dependency to the latest release.
|
- Update a dependency to the latest release.
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
// Author: Hugo Pointcheval
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
// Email: git@pcl.ovh
|
// Please see the AUTHORS file for details.
|
||||||
// -----
|
//
|
||||||
// File: bootstrap.dart
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// Created Date: 19/08/2022 15:05:17
|
// it under the terms of the GNU General Public License as published by
|
||||||
// Last Modified: Fri Nov 11 2022
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// -----
|
// any later version.
|
||||||
// Copyright (c) 2022
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,20 @@
|
|||||||
// Author: Hugo Pointcheval
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
// Email: git@pcl.ovh
|
// Please see the AUTHORS file for details.
|
||||||
// -----
|
//
|
||||||
// File: form_field.dart
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// Created Date: 19/08/2022 11:52:33
|
// it under the terms of the GNU General Public License as published by
|
||||||
// Last Modified: 19/08/2022 16:35:39
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// -----
|
// any later version.
|
||||||
// Copyright (c) 2022
|
//
|
||||||
|
// 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/>.
|
||||||
|
|
||||||
abstract class AppFormField {
|
abstract class AppFormField {
|
||||||
|
static const oldPassword = 'oldPassword';
|
||||||
static const confirmedPassword = 'confirmedPassword';
|
static const confirmedPassword = 'confirmedPassword';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,6 @@
|
|||||||
// 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:io';
|
abstract class AppFormName {
|
||||||
|
static const editProfile = 'editProfile';
|
||||||
bool get supportsAnsiColor => stdout.supportsAnsiEscapes;
|
}
|
||||||
@@ -1,12 +1,20 @@
|
|||||||
// Author: Hugo Pointcheval
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
// Email: git@pcl.ovh
|
// Please see the AUTHORS file for details.
|
||||||
// -----
|
//
|
||||||
// File: router.dart
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// Created Date: 19/08/2022 11:52:22
|
// it under the terms of the GNU General Public License as published by
|
||||||
// Last Modified: 19/08/2022 16:39:07
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// -----
|
// any later version.
|
||||||
// Copyright (c) 2022
|
//
|
||||||
|
// 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:example_router/presentation/features/edit_profile/edit_profile_page.dart';
|
||||||
import 'package:example_router/presentation/features/home/home_page.dart';
|
import 'package:example_router/presentation/features/home/home_page.dart';
|
||||||
import 'package:example_router/presentation/features/sign_in/sign_in_page.dart';
|
import 'package:example_router/presentation/features/sign_in/sign_in_page.dart';
|
||||||
import 'package:example_router/presentation/features/sign_up/sign_up_page.dart';
|
import 'package:example_router/presentation/features/sign_up/sign_up_page.dart';
|
||||||
@@ -75,5 +83,14 @@ class AppRouter {
|
|||||||
const SubPage(),
|
const SubPage(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/home/edit',
|
||||||
|
name: EditProfilePage.pageName,
|
||||||
|
pageBuilder: (context, state) => defaultTransition(
|
||||||
|
context,
|
||||||
|
state,
|
||||||
|
const EditProfilePage(),
|
||||||
|
),
|
||||||
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
// Author: Hugo Pointcheval
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
// Email: git@pcl.ovh
|
// Please see the AUTHORS file for details.
|
||||||
// -----
|
//
|
||||||
// File: app_bloc_observer.dart
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// Created Date: 19/08/2022 12:02:23
|
// it under the terms of the GNU General Public License as published by
|
||||||
// Last Modified: 19/08/2022 12:02:45
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// -----
|
// any later version.
|
||||||
// Copyright (c) 2022
|
//
|
||||||
|
// 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:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|||||||
@@ -14,37 +14,19 @@
|
|||||||
// 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/>.
|
||||||
|
|
||||||
part of prompt.framework;
|
import 'package:example_router/core/constants/form_field.dart';
|
||||||
|
import 'package:example_router/core/constants/form_name.dart';
|
||||||
|
import 'package:example_router/core/utils/custom_password.dart';
|
||||||
|
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
|
||||||
|
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
|
||||||
|
|
||||||
abstract class State<W extends Widget<dynamic>> {
|
abstract class AppForms {
|
||||||
W? _widget;
|
static WyattForm getEditProfileForm() => WyattFormImpl(
|
||||||
W get widget => _widget!;
|
[
|
||||||
|
FormInput(AuthFormField.email, const Email.pure()),
|
||||||
BuildContext? _context;
|
FormInput(AuthFormField.password, const CustomPassword.pure()),
|
||||||
BuildContext get context => _context!;
|
FormInput(AppFormField.oldPassword, const CustomPassword.pure()),
|
||||||
|
],
|
||||||
void build();
|
name: AppFormName.editProfile,
|
||||||
|
);
|
||||||
dynamic prompt();
|
|
||||||
|
|
||||||
@protected
|
|
||||||
@mustCallSuper
|
|
||||||
void dispose() {
|
|
||||||
_context = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
|
||||||
@mustCallSuper
|
|
||||||
void initState() {
|
|
||||||
_context ??= BuildContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
|
||||||
@mustCallSuper
|
|
||||||
void setState(void Function() fn) {
|
|
||||||
fn();
|
|
||||||
context.wipe();
|
|
||||||
build();
|
|
||||||
context.incrementBuildCount();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,19 @@
|
|||||||
|
// 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:example_router/bootstrap.dart';
|
import 'package:example_router/bootstrap.dart';
|
||||||
import 'package:example_router/presentation/features/app/app.dart';
|
import 'package:example_router/presentation/features/app/app.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
// Author: Hugo Pointcheval
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
// Email: git@pcl.ovh
|
// Please see the AUTHORS file for details.
|
||||||
// -----
|
//
|
||||||
// File: app.dart
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// Created Date: 19/08/2022 12:05:38
|
// it under the terms of the GNU General Public License as published by
|
||||||
// Last Modified: Sat Dec 03 2022
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// -----
|
// any later version.
|
||||||
// Copyright (c) 2022
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
@@ -14,6 +21,7 @@ import 'package:example_router/core/constants/form_field.dart';
|
|||||||
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/routes/router.dart';
|
import 'package:example_router/core/routes/router.dart';
|
||||||
import 'package:example_router/core/utils/custom_password.dart';
|
import 'package:example_router/core/utils/custom_password.dart';
|
||||||
|
import 'package:example_router/core/utils/forms.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
@@ -69,7 +77,7 @@ class App extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
AuthenticationState? previous;
|
AuthenticationState<int>? previous;
|
||||||
|
|
||||||
final AuthenticationCubit<int> authenticationCubit =
|
final AuthenticationCubit<int> authenticationCubit =
|
||||||
AuthenticationCubit(authenticationRepository: authenticationRepository);
|
AuthenticationCubit(authenticationRepository: authenticationRepository);
|
||||||
@@ -85,29 +93,18 @@ class App extends StatelessWidget {
|
|||||||
redirect: (context, state) {
|
redirect: (context, state) {
|
||||||
final authState = authenticationCubit.state;
|
final authState = authenticationCubit.state;
|
||||||
|
|
||||||
if (authState != previous) {
|
if (authState.status != previous?.status) {
|
||||||
previous = authState;
|
previous = authState;
|
||||||
// Check if current user is logged in
|
|
||||||
final loggedIn =
|
|
||||||
authState.status == AuthenticationStatus.authenticated;
|
|
||||||
|
|
||||||
// Checking if current path is onboarding or not
|
// Checking if current path is onboarding or not
|
||||||
final isOnboarding = AppRouter.publicRoutes.contains(state.subloc);
|
final isOnboarding = AppRouter.publicRoutes.contains(state.subloc);
|
||||||
|
if (authState.status == AuthenticationStatus.unauthenticated) {
|
||||||
if (!loggedIn) {
|
|
||||||
debugPrint('Not logged');
|
debugPrint('Not logged');
|
||||||
if (isOnboarding) {
|
if (!isOnboarding) {
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
return '/';
|
return '/';
|
||||||
}
|
}
|
||||||
} else {
|
} else if (authState.status == AuthenticationStatus.authenticated) {
|
||||||
debugPrint('Logged');
|
debugPrint('Logged');
|
||||||
if (isOnboarding) {
|
return '/home';
|
||||||
return '/home';
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -116,9 +113,13 @@ class App extends StatelessWidget {
|
|||||||
|
|
||||||
return MultiRepositoryProvider(
|
return MultiRepositoryProvider(
|
||||||
providers: [
|
providers: [
|
||||||
RepositoryProvider<AuthenticationRepository>.value(
|
RepositoryProvider<AuthenticationRepository<int>>.value(
|
||||||
value: authenticationRepository,
|
value: authenticationRepository,
|
||||||
),
|
),
|
||||||
|
RepositoryProvider<FormRepository>(
|
||||||
|
create: (context) =>
|
||||||
|
FormRepositoryImpl()..registerForm(AppForms.getEditProfileForm()),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
child: MultiBlocProvider(
|
child: MultiBlocProvider(
|
||||||
providers: [
|
providers: [
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
// 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:example_router/core/constants/form_field.dart';
|
||||||
|
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
|
||||||
|
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
|
||||||
|
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
||||||
|
|
||||||
|
class EditProfileCubit extends FormDataCubitImpl {
|
||||||
|
final AuthenticationRepository<int> authenticationRepository;
|
||||||
|
|
||||||
|
EditProfileCubit(
|
||||||
|
super._formRepository,
|
||||||
|
super._formName, {
|
||||||
|
required this.authenticationRepository,
|
||||||
|
}) : super();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> submit() async {
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
status: FormStatus.submissionInProgress,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
final user = (await authenticationRepository.getAccount()).ok;
|
||||||
|
|
||||||
|
final form = state.form;
|
||||||
|
final email = form.valueOf<String?>(AuthFormField.email);
|
||||||
|
final oldPassword = form.valueOf<String?>(AppFormField.oldPassword);
|
||||||
|
final newPassword = form.valueOf<String?>(AuthFormField.password);
|
||||||
|
|
||||||
|
if (email.isNullOrEmpty ||
|
||||||
|
oldPassword.isNullOrEmpty ||
|
||||||
|
newPassword.isNullOrEmpty) {
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
errorMessage: 'An error occured while retrieving data from the form.',
|
||||||
|
status: FormStatus.submissionFailure,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// await authenticationRepository.signInWithEmailAndPassword(
|
||||||
|
// email: user?.email ?? '',
|
||||||
|
// password: oldPassword ?? '',
|
||||||
|
// );
|
||||||
|
// await authenticationRepository.reauthenticateWithCredential();
|
||||||
|
await authenticationRepository.updateEmail(email: email!);
|
||||||
|
await authenticationRepository.updatePassword(password: newPassword!);
|
||||||
|
} on Exception catch (e) {
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
status: FormStatus.submissionFailure,
|
||||||
|
errorMessage: e.toString(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
emit(state.copyWith(status: FormStatus.submissionSuccess));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
// 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:example_router/core/constants/form_name.dart';
|
||||||
|
import 'package:example_router/presentation/features/edit_profile/blocs/edit_profile_cubit.dart';
|
||||||
|
import 'package:example_router/presentation/features/edit_profile/widgets/edit_profile_form.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
|
||||||
|
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
|
||||||
|
|
||||||
|
class EditProfilePage extends StatelessWidget {
|
||||||
|
const EditProfilePage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
static String pageName = 'EditProfile';
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(title: const Text('Edit Profile')),
|
||||||
|
body: Padding(
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: BlocProvider<EditProfileCubit>(
|
||||||
|
create: (context) => EditProfileCubit(
|
||||||
|
context.read<FormRepository>(),
|
||||||
|
AppFormName.editProfile,
|
||||||
|
authenticationRepository:
|
||||||
|
context.read<AuthenticationRepository<int>>(),
|
||||||
|
)..dataChanged<String?>(
|
||||||
|
AuthFormField.email,
|
||||||
|
Email.dirty(
|
||||||
|
context
|
||||||
|
.read<AuthenticationCubit<int>>()
|
||||||
|
.state
|
||||||
|
.accountWrapper
|
||||||
|
?.account
|
||||||
|
?.email ??
|
||||||
|
'',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: const EditProfileForm(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
// 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:example_router/core/constants/form_field.dart';
|
||||||
|
import 'package:example_router/core/utils/custom_password.dart';
|
||||||
|
import 'package:example_router/presentation/features/edit_profile/blocs/edit_profile_cubit.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
|
||||||
|
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
|
||||||
|
|
||||||
|
class _EmailInput extends StatelessWidget {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return InputBuilderTextController<EditProfileCubit, String?, void>(
|
||||||
|
field: AuthFormField.email,
|
||||||
|
builder: ((context, cubit, state, field, input, controller, extra) {
|
||||||
|
return TextField(
|
||||||
|
onChanged: (email) => cubit.dataChanged<String?>(
|
||||||
|
AuthFormField.email, Email.dirty(email)),
|
||||||
|
keyboardType: TextInputType.emailAddress,
|
||||||
|
controller: controller,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: 'Email',
|
||||||
|
helperText: '',
|
||||||
|
errorText: input.validator.invalid ? 'Invalid email' : null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _OldPasswordInput extends StatelessWidget {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return InputBuilder<EditProfileCubit>(
|
||||||
|
field: AppFormField.oldPassword,
|
||||||
|
builder: ((context, cubit, state, field, input) {
|
||||||
|
return TextField(
|
||||||
|
onChanged: (pwd) => cubit.dataChanged<String?>(
|
||||||
|
AppFormField.oldPassword, CustomPassword.dirty(pwd)),
|
||||||
|
obscureText: true,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: 'Old Password',
|
||||||
|
helperText: '',
|
||||||
|
errorText: input.validator.invalid ? 'Invalid password' : null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _NewPasswordInput extends StatelessWidget {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return InputBuilder<EditProfileCubit>(
|
||||||
|
field: AuthFormField.password,
|
||||||
|
builder: ((context, cubit, state, field, input) {
|
||||||
|
return TextField(
|
||||||
|
onChanged: (pwd) => cubit.dataChanged<String?>(
|
||||||
|
AuthFormField.password, CustomPassword.dirty(pwd)),
|
||||||
|
obscureText: true,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: 'New Password',
|
||||||
|
helperText: '',
|
||||||
|
errorText: input.validator.invalid ? 'Invalid password' : null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _EditButton extends StatelessWidget {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SubmitBuilder<EditProfileCubit>(
|
||||||
|
builder: ((context, cubit, status) {
|
||||||
|
return status.isSubmissionInProgress
|
||||||
|
? const CircularProgressIndicator()
|
||||||
|
: ElevatedButton(
|
||||||
|
onPressed: status.isValidated ? () => cubit.submit() : null,
|
||||||
|
child: const Text('Edit profile'),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EditProfileForm extends StatelessWidget {
|
||||||
|
const EditProfileForm({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocListener<EditProfileCubit, FormDataState>(
|
||||||
|
listener: (context, state) {
|
||||||
|
if (state.status == FormStatus.submissionFailure) {
|
||||||
|
ScaffoldMessenger.of(context)
|
||||||
|
..hideCurrentSnackBar()
|
||||||
|
..showSnackBar(
|
||||||
|
SnackBar(content: Text(state.errorMessage ?? 'Edit Failure')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
_EmailInput(),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
_OldPasswordInput(),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
_NewPasswordInput(),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
_EditButton(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,20 @@
|
|||||||
// Author: Hugo Pointcheval
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
// Email: git@pcl.ovh
|
// Please see the AUTHORS file for details.
|
||||||
// -----
|
//
|
||||||
// File: home_page.dart
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// Created Date: 19/08/2022 14:38:24
|
// it under the terms of the GNU General Public License as published by
|
||||||
// Last Modified: Wed Nov 09 2022
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// -----
|
// any later version.
|
||||||
// Copyright (c) 2022
|
//
|
||||||
|
// 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:example_router/presentation/features/edit_profile/edit_profile_page.dart';
|
||||||
import 'package:example_router/presentation/features/sub/sub_page.dart';
|
import 'package:example_router/presentation/features/sub/sub_page.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@@ -25,7 +33,8 @@ class HomePage extends StatelessWidget {
|
|||||||
title: const Text('Home'),
|
title: const Text('Home'),
|
||||||
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))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -35,8 +44,8 @@ class HomePage extends StatelessWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
AuthenticationBuilder<int>(
|
AuthenticationBuilder<int>(
|
||||||
authenticated: (context, accountWrapper) =>
|
authenticated: (context, accountWrapper) => Text(
|
||||||
Text('Logged as ${accountWrapper.account?.email} | GeneratedId is ${accountWrapper.data}'),
|
'Logged as ${accountWrapper.account?.email} | GeneratedId is ${accountWrapper.data}'),
|
||||||
unauthenticated: (context) =>
|
unauthenticated: (context) =>
|
||||||
const Text('Not logged (unauthenticated)'),
|
const Text('Not logged (unauthenticated)'),
|
||||||
unknown: (context) => const Text('Not logged (unknown)'),
|
unknown: (context) => const Text('Not logged (unknown)'),
|
||||||
@@ -45,8 +54,13 @@ class HomePage extends StatelessWidget {
|
|||||||
height: 8,
|
height: 8,
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () => context.pushNamed(SubPage.pageName),
|
onPressed: () => context.pushNamed(SubPage.pageName),
|
||||||
child: const Text('Go to sub page')),
|
child: const Text('Go to sub page'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () => context.pushNamed(EditProfilePage.pageName),
|
||||||
|
child: const Text('Go to edit profile page'),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
// Author: Hugo Pointcheval
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
// Email: git@pcl.ovh
|
// Please see the AUTHORS file for details.
|
||||||
// -----
|
//
|
||||||
// File: sign_in_page.dart
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// Created Date: 19/08/2022 12:41:42
|
// it under the terms of the GNU General Public License as published by
|
||||||
// Last Modified: 19/08/2022 15:26:36
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// -----
|
// any later version.
|
||||||
// Copyright (c) 2022
|
//
|
||||||
|
// 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:example_router/presentation/features/sign_in/widgets/sign_in_form.dart';
|
import 'package:example_router/presentation/features/sign_in/widgets/sign_in_form.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
// Author: Hugo Pointcheval
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
// Email: git@pcl.ovh
|
// Please see the AUTHORS file for details.
|
||||||
// -----
|
//
|
||||||
// File: sign_in_form.dart
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// Created Date: 19/08/2022 15:24:37
|
// it under the terms of the GNU General Public License as published by
|
||||||
// Last Modified: Sat Dec 03 2022
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// -----
|
// any later version.
|
||||||
// Copyright (c) 2022
|
//
|
||||||
|
// 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:example_router/core/utils/custom_password.dart';
|
import 'package:example_router/core/utils/custom_password.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
// Author: Hugo Pointcheval
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
// Email: git@pcl.ovh
|
// Please see the AUTHORS file for details.
|
||||||
// -----
|
//
|
||||||
// File: sign_up_page.dart
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// Created Date: 19/08/2022 12:41:27
|
// it under the terms of the GNU General Public License as published by
|
||||||
// Last Modified: 19/08/2022 14:58:51
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// -----
|
// any later version.
|
||||||
// Copyright (c) 2022
|
//
|
||||||
|
// 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:example_router/presentation/features/sign_up/widgets/sign_up_form.dart';
|
import 'package:example_router/presentation/features/sign_up/widgets/sign_up_form.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
// Author: Hugo Pointcheval
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
// Email: git@pcl.ovh
|
// Please see the AUTHORS file for details.
|
||||||
// -----
|
//
|
||||||
// File: sign_up_form.dart
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// Created Date: 19/08/2022 14:41:08
|
// it under the terms of the GNU General Public License as published by
|
||||||
// Last Modified: Sat Dec 03 2022
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// -----
|
// any later version.
|
||||||
// Copyright (c) 2022
|
//
|
||||||
|
// 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:example_router/core/constants/form_field.dart';
|
import 'package:example_router/core/constants/form_field.dart';
|
||||||
import 'package:example_router/core/utils/custom_password.dart';
|
import 'package:example_router/core/utils/custom_password.dart';
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
// Author: Hugo Pointcheval
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
// Email: git@pcl.ovh
|
// Please see the AUTHORS file for details.
|
||||||
// -----
|
//
|
||||||
// File: sub_page.dart
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// Created Date: 19/08/2022 16:10:05
|
// it under the terms of the GNU General Public License as published by
|
||||||
// Last Modified: Wed Nov 09 2022
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// -----
|
// any later version.
|
||||||
// Copyright (c) 2022
|
//
|
||||||
|
// 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:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@@ -24,7 +31,10 @@ class SubPage extends StatelessWidget {
|
|||||||
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(
|
||||||
|
onPressed: () => context.read<AuthenticationRepository<int>>().refresh(),
|
||||||
|
icon: const Icon(Icons.refresh))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: const Padding(
|
body: const Padding(
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
// Author: Hugo Pointcheval
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
// Email: git@pcl.ovh
|
// Please see the AUTHORS file for details.
|
||||||
// -----
|
//
|
||||||
// File: welcome_page.dart
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// Created Date: 19/08/2022 12:33:21
|
// it under the terms of the GNU General Public License as published by
|
||||||
// Last Modified: Wed Nov 09 2022
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// -----
|
// any later version.
|
||||||
// Copyright (c) 2022
|
//
|
||||||
|
// 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:example_router/presentation/features/sign_in/sign_in_page.dart';
|
import 'package:example_router/presentation/features/sign_in/sign_in_page.dart';
|
||||||
import 'package:example_router/presentation/features/sign_up/sign_up_page.dart';
|
import 'package:example_router/presentation/features/sign_up/sign_up_page.dart';
|
||||||
|
|||||||
@@ -40,15 +40,15 @@ dependencies:
|
|||||||
|
|
||||||
wyatt_form_bloc:
|
wyatt_form_bloc:
|
||||||
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
|
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
|
||||||
version: 0.2.0+1
|
version: 0.2.0+2
|
||||||
|
|
||||||
wyatt_architecture:
|
wyatt_architecture:
|
||||||
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
|
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
|
||||||
version: 0.1.0
|
version: 0.1.0+1
|
||||||
|
|
||||||
wyatt_type_utils:
|
wyatt_type_utils:
|
||||||
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
|
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
|
||||||
version: 0.0.3+1
|
version: 0.0.4
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
|
|||||||
@@ -256,3 +256,24 @@ abstract class GetIdTokenFailureInterface
|
|||||||
|
|
||||||
GetIdTokenFailureInterface.fromCode(super.code) : super.fromCode();
|
GetIdTokenFailureInterface.fromCode(super.code) : super.fromCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class ReauthenticateFailureInterface
|
||||||
|
extends AuthenticationFailureInterface {
|
||||||
|
ReauthenticateFailureInterface(super.code, super.msg);
|
||||||
|
|
||||||
|
ReauthenticateFailureInterface.fromCode(super.code) : super.fromCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class UpdateEmailFailureInterface
|
||||||
|
extends AuthenticationFailureInterface {
|
||||||
|
UpdateEmailFailureInterface(super.code, super.msg);
|
||||||
|
|
||||||
|
UpdateEmailFailureInterface.fromCode(super.code) : super.fromCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class UpdatePasswordFailureInterface
|
||||||
|
extends AuthenticationFailureInterface {
|
||||||
|
UpdatePasswordFailureInterface(super.code, super.msg);
|
||||||
|
|
||||||
|
UpdatePasswordFailureInterface.fromCode(super.code) : super.fromCode();
|
||||||
|
}
|
||||||
|
|||||||
@@ -277,3 +277,75 @@ class GetIdTokenFailureFirebase extends GetIdTokenFailureInterface {
|
|||||||
|
|
||||||
GetIdTokenFailureFirebase.fromCode(super.code) : super.fromCode();
|
GetIdTokenFailureFirebase.fromCode(super.code) : super.fromCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ReauthenticateFailureFirebase extends ReauthenticateFailureInterface {
|
||||||
|
ReauthenticateFailureFirebase([String? code, String? msg])
|
||||||
|
: super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
|
||||||
|
ReauthenticateFailureFirebase.fromCode(String code) : super.fromCode(code) {
|
||||||
|
switch (code) {
|
||||||
|
case 'user-mismatch':
|
||||||
|
msg = 'Given credential does not correspond to the user.';
|
||||||
|
break;
|
||||||
|
case 'user-not-found':
|
||||||
|
msg = 'User is not found, please create an account.';
|
||||||
|
break;
|
||||||
|
case 'invalid-credential':
|
||||||
|
msg = 'The credential received is malformed or has expired.';
|
||||||
|
break;
|
||||||
|
case 'invalid-email':
|
||||||
|
msg = 'Email is not valid or badly formatted.';
|
||||||
|
break;
|
||||||
|
case 'wrong-password':
|
||||||
|
msg = 'Incorrect password, please try again.';
|
||||||
|
break;
|
||||||
|
case 'invalid-verification-code':
|
||||||
|
msg = 'The credential verification code received is invalid.';
|
||||||
|
break;
|
||||||
|
case 'invalid-verification-id':
|
||||||
|
msg = 'The credential verification ID received is invalid.';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.code = 'unknown';
|
||||||
|
msg = 'An unknown error occurred.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UpdateEmailFailureFirebase extends UpdateEmailFailureInterface {
|
||||||
|
UpdateEmailFailureFirebase([String? code, String? msg])
|
||||||
|
: super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
|
||||||
|
UpdateEmailFailureFirebase.fromCode(String code) : super.fromCode(code) {
|
||||||
|
switch (code) {
|
||||||
|
case 'invalid-email':
|
||||||
|
msg = 'Email is not valid or badly formatted.';
|
||||||
|
break;
|
||||||
|
case 'email-already-in-use':
|
||||||
|
msg = 'An account already exists for that email.';
|
||||||
|
break;
|
||||||
|
case 'requires-recent-login':
|
||||||
|
msg = "User's last sign-in time does not meet the security threshold.";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.code = 'unknown';
|
||||||
|
msg = 'An unknown error occurred.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UpdatePasswordFailureFirebase extends UpdatePasswordFailureInterface {
|
||||||
|
UpdatePasswordFailureFirebase([String? code, String? msg])
|
||||||
|
: super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
|
||||||
|
UpdatePasswordFailureFirebase.fromCode(String code) : super.fromCode(code) {
|
||||||
|
switch (code) {
|
||||||
|
case 'weak-password':
|
||||||
|
msg = 'Please enter a stronger password.';
|
||||||
|
break;
|
||||||
|
case 'requires-recent-login':
|
||||||
|
msg = "User's last sign-in time does not meet the security threshold.";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.code = 'unknown';
|
||||||
|
msg = 'An unknown error occurred.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
|||||||
class AuthenticationFirebaseDataSourceImpl
|
class AuthenticationFirebaseDataSourceImpl
|
||||||
extends AuthenticationRemoteDataSource {
|
extends AuthenticationRemoteDataSource {
|
||||||
final FirebaseAuth _firebaseAuth;
|
final FirebaseAuth _firebaseAuth;
|
||||||
|
UserCredential? _latestCreds;
|
||||||
|
|
||||||
AuthenticationFirebaseDataSourceImpl({FirebaseAuth? firebaseAuth})
|
AuthenticationFirebaseDataSourceImpl({FirebaseAuth? firebaseAuth})
|
||||||
: _firebaseAuth = firebaseAuth ?? FirebaseAuth.instance;
|
: _firebaseAuth = firebaseAuth ?? FirebaseAuth.instance;
|
||||||
@@ -51,6 +52,7 @@ class AuthenticationFirebaseDataSourceImpl
|
|||||||
email: email,
|
email: email,
|
||||||
password: password,
|
password: password,
|
||||||
);
|
);
|
||||||
|
_latestCreds = userCredential;
|
||||||
final user = userCredential.user;
|
final user = userCredential.user;
|
||||||
if (user.isNotNull) {
|
if (user.isNotNull) {
|
||||||
return _mapper(user!);
|
return _mapper(user!);
|
||||||
@@ -76,6 +78,7 @@ class AuthenticationFirebaseDataSourceImpl
|
|||||||
email: email,
|
email: email,
|
||||||
password: password,
|
password: password,
|
||||||
);
|
);
|
||||||
|
_latestCreds = userCredential;
|
||||||
final user = userCredential.user;
|
final user = userCredential.user;
|
||||||
if (user.isNotNull) {
|
if (user.isNotNull) {
|
||||||
return _mapper(user!);
|
return _mapper(user!);
|
||||||
@@ -92,6 +95,7 @@ class AuthenticationFirebaseDataSourceImpl
|
|||||||
@override
|
@override
|
||||||
Future<void> signOut() async {
|
Future<void> signOut() async {
|
||||||
try {
|
try {
|
||||||
|
_latestCreds = null;
|
||||||
await _firebaseAuth.signOut();
|
await _firebaseAuth.signOut();
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
throw SignOutFailureFirebase();
|
throw SignOutFailureFirebase();
|
||||||
@@ -164,6 +168,7 @@ class AuthenticationFirebaseDataSourceImpl
|
|||||||
Future<Account> signInAnonymously() async {
|
Future<Account> signInAnonymously() async {
|
||||||
try {
|
try {
|
||||||
final userCredential = await _firebaseAuth.signInAnonymously();
|
final userCredential = await _firebaseAuth.signInAnonymously();
|
||||||
|
_latestCreds = userCredential;
|
||||||
final user = userCredential.user;
|
final user = userCredential.user;
|
||||||
if (user.isNotNull) {
|
if (user.isNotNull) {
|
||||||
return _mapper(user!);
|
return _mapper(user!);
|
||||||
@@ -199,4 +204,60 @@ class AuthenticationFirebaseDataSourceImpl
|
|||||||
throw RefreshFailureFirebase();
|
throw RefreshFailureFirebase();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Account> reauthenticateWithCredential() async {
|
||||||
|
try {
|
||||||
|
if (_latestCreds?.credential != null) {
|
||||||
|
await _firebaseAuth.currentUser
|
||||||
|
?.reauthenticateWithCredential(_latestCreds!.credential!);
|
||||||
|
} else {
|
||||||
|
throw Exception(); // Get caught just after.
|
||||||
|
}
|
||||||
|
final user = _firebaseAuth.currentUser;
|
||||||
|
if (user.isNotNull) {
|
||||||
|
return _mapper(user!);
|
||||||
|
} else {
|
||||||
|
throw Exception(); // Get caught just after.
|
||||||
|
}
|
||||||
|
} on FirebaseAuthException catch (e) {
|
||||||
|
throw ReauthenticateFailureFirebase.fromCode(e.code);
|
||||||
|
} catch (_) {
|
||||||
|
throw ReauthenticateFailureFirebase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Account> updateEmail({required String email}) async {
|
||||||
|
try {
|
||||||
|
await _firebaseAuth.currentUser!.updateEmail(email);
|
||||||
|
final user = _firebaseAuth.currentUser;
|
||||||
|
if (user.isNotNull) {
|
||||||
|
return _mapper(user!);
|
||||||
|
} else {
|
||||||
|
throw Exception(); // Get caught just after.
|
||||||
|
}
|
||||||
|
} on FirebaseAuthException catch (e) {
|
||||||
|
throw UpdateEmailFailureFirebase.fromCode(e.code);
|
||||||
|
} catch (_) {
|
||||||
|
throw UpdateEmailFailureFirebase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Account> updatePassword({required String password}) async {
|
||||||
|
try {
|
||||||
|
await _firebaseAuth.currentUser!.updatePassword(password);
|
||||||
|
final user = _firebaseAuth.currentUser;
|
||||||
|
if (user.isNotNull) {
|
||||||
|
return _mapper(user!);
|
||||||
|
} else {
|
||||||
|
throw Exception(); // Get caught just after.
|
||||||
|
}
|
||||||
|
} on FirebaseAuthException catch (e) {
|
||||||
|
throw UpdatePasswordFailureFirebase.fromCode(e.code);
|
||||||
|
} catch (_) {
|
||||||
|
throw UpdatePasswordFailureFirebase();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
|||||||
class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource {
|
class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource {
|
||||||
Pair<Account, String>? _connectedMock;
|
Pair<Account, String>? _connectedMock;
|
||||||
Pair<Account, String>? _registeredMock;
|
Pair<Account, String>? _registeredMock;
|
||||||
|
DateTime _lastSignInTime = DateTime.now();
|
||||||
final StreamController<Account?> _streamAccount = StreamController()
|
final StreamController<Account?> _streamAccount = StreamController()
|
||||||
..add(null);
|
..add(null);
|
||||||
|
|
||||||
@@ -118,6 +119,7 @@ class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource {
|
|||||||
);
|
);
|
||||||
_streamAccount.add(mock);
|
_streamAccount.add(mock);
|
||||||
_connectedMock = _connectedMock?.copyWith(left: mock);
|
_connectedMock = _connectedMock?.copyWith(left: mock);
|
||||||
|
_lastSignInTime = DateTime.now();
|
||||||
return Future.value(mock);
|
return Future.value(mock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,6 +151,7 @@ class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource {
|
|||||||
}
|
}
|
||||||
_streamAccount.add(_registeredMock!.left);
|
_streamAccount.add(_registeredMock!.left);
|
||||||
_connectedMock = _registeredMock!.copyWith();
|
_connectedMock = _registeredMock!.copyWith();
|
||||||
|
_lastSignInTime = DateTime.now();
|
||||||
return _registeredMock!.left!;
|
return _registeredMock!.left!;
|
||||||
}
|
}
|
||||||
throw SignInWithCredentialFailureFirebase();
|
throw SignInWithCredentialFailureFirebase();
|
||||||
@@ -193,6 +196,8 @@ class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource {
|
|||||||
);
|
);
|
||||||
_streamAccount.add(mock);
|
_streamAccount.add(mock);
|
||||||
_registeredMock = Pair(mock, password);
|
_registeredMock = Pair(mock, password);
|
||||||
|
_connectedMock = _registeredMock!.copyWith();
|
||||||
|
_lastSignInTime = DateTime.now();
|
||||||
return Future.value(mock);
|
return Future.value(mock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,4 +209,45 @@ class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource {
|
|||||||
await _randomDelay();
|
await _randomDelay();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Account> reauthenticateWithCredential() async {
|
||||||
|
await _randomDelay();
|
||||||
|
if (_connectedMock.isNull) {
|
||||||
|
throw ReauthenticateFailureFirebase();
|
||||||
|
}
|
||||||
|
await refresh();
|
||||||
|
_lastSignInTime = DateTime.now();
|
||||||
|
return Future.value(_connectedMock?.left);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Account> updateEmail({required String email}) {
|
||||||
|
final before = DateTime.now().subtract(const Duration(seconds: 10));
|
||||||
|
if (_lastSignInTime.isBefore(before)) {
|
||||||
|
throw UpdateEmailFailureFirebase('requires-recent-login');
|
||||||
|
}
|
||||||
|
final refresh = DateTime.now();
|
||||||
|
final mock = (_connectedMock?.left as AccountModel?)
|
||||||
|
?.copyWith(lastSignInTime: refresh, email: email);
|
||||||
|
_connectedMock = _connectedMock?.copyWith(left: mock);
|
||||||
|
_registeredMock = _registeredMock?.copyWith(left: mock);
|
||||||
|
_streamAccount.add(mock);
|
||||||
|
return Future.value(_connectedMock?.left);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Account> updatePassword({required String password}) {
|
||||||
|
final before = DateTime.now().subtract(const Duration(seconds: 10));
|
||||||
|
if (_lastSignInTime.isBefore(before)) {
|
||||||
|
throw UpdatePasswordFailureFirebase('requires-recent-login');
|
||||||
|
}
|
||||||
|
final refresh = DateTime.now();
|
||||||
|
final mock = (_connectedMock?.left as AccountModel?)
|
||||||
|
?.copyWith(lastSignInTime: refresh);
|
||||||
|
_connectedMock = _connectedMock?.copyWith(left: mock, right: password);
|
||||||
|
_registeredMock = _registeredMock?.copyWith(left: mock, right: password);
|
||||||
|
_streamAccount.add(mock);
|
||||||
|
return Future.value(_connectedMock?.left);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,4 +314,38 @@ class AuthenticationRepositoryImpl<T extends Object>
|
|||||||
},
|
},
|
||||||
(error) => error,
|
(error) => error,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
FutureOrResult<Account> reauthenticateWithCredential() =>
|
||||||
|
Result.tryCatchAsync<Account, AppException, AppException>(
|
||||||
|
() async {
|
||||||
|
final account = await _authenticationRemoteDataSource
|
||||||
|
.reauthenticateWithCredential();
|
||||||
|
return account;
|
||||||
|
},
|
||||||
|
(error) => error,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
FutureOrResult<Account> updateEmail({required String email}) =>
|
||||||
|
Result.tryCatchAsync<Account, AppException, AppException>(
|
||||||
|
() async {
|
||||||
|
final account =
|
||||||
|
await _authenticationRemoteDataSource.updateEmail(email: email);
|
||||||
|
return account;
|
||||||
|
},
|
||||||
|
(error) => error,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
FutureOrResult<Account> updatePassword({required String password}) =>
|
||||||
|
Result.tryCatchAsync<Account, AppException, AppException>(
|
||||||
|
() async {
|
||||||
|
final account = await _authenticationRemoteDataSource.updatePassword(
|
||||||
|
password: password,
|
||||||
|
);
|
||||||
|
return account;
|
||||||
|
},
|
||||||
|
(error) => error,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,4 +48,10 @@ abstract class AuthenticationRemoteDataSource extends BaseRemoteDataSource {
|
|||||||
Future<bool> verifyPasswordResetCode({required String code});
|
Future<bool> verifyPasswordResetCode({required String code});
|
||||||
|
|
||||||
Future<Account> signInAnonymously();
|
Future<Account> signInAnonymously();
|
||||||
|
|
||||||
|
Future<Account> updateEmail({required String email});
|
||||||
|
|
||||||
|
Future<Account> updatePassword({required String password});
|
||||||
|
|
||||||
|
Future<Account> reauthenticateWithCredential();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,12 +84,45 @@ abstract class AuthenticationRepository<T> extends BaseRepository {
|
|||||||
required String password,
|
required String password,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/// {@template update_email}
|
||||||
|
/// Update or add [email].
|
||||||
|
///
|
||||||
|
/// Throws a UpdateEmailFailureInterface if
|
||||||
|
/// an exception occurs.
|
||||||
|
/// {@endtemplate}
|
||||||
|
FutureOrResult<Account> updateEmail({
|
||||||
|
required String email,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// {@template update_password}
|
||||||
|
/// Update or add [password].
|
||||||
|
///
|
||||||
|
/// Throws a UpdatePasswordFailureInterface if
|
||||||
|
/// an exception occurs.
|
||||||
|
/// {@endtemplate}
|
||||||
|
FutureOrResult<Account> updatePassword({
|
||||||
|
required String password,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// {@template reauthenticate}
|
||||||
|
/// Some security-sensitive actions—such as deleting an account,
|
||||||
|
/// setting a primary email address, and changing a password—require that
|
||||||
|
/// the user has recently signed in.
|
||||||
|
///
|
||||||
|
/// Throws a ReauthenticateFailureInterface if
|
||||||
|
/// an exception occurs.
|
||||||
|
/// {@endtemplate}
|
||||||
|
FutureOrResult<Account> reauthenticateWithCredential();
|
||||||
|
|
||||||
/// {@template signout}
|
/// {@template signout}
|
||||||
/// Signs out the current user.
|
/// Signs out the current user.
|
||||||
/// It also clears the cache and the associated data.
|
/// It also clears the cache and the associated data.
|
||||||
/// {@endtemplate}
|
/// {@endtemplate}
|
||||||
FutureOrResult<void> signOut();
|
FutureOrResult<void> signOut();
|
||||||
|
|
||||||
|
/// {@template refresh}
|
||||||
|
/// Refreshes the current user, if signed in.
|
||||||
|
/// {@endtemplate}
|
||||||
FutureOrResult<void> refresh();
|
FutureOrResult<void> refresh();
|
||||||
|
|
||||||
/// {@template stream_account}
|
/// {@template stream_account}
|
||||||
|
|||||||
@@ -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+2
|
version: 0.4.0+3
|
||||||
|
|
||||||
publish_to: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub
|
publish_to: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub
|
||||||
|
|
||||||
@@ -25,15 +25,15 @@ dependencies:
|
|||||||
|
|
||||||
wyatt_form_bloc:
|
wyatt_form_bloc:
|
||||||
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
|
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
|
||||||
version: ^0.2.0+1
|
version: ^0.2.0+2
|
||||||
|
|
||||||
wyatt_architecture:
|
wyatt_architecture:
|
||||||
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
|
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
|
||||||
version: ^0.1.0
|
version: ^0.1.0+1
|
||||||
|
|
||||||
wyatt_type_utils:
|
wyatt_type_utils:
|
||||||
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
|
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
|
||||||
version: ^0.0.3+1
|
version: ^0.0.4
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
@@ -43,4 +43,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.2.2
|
version: 2.3.0
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
## 2.0.0
|
||||||
|
|
||||||
|
> Note: This release has breaking changes.
|
||||||
|
|
||||||
|
- **BREAKING** **REFACTOR**: update onWrap label (close #46).
|
||||||
|
|
||||||
## 1.2.0
|
## 1.2.0
|
||||||
|
|
||||||
- **REFACTOR**: general code update.
|
- **REFACTOR**: general code update.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: wyatt_bloc_helper
|
name: wyatt_bloc_helper
|
||||||
description: Your best friend for blocs in Flutter
|
description: Your best friend for blocs in Flutter
|
||||||
repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_bloc_helper
|
repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_bloc_helper
|
||||||
version: 1.2.0
|
version: 2.0.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
|
||||||
|
|
||||||
@@ -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.2.2
|
version: ^2.3.0
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
# Miscellaneous
|
||||||
|
*.class
|
||||||
|
*.lock
|
||||||
|
*.log
|
||||||
|
*.pyc
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
.atom/
|
||||||
|
.buildlog/
|
||||||
|
.history
|
||||||
|
.svn/
|
||||||
|
|
||||||
|
# IntelliJ related
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
.idea/*
|
||||||
|
|
||||||
|
# Visual Studio Code related
|
||||||
|
.classpath
|
||||||
|
.project
|
||||||
|
.settings/
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
|
||||||
|
# Flutter repo-specific
|
||||||
|
/bin/cache/
|
||||||
|
/bin/mingit/
|
||||||
|
/dev/benchmarks/mega_gallery/
|
||||||
|
/dev/bots/.recipe_deps
|
||||||
|
/dev/bots/android_tools/
|
||||||
|
/dev/docs/doc/
|
||||||
|
/dev/docs/flutter.docs.zip
|
||||||
|
/dev/docs/lib/
|
||||||
|
/dev/docs/pubspec.yaml
|
||||||
|
/dev/integration_tests/**/xcuserdata
|
||||||
|
/dev/integration_tests/**/Pods
|
||||||
|
/packages/flutter/coverage/
|
||||||
|
version
|
||||||
|
|
||||||
|
# packages file containing multi-root paths
|
||||||
|
.packages.generated
|
||||||
|
|
||||||
|
# Flutter/Dart/Pub related
|
||||||
|
**/doc/api/
|
||||||
|
**/ios/Flutter/.last_build_id
|
||||||
|
.dart_tool/
|
||||||
|
.flutter-plugins
|
||||||
|
.flutter-plugins-dependencies
|
||||||
|
.packages
|
||||||
|
.pub-cache/
|
||||||
|
.pub/
|
||||||
|
build/
|
||||||
|
flutter_*.png
|
||||||
|
linked_*.ds
|
||||||
|
unlinked.ds
|
||||||
|
unlinked_spec.ds
|
||||||
|
.fvm/
|
||||||
|
|
||||||
|
# Android related
|
||||||
|
**/android/**/gradle-wrapper.jar
|
||||||
|
**/android/.gradle
|
||||||
|
**/android/captures/
|
||||||
|
**/android/gradlew
|
||||||
|
**/android/gradlew.bat
|
||||||
|
**/android/local.properties
|
||||||
|
**/android/**/GeneratedPluginRegistrant.java
|
||||||
|
**/android/key.properties
|
||||||
|
**/android/.idea/
|
||||||
|
*.jks
|
||||||
|
|
||||||
|
# iOS/XCode related
|
||||||
|
**/ios/**/*.mode1v3
|
||||||
|
**/ios/**/*.mode2v3
|
||||||
|
**/ios/**/*.moved-aside
|
||||||
|
**/ios/**/*.pbxuser
|
||||||
|
**/ios/**/*.perspectivev3
|
||||||
|
**/ios/**/*sync/
|
||||||
|
**/ios/**/.sconsign.dblite
|
||||||
|
**/ios/**/.tags*
|
||||||
|
**/ios/**/.vagrant/
|
||||||
|
**/ios/**/DerivedData/
|
||||||
|
**/ios/**/Icon?
|
||||||
|
**/ios/**/Pods/
|
||||||
|
**/ios/**/.symlinks/
|
||||||
|
**/ios/**/profile
|
||||||
|
**/ios/**/xcuserdata
|
||||||
|
**/ios/.generated/
|
||||||
|
**/ios/Flutter/App.framework
|
||||||
|
**/ios/Flutter/Flutter.framework
|
||||||
|
**/ios/Flutter/Flutter.podspec
|
||||||
|
**/ios/Flutter/Generated.xcconfig
|
||||||
|
**/ios/Flutter/app.flx
|
||||||
|
**/ios/Flutter/app.zip
|
||||||
|
**/ios/Flutter/.last_build_id
|
||||||
|
**/ios/Flutter/flutter_assets/
|
||||||
|
**/ios/Flutter/flutter_export_environment.sh
|
||||||
|
**/ios/ServiceDefinitions.json
|
||||||
|
**/ios/Runner/GeneratedPluginRegistrant.*
|
||||||
|
|
||||||
|
# Coverage
|
||||||
|
coverage/
|
||||||
|
|
||||||
|
# Submodules
|
||||||
|
!pubspec.lock
|
||||||
|
packages/**/pubspec.lock
|
||||||
|
|
||||||
|
# Web related
|
||||||
|
lib/generated_plugin_registrant.dart
|
||||||
|
|
||||||
|
# Symbolication related
|
||||||
|
app.*.symbols
|
||||||
|
|
||||||
|
# Obfuscation related
|
||||||
|
app.*.map.json
|
||||||
|
|
||||||
|
# Exceptions to the above rules.
|
||||||
|
!**/ios/**/default.mode1v3
|
||||||
|
!**/ios/**/default.mode2v3
|
||||||
|
!**/ios/**/default.pbxuser
|
||||||
|
!**/ios/**/default.perspectivev3
|
||||||
|
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
|
||||||
|
!/dev/ci/**/Gemfile.lock
|
||||||
|
!.vscode/extensions.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.idea/codeStyles/
|
||||||
|
!.idea/dictionaries/
|
||||||
|
!.idea/runConfigurations/
|
||||||
|
|
||||||
|
# Omit committing pubspec.lock for library packages; see
|
||||||
|
# https://dart.dev/guides/libraries/private-files#pubspeclock.
|
||||||
|
pubspec.lock
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Launch Example",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "dart",
|
||||||
|
"cwd": "example/",
|
||||||
|
"program": "lib/main.dart",
|
||||||
|
"flutterMode": "debug"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -4,4 +4,5 @@
|
|||||||
# Name/Organization <email address>
|
# Name/Organization <email address>
|
||||||
|
|
||||||
Wyatt Group S.A.S
|
Wyatt Group S.A.S
|
||||||
Hugo Pointcheval <git@pcl.ovh>
|
Hugo Pointcheval <hugo.pointcheval@wyattapp.io>
|
||||||
|
Malo Léon <malo.leon@wyattapp.io>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# 0.0.1
|
||||||
|
|
||||||
|
- TODO: Describe initial release.
|
||||||
@@ -1,55 +1,43 @@
|
|||||||
<!--
|
<!--
|
||||||
* 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/>.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
# Dart - CLI Toolbox
|
|
||||||
|
# Flutter - Wyatt Bloc Layout
|
||||||
|
|
||||||
<p align="left">
|
<p align="left">
|
||||||
<a href="https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_analysis">
|
<a href="https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_analysis">
|
||||||
<img src="https://img.shields.io/badge/Style-Wyatt%20Analysis-blue.svg?style=flat-square" alt="Style: Wyatt Analysis" />
|
<img src="https://img.shields.io/badge/Style-Wyatt%20Analysis-blue.svg?style=flat-square" alt="Style: Wyatt Analysis" />
|
||||||
</a>
|
</a>
|
||||||
<img src="https://img.shields.io/badge/SDK-Dart-blue?style=flat-square" alt="SDK: Dart" />
|
<img src="https://img.shields.io/badge/SDK-Flutter-blue?style=flat-square" alt="SDK: Flutter" />
|
||||||
<img src="https://img.shields.io/badge/Status-WIP-red?style=flat-square" alt="WIP" />
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
Bloc Layout for Flutter.
|
||||||
|
|
||||||
|
|
||||||
TODO: Put a short description of the package here that helps potential users
|
|
||||||
know whether this package might be useful for them.
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
TODO: List what your package can do. Maybe include images, gifs, or videos.
|
<!-- TODO -->
|
||||||
|
|
||||||
## Getting started
|
## Getting started
|
||||||
|
|
||||||
TODO: List prerequisites and provide or point to information on how to
|
<!-- TODO -->
|
||||||
start using the package.
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
TODO: Include short and useful examples for package users. Add longer examples
|
<!-- TODO -->
|
||||||
to `/example` folder.
|
|
||||||
|
|
||||||
```dart
|
|
||||||
const like = 'sample';
|
|
||||||
```
|
|
||||||
|
|
||||||
## Additional information
|
|
||||||
|
|
||||||
TODO: Tell users more about the package: where to find more information, how to
|
|
||||||
contribute to the package, how to file issues, what response they can expect
|
|
||||||
from the package authors, and more.
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# 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/>.
|
||||||
|
|
||||||
|
|
||||||
|
include: package:wyatt_analysis/analysis_options.flutter.experimental.yaml
|
||||||
|
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart';
|
||||||
|
|
||||||
|
class ExampleCubit extends Cubit<CrudState> {
|
||||||
|
ExampleCubit() : super(CrudInitial());
|
||||||
|
|
||||||
|
FutureOr<void> run() async {
|
||||||
|
while (true) {
|
||||||
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
|
emit(CrudLoading());
|
||||||
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
|
emit(CrudError('Cubit Error'));
|
||||||
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
|
emit(CrudLoaded<String>('DATA LOADED'));
|
||||||
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
|
emit(CrudInitial());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FutureOr<void> runList() async {
|
||||||
|
while (true) {
|
||||||
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
|
emit(CrudLoading());
|
||||||
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
|
emit(CrudError('Cubit Error'));
|
||||||
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
|
emit(CrudListLoaded<String>([
|
||||||
|
'DATA LOADED 1',
|
||||||
|
'DATA LOADED 2',
|
||||||
|
'DATA LOADED 3',
|
||||||
|
'DATA LOADED 4'
|
||||||
|
]));
|
||||||
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
|
emit(CrudInitial());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart';
|
||||||
|
|
||||||
|
class AppThemeComponent {
|
||||||
|
static ComponentThemeData get components => ComponentThemeData.raw(
|
||||||
|
appBar: CustomAppBar(),
|
||||||
|
bottomNavigationBar: CustomBottomBar(),
|
||||||
|
loadingWidget: CustomLoadingWidget(),
|
||||||
|
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,
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
// 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:bloc_layout_example/bloc/example_cubit.dart';
|
||||||
|
import 'package:bloc_layout_example/components/theme_components.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
runApp(const MyApp());
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyApp extends StatelessWidget {
|
||||||
|
const MyApp({super.key});
|
||||||
|
|
||||||
|
// This widget is the root of your application.
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ComponentTheme(
|
||||||
|
componentThemeWidget: AppThemeComponent.components,
|
||||||
|
child: MaterialApp(
|
||||||
|
title: 'Bloc Layout Example',
|
||||||
|
theme: ThemeData(
|
||||||
|
primarySwatch: Colors.blue,
|
||||||
|
),
|
||||||
|
home: Scaffold(
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: BlocProvider(
|
||||||
|
create: (_) => ExampleCubit()..run(),
|
||||||
|
child: ExampleCrudStateManagement(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: BlocProvider(
|
||||||
|
create: (_) => ExampleCubit()..runList(),
|
||||||
|
child: ExampleListCrudStateManagement(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: BlocProvider(
|
||||||
|
create: (_) => ExampleCubit()..run(),
|
||||||
|
child: ExampleFrameLayoutCrudConsumer()),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: BlocProvider(
|
||||||
|
create: (_) => ExampleCubit()..runList(),
|
||||||
|
child: ExampleFrameLayoutCrudListConsumer()),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ExampleCrudStateManagement
|
||||||
|
extends CrudCubitConsumerScreen<ExampleCubit, String> {
|
||||||
|
@override
|
||||||
|
Widget initialBuilder(BuildContext context, CrudInitial state) =>
|
||||||
|
Container(color: Colors.yellow);
|
||||||
|
@override
|
||||||
|
Widget successBuilder(BuildContext context, CrudLoaded<String> state) =>
|
||||||
|
Center(child: Text(state.data ?? 'errors'));
|
||||||
|
}
|
||||||
|
|
||||||
|
class ExampleListCrudStateManagement
|
||||||
|
extends CrudListCubitConsumerScreen<ExampleCubit, String> {
|
||||||
|
@override
|
||||||
|
Widget initialBuilder(BuildContext context, CrudInitial state) =>
|
||||||
|
Container(color: Colors.green);
|
||||||
|
@override
|
||||||
|
Widget successBuilder(BuildContext context, CrudListLoaded<String> state) =>
|
||||||
|
Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: state.data.map((e) => Text(e ?? 'error')).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ExampleFrameLayoutCrudConsumer
|
||||||
|
extends FrameLayoutCrudConsumerScreen<ExampleCubit, String> {
|
||||||
|
const ExampleFrameLayoutCrudConsumer()
|
||||||
|
: super(
|
||||||
|
title: 'Example Title',
|
||||||
|
currentIndex: 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget successBuilder(BuildContext context, CrudLoaded<String> state) =>
|
||||||
|
Center(child: Text(state.data ?? 'errors'));
|
||||||
|
}
|
||||||
|
|
||||||
|
class ExampleFrameLayoutCrudListConsumer
|
||||||
|
extends FrameLayoutCrudListConsumerScreen<ExampleCubit, String> {
|
||||||
|
const ExampleFrameLayoutCrudListConsumer()
|
||||||
|
: super(
|
||||||
|
title: 'Example Title',
|
||||||
|
currentIndex: 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget successBuilder(BuildContext context, CrudListLoaded<String> state) =>
|
||||||
|
Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: state.data.map((e) => Text(e ?? 'error')).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
name: medium_feeds_example
|
name: bloc_layout_example
|
||||||
description: A new Flutter project.
|
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
|
||||||
@@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
version: 1.0.0+1
|
version: 1.0.0+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.16.2 <3.0.0"
|
sdk: ">=2.17.0 <3.0.0"
|
||||||
|
|
||||||
# Dependencies specify other packages that your package needs in order to work.
|
# Dependencies specify other packages that your package needs in order to work.
|
||||||
# To automatically upgrade your package dependencies to the latest versions
|
# To automatically upgrade your package dependencies to the latest versions
|
||||||
@@ -27,32 +27,30 @@ 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_medium_feeds:
|
wyatt_bloc_layout:
|
||||||
path: ../
|
path: "../"
|
||||||
|
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
|
||||||
cupertino_icons: ^1.0.2
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
# The "flutter_lints" package below contains a set of recommended lints to
|
|
||||||
# encourage good coding practices. The lint set provided by the package is
|
wyatt_analysis:
|
||||||
# activated in the `analysis_options.yaml` file located at the root of your
|
git:
|
||||||
# package. See that file for information about deactivating specific lint
|
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
|
||||||
# rules and activating additional ones.
|
ref: wyatt_analysis-v2.3.0
|
||||||
flutter_lints: ^2.0.0
|
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:
|
||||||
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// 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/>.
|
||||||
|
Before Width: | Height: | Size: 917 B After Width: | Height: | Size: 917 B |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
@@ -0,0 +1,58 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!--
|
||||||
|
If you are serving your web app in a path other than the root, change the
|
||||||
|
href value below to reflect the base path you are serving from.
|
||||||
|
|
||||||
|
The path provided below has to start and end with a slash "/" in order for
|
||||||
|
it to work correctly.
|
||||||
|
|
||||||
|
For more details:
|
||||||
|
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
|
||||||
|
|
||||||
|
This is a placeholder for base href that will be replaced by the value of
|
||||||
|
the `--base-href` argument provided to `flutter build`.
|
||||||
|
-->
|
||||||
|
<base href="$FLUTTER_BASE_HREF">
|
||||||
|
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
|
||||||
|
<meta name="description" content="A new Flutter project.">
|
||||||
|
|
||||||
|
<!-- iOS meta tags & icons -->
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="example">
|
||||||
|
<link rel="apple-touch-icon" href="icons/Icon-192.png">
|
||||||
|
|
||||||
|
<!-- Favicon -->
|
||||||
|
<link rel="icon" type="image/png" href="favicon.png"/>
|
||||||
|
|
||||||
|
<title>example</title>
|
||||||
|
<link rel="manifest" href="manifest.json">
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// The value below is injected by flutter build, do not touch.
|
||||||
|
var serviceWorkerVersion = null;
|
||||||
|
</script>
|
||||||
|
<!-- This script adds the flutter initialization JS code -->
|
||||||
|
<script src="flutter.js" defer></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
window.addEventListener('load', function(ev) {
|
||||||
|
// Download main.dart.js
|
||||||
|
_flutter.loader.loadEntrypoint({
|
||||||
|
serviceWorker: {
|
||||||
|
serviceWorkerVersion: serviceWorkerVersion,
|
||||||
|
}
|
||||||
|
}).then(function(engineInitializer) {
|
||||||
|
return engineInitializer.initializeEngine();
|
||||||
|
}).then(function(appRunner) {
|
||||||
|
return appRunner.runApp();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "medium_feeds_example",
|
"name": "example",
|
||||||
"short_name": "medium_feeds_example",
|
"short_name": "example",
|
||||||
"start_url": ".",
|
"start_url": ".",
|
||||||
"display": "standalone",
|
"display": "standalone",
|
||||||
"background_color": "#0175C2",
|
"background_color": "#0175C2",
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
// 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:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart' as bloc_base;
|
||||||
|
import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart';
|
||||||
|
|
||||||
|
abstract class AppBarLayoutCrudConsumerScreen<
|
||||||
|
Cubit extends bloc_base.Cubit<CrudState>,
|
||||||
|
T> extends CrudCubitConsumerScreen<Cubit, T> {
|
||||||
|
final String? title;
|
||||||
|
|
||||||
|
const AppBarLayoutCrudConsumerScreen({
|
||||||
|
this.title,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget parent(BuildContext context, Widget child) => AppBarLayout(
|
||||||
|
title: title ?? 'Title',
|
||||||
|
body: child,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class AppBarLayoutCrudListConsumerScreen<
|
||||||
|
Cubit extends bloc_base.Cubit<CrudState>,
|
||||||
|
T> extends CrudListCubitConsumerScreen<Cubit, T> {
|
||||||
|
final String? title;
|
||||||
|
final int? currentIndex;
|
||||||
|
|
||||||
|
const AppBarLayoutCrudListConsumerScreen({
|
||||||
|
this.title,
|
||||||
|
this.currentIndex,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget parent(BuildContext context, Widget child) => AppBarLayout(
|
||||||
|
title: title ?? 'Title',
|
||||||
|
body: child,
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
// 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:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart' as bloc_base;
|
||||||
|
import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart';
|
||||||
|
|
||||||
|
abstract class BottomNavigationBarLayoutCrudConsumerScreen<
|
||||||
|
Cubit extends bloc_base.Cubit<CrudState>,
|
||||||
|
T> extends CrudCubitConsumerScreen<Cubit, T> {
|
||||||
|
final int? currentIndex;
|
||||||
|
|
||||||
|
const BottomNavigationBarLayoutCrudConsumerScreen({
|
||||||
|
this.currentIndex,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget parent(BuildContext context, Widget child) =>
|
||||||
|
BottomNavigationBarLayout(
|
||||||
|
body: child,
|
||||||
|
currentIndex: currentIndex ?? 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class BottomNavigationBarLayoutCrudListConsumerScreen<
|
||||||
|
Cubit extends bloc_base.Cubit<CrudState>,
|
||||||
|
T> extends CrudListCubitConsumerScreen<Cubit, T> {
|
||||||
|
final String? title;
|
||||||
|
final int? currentIndex;
|
||||||
|
|
||||||
|
const BottomNavigationBarLayoutCrudListConsumerScreen({
|
||||||
|
this.title,
|
||||||
|
this.currentIndex,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget parent(BuildContext context, Widget child) =>
|
||||||
|
BottomNavigationBarLayout(
|
||||||
|
body: child,
|
||||||
|
currentIndex: currentIndex ?? 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
// 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:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart' as bloc_base;
|
||||||
|
import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart';
|
||||||
|
import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart';
|
||||||
|
import 'package:wyatt_ui_components/wyatt_wyatt_ui_components.dart';
|
||||||
|
|
||||||
|
abstract class CrudCubitConsumerScreenBase<
|
||||||
|
Cubit extends bloc_base.Cubit<CrudState>,
|
||||||
|
SuccessState extends CrudSuccess>
|
||||||
|
extends CubitConsumerScreen<Cubit, CrudState> {
|
||||||
|
const CrudCubitConsumerScreenBase({super.key});
|
||||||
|
|
||||||
|
Widget errorBuilder(BuildContext context, CrudError state) =>
|
||||||
|
context.components.errorWidget?.configure(error: state.message) ??
|
||||||
|
const SizedBox.shrink();
|
||||||
|
|
||||||
|
Widget loadingBuilder(BuildContext context, CrudLoading state) =>
|
||||||
|
context.components.loadingWidget ?? const SizedBox.shrink();
|
||||||
|
|
||||||
|
Widget initialBuilder(BuildContext context, CrudInitial state) =>
|
||||||
|
const SizedBox.shrink();
|
||||||
|
|
||||||
|
Widget successBuilder(BuildContext context, SuccessState state);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget onBuild(BuildContext context, CrudState state) =>
|
||||||
|
CrudBuilder<CrudInitial, CrudLoading, SuccessState, CrudError>(
|
||||||
|
errorBuilder: errorBuilder,
|
||||||
|
loadingBuilder: loadingBuilder,
|
||||||
|
initialBuilder: initialBuilder,
|
||||||
|
state: state,
|
||||||
|
builder: successBuilder,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class CrudCubitConsumerScreen<Cubit extends bloc_base.Cubit<CrudState>,
|
||||||
|
T> extends CrudCubitConsumerScreenBase<Cubit, CrudLoaded<T>> {
|
||||||
|
const CrudCubitConsumerScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class CrudListCubitConsumerScreen<
|
||||||
|
Cubit extends bloc_base.Cubit<CrudState>,
|
||||||
|
T> extends CrudCubitConsumerScreenBase<Cubit, CrudListLoaded<T>> {
|
||||||
|
const CrudListCubitConsumerScreen();
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:flutter/src/widgets/framework.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart' as bloc_base;
|
||||||
|
import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart';
|
||||||
|
|
||||||
|
abstract class FrameLayoutCrudConsumerScreen<
|
||||||
|
Cubit extends bloc_base.Cubit<CrudState>,
|
||||||
|
T> extends CrudCubitConsumerScreen<Cubit, T> {
|
||||||
|
final String? title;
|
||||||
|
final int? currentIndex;
|
||||||
|
|
||||||
|
const FrameLayoutCrudConsumerScreen({
|
||||||
|
this.title,
|
||||||
|
this.currentIndex,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget parent(BuildContext context, Widget child) => FrameLayout(
|
||||||
|
title: title ?? 'Title',
|
||||||
|
body: child,
|
||||||
|
currentIndex: currentIndex ?? 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class FrameLayoutCrudListConsumerScreen<
|
||||||
|
Cubit extends bloc_base.Cubit<CrudState>,
|
||||||
|
T> extends CrudListCubitConsumerScreen<Cubit, T> {
|
||||||
|
final String? title;
|
||||||
|
final int? currentIndex;
|
||||||
|
|
||||||
|
const FrameLayoutCrudListConsumerScreen({
|
||||||
|
this.title,
|
||||||
|
this.currentIndex,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget parent(BuildContext context, Widget child) => FrameLayout(
|
||||||
|
title: title ?? 'Title',
|
||||||
|
body: child,
|
||||||
|
currentIndex: currentIndex ?? 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
export 'consumers/crud_cubit_consumer_screen_bases.dart';
|
||||||
|
export 'consumers/bottom_navigation_bar_layout_crud_consumer_screen.dart';
|
||||||
|
export 'consumers/app_bar_cubit_consumer_screen.dart';
|
||||||
|
export 'consumers/frame_layout_crud_consumer_screen.dart';
|
||||||
|
export 'screens/crud_cubit_screen_base.dart';
|
||||||
|
export 'screens/app_bar_cubit_screen.dart';
|
||||||
|
export 'screens/bottom_navigation_bar_layout_crud_screen.dart';
|
||||||
|
export 'screens/frame_layout_crud_screen.dart';
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
// 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:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart' as bloc_base;
|
||||||
|
import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart';
|
||||||
|
|
||||||
|
abstract class AppBarLayoutCrudScreen<Cubit extends bloc_base.Cubit<CrudState>,
|
||||||
|
T> extends CrudCubitScreen<Cubit, T> {
|
||||||
|
final String? title;
|
||||||
|
|
||||||
|
const AppBarLayoutCrudScreen({
|
||||||
|
this.title,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget parent(BuildContext context, Widget child) => AppBarLayout(
|
||||||
|
title: title ?? 'Title',
|
||||||
|
body: child,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class AppBarLayoutCrudListScreen<
|
||||||
|
Cubit extends bloc_base.Cubit<CrudState>,
|
||||||
|
T> extends CrudListCubitScreen<Cubit, T> {
|
||||||
|
final String? title;
|
||||||
|
final int? currentIndex;
|
||||||
|
|
||||||
|
const AppBarLayoutCrudListScreen({
|
||||||
|
this.title,
|
||||||
|
this.currentIndex,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget parent(BuildContext context, Widget child) => AppBarLayout(
|
||||||
|
title: title ?? 'Title',
|
||||||
|
body: child,
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
// 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:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart' as bloc_base;
|
||||||
|
import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart';
|
||||||
|
|
||||||
|
abstract class BottomNavigationBarLayoutCrudScreen<
|
||||||
|
Cubit extends bloc_base.Cubit<CrudState>,
|
||||||
|
T> extends CrudCubitScreen<Cubit, T> {
|
||||||
|
final int? currentIndex;
|
||||||
|
|
||||||
|
const BottomNavigationBarLayoutCrudScreen({
|
||||||
|
this.currentIndex,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget parent(BuildContext context, Widget child) =>
|
||||||
|
BottomNavigationBarLayout(
|
||||||
|
body: child,
|
||||||
|
currentIndex: currentIndex ?? 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class BottomNavigationBarLayoutCrudListScreen<
|
||||||
|
Cubit extends bloc_base.Cubit<CrudState>,
|
||||||
|
T> extends CrudListCubitScreen<Cubit, T> {
|
||||||
|
final String? title;
|
||||||
|
final int? currentIndex;
|
||||||
|
|
||||||
|
const BottomNavigationBarLayoutCrudListScreen({
|
||||||
|
this.title,
|
||||||
|
this.currentIndex,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget parent(BuildContext context, Widget child) =>
|
||||||
|
BottomNavigationBarLayout(
|
||||||
|
body: child,
|
||||||
|
currentIndex: currentIndex ?? 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
// 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:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart' as bloc_base;
|
||||||
|
import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart';
|
||||||
|
|
||||||
|
abstract class CrudCubitScreenBase<Cubit extends bloc_base.Cubit<CrudState>,
|
||||||
|
SuccessState extends CrudSuccess> extends CubitScreen<Cubit, CrudState> {
|
||||||
|
const CrudCubitScreenBase();
|
||||||
|
Widget errorBuilder(BuildContext context, CrudError state) =>
|
||||||
|
context.components.errorWidget?.configure(error: state.message) ??
|
||||||
|
const SizedBox.shrink();
|
||||||
|
|
||||||
|
Widget loadingBuilder(BuildContext context, CrudLoading state) =>
|
||||||
|
context.components.loadingWidget ?? const SizedBox.shrink();
|
||||||
|
|
||||||
|
Widget initialBuilder(BuildContext context, CrudInitial state) =>
|
||||||
|
const SizedBox.shrink();
|
||||||
|
|
||||||
|
Widget successBuilder(BuildContext context, SuccessState state);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget onBuild(BuildContext context, CrudState state) =>
|
||||||
|
CrudBuilder<CrudInitial, CrudLoading, SuccessState, CrudError>(
|
||||||
|
errorBuilder: errorBuilder,
|
||||||
|
loadingBuilder: loadingBuilder,
|
||||||
|
initialBuilder: initialBuilder,
|
||||||
|
state: state,
|
||||||
|
builder: successBuilder,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class CrudCubitScreen<Cubit extends bloc_base.Cubit<CrudState>, T>
|
||||||
|
extends CrudCubitScreenBase<Cubit, CrudLoaded<T>> {
|
||||||
|
const CrudCubitScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class CrudListCubitScreen<Cubit extends bloc_base.Cubit<CrudState>, T>
|
||||||
|
extends CrudCubitScreenBase<Cubit, CrudListLoaded<T>> {
|
||||||
|
const CrudListCubitScreen();
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
// 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:flutter/src/widgets/framework.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart' as bloc_base;
|
||||||
|
import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart';
|
||||||
|
|
||||||
|
abstract class FrameLayoutCrudScreen<Cubit extends bloc_base.Cubit<CrudState>,
|
||||||
|
T> extends CrudCubitScreen<Cubit, T> {
|
||||||
|
final String? title;
|
||||||
|
final int? currentIndex;
|
||||||
|
|
||||||
|
const FrameLayoutCrudScreen({
|
||||||
|
this.title,
|
||||||
|
this.currentIndex,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget parent(BuildContext context, Widget child) => FrameLayout(
|
||||||
|
title: title ?? 'Title',
|
||||||
|
body: child,
|
||||||
|
currentIndex: currentIndex ?? 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class FrameLayoutCrudListScreen<
|
||||||
|
Cubit extends bloc_base.Cubit<CrudState>,
|
||||||
|
T> extends CrudListCubitScreen<Cubit, T> {
|
||||||
|
final String? title;
|
||||||
|
final int? currentIndex;
|
||||||
|
|
||||||
|
const FrameLayoutCrudListScreen({
|
||||||
|
this.title,
|
||||||
|
this.currentIndex,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget parent(BuildContext context, Widget child) => FrameLayout(
|
||||||
|
title: title ?? 'Title',
|
||||||
|
body: child,
|
||||||
|
currentIndex: currentIndex ?? 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -14,13 +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/>.
|
||||||
|
|
||||||
library prompt.framework;
|
export 'presentation/presentation.dart';
|
||||||
|
|
||||||
import 'dart:io';
|
export 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:meta/meta.dart';
|
export 'package:wyatt_ui_components/wyatt_wyatt_ui_components.dart';
|
||||||
import 'package:wyatt_cli_toolbox/src/sequences/sequences.dart';
|
export 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart';
|
||||||
import 'package:wyatt_cli_toolbox/src/stylish/stylish.dart';
|
export 'package:wyatt_ui_layout/wyatt_wyatt_ui_layout.dart';
|
||||||
|
export 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart';
|
||||||
part 'build_context.dart';
|
|
||||||
part 'state.dart';
|
|
||||||
part 'widget.dart';
|
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// 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/>.
|
||||||
|
|
||||||
|
/// Bloc Layout
|
||||||
|
library wyatt_bloc_layout;
|
||||||
|
|
||||||
|
export 'src/src.dart';
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
name: wyatt_bloc_layout
|
||||||
|
description: Layouts based on bloc helper library
|
||||||
|
repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_bloc_layout
|
||||||
|
version: 0.0.1
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: '>=2.17.0 <3.0.0'
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
|
||||||
|
flutter:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
|
wyatt_bloc_helper:
|
||||||
|
git:
|
||||||
|
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
|
||||||
|
path: packages/wyatt_bloc_helper
|
||||||
|
|
||||||
|
wyatt_ui_layout:
|
||||||
|
git:
|
||||||
|
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
|
||||||
|
path: packages/wyatt_ui_layout
|
||||||
|
|
||||||
|
wyatt_crud_bloc:
|
||||||
|
git:
|
||||||
|
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
|
||||||
|
path: packages/wyatt_crud_bloc
|
||||||
|
|
||||||
|
wyatt_ui_components:
|
||||||
|
git:
|
||||||
|
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
|
||||||
|
path: packages/wyatt_ui_components
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
|
||||||
|
flutter_test:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
|
|
||||||
|
wyatt_analysis:
|
||||||
|
git:
|
||||||
|
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
|
||||||
|
ref: wyatt_analysis-v2.3.0
|
||||||
|
path: packages/wyatt_analysis
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
# Files and directories created by pub.
|
|
||||||
.dart_tool/
|
|
||||||
.packages
|
|
||||||
|
|
||||||
# Conventional directory for build outputs.
|
|
||||||
build/
|
|
||||||
|
|
||||||
# Omit committing pubspec.lock for library packages; see
|
|
||||||
# https://dart.dev/guides/libraries/private-files#pubspeclock.
|
|
||||||
pubspec.lock
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
## 1.0.0
|
|
||||||
|
|
||||||
- Initial version.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
include: package:wyatt_analysis/analysis_options.yaml
|
|
||||||
@@ -1,273 +0,0 @@
|
|||||||
// Copyright (C) 2022 WYATT GROUP
|
|
||||||
// Please see the AUTHORS file for details.
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import 'dart:io';
|
|
||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:wyatt_cli_toolbox/wyatt_cli_toolbox.dart';
|
|
||||||
|
|
||||||
void testStylish() {
|
|
||||||
print('my beautiful text in magenta'.magenta());
|
|
||||||
print('you can combine multiple styles'.yellow().bgBlue().bold());
|
|
||||||
|
|
||||||
print('\x1B[36mstart style');
|
|
||||||
print('style continues on this line');
|
|
||||||
print('but not on this line'.reset());
|
|
||||||
|
|
||||||
print('\x1B[41mnot stripped\x1B[49m');
|
|
||||||
print('\x1B[41mstripped\x1B[49m'.strip());
|
|
||||||
|
|
||||||
Stylish.config(enable: false);
|
|
||||||
print('you can disable extension'.fg(r: 20, g: 160, b: 80));
|
|
||||||
Stylish.config(enable: true);
|
|
||||||
print('and reenable it on the fly'.fg(r: 20, g: 160, b: 80));
|
|
||||||
print('custom bg color'.bg(r: 80, g: 110, b: 30));
|
|
||||||
}
|
|
||||||
|
|
||||||
void testSequences() {
|
|
||||||
Sequences.clearEntireScreen();
|
|
||||||
print('Clear entire screen');
|
|
||||||
|
|
||||||
print('Hide cursor');
|
|
||||||
Sequences.hideCursor();
|
|
||||||
sleep(Duration(seconds: 1));
|
|
||||||
print('Unhide cursor');
|
|
||||||
Sequences.unhideCursor();
|
|
||||||
sleep(Duration(seconds: 1));
|
|
||||||
|
|
||||||
print('Save cursor position');
|
|
||||||
Sequences.savePosition();
|
|
||||||
sleep(Duration(seconds: 1));
|
|
||||||
|
|
||||||
print('Move cursor');
|
|
||||||
Sequences.moveCursor(6, 3);
|
|
||||||
sleep(Duration(seconds: 1));
|
|
||||||
|
|
||||||
Sequences.restorePosition();
|
|
||||||
Sequences.moveDown(1);
|
|
||||||
sleep(Duration(seconds: 1));
|
|
||||||
print('Restore cursor position');
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> testSpinners() async {
|
|
||||||
print('Starting computation 1...');
|
|
||||||
await Spinner.start(SpinnerType.fistBump);
|
|
||||||
sleep(Duration(seconds: 2));
|
|
||||||
Spinner.stop();
|
|
||||||
|
|
||||||
print('Starting computation 2...');
|
|
||||||
await Spinner.start(SpinnerType.dots5, text: 'Loading...');
|
|
||||||
sleep(Duration(seconds: 3));
|
|
||||||
Spinner.stop();
|
|
||||||
|
|
||||||
print('Starting computation 3...');
|
|
||||||
await Spinner.custom(
|
|
||||||
Indicator(
|
|
||||||
name: 'Eyes',
|
|
||||||
interval: 100,
|
|
||||||
frames: <String>['◡◡', '⊙⊙', '◠◠']
|
|
||||||
.map<String>((String e) => '\x1B[36m$e\x1B[39m')
|
|
||||||
.toList(),
|
|
||||||
label: 'Computing...',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
await Future<void>.delayed(Duration(seconds: 2));
|
|
||||||
Spinner.stop();
|
|
||||||
|
|
||||||
print('Starting computation 4...');
|
|
||||||
await Spinner.start(SpinnerType.pipe, text: 'Linking...');
|
|
||||||
sleep(Duration(seconds: 3));
|
|
||||||
Spinner.update(
|
|
||||||
SpinnerType.circle.indicator.copyWith(label: 'Compiling...'),
|
|
||||||
);
|
|
||||||
sleep(Duration(seconds: 3));
|
|
||||||
Spinner.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
void testPrompt() {
|
|
||||||
final Prompt pr = Prompt();
|
|
||||||
final StringQuestion q1 = StringQuestion(
|
|
||||||
"What's your name ?",
|
|
||||||
identifier: 'name',
|
|
||||||
);
|
|
||||||
final PasswordQuestion q8 = PasswordQuestion(
|
|
||||||
'Password ?',
|
|
||||||
comment: 'Secret shhht.',
|
|
||||||
identifier: 'password',
|
|
||||||
);
|
|
||||||
final NumberQuestion q7 = NumberQuestion(
|
|
||||||
'How old are you?',
|
|
||||||
identifier: 'age',
|
|
||||||
);
|
|
||||||
final BooleanQuestion q2 = BooleanQuestion(
|
|
||||||
'Do you like Dart ?',
|
|
||||||
identifier: 'dart',
|
|
||||||
);
|
|
||||||
final ListQuestion q3 = ListQuestion(
|
|
||||||
'Which target ?',
|
|
||||||
<String>['android', 'ios', 'windows', 'macos'],
|
|
||||||
identifier: 'platform',
|
|
||||||
);
|
|
||||||
final Message q4 = Message(
|
|
||||||
'Oh oh !',
|
|
||||||
level: MessageLevel.warn,
|
|
||||||
identifier: 'warn',
|
|
||||||
);
|
|
||||||
final Message q5 = Message(
|
|
||||||
'Oh damn :(',
|
|
||||||
level: MessageLevel.fail,
|
|
||||||
identifier: 'error',
|
|
||||||
);
|
|
||||||
final Message q6 = Message(
|
|
||||||
'Thank you, bye! 🤙',
|
|
||||||
comment: 'Pretty comment nah?',
|
|
||||||
identifier: 'bye',
|
|
||||||
);
|
|
||||||
|
|
||||||
pr
|
|
||||||
..addAll(<Question<dynamic>>[q1, q8, q7, q2, q3, q4, q5, q6])
|
|
||||||
..ask();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> testWorkflow() async {
|
|
||||||
final Task<int> t1 = Task<int>(
|
|
||||||
name: 'Analyzing',
|
|
||||||
id: 'analyze',
|
|
||||||
spinner: SpinnerType.circle,
|
|
||||||
task: () {
|
|
||||||
return waitFor<int>(
|
|
||||||
Future<int>.delayed(Duration(seconds: 3), () => 13),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
onFinish: (Object? i) {
|
|
||||||
return '$i files analyzed';
|
|
||||||
},
|
|
||||||
);
|
|
||||||
final Task<int> t2 = Task<int>(
|
|
||||||
name: 'Formatting',
|
|
||||||
id: 'format',
|
|
||||||
spinner: SpinnerType.circle,
|
|
||||||
task: () {
|
|
||||||
return waitFor<int>(
|
|
||||||
Future<int>.delayed(Duration(seconds: 4), () => 1287),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
onFinish: (Object? i) {
|
|
||||||
return '$i files modified';
|
|
||||||
},
|
|
||||||
);
|
|
||||||
final Task<void> t3 = Task<void>(
|
|
||||||
name: 'Building',
|
|
||||||
id: 'build',
|
|
||||||
task: () {
|
|
||||||
final List<String> _tasks = <String>[
|
|
||||||
'main.c',
|
|
||||||
'crypto.c',
|
|
||||||
'workflow.c',
|
|
||||||
'wyatt.c',
|
|
||||||
'logger.c',
|
|
||||||
'task.c',
|
|
||||||
];
|
|
||||||
for (final String i in _tasks) {
|
|
||||||
Task.print(i);
|
|
||||||
sleep(Duration(seconds: Random().nextInt(4) + 1));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onFinish: (_) {
|
|
||||||
return 'Compilation success';
|
|
||||||
},
|
|
||||||
);
|
|
||||||
final Task<void> t4 = Task<void>(
|
|
||||||
name: 'Testing',
|
|
||||||
id: 'test',
|
|
||||||
task: () {
|
|
||||||
final List<String> _tasks = <String>[
|
|
||||||
'wyatt.h',
|
|
||||||
'crypto.h',
|
|
||||||
];
|
|
||||||
for (final String i in _tasks) {
|
|
||||||
Task.print(i);
|
|
||||||
sleep(Duration(seconds: Random().nextInt(3)));
|
|
||||||
}
|
|
||||||
throw Exception('An error occured during ${'test::crypto.h'.red()}');
|
|
||||||
},
|
|
||||||
onFinish: (_) {
|
|
||||||
return 'All tests passed';
|
|
||||||
},
|
|
||||||
onError: (Object e) {
|
|
||||||
return e.toString();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
final Task<void> t5 = Task<void>(
|
|
||||||
name: 'Bundling',
|
|
||||||
id: 'bundle',
|
|
||||||
task: () {
|
|
||||||
sleep(Duration(seconds: 3));
|
|
||||||
throw SkipException('Bundle skipped.');
|
|
||||||
},
|
|
||||||
onFinish: (_) {
|
|
||||||
return 'Files generated in dist/';
|
|
||||||
},
|
|
||||||
onSkip: (SkipException e) {
|
|
||||||
return e.toString();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
final Workflow w = await Workflow.create(<Task<dynamic>>[t1, t2, t3, t4, t5]);
|
|
||||||
w.start();
|
|
||||||
|
|
||||||
print('\n${w.results.toString().dim()}');
|
|
||||||
}
|
|
||||||
|
|
||||||
void testNewPrompt() {
|
|
||||||
final name = Input(message: 'Your name').prompt();
|
|
||||||
stdout.writeln(name);
|
|
||||||
|
|
||||||
final email = Input(
|
|
||||||
message: 'Your email',
|
|
||||||
validator: (String x) {
|
|
||||||
if (x.contains('@')) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
throw ValidationError('Not a valid email');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
).prompt();
|
|
||||||
stdout.writeln(email);
|
|
||||||
|
|
||||||
final planet = Input(
|
|
||||||
message: 'Your planet',
|
|
||||||
defaultValue: 'Earth',
|
|
||||||
).prompt();
|
|
||||||
stdout.writeln(planet);
|
|
||||||
|
|
||||||
final galaxy = Input(
|
|
||||||
message: 'Your galaxy',
|
|
||||||
initialValue: 'Andromeda',
|
|
||||||
).prompt();
|
|
||||||
stdout.writeln(galaxy);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> main() async {
|
|
||||||
// sleep(Duration(seconds: 2));
|
|
||||||
// testPrompt();
|
|
||||||
// await testWorkflow();
|
|
||||||
// testStylish();
|
|
||||||
// testSequences();
|
|
||||||
// await testSpinners();
|
|
||||||
// testPrompt();
|
|
||||||
testNewPrompt();
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
// Copyright (C) 2022 WYATT GROUP
|
|
||||||
// Please see the AUTHORS file for details.
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:wyatt_cli_toolbox/src/prompt/question.dart';
|
|
||||||
import 'package:wyatt_cli_toolbox/src/sequences/sequences.dart';
|
|
||||||
import 'package:wyatt_cli_toolbox/src/stylish/stylish.dart';
|
|
||||||
|
|
||||||
class BooleanQuestion extends Question<bool> {
|
|
||||||
BooleanQuestion(
|
|
||||||
String question, {
|
|
||||||
this.defaultTo = false,
|
|
||||||
String? comment,
|
|
||||||
required String identifier,
|
|
||||||
}) : super(QuestionType.booleanQuestion, identifier, question, comment);
|
|
||||||
|
|
||||||
bool? answer;
|
|
||||||
final bool defaultTo;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String formatComment() => (super.formatComment().trim().isEmpty)
|
|
||||||
? defaultTo
|
|
||||||
? ' (Y/n) '.dim()
|
|
||||||
: ' (y/N) '.dim()
|
|
||||||
: super.formatComment();
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool ask() {
|
|
||||||
stdout.write(formatQuestion());
|
|
||||||
String input = '';
|
|
||||||
input = stdin.readLineSync(encoding: utf8)!.trim();
|
|
||||||
stdout.write(Sequences.escMoveUp(1) + formatQuestion());
|
|
||||||
if (input.isEmpty) {
|
|
||||||
answer = defaultTo;
|
|
||||||
} else {
|
|
||||||
answer = input[0] == 'y' || input[0] == 'Y';
|
|
||||||
}
|
|
||||||
String replaceStr =
|
|
||||||
'\r${formatQuestion()}${Sequences.escClearLineFromCursorToEnd()}';
|
|
||||||
replaceStr += answer! ? 'Yes'.blue() : 'No'.blue();
|
|
||||||
stdout.writeln(replaceStr);
|
|
||||||
|
|
||||||
return answer!;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
// Copyright (C) 2022 WYATT GROUP
|
|
||||||
// Please see the AUTHORS file for details.
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:wyatt_cli_toolbox/src/sequences/sequences.dart';
|
|
||||||
import 'package:wyatt_cli_toolbox/src/stylish/stylish.dart';
|
|
||||||
|
|
||||||
/// Abstract class providing XTerm escape sequences
|
|
||||||
abstract class Control {
|
|
||||||
/// Use Squences.escMoveUp, concatenate your string ([str])
|
|
||||||
/// and then blank the remaining line.
|
|
||||||
static String replacePreviousLine(String str) =>
|
|
||||||
Sequences.escMoveUp(1) + str + Sequences.escClearLineFromCursorToEnd();
|
|
||||||
|
|
||||||
/// Reset XTerm sequence.
|
|
||||||
/// This is always applied after using some other sequence.
|
|
||||||
static String reset = ''.reset();
|
|
||||||
|
|
||||||
/// See: https://codepoints.net/dingbats
|
|
||||||
static String questionIndicator() => '?'.green();
|
|
||||||
|
|
||||||
static String exclamationIndicator() => '!'.yellow();
|
|
||||||
|
|
||||||
static String infoIndicator() =>
|
|
||||||
Platform.isWindows ? 'i'.cyan() : '\u2139'.cyan();
|
|
||||||
|
|
||||||
static String rightIndicator() =>
|
|
||||||
Platform.isWindows ? '>'.blue() : '\u276F'.blue();
|
|
||||||
|
|
||||||
static String validIndicator() =>
|
|
||||||
Platform.isWindows ? 'v'.green() : '\u2714'.green();
|
|
||||||
|
|
||||||
static String wrongIndicator() =>
|
|
||||||
Platform.isWindows ? 'x'.red() : '\u2718'.red();
|
|
||||||
}
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
// Copyright (C) 2022 WYATT GROUP
|
|
||||||
// Please see the AUTHORS file for details.
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
part of prompt.framework;
|
|
||||||
|
|
||||||
class BuildContext {
|
|
||||||
int _buildCount = 0;
|
|
||||||
int get buildCount => _buildCount;
|
|
||||||
void incrementBuildCount() => _buildCount++;
|
|
||||||
void resetBuildCount() => _buildCount = 0;
|
|
||||||
|
|
||||||
int _lineCount = 0;
|
|
||||||
int get lineCount => _lineCount;
|
|
||||||
void incrementLineCount() => _lineCount++;
|
|
||||||
void resetLineCount() => _lineCount = 0;
|
|
||||||
|
|
||||||
static void reset() {
|
|
||||||
Sequences.unhideCursor();
|
|
||||||
Sequences.write(''.reset());
|
|
||||||
}
|
|
||||||
|
|
||||||
void hideCursor() {
|
|
||||||
Sequences.hideCursor();
|
|
||||||
}
|
|
||||||
|
|
||||||
void showCursor() {
|
|
||||||
Sequences.unhideCursor();
|
|
||||||
}
|
|
||||||
|
|
||||||
void write(String text) {
|
|
||||||
Sequences.write(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void writeln(String text) {
|
|
||||||
incrementLineCount();
|
|
||||||
Sequences.writeln(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void erasePreviousLine([int n = 1]) {
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
Sequences.moveUp(1);
|
|
||||||
Sequences.clearEntireLine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void wipe() {
|
|
||||||
erasePreviousLine(lineCount);
|
|
||||||
resetLineCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
int readKey() => stdin.readByteSync();
|
|
||||||
|
|
||||||
String readLine({
|
|
||||||
String initialValue = '',
|
|
||||||
}) {
|
|
||||||
var buffer = initialValue;
|
|
||||||
var index = buffer.length;
|
|
||||||
|
|
||||||
Sequences.savePosition();
|
|
||||||
|
|
||||||
if (buffer.isNotEmpty) {
|
|
||||||
write(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
final key = readKey();
|
|
||||||
if (index == buffer.length) {
|
|
||||||
buffer += String.fromCharCode(key);
|
|
||||||
index++;
|
|
||||||
} else {
|
|
||||||
buffer = buffer.substring(0, index) +
|
|
||||||
String.fromCharCode(key) +
|
|
||||||
buffer.substring(index);
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sequences.restorePosition();
|
|
||||||
Sequences.clearLineFromCursorToEnd();
|
|
||||||
write(buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,150 +0,0 @@
|
|||||||
// 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 'dart:io';
|
|
||||||
|
|
||||||
import 'package:wyatt_cli_toolbox/src/spinners/spinners.dart';
|
|
||||||
import 'package:wyatt_cli_toolbox/src/stylish/stylish.dart';
|
|
||||||
|
|
||||||
typedef StyleFunction = String Function(String);
|
|
||||||
|
|
||||||
class Theme {
|
|
||||||
final String inputPrefix;
|
|
||||||
final String inputSuffix;
|
|
||||||
final String successPrefix;
|
|
||||||
final String successSuffix;
|
|
||||||
final String errorPrefix;
|
|
||||||
final String hiddenPrefix;
|
|
||||||
final StyleFunction messageStyle;
|
|
||||||
final StyleFunction errorStyle;
|
|
||||||
final StyleFunction hintStyle;
|
|
||||||
final StyleFunction valueStyle;
|
|
||||||
final StyleFunction defaultStyle;
|
|
||||||
|
|
||||||
final String activeItemPrefix;
|
|
||||||
final String inactiveItemPrefix;
|
|
||||||
final StyleFunction activeItemStyle;
|
|
||||||
final StyleFunction inactiveItemStyle;
|
|
||||||
|
|
||||||
final String checkedItemPrefix;
|
|
||||||
final String uncheckedItemPrefix;
|
|
||||||
|
|
||||||
final String pickedItemPrefix;
|
|
||||||
final String unpickedItemPrefix;
|
|
||||||
|
|
||||||
final bool showActiveCursor;
|
|
||||||
|
|
||||||
final SpinnerType spinner;
|
|
||||||
|
|
||||||
const Theme({
|
|
||||||
required this.inputPrefix,
|
|
||||||
required this.inputSuffix,
|
|
||||||
required this.successPrefix,
|
|
||||||
required this.successSuffix,
|
|
||||||
required this.errorPrefix,
|
|
||||||
required this.hiddenPrefix,
|
|
||||||
required this.messageStyle,
|
|
||||||
required this.errorStyle,
|
|
||||||
required this.hintStyle,
|
|
||||||
required this.valueStyle,
|
|
||||||
required this.defaultStyle,
|
|
||||||
required this.activeItemPrefix,
|
|
||||||
required this.inactiveItemPrefix,
|
|
||||||
required this.activeItemStyle,
|
|
||||||
required this.inactiveItemStyle,
|
|
||||||
required this.checkedItemPrefix,
|
|
||||||
required this.uncheckedItemPrefix,
|
|
||||||
required this.pickedItemPrefix,
|
|
||||||
required this.unpickedItemPrefix,
|
|
||||||
required this.showActiveCursor,
|
|
||||||
required this.spinner,
|
|
||||||
});
|
|
||||||
|
|
||||||
Theme copyWith({
|
|
||||||
String? inputPrefix,
|
|
||||||
String? inputSuffix,
|
|
||||||
String? successPrefix,
|
|
||||||
String? successSuffix,
|
|
||||||
String? errorPrefix,
|
|
||||||
String? hiddenPrefix,
|
|
||||||
StyleFunction? messageStyle,
|
|
||||||
StyleFunction? errorStyle,
|
|
||||||
StyleFunction? hintStyle,
|
|
||||||
StyleFunction? valueStyle,
|
|
||||||
StyleFunction? defaultStyle,
|
|
||||||
String? activeItemPrefix,
|
|
||||||
String? inactiveItemPrefix,
|
|
||||||
StyleFunction? activeItemStyle,
|
|
||||||
StyleFunction? inactiveItemStyle,
|
|
||||||
String? checkedItemPrefix,
|
|
||||||
String? uncheckedItemPrefix,
|
|
||||||
String? pickedItemPrefix,
|
|
||||||
String? unpickedItemPrefix,
|
|
||||||
bool? showActiveCursor,
|
|
||||||
SpinnerType? spinner,
|
|
||||||
}) {
|
|
||||||
return Theme(
|
|
||||||
inputPrefix: inputPrefix ?? this.inputPrefix,
|
|
||||||
inputSuffix: inputSuffix ?? this.inputSuffix,
|
|
||||||
successPrefix: successPrefix ?? this.successPrefix,
|
|
||||||
successSuffix: successSuffix ?? this.successSuffix,
|
|
||||||
errorPrefix: errorPrefix ?? this.errorPrefix,
|
|
||||||
hiddenPrefix: hiddenPrefix ?? this.hiddenPrefix,
|
|
||||||
messageStyle: messageStyle ?? this.messageStyle,
|
|
||||||
errorStyle: errorStyle ?? this.errorStyle,
|
|
||||||
hintStyle: hintStyle ?? this.hintStyle,
|
|
||||||
valueStyle: valueStyle ?? this.valueStyle,
|
|
||||||
defaultStyle: defaultStyle ?? this.defaultStyle,
|
|
||||||
activeItemPrefix: activeItemPrefix ?? this.activeItemPrefix,
|
|
||||||
inactiveItemPrefix: inactiveItemPrefix ?? this.inactiveItemPrefix,
|
|
||||||
activeItemStyle: activeItemStyle ?? this.activeItemStyle,
|
|
||||||
inactiveItemStyle: inactiveItemStyle ?? this.inactiveItemStyle,
|
|
||||||
checkedItemPrefix: checkedItemPrefix ?? this.checkedItemPrefix,
|
|
||||||
uncheckedItemPrefix: uncheckedItemPrefix ?? this.uncheckedItemPrefix,
|
|
||||||
pickedItemPrefix: pickedItemPrefix ?? this.pickedItemPrefix,
|
|
||||||
unpickedItemPrefix: unpickedItemPrefix ?? this.unpickedItemPrefix,
|
|
||||||
showActiveCursor: showActiveCursor ?? this.showActiveCursor,
|
|
||||||
spinner: spinner ?? this.spinner,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Theme defaultTheme = colorfulTheme;
|
|
||||||
|
|
||||||
static final colorfulTheme = Theme(
|
|
||||||
inputPrefix: '?'.padRight(2).green(),
|
|
||||||
inputSuffix: (Platform.isWindows ? '>' : '\u276F').padLeft(2).grey(),
|
|
||||||
successPrefix: (Platform.isWindows ? 'v' : '\u2714').padRight(2).green(),
|
|
||||||
successSuffix: '•'.padLeft(2).grey(),
|
|
||||||
errorPrefix: (Platform.isWindows ? 'x' : '\u2718').padRight(2).red(),
|
|
||||||
hiddenPrefix: '*****',
|
|
||||||
messageStyle: (String message) => message.bold(),
|
|
||||||
errorStyle: (String error) => error.red(),
|
|
||||||
hintStyle: (String hint) => '($hint)'.grey(),
|
|
||||||
valueStyle: (String value) => value.green(),
|
|
||||||
defaultStyle: (String value) => value.cyan(),
|
|
||||||
activeItemPrefix: (Platform.isWindows ? '>' : '\u276F').green(),
|
|
||||||
inactiveItemPrefix: ' ',
|
|
||||||
activeItemStyle: (String item) => item.cyan(),
|
|
||||||
inactiveItemStyle: (String item) => item,
|
|
||||||
checkedItemPrefix: (Platform.isWindows ? 'v' : '\u2714').green(),
|
|
||||||
uncheckedItemPrefix: ' ',
|
|
||||||
pickedItemPrefix: (Platform.isWindows ? '>' : '\u276F').green(),
|
|
||||||
unpickedItemPrefix: ' ',
|
|
||||||
showActiveCursor: false,
|
|
||||||
spinner: SpinnerType.arrow,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
// Copyright (C) 2022 WYATT GROUP
|
|
||||||
// Please see the AUTHORS file for details.
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
part of prompt.framework;
|
|
||||||
|
|
||||||
abstract class Widget<T extends dynamic> {
|
|
||||||
int _initLineCount = 0;
|
|
||||||
|
|
||||||
/// Creates the mutable state for this widget
|
|
||||||
@protected
|
|
||||||
@factory
|
|
||||||
State createState();
|
|
||||||
|
|
||||||
State pipeState(State state) => state;
|
|
||||||
|
|
||||||
T prompt() {
|
|
||||||
final state = pipeState(createState())
|
|
||||||
.._widget = this
|
|
||||||
..initState();
|
|
||||||
_initLineCount = state.context.lineCount;
|
|
||||||
state.context.resetLineCount();
|
|
||||||
|
|
||||||
state.build();
|
|
||||||
state.context.incrementBuildCount();
|
|
||||||
|
|
||||||
final dynamic out = state.prompt();
|
|
||||||
state.context.wipe();
|
|
||||||
state.context.erasePreviousLine(_initLineCount);
|
|
||||||
state.dispose();
|
|
||||||
|
|
||||||
return out as T;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
// Copyright (C) 2022 WYATT GROUP
|
|
||||||
// Please see the AUTHORS file for details.
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
// ignore_for_file: constant_identifier_names
|
|
||||||
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
const int ARROW_UP = 65;
|
|
||||||
const int ARROW_DOWN = 66;
|
|
||||||
const int ENTER = 10;
|
|
||||||
const int SPACE = 32;
|
|
||||||
|
|
||||||
const int WIN_UP = 119;
|
|
||||||
const int WIN_DOWN = 115;
|
|
||||||
const int WIN_ENTER = 13;
|
|
||||||
const int WIN_SPACE = 20;
|
|
||||||
|
|
||||||
/// Abstract class providing some key codes which can be statically accessed.
|
|
||||||
abstract class Keys {
|
|
||||||
/// Arrow down. Consists of three bytes.
|
|
||||||
/// For historical reasons, you can also use 's'
|
|
||||||
/// instead of arrow down on Windows.
|
|
||||||
///
|
|
||||||
/// It is packed into a single element list in
|
|
||||||
/// order to not break the spread syntax.
|
|
||||||
static final List<int> arrowDown =
|
|
||||||
Platform.isWindows ? <int>[WIN_DOWN] : <int>[27, 91, 66];
|
|
||||||
|
|
||||||
/// Arrows up. Consists of three bytes in Unix like systems (including MacOS).
|
|
||||||
/// For historical reasons, you can also use 'w' insted of arrow
|
|
||||||
/// up on Windows.
|
|
||||||
///
|
|
||||||
/// It is packed into a single element list in
|
|
||||||
/// order to not break the spread syntax.
|
|
||||||
static final List<int> arrowUp =
|
|
||||||
Platform.isWindows ? <int>[WIN_UP] : <int>[27, 91, 65];
|
|
||||||
|
|
||||||
/// Enter key. Single byte.
|
|
||||||
static final int enter = Platform.isWindows ? WIN_ENTER : ENTER;
|
|
||||||
|
|
||||||
/// Space key. Single byte.
|
|
||||||
static final int space = Platform.isWindows ? WIN_SPACE : SPACE;
|
|
||||||
}
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
// Copyright (C) 2022 WYATT GROUP
|
|
||||||
// Please see the AUTHORS file for details.
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:wyatt_cli_toolbox/src/prompt/control.dart';
|
|
||||||
import 'package:wyatt_cli_toolbox/src/prompt/keys.dart';
|
|
||||||
import 'package:wyatt_cli_toolbox/src/sequences/sequences.dart';
|
|
||||||
import 'package:wyatt_cli_toolbox/src/stylish/stylish.dart';
|
|
||||||
|
|
||||||
class ListChooser {
|
|
||||||
ListChooser(this.options) {
|
|
||||||
if (stdin.hasTerminal) {
|
|
||||||
// lineMode must be true to set echoMode in Windows
|
|
||||||
// see https://github.com/dart-lang/sdk/issues/28599
|
|
||||||
stdin.echoMode = false;
|
|
||||||
stdin.lineMode = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> options;
|
|
||||||
|
|
||||||
String choose() {
|
|
||||||
int input;
|
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
_renderList(0, initial: true);
|
|
||||||
|
|
||||||
while ((input = _userInput()) != ENTER) {
|
|
||||||
if (input == ARROW_UP) {
|
|
||||||
if (index > 0) {
|
|
||||||
index--;
|
|
||||||
}
|
|
||||||
} else if (input == ARROW_DOWN) {
|
|
||||||
if (index < options.length - 1) {
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_renderList(index);
|
|
||||||
}
|
|
||||||
_resetStdin();
|
|
||||||
return options[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
void _deletePreviousList() {
|
|
||||||
for (int i = 0; i < options.length; i++) {
|
|
||||||
Sequences.write(
|
|
||||||
Sequences.escMoveUp(1) + Sequences.escClearLineFromCursorToEnd(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _renderList(int index, {bool initial = false}) {
|
|
||||||
if (!initial) {
|
|
||||||
_deletePreviousList();
|
|
||||||
}
|
|
||||||
for (int i = 0; i < options.length; i++) {
|
|
||||||
if (i == index) {
|
|
||||||
stdout.writeln('${Control.rightIndicator()} ${options[i].blue()}');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
stdout.writeln(' ${options[i]}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _resetStdin() {
|
|
||||||
if (stdin.hasTerminal) {
|
|
||||||
// Order is important here
|
|
||||||
stdin.lineMode = true;
|
|
||||||
stdin.echoMode = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(hpcl): improve keycode parsing for multiple bytes codes
|
|
||||||
int _userInput() {
|
|
||||||
final int navigationResult = stdin.readByteSync();
|
|
||||||
if (navigationResult < 0) {
|
|
||||||
return navigationResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Platform.isWindows) {
|
|
||||||
if (navigationResult == Keys.enter) {
|
|
||||||
return ENTER;
|
|
||||||
}
|
|
||||||
if (navigationResult == Keys.space) {
|
|
||||||
return SPACE;
|
|
||||||
}
|
|
||||||
if (navigationResult == Keys.arrowUp[0]) {
|
|
||||||
return ARROW_UP;
|
|
||||||
}
|
|
||||||
if (navigationResult == Keys.arrowDown[0]) {
|
|
||||||
return ARROW_DOWN;
|
|
||||||
} else {
|
|
||||||
return navigationResult;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (navigationResult == ENTER) {
|
|
||||||
return ENTER;
|
|
||||||
}
|
|
||||||
if (navigationResult == SPACE) {
|
|
||||||
return SPACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int anotherByte = stdin.readByteSync();
|
|
||||||
if (anotherByte == ENTER) {
|
|
||||||
return ENTER;
|
|
||||||
}
|
|
||||||
if (anotherByte == SPACE) {
|
|
||||||
return SPACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int input = stdin.readByteSync();
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
// Copyright (C) 2022 WYATT GROUP
|
|
||||||
// Please see the AUTHORS file for details.
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:wyatt_cli_toolbox/src/prompt/list_chooser.dart';
|
|
||||||
import 'package:wyatt_cli_toolbox/src/prompt/question.dart';
|
|
||||||
import 'package:wyatt_cli_toolbox/src/stylish/stylish.dart';
|
|
||||||
|
|
||||||
class ListQuestion extends Question<String> {
|
|
||||||
ListQuestion(
|
|
||||||
String question,
|
|
||||||
this.options, {
|
|
||||||
String? comment,
|
|
||||||
required String identifier,
|
|
||||||
}) : super(QuestionType.listQuestion, identifier, question, comment);
|
|
||||||
|
|
||||||
List<String> options;
|
|
||||||
String? answer;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String formatComment() => (super.formatComment().trim().isEmpty)
|
|
||||||
? ' (User arrow keys) '.dim()
|
|
||||||
: super.formatComment();
|
|
||||||
|
|
||||||
@override
|
|
||||||
String ask() {
|
|
||||||
stdout.writeln(formatQuestion());
|
|
||||||
final ListChooser chooser = ListChooser(options);
|
|
||||||
final String input = chooser.choose();
|
|
||||||
answer = input;
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
// Copyright (C) 2022 WYATT GROUP
|
|
||||||
// Please see the AUTHORS file for details.
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:wyatt_cli_toolbox/src/prompt/control.dart';
|
|
||||||
import 'package:wyatt_cli_toolbox/src/prompt/question.dart';
|
|
||||||
|
|
||||||
enum MessageLevel { debug, info, success, warn, fail }
|
|
||||||
|
|
||||||
class Message extends Question<void> {
|
|
||||||
Message(
|
|
||||||
String text, {
|
|
||||||
String? comment,
|
|
||||||
this.level = MessageLevel.info,
|
|
||||||
required String identifier,
|
|
||||||
}) : super(QuestionType.message, identifier, text, comment);
|
|
||||||
|
|
||||||
MessageLevel level;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get prefix {
|
|
||||||
switch (level) {
|
|
||||||
case MessageLevel.debug:
|
|
||||||
return ' ';
|
|
||||||
case MessageLevel.info:
|
|
||||||
return Control.infoIndicator();
|
|
||||||
case MessageLevel.success:
|
|
||||||
return Control.validIndicator();
|
|
||||||
case MessageLevel.warn:
|
|
||||||
return Control.exclamationIndicator();
|
|
||||||
case MessageLevel.fail:
|
|
||||||
return Control.wrongIndicator();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void ask() {
|
|
||||||
stdout.writeln(formatQuestion());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
// Copyright (C) 2022 WYATT GROUP
|
|
||||||
// Please see the AUTHORS file for details.
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:wyatt_cli_toolbox/src/prompt/question.dart';
|
|
||||||
import 'package:wyatt_cli_toolbox/src/sequences/sequences.dart';
|
|
||||||
import 'package:wyatt_cli_toolbox/src/stylish/stylish.dart';
|
|
||||||
|
|
||||||
class NumberQuestion extends Question<num> {
|
|
||||||
NumberQuestion(String question, {String? comment, required String identifier})
|
|
||||||
: super(QuestionType.stringQuestion, identifier, question, comment);
|
|
||||||
|
|
||||||
num? answer;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String formatComment() => (super.formatComment().trim().isEmpty)
|
|
||||||
? ' Mandatory! '.dim()
|
|
||||||
: super.formatComment();
|
|
||||||
|
|
||||||
@override
|
|
||||||
num ask() {
|
|
||||||
stdout.write(formatQuestion());
|
|
||||||
String input = '';
|
|
||||||
bool valid = false;
|
|
||||||
num answer = 0;
|
|
||||||
while (!valid) {
|
|
||||||
input = stdin.readLineSync(encoding: utf8)!.trim();
|
|
||||||
try {
|
|
||||||
valid = input.isNotEmpty;
|
|
||||||
answer = num.parse(input);
|
|
||||||
} catch (e) {
|
|
||||||
valid = false;
|
|
||||||
}
|
|
||||||
stdout.write(Sequences.escMoveUp(1) + formatQuestion());
|
|
||||||
}
|
|
||||||
stdout.writeln(
|
|
||||||
// ignore: lines_longer_than_80_chars
|
|
||||||
'\r${formatQuestion()}${answer.toString().blue()}${Sequences.escClearLineFromCursorToEnd()}',
|
|
||||||
);
|
|
||||||
return answer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
// Copyright (C) 2022 WYATT GROUP
|
|
||||||
// Please see the AUTHORS file for details.
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:wyatt_cli_toolbox/src/prompt/keys.dart';
|
|
||||||
import 'package:wyatt_cli_toolbox/src/prompt/question.dart';
|
|
||||||
import 'package:wyatt_cli_toolbox/src/sequences/sequences.dart';
|
|
||||||
import 'package:wyatt_cli_toolbox/src/stylish/stylish.dart';
|
|
||||||
|
|
||||||
class PasswordQuestion extends Question<String> {
|
|
||||||
PasswordQuestion(
|
|
||||||
String question, {
|
|
||||||
String? comment,
|
|
||||||
required String identifier,
|
|
||||||
}) : super(QuestionType.passwordQuestion, identifier, question, comment);
|
|
||||||
|
|
||||||
String? answer;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String ask() {
|
|
||||||
if (stdin.hasTerminal) {
|
|
||||||
stdin.echoMode = false;
|
|
||||||
stdin.lineMode = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
stdout.write(formatQuestion());
|
|
||||||
String input = '';
|
|
||||||
final List<int> bytes = <int>[];
|
|
||||||
|
|
||||||
int lastB = stdin.readByteSync();
|
|
||||||
while (lastB != Keys.enter) {
|
|
||||||
stdout.write('*');
|
|
||||||
bytes.add(lastB);
|
|
||||||
lastB = stdin.readByteSync();
|
|
||||||
}
|
|
||||||
input = utf8.decode(bytes);
|
|
||||||
stdout.write(formatQuestion());
|
|
||||||
answer = List<String>.generate(input.length, (_) => '*')
|
|
||||||
.reduce((String value, String element) => '$value$element');
|
|
||||||
stdout.writeln(
|
|
||||||
// ignore: lines_longer_than_80_chars
|
|
||||||
'\r${formatQuestion()}${answer!.blue()}${Sequences.escClearLineFromCursorToEnd()}',
|
|
||||||
);
|
|
||||||
|
|
||||||
if (stdin.hasTerminal) {
|
|
||||||
stdin.lineMode = true;
|
|
||||||
stdin.echoMode = true;
|
|
||||||
}
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
// Copyright (C) 2022 WYATT GROUP
|
|
||||||
// Please see the AUTHORS file for details.
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import 'package:wyatt_cli_toolbox/src/prompt/question.dart';
|
|
||||||
|
|
||||||
export 'boolean_question.dart';
|
|
||||||
export 'framework/framework.dart';
|
|
||||||
export 'framework/theme.dart';
|
|
||||||
export 'list_question.dart';
|
|
||||||
export 'message.dart';
|
|
||||||
export 'number_question.dart';
|
|
||||||
export 'password_question.dart';
|
|
||||||
export 'question.dart';
|
|
||||||
export 'string_question.dart';
|
|
||||||
export 'widgets/input.dart';
|
|
||||||
|
|
||||||
class Prompt {
|
|
||||||
Prompt({this.questions});
|
|
||||||
|
|
||||||
Map<String, dynamic> answers = <String, dynamic>{};
|
|
||||||
List<Question<dynamic>>? questions;
|
|
||||||
|
|
||||||
void add(Question<dynamic> question) {
|
|
||||||
if (questions != null) {
|
|
||||||
questions!.add(question);
|
|
||||||
} else {
|
|
||||||
questions = <Question<dynamic>>[question];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void addAll(List<Question<dynamic>> questions) {
|
|
||||||
if (this.questions != null) {
|
|
||||||
this.questions!.addAll(questions);
|
|
||||||
} else {
|
|
||||||
this.questions = questions;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> ask() {
|
|
||||||
if (questions != null) {
|
|
||||||
for (final Question<dynamic> question in questions!) {
|
|
||||||
if (!(question.type == QuestionType.message)) {
|
|
||||||
answers[question.identifier] = question.ask();
|
|
||||||
} else {
|
|
||||||
question.ask();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw Exception('You must add questions before asking for prompt.');
|
|
||||||
}
|
|
||||||
return answers;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
// Copyright (C) 2022 WYATT GROUP
|
|
||||||
// Please see the AUTHORS file for details.
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:wyatt_cli_toolbox/src/prompt/question.dart';
|
|
||||||
import 'package:wyatt_cli_toolbox/src/sequences/sequences.dart';
|
|
||||||
import 'package:wyatt_cli_toolbox/src/stylish/stylish.dart';
|
|
||||||
|
|
||||||
class StringQuestion extends Question<String> {
|
|
||||||
StringQuestion(String question, {String? comment, required String identifier})
|
|
||||||
: super(QuestionType.stringQuestion, identifier, question, comment);
|
|
||||||
|
|
||||||
String? answer;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String ask() {
|
|
||||||
stdout.write(formatQuestion());
|
|
||||||
String input = '';
|
|
||||||
input = stdin.readLineSync(encoding: utf8)!.trim();
|
|
||||||
stdout.write(Sequences.escMoveUp(1) + formatQuestion());
|
|
||||||
answer = input;
|
|
||||||
stdout.writeln(
|
|
||||||
// ignore: lines_longer_than_80_chars
|
|
||||||
'\r${formatQuestion()}${answer!.blue()}${Sequences.escClearLineFromCursorToEnd()}',
|
|
||||||
);
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
}
|
|
||||||