├── .github
└── workflows
│ └── release_deploy_web.yml
├── .gitignore
├── .vscode
├── launch.json
└── mock.rest
├── LICENSE
├── README.md
├── all_lint_rules.yaml
├── analysis_options.yaml
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── brizaldi
│ │ │ │ └── flutter_project_template_riverpod
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable-v21
│ │ │ └── launch_background.xml
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── values-night
│ │ │ └── styles.xml
│ │ │ └── values
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── assets
└── images
│ ├── 2.0x
│ └── flutter_logo.png
│ ├── 3.0x
│ └── flutter_logo.png
│ └── flutter_logo.png
├── flutter_launcher_icons.yaml
├── flutter_native_splash.yaml
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata
│ │ └── xcschemes
│ │ ├── development.xcscheme
│ │ ├── production.xcscheme
│ │ └── staging.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
├── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ └── Icon-App-83.5x83.5@2x.png
│ │ └── LaunchImage.imageset
│ │ │ ├── Contents.json
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ └── README.md
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── Info.plist
│ └── Runner-Bridging-Header.h
└── RunnerTests
│ └── RunnerTests.swift
├── l10n.yaml
├── lib
├── config
│ ├── configuration.dart
│ └── src
│ │ ├── build_config.dart
│ │ └── env.dart
├── constants
│ ├── assets.dart
│ └── strings.dart
├── features
│ ├── auth
│ │ ├── application
│ │ │ ├── auth
│ │ │ │ ├── auth_notifier.dart
│ │ │ │ └── auth_state.dart
│ │ │ ├── sign_in_form
│ │ │ │ ├── sign_in_form_notifier.dart
│ │ │ │ └── sign_in_form_state.dart
│ │ │ └── sign_out
│ │ │ │ ├── sign_out_notifier.dart
│ │ │ │ └── sign_out_state.dart
│ │ ├── domain
│ │ │ ├── auth_failure.dart
│ │ │ ├── user.dart
│ │ │ └── value_objects.dart
│ │ ├── infrastructure
│ │ │ ├── auth_interceptor.dart
│ │ │ ├── auth_remote_service.dart
│ │ │ ├── auth_repository.dart
│ │ │ ├── auth_response.dart
│ │ │ ├── credentials_storage
│ │ │ │ ├── credentials_storage.dart
│ │ │ │ └── secure_credentials_storage.dart
│ │ │ └── dto
│ │ │ │ └── user_dto.dart
│ │ ├── presentation
│ │ │ ├── sign_in_page.dart
│ │ │ └── widgets
│ │ │ │ ├── sign_in_form.dart
│ │ │ │ └── sign_in_scaffold.dart
│ │ └── shared
│ │ │ └── providers.dart
│ ├── core
│ │ ├── application
│ │ │ └── routes
│ │ │ │ ├── route_names.dart
│ │ │ │ └── route_notifier.dart
│ │ ├── domain
│ │ │ ├── errors.dart
│ │ │ ├── failures.dart
│ │ │ └── value_objects.dart
│ │ ├── infrastructure
│ │ │ ├── dio_extensions.dart
│ │ │ ├── exceptions.dart
│ │ │ ├── hive_database.dart
│ │ │ └── remote_response.dart
│ │ ├── presentation
│ │ │ ├── app_widget.dart
│ │ │ └── widgets
│ │ │ │ ├── alert_helper.dart
│ │ │ │ └── loading_overlay.dart
│ │ └── shared
│ │ │ └── providers.dart
│ ├── home
│ │ ├── core
│ │ │ ├── presentation
│ │ │ │ ├── home_page.dart
│ │ │ │ └── widgets
│ │ │ │ │ └── home_scaffold.dart
│ │ │ └── shared
│ │ │ │ └── providers.dart
│ │ └── counter
│ │ │ ├── application
│ │ │ └── counter_notifier.dart
│ │ │ └── presentation
│ │ │ └── counter_page.dart
│ └── splash
│ │ └── presentation
│ │ └── splash_page.dart
├── l10n
│ ├── arb
│ │ ├── app_en.arb
│ │ └── app_id.arb
│ └── l10n.dart
├── main.dart
├── style
│ ├── src
│ │ ├── palette.dart
│ │ └── themes.dart
│ └── style.dart
└── utils
│ ├── logging.dart
│ ├── string_utils.dart
│ ├── validator.dart
│ └── value_validators.dart
├── pubspec.lock
├── pubspec.yaml
├── test
└── .gitkeep
├── web
├── favicon.png
├── icons
│ ├── Icon-192.png
│ ├── Icon-512.png
│ ├── Icon-maskable-192.png
│ └── Icon-maskable-512.png
├── index.html
└── manifest.json
└── windows
├── .gitignore
├── CMakeLists.txt
├── flutter
├── CMakeLists.txt
├── generated_plugin_registrant.cc
├── generated_plugin_registrant.h
└── generated_plugins.cmake
└── runner
├── CMakeLists.txt
├── Runner.rc
├── flutter_window.cpp
├── flutter_window.h
├── main.cpp
├── resource.h
├── resources
└── app_icon.ico
├── runner.exe.manifest
├── utils.cpp
├── utils.h
├── win32_window.cpp
└── win32_window.h
/.github/workflows/release_deploy_web.yml:
--------------------------------------------------------------------------------
1 | name: Deploy to Github Pages
2 |
3 | on:
4 | push:
5 | branches: [master]
6 | paths-ignore:
7 | - '**/README.md'
8 | pull_request:
9 | branches: [master]
10 | workflow_dispatch:
11 |
12 | jobs:
13 | build:
14 | runs-on: ubuntu-latest
15 | env:
16 | FLAVOR: "production"
17 | steps:
18 | - uses: actions/checkout@v2
19 | - uses: subosito/flutter-action@v1
20 | - run: flutter pub get
21 | - run: flutter packages pub run build_runner build --delete-conflicting-outputs
22 | - uses: bluefireteam/flutter-gh-pages@v7
23 | with:
24 | baseHref: /flutter-project-template-riverpod/
25 | customArgs: --dart-define="flavor=$FLAVOR"
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 | migrate_working_dir/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/
18 |
19 | # The .vscode folder contains launch configuration and tasks you configure in
20 | # VS Code which you may wish to be included in version control, so this line
21 | # is commented out by default.
22 | .vscode/settings.json
23 |
24 | # Flutter/Dart/Pub related
25 | **/doc/api/
26 | **/ios/Flutter/.last_build_id
27 | .dart_tool/
28 | .flutter-plugins
29 | .flutter-plugins-dependencies
30 | .pub-cache/
31 | .pub/
32 | /build/
33 |
34 | # Dart generated code related
35 | **.gr.dart
36 | **.g.dart
37 | **.freezed.dart
38 | **.mocks.dart
39 | **.config.dart
40 |
41 | # Android related
42 | **/android/**/gradle-wrapper.jar
43 | **/android/.gradle
44 | **/android/captures/
45 | **/android/gradlew
46 | **/android/gradlew.bat
47 | **/android/local.properties
48 | **/android/**/GeneratedPluginRegistrant.java
49 |
50 | # Android Studio will place build artifacts here
51 | /android/app/debug
52 | /android/app/profile
53 | /android/app/release
54 |
55 | # iOS/XCode related
56 | **/ios/**/*.mode1v3
57 | **/ios/**/*.mode2v3
58 | **/ios/**/*.moved-aside
59 | **/ios/**/*.pbxuser
60 | **/ios/**/*.perspectivev3
61 | **/ios/**/*sync/
62 | **/ios/**/.sconsign.dblite
63 | **/ios/**/.tags*
64 | **/ios/**/.vagrant/
65 | **/ios/**/DerivedData/
66 | **/ios/**/Icon?
67 | **/ios/**/Pods/
68 | **/ios/**/.symlinks/
69 | **/ios/**/profile
70 | **/ios/**/xcuserdata
71 | **/ios/.generated/
72 | **/ios/Flutter/App.framework
73 | **/ios/Flutter/Flutter.framework
74 | **/ios/Flutter/Generated.xcconfig
75 | **/ios/Flutter/app.flx
76 | **/ios/Flutter/app.zip
77 | **/ios/Flutter/flutter_assets/
78 | **/ios/ServiceDefinitions.json
79 | **/ios/Runner/GeneratedPluginRegistrant.*
80 |
81 | # Web related
82 | lib/generated_plugin_registrant.dart
83 |
84 | # Symbolication related
85 | app.*.symbols
86 |
87 | # Obfuscation related
88 | app.*.map.json
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "Flutter: App dev",
9 | "request": "launch",
10 | "type": "dart",
11 | "args": [
12 | "--flavor",
13 | "development",
14 | "--dart-define",
15 | "flavor=development",
16 | ]
17 | },
18 | {
19 | "name": "Flutter: App staging",
20 | "request": "launch",
21 | "type": "dart",
22 | "args": [
23 | "--flavor",
24 | "staging",
25 | "--dart-define",
26 | "flavor=staging",
27 | ]
28 | },
29 | {
30 | "name": "Flutter: App production",
31 | "request": "launch",
32 | "type": "dart",
33 | "args": [
34 | "--flavor",
35 | "production",
36 | "--dart-define",
37 | "flavor=production",
38 | ]
39 | },
40 | {
41 | "name": "Dart: Run all Tests",
42 | "type": "dart",
43 | "request": "launch",
44 | "program": "./test/"
45 | }
46 | ]
47 | }
--------------------------------------------------------------------------------
/.vscode/mock.rest:
--------------------------------------------------------------------------------
1 | @baseUrl = https://6128855786a213001729f948.mockapi.io/api/v1
2 |
3 | POST {{baseUrl}}/login
4 | content-type: application/json
5 |
6 | {
7 | "email": "john@gmail.com",
8 | "password": "12345678"
9 | }
10 | ###
11 | GET {{baseUrl}}/logout
12 | content-type: application/json
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Bahri Rizaldi
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # flutter-project-template-riverpod
2 |
3 | ## Requirements
4 | Flutter: >=3.16.0
5 | Dart SDK: >=3.2.0
6 |
7 | ## Supported Platforms
8 | | Android | iOS | Web | Windows | MacOS | Linux |
9 | | :-----: | :---: | :---: | :-----: | :---: | :---: |
10 | | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
11 |
12 | ## Live Demo
13 | https://brizaldi.github.io/flutter-project-template-riverpod/
14 |
15 | ## Installation
16 | - Add [Flutter](https://flutter.dev/docs/get-started/install 'Flutter') to your machine
17 | - Open this project folder with Terminal/CMD
18 | - Ensure there's no cache/build leftover by running `flutter clean` in the Terminal
19 | - Run in the Terminal `flutter packages get`
20 | - Run in the Terminal `dart run build_runner build --delete-conflicting-outputs`
21 |
22 | ## Additional steps for iOS
23 | - Open ios folder inside Terminal/CMD
24 | - Run in the Terminal `pod install`
25 | - Run in the Terminal `pod update`
26 |
27 | ## Running the App
28 | - Open Android Emulator or iOS Simulator
29 | - Run `flutter run --flavor {RELEASE_TYPE} --dart-define flavor={RELEASE_TYPE}`
30 | - Supported release type: `development`, `staging`, and `production`
31 |
32 | ## Build an APK
33 | - Run `flutter build apk --flavor {RELEASE_TYPE}`
34 | - The apk will be saved under this location: `[project]/build/app/outputs/flutter-apk/`
35 | - We can also build appbundle (.aab) by running this command: `flutter build appbundle --flavor {RELEASE_TYPE} --dart-define flavor={RELEASE_TYPE}`
36 |
37 | ## Build for iOS
38 | - Follow the tutorial from this link: https://flutter.dev/docs/deployment/ios#create-a-build-archive-with-xcode
39 | - Don't forget to add the release type behind the build command
40 | - For example `flutter build ipa --flavor {RELEASE_TYPE} --dart-define flavor={RELEASE_TYPE}`
41 |
42 | For more information, check out the [official documentation](https://flutter.dev/docs 'documentation')
43 |
--------------------------------------------------------------------------------
/all_lint_rules.yaml:
--------------------------------------------------------------------------------
1 | linter:
2 | rules:
3 | - always_declare_return_types
4 | - always_put_control_body_on_new_line
5 | - always_put_required_named_parameters_first
6 | - always_require_non_null_named_parameters
7 | - always_specify_types
8 | - always_use_package_imports
9 | - annotate_overrides
10 | - annotate_redeclares
11 | - avoid_annotating_with_dynamic
12 | - avoid_bool_literals_in_conditional_expressions
13 | - avoid_catches_without_on_clauses
14 | - avoid_catching_errors
15 | - avoid_classes_with_only_static_members
16 | - avoid_double_and_int_checks
17 | - avoid_dynamic_calls
18 | - avoid_empty_else
19 | - avoid_equals_and_hash_code_on_mutable_classes
20 | - avoid_escaping_inner_quotes
21 | - avoid_field_initializers_in_const_classes
22 | - avoid_final_parameters
23 | - avoid_function_literals_in_foreach_calls
24 | - avoid_implementing_value_types
25 | - avoid_init_to_null
26 | - avoid_js_rounded_ints
27 | - avoid_multiple_declarations_per_line
28 | - avoid_null_checks_in_equality_operators
29 | - avoid_positional_boolean_parameters
30 | - avoid_print
31 | - avoid_private_typedef_functions
32 | - avoid_redundant_argument_values
33 | - avoid_relative_lib_imports
34 | - avoid_renaming_method_parameters
35 | - avoid_return_types_on_setters
36 | - avoid_returning_null
37 | - avoid_returning_null_for_future
38 | - avoid_returning_null_for_void
39 | - avoid_returning_this
40 | - avoid_setters_without_getters
41 | - avoid_shadowing_type_parameters
42 | - avoid_single_cascade_in_expression_statements
43 | - avoid_slow_async_io
44 | - avoid_type_to_string
45 | - avoid_types_as_parameter_names
46 | - avoid_types_on_closure_parameters
47 | - avoid_unnecessary_containers
48 | - avoid_unstable_final_fields
49 | - avoid_unused_constructor_parameters
50 | - avoid_void_async
51 | - avoid_web_libraries_in_flutter
52 | - await_only_futures
53 | - camel_case_extensions
54 | - camel_case_types
55 | - cancel_subscriptions
56 | - cascade_invocations
57 | - cast_nullable_to_non_nullable
58 | - close_sinks
59 | - collection_methods_unrelated_type
60 | - combinators_ordering
61 | - comment_references
62 | - conditional_uri_does_not_exist
63 | - constant_identifier_names
64 | - control_flow_in_finally
65 | - curly_braces_in_flow_control_structures
66 | - dangling_library_doc_comments
67 | - depend_on_referenced_packages
68 | - deprecated_consistency
69 | - deprecated_member_use_from_same_package
70 | - diagnostic_describe_all_properties
71 | - directives_ordering
72 | - discarded_futures
73 | - do_not_use_environment
74 | - empty_catches
75 | - empty_constructor_bodies
76 | - empty_statements
77 | - eol_at_end_of_file
78 | - exhaustive_cases
79 | - file_names
80 | - flutter_style_todos
81 | - hash_and_equals
82 | - implementation_imports
83 | - implicit_call_tearoffs
84 | - implicit_reopen
85 | - invalid_case_patterns
86 | - iterable_contains_unrelated_type
87 | - join_return_with_assignment
88 | - leading_newlines_in_multiline_strings
89 | - library_annotations
90 | - library_names
91 | - library_prefixes
92 | - library_private_types_in_public_api
93 | - lines_longer_than_80_chars
94 | - list_remove_unrelated_type
95 | - literal_only_boolean_expressions
96 | - matching_super_parameters
97 | - missing_whitespace_between_adjacent_strings
98 | - no_adjacent_strings_in_list
99 | - no_default_cases
100 | - no_duplicate_case_values
101 | - no_leading_underscores_for_library_prefixes
102 | - no_leading_underscores_for_local_identifiers
103 | - no_literal_bool_comparisons
104 | - no_logic_in_create_state
105 | - no_runtimeType_toString
106 | - no_self_assignments
107 | - no_wildcard_variable_uses
108 | - non_constant_identifier_names
109 | - noop_primitive_operations
110 | - null_check_on_nullable_type_parameter
111 | - null_closures
112 | - omit_local_variable_types
113 | - one_member_abstracts
114 | - only_throw_errors
115 | - overridden_fields
116 | - package_api_docs
117 | - package_names
118 | - package_prefixed_library_names
119 | - parameter_assignments
120 | - prefer_adjacent_string_concatenation
121 | - prefer_asserts_in_initializer_lists
122 | - prefer_asserts_with_message
123 | - prefer_collection_literals
124 | - prefer_conditional_assignment
125 | - prefer_const_constructors
126 | - prefer_const_constructors_in_immutables
127 | - prefer_const_declarations
128 | - prefer_const_literals_to_create_immutables
129 | - prefer_constructors_over_static_methods
130 | - prefer_contains
131 | - prefer_double_quotes
132 | - prefer_expression_function_bodies
133 | - prefer_final_fields
134 | - prefer_final_in_for_each
135 | - prefer_final_locals
136 | - prefer_final_parameters
137 | - prefer_for_elements_to_map_fromIterable
138 | - prefer_foreach
139 | - prefer_function_declarations_over_variables
140 | - prefer_generic_function_type_aliases
141 | - prefer_if_elements_to_conditional_expressions
142 | - prefer_if_null_operators
143 | - prefer_initializing_formals
144 | - prefer_inlined_adds
145 | - prefer_int_literals
146 | - prefer_interpolation_to_compose_strings
147 | - prefer_is_empty
148 | - prefer_is_not_empty
149 | - prefer_is_not_operator
150 | - prefer_iterable_whereType
151 | - prefer_mixin
152 | - prefer_null_aware_method_calls
153 | - prefer_null_aware_operators
154 | - prefer_relative_imports
155 | - prefer_single_quotes
156 | - prefer_spread_collections
157 | - prefer_typing_uninitialized_variables
158 | - prefer_void_to_null
159 | - provide_deprecation_message
160 | - public_member_api_docs
161 | - recursive_getters
162 | - require_trailing_commas
163 | - secure_pubspec_urls
164 | - sized_box_for_whitespace
165 | - sized_box_shrink_expand
166 | - slash_for_doc_comments
167 | - sort_child_properties_last
168 | - sort_constructors_first
169 | - sort_pub_dependencies
170 | - sort_unnamed_constructors_first
171 | - test_types_in_equals
172 | - throw_in_finally
173 | - tighten_type_of_initializing_formals
174 | - type_annotate_public_apis
175 | - type_init_formals
176 | - type_literal_in_constant_pattern
177 | - unawaited_futures
178 | - unnecessary_await_in_return
179 | - unnecessary_brace_in_string_interps
180 | - unnecessary_breaks
181 | - unnecessary_const
182 | - unnecessary_constructor_name
183 | - unnecessary_final
184 | - unnecessary_getters_setters
185 | - unnecessary_lambdas
186 | - unnecessary_late
187 | - unnecessary_library_directive
188 | - unnecessary_new
189 | - unnecessary_null_aware_assignments
190 | - unnecessary_null_aware_operator_on_extension_on_nullable
191 | - unnecessary_null_checks
192 | - unnecessary_null_in_if_null_operators
193 | - unnecessary_nullable_for_final_variable_declarations
194 | - unnecessary_overrides
195 | - unnecessary_parenthesis
196 | - unnecessary_raw_strings
197 | - unnecessary_statements
198 | - unnecessary_string_escapes
199 | - unnecessary_string_interpolations
200 | - unnecessary_this
201 | - unnecessary_to_list_in_spreads
202 | - unreachable_from_main
203 | - unrelated_type_equality_checks
204 | - unsafe_html
205 | - use_build_context_synchronously
206 | - use_colored_box
207 | - use_decorated_box
208 | - use_enums
209 | - use_full_hex_values_for_flutter_colors
210 | - use_function_type_syntax_for_parameters
211 | - use_if_null_to_convert_nulls_to_bools
212 | - use_is_even_rather_than_modulo
213 | - use_key_in_widget_constructors
214 | - use_late_for_private_fields_and_variables
215 | - use_named_constants
216 | - use_raw_strings
217 | - use_rethrow_when_possible
218 | - use_setters_to_change_properties
219 | - use_string_buffers
220 | - use_string_in_part_of_directives
221 | - use_super_parameters
222 | - use_test_throws_matchers
223 | - use_to_and_as_if_applicable
224 | - valid_regexps
225 | - void_checks
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id "com.android.application"
3 | id "kotlin-android"
4 | id "dev.flutter.flutter-gradle-plugin"
5 | }
6 |
7 | def localProperties = new Properties()
8 | def localPropertiesFile = rootProject.file('local.properties')
9 | if (localPropertiesFile.exists()) {
10 | localPropertiesFile.withReader('UTF-8') { reader ->
11 | localProperties.load(reader)
12 | }
13 | }
14 |
15 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
16 | if (flutterVersionCode == null) {
17 | flutterVersionCode = '1'
18 | }
19 |
20 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
21 | if (flutterVersionName == null) {
22 | flutterVersionName = '1.0'
23 | }
24 |
25 | android {
26 | namespace "com.brizaldi.flutter_project_template_riverpod"
27 | compileSdkVersion 34
28 | ndkVersion flutter.ndkVersion
29 |
30 | compileOptions {
31 | sourceCompatibility JavaVersion.VERSION_1_8
32 | targetCompatibility JavaVersion.VERSION_1_8
33 | }
34 |
35 | kotlinOptions {
36 | jvmTarget = '1.8'
37 | }
38 |
39 | sourceSets {
40 | main.java.srcDirs += 'src/main/kotlin'
41 | }
42 |
43 | defaultConfig {
44 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
45 | applicationId "com.brizaldi.flutter_project_template_riverpod"
46 | // You can update the following values to match your application needs.
47 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
48 | minSdkVersion 21
49 | targetSdkVersion flutter.targetSdkVersion
50 | versionCode flutterVersionCode.toInteger()
51 | versionName flutterVersionName
52 | }
53 |
54 | buildTypes {
55 | release {
56 | // TODO: Add your own signing config for the release build.
57 | // Signing with the debug keys for now, so `flutter run --release` works.
58 | signingConfig signingConfigs.debug
59 | }
60 | }
61 |
62 | flavorDimensions "default"
63 |
64 | productFlavors {
65 | development {
66 | applicationIdSuffix ".dev"
67 | versionNameSuffix = "-dev"
68 | resValue "string", "app_name", "App Template Dev"
69 | }
70 | staging {
71 | applicationIdSuffix ".staging"
72 | versionNameSuffix = "-staging"
73 | resValue "string", "app_name", "App Template Stg"
74 | }
75 | production {
76 | resValue "string", "app_name", "App Template"
77 | }
78 | }
79 | }
80 |
81 | flutter {
82 | source '../..'
83 | }
84 |
85 | dependencies {}
86 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
14 |
18 |
22 |
23 |
24 |
25 |
26 |
27 |
29 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/brizaldi/flutter_project_template_riverpod/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.brizaldi.flutter_project_template_riverpod
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 | import io.flutter.embedding.engine.FlutterEngine
5 | import io.flutter.plugin.common.MethodChannel
6 |
7 | class MainActivity: FlutterActivity() {
8 | override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
9 | super.configureFlutterEngine(flutterEngine)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.7.10'
3 | repositories {
4 | google()
5 | mavenCentral()
6 | }
7 |
8 | dependencies {
9 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
10 | }
11 | }
12 |
13 | allprojects {
14 | repositories {
15 | google()
16 | mavenCentral()
17 | }
18 | }
19 |
20 | rootProject.buildDir = '../build'
21 | subprojects {
22 | project.buildDir = "${rootProject.buildDir}/${project.name}"
23 | }
24 | subprojects {
25 | project.evaluationDependsOn(':app')
26 | }
27 |
28 | tasks.register("clean", Delete) {
29 | delete rootProject.buildDir
30 | }
31 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx4G
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
6 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | def flutterSdkPath = {
3 | def properties = new Properties()
4 | file("local.properties").withInputStream { properties.load(it) }
5 | def flutterSdkPath = properties.getProperty("flutter.sdk")
6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
7 | return flutterSdkPath
8 | }
9 | settings.ext.flutterSdkPath = flutterSdkPath()
10 |
11 | includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")
12 |
13 | repositories {
14 | google()
15 | mavenCentral()
16 | gradlePluginPortal()
17 | }
18 |
19 | plugins {
20 | id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false
21 | }
22 | }
23 |
24 | plugins {
25 | id "dev.flutter.flutter-plugin-loader" version "1.0.0"
26 | id "com.android.application" version "7.3.0" apply false
27 | }
28 |
29 | include ":app"
30 |
--------------------------------------------------------------------------------
/assets/images/2.0x/flutter_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/assets/images/2.0x/flutter_logo.png
--------------------------------------------------------------------------------
/assets/images/3.0x/flutter_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/assets/images/3.0x/flutter_logo.png
--------------------------------------------------------------------------------
/assets/images/flutter_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/assets/images/flutter_logo.png
--------------------------------------------------------------------------------
/flutter_launcher_icons.yaml:
--------------------------------------------------------------------------------
1 | # Run it using below commands:
2 | # flutter pub get
3 | # flutter pub run flutter_launcher_icons:main
4 |
5 | flutter_icons:
6 | android: "launcher_icon"
7 | ios: true
8 | image_path_android: "assets/images/ios_launcher_icon.png"
9 | image_path_ios: "assets/images/ios_launcher_icon.png"
10 | adaptive_icon_background: "#ffffff"
11 | adaptive_icon_foreground: "assets/images/android_launcher_icon.png"
--------------------------------------------------------------------------------
/flutter_native_splash.yaml:
--------------------------------------------------------------------------------
1 | flutter_native_splash:
2 |
3 | # This package generates native code to customize Flutter's default white native splash screen
4 | # with background color and splash image.
5 | # Customize the parameters below, and run the following command in the terminal:
6 | # flutter pub run flutter_native_splash:create
7 | # To restore Flutter's default white splash screen, run the following command in the terminal:
8 | # flutter pub run flutter_native_splash:remove
9 |
10 | # color is the only required parameter. It sets the background color of your splash screen.
11 | color: "#ffffff"
12 |
13 | # Optional parameters are listed below. To enable a parameter, uncomment the line by removing
14 | # the leading # character.
15 |
16 | # The image parameter allows you to specify an image used in the splash screen. It must be a
17 | # png file.
18 | image: assets/images/splash_logo.png
19 |
20 | # The color_dark and image_dark are parameters that set the color and image when the device is
21 | # in dark mode. If they are not specified, the app will use the color and image above.
22 | # If the image_dark parameter is specified, color_dark must be specified.
23 | #color_dark: "#042a49"
24 | #image_dark: assets/splash-invert.png
25 |
26 | # The android and ios parameters can be used to disable generating a splash screen on a given
27 | # platform.
28 | #android: false
29 | #ios: false
30 | #web: false
31 |
32 | # The position of the splash image can be set with android_gravity, ios_content_mode, and
33 | # web_image_mode parameters. All default to center.
34 | #
35 | # android_gravity can be one of the following Android Gravity (see
36 | # https://developer.android.com/reference/android/view/Gravity): bottom, center,
37 | # center_horizontal, center_vertical, clip_horizontal, clip_vertical, end, fill, fill_horizontal,
38 | # fill_vertical, left, right, start, or top.
39 | #android_gravity: center
40 | #
41 | # ios_content_mode can be one of the following iOS UIView.ContentMode (see
42 | # https://developer.apple.com/documentation/uikit/uiview/contentmode): scaleToFill,
43 | # scaleAspectFit, scaleAspectFill, center, top, bottom, left, right, topLeft, topRight,
44 | # bottomLeft, or bottomRight.
45 | #ios_content_mode: center
46 | #
47 | # web_image_mode can be one of the following modes: center, contain, stretch, and cover.
48 | #web_image_mode: center
49 |
50 | # To hide the notification bar, use the fullscreen parameter. Has no affect in web since web
51 | # has no notification bar. Defaults to false.
52 | # NOTE: Unlike Android, iOS will not automatically show the notification bar when the app loads.
53 | # To show the notification bar, add the following code to your Flutter app:
54 | # WidgetsFlutterBinding.ensureInitialized();
55 | # SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom, SystemUiOverlay.top]);
56 | #fullscreen: true
57 |
58 | # If you have changed the name(s) of your info.plist file(s), you can specify the filename(s)
59 | # with the info_plist_files parameter. Remove only the # characters in the three lines below,
60 | # do not remove any spaces:
61 | #info_plist_files:
62 | # - 'ios/Runner/Info-Debug.plist'
63 | # - 'ios/Runner/Info-Release.plist'
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | **/dgph
2 | *.mode1v3
3 | *.mode2v3
4 | *.moved-aside
5 | *.pbxuser
6 | *.perspectivev3
7 | **/*sync/
8 | .sconsign.dblite
9 | .tags*
10 | **/.vagrant/
11 | **/DerivedData/
12 | Icon?
13 | **/Pods/
14 | **/.symlinks/
15 | profile
16 | xcuserdata
17 | **/.generated/
18 | Flutter/App.framework
19 | Flutter/Flutter.framework
20 | Flutter/Flutter.podspec
21 | Flutter/Generated.xcconfig
22 | Flutter/ephemeral/
23 | Flutter/app.flx
24 | Flutter/app.zip
25 | Flutter/flutter_assets/
26 | Flutter/flutter_export_environment.sh
27 | ServiceDefinitions.json
28 | Runner/GeneratedPluginRegistrant.*
29 |
30 | # Exceptions to above rules.
31 | !default.mode1v3
32 | !default.mode2v3
33 | !default.pbxuser
34 | !default.perspectivev3
35 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 11.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/development.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
41 |
42 |
52 |
54 |
60 |
61 |
62 |
63 |
69 |
71 |
77 |
78 |
79 |
80 |
82 |
83 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/production.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
41 |
42 |
52 |
54 |
60 |
61 |
62 |
63 |
69 |
71 |
77 |
78 |
79 |
80 |
82 |
83 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/staging.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
41 |
42 |
52 |
54 |
60 |
61 |
62 |
63 |
69 |
71 |
77 |
78 |
79 |
80 |
82 |
83 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brizaldi/flutter-project-template-riverpod/b6905d46814a135ac064ae085da47cab0be4350a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | $(APP_NAME)
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(APP_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(FLUTTER_BUILD_NUMBER)
25 | Flavor
26 | $(APP_FLAVOR)
27 | LSRequiresIPhoneOS
28 |
29 | UILaunchStoryboardName
30 | LaunchScreen
31 | UIMainStoryboardFile
32 | Main
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 | CFBundleLocalizations
47 |
48 | en
49 | id
50 |
51 | CADisableMinimumFrameDurationOnPhone
52 |
53 | UIApplicationSupportsIndirectInputEvents
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/ios/RunnerTests/RunnerTests.swift:
--------------------------------------------------------------------------------
1 | import Flutter
2 | import UIKit
3 | import XCTest
4 |
5 | class RunnerTests: XCTestCase {
6 |
7 | func testExample() {
8 | // If you add code to the Runner application, consider adding tests here.
9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest.
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/l10n.yaml:
--------------------------------------------------------------------------------
1 | arb-dir: lib/l10n/arb
2 | template-arb-file: app_en.arb
3 | output-localization-file: app_localizations.dart
4 | nullable-getter: false
--------------------------------------------------------------------------------
/lib/config/configuration.dart:
--------------------------------------------------------------------------------
1 | library configuration;
2 |
3 | import 'dart:async';
4 |
5 | import 'package:flutter/foundation.dart';
6 | import 'package:flutter/material.dart';
7 | import 'package:flutter_web_plugins/url_strategy.dart';
8 | import 'package:hooks_riverpod/hooks_riverpod.dart';
9 | import 'package:logging/logging.dart';
10 |
11 | import '../style/style.dart';
12 | import '../utils/logging.dart';
13 |
14 | part 'src/build_config.dart';
15 | part 'src/env.dart';
16 |
--------------------------------------------------------------------------------
/lib/config/src/build_config.dart:
--------------------------------------------------------------------------------
1 | part of '../configuration.dart';
2 |
3 | enum Flavor { development, staging, release }
4 |
5 | class BuildConfig {
6 | const BuildConfig._({
7 | required this.baseUrl,
8 | required this.socketUrl,
9 | required this.connectTimeout,
10 | required this.receiveTimeout,
11 | required this.flavor,
12 | });
13 |
14 | const BuildConfig._development()
15 | : this._(
16 | baseUrl: 'https://6128855786a213001729f948.mockapi.io/api/v1/',
17 | socketUrl: '',
18 | connectTimeout: const Duration(milliseconds: 20000),
19 | receiveTimeout: const Duration(milliseconds: 20000),
20 | flavor: Flavor.development,
21 | );
22 |
23 | const BuildConfig._staging()
24 | : this._(
25 | baseUrl: 'https://6128855786a213001729f948.mockapi.io/api/v1/',
26 | socketUrl: '',
27 | connectTimeout: const Duration(milliseconds: 20000),
28 | receiveTimeout: const Duration(milliseconds: 20000),
29 | flavor: Flavor.staging,
30 | );
31 |
32 | const BuildConfig._release()
33 | : this._(
34 | baseUrl: 'https://6128855786a213001729f948.mockapi.io/api/v1/',
35 | socketUrl: '',
36 | connectTimeout: const Duration(milliseconds: 20000),
37 | receiveTimeout: const Duration(milliseconds: 20000),
38 | flavor: Flavor.release,
39 | );
40 |
41 | static late BuildConfig _instance;
42 |
43 | static void init({String? flavor}) {
44 | debugPrint(
45 | '╔══════════════════════════════════════════════════════════════╗');
46 | debugPrint(
47 | ' Build Flavor: $flavor ');
48 | debugPrint(
49 | '╚══════════════════════════════════════════════════════════════╝');
50 | switch (flavor) {
51 | case 'development':
52 | _instance = const BuildConfig._development();
53 | case 'staging':
54 | _instance = const BuildConfig._staging();
55 | default:
56 | _instance = const BuildConfig._release();
57 | }
58 | unawaited(_initLog());
59 | }
60 |
61 | static BuildConfig get() {
62 | return _instance;
63 | }
64 |
65 | static Future _initLog() async {
66 | await Log.init();
67 | switch (_instance.flavor) {
68 | case Flavor.development:
69 | case Flavor.staging:
70 | Log.setLevel(Level.ALL);
71 | case Flavor.release:
72 | Log.setLevel(Level.OFF);
73 | }
74 | }
75 |
76 | final String baseUrl;
77 | final String socketUrl;
78 | final Duration connectTimeout;
79 | final Duration receiveTimeout;
80 | final Flavor flavor;
81 |
82 | static String get flavorName => _instance.flavor.name;
83 |
84 | static bool get isProduction => _instance.flavor == Flavor.release;
85 |
86 | static bool get isStaging => _instance.flavor == Flavor.staging;
87 |
88 | static bool get isDevelopment => _instance.flavor == Flavor.development;
89 | }
90 |
--------------------------------------------------------------------------------
/lib/config/src/env.dart:
--------------------------------------------------------------------------------
1 | part of '../configuration.dart';
2 |
3 | abstract class Env {
4 | Env() {
5 | _init();
6 | }
7 |
8 | void _init() {
9 | if (kReleaseMode) {
10 | // Used to prevent printing in release mode
11 | debugPrint = (String? message, {int? wrapWidth}) {};
12 | }
13 |
14 | unawaited(runZonedGuarded(() async {
15 | WidgetsFlutterBinding.ensureInitialized();
16 |
17 | BuildConfig.init(flavor: const String.fromEnvironment('flavor'));
18 |
19 | Themes.initUiOverlayStyle();
20 |
21 | usePathUrlStrategy();
22 |
23 | final app = await onCreate();
24 |
25 | runApp(
26 | ProviderScope(
27 | child: app,
28 | ),
29 | );
30 | }, (obj, stack) {
31 | debugPrint(obj.toString());
32 | debugPrint(stack.toString());
33 | }));
34 | }
35 |
36 | FutureOr onCreate();
37 | }
38 |
--------------------------------------------------------------------------------
/lib/constants/assets.dart:
--------------------------------------------------------------------------------
1 | class Assets {
2 | static const String appLogo = 'assets/images/app_logo.png';
3 | }
4 |
--------------------------------------------------------------------------------
/lib/constants/strings.dart:
--------------------------------------------------------------------------------
1 | class Strings {
2 | static const String appName = 'Project Template';
3 | static const String appCodeName = 'project-template';
4 |
5 | //* Local DB key string
6 | static const String token = 'TOKEN';
7 | static const String languageCode = 'LANGUAGE_CODE';
8 | static const String countryCode = 'COUNTRY_CODE';
9 | }
10 |
--------------------------------------------------------------------------------
/lib/features/auth/application/auth/auth_notifier.dart:
--------------------------------------------------------------------------------
1 | import 'package:freezed_annotation/freezed_annotation.dart';
2 | import 'package:hooks_riverpod/hooks_riverpod.dart';
3 |
4 | import '../../domain/auth_failure.dart';
5 | import '../../infrastructure/auth_repository.dart';
6 |
7 | part 'auth_notifier.freezed.dart';
8 | part 'auth_state.dart';
9 |
10 | class AuthNotifier extends StateNotifier {
11 | AuthNotifier(this._repository) : super(const AuthState.initial());
12 |
13 | final AuthRepository _repository;
14 |
15 | Future checkAndUpdateAuthStatus() async {
16 | final isSignedIn = await _repository.isSignedIn();
17 | if (isSignedIn) {
18 | state = const AuthState.authenticated();
19 | } else {
20 | state = const AuthState.unauthenticated();
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/lib/features/auth/application/auth/auth_state.dart:
--------------------------------------------------------------------------------
1 | part of 'auth_notifier.dart';
2 |
3 | @freezed
4 | class AuthState with _$AuthState {
5 | const factory AuthState.initial() = _Initial;
6 | const factory AuthState.authenticated() = _Authenticated;
7 | const factory AuthState.unauthenticated() = _Unauthenticated;
8 | const factory AuthState.failure(AuthFailure failure) = _Failure;
9 | }
10 |
--------------------------------------------------------------------------------
/lib/features/auth/application/sign_in_form/sign_in_form_notifier.dart:
--------------------------------------------------------------------------------
1 | import 'package:fpdart/fpdart.dart';
2 | import 'package:freezed_annotation/freezed_annotation.dart';
3 | import 'package:hooks_riverpod/hooks_riverpod.dart';
4 |
5 | import '../../../../utils/validator.dart';
6 | import '../../domain/auth_failure.dart';
7 | import '../../domain/value_objects.dart';
8 | import '../../infrastructure/auth_repository.dart';
9 |
10 | part 'sign_in_form_notifier.freezed.dart';
11 | part 'sign_in_form_state.dart';
12 |
13 | class SignInFormNotifier extends StateNotifier {
14 | SignInFormNotifier(this._repository) : super(SignInFormState.initial());
15 |
16 | final AuthRepository _repository;
17 |
18 | void changeEmail(String emailStr) {
19 | state = state.copyWith(
20 | email: Email(emailStr),
21 | failureOrSuccessOption: none(),
22 | );
23 | }
24 |
25 | void changePassword(String passwordStr) {
26 | state = state.copyWith(
27 | password: Password(passwordStr),
28 | failureOrSuccessOption: none(),
29 | );
30 | }
31 |
32 | Future signInWithEmailAndPassword() async {
33 | Either? signInFailureOrSuccess;
34 |
35 | if (isValid) {
36 | state = state.copyWith(
37 | isSubmitting: true,
38 | failureOrSuccessOption: none(),
39 | );
40 |
41 | signInFailureOrSuccess = await _repository.signInWithEmailAndPassword(
42 | email: state.email,
43 | password: state.password,
44 | );
45 | }
46 |
47 | state = state.copyWith(
48 | isSubmitting: false,
49 | showErrorMessages: true,
50 | failureOrSuccessOption: optionOf(signInFailureOrSuccess),
51 | );
52 | }
53 |
54 | bool get isValid {
55 | final values = [
56 | state.email,
57 | state.password,
58 | ];
59 |
60 | return Validator.validate(values);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/lib/features/auth/application/sign_in_form/sign_in_form_state.dart:
--------------------------------------------------------------------------------
1 | part of 'sign_in_form_notifier.dart';
2 |
3 | @freezed
4 | class SignInFormState with _$SignInFormState {
5 | const factory SignInFormState({
6 | required Email email,
7 | required Password password,
8 | required bool showErrorMessages,
9 | required bool isSubmitting,
10 | required Option> failureOrSuccessOption,
11 | }) = _SignInFormState;
12 |
13 | factory SignInFormState.initial() => SignInFormState(
14 | email: Email(''),
15 | password: Password(''),
16 | showErrorMessages: false,
17 | isSubmitting: false,
18 | failureOrSuccessOption: none(),
19 | );
20 | }
21 |
--------------------------------------------------------------------------------
/lib/features/auth/application/sign_out/sign_out_notifier.dart:
--------------------------------------------------------------------------------
1 | import 'package:freezed_annotation/freezed_annotation.dart';
2 | import 'package:hooks_riverpod/hooks_riverpod.dart';
3 |
4 | import '../../domain/auth_failure.dart';
5 | import '../../infrastructure/auth_repository.dart';
6 |
7 | part 'sign_out_notifier.freezed.dart';
8 | part 'sign_out_state.dart';
9 |
10 | class SignOutNotifier extends StateNotifier {
11 | SignOutNotifier(this._repository) : super(const SignOutState.initial());
12 |
13 | final AuthRepository _repository;
14 |
15 | Future signOut() async {
16 | state = const SignOutState.inProgress();
17 | final failureOrSuccess = await _repository.signOut();
18 | state = failureOrSuccess.fold(
19 | SignOutState.failure,
20 | (_) => const SignOutState.success(),
21 | );
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/lib/features/auth/application/sign_out/sign_out_state.dart:
--------------------------------------------------------------------------------
1 | part of 'sign_out_notifier.dart';
2 |
3 | @freezed
4 | class SignOutState with _$SignOutState {
5 | const factory SignOutState.initial() = _Initial;
6 | const factory SignOutState.inProgress() = _InProgress;
7 | const factory SignOutState.success() = _Success;
8 | const factory SignOutState.failure(AuthFailure failure) = _Failure;
9 | }
10 |
--------------------------------------------------------------------------------
/lib/features/auth/domain/auth_failure.dart:
--------------------------------------------------------------------------------
1 | import 'package:freezed_annotation/freezed_annotation.dart';
2 |
3 | part 'auth_failure.freezed.dart';
4 |
5 | @freezed
6 | class AuthFailure with _$AuthFailure {
7 | const factory AuthFailure.storage() = _Storage;
8 | const factory AuthFailure.server([int? errorCode, String? message]) = _Server;
9 | const factory AuthFailure.noConnection() = _NoConnection;
10 | }
11 |
--------------------------------------------------------------------------------
/lib/features/auth/domain/user.dart:
--------------------------------------------------------------------------------
1 | import 'package:freezed_annotation/freezed_annotation.dart';
2 |
3 | import '../../core/domain/value_objects.dart';
4 | import 'value_objects.dart';
5 |
6 | part 'user.freezed.dart';
7 |
8 | @freezed
9 | class User with _$User {
10 | const factory User({
11 | required UniqueId id,
12 | required Email email,
13 | required UserToken userToken,
14 | }) = _User;
15 | }
16 |
--------------------------------------------------------------------------------
/lib/features/auth/domain/value_objects.dart:
--------------------------------------------------------------------------------
1 | import 'package:fpdart/fpdart.dart';
2 |
3 | import '../../../utils/value_validators.dart';
4 | import '../../core/domain/failures.dart';
5 | import '../../core/domain/value_objects.dart';
6 |
7 | class Email extends ValueObject {
8 | factory Email(String input) {
9 | return Email._(
10 | validateStringNotEmpty(input).flatMap(validateEmail),
11 | );
12 | }
13 |
14 | const Email._(this.value);
15 |
16 | @override
17 | final Either, String> value;
18 | }
19 |
20 | class Password extends ValueObject {
21 | factory Password(String input) {
22 | return Password._(
23 | validatePassword(input),
24 | );
25 | }
26 |
27 | const Password._(this.value);
28 |
29 | @override
30 | final Either, String> value;
31 | }
32 |
33 | class UserToken extends ValueObject {
34 | factory UserToken(String input) {
35 | return UserToken._(
36 | validateStringNotEmpty(input),
37 | );
38 | }
39 |
40 | const UserToken._(this.value);
41 |
42 | @override
43 | final Either, String> value;
44 | }
45 |
--------------------------------------------------------------------------------
/lib/features/auth/infrastructure/auth_interceptor.dart:
--------------------------------------------------------------------------------
1 | import 'package:dio/dio.dart';
2 |
3 | import 'auth_repository.dart';
4 |
5 | class AuthInterceptor extends Interceptor {
6 | AuthInterceptor(this._repository);
7 |
8 | final AuthRepository _repository;
9 |
10 | @override
11 | Future onRequest(
12 | RequestOptions options,
13 | RequestInterceptorHandler handler,
14 | ) async {
15 | final storedCredentials = await _repository.getSignedInCredentials();
16 |
17 | final RequestOptions modifiedOptions = options
18 | ..headers.addAll(
19 | storedCredentials == null
20 | ? {}
21 | : {'Authorization': 'bearer $storedCredentials'},
22 | );
23 |
24 | handler.next(modifiedOptions);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/lib/features/auth/infrastructure/auth_remote_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:dio/dio.dart';
2 |
3 | import '../../core/infrastructure/dio_extensions.dart';
4 | import '../../core/infrastructure/exceptions.dart';
5 | import 'auth_response.dart';
6 |
7 | class AuthRemoteService {
8 | AuthRemoteService(this._dio);
9 |
10 | final Dio _dio;
11 |
12 | Future signOut() async {
13 | try {
14 | await _dio.get('logout');
15 | } on DioException catch (e) {
16 | if (e.isNoConnectionError || e.isConnectionTimeout) {
17 | throw NoConnectionException();
18 | } else if (e.response != null) {
19 | throw RestApiException(e.response?.statusCode);
20 | } else {
21 | rethrow;
22 | }
23 | }
24 | }
25 |
26 | Future signIn({
27 | required String email,
28 | required String password,
29 | }) async {
30 | try {
31 | final response = await _dio.post