Compare commits

..
Author SHA1 Message Date
hugo b1d66dc6e4 chore(release): publish packages
continuous-integration/drone/push Build is passing
- wyatt_analysis@2.4.1
2023-02-24 10:20:00 +01:00
hugo 25cf9518f9 chore: fix all problems
continuous-integration/drone/push Build is passing
2023-02-24 10:12:04 +01:00
hugo 8d833d39d7 chore: fix and format using melos 2023-02-23 19:19:48 +01:00
hugo d098d9a6bf feat(analysis): add latest version persistence between script executions
continuous-integration/drone/push Build is passing
2023-02-23 18:53:03 +01:00
hugo 0f8c5bb983 ci(analysis): ignore script in publish (closes #124) 2023-02-23 18:52:27 +01:00
hugo 20f07a177b feat(analysis): ignore todo's 2023-02-23 18:50:17 +01:00
hugo 1a48b606a4 refactor(ui): replace ThemeResolver by ThemeHelper in Loader / RichTextBuilder (closes #148) 2023-02-23 18:27:17 +01:00
hugo 6c54689393 refactor(ui)!: remove bloc export in buttons to be state management solution agnostic (closes #147) 2023-02-23 16:59:56 +01:00
hugo d6c9dfd8a7 feat(ui_components): add extra state 2023-02-23 16:57:18 +01:00
hugo 881cbc5bef fix(ui): change example to be compatible with new AppTopBar and TextWrapper 2023-02-23 11:50:13 +01:00
malo 81c8851ac8 style(ui_components): remove useless comment
continuous-integration/drone/push Build is passing
2023-02-23 10:40:05 +01:00
malo 0c176ba0fa feat(ui_kit-ui_components): Modify the theme resolver to utilize the theme helper and streamline the logic 2023-02-23 10:24:54 +01:00
malo 970dde2ef1 feat(ui_kit): remove .raw call 2023-02-23 09:33:05 +01:00
malo 2e187b26eb feat(ui_kit): export ui kit as component theme data 2023-02-23 09:30:11 +01:00
malo 0337d4f97a feat(ui_components): make component theme data copyable 2023-02-23 09:29:46 +01:00
malo 3c3545abfe style(ui_kit): remove test style
continuous-integration/drone/push Build is passing
2023-02-22 19:29:39 +01:00
malo 2dfbd59773 feat(ui_kit): allow to cascade styles in ThemeHelper 2023-02-22 19:28:09 +01:00
malo 4a3fde3a1e feat(ui_kit): implement top nav bar
continuous-integration/drone/push Build is passing
2023-02-22 17:43:42 +01:00
malo 317eb56d66 refactor(ui_kit): adapt ui_kit 2023-02-22 16:13:07 +01:00
malo b9dac32143 refactor(ui_components): migrate top nav bar using generify top bar 2023-02-22 16:10:25 +01:00
malo 8955788fa5 feat(ui_components): generify bars 2023-02-22 16:05:40 +01:00
malo ca6af3ccc3 style(ui_components): clean folders and gather bars 2023-02-22 16:01:51 +01:00
malo ad0f1ec1c5 feat(ui_kit): implement top app bar and update example 2023-02-22 15:50:46 +01:00
malo 41a484c013 feat(ui_components): update attributs and proxy most of appbar attributs 2023-02-22 15:50:21 +01:00
malo 4811ed8998 feat(ui_components): add centerTitle property to app bar component 2023-02-22 11:37:29 +01:00
malo dba14088b0 style(ui_components): format imports 2023-02-22 11:25:22 +01:00
malo b2fe14a123 feat(ui_components): add top navigation bar component to theme data 2023-02-22 11:24:30 +01:00
malo bbd3f0a02d feat(ui_components): add Top Navigation Bar Component 2023-02-22 11:23:08 +01:00
malo 79dc34414c fix(ui_components): add loader to theme data (close #152)
continuous-integration/drone/push Build is passing
2023-02-22 00:02:26 +00:00
malo 349d1ae288 feat(ui_components): add new components to theme data (close #152) 2023-02-22 00:02:26 +00:00
malo 49b534d145 fix(ui_kit): fix tab action focus on textinputs
continuous-integration/drone/push Build is passing
2023-02-21 18:44:11 +01:00
hugo a68da15cdc feat(ui): add some useful text customization in TextWrapper (closes #149)
continuous-integration/drone/push Build is passing
2023-02-21 18:05:56 +01:00
hugo 6037e13f50 fix(ui_component): inverse merge in TextInputStyle
continuous-integration/drone/push Build is passing
2023-02-21 16:08:23 +01:00
hugo 93cc5058d1 refactor(ui_kit): use ThemeHelper in cards 2023-02-21 15:37:42 +01:00
hugo 12d04c91ed fix(ui): use multicolor in cards 2023-02-21 15:17:05 +01:00
hugo 5906d54aad build(ui_component): remove freezed 2023-02-21 15:08:24 +01:00
hugo b077f4baf0 refactor(ui_kit): rename GradientBoxBorder 2023-02-21 15:07:56 +01:00
malo 133e0e910b fix(ui_kit): make card core stateless 2023-02-21 13:34:04 +01:00
malo 25224469b5 fix(ui_components): fix MultiColor lerp method 2023-02-21 13:27:19 +01:00
malo 6537945946 fix(ui_kit): remove null check operator in RichTextBuilder component 2023-02-21 13:23:51 +01:00
malo 702164082a fix(ui_kit): remove null check operator in Loader component 2023-02-21 13:19:11 +01:00
malo f2b8c03dd7 refactor(ui_kit): update textinput component using borderColors as Color 2023-02-21 13:15:47 +01:00
malo 51672cc95a refactor(ui_components): move borderColors type 2023-02-21 13:13:01 +01:00
malo eda643e9b4 chore(ui_components): remove g files and copy with deps 2023-02-21 13:09:20 +01:00
malo cae4b68046 refactor(ui_components): add CopyWith method in ThemeStyle 2023-02-21 12:10:17 +01:00
malo 4030511f4a fix(ui_components-ui_kit): fix, clean and unify logic and code after rebase 2023-02-21 09:54:19 +01:00
malo 8ed8a71c7c fix(ui_kit): fix conflicts in card component after rebase 2023-02-21 08:53:38 +01:00
malo b6d22002ee fix(ui_kit): fix export theme file 2023-02-21 08:52:18 +01:00
malo 9b9339cb56 chore(ui_components): add copywith deps 2023-02-21 08:49:52 +01:00
malo b57500b854 feat(ui_kit): update example (#138) 2023-02-21 08:46:14 +01:00
malo 1edb1f7324 feat(ui_kit): implemement text inputs (#138) 2023-02-21 08:37:36 +01:00
malo edf72cf4c2 feat(ui_components):add text input components, theme extension and worked on utils (#138) 2023-02-21 08:36:58 +01:00
malo f6c16c5dc4 feat(ui_components): add isColor getter in multicolor helper 2023-02-21 08:35:12 +01:00
malo c6beae597b refactor(ui_components): update colors using Multicolor class (#138) 2023-02-21 08:35:12 +01:00
malo c2b60f2d79 feat(ui_kit): add text input theme extension (#138) 2023-02-21 08:35:12 +01:00
malo 1e8d5d088e chore(ui_components): export text inputs (#138) 2023-02-21 08:35:04 +01:00
malo 419c99c103 feat(ui_components): add text input abstract class (#138) 2023-02-21 08:32:38 +01:00
hugo 5387dd6eed build(ui_kit): use hosted version of bloc_helper
continuous-integration/drone/push Build is passing
2023-02-17 17:26:23 +01:00
hugo f67e4aa112 ci: use latest dart version in ci container
continuous-integration/drone/push Build is passing
2023-02-17 16:28:22 +01:00
hugo 2769d45e20 fix(ui_kit): fix text align, add selection and update example for rich text builder
continuous-integration/drone/push Build is failing
2023-02-17 15:57:54 +01:00
hugo 66719732f7 feat(ui_kit): implement rich text builder (closes #141) 2023-02-17 14:49:41 +01:00
hugo 25018dc78a feat(ui_component): add rich text builder / parser 2023-02-17 14:48:49 +01:00
hugo efeb3acff3 build(ui): optimize build runner 2023-02-17 14:48:23 +01:00
hugo ef52015372 refactor(ui): rework text gradient and text wrapper 2023-02-17 14:47:56 +01:00
hugo c5f8b69184 style(ui_kit): add example demo-page auto-generation
continuous-integration/drone/push Build is failing
2023-02-16 15:13:55 +01:00
hugo 33984b1733 feat(ui_kit): add loader implementation 2023-02-16 15:13:21 +01:00
hugo a47c28a4d6 feat(ui_component): add loader component and style 2023-02-16 15:12:40 +01:00
hugo 63bbde8213 refactor(ui_component): remove CopyWith extension 2023-02-16 15:12:18 +01:00
hugo 8070623e88 fix(ui_component): add generated component with theme resolver 2023-02-16 15:11:34 +01:00
hugo 4c08a692d2 refactor(ui_kit): move exportable bloc from mixin to widget
continuous-integration/drone/push Build is failing
2023-02-16 11:55:11 +01:00
hugo 8044d07413 fix(ui_component): add style merge in Theme Resolver 2023-02-16 11:54:42 +01:00
hugo 1af9b0b1f1 refactor(ui_kit): make resolve private and dotter child a widget 2023-02-16 10:23:48 +01:00
hugo 3a7b0abc58 style(ui_kit): fix padding file selection
continuous-integration/drone/push Build is failing
2023-02-15 22:40:19 +01:00
hugo dd198b0e51 feat(ui_kit): update example with full studio button theme 2023-02-15 22:36:26 +01:00
hugo a595183107 fix(ui_component): fix extra value in compute extension function 2023-02-15 22:35:31 +01:00
hugo c786c153e0 feat(ui_kit): add theme control in example 2023-02-15 21:45:46 +01:00
hugo cc71bf7abd feat(ui_kit): finalize material ready buttons 2023-02-15 21:07:53 +01:00
hugo ed06e18043 fix(ui): move theme_resolver in compnoent to fix code generation 2023-02-15 20:35:25 +01:00
hugo 96781880f4 feat(ui): move style implementation from component to ui_kit with theme resolver 2023-02-15 20:14:32 +01:00
hugo c331bc6056 feat(ui_kit): add theme extension support in buttons + theme negociation 2023-02-15 15:57:36 +01:00
hugo 77ce4e33ab feat(ui_kit): add theme extension shortcut 2023-02-15 15:57:04 +01:00
hugo 2806ac5923 feat(ui_component): add copyWith gen and make button style lerping 2023-02-15 15:56:35 +01:00
hugo ed29f39673 refactor(ui_component): move extensions 2023-02-15 15:55:46 +01:00
hugo 7880293723 feat(ui_component): add lerp on multicolor 2023-02-15 15:55:27 +01:00
hugo 5c34528b3d fix(ui_kit): add cacheExtend as a trade-off in listview example 2023-02-14 14:49:39 +01:00
hugo 198d83b663 fix(ui_kit): add local font assets + compress images 2023-02-14 14:48:11 +01:00
hugo bd636e9d24 docs(ui_kit): add theme negociation explaination 2023-02-14 14:20:00 +01:00
hugo c942e2aacf feat(ui_kit): update example with drawer and custom launch parameters 2023-02-14 12:50:46 +01:00
hugo 82eeba4d7d feat(ui_kit): add multicolor support in linear gradient helper 2023-02-14 12:50:17 +01:00
hugo 4695cf0618 feat(ui_kit): implement file selection button with invalid cubit and dotted package 2023-02-14 11:55:34 +01:00
hugo d49a4cad31 feat(ui_component): add file selection component 2023-02-14 11:55:34 +01:00
hugo e4d904eb8d feat(ui_kit): implement simple icon button and use dimension style 2023-02-14 11:55:34 +01:00
hugo 4f1a064298 feat(ui_component): add simple icon button and dimension style 2023-02-14 11:55:34 +01:00
hugo 168d840b87 feat(ui_kit): add symbol button + enhance bloc control over state 2023-02-14 11:55:34 +01:00
hugo aea71fa32c feat(ui_kit): add symbol button 2023-02-14 11:55:34 +01:00
hugo b6f25dd5b5 refactor(ui_kit): use tapped state and merged styles 2023-02-14 11:55:34 +01:00
hugo 61e28ce5e7 refactor(ui_component): merge flat and outline buttons in only one style 2023-02-14 11:55:34 +01:00
hugo 5050e2c2bb feat(ui_component): add tapped control state 2023-02-14 11:55:34 +01:00
hugo 9e1b76e07b feat(ui_kit): use MultiColor in button style 2023-02-14 11:55:34 +01:00
hugo 442baa6882 feat(ui_component): add MultiColor util class 2023-02-14 11:55:34 +01:00
hugo 60126fffc4 feat(ui_kit): implement flat/outlined button 2023-02-14 11:55:34 +01:00
hugo 07572aeca2 feat(ui_component): add flat/outlined button styles 2023-02-14 11:55:34 +01:00
hugo 4332eafda0 feat(ui_kit): implement flat button 2023-02-14 11:55:34 +01:00
hugo 160b30d21b feat(ui_component): add button components 2023-02-14 11:54:48 +01:00
hugo 602a372d7c fix(uikit): remove useless file 2023-02-14 11:54:48 +01:00
hugo 43df087319 chore: update repo bricks 2023-02-14 11:54:48 +01:00
hugo 4f71118a65 chore(uikit): create package with mason 2023-02-14 11:54:48 +01:00
malo 4b37175d17 feat(ui_kit): add card theme extension, fix bugs & update example (close #126)
continuous-integration/drone/push Build is failing
2023-02-14 11:34:45 +01:00
malo ea18d39c44 style(ui_kit): remove cache files
continuous-integration/drone/push Build is failing
2023-02-10 16:23:08 +01:00
malo b9f2305bca build(ui_kit): add firebase config 2023-02-10 16:17:35 +01:00
malo 55822ad870 feat(ui_kit): add quote / skill / portfolio cards (#126)
continuous-integration/drone/push Build is failing
2023-02-10 16:01:07 +01:00
malo a563bd1fe3 style(ui_kit): add macos platform in example
continuous-integration/drone/push Build is failing
2023-02-10 14:19:32 +01:00
malo 5464cd1d40 feat(ui_kit): implement information card (#126)
continuous-integration/drone/push Build is failing
2023-02-10 14:08:04 +01:00
malo ba1c1016e5 style(ui_kit): remove default files 2023-02-10 11:35:51 +01:00
malo 23b608ed10 feat(ui_components): add gradient attribut to text wrapper
continuous-integration/drone/push Build is failing
2023-02-10 11:25:39 +01:00
hugo 44b2b7c27d chore(ui_kit): create package template
continuous-integration/drone/push Build is failing
2023-02-09 18:10:11 +01:00
hugo 6bad9a8a05 fix(ui_layout): fix textwrapper 2023-02-09 18:09:45 +01:00
hugo 5d8f94bee8 fix(cw_gen): fix textwrapper 2023-02-09 18:09:14 +01:00
hugo 75cb341447 fix(bloc_layout): fix textwrapper 2023-02-09 18:08:49 +01:00
hugo efa7ca09dd feat(ui_component): add string extension to easely wrap text 2023-02-09 18:08:03 +01:00
malo ac432f6dc8 feat(ui_components): export cards #126
continuous-integration/drone/push Build is failing
2023-02-09 16:50:48 +00:00
malo 6c85faba82 feat(ui_components): add portfolio & skill cards #126 2023-02-09 16:50:48 +00:00
malo dd75ecfc7a feat: make text wrapper constructor constant 2023-02-09 16:50:48 +00:00
malo 0132771e17 feat(ui_components): add text wrapper instead of String/Widget for Texts 2023-02-09 16:50:48 +00:00
malo 5d5ae145aa feat(ui_components): make fields nullable and not required in quote card 2023-02-09 16:50:48 +00:00
malo 07428a5215 fix(ui_components): remove darkmode enable field in cards 2023-02-09 16:50:48 +00:00
malo c994c822b0 feat(ui_components): export components and add license header 2023-02-09 16:50:48 +00:00
malo bde54e0cf5 feat(ui_components): add information_card & quote_card (#126) 2023-02-09 16:50:48 +00:00
malo f3c3939ba1 docs: update readme
continuous-integration/drone/push Build is failing
2023-02-07 14:26:53 +00:00
hugo 9339100399 chore(release): publish packages
continuous-integration/drone/push Build is failing
- wyatt_analysis@2.4.0
2023-02-07 14:46:21 +01:00
hugo 03725c25c7 feat(analysis): add new lint rules 2023-02-07 14:44:57 +01:00
hugo 588a09e0a1 docs(analysis): add instructions to create a new version (closes #104) 2023-02-07 14:43:52 +01:00
malo bd53d11e0d refactor(bloc_layout): migrate bloc layouts using copywith component method (close #121)
continuous-integration/drone/push Build is failing
2023-02-07 11:46:50 +01:00
malo ee8f08cc32 refactor(ui_layout): update exemple (close #116)
continuous-integration/drone/push Build is failing
2023-02-07 10:49:56 +01:00
malo 413589462b refactor(ui_layout): migrate layouts using copywith component method (#116) 2023-02-07 10:49:09 +01:00
malo ff3f2008de fix(ui_components): generate new files after generator fixes (close #118)
continuous-integration/drone/push Build is failing
2023-02-07 10:25:58 +01:00
malo 0b27a62669 fix(component_copy_with_gen): update example (#118) 2023-02-07 10:24:00 +01:00
malo 6c9b6e239b fix(component_copy_with_gen): copywith method takes non nullable fields too (#118) 2023-02-07 10:22:32 +01:00
malo 576a01512b refactor(ui_components): update example (close #115)
continuous-integration/drone/push Build is failing
2023-02-07 09:44:34 +01:00
malo cd3ed0fe69 refactor(ui_components): migrate components using code generator packages (#115) 2023-02-07 09:44:03 +01:00
AN12345 46c51525e8 feat: add generators for components proxy and mixins to enable copywith methods
continuous-integration/drone/push Build is failing
2023-02-06 18:42:34 +01:00
AN12345 b025247002 feat: add class annotation for component code generators 2023-02-06 18:41:54 +01:00
AN12345 c70d4c6650 build: update mason file to add new tempalte 2023-02-06 18:40:35 +01:00
AN12345 04a87fe32a feat(bloc_layout): make package compatible with crud cubit (close #111)
continuous-integration/drone/push Build is passing
2022-12-19 19:21:38 -05:00
AN12345 f8f367baf6 (feat): rething conception and add missing layouts (close #97)
continuous-integration/drone/push Build is passing
2022-12-13 18:50:47 -05:00
AN12345 e667aa06d0 feat(ui_layout): make field nullable & add new app bar fields (#97) 2022-12-13 18:49:28 -05:00
hugo f6ef5828bb chore(release): publish packages
continuous-integration/drone/push Build is passing
- wyatt_authentication_bloc@0.4.1
2022-12-13 17:29:38 -05:00
Malo Léon f22ba300cb Merge pull request 'authentication/feature/google_signin' (#105) from authentication/feature/google_signin into master
continuous-integration/drone/push Build is passing
Reviewed-on: #105
Reviewed-by: Malo Léon <malo.leon@wyattapp.io>
2022-12-13 22:07:16 +00:00
hugo 5f52b2fc3d refactor(authentication): use fromFirebaseUser factory to parse user 2022-12-13 17:00:26 -05:00
hugo f46707f5c1 style(authentication): Merge 'origin/master' into authentication/feature/google_signin 2022-12-13 16:42:50 -05:00
AN12345 17ff0f8ba1 clean(packages): apply dart fix (close #106)
continuous-integration/drone/push Build is passing
2022-12-13 13:52:49 -05:00
hugo 1a3631f691 feat(authentication): add google sign in in signIn cubit 2022-12-13 00:36:20 -05:00
hugo 197c5d54e6 feat(authentication): add google sign in parameter in firebase data source constructor 2022-12-12 23:47:29 -05:00
hugo c7b241de2d feat(authentication): add google sign_in support (closes #59) 2022-12-12 23:16:10 -05:00
hugo 94d573a584 refactor(authentication): update deps and re-export them 2022-12-12 23:14:55 -05:00
hugo 37e00fe9c4 style(analysis): dart format + follows wyatt analysis 2.3.0 2022-12-12 22:43:54 -05:00
hugo 3c8ff373a1 chore(release): publish packages
continuous-integration/drone/push Build is passing
- wyatt_analysis@2.3.0
2022-12-12 22:17:35 -05:00
hugo 640cfaf118 refactor(analysis): follow melos versioning
continuous-integration/drone/push Build is passing
2022-12-12 22:15:32 -05:00
hugo 7fc3736854 feat(analysis): exclude generated code, and add dart>2.16 rules
continuous-integration/drone/push Build is passing
2022-12-12 22:02:31 -05:00
hugo 29d8ec640f feat(analysis): add overwrite protection 2022-12-12 21:38:57 -05:00
hugo 7f9621b4f6 feat(analysis): add 2.2.2 files for archive 2022-12-12 21:37:20 -05:00
hugo 7b61f3f08a feat(analysis): add utils script to easely bump version 2022-12-12 21:36:39 -05:00
hugo 75a5facfdc fix(analysis): change file include to keep coherence 2022-12-12 21:30:22 -05:00
AN12345 c93b7fb5f7 feat(bloc_layout): export layout_package & adapt imports
continuous-integration/drone/push Build is passing
2022-12-12 20:32:29 -05:00
hugo aee7060a0b ci: fix http client test error
continuous-integration/drone/push Build is passing
2022-12-12 15:20:47 -05:00
AN12345 4f49f4931c refactor(ui_layout): update example (#92)
continuous-integration/drone/push Build is failing
2022-12-12 14:21:48 -05:00
AN12345 e8172004a3 refactor(ui_component): update example (#92) 2022-12-12 14:21:13 -05:00
AN12345 c6d8ca37fe refactor(bloc_layout): update example (#92) 2022-12-12 14:20:20 -05:00
AN12345 e01f47d41a refactor(ui_layout): update package using nullable component data (#92) 2022-12-12 14:14:15 -05:00
AN12345 7a24a36af0 refactor(bloc_layout): update package using nullable component data (#92) 2022-12-12 14:13:00 -05:00
AN12345 244a286509 refactor(ui_components): update example (#92) 2022-12-12 14:10:41 -05:00
AN12345 81a7ca5a1f feat(ui_components): make component data field nullable (#92) 2022-12-12 14:08:36 -05:00
AN12345 45c7bd6fca refactor(ui_layout): update example with components updates (close #90)
continuous-integration/drone/push Build is failing
2022-12-12 12:42:11 -05:00
AN12345 cd2806b07b refactor(bloc_layout): update example with new app bar entity (#90) 2022-12-12 12:36:40 -05:00
AN12345 dd275460f6 feat(ui_components): make app bar leading & actions customizable 2022-12-12 12:34:02 -05:00
AN12345 dc0f0c61c6 feat(bloc_layout): export useful packages (close #88)
continuous-integration/drone/push Build is failing
2022-12-12 11:25:40 -05:00
hugo 1e305c75bd docs: update readme with melos commands
continuous-integration/drone/push Build is failing
2022-12-11 21:28:47 -05:00
hugo 9af76b8e1f ci: add package tests and validation 2022-12-12 01:21:37 +00:00
hugo 5593620181 refactor: change quality check rule name 2022-12-12 01:21:37 +00:00
hugo a19d4bc5ce chore: update melos config 2022-12-12 01:21:37 +00:00
hugo 21b18054ba chore(package): clean unimplemented tests 2022-12-12 01:21:37 +00:00
AN12345 ff90af47cd fix(bloc_layout): update export file 2022-12-11 23:38:54 +00:00
AN12345 3bb57e65f8 fix(bloc_layout): rename file 2022-12-11 23:38:54 +00:00
AN12345 9d0aac7894 feat(bloc_layout): add all layout avalaible with crud bloc 2022-12-11 23:38:54 +00:00
AN12345 a561cbff23 feat(bloc_layout): link error widget to error state 2022-12-11 23:38:54 +00:00
AN12345 fafec78546 clean(bloc_layout): remove test folder 2022-12-11 23:38:54 +00:00
AN12345 feca378131 feat(bloc_layout): add new package to combine bloc_helper, crud_bloc, ui_components, and ui_layout 2022-12-11 23:38:54 +00:00
hugo f223811f4b chore(medium): remove unused package 2022-12-08 14:32:19 -05:00
hugo ed65489316 chore(cli): remove unused package 2022-12-08 14:31:57 -05:00
AN12345 33797e4dbf refactor(ui_layout): update appbar component (close #78) 2022-12-08 18:58:37 +00:00
AN12345 3aa6d03dd6 refactor(crud_bloc): update package using new architecture usecase execute method (close #77) 2022-12-08 13:29:01 -05:00
hugo bf03324fd0 chore: add pre-commit rule (see #72) 2022-12-08 03:46:10 +00:00
hugo 5e83c9e74e docs(auth): add correct header 2022-12-07 19:52:01 -05:00
hugo 672aba7084 fix(auth): fix mock on register 2022-12-07 19:52:00 -05:00
hugo 94d7efbe8c fix(form): fix textController rebuild 2022-12-07 19:51:59 -05:00
hugo 5298bd99ed feat(authentication): add reauthenticate, updateEmail and updatePassword 2022-12-07 19:50:19 -05:00
AN12345 d792f4cbe9 feat(ui_layout): update example & move configure function (#69) 2022-12-07 18:54:48 -05:00
AN12345 098ec9715e feat(ui_layout): add loading & error widget to component theme (close #69) 2022-12-07 18:20:04 -05:00
AN12345 6d3c64d17c feat(ui_layout): add frame layout (close #67) 2022-12-07 17:14:00 -05:00
AN12345 c615186f19 docs(ui_layout): update models 2022-12-07 15:44:05 -05:00
AN12345 55e24fb23b fix(ui_layout): fix emample after splititng packages 2022-12-07 15:37:46 -05:00
AN12345 4d04c3f446 doc: update readme(s) 2022-12-07 15:04:48 -05:00
AN12345 a20e4a1715 refractor: migrate components in right package 2022-12-07 14:56:05 -05:00
AN12345 cf9f1ddb65 feat: create new package to split components and layouts 2022-12-07 14:13:24 -05:00
AN12345 0c141c715e fix(ui_layout): remove unecessary dependencies 2022-12-07 02:38:14 +00:00
AN12345 d0f59bbf29 refactor(ui_layout): update field name 2022-12-07 02:38:14 +00:00
AN12345 562f84dd33 doc(ui_layout): add class models 2022-12-07 02:38:14 +00:00
AN12345 771f600eb7 feat(ui_layout): add new package for app compenant and start implementing layouts 2022-12-07 02:38:14 +00:00
757 changed files with 26804 additions and 5430 deletions
+36
View File
@@ -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-1
commands:
- melos run quality-check
- melos run publish:validate
- name: publish
image: git.wyatt-studio.fr/wyatt-foss/flutter-melos:2.9.0-1
commands:
- melos run publish:validate
trigger:
branch:
- master
event:
- push
+7
View File
@@ -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]
+98
View File
@@ -3,6 +3,104 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## 2023-02-24
### Changes
---
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- [`wyatt_analysis` - `v2.4.1`](#wyatt_analysis---v241)
---
#### `wyatt_analysis` - `v2.4.1`
- **FEAT**: add latest version persistence between script executions.
- **FEAT**: ignore todo's.
## 2023-02-07
### Changes
---
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- [`wyatt_analysis` - `v2.4.0`](#wyatt_analysis---v240)
---
#### `wyatt_analysis` - `v2.4.0`
- **FEAT**: add new lint rules.
- **DOCS**: add instructions to create a new version (closes #104).
## 2022-12-13
### Changes
---
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- [`wyatt_authentication_bloc` - `v0.4.1`](#wyatt_authentication_bloc---v041)
---
#### `wyatt_authentication_bloc` - `v0.4.1`
- **REFACTOR**: use fromFirebaseUser factory to parse user.
- **REFACTOR**: update deps and re-export them.
- **FIX**: fix mock on register.
- **FEAT**: add google sign in in signIn cubit.
- **FEAT**: add google sign in parameter in firebase data source constructor.
- **FEAT**: add google sign_in support (closes #59).
- **FEAT**: add reauthenticate, updateEmail and updatePassword.
- **DOCS**: add correct header.
## 2022-12-12
### 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
+52 -52
View File
@@ -17,11 +17,7 @@
-->
<p align="center">
<a href="https://wyattapp.io">
<img width="150px" src="resources/wyatt-campus-logo.png">
</a>
<a href="https://wyatt-studio.fr">
<a href="https://wyatt-studio.fr">
<img width="150px" src="resources/wyatt-studio-logo.png">
</a>
<h1 align="center">Wyatt Packages</h1>
@@ -44,10 +40,9 @@
## About
Here is it a set of [Flutter plugins](https://flutter.io/platform-plugins/) that power up your applications.
Here is a set of [Flutter plugins](https://flutter.io/platform-plugins/) that enhance your applications.
[Flutter](https://flutter.dev) is Google's UI toolkit for building beautiful, natively compiled applications for mobile, web, and desktop from a single codebase. Flutter is used by developers and organizations around the world, and is free
and open source.
[Flutter](https://flutter.dev) is Google's UI toolkit for building beautiful, natively compiled applications for mobile, web, and desktop using a single codebase. It is used by developers and organizations worldwide and is free and open-source.
---
@@ -61,21 +56,21 @@ git clone ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-packages.git
### Prerequisite
- [Flutter](https://github.com/flutter/flutter).
1. [Flutter](https://github.com/flutter/flutter). It is a UI toolkit developed by Google for building beautiful and natively compiled applications for mobile, web, and desktop from a single codebase.
- [Melos](https://github.com/invertase/melos). Used to manage Dart projects with multiple packages.
2. [Melos](https://github.com/invertase/melos). Melos is a tool that helps in managing Dart projects that have multiple packages. It can be installed using the following command:
```shell
dart pub global activate melos
```
- [Mason](https://github.com/felangel/mason). Used for code generation.
3. [Mason](https://github.com/felangel/mason). Mason is used for code generation purposes. It can be installed by running the following command:
```shell
dart pub global activate mason_cli
```
- [Lcov](https://github.com/linux-test-project/lcov). Used to generate coverage data.
4. [Lcov](https://github.com/linux-test-project/lcov). Lcov is a tool used to generate coverage data. It can be installed on macOS by running the following command:
```shell
# on macos
@@ -84,38 +79,39 @@ brew install lcov
- genhtml. Used to convert coverage data into html pages.
After installing all these packages, bootstrap with `melos bs`.
After installation of all these packages, the project can be bootstrapped using the command `melos bs`.
### Create a new package
Create a new package in `packages/` folder.
To create a new package in the packages/ folder, run the following command in the terminal:
```shell
mason make wyatt_package --package_name wyatt_<name> --description A new Wyatt package --flutter_only false
```
Then bootstrap project with `melos bs` command.
The <name> variable in the above command is important and must be clear and understandable.
After creating the package, bootstrap the project with the `melos bs` command.
#### Naming
In the previous instructions `<name>` variable is important.
It have to be clear and intelligible.
You **MUST** use underscores.
1. You must use underscores in the name.
2. You must use the wyatt prefix for the package name.
3. You must name the example with a specific name.
You **MUST** use `wyatt` prefix for package.
For example, if the name is "CRUD BLOC," the following naming conventions should be used:
You **MUST** name example with specific name.
For example, if name is CRUD BLOC
- name will be crud_bloc
- so the package will be: `wyatt_crud_bloc`
- and the example will be: `crud_bloc_example`
1. name: crud_bloc
2. package name: wyatt_crud_bloc
3. example name: crud_bloc_example
### Create issues
Add the issues directly related to what you want to develop and label them correctly.
Create an issue for each specific feature or task you want to work on and label it correctly using the following format:
```
Type(scope): issue.
@@ -128,18 +124,18 @@ For example, on notification bloc package :
### Branches
Master is protected. You can't push on it. Please develop your feature on another branch. The name of your branch has to match with the issue opened.
The master branch is protected and cannot be pushed to directly. Please create a separate branch for each feature or task, with a name that corresponds to the related issue. The branch name should follow this format:
`type(scope):issue`
Example :
Issue :
For the issue:
- `Feature(notification_bloc): add firebase messaging data source.`
Branch related to this issue :
The related branch should be named:
- `feature(notification_bloc)/add_firebase_messaging_data_source`
- `notification_bloc/feat/add_firebase_messaging_data_source`
### Commits
@@ -163,55 +159,59 @@ Some examples :
- `docs: update readme.` = update **this** readme file.
- `fix(crud)!: fix bug in awesome() function. (#32)` = fix a bug, `!` is important and indicate `BREAKING CHANGES` linked with the 32nd issue.
When you have finished developing, and are ready to close the issue, close it via your commit :
`feat(auth): add AWS support. (close #31)`
Note that your issue will be close after merging on master.
Before closing the issue, please check tests and update coverage. You might run :
When you have completed your development work and are ready to resolve the related issue, you can close it via your commit message by including (close #issue_number). For example:
```shell
melos run test
melos run gen_coverage
feat(auth): add AWS support. (close #31)
```
```shell
melos run test:all # this will run all tests in this project
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
```
Please note that the issue will only be closed after it has been merged into the master branch. Before closing the issue, it is important to verify that all tests have been run and that coverage has been updated.
#### Merge your work
After closing your issue, some work may have been done on master in the meantime. To keep a clean git history, please rebase before opening a change request.
When you have completed your work and closed the related issue, it's possible that some changes may have been made to the master branch in the meantime. To maintain a clean Git history, it's recommended to rebase before creating a change request (pull request).
Two situations :
- You have not yet created your branch and have committed locally :
- You haven't created a branch yet and have made local commits:
```shell
git pull --rebase
```
- You are already working on your branch :
- You are already working on a branch:
```shell
git rebase -i master
```
If possible, please use `--fixup` on your commit in interactive rebase.
It's recommended to use the `--fixup` option during the interactive rebase to keep the Git history clean.
Then, opend your PR, get the necessary approval and merge your work. Then you're done ✅.
Once you have rebased, you can create a pull request, receive the necessary approvals, and then merge your work. And with that, you're done! 🎉
#### Update version.
Once your work is on the master, you can update your package version. Please filter packages to update only your package. `--scope` is used to do it.
For example, after merging changes on `wyatt_otification_bloc` package, you might run :
When your work has been merged into the master branch, it's time to update the package version. To update only your specific package, use the --scope option. For example, after merging changes into the `wyatt_notification_bloc` package, you can run the following command:
```shell
melos version --scope="*wyatt_notification_bloc*"
```
In fact, melos will filter all packages that match the `wyatt_notification_block` pattern.
This will filter all packages that match the `wyatt_notification_bloc` pattern and update only that package.
You can update check all packages tests by running :
You can then verify that all packages and their tests are working correctly by running:
```shell
melos run test
melos run test:all
```
#### Publish your package
@@ -259,14 +259,14 @@ Here you can change `package name` and `package version`.
---
## Status
![Status: Experimental](https://img.shields.io/badge/Status-WIP-red?style=flat-square)
This repository is maintained by Wyatt Studio but work is in progress.
## Simple work flow diagramm
To sum up, here a simple work flow diagramm.
![Dev Wokflow](doc/workflow.svg)
## Status
![Status: Experimental](https://img.shields.io/badge/Status-WIP-red?style=flat-square)
This repository is maintained by Wyatt Studio but work is in progress.
+1 -1
View File
@@ -1 +1 @@
{"bricks":{"wyatt_clean_code":{"git":{"url":"ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-bricks.git","path":"bricks/wyatt_clean_code","ref":"033baa65408ec6b68e6a2ef43e64c24708ef16a1"}},"wyatt_feature_brick":{"git":{"url":"ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-bricks.git","path":"bricks/wyatt_feature_brick","ref":"033baa65408ec6b68e6a2ef43e64c24708ef16a1"}},"wyatt_package":{"git":{"url":"ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-bricks.git","path":"bricks/wyatt_package","ref":"033baa65408ec6b68e6a2ef43e64c24708ef16a1"}}}}
{"bricks":{"wyatt_component_template":{"git":{"url":"ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-bricks.git","path":"bricks/wyatt_component_template","ref":"7cea909470ce75b91840f479649b93f953ded596"}}}}
+22 -10
View File
@@ -1,13 +1,25 @@
# Copyright (C) 2023 WYATT GROUP
# Please see the AUTHORS file for details.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
bricks:
wyatt_clean_code:
wyatt_package_template:
git:
url: ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-bricks.git
path: bricks/wyatt_clean_code
wyatt_feature_brick:
url: "ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-bricks.git"
path: bricks/wyatt_package_template
wyatt_component_template:
git:
url: ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-bricks.git
path: bricks/wyatt_feature_brick
wyatt_package:
git:
url: ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-bricks.git
path: bricks/wyatt_package
url: "ssh://git@git.wyatt-studio.fr:993/Wyatt-FOSS/wyatt-bricks.git"
path: bricks/wyatt_component_template
+33 -10
View File
@@ -21,35 +21,58 @@ scripts:
analyze:
run: |
melos exec -c 10 -- \
flutter analyze --fatal-infos
melos exec -c 1 -- flutter analyze --fatal-infos
description: Run `flutter analyze` for all packages.
fix:
run: melos exec dart fix . --apply
description: Run `dart fix` for all packages.
format:
run: melos exec flutter format . --fix
description: Run `flutter format` for all packages.
run: melos exec dart format .
description: Run `dart format` for all packages.
format-check:
run: melos exec flutter format . --set-exit-if-changed
description: Run `flutter format` checks for all packages.
run: melos exec dart fix . --set-exit-if-changed
description: Run `dart fix` checks for all packages.
clean:deep:
run: git clean -x -d -f -q
description: Clean things very deeply with `git clean`.
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.
select-package:
flutter: true
dir-exists:
- test
ignore:
- '*example*'
test:
test:all:
run: melos run test:selective_unit_test --no-select
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-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.
postclean: >
+1
View File
@@ -0,0 +1 @@
2.4.1
+2
View File
@@ -0,0 +1,2 @@
new_version.sh
.latest_version
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2022 WYATT GROUP
* Copyright (C) 2023 WYATT GROUP
* Please see the AUTHORS file for details.
*
* This program is free software: you can redistribute it and/or modify
+19
View File
@@ -1,3 +1,22 @@
## 2.4.1
- **FEAT**: add latest version persistence between script executions.
- **FEAT**: ignore todo's.
## 2.4.0
- **FEAT**: add new lint rules.
- **DOCS**: add instructions to create a new version (closes #104).
## 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
- **DOCS**: add publish_to self hosted pub server.
+31 -15
View File
@@ -1,5 +1,5 @@
<!--
* Copyright (C) 2022 WYATT GROUP
* Copyright (C) 2023 WYATT GROUP
* Please see the AUTHORS file for details.
*
* This program is free software: you can redistribute it and/or modify
@@ -20,24 +20,29 @@
![SDK: Dart & Flutter](https://img.shields.io/badge/SDK-Dart%20%7C%20Flutter-blue?style=flat-square)
This package provides lint rules for Dart and Flutter which are used at [Wyatt](https://wyattapp.io) and [Wyatt Studio](https://wyatt-studio.fr). For more information, see the complete list of options in **lib/analysis_options.2.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.4.1.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).
## Usage
## Adding Wyatt Analysis to your project
To use the lints, add a dependency in your `pubspec.yaml`:
Using CLI:
```yaml
dev_dependencies:
wyatt_analysis:
git:
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
ref: wyatt_analysis-v2.0.0
path: packages/wyatt_analysis
```sh
dart pub add wyatt_analysis:2.4.1 --dev --hosted-url=https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
```
Then, add an include in `analysis_options.yaml`:
## Usage
To use the lints, add a dependency in your `pubspec.yaml` :
```yaml
wyatt_analysis:
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
version: 2.4.1
```
Then, add an include in `analysis_options.yaml` :
```yaml
include: package:wyatt_analysis/analysis_options.yaml
@@ -52,13 +57,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:
```yaml
include: package:wyatt_analysis/analysis_options.flutter.2.0.0.yaml
include: package:wyatt_analysis/analysis_options.flutter.2.4.1.yaml
```
If you just want **Dart** version:
```yaml
include: package:wyatt_analysis/analysis_options.2.0.0.yaml
include: package:wyatt_analysis/analysis_options.2.4.1.yaml
```
## Suppressing Lints
@@ -90,7 +95,7 @@ class B {}
### Project Level
To surpress a specific lint rule for an entire project, modify `analysis_options.yaml`:
To surpress a specific lint rule for an entire project, modify `analysis_options.yaml` :
```yaml
include: package:wyatt_analysis/analysis_options.yaml
@@ -107,6 +112,17 @@ To indicate your project is using `wyatt_analysis` → [![style: wyatt analysis]
[![style: wyatt analysis](https://img.shields.io/badge/Style-Wyatt%20Analysis-blue)](https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_analysis)
```
## Development
When you want to create a new version of the plugin. Before any modification, execute the following command to create new files:
```sh
./new_version.sh <new_version>
```
The previous version is automatically detected thanks to the `.latest_version` file.
So `.latest_version` needs to be versioned!
## Notes
You can explore every lint rules [here](https://dart-lang.github.io/linter/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
@@ -0,0 +1,217 @@
# Copyright (C) 2023 WYATT GROUP
# Please see the AUTHORS file for details.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
analyzer:
language:
strict-casts: true
strict-inference: true
strict-raw-types: true
errors:
todo: info
close_sinks: ignore
missing_required_param: error
missing_return: error
exclude:
- lib/l10n/**
- lib/generated/**
- lib/gen/**
- lib/generated_plugin_registrant.dart
- test/.test_coverage.dart
- '**/*.g.dart'
- '**/*.freezed.dart'
linter:
rules:
- always_declare_return_types
- always_put_control_body_on_new_line
- always_put_required_named_parameters_first
- always_require_non_null_named_parameters
- always_use_package_imports
- annotate_overrides
- avoid_bool_literals_in_conditional_expressions
- avoid_catching_errors
- avoid_double_and_int_checks
- avoid_dynamic_calls
- avoid_empty_else
- avoid_equals_and_hash_code_on_mutable_classes
- avoid_escaping_inner_quotes
- avoid_field_initializers_in_const_classes
- avoid_final_parameters
- avoid_function_literals_in_foreach_calls
- avoid_init_to_null
- avoid_js_rounded_ints
- avoid_multiple_declarations_per_line
- avoid_null_checks_in_equality_operators
- avoid_positional_boolean_parameters
- avoid_private_typedef_functions
- avoid_redundant_argument_values
- avoid_relative_lib_imports
- avoid_renaming_method_parameters
- avoid_return_types_on_setters
- avoid_returning_null
- avoid_returning_null_for_future
- avoid_returning_null_for_void
- avoid_returning_this
- avoid_setters_without_getters
- avoid_shadowing_type_parameters
- avoid_single_cascade_in_expression_statements
- avoid_slow_async_io
- avoid_type_to_string
- avoid_types_as_parameter_names
- avoid_types_on_closure_parameters
- avoid_unused_constructor_parameters
- avoid_void_async
- await_only_futures
- camel_case_extensions
- camel_case_types
- cancel_subscriptions
- cascade_invocations
- cast_nullable_to_non_nullable
- collection_methods_unrelated_type
- combinators_ordering
- comment_references
- conditional_uri_does_not_exist
- constant_identifier_names
- control_flow_in_finally
- curly_braces_in_flow_control_structures
- depend_on_referenced_packages
- deprecated_consistency
- directives_ordering
- empty_catches
- empty_constructor_bodies
- empty_statements
- eol_at_end_of_file
- exhaustive_cases
- file_names
- flutter_style_todos
- hash_and_equals
- implementation_imports
- implicit_call_tearoffs
- iterable_contains_unrelated_type
- join_return_with_assignment
- leading_newlines_in_multiline_strings
- library_names
- library_prefixes
- library_private_types_in_public_api
- lines_longer_than_80_chars
- list_remove_unrelated_type
- literal_only_boolean_expressions
- missing_whitespace_between_adjacent_strings
- no_adjacent_strings_in_list
- no_default_cases
- no_duplicate_case_values
- no_leading_underscores_for_library_prefixes
- no_leading_underscores_for_local_identifiers
- no_runtimeType_toString
- non_constant_identifier_names
- noop_primitive_operations
- null_check_on_nullable_type_parameter
- null_closures
- one_member_abstracts
- only_throw_errors
- overridden_fields
- package_api_docs
- package_names
- package_prefixed_library_names
- parameter_assignments
- prefer_adjacent_string_concatenation
- prefer_asserts_in_initializer_lists
- prefer_asserts_with_message
- prefer_collection_literals
- prefer_conditional_assignment
- prefer_const_constructors
- prefer_const_constructors_in_immutables
- prefer_const_declarations
- prefer_const_literals_to_create_immutables
- prefer_constructors_over_static_methods
- prefer_contains
- prefer_equal_for_default_values
- prefer_expression_function_bodies
- prefer_final_fields
- prefer_final_in_for_each
- prefer_final_locals
- prefer_for_elements_to_map_fromIterable
- prefer_function_declarations_over_variables
- prefer_generic_function_type_aliases
- prefer_if_elements_to_conditional_expressions
- prefer_if_null_operators
- prefer_initializing_formals
- prefer_inlined_adds
- prefer_int_literals
- prefer_interpolation_to_compose_strings
- prefer_is_empty
- prefer_is_not_empty
- prefer_is_not_operator
- prefer_iterable_whereType
- prefer_mixin
- prefer_null_aware_method_calls
- prefer_null_aware_operators
- prefer_single_quotes
- prefer_spread_collections
- prefer_typing_uninitialized_variables
- prefer_void_to_null
- provide_deprecation_message
- recursive_getters
- require_trailing_commas
- slash_for_doc_comments
- sort_constructors_first
- sort_unnamed_constructors_first
- test_types_in_equals
- throw_in_finally
- tighten_type_of_initializing_formals
- type_annotate_public_apis
- type_init_formals
- unawaited_futures
- unnecessary_await_in_return
- unnecessary_brace_in_string_interps
- unnecessary_const
- unnecessary_constructor_name
- unnecessary_getters_setters
- unnecessary_lambdas
- unnecessary_late
- unnecessary_new
- unnecessary_null_aware_assignments
- unnecessary_null_checks
- unnecessary_null_in_if_null_operators
- unnecessary_nullable_for_final_variable_declarations
- unnecessary_overrides
- unnecessary_parenthesis
- unnecessary_raw_strings
- unnecessary_statements
- unnecessary_string_escapes
- unnecessary_string_interpolations
- unnecessary_this
- unnecessary_to_list_in_spreads
- unrelated_type_equality_checks
- unsafe_html
- use_enums
- use_function_type_syntax_for_parameters
- use_if_null_to_convert_nulls_to_bools
- use_is_even_rather_than_modulo
- use_late_for_private_fields_and_variables
- use_named_constants
- use_raw_strings
- use_rethrow_when_possible
- use_setters_to_change_properties
- use_string_buffers
- use_string_in_part_of_directives
- use_super_parameters
- use_test_throws_matchers
- use_to_and_as_if_applicable
- valid_regexps
- void_checks
@@ -0,0 +1,217 @@
# Copyright (C) 2023 WYATT GROUP
# Please see the AUTHORS file for details.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
analyzer:
language:
strict-casts: true
strict-inference: true
strict-raw-types: true
errors:
todo: ignore
close_sinks: ignore
missing_required_param: error
missing_return: error
exclude:
- lib/l10n/**
- lib/generated/**
- lib/gen/**
- lib/generated_plugin_registrant.dart
- test/.test_coverage.dart
- "**/*.g.dart"
- "**/*.freezed.dart"
linter:
rules:
- always_declare_return_types
- always_put_control_body_on_new_line
- always_put_required_named_parameters_first
- always_require_non_null_named_parameters
- always_use_package_imports
- annotate_overrides
- avoid_bool_literals_in_conditional_expressions
- avoid_catching_errors
- avoid_double_and_int_checks
- avoid_dynamic_calls
- avoid_empty_else
- avoid_equals_and_hash_code_on_mutable_classes
- avoid_escaping_inner_quotes
- avoid_field_initializers_in_const_classes
- avoid_final_parameters
- avoid_function_literals_in_foreach_calls
- avoid_init_to_null
- avoid_js_rounded_ints
- avoid_multiple_declarations_per_line
- avoid_null_checks_in_equality_operators
- avoid_positional_boolean_parameters
- avoid_private_typedef_functions
- avoid_redundant_argument_values
- avoid_relative_lib_imports
- avoid_renaming_method_parameters
- avoid_return_types_on_setters
- avoid_returning_null
- avoid_returning_null_for_future
- avoid_returning_null_for_void
- avoid_returning_this
- avoid_setters_without_getters
- avoid_shadowing_type_parameters
- avoid_single_cascade_in_expression_statements
- avoid_slow_async_io
- avoid_type_to_string
- avoid_types_as_parameter_names
- avoid_types_on_closure_parameters
- avoid_unused_constructor_parameters
- avoid_void_async
- await_only_futures
- camel_case_extensions
- camel_case_types
- cancel_subscriptions
- cascade_invocations
- cast_nullable_to_non_nullable
- collection_methods_unrelated_type
- combinators_ordering
- comment_references
- conditional_uri_does_not_exist
- constant_identifier_names
- control_flow_in_finally
- curly_braces_in_flow_control_structures
- depend_on_referenced_packages
- deprecated_consistency
- directives_ordering
- empty_catches
- empty_constructor_bodies
- empty_statements
- eol_at_end_of_file
- exhaustive_cases
- file_names
- flutter_style_todos
- hash_and_equals
- implementation_imports
- implicit_call_tearoffs
- iterable_contains_unrelated_type
- join_return_with_assignment
- leading_newlines_in_multiline_strings
- library_names
- library_prefixes
- library_private_types_in_public_api
- lines_longer_than_80_chars
- list_remove_unrelated_type
- literal_only_boolean_expressions
- missing_whitespace_between_adjacent_strings
- no_adjacent_strings_in_list
- no_default_cases
- no_duplicate_case_values
- no_leading_underscores_for_library_prefixes
- no_leading_underscores_for_local_identifiers
- no_runtimeType_toString
- non_constant_identifier_names
- noop_primitive_operations
- null_check_on_nullable_type_parameter
- null_closures
- one_member_abstracts
- only_throw_errors
- overridden_fields
- package_api_docs
- package_names
- package_prefixed_library_names
- parameter_assignments
- prefer_adjacent_string_concatenation
- prefer_asserts_in_initializer_lists
- prefer_asserts_with_message
- prefer_collection_literals
- prefer_conditional_assignment
- prefer_const_constructors
- prefer_const_constructors_in_immutables
- prefer_const_declarations
- prefer_const_literals_to_create_immutables
- prefer_constructors_over_static_methods
- prefer_contains
- prefer_equal_for_default_values
- prefer_expression_function_bodies
- prefer_final_fields
- prefer_final_in_for_each
- prefer_final_locals
- prefer_for_elements_to_map_fromIterable
- prefer_function_declarations_over_variables
- prefer_generic_function_type_aliases
- prefer_if_elements_to_conditional_expressions
- prefer_if_null_operators
- prefer_initializing_formals
- prefer_inlined_adds
- prefer_int_literals
- prefer_interpolation_to_compose_strings
- prefer_is_empty
- prefer_is_not_empty
- prefer_is_not_operator
- prefer_iterable_whereType
- prefer_mixin
- prefer_null_aware_method_calls
- prefer_null_aware_operators
- prefer_single_quotes
- prefer_spread_collections
- prefer_typing_uninitialized_variables
- prefer_void_to_null
- provide_deprecation_message
- recursive_getters
- require_trailing_commas
- slash_for_doc_comments
- sort_constructors_first
- sort_unnamed_constructors_first
- test_types_in_equals
- throw_in_finally
- tighten_type_of_initializing_formals
- type_annotate_public_apis
- type_init_formals
- unawaited_futures
- unnecessary_await_in_return
- unnecessary_brace_in_string_interps
- unnecessary_const
- unnecessary_constructor_name
- unnecessary_getters_setters
- unnecessary_lambdas
- unnecessary_late
- unnecessary_new
- unnecessary_null_aware_assignments
- unnecessary_null_checks
- unnecessary_null_in_if_null_operators
- unnecessary_nullable_for_final_variable_declarations
- unnecessary_overrides
- unnecessary_parenthesis
- unnecessary_raw_strings
- unnecessary_statements
- unnecessary_string_escapes
- unnecessary_string_interpolations
- unnecessary_this
- unnecessary_to_list_in_spreads
- unrelated_type_equality_checks
- unsafe_html
- use_enums
- use_function_type_syntax_for_parameters
- use_if_null_to_convert_nulls_to_bools
- use_is_even_rather_than_modulo
- use_late_for_private_fields_and_variables
- use_named_constants
- use_raw_strings
- use_rethrow_when_possible
- use_setters_to_change_properties
- use_string_buffers
- use_string_in_part_of_directives
- use_super_parameters
- use_test_throws_matchers
- use_to_and_as_if_applicable
- valid_regexps
- void_checks
@@ -14,7 +14,7 @@
# 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.1.1.yaml
include: package:wyatt_analysis/analysis_options.2.2.0.yaml
linter:
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
@@ -0,0 +1,32 @@
# Copyright (C) 2023 WYATT GROUP
# Please see the AUTHORS file for details.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
include: package:wyatt_analysis/analysis_options.2.4.0.yaml
linter:
rules:
- avoid_print
- avoid_unnecessary_containers
- avoid_web_libraries_in_flutter
- no_logic_in_create_state
- sized_box_for_whitespace
- sized_box_shrink_expand
- sort_child_properties_last
- use_build_context_synchronously
- use_colored_box
- use_decorated_box
- use_full_hex_values_for_flutter_colors
- use_key_in_widget_constructors
@@ -0,0 +1,32 @@
# Copyright (C) 2023 WYATT GROUP
# Please see the AUTHORS file for details.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
include: package:wyatt_analysis/analysis_options.2.4.1.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,4 +1,4 @@
# Copyright (C) 2022 WYATT GROUP
# Copyright (C) 2023 WYATT GROUP
# Please see the AUTHORS file for details.
#
# This program is free software: you can redistribute it and/or modify
@@ -14,4 +14,4 @@
# 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.2.2.1.yaml
include: package:wyatt_analysis/analysis_options.flutter.2.4.1.yaml
@@ -1,4 +1,4 @@
# Copyright (C) 2022 WYATT GROUP
# Copyright (C) 2023 WYATT GROUP
# Please see the AUTHORS file for details.
#
# This program is free software: you can redistribute it and/or modify
@@ -14,4 +14,4 @@
# 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.1.yaml
include: package:wyatt_analysis/analysis_options.2.4.1.yaml
@@ -1,4 +1,4 @@
// Copyright (C) 2022 WYATT GROUP
// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -15,8 +15,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
/// Wyatt analyzer settings and best practices
/// used internally at [Wyatt](https://wyattapp.io)
/// and [Wyatt Studio](https://wyatt-studio.fr).
/// used internally at [Wyatt Studio](https://wyatt-studio.fr).
library wyatt_analysis;
const String wyattAnalysisVersion = '2.2.1';
const String wyattAnalysisVersion = '2.4.1';
+142
View File
@@ -0,0 +1,142 @@
#!/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") <new_version> -- create new analyzer files.
where:
new_version: new version, for example \`2.4.0\`"
new=$1
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}")"
LATEST_VERSION="${ABS_DIRECTORY}/.latest_version"
# Read latest version
if [ -e "$LATEST_VERSION" ]; then
old=$(cat "$LATEST_VERSION")
echo "> latest package version is: $old"
echo "> new package version is: $new"
else
echo "latest version is not set"
echo "create a file named \`.latest_version\` in the root of the project"
exit 1
fi
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) 2023 WYATT GROUP
# Please see the AUTHORS file for details.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
include: package:wyatt_analysis/analysis_options.${new}.yaml
" > "${OPTIONS}"
echo "
# Copyright (C) 2023 WYATT GROUP
# Please see the AUTHORS file for details.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
include: package:wyatt_analysis/analysis_options.flutter.${new}.yaml
" > "${OPTIONS_FLUTTER}"
# Update latest version
echo "${new}" > "$LATEST_VERSION"
exit 0
+19 -3
View File
@@ -1,9 +1,25 @@
# Copyright (C) 2023 WYATT GROUP
# Please see the AUTHORS file for details.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
name: wyatt_analysis
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
version: 2.2.2
version: 2.4.1
publish_to: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub
environment:
sdk: '>=2.12.0 <3.0.0'
sdk: ">=2.12.0 <3.0.0"
@@ -24,9 +24,8 @@ import 'package:wyatt_http_client/wyatt_http_client.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
class AlbumApiDataSourceImpl extends AlbumRemoteDataSource {
final MiddlewareClient _client;
AlbumApiDataSourceImpl(this._client);
final MiddlewareClient _client;
@override
Future<Album> getAlbum(int id) async {
@@ -24,9 +24,8 @@ import 'package:wyatt_http_client/wyatt_http_client.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
class PhotoApiDataSourceImpl extends PhotoRemoteDataSource {
final MiddlewareClient _client;
PhotoApiDataSourceImpl(this._client);
final MiddlewareClient _client;
@override
Future<Photo> getPhoto(int id) async {
@@ -15,7 +15,6 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:architecture_example/data/models/photo_model.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
@@ -24,15 +24,14 @@ import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
class PhotoRepositoryImpl extends PhotoRepository {
final PhotoRemoteDataSource _photoRemoteDataSource;
final AlbumRemoteDataSource _albumRemoteDataSource;
final FavoriteLocalDataSource _favoriteLocalDataSource;
PhotoRepositoryImpl(
this._photoRemoteDataSource,
this._albumRemoteDataSource,
this._favoriteLocalDataSource,
);
final PhotoRemoteDataSource _photoRemoteDataSource;
final AlbumRemoteDataSource _albumRemoteDataSource;
final FavoriteLocalDataSource _favoriteLocalDataSource;
@override
FutureOrResult<void> addPhotoToFavorites(Photo photo) => Result.tryCatchAsync(
@@ -21,9 +21,8 @@ import 'package:architecture_example/domain/repositories/photo_repository.dart';
import 'package:wyatt_architecture/wyatt_architecture.dart';
class AddPhotoToFavorites extends AsyncUseCase<Photo, List<Photo>> {
final PhotoRepository _photoRepository;
AddPhotoToFavorites(this._photoRepository);
final PhotoRepository _photoRepository;
@override
FutureOrResult<List<Photo>> execute(Photo? params) async {
@@ -20,9 +20,8 @@ import 'package:architecture_example/domain/repositories/photo_repository.dart';
import 'package:wyatt_architecture/wyatt_architecture.dart';
class CheckIfPhotoIsInFavorites extends AsyncUseCase<int, bool> {
final PhotoRepository _photoRepository;
CheckIfPhotoIsInFavorites(this._photoRepository);
final PhotoRepository _photoRepository;
@override
FutureOrResult<bool> execute(int? params) async =>
@@ -19,9 +19,8 @@ import 'package:architecture_example/domain/repositories/photo_repository.dart';
import 'package:wyatt_architecture/wyatt_architecture.dart';
class DisplayFavorites extends AsyncUseCase<NoParam, List<Photo>> {
final PhotoRepository _photoRepository;
DisplayFavorites(this._photoRepository);
final PhotoRepository _photoRepository;
@override
FutureOrResult<List<Photo>> execute(void params) {
@@ -21,9 +21,8 @@ import 'package:architecture_example/domain/repositories/photo_repository.dart';
import 'package:wyatt_architecture/wyatt_architecture.dart';
class DisplayPhoto extends AsyncUseCase<int, Photo> {
final PhotoRepository _photoRepository;
DisplayPhoto(this._photoRepository);
final PhotoRepository _photoRepository;
@override
FutureOrResult<Photo> execute(int? params) {
@@ -22,9 +22,8 @@ import 'package:architecture_example/domain/usecases/photos/params/query_paramet
import 'package:wyatt_architecture/wyatt_architecture.dart';
class OpenAlbum extends AsyncUseCase<QueryParameters, List<Photo>> {
final PhotoRepository _photoRepository;
OpenAlbum(this._photoRepository);
final PhotoRepository _photoRepository;
@override
FutureOrResult<List<Photo>> execute(QueryParameters? params) {
@@ -15,9 +15,8 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
class QueryParameters {
QueryParameters(this.start, this.limit, {this.albumId = -1});
final int albumId;
final int? start;
final int? limit;
QueryParameters(this.start, this.limit, {this.albumId = -1});
}
@@ -21,9 +21,8 @@ import 'package:architecture_example/domain/repositories/photo_repository.dart';
import 'package:wyatt_architecture/wyatt_architecture.dart';
class RemovePhotoFromFavorites extends AsyncUseCase<int, List<Photo>> {
final PhotoRepository _photoRepository;
RemovePhotoFromFavorites(this._photoRepository);
final PhotoRepository _photoRepository;
@override
FutureOrResult<List<Photo>> execute(int? params) async {
@@ -22,9 +22,8 @@ import 'package:architecture_example/domain/usecases/photos/params/query_paramet
import 'package:wyatt_architecture/wyatt_architecture.dart';
class RetrieveAllAlbums extends AsyncUseCase<QueryParameters, List<Album>> {
final PhotoRepository _photoRepository;
RetrieveAllAlbums(this._photoRepository);
final PhotoRepository _photoRepository;
@override
FutureOrResult<List<Album>> execute(QueryParameters? params) {
@@ -33,14 +33,13 @@ EventTransformer<E> throttleDroppable<E>(Duration duration) =>
(events, mapper) => droppable<E>().call(events.throttle(duration), mapper);
class AlbumBloc extends Bloc<AlbumEvent, AlbumState> {
final RetrieveAllAlbums _retrieveAllAlbums;
AlbumBloc(this._retrieveAllAlbums) : super(const AlbumState()) {
on<AlbumFetched>(
_onAlbumFetched,
transformer: throttleDroppable(throttleDuration),
);
}
final RetrieveAllAlbums _retrieveAllAlbums;
Future<void> _onAlbumFetched(
AlbumFetched event,
@@ -35,7 +35,7 @@ class AlbumsScreen extends BlocScreen<AlbumBloc, AlbumEvent, AlbumState> {
bloc..add(AlbumFetched());
@override
Widget onWrap(BuildContext context, Widget child) => AlbumsWrapperWidget(
Widget parent(BuildContext context, Widget child) => AlbumsWrapperWidget(
child: child,
);
@@ -22,8 +22,11 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class AlbumsList extends StatefulWidget {
const AlbumsList(
{required this.albums, required this.hasReachedMax, super.key,});
const AlbumsList({
required this.albums,
required this.hasReachedMax,
super.key,
});
final List<Album> albums;
final bool hasReachedMax;
@@ -26,19 +26,17 @@ abstract class PhotoDetailsState extends Equatable {
class PhotoDetailsInitial extends PhotoDetailsState {}
class PhotoDetailsSuccess extends PhotoDetailsState {
const PhotoDetailsSuccess(this.photo, {required this.isFavorite});
final Photo photo;
final bool isFavorite;
const PhotoDetailsSuccess(this.photo, {required this.isFavorite});
@override
List<Object> get props => [photo, isFavorite];
}
class PhotoDetailsFailure extends PhotoDetailsState {
final String error;
const PhotoDetailsFailure(this.error);
final String error;
@override
List<Object> get props => [error];
@@ -43,7 +43,7 @@ class PhotoDetailsScreen
bloc..load(photoId);
@override
Widget onWrap(BuildContext context, Widget child) =>
Widget parent(BuildContext context, Widget child) =>
PhotoDetailsWrapperWidget(child: child);
@override
@@ -23,10 +23,9 @@ import 'package:flutter_bloc/flutter_bloc.dart';
part 'favorite_checker_state.dart';
class FavoriteCheckerCubit extends Cubit<FavoriteCheckerState> {
final CheckIfPhotoIsInFavorites _checkIfPhotoIsInFavorites;
FavoriteCheckerCubit(this._checkIfPhotoIsInFavorites)
: super(FavoriteCheckerInitial());
final CheckIfPhotoIsInFavorites _checkIfPhotoIsInFavorites;
FutureOr<void> checkIfPhotoIsInFavorites(int photoId) async {
final response = await _checkIfPhotoIsInFavorites.call(photoId);
@@ -10,19 +10,17 @@ abstract class FavoriteCheckerState extends Equatable {
class FavoriteCheckerInitial extends FavoriteCheckerState {}
class FavoriteCheckerSuccess extends FavoriteCheckerState {
const FavoriteCheckerSuccess(this.photoId, {required this.isFavorite});
final int photoId;
final bool isFavorite;
const FavoriteCheckerSuccess(this.photoId, {required this.isFavorite});
@override
List<Object> get props => [photoId, isFavorite];
}
class FavoriteCheckerFailure extends FavoriteCheckerState {
final String error;
const FavoriteCheckerFailure(this.error);
final String error;
@override
List<Object> get props => [error];
@@ -33,14 +33,13 @@ EventTransformer<E> throttleDroppable<E>(Duration duration) =>
(events, mapper) => droppable<E>().call(events.throttle(duration), mapper);
class PhotoBloc extends Bloc<PhotoEvent, PhotoState> {
final OpenAlbum _openAlbum;
PhotoBloc(this._openAlbum) : super(const PhotoState()) {
on<PhotoFetched>(
_onPhotoFetched,
transformer: throttleDroppable(throttleDuration),
);
}
final OpenAlbum _openAlbum;
Future<void> _onPhotoFetched(
PhotoFetched event,
@@ -24,7 +24,6 @@ abstract class PhotoEvent extends Equatable {
}
class PhotoFetched extends PhotoEvent {
final int albumId;
const PhotoFetched(this.albumId);
final int albumId;
}
@@ -37,7 +37,7 @@ class PhotosScreen extends BlocScreen<PhotoBloc, PhotoEvent, PhotoState> {
bloc..add(PhotoFetched(albumId));
@override
Widget onWrap(BuildContext context, Widget child) => PhotosWrapperWidget(
Widget parent(BuildContext context, Widget child) => PhotosWrapperWidget(
child: child,
);
@@ -71,17 +71,17 @@ class _PhotosGridState extends State<PhotosGrid> {
@override
Widget build(BuildContext context) => GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisSpacing: 4,
mainAxisSpacing: 4,
crossAxisCount: 4,
),
itemCount: widget.hasReachedMax
? widget.photos.length
: widget.photos.length + 1,
controller: _scrollController,
itemBuilder: (context, index) => index >= widget.photos.length
? const BottomLoader()
: PhotosGridThumbnail(photo: widget.photos[index]),
);
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisSpacing: 4,
mainAxisSpacing: 4,
crossAxisCount: 4,
),
itemCount: widget.hasReachedMax
? widget.photos.length
: widget.photos.length + 1,
controller: _scrollController,
itemBuilder: (context, index) => index >= widget.photos.length
? const BottomLoader()
: PhotosGridThumbnail(photo: widget.photos[index]),
);
}
@@ -55,7 +55,10 @@ class PhotosGridThumbnail
),
if (state is FavoriteCheckerSuccess && state.isFavorite) ...[
const Positioned(
bottom: 10, right: 10, child: Icon(Icons.favorite),)
bottom: 10,
right: 10,
child: Icon(Icons.favorite),
)
]
],
),
@@ -67,7 +67,7 @@ dev_dependencies:
wyatt_analysis:
git:
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
ref: wyatt_analysis-v2.2.2
ref: wyatt_analysis-v2.4.1
path: packages/wyatt_analysis
# For information on the generic Dart part of this file, see the
@@ -17,9 +17,8 @@
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
abstract class AppException implements Exception {
final String? message;
AppException([this.message]);
final String? message;
@override
String toString() {
+1 -1
View File
@@ -24,4 +24,4 @@ dev_dependencies:
wyatt_analysis:
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub
version: ^2.2.2
version: ^2.4.1
@@ -1,3 +1,14 @@
## 0.4.1
- **REFACTOR**: use fromFirebaseUser factory to parse user.
- **REFACTOR**: update deps and re-export them.
- **FIX**: fix mock on register.
- **FEAT**: add google sign in in signIn cubit.
- **FEAT**: add google sign in parameter in firebase data source constructor.
- **FEAT**: add google sign_in support (closes #59).
- **FEAT**: add reauthenticate, updateEmail and updatePassword.
- **DOCS**: add correct header.
## 0.4.0+3
- Update a dependency to the latest release.
@@ -1,4 +1 @@
include: package:wyatt_analysis/analysis_options.flutter.yaml
analyzer:
exclude: "!example/**"
@@ -45,5 +45,3 @@ app.*.map.json
/android/app/debug
/android/app/profile
/android/app/release
firebase_options.dart
@@ -4,7 +4,7 @@
* -----
* File: launch.json
* Created Date: 19/08/2022 15:12:25
* Last Modified: 19/08/2022 15:22:02
* Last Modified: Tue Dec 13 2022
* -----
* Copyright (c) 2022
*/
@@ -15,11 +15,18 @@
"version": "0.2.0",
"configurations": [
{
"name": "example_router",
"name": "Mock",
"request": "launch",
"type": "dart",
"program": "lib/main.dart",
"flutterMode": "debug"
},
{
"name": "Firebase",
"request": "launch",
"type": "dart",
"program": "lib/main_firebase.dart",
"flutterMode": "debug"
}
]
}
@@ -5,41 +5,30 @@ PODS:
- AppAuth/Core (1.6.0)
- AppAuth/ExternalUserAgent (1.6.0):
- AppAuth/Core
- FBAEMKit (14.1.0):
- FBSDKCoreKit_Basics (= 14.1.0)
- FBSDKCoreKit (14.1.0):
- FBAEMKit (= 14.1.0)
- FBSDKCoreKit_Basics (= 14.1.0)
- FBSDKCoreKit_Basics (14.1.0)
- FBSDKLoginKit (14.1.0):
- FBSDKCoreKit (= 14.1.0)
- Firebase/Auth (10.0.0):
- Firebase/Auth (10.3.0):
- Firebase/CoreOnly
- FirebaseAuth (~> 10.0.0)
- Firebase/CoreOnly (10.0.0):
- FirebaseCore (= 10.0.0)
- firebase_auth (4.1.1):
- Firebase/Auth (= 10.0.0)
- FirebaseAuth (~> 10.3.0)
- Firebase/CoreOnly (10.3.0):
- FirebaseCore (= 10.3.0)
- firebase_auth (4.2.0):
- Firebase/Auth (= 10.3.0)
- firebase_core
- Flutter
- firebase_core (2.1.1):
- Firebase/CoreOnly (= 10.0.0)
- firebase_core (2.4.0):
- Firebase/CoreOnly (= 10.3.0)
- Flutter
- FirebaseAuth (10.0.0):
- FirebaseAuth (10.3.0):
- FirebaseCore (~> 10.0)
- GoogleUtilities/AppDelegateSwizzler (~> 7.8)
- GoogleUtilities/Environment (~> 7.8)
- GTMSessionFetcher/Core (~> 2.1)
- FirebaseCore (10.0.0):
- GTMSessionFetcher/Core (< 4.0, >= 2.1)
- FirebaseCore (10.3.0):
- FirebaseCoreInternal (~> 10.0)
- GoogleUtilities/Environment (~> 7.8)
- GoogleUtilities/Logger (~> 7.8)
- FirebaseCoreInternal (10.1.0):
- FirebaseCoreInternal (10.3.0):
- "GoogleUtilities/NSData+zlib (~> 7.8)"
- Flutter (1.0.0)
- flutter_facebook_auth (4.4.1):
- FBSDKLoginKit (= 14.1.0)
- Flutter
- google_sign_in_ios (0.0.1):
- Flutter
- GoogleSignIn (~> 6.2)
@@ -47,47 +36,36 @@ PODS:
- AppAuth (~> 1.5)
- GTMAppAuth (~> 1.3)
- GTMSessionFetcher/Core (< 3.0, >= 1.1)
- GoogleUtilities/AppDelegateSwizzler (7.8.0):
- GoogleUtilities/AppDelegateSwizzler (7.10.0):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
- GoogleUtilities/Network
- GoogleUtilities/Environment (7.8.0):
- GoogleUtilities/Environment (7.10.0):
- PromisesObjC (< 3.0, >= 1.2)
- GoogleUtilities/Logger (7.8.0):
- GoogleUtilities/Logger (7.10.0):
- GoogleUtilities/Environment
- GoogleUtilities/Network (7.8.0):
- GoogleUtilities/Network (7.10.0):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Reachability
- "GoogleUtilities/NSData+zlib (7.8.0)"
- GoogleUtilities/Reachability (7.8.0):
- "GoogleUtilities/NSData+zlib (7.10.0)"
- GoogleUtilities/Reachability (7.10.0):
- GoogleUtilities/Logger
- GTMAppAuth (1.3.1):
- AppAuth/Core (~> 1.6)
- GTMSessionFetcher/Core (< 3.0, >= 1.5)
- GTMSessionFetcher/Core (2.1.0)
- GTMSessionFetcher/Core (2.3.0)
- PromisesObjC (2.1.1)
- sign_in_with_apple (0.0.1):
- Flutter
- twitter_login (0.0.1):
- Flutter
DEPENDENCIES:
- firebase_auth (from `.symlinks/plugins/firebase_auth/ios`)
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
- Flutter (from `Flutter`)
- flutter_facebook_auth (from `.symlinks/plugins/flutter_facebook_auth/ios`)
- google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/ios`)
- sign_in_with_apple (from `.symlinks/plugins/sign_in_with_apple/ios`)
- twitter_login (from `.symlinks/plugins/twitter_login/ios`)
SPEC REPOS:
trunk:
- AppAuth
- FBAEMKit
- FBSDKCoreKit
- FBSDKCoreKit_Basics
- FBSDKLoginKit
- Firebase
- FirebaseAuth
- FirebaseCore
@@ -105,37 +83,24 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/firebase_core/ios"
Flutter:
:path: Flutter
flutter_facebook_auth:
:path: ".symlinks/plugins/flutter_facebook_auth/ios"
google_sign_in_ios:
:path: ".symlinks/plugins/google_sign_in_ios/ios"
sign_in_with_apple:
:path: ".symlinks/plugins/sign_in_with_apple/ios"
twitter_login:
:path: ".symlinks/plugins/twitter_login/ios"
SPEC CHECKSUMS:
AppAuth: 8fca6b5563a5baef2c04bee27538025e4ceb2add
FBAEMKit: a899515e45476027f73aef377b5cffadcd56ca3a
FBSDKCoreKit: 24f8bc8d3b5b2a8c5c656a1329492a12e8efa792
FBSDKCoreKit_Basics: 6e578c9bdc7aa1365dbbbde633c9ebb536bcaa98
FBSDKLoginKit: 787de205d524c3a4b17d527916f1d066e4361660
Firebase: 1b810f3d0c0532e27a48f1961f8c0400a668a2cf
firebase_auth: dd33e93fce72a1c72040f7380dacf06e89db5705
firebase_core: 5c0bb0ca7d0e70480a68a6e9ad9bf55d1edd5305
FirebaseAuth: 493382cf533cc45e2862b00e9aa4cfe4c98daf71
FirebaseCore: 97f48a3a567a72b8d4daa0f03c3aadb78df4e995
FirebaseCoreInternal: 96d75228e10fd369564da51bd898414eb0f54df5
Firebase: f92fc551ead69c94168d36c2b26188263860acd9
firebase_auth: 579a0dc15451491cc83fccaa5102296635f24938
firebase_core: 6f2f753e316765799d88568232ed59e300ff53db
FirebaseAuth: 0e415d29d846c1dce2fb641e46f35e9888d9bec6
FirebaseCore: 988754646ab3bd4bdcb740f1bfe26b9f6c0d5f2a
FirebaseCoreInternal: 29b76f784d607df8b2a1259d73c3f04f1210137b
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_facebook_auth: 361ac7a57263ebf327f26089507ead0d66558ee8
google_sign_in_ios: 4f85eb9f937450765c8573bb85fd8cd6a5af675c
GoogleSignIn: 5651ce3a61e56ca864160e79b484cd9ed3f49b7a
GoogleUtilities: 1d20a6ad97ef46f67bbdec158ce00563a671ebb7
GoogleUtilities: bad72cb363809015b1f7f19beb1f1cd23c589f95
GTMAppAuth: 0ff230db599948a9ad7470ca667337803b3fc4dd
GTMSessionFetcher: ffbb25ec00ebcb5201adab0a56d808f6f1902d9f
GTMSessionFetcher: 3a63d75eecd6aa32c2fc79f578064e1214dfdec2
PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb
sign_in_with_apple: f3bf75217ea4c2c8b91823f225d70230119b8440
twitter_login: 2794db69b7640681171b17b3c2c84ad9dfb4a57f
PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3
@@ -28,6 +28,17 @@
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>com.googleusercontent.apps.405351917235-2jv4ff02kovoim58f8d6d0rsa14apgkj</string>
</array>
</dict>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
@@ -1,7 +1,7 @@
{
"file_generated_by": "FlutterFire CLI",
"purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory",
"GOOGLE_APP_ID": "1:136771801992:ios:bcdca68d2b7d227097203d",
"FIREBASE_PROJECT_ID": "tchat-beta",
"GCM_SENDER_ID": "136771801992"
"GOOGLE_APP_ID": "1:405351917235:ios:869f0ad8ace08db899f2c6",
"FIREBASE_PROJECT_ID": "meerabel-dev",
"GCM_SENDER_ID": "405351917235"
}
@@ -1,19 +1,64 @@
// Author: Hugo Pointcheval
// Email: git@pcl.ovh
// -----
// File: bootstrap.dart
// Created Date: 19/08/2022 15:05:17
// Last Modified: Fri Nov 11 2022
// -----
// Copyright (c) 2022
// 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:async';
import 'package:example_router/core/dependency_injection/get_it.dart';
import 'package:example_router/core/utils/app_bloc_observer.dart';
import 'package:example_router/firebase_options.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class MockSettings {
static MockSettings? _instance;
/// Data source mode
late bool enable = false;
MockSettings._(this.enable);
factory MockSettings.enable() {
_instance ??= MockSettings._(true);
if (_instance!.enable != true) {
throw Exception('Mock already initialized in: ${_instance!.enable}');
}
return _instance!;
}
factory MockSettings.disable() {
_instance ??= MockSettings._(false);
if (_instance!.enable != false) {
throw Exception('Mock already initialized in: ${_instance!.enable}');
}
return _instance!;
}
static bool isEnable() {
if (_instance == null) {
throw Exception('MockSettings not initialized!');
}
return _instance!.enable == true;
}
static bool isDisable() {
return !isEnable();
}
}
Future<void> bootstrap(FutureOr<Widget> Function() builder) async {
await runZonedGuarded(
() async {
@@ -23,6 +68,12 @@ Future<void> bootstrap(FutureOr<Widget> Function() builder) async {
FlutterError.onError = (details) {
debugPrint(details.toString());
};
if (MockSettings.isDisable()) {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
}
await GetItInitializer.init();
runApp(await builder());
@@ -1,12 +1,20 @@
// Author: Hugo Pointcheval
// Email: git@pcl.ovh
// -----
// File: form_field.dart
// Created Date: 19/08/2022 11:52:33
// Last Modified: 19/08/2022 16:35:39
// -----
// Copyright (c) 2022
// 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/>.
abstract class AppFormField {
static const oldPassword = 'oldPassword';
static const confirmedPassword = 'confirmedPassword';
}
@@ -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/>.
abstract class AppFormName {
static const editProfile = 'editProfile';
}
@@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:example_router/bootstrap.dart';
import 'package:example_router/firebase_options.dart';
import 'package:get_it/get_it.dart';
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
@@ -24,28 +26,32 @@ abstract class GetItInitializer {
static Future<void> init() async {
getIt
..registerLazySingleton<AuthenticationRemoteDataSource>(
() => AuthenticationMockDataSourceImpl(registeredAccounts: [
Pair(
AccountModel(
uid: '1',
emailVerified: true,
isAnonymous: false,
providerId: 'wyatt',
email: 'toto@test.fr',
),
'toto1234',
),
Pair(
AccountModel(
uid: '2',
emailVerified: false,
isAnonymous: false,
providerId: 'wyatt',
email: 'tata@test.fr',
),
'tata1234',
),
]),
MockSettings.isEnable()
? () => AuthenticationMockDataSourceImpl(registeredAccounts: [
Pair(
AccountModel(
uid: '1',
emailVerified: true,
isAnonymous: false,
providerId: 'wyatt',
email: 'toto@test.fr',
),
'toto1234',
),
Pair(
AccountModel(
uid: '2',
emailVerified: false,
isAnonymous: false,
providerId: 'wyatt',
email: 'tata@test.fr',
),
'tata1234',
),
])
: () => AuthenticationFirebaseDataSourceImpl(
googleSignIn: GoogleSignIn(
clientId: DefaultFirebaseOptions.ios.iosClientId)),
)
..registerLazySingleton<AuthenticationCacheDataSource<int>>(
() => AuthenticationCacheDataSourceImpl<int>(),
@@ -1,12 +1,20 @@
// Author: Hugo Pointcheval
// Email: git@pcl.ovh
// -----
// File: router.dart
// Created Date: 19/08/2022 11:52:22
// Last Modified: 19/08/2022 16:39:07
// -----
// Copyright (c) 2022
// 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/presentation/features/edit_profile/edit_profile_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_up/sign_up_page.dart';
@@ -75,5 +83,14 @@ class AppRouter {
const SubPage(),
),
),
GoRoute(
path: '/home/edit',
name: EditProfilePage.pageName,
pageBuilder: (context, state) => defaultTransition(
context,
state,
const EditProfilePage(),
),
),
];
}
@@ -1,11 +1,18 @@
// Author: Hugo Pointcheval
// Email: git@pcl.ovh
// -----
// File: app_bloc_observer.dart
// Created Date: 19/08/2022 12:02:23
// Last Modified: 19/08/2022 12:02:45
// -----
// Copyright (c) 2022
// 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/foundation.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -14,33 +14,19 @@
// 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;
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 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;
}
abstract class AppForms {
static WyattForm getEditProfileForm() => WyattFormImpl(
[
FormInput(AuthFormField.email, const Email.pure()),
FormInput(AuthFormField.password, const CustomPassword.pure()),
FormInput(AppFormField.oldPassword, const CustomPassword.pure()),
],
name: AppFormName.editProfile,
);
}
@@ -0,0 +1,67 @@
// File generated by FlutterFire CLI.
// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
show defaultTargetPlatform, kIsWeb, TargetPlatform;
/// Default [FirebaseOptions] for use with your Firebase apps.
///
/// Example:
/// ```dart
/// import 'firebase_options.dart';
/// // ...
/// await Firebase.initializeApp(
/// options: DefaultFirebaseOptions.currentPlatform,
/// );
/// ```
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
if (kIsWeb) {
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for web - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
}
switch (defaultTargetPlatform) {
case TargetPlatform.android:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for android - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.iOS:
return ios;
case TargetPlatform.macOS:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for macos - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.windows:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for windows - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.linux:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for linux - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
default:
throw UnsupportedError(
'DefaultFirebaseOptions are not supported for this platform.',
);
}
}
static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'AIzaSyDDmtf0KN7Xw12_pqUsxoBfAxMuvCMmMmk',
appId: '1:405351917235:ios:869f0ad8ace08db899f2c6',
messagingSenderId: '405351917235',
projectId: 'meerabel-dev',
storageBucket: 'meerabel-dev.appspot.com',
androidClientId:
'405351917235-4g1dh3475tq6t1sa2qoh7ol60nf4ta05.apps.googleusercontent.com',
iosClientId:
'405351917235-2jv4ff02kovoim58f8d6d0rsa14apgkj.apps.googleusercontent.com',
iosBundleId: 'com.example.exampleRouter',
);
}
@@ -1,6 +1,23 @@
// 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/presentation/features/app/app.dart';
void main() {
MockSettings.enable();
bootstrap(App.new);
}
@@ -14,6 +14,10 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'dart:io';
import 'package:example_router/bootstrap.dart';
import 'package:example_router/presentation/features/app/app.dart';
bool get supportsAnsiColor => stdout.supportsAnsiEscapes;
void main() {
MockSettings.disable();
bootstrap(App.new);
}
@@ -1,11 +1,18 @@
// Author: Hugo Pointcheval
// Email: git@pcl.ovh
// -----
// File: app.dart
// Created Date: 19/08/2022 12:05:38
// Last Modified: Sat Dec 03 2022
// -----
// Copyright (c) 2022
// 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:async';
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/routes/router.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_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
@@ -69,7 +77,7 @@ class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
AuthenticationState? previous;
AuthenticationState<int>? previous;
final AuthenticationCubit<int> authenticationCubit =
AuthenticationCubit(authenticationRepository: authenticationRepository);
@@ -85,29 +93,18 @@ class App extends StatelessWidget {
redirect: (context, state) {
final authState = authenticationCubit.state;
if (authState != previous) {
if (authState.status != previous?.status) {
previous = authState;
// Check if current user is logged in
final loggedIn =
authState.status == AuthenticationStatus.authenticated;
// Checking if current path is onboarding or not
final isOnboarding = AppRouter.publicRoutes.contains(state.subloc);
if (!loggedIn) {
if (authState.status == AuthenticationStatus.unauthenticated) {
debugPrint('Not logged');
if (isOnboarding) {
return null;
} else {
if (!isOnboarding) {
return '/';
}
} else {
} else if (authState.status == AuthenticationStatus.authenticated) {
debugPrint('Logged');
if (isOnboarding) {
return '/home';
} else {
return null;
}
return '/home';
}
}
return null;
@@ -116,9 +113,13 @@ class App extends StatelessWidget {
return MultiRepositoryProvider(
providers: [
RepositoryProvider<AuthenticationRepository>.value(
RepositoryProvider<AuthenticationRepository<int>>.value(
value: authenticationRepository,
),
RepositoryProvider<FormRepository>(
create: (context) =>
FormRepositoryImpl()..registerForm(AppForms.getEditProfileForm()),
),
],
child: MultiBlocProvider(
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
// Email: git@pcl.ovh
// -----
// File: home_page.dart
// Created Date: 19/08/2022 14:38:24
// Last Modified: Wed Nov 09 2022
// -----
// Copyright (c) 2022
// 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/presentation/features/edit_profile/edit_profile_page.dart';
import 'package:example_router/presentation/features/sub/sub_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -25,7 +33,8 @@ class HomePage extends StatelessWidget {
title: const Text('Home'),
actions: [
IconButton(
onPressed: () => context.read<AuthenticationCubit<int>>().signOut(),
onPressed: () =>
context.read<AuthenticationCubit<int>>().signOut(),
icon: const Icon(Icons.logout_rounded))
],
),
@@ -35,8 +44,8 @@ class HomePage extends StatelessWidget {
child: Column(
children: [
AuthenticationBuilder<int>(
authenticated: (context, accountWrapper) =>
Text('Logged as ${accountWrapper.account?.email} | GeneratedId is ${accountWrapper.data}'),
authenticated: (context, accountWrapper) => Text(
'Logged as ${accountWrapper.account?.email} | GeneratedId is ${accountWrapper.data}'),
unauthenticated: (context) =>
const Text('Not logged (unauthenticated)'),
unknown: (context) => const Text('Not logged (unknown)'),
@@ -45,8 +54,13 @@ class HomePage extends StatelessWidget {
height: 8,
),
ElevatedButton(
onPressed: () => context.pushNamed(SubPage.pageName),
child: const Text('Go to sub page')),
onPressed: () => context.pushNamed(SubPage.pageName),
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
// Email: git@pcl.ovh
// -----
// File: sign_in_page.dart
// Created Date: 19/08/2022 12:41:42
// Last Modified: 19/08/2022 15:26:36
// -----
// Copyright (c) 2022
// 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/presentation/features/sign_in/widgets/sign_in_form.dart';
import 'package:flutter/material.dart';
@@ -1,11 +1,18 @@
// Author: Hugo Pointcheval
// Email: git@pcl.ovh
// -----
// File: sign_in_form.dart
// Created Date: 19/08/2022 15:24:37
// Last Modified: Sat Dec 03 2022
// -----
// Copyright (c) 2022
// 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/utils/custom_password.dart';
import 'package:flutter/material.dart';
@@ -87,6 +94,22 @@ class _SignInAnonymouslyButton extends StatelessWidget {
}
}
class _SignInWithGoogleButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SubmitBuilder<SignInCubit<int>>(
builder: ((context, cubit, status) {
return status.isSubmissionInProgress
? const CircularProgressIndicator()
: ElevatedButton(
onPressed: () => cubit.signInWithGoogle(),
child: const Text('Sign in Google'),
);
}),
);
}
}
class SignInForm extends StatelessWidget {
const SignInForm({Key? key}) : super(key: key);
@@ -109,6 +132,8 @@ class SignInForm extends StatelessWidget {
_SignInButton(),
const SizedBox(height: 16),
_SignInAnonymouslyButton(),
const SizedBox(height: 16),
_SignInWithGoogleButton(),
],
),
),
@@ -1,11 +1,18 @@
// Author: Hugo Pointcheval
// Email: git@pcl.ovh
// -----
// File: sign_up_page.dart
// Created Date: 19/08/2022 12:41:27
// Last Modified: 19/08/2022 14:58:51
// -----
// Copyright (c) 2022
// 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/presentation/features/sign_up/widgets/sign_up_form.dart';
import 'package:flutter/material.dart';
@@ -1,11 +1,18 @@
// Author: Hugo Pointcheval
// Email: git@pcl.ovh
// -----
// File: sign_up_form.dart
// Created Date: 19/08/2022 14:41:08
// Last Modified: Sat Dec 03 2022
// -----
// Copyright (c) 2022
// 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';
@@ -1,11 +1,18 @@
// Author: Hugo Pointcheval
// Email: git@pcl.ovh
// -----
// File: sub_page.dart
// Created Date: 19/08/2022 16:10:05
// Last Modified: Wed Nov 09 2022
// -----
// Copyright (c) 2022
// 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';
@@ -23,8 +30,13 @@ class SubPage extends StatelessWidget {
title: const Text('Sub'),
actions: [
IconButton(
onPressed: () => context.read<AuthenticationCubit<int>>().signOut(),
icon: const Icon(Icons.logout_rounded))
onPressed: () =>
context.read<AuthenticationCubit<int>>().signOut(),
icon: const Icon(Icons.logout_rounded)),
IconButton(
onPressed: () =>
context.read<AuthenticationRepository<int>>().refresh(),
icon: const Icon(Icons.refresh))
],
),
body: const Padding(
@@ -1,11 +1,18 @@
// Author: Hugo Pointcheval
// Email: git@pcl.ovh
// -----
// File: welcome_page.dart
// Created Date: 19/08/2022 12:33:21
// Last Modified: Wed Nov 09 2022
// -----
// Copyright (c) 2022
// 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/presentation/features/sign_in/sign_in_page.dart';
import 'package:example_router/presentation/features/sign_up/sign_up_page.dart';
@@ -18,4 +18,3 @@ export 'constants/form_field.dart';
export 'constants/form_name.dart';
export 'enums/enums.dart';
export 'exceptions/exceptions.dart';
export 'utils/utils.dart';
@@ -20,15 +20,14 @@ part 'exceptions_firebase.dart';
abstract class AuthenticationFailureInterface extends AppException
implements Exception {
AuthenticationFailureInterface(this.code, this.msg);
AuthenticationFailureInterface.fromCode(this.code)
: msg = 'An unknown error occurred.';
String code;
String msg;
@override
String get message => msg;
AuthenticationFailureInterface(this.code, this.msg);
AuthenticationFailureInterface.fromCode(this.code)
: msg = 'An unknown error occurred.';
}
/// {@template apply_action_code_failure}
@@ -256,3 +255,31 @@ abstract class GetIdTokenFailureInterface
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();
}
abstract class ModelParsingFailureInterface
extends AuthenticationFailureInterface {
ModelParsingFailureInterface(super.code, super.msg);
ModelParsingFailureInterface.fromCode(super.code) : super.fromCode();
}
@@ -277,3 +277,82 @@ class GetIdTokenFailureFirebase extends GetIdTokenFailureInterface {
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.';
}
}
}
class ModelParsingFailureFirebase extends ModelParsingFailureInterface {
ModelParsingFailureFirebase([String? code, String? msg])
: super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
ModelParsingFailureFirebase.fromCode(super.code) : super.fromCode();
}
@@ -1,39 +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:math';
import 'package:crypto/crypto.dart';
class Cryptography {
/// Generates a cryptographically secure random nonce, to be included in a
/// credential request.
static String generateNonce([int length = 32]) {
const charset =
'0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._';
final random = Random.secure();
return List.generate(length, (_) => charset[random.nextInt(charset.length)])
.join();
}
/// Returns the sha256 hash of [input] in hex notation.
static String sha256ofString(String input) {
final bytes = utf8.encode(input);
final digest = sha256.convert(bytes);
return digest.toString();
}
}
@@ -20,11 +20,10 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
class AuthenticationCacheDataSourceImpl<T extends Object>
extends AuthenticationCacheDataSource<T> {
AuthenticationCacheDataSourceImpl();
Account? _account;
T? _data;
AuthenticationCacheDataSourceImpl();
@override
Future<void> storeAccount(Account? account) async {
_account = account;
@@ -14,32 +14,21 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:firebase_auth/firebase_auth.dart';
import 'package:wyatt_authentication_bloc/src/data/models/account_model_firebase.dart';
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
class AuthenticationFirebaseDataSourceImpl
extends AuthenticationRemoteDataSource {
AuthenticationFirebaseDataSourceImpl({
FirebaseAuth? firebaseAuth,
GoogleSignIn? googleSignIn,
}) : _firebaseAuth = firebaseAuth ?? FirebaseAuth.instance,
_googleSignIn = googleSignIn ?? GoogleSignIn();
final FirebaseAuth _firebaseAuth;
AuthenticationFirebaseDataSourceImpl({FirebaseAuth? firebaseAuth})
: _firebaseAuth = firebaseAuth ?? FirebaseAuth.instance;
Account _mapper(User user) => AccountModel(
uid: user.uid,
emailVerified: user.emailVerified,
isAnonymous: user.isAnonymous,
providerId: user.providerData.first.providerId,
creationTime: user.metadata.creationTime,
lastSignInTime: user.metadata.lastSignInTime,
isNewUser: (user.metadata.creationTime != null &&
user.metadata.lastSignInTime != null)
? user.metadata.lastSignInTime! == user.metadata.creationTime!
: null,
email: user.email,
phoneNumber: user.phoneNumber,
photoURL: user.photoURL,
);
final GoogleSignIn _googleSignIn;
UserCredential? _latestCreds;
@override
Future<Account> signInWithEmailAndPassword({
@@ -51,12 +40,9 @@ class AuthenticationFirebaseDataSourceImpl
email: email,
password: password,
);
_latestCreds = userCredential;
final user = userCredential.user;
if (user.isNotNull) {
return _mapper(user!);
} else {
throw Exception(); // Get caught just after.
}
return AccountModelFirebase.fromFirebaseUser(user);
} on FirebaseAuthException catch (e) {
throw SignInWithEmailAndPasswordFailureFirebase.fromCode(e.code);
} catch (_) {
@@ -76,12 +62,9 @@ class AuthenticationFirebaseDataSourceImpl
email: email,
password: password,
);
_latestCreds = userCredential;
final user = userCredential.user;
if (user.isNotNull) {
return _mapper(user!);
} else {
throw Exception(); // Get caught just after.
}
return AccountModelFirebase.fromFirebaseUser(user);
} on FirebaseAuthException catch (e) {
throw SignUpWithEmailAndPasswordFailureFirebase.fromCode(e.code);
} catch (_) {
@@ -92,6 +75,7 @@ class AuthenticationFirebaseDataSourceImpl
@override
Future<void> signOut() async {
try {
_latestCreds = null;
await _firebaseAuth.signOut();
} catch (_) {
throw SignOutFailureFirebase();
@@ -117,8 +101,11 @@ class AuthenticationFirebaseDataSourceImpl
@override
Stream<Account?> streamAccount() =>
_firebaseAuth.userChanges().map<Account?>((user) {
final Account? account = (user.isNotNull) ? _mapper(user!) : null;
return account;
try {
return AccountModelFirebase.fromFirebaseUser(user);
} on FirebaseAuthException {
return null;
}
});
@override
@@ -164,12 +151,9 @@ class AuthenticationFirebaseDataSourceImpl
Future<Account> signInAnonymously() async {
try {
final userCredential = await _firebaseAuth.signInAnonymously();
_latestCreds = userCredential;
final user = userCredential.user;
if (user.isNotNull) {
return _mapper(user!);
} else {
throw Exception(); // Get caught just after.
}
return AccountModelFirebase.fromFirebaseUser(user);
} on FirebaseAuthException catch (e) {
throw SignInAnonymouslyFailureFirebase.fromCode(e.code);
} catch (_) {
@@ -177,6 +161,35 @@ class AuthenticationFirebaseDataSourceImpl
}
}
@override
Future<Account> signInWithGoogle() async {
try {
// Trigger the authentication flow
final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
// Obtain the auth details from the request
final GoogleSignInAuthentication? googleAuth =
await googleUser?.authentication;
// Create a new credential
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth?.accessToken,
idToken: googleAuth?.idToken,
);
final userCredential =
await _firebaseAuth.signInWithCredential(credential);
_latestCreds = userCredential;
final user = userCredential.user;
return AccountModelFirebase.fromFirebaseUser(user);
} on FirebaseAuthException catch (e) {
throw SignInWithGoogleFailureFirebase.fromCode(e.code);
} catch (_) {
throw SignInWithGoogleFailureFirebase();
}
}
@override
Future<bool> verifyPasswordResetCode({required String code}) async {
try {
@@ -199,4 +212,48 @@ class AuthenticationFirebaseDataSourceImpl
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;
return AccountModelFirebase.fromFirebaseUser(user);
} 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;
return AccountModelFirebase.fromFirebaseUser(user);
} 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;
return AccountModelFirebase.fromFirebaseUser(user);
} on FirebaseAuthException catch (e) {
throw UpdatePasswordFailureFirebase.fromCode(e.code);
} catch (_) {
throw UpdatePasswordFailureFirebase();
}
}
}
@@ -21,19 +21,19 @@ import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource {
AuthenticationMockDataSourceImpl({
this.idToken = 'fake-id-token',
this.registeredAccounts,
});
Pair<Account, String>? _connectedMock;
Pair<Account, String>? _registeredMock;
DateTime _lastSignInTime = DateTime.now();
final StreamController<Account?> _streamAccount = StreamController()
..add(null);
final List<Pair<Account, String>>? registeredAccounts;
final String idToken;
AuthenticationMockDataSourceImpl({
this.idToken = 'fake-id-token',
this.registeredAccounts,
});
Future<void> _randomDelay() async {
await Future<void>.delayed(
Duration(milliseconds: Random().nextInt(400) + 200),
@@ -111,13 +111,33 @@ class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource {
uid: 'mock-id-anom',
emailVerified: false,
isAnonymous: true,
providerId: 'wyatt',
providerId: 'wyatt-studio.fr',
creationTime: creation,
lastSignInTime: creation,
isNewUser: creation == creation,
);
_streamAccount.add(mock);
_connectedMock = _connectedMock?.copyWith(left: mock);
_lastSignInTime = DateTime.now();
return Future.value(mock);
}
@override
Future<Account> signInWithGoogle() async {
await _randomDelay();
final creation = DateTime.now();
final mock = AccountModel(
uid: 'mock-id-google',
emailVerified: true,
isAnonymous: false,
providerId: 'google.com',
creationTime: creation,
lastSignInTime: creation,
isNewUser: creation == creation,
);
_streamAccount.add(mock);
_connectedMock = _connectedMock?.copyWith(left: mock);
_lastSignInTime = DateTime.now();
return Future.value(mock);
}
@@ -149,6 +169,7 @@ class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource {
}
_streamAccount.add(_registeredMock!.left);
_connectedMock = _registeredMock!.copyWith();
_lastSignInTime = DateTime.now();
return _registeredMock!.left!;
}
throw SignInWithCredentialFailureFirebase();
@@ -193,6 +214,8 @@ class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource {
);
_streamAccount.add(mock);
_registeredMock = Pair(mock, password);
_connectedMock = _registeredMock!.copyWith();
_lastSignInTime = DateTime.now();
return Future.value(mock);
}
@@ -204,4 +227,45 @@ class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource {
await _randomDelay();
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);
}
}
@@ -72,16 +72,17 @@ class AccountModel extends Account {
String? phoneNumber,
String? photoURL,
String? providerId,
}) => AccountModel(
uid: uid ?? this.uid,
email: email ?? this.email,
creationTime: creationTime ?? this.creationTime,
emailVerified: emailVerified ?? this.emailVerified,
isAnonymous: isAnonymous ?? this.isAnonymous,
isNewUser: isNewUser ?? this.isNewUser,
lastSignInTime: lastSignInTime ?? this.lastSignInTime,
phoneNumber: phoneNumber ?? this.phoneNumber,
photoURL: photoURL ?? this.photoURL,
providerId: providerId ?? this.providerId,
);
}) =>
AccountModel(
uid: uid ?? this.uid,
email: email ?? this.email,
creationTime: creationTime ?? this.creationTime,
emailVerified: emailVerified ?? this.emailVerified,
isAnonymous: isAnonymous ?? this.isAnonymous,
isNewUser: isNewUser ?? this.isNewUser,
lastSignInTime: lastSignInTime ?? this.lastSignInTime,
phoneNumber: phoneNumber ?? this.phoneNumber,
photoURL: photoURL ?? this.photoURL,
providerId: providerId ?? this.providerId,
);
}
@@ -0,0 +1,55 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
class AccountModelFirebase extends AccountModel {
AccountModelFirebase._({
required super.uid,
required super.emailVerified,
required super.isAnonymous,
required super.providerId,
super.lastSignInTime,
super.creationTime,
super.isNewUser,
super.email,
super.phoneNumber,
super.photoURL,
});
factory AccountModelFirebase.fromFirebaseUser(User? user) {
if (user != null) {
return AccountModelFirebase._(
uid: user.uid,
emailVerified: user.emailVerified,
isAnonymous: user.isAnonymous,
providerId: user.providerData.first.providerId,
creationTime: user.metadata.creationTime,
lastSignInTime: user.metadata.lastSignInTime,
isNewUser: (user.metadata.creationTime != null &&
user.metadata.lastSignInTime != null)
? user.metadata.lastSignInTime! == user.metadata.creationTime!
: null,
email: user.email,
phoneNumber: user.phoneNumber,
photoURL: user.photoURL,
);
} else {
throw ModelParsingFailureFirebase('null-user', 'User cannot be null!');
}
}
}
@@ -29,8 +29,9 @@ class AccountWrapperModel<T> extends AccountWrapper<T> {
AccountWrapperModel<T> copyWith({
Account? account,
T? data,
}) => AccountWrapperModel<T>(
account ?? this.account,
data ?? this.data,
);
}) =>
AccountWrapperModel<T>(
account ?? this.account,
data ?? this.data,
);
}
@@ -42,19 +42,6 @@ typedef OnAuthChange<T> = FutureOrResult<T?> Function(
class AuthenticationRepositoryImpl<T extends Object>
extends AuthenticationRepository<T> {
final AuthenticationCacheDataSource<T> _authenticationLocalDataSource;
final AuthenticationRemoteDataSource _authenticationRemoteDataSource;
late FormRepository _formRepository;
final OnSignUpSuccess<T>? _onSignUpSuccess;
final OnAuthChange<T>? _onAccountChanges;
final StreamController<FutureOrResult<AccountWrapper<T>>> _signUpStream =
StreamController();
bool _pause = false; // Semaphore
AuthenticationRepositoryImpl({
required AuthenticationCacheDataSource<T> authenticationCacheDataSource,
required AuthenticationRemoteDataSource authenticationRemoteDataSource,
@@ -106,6 +93,18 @@ class AuthenticationRepositoryImpl<T extends Object>
),
);
}
final AuthenticationCacheDataSource<T> _authenticationLocalDataSource;
final AuthenticationRemoteDataSource _authenticationRemoteDataSource;
late FormRepository _formRepository;
final OnSignUpSuccess<T>? _onSignUpSuccess;
final OnAuthChange<T>? _onAccountChanges;
final StreamController<FutureOrResult<AccountWrapper<T>>> _signUpStream =
StreamController();
bool _pause = false;
@override
FormRepository get formRepository => _formRepository;
@@ -295,6 +294,17 @@ class AuthenticationRepositoryImpl<T extends Object>
(error) => error,
);
@override
FutureOrResult<Account> signInWithGoogle() =>
Result.tryCatchAsync<Account, AppException, AppException>(
() async {
final account =
await _authenticationRemoteDataSource.signInWithGoogle();
return account;
},
(error) => error,
);
@override
FutureOrResult<bool> verifyPasswordResetCode({required String code}) =>
Result.tryCatchAsync<bool, AppException, AppException>(
@@ -314,4 +324,38 @@ class AuthenticationRepositoryImpl<T extends Object>
},
(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,12 @@ abstract class AuthenticationRemoteDataSource extends BaseRemoteDataSource {
Future<bool> verifyPasswordResetCode({required String code});
Future<Account> signInAnonymously();
Future<Account> signInWithGoogle();
Future<Account> updateEmail({required String email});
Future<Account> updatePassword({required String password});
Future<Account> reauthenticateWithCredential();
}
@@ -73,6 +73,13 @@ abstract class AuthenticationRepository<T> extends BaseRepository {
/// {@endtemplate}
FutureOrResult<Account> signInAnonymously();
/// {@template signin_google}
/// Starts the Sign In with Google Flow.
///
/// Throws a SignInWithGoogleFailureInterface if an exception occurs.
/// {@endtemplate}
FutureOrResult<Account> signInWithGoogle();
/// {@template signin_pwd}
/// Signs in with the provided [email] and [password].
///
@@ -84,12 +91,45 @@ abstract class AuthenticationRepository<T> extends BaseRepository {
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}
/// Signs out the current user.
/// It also clears the cache and the associated data.
/// {@endtemplate}
FutureOrResult<void> signOut();
/// {@template refresh}
/// Refreshes the current user, if signed in.
/// {@endtemplate}
FutureOrResult<void> refresh();
/// {@template stream_account}
@@ -26,14 +26,13 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
part 'authentication_state.dart';
class AuthenticationCubit<Extra> extends Cubit<AuthenticationState<Extra>> {
final AuthenticationRepository<Extra> _authenticationRepository;
AuthenticationCubit({
required AuthenticationRepository<Extra> authenticationRepository,
}) : _authenticationRepository = authenticationRepository,
super(const AuthenticationState.unknown()) {
_listenForAuthenticationChanges();
}
final AuthenticationRepository<Extra> _authenticationRepository;
void _listenForAuthenticationChanges() {
_authenticationRepository.streamAccount().listen((accountFutureResult) {
@@ -17,13 +17,8 @@
part of 'authentication_cubit.dart';
class AuthenticationState<Extra> extends Equatable {
final AuthenticationStatus status;
final AccountWrapper<Extra>? accountWrapper;
const AuthenticationState._({required this.status, this.accountWrapper});
const AuthenticationState.unknown()
: this._(status: AuthenticationStatus.unknown);
const AuthenticationState.unauthenticated()
: this._(status: AuthenticationStatus.unauthenticated);
const AuthenticationState.authenticated(AccountWrapper<Extra> accountWrapper)
: this._(
@@ -31,8 +26,12 @@ class AuthenticationState<Extra> extends Equatable {
accountWrapper: accountWrapper,
);
const AuthenticationState.unauthenticated()
: this._(status: AuthenticationStatus.unauthenticated);
const AuthenticationState.unknown()
: this._(status: AuthenticationStatus.unknown);
const AuthenticationState._({required this.status, this.accountWrapper});
final AuthenticationStatus status;
final AccountWrapper<Extra>? accountWrapper;
@override
List<Object?> get props => [status, accountWrapper];
@@ -24,12 +24,11 @@ import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
part 'email_verification_state.dart';
class EmailVerificationCubit<Extra> extends Cubit<EmailVerificationState> {
final AuthenticationRepository<Extra> _authenticationRepository;
EmailVerificationCubit({
required AuthenticationRepository<Extra> authenticationRepository,
}) : _authenticationRepository = authenticationRepository,
super(const EmailVerificationState());
final AuthenticationRepository<Extra> _authenticationRepository;
FutureOr<void> sendEmailVerification() async {
emit(state.copyWith(status: FormStatus.submissionInProgress));
@@ -25,10 +25,6 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
part 'password_reset_state.dart';
class PasswordResetCubit<Extra> extends FormDataCubit<PasswordResetState> {
final AuthenticationRepository<Extra> _authenticationRepository;
FormRepository get _formRepository =>
_authenticationRepository.formRepository;
PasswordResetCubit({
required AuthenticationRepository<Extra> authenticationRepository,
}) : _authenticationRepository = authenticationRepository,
@@ -38,6 +34,9 @@ class PasswordResetCubit<Extra> extends FormDataCubit<PasswordResetState> {
.accessForm(AuthFormName.passwordResetForm),
),
);
final AuthenticationRepository<Extra> _authenticationRepository;
FormRepository get _formRepository =>
_authenticationRepository.formRepository;
@override
String get formName => AuthFormName.passwordResetForm;
@@ -17,13 +17,12 @@
part of 'password_reset_cubit.dart';
class PasswordResetState extends FormDataState {
Email get email => form.validatorOf(AuthFormField.email);
const PasswordResetState({
required super.form,
super.status = FormStatus.pure,
super.errorMessage,
});
Email get email => form.validatorOf(AuthFormField.email);
PasswordResetState copyWith({
WyattForm? form,

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