├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── main.yaml ├── .gitignore ├── .idea └── runConfigurations │ ├── development.xml │ ├── production.xml │ └── staging.xml ├── .metadata ├── .vscode ├── extensions.json └── launch.json ├── LICENSE ├── README.md ├── analysis_options.yaml ├── android ├── .gitignore ├── app │ ├── build.gradle │ ├── google-services.json │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── development │ │ ├── ic_launcher-playstore.png │ │ └── res │ │ │ ├── drawable │ │ │ └── ic_launcher_foreground.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ └── values │ │ │ └── ic_launcher_background.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── ic_launcher-playstore.png │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── verygoodcore │ │ │ │ └── MainActivity.kt │ │ └── res │ │ │ ├── drawable-v21 │ │ │ └── launch_background.xml │ │ │ ├── drawable │ │ │ ├── appicon.png │ │ │ ├── ic_launch_image.xml │ │ │ ├── ic_launcher_foreground.xml │ │ │ └── launch_background.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── values-night │ │ │ └── styles.xml │ │ │ └── values │ │ │ ├── ic_launcher_background.xml │ │ │ └── styles.xml │ │ ├── profile │ │ └── AndroidManifest.xml │ │ └── staging │ │ ├── ic_launcher-playstore.png │ │ └── res │ │ ├── drawable │ │ └── ic_launcher_foreground.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ └── ic_launcher_background.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── assets └── icon.png ├── coverage_badge.svg ├── ios ├── .gitignore ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata │ │ └── xcschemes │ │ ├── Runner.xcscheme │ │ ├── development.xcscheme │ │ ├── production.xcscheme │ │ └── staging.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings ├── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon-dev.appiconset │ │ │ ├── 100.png │ │ │ ├── 1024.png │ │ │ ├── 114.png │ │ │ ├── 120.png │ │ │ ├── 128.png │ │ │ ├── 144.png │ │ │ ├── 152.png │ │ │ ├── 16.png │ │ │ ├── 167.png │ │ │ ├── 172.png │ │ │ ├── 180.png │ │ │ ├── 196.png │ │ │ ├── 20.png │ │ │ ├── 216.png │ │ │ ├── 256.png │ │ │ ├── 29.png │ │ │ ├── 32.png │ │ │ ├── 40.png │ │ │ ├── 48.png │ │ │ ├── 50.png │ │ │ ├── 512.png │ │ │ ├── 55.png │ │ │ ├── 57.png │ │ │ ├── 58.png │ │ │ ├── 60.png │ │ │ ├── 64.png │ │ │ ├── 72.png │ │ │ ├── 76.png │ │ │ ├── 80.png │ │ │ ├── 87.png │ │ │ ├── 88.png │ │ │ └── Contents.json │ │ ├── AppIcon-stg.appiconset │ │ │ ├── 100.png │ │ │ ├── 1024.png │ │ │ ├── 114.png │ │ │ ├── 120.png │ │ │ ├── 128.png │ │ │ ├── 144.png │ │ │ ├── 152.png │ │ │ ├── 16.png │ │ │ ├── 167.png │ │ │ ├── 172.png │ │ │ ├── 180.png │ │ │ ├── 196.png │ │ │ ├── 20.png │ │ │ ├── 216.png │ │ │ ├── 256.png │ │ │ ├── 29.png │ │ │ ├── 32.png │ │ │ ├── 40.png │ │ │ ├── 48.png │ │ │ ├── 50.png │ │ │ ├── 512.png │ │ │ ├── 55.png │ │ │ ├── 57.png │ │ │ ├── 58.png │ │ │ ├── 60.png │ │ │ ├── 64.png │ │ │ ├── 72.png │ │ │ ├── 76.png │ │ │ ├── 80.png │ │ │ ├── 87.png │ │ │ ├── 88.png │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ ├── 100.png │ │ │ ├── 1024.png │ │ │ ├── 114.png │ │ │ ├── 120.png │ │ │ ├── 128.png │ │ │ ├── 144.png │ │ │ ├── 152.png │ │ │ ├── 16.png │ │ │ ├── 167.png │ │ │ ├── 172.png │ │ │ ├── 180.png │ │ │ ├── 196.png │ │ │ ├── 20.png │ │ │ ├── 216.png │ │ │ ├── 256.png │ │ │ ├── 29.png │ │ │ ├── 32.png │ │ │ ├── 40.png │ │ │ ├── 48.png │ │ │ ├── 50.png │ │ │ ├── 512.png │ │ │ ├── 55.png │ │ │ ├── 57.png │ │ │ ├── 58.png │ │ │ ├── 60.png │ │ │ ├── 64.png │ │ │ ├── 72.png │ │ │ ├── 76.png │ │ │ ├── 80.png │ │ │ ├── 87.png │ │ │ ├── 88.png │ │ │ ├── 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 │ │ ├── Contents.json │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage@1x.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ └── Runner-Bridging-Header.h └── firebase_app_id_file.json ├── l10n.yaml ├── lib ├── app │ ├── app.dart │ ├── app_bloc_observer.dart │ ├── bloc │ │ ├── app_bloc.dart │ │ ├── app_event.dart │ │ └── app_state.dart │ └── routes │ │ └── route.dart ├── bootstrap.dart ├── edit_todo │ ├── bloc │ │ ├── edit_todo_bloc.dart │ │ ├── edit_todo_event.dart │ │ └── edit_todo_state.dart │ ├── edit_todo.dart │ └── view │ │ └── edit_todo.dart ├── firebase_options.dart ├── home │ ├── cubit │ │ ├── home_cubit.dart │ │ └── home_state.dart │ ├── home.dart │ └── view │ │ └── home_page.dart ├── l10n │ ├── arb │ │ └── app_en.arb │ └── l10n.dart ├── login │ ├── cubit │ │ ├── login_cubit.dart │ │ └── login_state.dart │ ├── login.dart │ └── view │ │ ├── login.dart │ │ └── login_form.dart ├── main_development.dart ├── main_production.dart ├── main_staging.dart ├── service │ └── notification_service.dart ├── settings │ ├── cubit │ │ ├── settings_cubit.dart │ │ └── settings_state.dart │ ├── settings.dart │ └── view │ │ └── settings_page.dart ├── sign_up │ ├── bloc │ │ ├── sign_up_bloc.dart │ │ └── sign_up_state.dart │ ├── sign_up.dart │ └── view │ │ ├── sign_up_form.dart │ │ └── sign_up_page.dart ├── splash │ ├── splash.dart │ └── view │ │ └── splash_page.dart ├── stats │ ├── bloc │ │ ├── stats_bloc.dart │ │ ├── stats_event.dart │ │ └── stats_state.dart │ ├── stats.dart │ └── view │ │ └── stats_page.dart ├── theme │ ├── app_theme.dart │ ├── sharepreference.dart │ ├── theme_bloc.dart │ ├── theme_event.dart │ └── theme_state.dart ├── todo_overview │ ├── bloc │ │ ├── todo_overview_bloc.dart │ │ ├── todo_overview_event.dart │ │ └── todo_overview_state.dart │ ├── model │ │ └── todo_view_filter.dart │ ├── todo_overview.dart │ └── view │ │ ├── todo_overview_page.dart │ │ └── widget │ │ ├── date_task_bar.dart │ │ ├── todo_tiles.dart │ │ └── todos_overview_filter_button.dart └── widget │ ├── dialog │ ├── loading_screen.dart │ └── loading_screen_controller.dart │ └── widget.dart ├── packages ├── auth_repo │ ├── .gitignore │ ├── README.md │ ├── analysis_options.yaml │ ├── lib │ │ ├── auth_repo.dart │ │ └── src │ │ │ ├── auth_repo.dart │ │ │ └── model │ │ │ ├── auth │ │ │ └── auth_error.dart │ │ │ ├── model.dart │ │ │ └── user.dart │ ├── pubspec.yaml │ └── test │ │ └── src │ │ └── auth_repo_test.dart ├── cache │ ├── .gitignore │ ├── README.md │ ├── analysis_options.yaml │ ├── lib │ │ ├── cache.dart │ │ └── src │ │ │ └── cache.dart │ └── pubspec.yaml ├── cloud_storage_todos_api │ ├── .gitignore │ ├── README.md │ ├── analysis_options.yaml │ ├── lib │ │ ├── cloud_storage_todos_api.dart │ │ └── src │ │ │ └── cloud_storage_todos_api.dart │ └── pubspec.yaml ├── form_input │ ├── .gitignore │ ├── README.md │ ├── analysis_options.yaml │ ├── lib │ │ ├── form_input.dart │ │ └── src │ │ │ ├── confirm_password.dart │ │ │ ├── email.dart │ │ │ └── password.dart │ └── pubspec.yaml ├── local_storage_todos_api │ ├── .gitignore │ ├── README.md │ ├── analysis_options.yaml │ ├── lib │ │ ├── local_storage_todos_api.dart │ │ └── src │ │ │ └── local_storage_todos_api.dart │ ├── pubspec.lock │ └── pubspec.yaml ├── todos_api │ ├── .gitignore │ ├── README.md │ ├── analysis_options.yaml │ ├── lib │ │ ├── src │ │ │ ├── models │ │ │ │ ├── models.dart │ │ │ │ ├── todo.dart │ │ │ │ └── todo_serialize.dart │ │ │ └── todos_api.dart │ │ └── todos_api.dart │ ├── pubspec.lock │ └── pubspec.yaml └── todos_repository │ ├── README.md │ ├── analysis_options.yaml │ ├── lib │ ├── src │ │ └── todos_repository.dart │ └── todo_repository.dart │ └── pubspec.yaml ├── pubspec.lock ├── pubspec.yaml ├── web ├── favicon.png ├── icons │ ├── Icon-192.png │ ├── Icon-512.png │ └── favicon.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/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | ## Description 10 | 11 | 12 | 13 | ## Type of Change 14 | 15 | 16 | 17 | - [ ] ✨ New feature (non-breaking change which adds functionality) 18 | - [ ] 🛠️ Bug fix (non-breaking change which fixes an issue) 19 | - [ ] ❌ Breaking change (fix or feature that would cause existing functionality to change) 20 | - [ ] 🧹 Code refactor 21 | - [ ] ✅ Build configuration change 22 | - [ ] 📝 Documentation 23 | - [ ] 🗑️ Chore 24 | -------------------------------------------------------------------------------- /.github/workflows/main.yaml: -------------------------------------------------------------------------------- 1 | name: todo 2 | 3 | on: [pull_request, push] 4 | 5 | jobs: 6 | build: 7 | uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v1 8 | with: 9 | flutter_channel: stable 10 | flutter_version: 2.10.0 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.lock 4 | *.log 5 | *.pyc 6 | *.swp 7 | .DS_Store 8 | .atom/ 9 | .buildlog/ 10 | .history 11 | .svn/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/* 18 | 19 | # Visual Studio Code related 20 | .classpath 21 | .project 22 | .settings/ 23 | .vscode/* 24 | 25 | # Flutter repo-specific 26 | /bin/cache/ 27 | /bin/mingit/ 28 | /dev/benchmarks/mega_gallery/ 29 | /dev/bots/.recipe_deps 30 | /dev/bots/android_tools/ 31 | /dev/docs/doc/ 32 | /dev/docs/flutter.docs.zip 33 | /dev/docs/lib/ 34 | /dev/docs/pubspec.yaml 35 | /dev/integration_tests/**/xcuserdata 36 | /dev/integration_tests/**/Pods 37 | /packages/flutter/coverage/ 38 | version 39 | 40 | # packages file containing multi-root paths 41 | .packages.generated 42 | 43 | # Flutter/Dart/Pub related 44 | **/doc/api/ 45 | **/ios/Flutter/.last_build_id 46 | .dart_tool/ 47 | .flutter-plugins 48 | .flutter-plugins-dependencies 49 | .packages 50 | .pub-cache/ 51 | .pub/ 52 | build/ 53 | flutter_*.png 54 | linked_*.ds 55 | unlinked.ds 56 | unlinked_spec.ds 57 | .fvm/ 58 | 59 | # Android related 60 | **/android/**/gradle-wrapper.jar 61 | **/android/.gradle 62 | **/android/captures/ 63 | **/android/gradlew 64 | **/android/gradlew.bat 65 | **/android/local.properties 66 | **/android/**/GeneratedPluginRegistrant.java 67 | **/android/key.properties 68 | **/android/.idea/ 69 | *.jks 70 | 71 | # iOS/XCode related 72 | **/ios/**/*.mode1v3 73 | **/ios/**/*.mode2v3 74 | **/ios/**/*.moved-aside 75 | **/ios/**/*.pbxuser 76 | **/ios/**/*.perspectivev3 77 | **/ios/**/*sync/ 78 | **/ios/**/.sconsign.dblite 79 | **/ios/**/.tags* 80 | **/ios/**/.vagrant/ 81 | **/ios/**/DerivedData/ 82 | **/ios/**/Icon? 83 | **/ios/**/Pods/ 84 | **/ios/**/.symlinks/ 85 | **/ios/**/profile 86 | **/ios/**/xcuserdata 87 | **/ios/.generated/ 88 | **/ios/Flutter/App.framework 89 | **/ios/Flutter/Flutter.framework 90 | **/ios/Flutter/Flutter.podspec 91 | **/ios/Flutter/Generated.xcconfig 92 | **/ios/Flutter/app.flx 93 | **/ios/Flutter/app.zip 94 | **/ios/Flutter/.last_build_id 95 | **/ios/Flutter/flutter_assets/ 96 | **/ios/Flutter/flutter_export_environment.sh 97 | **/ios/ServiceDefinitions.json 98 | **/ios/Runner/GeneratedPluginRegistrant.* 99 | 100 | # Coverage 101 | coverage/ 102 | 103 | # Submodules 104 | !pubspec.lock 105 | packages/**/pubspec.lock 106 | 107 | # Web related 108 | lib/generated_plugin_registrant.dart 109 | 110 | # Symbolication related 111 | app.*.symbols 112 | 113 | # Obfuscation related 114 | app.*.map.json 115 | 116 | # Exceptions to the above rules. 117 | !**/ios/**/default.mode1v3 118 | !**/ios/**/default.mode2v3 119 | !**/ios/**/default.pbxuser 120 | !**/ios/**/default.perspectivev3 121 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 122 | !/dev/ci/**/Gemfile.lock 123 | !.vscode/extensions.json 124 | !.vscode/launch.json 125 | !.idea/codeStyles/ 126 | !.idea/dictionaries/ 127 | !.idea/runConfigurations/ 128 | -------------------------------------------------------------------------------- /.idea/runConfigurations/development.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /.idea/runConfigurations/production.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /.idea/runConfigurations/staging.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 9b2d32b605630f28625709ebd9d78ab3016b2bf6 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "dart-code.dart-code", 6 | "dart-code.flutter", 7 | "felixangelov.bloc" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /.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": "Launch development", 9 | "request": "launch", 10 | "type": "dart", 11 | "program": "lib/main_development.dart", 12 | "args": [ 13 | "--flavor", 14 | "development", 15 | "--target", 16 | "lib/main_development.dart" 17 | ] 18 | }, 19 | { 20 | "name": "Launch staging", 21 | "request": "launch", 22 | "type": "dart", 23 | "program": "lib/main_staging.dart", 24 | "args": ["--flavor", "staging", "--target", "lib/main_staging.dart"] 25 | }, 26 | { 27 | "name": "Launch production", 28 | "request": "launch", 29 | "type": "dart", 30 | "program": "lib/main_production.dart", 31 | "args": ["--flavor", "production", "--target", "lib/main_production.dart"] 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Very Good Ventures 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. -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:very_good_analysis/analysis_options.2.4.0.yaml 2 | linter: 3 | rules: 4 | public_member_api_docs: false 5 | -------------------------------------------------------------------------------- /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 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /android/app/google-services.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/google-services.json -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/development/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/development/ic_launcher-playstore.png -------------------------------------------------------------------------------- /android/app/src/development/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/development/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/development/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/development/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/development/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/development/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/development/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/development/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/development/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/development/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/development/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/development/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/development/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/development/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/development/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/development/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/development/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/development/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/development/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/development/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/development/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/development/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/development/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 11 | 19 | 23 | 27 | 28 | 29 | 30 | 31 | 32 | 34 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /android/app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/verygoodcore/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.verygoodcore.todo 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/appicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/main/res/drawable/appicon.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/staging/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/staging/ic_launcher-playstore.png -------------------------------------------------------------------------------- /android/app/src/staging/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/staging/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/staging/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/staging/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/staging/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/staging/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/staging/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/staging/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/staging/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/staging/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/staging/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/staging/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/staging/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/staging/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/staging/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/staging/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/staging/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/staging/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/staging/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/staging/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/staging/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/android/app/src/staging/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/staging/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.6.10' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.1.2' 10 | // START: FlutterFire Configuration 11 | classpath 'com.google.gms:google-services:4.3.10' 12 | // END: FlutterFire Configuration 13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 14 | } 15 | } 16 | 17 | allprojects { 18 | repositories { 19 | google() 20 | mavenCentral() 21 | } 22 | } 23 | 24 | rootProject.buildDir = '../build' 25 | subprojects { 26 | project.buildDir = "${rootProject.buildDir}/${project.name}" 27 | project.evaluationDependsOn(':app') 28 | } 29 | 30 | task clean(type: Delete) { 31 | delete rootProject.buildDir 32 | } 33 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip 7 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/assets/icon.png -------------------------------------------------------------------------------- /coverage_badge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | coverage 16 | coverage 17 | 100% 18 | 100% 19 | 20 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | 9.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/Runner.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/development.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/production.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/staging.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /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-dev.appiconset/100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/100.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/1024.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/114.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/120.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/128.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/144.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/152.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/16.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/167.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/172.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/172.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/180.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/196.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/20.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/216.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/216.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/256.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/29.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/32.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/40.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/48.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/50.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/512.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/55.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/57.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/58.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/60.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/64.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/72.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/76.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/80.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/87.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/88.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-dev.appiconset/88.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/100.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/1024.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/114.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/120.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/128.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/144.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/152.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/16.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/167.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/172.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/172.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/180.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/196.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/20.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/216.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/216.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/256.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/29.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/32.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/40.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/48.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/50.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/512.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/55.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/57.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/58.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/60.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/64.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/72.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/76.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/80.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/87.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/88.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon-stg.appiconset/88.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/128.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/16.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/172.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/172.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/196.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/216.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/216.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/256.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/32.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/48.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/512.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/55.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/64.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/88.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/88.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/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/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/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/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/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/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/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/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/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/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/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/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/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/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/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/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/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/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/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/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/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/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/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/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/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/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/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/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "LaunchImage@1x.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "LaunchImage@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "LaunchImage@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/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 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /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 | CFBundleLocalizations 6 | 7 | en 8 | es 9 | 10 | CFBundleDevelopmentRegion 11 | $(DEVELOPMENT_LANGUAGE) 12 | CFBundleDisplayName 13 | $(FLAVOR_APP_NAME) 14 | CFBundleExecutable 15 | $(EXECUTABLE_NAME) 16 | CFBundleIdentifier 17 | $(PRODUCT_BUNDLE_IDENTIFIER) 18 | CFBundleInfoDictionaryVersion 19 | 6.0 20 | CFBundleName 21 | Cloud Based Todo App 22 | CFBundlePackageType 23 | APPL 24 | CFBundleShortVersionString 25 | $(FLUTTER_BUILD_NAME) 26 | CFBundleSignature 27 | ???? 28 | CFBundleVersion 29 | $(FLUTTER_BUILD_NUMBER) 30 | LSRequiresIPhoneOS 31 | 32 | UILaunchStoryboardName 33 | LaunchScreen 34 | UIMainStoryboardFile 35 | Main 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | UIViewControllerBasedStatusBarAppearance 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /ios/firebase_app_id_file.json: -------------------------------------------------------------------------------- 1 | { 2 | "file_generated_by": "FlutterFire CLI", 3 | "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", 4 | "GOOGLE_APP_ID": "1:311087396382:ios:c7415a03c1d499a2d2e00f", 5 | "FIREBASE_PROJECT_ID": "flutter-project-cd13d", 6 | "GCM_SENDER_ID": "311087396382" 7 | } -------------------------------------------------------------------------------- /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 5 | -------------------------------------------------------------------------------- /lib/app/app.dart: -------------------------------------------------------------------------------- 1 | import 'package:auth_repo/auth_repo.dart'; 2 | import 'package:flow_builder/flow_builder.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_bloc/flutter_bloc.dart'; 5 | import 'package:todo/app/bloc/app_bloc.dart'; 6 | import 'package:todo/app/bloc/app_event.dart'; 7 | import 'package:todo/app/bloc/app_state.dart'; 8 | import 'package:todo/app/routes/route.dart'; 9 | import 'package:todo/home/view/home_page.dart'; 10 | import 'package:todo/theme/app_theme.dart'; 11 | import 'package:todo/theme/theme_bloc.dart'; 12 | import 'package:todo/theme/theme_state.dart'; 13 | import 'package:todos_repository/todo_repository.dart'; 14 | 15 | class App extends StatelessWidget { 16 | const App( 17 | {Key? key, 18 | required TodoRepository todoRepository, 19 | required AuthRepo authRepo}) 20 | : _todoRepository = todoRepository, 21 | _authRepo = authRepo, 22 | super(key: key); 23 | 24 | final TodoRepository _todoRepository; 25 | final AuthRepo _authRepo; 26 | 27 | @override 28 | Widget build(BuildContext context) { 29 | return MultiRepositoryProvider( 30 | providers: [ 31 | RepositoryProvider( 32 | create: (context) => _authRepo, 33 | ), 34 | RepositoryProvider( 35 | create: (context) => _todoRepository) 36 | ], 37 | child: BlocProvider( 38 | create: (_) => AppBloc(authRepo: _authRepo)..add(AppStartedEvent()), 39 | child: const AppView())); 40 | } 41 | } 42 | 43 | class AppView extends StatelessWidget { 44 | const AppView({Key? key}) : super(key: key); 45 | 46 | @override 47 | Widget build(BuildContext context) { 48 | return BlocProvider( 49 | create: (_) => ThemeBloc(), 50 | child: BlocBuilder(builder: (context, state) { 51 | return MaterialApp( 52 | debugShowCheckedModeBanner: false, 53 | theme: state.themeData, 54 | darkTheme: FlutterTodosTheme.dark, 55 | home: FlowBuilder( 56 | state: context.select((AppBloc bloc) => bloc.state.status), 57 | onGeneratePages: onGenerateAppViewPages, 58 | ), 59 | ); 60 | }), 61 | ); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /lib/app/app_bloc_observer.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer'; 2 | 3 | import 'package:flutter_bloc/flutter_bloc.dart'; 4 | 5 | class AppBlocObserver extends BlocObserver { 6 | @override 7 | void onChange(BlocBase bloc, Change change) { 8 | super.onChange(bloc, change); 9 | log('onChange(${bloc.runtimeType}, $change)'); 10 | } 11 | 12 | @override 13 | void onError(BlocBase bloc, Object error, StackTrace stackTrace) { 14 | log('onError(${bloc.runtimeType}, $error, $stackTrace)'); 15 | super.onError(bloc, error, stackTrace); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/app/bloc/app_bloc.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:auth_repo/auth_repo.dart'; 4 | import 'package:flutter_bloc/flutter_bloc.dart'; 5 | import 'package:todo/app/bloc/app_event.dart'; 6 | import 'package:todo/app/bloc/app_state.dart'; 7 | 8 | class AppBloc extends Bloc { 9 | AppBloc({required AuthRepo authRepo}) 10 | : _authRepo = authRepo, 11 | super( 12 | const AppState.AppStarted(), 13 | ) { 14 | on(_onUserChanged); 15 | on(_onLogoutRequested); 16 | on(_onAppStarted); 17 | 18 | _userSubscription = _authRepo.user.listen((user) { 19 | if (state.status == AppStatus.appStarted) { 20 | add(AppStartedEvent()); 21 | } else { 22 | add(AppUserChanged(user)); 23 | } 24 | }); 25 | } 26 | 27 | final AuthRepo _authRepo; 28 | late final StreamSubscription _userSubscription; 29 | 30 | void _onUserChanged(AppUserChanged event, Emitter emit) { 31 | emit( 32 | event.user.isNotEmpty 33 | ? AppState.authenticated(event.user) 34 | : const AppState.unauthenticated(), 35 | ); 36 | } 37 | 38 | void _onAppStarted(AppStartedEvent event, Emitter emit) async { 39 | emit(const AppState.AppStarted()); 40 | await Future.delayed(const Duration(seconds: 4), () { 41 | emit(_authRepo.currentUser.isNotEmpty 42 | ? AppState.authenticated(_authRepo.currentUser) 43 | : const AppState.unauthenticated()); 44 | }); 45 | } 46 | 47 | void _onLogoutRequested(AppLogoutRequested event, Emitter emit) { 48 | unawaited(_authRepo.logout()); 49 | } 50 | 51 | @override 52 | Future close() { 53 | _userSubscription.cancel(); 54 | return super.close(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lib/app/bloc/app_event.dart: -------------------------------------------------------------------------------- 1 | import 'package:auth_repo/auth_repo.dart'; 2 | import 'package:equatable/equatable.dart'; 3 | import 'package:meta/meta.dart'; 4 | import 'package:todo/app/app.dart'; 5 | 6 | abstract class AppEvent extends Equatable { 7 | const AppEvent(); 8 | 9 | @override 10 | List get props => []; 11 | } 12 | 13 | class AppLogoutRequested extends AppEvent {} 14 | 15 | class AppStartedEvent extends AppEvent {} 16 | 17 | class AppUserChanged extends AppEvent { 18 | @visibleForTesting 19 | const AppUserChanged(this.user); 20 | 21 | final UserModel user; 22 | 23 | @override 24 | List get props => [user]; 25 | } 26 | -------------------------------------------------------------------------------- /lib/app/bloc/app_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:auth_repo/auth_repo.dart'; 2 | import 'package:equatable/equatable.dart'; 3 | 4 | enum AppStatus { 5 | appStarted, 6 | authenticated, 7 | unauthenticated, 8 | } 9 | 10 | class AppState extends Equatable { 11 | const AppState._({required this.status, this.user = UserModel.empty}); 12 | 13 | final AppStatus status; 14 | final UserModel user; 15 | 16 | const AppState.authenticated(UserModel user) 17 | : this._(status: AppStatus.authenticated, user: user); 18 | 19 | const AppState.unauthenticated() : this._(status: AppStatus.unauthenticated); 20 | 21 | const AppState.AppStarted() : this._(status: AppStatus.appStarted); 22 | 23 | @override 24 | List get props => [status, user]; 25 | } 26 | -------------------------------------------------------------------------------- /lib/app/routes/route.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:todo/app/bloc/app_state.dart'; 3 | import 'package:todo/home/view/home_page.dart'; 4 | import 'package:todo/login/view/login.dart'; 5 | import 'package:todo/splash/view/splash_page.dart'; 6 | 7 | List onGenerateAppViewPages(AppStatus state, List> page) { 8 | switch (state) { 9 | case AppStatus.authenticated: 10 | return [HomePage.page()]; 11 | case AppStatus.unauthenticated: 12 | return [LoginPage.page()]; 13 | case AppStatus.appStarted: 14 | return [SplashPage.page()]; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/bootstrap.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:developer'; 3 | import 'package:auth_repo/auth_repo.dart'; 4 | import 'package:bloc/bloc.dart'; 5 | import 'package:flutter/material.dart'; 6 | import 'package:todo/app/app.dart'; 7 | import 'package:todo/app/app_bloc_observer.dart'; 8 | import 'package:todos_api/todos_api.dart'; 9 | import 'package:todos_repository/todo_repository.dart'; 10 | 11 | void boostrap({ 12 | required TodosApi todosApi, 13 | }) { 14 | FlutterError.onError = (details) { 15 | log( 16 | details.exceptionAsString(), 17 | stackTrace: details.stack, 18 | ); 19 | }; 20 | 21 | final todoRepository = TodoRepository( 22 | todosApi: todosApi, 23 | ); 24 | final authRepository = AuthRepo(); 25 | 26 | runZonedGuarded( 27 | () async { 28 | await authRepository.user.first; 29 | await BlocOverrides.runZoned( 30 | () async => runApp( 31 | App( 32 | todoRepository: todoRepository, 33 | authRepo: authRepository, 34 | ), 35 | ), 36 | blocObserver: AppBlocObserver(), 37 | ); 38 | }, 39 | (error, stackTrace) => log( 40 | error.toString(), 41 | stackTrace: stackTrace, 42 | ), 43 | ); 44 | } 45 | -------------------------------------------------------------------------------- /lib/edit_todo/bloc/edit_todo_bloc.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_bloc/flutter_bloc.dart'; 2 | import 'package:todo/edit_todo/bloc/edit_todo_event.dart'; 3 | import 'package:todo/edit_todo/bloc/edit_todo_state.dart'; 4 | import 'package:todos_repository/todo_repository.dart'; 5 | 6 | class EditTodoBloc extends Bloc { 7 | EditTodoBloc( 8 | {required TodoRepository todoRepository, required Todo? initialTodo}) 9 | : _todoRepository = todoRepository, 10 | super(EditTodoState( 11 | initialTodo: initialTodo, 12 | title: initialTodo?.title ?? '', 13 | description: initialTodo?.description ?? '', 14 | startTime: initialTodo?.startTime ?? '', 15 | date: initialTodo?.date ?? '', 16 | repeat: initialTodo?.repeat ?? '', 17 | )) { 18 | on(_onTitleChanged); 19 | on(_onDescriptionChanged); 20 | on(_onDateChanged); 21 | on(_onStartTime); 22 | on(_onRepeatChanged); 23 | on(_onSubmitted); 24 | } 25 | 26 | final TodoRepository _todoRepository; 27 | 28 | void _onTitleChanged( 29 | EditTodoTitleChanged event, 30 | Emitter emit, 31 | ) { 32 | emit(state.copyWith(title: event.title)); 33 | } 34 | 35 | void _onDescriptionChanged( 36 | EditTodoDescriptionChanged event, 37 | Emitter emit, 38 | ) { 39 | emit(state.copyWith(description: event.description)); 40 | } 41 | 42 | void _onDateChanged(EditTodoDateChanged event, Emitter emit) { 43 | emit(state.copyWith(date: event.date)); 44 | } 45 | 46 | void _onStartTime( 47 | EditTodoStartTimeChanged event, Emitter emit) { 48 | emit(state.copyWith(startTime: event.startTime)); 49 | } 50 | 51 | void _onRepeatChanged( 52 | EditTodoRepeatChanged event, Emitter emit) { 53 | emit(state.copyWith(repeat: event.repeat)); 54 | } 55 | 56 | Future _onSubmitted( 57 | EditTodoSubmitted event, Emitter emit) async { 58 | emit(state.copyWith(status: EditTodoStatus.loading)); 59 | final todo = (state.initialTodo ?? Todo(title: '')).copyWith( 60 | title: state.title, 61 | description: state.description, 62 | date: state.date, 63 | startTime: state.startTime, 64 | repeat: state.repeat, 65 | notificationId: state.title.length + state.description.length, 66 | ); 67 | 68 | try { 69 | await _todoRepository.saveTodo(todo); 70 | emit(state.copyWith(status: EditTodoStatus.success)); 71 | } catch (e) { 72 | emit(state.copyWith(status: EditTodoStatus.failure)); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /lib/edit_todo/bloc/edit_todo_event.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | abstract class EditTodoEvent extends Equatable { 4 | const EditTodoEvent(); 5 | 6 | @override 7 | List get props => []; 8 | } 9 | 10 | class EditTodoTitleChanged extends EditTodoEvent { 11 | const EditTodoTitleChanged(this.title); 12 | 13 | final String title; 14 | 15 | @override 16 | List get props => [title]; 17 | } 18 | 19 | class EditTodoDescriptionChanged extends EditTodoEvent { 20 | const EditTodoDescriptionChanged(this.description); 21 | 22 | final String description; 23 | 24 | @override 25 | List get props => [description]; 26 | } 27 | 28 | class EditTodoDateChanged extends EditTodoEvent { 29 | const EditTodoDateChanged(this.date); 30 | final String date; 31 | 32 | @override 33 | List get props => [date]; 34 | } 35 | 36 | class EditTodoRepeatChanged extends EditTodoEvent { 37 | const EditTodoRepeatChanged(this.repeat); 38 | final String repeat; 39 | 40 | @override 41 | List get props => [repeat]; 42 | } 43 | 44 | class EditTodoStartTimeChanged extends EditTodoEvent { 45 | const EditTodoStartTimeChanged(this.startTime); 46 | final String startTime; 47 | 48 | @override 49 | List get props => [startTime]; 50 | } 51 | 52 | class EditTodoSubmitted extends EditTodoEvent { 53 | const EditTodoSubmitted(); 54 | } 55 | -------------------------------------------------------------------------------- /lib/edit_todo/bloc/edit_todo_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:todos_repository/todo_repository.dart'; 3 | 4 | enum EditTodoStatus { initial, loading, success, failure } 5 | 6 | extension EditTodoStatusX on EditTodoStatus { 7 | bool get isLoadingOrSuccess => [ 8 | EditTodoStatus.loading, 9 | EditTodoStatus.success, 10 | ].contains(this); 11 | } 12 | 13 | class EditTodoState extends Equatable { 14 | const EditTodoState({ 15 | this.status = EditTodoStatus.initial, 16 | this.initialTodo, 17 | this.title = '', 18 | this.description = '', 19 | this.date = '', 20 | this.repeat = '', 21 | this.startTime = '', 22 | }); 23 | 24 | final EditTodoStatus status; 25 | final Todo? initialTodo; 26 | final String title; 27 | final String description; 28 | final String date; 29 | final String startTime; 30 | final String repeat; 31 | 32 | bool get isNewTodo => initialTodo == null; 33 | 34 | EditTodoState copyWith({ 35 | EditTodoStatus? status, 36 | Todo? initialTodo, 37 | String? title, 38 | String? description, 39 | String? date, 40 | String? startTime, 41 | String? repeat, 42 | }) { 43 | return EditTodoState( 44 | status: status ?? this.status, 45 | initialTodo: initialTodo ?? this.initialTodo, 46 | title: title ?? this.title, 47 | description: description ?? this.description, 48 | date: date ?? this.date, 49 | startTime: startTime ?? this.startTime, 50 | repeat: repeat ?? this.repeat, 51 | ); 52 | } 53 | 54 | @override 55 | List get props => [ 56 | status, 57 | initialTodo, 58 | title, 59 | description, 60 | date, 61 | startTime, 62 | repeat, 63 | ]; 64 | } 65 | -------------------------------------------------------------------------------- /lib/edit_todo/edit_todo.dart: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/lib/edit_todo/edit_todo.dart -------------------------------------------------------------------------------- /lib/firebase_options.dart: -------------------------------------------------------------------------------- 1 | // File generated by FlutterFire CLI. 2 | // ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members 3 | import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; 4 | import 'package:flutter/foundation.dart' 5 | show defaultTargetPlatform, kIsWeb, TargetPlatform; 6 | 7 | /// Default [FirebaseOptions] for use with your Firebase apps. 8 | /// 9 | /// Example: 10 | /// ```dart 11 | /// import 'firebase_options.dart'; 12 | /// // ... 13 | /// await Firebase.initializeApp( 14 | /// options: DefaultFirebaseOptions.currentPlatform, 15 | /// ); 16 | /// ``` 17 | class DefaultFirebaseOptions { 18 | static FirebaseOptions get currentPlatform { 19 | if (kIsWeb) { 20 | return web; 21 | } 22 | switch (defaultTargetPlatform) { 23 | case TargetPlatform.android: 24 | return android; 25 | case TargetPlatform.iOS: 26 | return ios; 27 | case TargetPlatform.macOS: 28 | throw UnsupportedError( 29 | 'DefaultFirebaseOptions have not been configured for macos - ' 30 | 'you can reconfigure this by running the FlutterFire CLI again.', 31 | ); 32 | default: 33 | throw UnsupportedError( 34 | 'DefaultFirebaseOptions are not supported for this platform.', 35 | ); 36 | } 37 | } 38 | 39 | static const FirebaseOptions web = FirebaseOptions( 40 | apiKey: 'AIzaSyC1jZIHs5uxYwCyROmGj_YCbmj_xxsZaVY', 41 | appId: '1:311087396382:web:932c7f7776f4a447d2e00f', 42 | messagingSenderId: '311087396382', 43 | projectId: 'flutter-project-cd13d', 44 | authDomain: 'flutter-project-cd13d.firebaseapp.com', 45 | storageBucket: 'flutter-project-cd13d.appspot.com', 46 | measurementId: 'G-Y99L8M92J8', 47 | ); 48 | 49 | static const FirebaseOptions android = FirebaseOptions( 50 | apiKey: 'AIzaSyCmdMcrlDd380iFgDYFEn1bY7GCR31PJ-M', 51 | appId: '1:311087396382:android:a8b55bc41328aaf2d2e00f', 52 | messagingSenderId: '311087396382', 53 | projectId: 'flutter-project-cd13d', 54 | storageBucket: 'flutter-project-cd13d.appspot.com', 55 | ); 56 | 57 | static const FirebaseOptions ios = FirebaseOptions( 58 | apiKey: 'AIzaSyAuKDjQAUjQ8OuGnVgEKG9aqx9zmvBtEH0', 59 | appId: '1:311087396382:ios:c7415a03c1d499a2d2e00f', 60 | messagingSenderId: '311087396382', 61 | projectId: 'flutter-project-cd13d', 62 | storageBucket: 'flutter-project-cd13d.appspot.com', 63 | iosClientId: '311087396382-75mtsg43u7j224pdlg5onmg53h7vt40r.apps.googleusercontent.com', 64 | iosBundleId: 'com.example.verygoodcore.todo', 65 | ); 66 | } 67 | -------------------------------------------------------------------------------- /lib/home/cubit/home_cubit.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_bloc/flutter_bloc.dart'; 2 | import 'package:todo/home/cubit/home_state.dart'; 3 | 4 | class HomeCubit extends Cubit { 5 | HomeCubit() : super(const HomeState()); 6 | 7 | void setTab(HomeTab tab) => emit(HomeState(tab: tab)); 8 | } 9 | -------------------------------------------------------------------------------- /lib/home/cubit/home_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | enum HomeTab { todos, stats, settings } 4 | 5 | class HomeState extends Equatable { 6 | const HomeState({this.tab = HomeTab.todos}); 7 | 8 | final HomeTab tab; 9 | 10 | @override 11 | List get props => [tab]; 12 | } 13 | -------------------------------------------------------------------------------- /lib/home/home.dart: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/lib/home/home.dart -------------------------------------------------------------------------------- /lib/home/view/home_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | import 'package:todo/edit_todo/view/edit_todo.dart'; 4 | import 'package:todo/home/cubit/home_cubit.dart'; 5 | import 'package:todo/home/cubit/home_state.dart'; 6 | import 'package:todo/settings/view/settings_page.dart'; 7 | import 'package:todo/stats/view/stats_page.dart'; 8 | import 'package:todo/todo_overview/view/todo_overview_page.dart'; 9 | import 'package:todos_repository/todo_repository.dart'; 10 | 11 | class HomePage extends StatelessWidget { 12 | const HomePage({Key? key}) : super(key: key); 13 | 14 | static Page page() => const MaterialPage(child: HomePage()); 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return BlocProvider( 19 | create: (_) => HomeCubit(), 20 | child: const HomeView(), 21 | ); 22 | } 23 | } 24 | 25 | class HomeView extends StatelessWidget { 26 | const HomeView({Key? key}) : super(key: key); 27 | 28 | @override 29 | Widget build(BuildContext context) { 30 | final selectedTab = context.select((HomeCubit cubit) => cubit.state.tab); 31 | 32 | return Scaffold( 33 | body: IndexedStack( 34 | index: selectedTab.index, 35 | children: const [TodosOverviewPage(), StatsPage(), SettingPage()], 36 | ), 37 | floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, 38 | floatingActionButton: FloatingActionButton( 39 | key: const Key('homeView_addTodo_floatingActionButton'), 40 | onPressed: () => Navigator.of(context).push(EditTodoPage.route()), 41 | child: const Icon(Icons.add), 42 | ), 43 | bottomNavigationBar: BottomAppBar( 44 | shape: const CircularNotchedRectangle(), 45 | child: Row( 46 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 47 | children: [ 48 | _HomeTabButton( 49 | groupValue: selectedTab, 50 | value: HomeTab.todos, 51 | icon: const Icon(Icons.list_rounded)), 52 | _HomeTabButton( 53 | groupValue: selectedTab, 54 | value: HomeTab.stats, 55 | icon: const Icon(Icons.show_chart_rounded)), 56 | _HomeTabButton( 57 | groupValue: selectedTab, 58 | value: HomeTab.settings, 59 | icon: const Icon(Icons.settings_outlined)), 60 | ], 61 | ), 62 | ), 63 | ); 64 | } 65 | } 66 | 67 | class _HomeTabButton extends StatelessWidget { 68 | const _HomeTabButton( 69 | {Key? key, 70 | required this.groupValue, 71 | required this.value, 72 | required this.icon}) 73 | : super(key: key); 74 | 75 | final HomeTab groupValue; 76 | final HomeTab value; 77 | final Widget icon; 78 | 79 | @override 80 | Widget build(BuildContext context) { 81 | return IconButton( 82 | onPressed: () => context.read().setTab(value), 83 | iconSize: 32, 84 | color: 85 | groupValue != value ? null : Theme.of(context).colorScheme.secondary, 86 | icon: icon, 87 | ); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /lib/l10n/l10n.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | import 'package:flutter_gen/gen_l10n/app_localizations.dart'; 3 | 4 | extension AppLocalizationsX on BuildContext { 5 | AppLocalizations get l10n => AppLocalizations.of(this); 6 | } 7 | -------------------------------------------------------------------------------- /lib/login/cubit/login_cubit.dart: -------------------------------------------------------------------------------- 1 | import 'package:auth_repo/auth_repo.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | import 'package:form_input/form_input.dart'; 4 | import 'package:formz/formz.dart'; 5 | import 'package:todo/login/cubit/login_state.dart'; 6 | 7 | class LoginCubit extends Cubit { 8 | LoginCubit(this._authRepo) : super(const LoginState()); 9 | 10 | final AuthRepo _authRepo; 11 | 12 | void emailChanged(String value) { 13 | final email = Email.dirty(value); 14 | emit( 15 | state.copyWith( 16 | email: email, 17 | status: Formz.validate([email, state.password]), 18 | ), 19 | ); 20 | } 21 | 22 | void passwordChanged(String value) { 23 | final password = Password.dirty(value); 24 | emit( 25 | state.copyWith( 26 | password: password, 27 | status: Formz.validate( 28 | [state.email, password], 29 | ), 30 | ), 31 | ); 32 | } 33 | 34 | Future login() async { 35 | if (!state.status.isValidated) return; 36 | emit( 37 | state.copyWith( 38 | status: FormzStatus.submissionInProgress, 39 | ), 40 | ); 41 | try { 42 | await _authRepo.login( 43 | email: state.email.value, 44 | password: state.password.value, 45 | ); 46 | emit( 47 | state.copyWith( 48 | status: FormzStatus.submissionSuccess, 49 | ), 50 | ); 51 | } on AuthError catch (e) { 52 | emit( 53 | state.copyWith( 54 | errorMessage: e.dialogText, 55 | status: FormzStatus.submissionFailure, 56 | ), 57 | ); 58 | } catch (_) { 59 | emit( 60 | state.copyWith( 61 | status: FormzStatus.submissionFailure, 62 | ), 63 | ); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /lib/login/cubit/login_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:form_input/form_input.dart'; 3 | import 'package:formz/formz.dart'; 4 | 5 | class LoginState extends Equatable { 6 | const LoginState({ 7 | this.email = const Email.pure(), 8 | this.password = const Password.pure(), 9 | this.status = FormzStatus.pure, 10 | this.errorMessage, 11 | }); 12 | 13 | final Email email; 14 | final Password password; 15 | final FormzStatus status; 16 | final String? errorMessage; 17 | 18 | LoginState copyWith({ 19 | Email? email, 20 | Password? password, 21 | FormzStatus? status, 22 | String? errorMessage, 23 | }) { 24 | return LoginState( 25 | email: email ?? this.email, 26 | password: password ?? this.password, 27 | status: status ?? this.status, 28 | errorMessage: errorMessage ?? this.errorMessage, 29 | ); 30 | } 31 | 32 | @override 33 | List get props => [ 34 | email, 35 | password, 36 | status, 37 | ]; 38 | } 39 | -------------------------------------------------------------------------------- /lib/login/login.dart: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/lib/login/login.dart -------------------------------------------------------------------------------- /lib/login/view/login.dart: -------------------------------------------------------------------------------- 1 | import 'package:auth_repo/auth_repo.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_bloc/flutter_bloc.dart'; 4 | import 'package:todo/login/cubit/login_cubit.dart'; 5 | import 'package:todo/login/view/login_form.dart'; 6 | import 'package:todo/theme/app_theme.dart'; 7 | import 'package:todo/theme/theme_bloc.dart'; 8 | 9 | class LoginPage extends StatelessWidget { 10 | const LoginPage({Key? key}) : super(key: key); 11 | 12 | static Page page() => const MaterialPage(child: LoginPage()); 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | final themeData = context.select( 17 | (ThemeBloc bloc) => bloc.state.themeData, 18 | ); 19 | final appbarColor = themeData == FlutterTodosTheme.dark 20 | ? Theme.of(context).scaffoldBackgroundColor 21 | : null; 22 | return Scaffold( 23 | appBar: AppBar( 24 | elevation: 2, 25 | title: const Text('Login'), 26 | backgroundColor: appbarColor, 27 | ), 28 | body: Padding( 29 | padding: const EdgeInsets.all(8), 30 | child: BlocProvider( 31 | create: (_) => LoginCubit(context.read()), 32 | child: const LoginForm(), 33 | ), 34 | )); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/main_development.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_storage_todos_api/cloud_storage_todos_api.dart'; 2 | import 'package:firebase_core/firebase_core.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter/services.dart'; 5 | import 'package:flutter_services_binding/flutter_services_binding.dart'; 6 | import 'package:local_storage_todos_api/local_storage_todos_api.dart'; 7 | import 'package:todo/bootstrap.dart'; 8 | import 'package:todo/service/notification_service.dart'; 9 | import 'package:todo/theme/sharepreference.dart'; 10 | 11 | Future main() async { 12 | FlutterServicesBinding.ensureInitialized(); 13 | SystemChrome.setSystemUIOverlayStyle( 14 | const SystemUiOverlayStyle( 15 | // navigation bar color 16 | statusBarColor: Colors.blue, 17 | statusBarIconBrightness: Brightness.dark // status bar color 18 | ), 19 | ); 20 | await SystemChrome.setPreferredOrientations([ 21 | DeviceOrientation.portraitUp, 22 | DeviceOrientation.portraitDown, 23 | ]); 24 | await Firebase.initializeApp(); 25 | await Preferences.init(); 26 | await NotifyHelper.initializeNotification(); 27 | NotifyHelper.requestIOSPermissions(); 28 | final cloudTodoApi = CloudStorageTodosApi(); 29 | final todosApi = LocalStorageTodosApi( 30 | plugin: await SharedPreferences.getInstance(), 31 | cloudStorageTodosApi: cloudTodoApi, 32 | ); 33 | boostrap(todosApi: todosApi); 34 | } 35 | -------------------------------------------------------------------------------- /lib/main_production.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_storage_todos_api/cloud_storage_todos_api.dart'; 2 | import 'package:firebase_core/firebase_core.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter/services.dart'; 5 | import 'package:flutter_services_binding/flutter_services_binding.dart'; 6 | import 'package:local_storage_todos_api/local_storage_todos_api.dart'; 7 | import 'package:todo/bootstrap.dart'; 8 | import 'package:todo/service/notification_service.dart'; 9 | import 'package:todo/theme/sharepreference.dart'; 10 | 11 | Future main() async { 12 | FlutterServicesBinding.ensureInitialized(); 13 | SystemChrome.setSystemUIOverlayStyle( 14 | const SystemUiOverlayStyle( 15 | // navigation bar color 16 | statusBarColor: Colors.blue, 17 | statusBarIconBrightness: Brightness.dark // status bar color 18 | ), 19 | ); 20 | await SystemChrome.setPreferredOrientations([ 21 | DeviceOrientation.portraitUp, 22 | DeviceOrientation.portraitDown, 23 | ]); 24 | await Firebase.initializeApp(); 25 | await Preferences.init(); 26 | await NotifyHelper.initializeNotification(); 27 | NotifyHelper.requestIOSPermissions(); 28 | final cloudTodoApi = CloudStorageTodosApi(); 29 | final todosApi = LocalStorageTodosApi( 30 | plugin: await SharedPreferences.getInstance(), 31 | cloudStorageTodosApi: cloudTodoApi, 32 | ); 33 | 34 | boostrap(todosApi: todosApi); 35 | } 36 | -------------------------------------------------------------------------------- /lib/main_staging.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_storage_todos_api/cloud_storage_todos_api.dart'; 2 | import 'package:firebase_core/firebase_core.dart'; 3 | import 'package:flutter_services_binding/flutter_services_binding.dart'; 4 | import 'package:local_storage_todos_api/local_storage_todos_api.dart'; 5 | import 'package:todo/bootstrap.dart'; 6 | import 'package:todo/theme/sharepreference.dart'; 7 | 8 | Future main() async { 9 | FlutterServicesBinding.ensureInitialized(); 10 | await Firebase.initializeApp(); 11 | await Preferences.init(); 12 | final cloudTodoApi = CloudStorageTodosApi(); 13 | final todosApi = LocalStorageTodosApi( 14 | plugin: await SharedPreferences.getInstance(), 15 | cloudStorageTodosApi: cloudTodoApi, 16 | ); 17 | 18 | boostrap(todosApi: todosApi); 19 | } 20 | -------------------------------------------------------------------------------- /lib/service/notification_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_local_notifications/flutter_local_notifications.dart'; 2 | import 'package:flutter_native_timezone/flutter_native_timezone.dart'; 3 | import 'package:todos_api/todos_api.dart'; 4 | import 'package:timezone/timezone.dart' as tz; 5 | import 'package:timezone/data/latest.dart' as tz; 6 | 7 | class NotifyHelper { 8 | static FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = 9 | FlutterLocalNotificationsPlugin(); // 10 | 11 | static Future initializeNotification() async { 12 | _configureLocalTimeZone(); 13 | final initializationSettingsIOS = IOSInitializationSettings( 14 | requestSoundPermission: false, 15 | requestBadgePermission: false, 16 | requestAlertPermission: false, 17 | onDidReceiveLocalNotification: onDidReceiveLocalNotification); 18 | 19 | final AndroidInitializationSettings initializationSettingsAndroid = 20 | AndroidInitializationSettings("appicon"); 21 | 22 | final initializationSettings = InitializationSettings( 23 | iOS: initializationSettingsIOS, 24 | android: initializationSettingsAndroid, 25 | ); 26 | 27 | await flutterLocalNotificationsPlugin.initialize(initializationSettings, 28 | onSelectNotification: selectNotification); 29 | } 30 | 31 | static Future onDidReceiveLocalNotification( 32 | int id, String? title, String? body, String? payload) async {} 33 | 34 | static Future selectNotification(String? payload) async { 35 | if (payload != null) { 36 | } else {} 37 | } 38 | 39 | static void requestIOSPermissions() { 40 | flutterLocalNotificationsPlugin 41 | .resolvePlatformSpecificImplementation< 42 | IOSFlutterLocalNotificationsPlugin>() 43 | ?.requestPermissions( 44 | alert: true, 45 | badge: true, 46 | sound: true, 47 | ); 48 | } 49 | 50 | static Future scheduledNotification( 51 | int hour, 52 | int minutes, 53 | Todo todo, 54 | ) async { 55 | await flutterLocalNotificationsPlugin.zonedSchedule( 56 | todo.notificationId, 57 | todo.title, 58 | todo.description, 59 | _convertTime(hour, minutes), 60 | const NotificationDetails( 61 | android: AndroidNotificationDetails( 62 | 'your channel id', 63 | 'your channel name', 64 | ), 65 | ), 66 | androidAllowWhileIdle: true, 67 | uiLocalNotificationDateInterpretation: 68 | UILocalNotificationDateInterpretation.absoluteTime, 69 | matchDateTimeComponents: DateTimeComponents.time, 70 | payload: '${todo.title}|' '${todo.description}|'); 71 | } 72 | 73 | static tz.TZDateTime _convertTime(int hour, int minutes) { 74 | final now = tz.TZDateTime.now(tz.local); 75 | var scheduleDate = 76 | tz.TZDateTime(tz.local, now.year, now.month, now.day, hour, minutes); 77 | if (scheduleDate.isBefore(now)) { 78 | scheduleDate = scheduleDate.add(const Duration(days: 1)); 79 | } 80 | return scheduleDate; 81 | } 82 | 83 | static Future _configureLocalTimeZone() async { 84 | tz.initializeTimeZones(); 85 | final timeZone = await FlutterNativeTimezone.getLocalTimezone(); 86 | tz.setLocalLocation(tz.getLocation(timeZone)); 87 | } 88 | 89 | static Future cancelNotification(int notificationId) async { 90 | await flutterLocalNotificationsPlugin.cancel(notificationId); 91 | } 92 | 93 | static Future cancelAllNotification() async { 94 | await flutterLocalNotificationsPlugin.cancelAll(); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /lib/settings/cubit/settings_cubit.dart: -------------------------------------------------------------------------------- 1 | import 'package:auth_repo/auth_repo.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | import 'package:todo/settings/cubit/settings_state.dart'; 4 | 5 | class SettingsCubit extends Cubit { 6 | SettingsCubit({required AuthRepo authRepo}) 7 | : _authRepo = authRepo, 8 | super(const SettingsState()); 9 | final AuthRepo _authRepo; 10 | } 11 | -------------------------------------------------------------------------------- /lib/settings/cubit/settings_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | class SettingsState extends Equatable { 4 | const SettingsState(); 5 | 6 | @override 7 | List get props => []; 8 | } 9 | -------------------------------------------------------------------------------- /lib/settings/settings.dart: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/lib/settings/settings.dart -------------------------------------------------------------------------------- /lib/sign_up/bloc/sign_up_bloc.dart: -------------------------------------------------------------------------------- 1 | import 'package:auth_repo/auth_repo.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | import 'package:form_input/form_input.dart'; 4 | import 'package:formz/formz.dart'; 5 | import 'package:todo/sign_up/bloc/sign_up_state.dart'; 6 | 7 | class SignUpCubit extends Cubit { 8 | SignUpCubit(this._authRepo) : super(const SignUpState()); 9 | final AuthRepo _authRepo; 10 | 11 | void emailChanged(String value) { 12 | final email = Email.dirty(value); 13 | emit( 14 | state.copyWith( 15 | email: email, 16 | status: Formz.validate([ 17 | email, 18 | state.password, 19 | state.confirmedPassword, 20 | ]), 21 | ), 22 | ); 23 | } 24 | 25 | void passwordChanged(String value) { 26 | final password = Password.dirty(value); 27 | final confirmPassword = ConfirmedPassword.dirty( 28 | password: password.value, value: state.confirmedPassword.value); 29 | emit(state.copyWith( 30 | password: password, 31 | confirmedPassword: confirmPassword, 32 | status: Formz.validate([ 33 | state.email, 34 | password, 35 | confirmPassword, 36 | ]), 37 | )); 38 | } 39 | 40 | void confirmedPasswordChanged(String value) { 41 | final confirmedPassword = ConfirmedPassword.dirty( 42 | password: state.password.value, 43 | value: value, 44 | ); 45 | emit( 46 | state.copyWith( 47 | confirmedPassword: confirmedPassword, 48 | status: Formz.validate([ 49 | state.email, 50 | state.password, 51 | confirmedPassword, 52 | ]), 53 | ), 54 | ); 55 | } 56 | 57 | Future signUpFormSubmitted() async { 58 | if (!state.status.isValidated) return; 59 | emit( 60 | state.copyWith( 61 | status: FormzStatus.submissionInProgress, 62 | ), 63 | ); 64 | try { 65 | await _authRepo.signUp( 66 | email: state.email.value, 67 | password: state.password.value, 68 | ); 69 | emit( 70 | state.copyWith( 71 | status: FormzStatus.submissionSuccess, 72 | ), 73 | ); 74 | } on AuthError catch (e) { 75 | emit( 76 | state.copyWith( 77 | errorMessage: e.dialogText, 78 | status: FormzStatus.submissionFailure, 79 | ), 80 | ); 81 | } catch (_) { 82 | emit( 83 | state.copyWith( 84 | status: FormzStatus.submissionFailure, 85 | ), 86 | ); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /lib/sign_up/bloc/sign_up_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:form_input/form_input.dart'; 3 | import 'package:formz/formz.dart'; 4 | 5 | enum ConfirmationValidationError { invalid } 6 | 7 | class SignUpState extends Equatable { 8 | const SignUpState({ 9 | this.email = const Email.pure(), 10 | this.password = const Password.pure(), 11 | this.confirmedPassword = const ConfirmedPassword.pure(), 12 | this.status = FormzStatus.pure, 13 | this.errorMessage, 14 | }); 15 | 16 | final Email email; 17 | final Password password; 18 | final ConfirmedPassword confirmedPassword; 19 | final FormzStatus status; 20 | final String? errorMessage; 21 | 22 | @override 23 | List get props => [email, password, confirmedPassword, status]; 24 | 25 | SignUpState copyWith({ 26 | Email? email, 27 | Password? password, 28 | ConfirmedPassword? confirmedPassword, 29 | FormzStatus? status, 30 | String? errorMessage, 31 | }) { 32 | return SignUpState( 33 | email: email ?? this.email, 34 | password: password ?? this.password, 35 | confirmedPassword: confirmedPassword ?? this.confirmedPassword, 36 | status: status ?? this.status, 37 | errorMessage: errorMessage ?? this.errorMessage, 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/sign_up/sign_up.dart: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/lib/sign_up/sign_up.dart -------------------------------------------------------------------------------- /lib/sign_up/view/sign_up_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:auth_repo/auth_repo.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_bloc/flutter_bloc.dart'; 4 | import 'package:todo/sign_up/bloc/sign_up_bloc.dart'; 5 | import 'package:todo/sign_up/view/sign_up_form.dart'; 6 | import 'package:todo/theme/app_theme.dart'; 7 | import 'package:todo/theme/theme_bloc.dart'; 8 | 9 | class SignUpPage extends StatelessWidget { 10 | const SignUpPage({Key? key}) : super(key: key); 11 | 12 | static Route route() { 13 | return MaterialPageRoute(builder: (_) => const SignUpPage()); 14 | } 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | final themeData = context.select( 19 | (ThemeBloc bloc) => bloc.state.themeData, 20 | ); 21 | final appbarColor = themeData == FlutterTodosTheme.dark 22 | ? Theme.of(context).scaffoldBackgroundColor 23 | : null; 24 | return Scaffold( 25 | appBar: AppBar( 26 | title: const Text('Sign Up'), 27 | elevation: 2, 28 | backgroundColor: appbarColor, 29 | ), 30 | body: Padding( 31 | padding: const EdgeInsets.all(8), 32 | child: BlocProvider( 33 | create: (_) => SignUpCubit(context.read()), 34 | child: const SignupForm(), 35 | ), 36 | ), 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lib/splash/splash.dart: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/lib/splash/splash.dart -------------------------------------------------------------------------------- /lib/splash/view/splash_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/services.dart'; 3 | import 'package:todo/theme/app_theme.dart'; 4 | 5 | class SplashPage extends StatelessWidget { 6 | const SplashPage({Key? key}) : super(key: key); 7 | 8 | static Page page() => const MaterialPage(child: SplashPage()); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | SystemChrome.setEnabledSystemUIMode( 13 | SystemUiMode.manual, 14 | overlays: [ 15 | SystemUiOverlay.top, 16 | SystemUiOverlay.bottom, 17 | ], 18 | ); 19 | return const Scaffold( 20 | backgroundColor: Colors.blue, 21 | body: Center( 22 | child: Text( 23 | 'Todo APP with Bloc Design Pattern', 24 | style: TextStyle( 25 | fontSize: 24, 26 | fontWeight: FontWeight.w900, 27 | color: Colors.white, 28 | ), 29 | ), 30 | ), 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/stats/bloc/stats_bloc.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_bloc/flutter_bloc.dart'; 2 | import 'package:todo/stats/bloc/stats_event.dart'; 3 | import 'package:todo/stats/bloc/stats_state.dart'; 4 | import 'package:todos_repository/todo_repository.dart'; 5 | 6 | class StatsBloc extends Bloc { 7 | StatsBloc({ 8 | required TodoRepository todoRepository, 9 | }) : _todoRepository = todoRepository, 10 | super(const StatsState()) { 11 | on(_onSubscriptionRequested); 12 | } 13 | 14 | final TodoRepository _todoRepository; 15 | 16 | Future _onSubscriptionRequested( 17 | StatsSubscriptionRequested event, Emitter emit) async { 18 | emit(state.copyWith(status: StatsStatus.loading)); 19 | 20 | await emit.forEach>( 21 | _todoRepository.getTodos(), 22 | onData: (todos) => state.copyWith( 23 | status: StatsStatus.success, 24 | completedTodos: todos.where((todo) => todo.isCompleted).length, 25 | activeTodos: todos.where((todo) => !todo.isCompleted).length), 26 | onError: (_, __) => state.copyWith(status: StatsStatus.failure), 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lib/stats/bloc/stats_event.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | abstract class StatsEvent extends Equatable { 4 | const StatsEvent(); 5 | 6 | @override 7 | List get props => []; 8 | } 9 | 10 | class StatsSubscriptionRequested extends StatsEvent { 11 | const StatsSubscriptionRequested(); 12 | } 13 | -------------------------------------------------------------------------------- /lib/stats/bloc/stats_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | enum StatsStatus { initial, loading, success, failure } 4 | 5 | class StatsState extends Equatable { 6 | const StatsState( 7 | {this.status = StatsStatus.initial, 8 | this.completedTodos = 0, 9 | this.activeTodos = 0}); 10 | 11 | final StatsStatus status; 12 | final int completedTodos; 13 | final int activeTodos; 14 | 15 | @override 16 | List get props => [status, completedTodos, activeTodos]; 17 | 18 | StatsState copyWith( 19 | {StatsStatus? status, int? completedTodos, int? activeTodos}) { 20 | return StatsState( 21 | status: status ?? this.status, 22 | completedTodos: completedTodos ?? this.completedTodos, 23 | activeTodos: activeTodos ?? this.activeTodos); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/stats/stats.dart: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/lib/stats/stats.dart -------------------------------------------------------------------------------- /lib/stats/view/stats_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | import 'package:todo/stats/bloc/stats_bloc.dart'; 4 | import 'package:todo/stats/bloc/stats_event.dart'; 5 | import 'package:todo/theme/app_theme.dart'; 6 | import 'package:todo/theme/theme_bloc.dart'; 7 | import 'package:todos_repository/todo_repository.dart'; 8 | 9 | class StatsPage extends StatelessWidget { 10 | const StatsPage({Key? key}) : super(key: key); 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | return BlocProvider( 15 | create: (context) => 16 | StatsBloc(todoRepository: context.read()) 17 | ..add(const StatsSubscriptionRequested()), 18 | child: const StatsView(), 19 | ); 20 | } 21 | } 22 | 23 | class StatsView extends StatelessWidget { 24 | const StatsView({Key? key}) : super(key: key); 25 | 26 | @override 27 | Widget build(BuildContext context) { 28 | final state = context.watch().state; 29 | final textTheme = Theme.of(context).textTheme; 30 | final themeData = context.select( 31 | (ThemeBloc bloc) => bloc.state.themeData, 32 | ); 33 | final appbarColor = themeData == FlutterTodosTheme.dark 34 | ? Theme.of(context).scaffoldBackgroundColor 35 | : null; 36 | 37 | return Scaffold( 38 | appBar: AppBar( 39 | elevation: 2, 40 | title: const Text('Stats of Todos'), 41 | backgroundColor: appbarColor, 42 | ), 43 | body: Column( 44 | mainAxisAlignment: MainAxisAlignment.center, 45 | children: [ 46 | ListTile( 47 | key: const Key('statsView_completedTodos_listTile'), 48 | leading: const Icon(Icons.check_rounded), 49 | title: const Text( 50 | 'Completed Todos', 51 | ), 52 | trailing: 53 | Text('${state.completedTodos}', style: textTheme.headline5), 54 | ), 55 | ListTile( 56 | key: const Key('statsView_activeTodos_listTile'), 57 | leading: const Icon(Icons.radio_button_unchecked_rounded), 58 | title: const Text('Active Todos'), 59 | trailing: Text('${state.activeTodos}', style: textTheme.headline5), 60 | ) 61 | ], 62 | ), 63 | ); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /lib/theme/app_theme.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class FlutterTodosTheme { 4 | static ThemeData get light { 5 | return ThemeData( 6 | appBarTheme: const AppBarTheme(color: Colors.blue), 7 | colorScheme: ColorScheme.fromSwatch( 8 | accentColor: Colors.blue, 9 | ), 10 | snackBarTheme: const SnackBarThemeData( 11 | behavior: SnackBarBehavior.floating, 12 | ), 13 | toggleableActiveColor: Colors.blue, 14 | ); 15 | } 16 | 17 | static ThemeData get dark { 18 | return ThemeData( 19 | appBarTheme: const AppBarTheme( 20 | color: Colors.blue, 21 | ), 22 | colorScheme: ColorScheme.fromSwatch( 23 | brightness: Brightness.dark, 24 | accentColor: const Color(0xFF13B9FF), 25 | ), 26 | snackBarTheme: const SnackBarThemeData( 27 | behavior: SnackBarBehavior.floating, 28 | ), 29 | toggleableActiveColor: Colors.blue, 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/theme/sharepreference.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'dart:ffi'; 3 | 4 | import 'package:flutter/material.dart'; 5 | import 'package:local_storage_todos_api/local_storage_todos_api.dart'; 6 | import 'package:todo/theme/app_theme.dart'; 7 | 8 | class Preferences { 9 | static SharedPreferences? preferences; 10 | static const String KEY_SELECTED_THEME = 'key_selected_theme'; 11 | 12 | static Future init() async { 13 | preferences = await SharedPreferences.getInstance(); 14 | } 15 | 16 | static Future saveTheme(bool isDarkTheme) async { 17 | await preferences!.setString(KEY_SELECTED_THEME, isDarkTheme.toString()); 18 | } 19 | 20 | static ThemeData getTheme() { 21 | final theme = preferences!.getString(KEY_SELECTED_THEME); 22 | if (theme != null && theme == 'true') { 23 | return FlutterTodosTheme.dark; 24 | } else { 25 | return FlutterTodosTheme.light; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lib/theme/theme_bloc.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_bloc/flutter_bloc.dart'; 2 | import 'package:todo/theme/app_theme.dart'; 3 | import 'package:todo/theme/sharepreference.dart'; 4 | import 'package:todo/theme/theme_event.dart'; 5 | import 'package:todo/theme/theme_state.dart'; 6 | 7 | class ThemeBloc extends Bloc { 8 | ThemeBloc() : super(ThemeState(themeData: Preferences.getTheme())) { 9 | on(_onAppThemeChanged); 10 | } 11 | 12 | Future _onAppThemeChanged( 13 | ThemeEvent event, 14 | Emitter emit, 15 | ) async { 16 | await Preferences.saveTheme(event.value); 17 | emit(ThemeState(themeData: Preferences.getTheme())); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/theme/theme_event.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:todo/theme/app_theme.dart'; 4 | 5 | abstract class AppThemeEvent extends Equatable { 6 | const AppThemeEvent(); 7 | 8 | @override 9 | List get props => []; 10 | } 11 | 12 | class ThemeEvent extends AppThemeEvent { 13 | final bool value; 14 | const ThemeEvent({required this.value}); 15 | } 16 | -------------------------------------------------------------------------------- /lib/theme/theme_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class ThemeState extends Equatable { 5 | final ThemeData themeData; 6 | 7 | const ThemeState({ 8 | required this.themeData, 9 | }); 10 | 11 | @override 12 | List get props => [themeData]; 13 | } 14 | -------------------------------------------------------------------------------- /lib/todo_overview/bloc/todo_overview_event.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:todos_repository/todo_repository.dart'; 3 | 4 | import '../model/todo_view_filter.dart'; 5 | 6 | abstract class TodosOverviewEvent extends Equatable { 7 | const TodosOverviewEvent(); 8 | 9 | @override 10 | List get props => []; 11 | } 12 | 13 | class TodosOverviewSubcriptionRequested extends TodosOverviewEvent { 14 | const TodosOverviewSubcriptionRequested(); 15 | } 16 | 17 | class TodosOverviewTodoCompletionToggled extends TodosOverviewEvent { 18 | const TodosOverviewTodoCompletionToggled( 19 | {required this.todo, required this.isCompleted}); 20 | 21 | final Todo todo; 22 | final bool isCompleted; 23 | 24 | @override 25 | List get props => [todo]; 26 | } 27 | 28 | class TodosOverviewTodoDeleted extends TodosOverviewEvent { 29 | const TodosOverviewTodoDeleted(this.todo); 30 | 31 | final Todo todo; 32 | 33 | @override 34 | List get props => [todo]; 35 | } 36 | 37 | class TodosOverviewUndoDeletionRequested extends TodosOverviewEvent { 38 | const TodosOverviewUndoDeletionRequested(); 39 | } 40 | 41 | class TodosOverviewFilterChanged extends TodosOverviewEvent { 42 | const TodosOverviewFilterChanged(this.filter); 43 | 44 | final TodosViewFilter filter; 45 | 46 | @override 47 | List get props => [filter]; 48 | } 49 | 50 | class TodosOverviewToggleAllRequested extends TodosOverviewEvent { 51 | const TodosOverviewToggleAllRequested(); 52 | } 53 | 54 | class TodosOverviewClearCompletedRequested extends TodosOverviewEvent { 55 | const TodosOverviewClearCompletedRequested(); 56 | } 57 | 58 | class TodoRefreshFromCloud extends TodosOverviewEvent { 59 | const TodoRefreshFromCloud(); 60 | } 61 | 62 | class TodoOverviewDateTimeChanged extends TodosOverviewEvent { 63 | const TodoOverviewDateTimeChanged(this.date); 64 | 65 | final DateTime date; 66 | 67 | @override 68 | List get props => [date]; 69 | } 70 | -------------------------------------------------------------------------------- /lib/todo_overview/bloc/todo_overview_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:todo/todo_overview/model/todo_view_filter.dart'; 3 | import 'package:todos_repository/todo_repository.dart'; 4 | 5 | enum TodosOverviewStatus { initial, loading, success, failure } 6 | 7 | class TodosOverviewState extends Equatable { 8 | const TodosOverviewState({ 9 | this.status = TodosOverviewStatus.initial, 10 | this.todos = const [], 11 | this.filter = TodosViewFilter.all, 12 | this.lastDeletedTodo, 13 | this.date, 14 | }); 15 | 16 | final TodosOverviewStatus status; 17 | final List todos; 18 | final TodosViewFilter filter; 19 | final Todo? lastDeletedTodo; 20 | final DateTime? date; 21 | 22 | Iterable get filteredTodos => filter.applyAll(todos); 23 | 24 | TodosOverviewState copyWith({ 25 | TodosOverviewStatus Function()? status, 26 | List Function()? todos, 27 | TodosViewFilter Function()? filter, 28 | Todo? Function()? lastDeletedTodo, 29 | DateTime? Function()? date, 30 | }) { 31 | return TodosOverviewState( 32 | status: status != null ? status() : this.status, 33 | todos: todos != null ? todos() : this.todos, 34 | filter: filter != null ? filter() : this.filter, 35 | lastDeletedTodo: 36 | lastDeletedTodo != null ? lastDeletedTodo() : this.lastDeletedTodo, 37 | date: date != null ? date() : this.date, 38 | ); 39 | } 40 | 41 | @override 42 | List get props => [status, todos, filter, lastDeletedTodo, date]; 43 | } 44 | -------------------------------------------------------------------------------- /lib/todo_overview/model/todo_view_filter.dart: -------------------------------------------------------------------------------- 1 | import 'package:todos_repository/todo_repository.dart'; 2 | 3 | enum TodosViewFilter { all, activeOnly, completedOnly } 4 | 5 | extension TodosViewFilterX on TodosViewFilter { 6 | bool apply(Todo todo) { 7 | switch (this) { 8 | case TodosViewFilter.all: 9 | return true; 10 | case TodosViewFilter.activeOnly: 11 | return !todo.isCompleted; 12 | case TodosViewFilter.completedOnly: 13 | return todo.isCompleted; 14 | } 15 | } 16 | 17 | Iterable applyAll(Iterable todos) { 18 | return todos.where(apply); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/todo_overview/todo_overview.dart: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /lib/todo_overview/view/widget/date_task_bar.dart: -------------------------------------------------------------------------------- 1 | import 'package:date_picker_timeline/date_picker_timeline.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class AddDateTaskBar extends StatelessWidget { 5 | const AddDateTaskBar({Key? key, this.dateTime}) : super(key: key); 6 | final Function(DateTime)? dateTime; 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return Container( 11 | margin: const EdgeInsets.only(top: 20, left: 20), 12 | child: DatePicker( 13 | DateTime.now(), 14 | height: 100, 15 | width: 80, 16 | initialSelectedDate: DateTime.now(), 17 | selectionColor: Colors.blue, 18 | selectedTextColor: Colors.white, 19 | dateTextStyle: const TextStyle( 20 | fontSize: 14, 21 | fontWeight: FontWeight.w600, 22 | color: Colors.grey, 23 | ), 24 | dayTextStyle: const TextStyle( 25 | fontSize: 16, 26 | fontWeight: FontWeight.w600, 27 | color: Colors.grey, 28 | ), 29 | monthTextStyle: const TextStyle( 30 | fontSize: 14, 31 | fontWeight: FontWeight.w600, 32 | color: Colors.grey, 33 | ), 34 | onDateChange: (date) { 35 | dateTime!(date); 36 | }, 37 | ), 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/todo_overview/view/widget/todo_tiles.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:todos_api/todos_api.dart'; 3 | 4 | class TodoListTiles extends StatelessWidget { 5 | const TodoListTiles( 6 | {Key? key, 7 | required this.todo, 8 | this.onTap, 9 | this.onToggleCompleted, 10 | this.onDismissed}) 11 | : super(key: key); 12 | 13 | final Todo todo; 14 | final ValueChanged? onToggleCompleted; 15 | final DismissDirectionCallback? onDismissed; 16 | final VoidCallback? onTap; 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | final theme = Theme.of(context); 21 | final captionColor = theme.textTheme.caption?.color; 22 | 23 | return Dismissible( 24 | key: Key('todoListTile_dismissible_${todo.id}'), 25 | onDismissed: onDismissed, 26 | direction: DismissDirection.endToStart, 27 | background: Container( 28 | alignment: Alignment.centerRight, 29 | color: theme.colorScheme.error, 30 | padding: const EdgeInsets.symmetric(horizontal: 16), 31 | child: const Icon( 32 | Icons.delete, 33 | color: Color(0xAAFFFFFF), 34 | ), 35 | ), 36 | child: ListTile( 37 | onTap: onTap, 38 | title: Text( 39 | todo.title, 40 | maxLines: 1, 41 | overflow: TextOverflow.ellipsis, 42 | style: !todo.isCompleted 43 | ? null 44 | : TextStyle( 45 | color: captionColor, 46 | decoration: TextDecoration.lineThrough, 47 | ), 48 | ), 49 | subtitle: Text( 50 | todo.description, 51 | maxLines: 1, 52 | overflow: TextOverflow.ellipsis, 53 | ), 54 | leading: Checkbox( 55 | shape: const ContinuousRectangleBorder( 56 | borderRadius: BorderRadius.all(Radius.circular(8)), 57 | ), 58 | value: todo.isCompleted, 59 | onChanged: onToggleCompleted == null 60 | ? null 61 | : (value) => onToggleCompleted!(value!), 62 | ), 63 | trailing: onTap == null ? null : const Icon(Icons.chevron_right), 64 | ), 65 | ); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /lib/widget/dialog/loading_screen.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/cupertino.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:todo/widget/dialog/loading_screen_controller.dart'; 6 | 7 | class LoadingScreen { 8 | LoadingScreen._sharedInstance(); 9 | static late final LoadingScreen _shared = LoadingScreen._sharedInstance(); 10 | factory LoadingScreen.instance() => _shared; 11 | 12 | LoadingScreenController? _controller; 13 | 14 | void show({required BuildContext context, required String text}) { 15 | if (_controller?.update(text) ?? false) { 16 | return; 17 | } else { 18 | _controller = _showOverlay(context: context, text: text); 19 | } 20 | } 21 | 22 | void hide() { 23 | _controller?.close(); 24 | _controller = null; 25 | } 26 | 27 | LoadingScreenController _showOverlay({ 28 | required BuildContext context, 29 | required String text, 30 | }) { 31 | final _text = StreamController(); 32 | _text.add(text); 33 | 34 | final state = Overlay.of(context); 35 | final renderBox = context.findRenderObject() as RenderBox; 36 | final size = renderBox.size; 37 | 38 | final overlay = OverlayEntry(builder: (context) { 39 | return Material( 40 | color: Colors.black.withAlpha(150), 41 | child: Center( 42 | child: Container( 43 | constraints: BoxConstraints( 44 | maxHeight: size.height * 0.8, 45 | maxWidth: size.width * 0.8, 46 | minWidth: size.width * 0.5), 47 | decoration: BoxDecoration( 48 | color: Theme.of(context).backgroundColor, 49 | borderRadius: BorderRadius.circular(10.0)), 50 | child: Padding( 51 | padding: const EdgeInsets.all(16.0), 52 | child: SingleChildScrollView( 53 | child: Column( 54 | mainAxisSize: MainAxisSize.min, 55 | mainAxisAlignment: MainAxisAlignment.center, 56 | children: [ 57 | const SizedBox( 58 | height: 10, 59 | ), 60 | const CircularProgressIndicator(), 61 | const SizedBox( 62 | height: 20, 63 | ), 64 | StreamBuilder( 65 | stream: _text.stream, 66 | builder: (context, snapshot) { 67 | if (snapshot.hasData) { 68 | return Text( 69 | snapshot.data!, 70 | textAlign: TextAlign.center, 71 | ); 72 | } else { 73 | return Container(); 74 | } 75 | }, 76 | ) 77 | ], 78 | ), 79 | ), 80 | ), 81 | ), 82 | ), 83 | ); 84 | }); 85 | state?.insert(overlay); 86 | return LoadingScreenController(close: () { 87 | _text.close(); 88 | overlay.remove(); 89 | return true; 90 | }, update: (text) { 91 | _text.add(text); 92 | return true; 93 | }); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /lib/widget/dialog/loading_screen_controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart' show immutable; 2 | 3 | typedef CloseLoadingScreen = bool Function(); 4 | typedef UpdateLoadingScreen = bool Function(String text); 5 | 6 | @immutable 7 | class LoadingScreenController { 8 | final CloseLoadingScreen close; 9 | final UpdateLoadingScreen update; 10 | const LoadingScreenController({required this.close, required this.update}); 11 | } 12 | -------------------------------------------------------------------------------- /lib/widget/widget.dart: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/lib/widget/widget.dart -------------------------------------------------------------------------------- /packages/auth_repo/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # VSCode related 19 | .vscode/ 20 | 21 | # Flutter/Dart/Pub related 22 | **/doc/api/ 23 | **/ios/Flutter/.last_build_id 24 | .dart_tool/ 25 | .flutter-plugins 26 | .flutter-plugins-dependencies 27 | .packages 28 | .pub-cache/ 29 | .pub/ 30 | /build/ 31 | 32 | # Web related 33 | lib/generated_plugin_registrant.dart 34 | 35 | # Symbolication related 36 | app.*.symbols 37 | 38 | # Obfuscation related 39 | app.*.map.json 40 | -------------------------------------------------------------------------------- /packages/auth_repo/README.md: -------------------------------------------------------------------------------- 1 | # auth_repo 2 | 3 | [![style: very good analysis][very_good_analysis_badge]][very_good_analysis_link] 4 | [![License: MIT][license_badge]][license_link] 5 | 6 | Authentication repository 7 | 8 | [license_badge]: https://img.shields.io/badge/license-MIT-blue.svg 9 | [license_link]: https://opensource.org/licenses/MIT 10 | [very_good_analysis_badge]: https://img.shields.io/badge/style-very_good_analysis-B22C89.svg 11 | [very_good_analysis_link]: https://pub.dev/packages/very_good_analysis -------------------------------------------------------------------------------- /packages/auth_repo/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:very_good_analysis/analysis_options.2.4.0.yaml -------------------------------------------------------------------------------- /packages/auth_repo/lib/auth_repo.dart: -------------------------------------------------------------------------------- 1 | library auth_repo; 2 | 3 | export 'src/auth_repo.dart'; 4 | export 'src/model/user.dart'; 5 | export 'src/model/auth/auth_error.dart'; 6 | -------------------------------------------------------------------------------- /packages/auth_repo/lib/src/auth_repo.dart: -------------------------------------------------------------------------------- 1 | import 'package:auth_repo/auth_repo.dart'; 2 | import 'package:auth_repo/src/model/auth/auth_error.dart'; 3 | import 'package:cache/cache.dart'; 4 | import 'package:cloud_firestore/cloud_firestore.dart'; 5 | import 'package:firebase_auth/firebase_auth.dart'; 6 | import 'package:firebase_auth/firebase_auth.dart' as firebase_auth; 7 | import 'package:meta/meta.dart'; 8 | 9 | class AuthRepo { 10 | // ignore: public_member_api_docs 11 | AuthRepo( 12 | {CacheClient? cache, 13 | firebase_auth.FirebaseAuth? firebaseAuth, 14 | FirebaseFirestore? firestore}) 15 | : _cache = cache ?? CacheClient(), 16 | _firebaseAuth = firebaseAuth ?? FirebaseAuth.instance, 17 | _firestore = firestore ?? FirebaseFirestore.instance; 18 | 19 | final firebase_auth.FirebaseAuth _firebaseAuth; 20 | final FirebaseFirestore _firestore; 21 | final CacheClient _cache; 22 | 23 | @visibleForTesting 24 | static const userCacheKey = '__user_cache_key__'; 25 | 26 | Stream get user { 27 | return _firebaseAuth.authStateChanges().map((firebaseUser) { 28 | final user = firebaseUser == null ? UserModel.empty : firebaseUser.toUser; 29 | _cache.write(key: userCacheKey, value: user); 30 | return user; 31 | }); 32 | } 33 | 34 | UserModel get currentUser { 35 | return _cache.read(key: userCacheKey) ?? UserModel.empty; 36 | } 37 | 38 | Future signUp({required String email, required String password}) async { 39 | try { 40 | final cred = await _firebaseAuth.createUserWithEmailAndPassword( 41 | email: email, password: password); 42 | await _firestore 43 | .collection('Users') 44 | .doc(cred.user!.uid) 45 | .set(toJson(UserModel(id: cred.user!.uid, email: email))); 46 | } on FirebaseAuthException catch (e) { 47 | throw AuthError.from(e); 48 | } catch (e) { 49 | throw AuthError.unknown(); 50 | } 51 | } 52 | 53 | Future login({required String email, required String password}) async { 54 | try { 55 | await _firebaseAuth.signInWithEmailAndPassword( 56 | email: email, password: password); 57 | } on FirebaseAuthException catch (e) { 58 | throw AuthError.from(e); 59 | } 60 | } 61 | 62 | Future logout() async { 63 | try { 64 | await Future.wait([_firebaseAuth.signOut()]); 65 | } catch (_) { 66 | throw AuthError.unknown(); 67 | } 68 | } 69 | } 70 | 71 | extension on firebase_auth.User { 72 | UserModel get toUser { 73 | return UserModel(id: uid, email: email, name: displayName); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /packages/auth_repo/lib/src/model/model.dart: -------------------------------------------------------------------------------- 1 | export 'user.dart'; -------------------------------------------------------------------------------- /packages/auth_repo/lib/src/model/user.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | class UserModel extends Equatable { 4 | const UserModel({ 5 | required this.id, 6 | this.name, 7 | this.email, 8 | }); 9 | final String id; 10 | final String? email; 11 | final String? name; 12 | 13 | static const empty = UserModel(id: ''); 14 | 15 | bool get isEmpty => this == UserModel.empty; 16 | bool get isNotEmpty => this != UserModel.empty; 17 | 18 | @override 19 | List get props => [email, id, name]; 20 | } 21 | 22 | Map toJson(UserModel user) => { 23 | 'uid': user.id, 24 | 'email': user.email, 25 | }; 26 | -------------------------------------------------------------------------------- /packages/auth_repo/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: auth_repo 2 | description: Authentication repository 3 | version: 1.0.0+1 4 | publish_to: none 5 | 6 | environment: 7 | sdk: ">=2.16.0 <3.0.0" 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | cache: 13 | path: ../cache 14 | equatable: ^2.0.3 15 | firebase_auth: ^3.0.2 16 | firebase_core: ^1.5.0 17 | cloud_firestore: ^3.1.14 18 | meta: ^1.3.0 19 | very_good_analysis: ^2.4.0 20 | 21 | 22 | dev_dependencies: 23 | flutter_test: 24 | sdk: flutter 25 | very_good_analysis: ^2.4.0 -------------------------------------------------------------------------------- /packages/auth_repo/test/src/auth_repo_test.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: prefer_const_constructors 2 | import 'package:auth_repo/auth_repo.dart'; 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | void main() { 6 | group('AuthRepo', () { 7 | test('can be instantiated', () { 8 | expect(AuthRepo(), isNotNull); 9 | }); 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /packages/cache/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # VSCode related 19 | .vscode/ 20 | 21 | # Flutter/Dart/Pub related 22 | **/doc/api/ 23 | **/ios/Flutter/.last_build_id 24 | .dart_tool/ 25 | .flutter-plugins 26 | .flutter-plugins-dependencies 27 | .packages 28 | .pub-cache/ 29 | .pub/ 30 | /build/ 31 | 32 | # Web related 33 | lib/generated_plugin_registrant.dart 34 | 35 | # Symbolication related 36 | app.*.symbols 37 | 38 | # Obfuscation related 39 | app.*.map.json 40 | -------------------------------------------------------------------------------- /packages/cache/README.md: -------------------------------------------------------------------------------- 1 | # cache 2 | 3 | [![style: very good analysis][very_good_analysis_badge]][very_good_analysis_link] 4 | [![License: MIT][license_badge]][license_link] 5 | 6 | cache package 7 | 8 | [license_badge]: https://img.shields.io/badge/license-MIT-blue.svg 9 | [license_link]: https://opensource.org/licenses/MIT 10 | [very_good_analysis_badge]: https://img.shields.io/badge/style-very_good_analysis-B22C89.svg 11 | [very_good_analysis_link]: https://pub.dev/packages/very_good_analysis -------------------------------------------------------------------------------- /packages/cache/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:very_good_analysis/analysis_options.2.4.0.yaml -------------------------------------------------------------------------------- /packages/cache/lib/cache.dart: -------------------------------------------------------------------------------- 1 | library cache; 2 | 3 | export 'src/cache.dart'; 4 | -------------------------------------------------------------------------------- /packages/cache/lib/src/cache.dart: -------------------------------------------------------------------------------- 1 | 2 | class CacheClient { 3 | 4 | CacheClient() : _cache = {}; 5 | 6 | final Map _cache; 7 | 8 | void write({required String key, required T value}){ 9 | _cache[key] = value; 10 | } 11 | 12 | T? read({required String key}){ 13 | final value = _cache[key]; 14 | if(value is T) return value; 15 | return null; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/cache/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: cache 2 | description: cache package 3 | version: 1.0.0+1 4 | publish_to: none 5 | 6 | environment: 7 | sdk: ">=2.16.0 <3.0.0" 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | 13 | dev_dependencies: 14 | flutter_test: 15 | sdk: flutter 16 | very_good_analysis: ^2.4.0 -------------------------------------------------------------------------------- /packages/cloud_storage_todos_api/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # VSCode related 19 | .vscode/ 20 | 21 | # Flutter/Dart/Pub related 22 | **/doc/api/ 23 | **/ios/Flutter/.last_build_id 24 | .dart_tool/ 25 | .flutter-plugins 26 | .flutter-plugins-dependencies 27 | .packages 28 | .pub-cache/ 29 | .pub/ 30 | /build/ 31 | 32 | # Web related 33 | lib/generated_plugin_registrant.dart 34 | 35 | # Symbolication related 36 | app.*.symbols 37 | 38 | # Obfuscation related 39 | app.*.map.json 40 | -------------------------------------------------------------------------------- /packages/cloud_storage_todos_api/README.md: -------------------------------------------------------------------------------- 1 | # cloud_storage_todos_api 2 | 3 | [![style: very good analysis][very_good_analysis_badge]][very_good_analysis_link] 4 | [![License: MIT][license_badge]][license_link] 5 | 6 | firebase firestore todo storage 7 | 8 | [license_badge]: https://img.shields.io/badge/license-MIT-blue.svg 9 | [license_link]: https://opensource.org/licenses/MIT 10 | [very_good_analysis_badge]: https://img.shields.io/badge/style-very_good_analysis-B22C89.svg 11 | [very_good_analysis_link]: https://pub.dev/packages/very_good_analysis -------------------------------------------------------------------------------- /packages/cloud_storage_todos_api/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:very_good_analysis/analysis_options.2.4.0.yaml -------------------------------------------------------------------------------- /packages/cloud_storage_todos_api/lib/cloud_storage_todos_api.dart: -------------------------------------------------------------------------------- 1 | library cloud_storage_todos_api; 2 | 3 | export 'src/cloud_storage_todos_api.dart'; 4 | -------------------------------------------------------------------------------- /packages/cloud_storage_todos_api/lib/src/cloud_storage_todos_api.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_firestore/cloud_firestore.dart'; 2 | import 'package:firebase_auth/firebase_auth.dart'; 3 | import 'package:todos_api/todos_api.dart'; 4 | 5 | /// {@template cloud_storage_todos_api} 6 | /// firebase firestore todo storage 7 | /// {@endtemplate} 8 | class CloudStorageTodosApi extends TodosApi { 9 | /// {@macro cloud_storage_todos_api} 10 | CloudStorageTodosApi( 11 | {FirebaseAuth? firebaseAuth, FirebaseFirestore? firebaseFirestore}) 12 | : _auth = firebaseAuth ?? FirebaseAuth.instance, 13 | _firestore = firebaseFirestore ?? FirebaseFirestore.instance, 14 | super(); 15 | 16 | final FirebaseAuth _auth; 17 | final FirebaseFirestore _firestore; 18 | 19 | @override 20 | Future clearCompleted() async { 21 | final ref = _firestore 22 | .collection('Users') 23 | .doc(_auth.currentUser?.uid) 24 | .collection('My Todos'); 25 | await ref.where('isCompleted', isEqualTo: true).get().then((res) { 26 | for (final data in res.docs) { 27 | final todo = TodoFromJson(data.data()); 28 | ref.doc(todo.id).delete(); 29 | } 30 | }); 31 | return 0; 32 | } 33 | 34 | @override 35 | Future completeAll({required bool completed}) async { 36 | final ref = _firestore 37 | .collection('Users') 38 | .doc(_auth.currentUser?.uid) 39 | .collection('My Todos'); 40 | 41 | await ref.where('isCompleted', isEqualTo: !completed).get().then((res) { 42 | for (final data in res.docs) { 43 | final todo = TodoFromJson(data.data()); 44 | final newTodo = todo.copyWith(isCompleted: completed); 45 | ref.doc(newTodo.id).set(newTodo.toJson()); 46 | } 47 | }); 48 | 49 | return 0; 50 | } 51 | 52 | @override 53 | Future deleteTodo(String id) async { 54 | final ref = _firestore 55 | .collection('Users') 56 | .doc(_auth.currentUser?.uid) 57 | .collection('My Todos'); 58 | await ref.doc(id).delete(); 59 | } 60 | 61 | @override 62 | Stream> getTodos() { 63 | // TODO: implement getTodos 64 | throw UnimplementedError(); 65 | } 66 | 67 | @override 68 | Future saveTodo(Todo todo) async { 69 | await _firestore 70 | .collection('Users') 71 | .doc(_auth.currentUser?.uid) 72 | .collection('My Todos') 73 | .doc(todo.id) 74 | .set(todo.toJson()); 75 | } 76 | 77 | @override 78 | Future> getTodoFromCloud() async { 79 | var result = []; 80 | final ref = _firestore 81 | .collection('Users') 82 | .doc(_auth.currentUser?.uid) 83 | .collection('My Todos'); 84 | 85 | await ref.get().then((res) { 86 | for (final data in res.docs) { 87 | final todo = TodoFromJson(data.data()); 88 | result.add(todo); 89 | } 90 | }); 91 | return result; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /packages/cloud_storage_todos_api/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: cloud_storage_todos_api 2 | description: firebase firestore todo storage 3 | version: 1.0.0+1 4 | publish_to: none 5 | 6 | environment: 7 | sdk: ">=2.16.0 <3.0.0" 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | todos_api: 13 | path: ../todos_api 14 | firebase_auth: ^3.0.2 15 | firebase_core: ^1.5.0 16 | cloud_firestore: ^3.1.14 17 | 18 | dev_dependencies: 19 | flutter_test: 20 | sdk: flutter 21 | very_good_analysis: ^2.4.0 -------------------------------------------------------------------------------- /packages/form_input/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # VSCode related 19 | .vscode/ 20 | 21 | # Flutter/Dart/Pub related 22 | **/doc/api/ 23 | **/ios/Flutter/.last_build_id 24 | .dart_tool/ 25 | .flutter-plugins 26 | .flutter-plugins-dependencies 27 | .packages 28 | .pub-cache/ 29 | .pub/ 30 | /build/ 31 | 32 | # Web related 33 | lib/generated_plugin_registrant.dart 34 | 35 | # Symbolication related 36 | app.*.symbols 37 | 38 | # Obfuscation related 39 | app.*.map.json 40 | -------------------------------------------------------------------------------- /packages/form_input/README.md: -------------------------------------------------------------------------------- 1 | # form_input 2 | 3 | [![style: very good analysis][very_good_analysis_badge]][very_good_analysis_link] 4 | [![License: MIT][license_badge]][license_link] 5 | 6 | for validation error 7 | 8 | [license_badge]: https://img.shields.io/badge/license-MIT-blue.svg 9 | [license_link]: https://opensource.org/licenses/MIT 10 | [very_good_analysis_badge]: https://img.shields.io/badge/style-very_good_analysis-B22C89.svg 11 | [very_good_analysis_link]: https://pub.dev/packages/very_good_analysis -------------------------------------------------------------------------------- /packages/form_input/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:very_good_analysis/analysis_options.2.4.0.yaml -------------------------------------------------------------------------------- /packages/form_input/lib/form_input.dart: -------------------------------------------------------------------------------- 1 | library form_input; 2 | 3 | export './src/confirm_password.dart'; 4 | export './src/email.dart'; 5 | export './src/password.dart'; 6 | 7 | -------------------------------------------------------------------------------- /packages/form_input/lib/src/confirm_password.dart: -------------------------------------------------------------------------------- 1 | import 'package:formz/formz.dart'; 2 | 3 | enum ConfirmedPasswordValidationError { invalid } 4 | 5 | class ConfirmedPassword 6 | extends FormzInput { 7 | const ConfirmedPassword.pure({this.password = ''}) : super.pure(''); 8 | 9 | const ConfirmedPassword.dirty({required this.password, String value = ''}) 10 | : super.dirty(value); 11 | 12 | final String password; 13 | 14 | @override 15 | ConfirmedPasswordValidationError? validator(String? value) { 16 | return password == value ? null : ConfirmedPasswordValidationError.invalid; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/form_input/lib/src/email.dart: -------------------------------------------------------------------------------- 1 | import 'package:formz/formz.dart'; 2 | 3 | enum EmailValidationError { invalid } 4 | 5 | class Email extends FormzInput { 6 | const Email.pure() : super.pure(''); 7 | 8 | const Email.dirty([String value = '']) : super.dirty(value); 9 | 10 | static final RegExp _emailRegExp = RegExp( 11 | r'^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$'); 12 | 13 | @override 14 | EmailValidationError? validator(String? value) { 15 | return _emailRegExp.hasMatch(value ?? '') 16 | ? null 17 | : EmailValidationError.invalid; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/form_input/lib/src/password.dart: -------------------------------------------------------------------------------- 1 | import 'package:formz/formz.dart'; 2 | 3 | enum PasswordValidationError { invalid } 4 | 5 | class Password extends FormzInput { 6 | const Password.pure() : super.pure(''); 7 | 8 | const Password.dirty([String value = '']) : super.dirty(value); 9 | 10 | static final _passwordRegExp = 11 | RegExp(r'^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$'); 12 | 13 | @override 14 | PasswordValidationError? validator(String? value) { 15 | return _passwordRegExp.hasMatch(value ?? '') 16 | ? null 17 | : PasswordValidationError.invalid; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/form_input/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: form_input 2 | description: for validation error 3 | version: 1.0.0+1 4 | publish_to: none 5 | 6 | environment: 7 | sdk: ">=2.16.0 <3.0.0" 8 | 9 | dependencies: 10 | formz: ^0.4.0 11 | 12 | dev_dependencies: 13 | very_good_analysis: ^2.4.0 -------------------------------------------------------------------------------- /packages/local_storage_todos_api/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.lock 4 | *.log 5 | *.pyc 6 | *.swp 7 | .DS_Store 8 | .atom/ 9 | .buildlog/ 10 | .history 11 | .svn/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/* 18 | 19 | # Visual Studio Code related 20 | .classpath 21 | .project 22 | .settings/ 23 | .vscode/* 24 | 25 | # Flutter repo-specific 26 | /bin/cache/ 27 | /bin/mingit/ 28 | /dev/benchmarks/mega_gallery/ 29 | /dev/bots/.recipe_deps 30 | /dev/bots/android_tools/ 31 | /dev/docs/doc/ 32 | /dev/docs/flutter.docs.zip 33 | /dev/docs/lib/ 34 | /dev/docs/pubspec.yaml 35 | /dev/integration_tests/**/xcuserdata 36 | /dev/integration_tests/**/Pods 37 | /packages/flutter/coverage/ 38 | version 39 | 40 | # packages file containing multi-root paths 41 | .packages.generated 42 | 43 | # Flutter/Dart/Pub related 44 | **/doc/api/ 45 | **/ios/Flutter/.last_build_id 46 | .dart_tool/ 47 | .flutter-plugins 48 | .flutter-plugins-dependencies 49 | .packages 50 | .pub-cache/ 51 | .pub/ 52 | build/ 53 | flutter_*.png 54 | linked_*.ds 55 | unlinked.ds 56 | unlinked_spec.ds 57 | .fvm/ 58 | 59 | # Android related 60 | **/android/**/gradle-wrapper.jar 61 | **/android/.gradle 62 | **/android/captures/ 63 | **/android/gradlew 64 | **/android/gradlew.bat 65 | **/android/local.properties 66 | **/android/**/GeneratedPluginRegistrant.java 67 | **/android/key.properties 68 | **/android/.idea/ 69 | *.jks 70 | 71 | # iOS/XCode related 72 | **/ios/**/*.mode1v3 73 | **/ios/**/*.mode2v3 74 | **/ios/**/*.moved-aside 75 | **/ios/**/*.pbxuser 76 | **/ios/**/*.perspectivev3 77 | **/ios/**/*sync/ 78 | **/ios/**/.sconsign.dblite 79 | **/ios/**/.tags* 80 | **/ios/**/.vagrant/ 81 | **/ios/**/DerivedData/ 82 | **/ios/**/Icon? 83 | **/ios/**/Pods/ 84 | **/ios/**/.symlinks/ 85 | **/ios/**/profile 86 | **/ios/**/xcuserdata 87 | **/ios/.generated/ 88 | **/ios/Flutter/App.framework 89 | **/ios/Flutter/Flutter.framework 90 | **/ios/Flutter/Flutter.podspec 91 | **/ios/Flutter/Generated.xcconfig 92 | **/ios/Flutter/app.flx 93 | **/ios/Flutter/app.zip 94 | **/ios/Flutter/.last_build_id 95 | **/ios/Flutter/flutter_assets/ 96 | **/ios/Flutter/flutter_export_environment.sh 97 | **/ios/ServiceDefinitions.json 98 | **/ios/Runner/GeneratedPluginRegistrant.* 99 | 100 | # Coverage 101 | coverage/ 102 | 103 | # Submodules 104 | !pubspec.lock 105 | packages/**/pubspec.lock 106 | 107 | # Web related 108 | lib/generated_plugin_registrant.dart 109 | 110 | # Symbolication related 111 | app.*.symbols 112 | 113 | # Obfuscation related 114 | app.*.map.json 115 | 116 | # Exceptions to the above rules. 117 | !**/ios/**/default.mode1v3 118 | !**/ios/**/default.mode2v3 119 | !**/ios/**/default.pbxuser 120 | !**/ios/**/default.perspectivev3 121 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 122 | !/dev/ci/**/Gemfile.lock 123 | !.vscode/extensions.json 124 | !.vscode/launch.json 125 | !.idea/codeStyles/ 126 | !.idea/dictionaries/ 127 | !.idea/runConfigurations/ 128 | -------------------------------------------------------------------------------- /packages/local_storage_todos_api/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:very_good_analysis/analysis_options.2.4.0.yaml 2 | linter: 3 | rules: 4 | public_member_api_docs: false 5 | -------------------------------------------------------------------------------- /packages/local_storage_todos_api/lib/local_storage_todos_api.dart: -------------------------------------------------------------------------------- 1 | library local_storage_todos_api; 2 | 3 | export 'package:shared_preferences/shared_preferences.dart' 4 | show SharedPreferences; 5 | 6 | export 'src/local_storage_todos_api.dart'; 7 | -------------------------------------------------------------------------------- /packages/local_storage_todos_api/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: local_storage_todos_api 2 | description: A Very Good Project created by Very Good CLI. 3 | version: 1.0.0+1 4 | publish_to: none 5 | 6 | environment: 7 | sdk: ">=2.16.0 <3.0.0" 8 | 9 | dependencies: 10 | bloc: ^8.0.3 11 | flutter: 12 | sdk: flutter 13 | flutter_bloc: ^8.0.1 14 | flutter_localizations: 15 | sdk: flutter 16 | intl: ^0.17.0 17 | meta: ^1.3.0 18 | rxdart: ^0.27.2 19 | shared_preferences: ^2.0.7 20 | todos_api: 21 | path: ../todos_api 22 | cloud_storage_todos_api: 23 | path: ../cloud_storage_todos_api 24 | 25 | dev_dependencies: 26 | bloc_test: ^9.0.3 27 | flutter_test: 28 | sdk: flutter 29 | mocktail: ^0.3.0 30 | very_good_analysis: ^2.4.0 31 | 32 | flutter: 33 | uses-material-design: true 34 | generate: true 35 | -------------------------------------------------------------------------------- /packages/todos_api/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.lock 4 | *.log 5 | *.pyc 6 | *.swp 7 | .DS_Store 8 | .atom/ 9 | .buildlog/ 10 | .history 11 | .svn/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/* 18 | 19 | # Visual Studio Code related 20 | .classpath 21 | .project 22 | .settings/ 23 | .vscode/* 24 | 25 | # Flutter repo-specific 26 | /bin/cache/ 27 | /bin/mingit/ 28 | /dev/benchmarks/mega_gallery/ 29 | /dev/bots/.recipe_deps 30 | /dev/bots/android_tools/ 31 | /dev/docs/doc/ 32 | /dev/docs/flutter.docs.zip 33 | /dev/docs/lib/ 34 | /dev/docs/pubspec.yaml 35 | /dev/integration_tests/**/xcuserdata 36 | /dev/integration_tests/**/Pods 37 | /packages/flutter/coverage/ 38 | version 39 | 40 | # packages file containing multi-root paths 41 | .packages.generated 42 | 43 | # Flutter/Dart/Pub related 44 | **/doc/api/ 45 | **/ios/Flutter/.last_build_id 46 | .dart_tool/ 47 | .flutter-plugins 48 | .flutter-plugins-dependencies 49 | .packages 50 | .pub-cache/ 51 | .pub/ 52 | build/ 53 | flutter_*.png 54 | linked_*.ds 55 | unlinked.ds 56 | unlinked_spec.ds 57 | .fvm/ 58 | 59 | # Android related 60 | **/android/**/gradle-wrapper.jar 61 | **/android/.gradle 62 | **/android/captures/ 63 | **/android/gradlew 64 | **/android/gradlew.bat 65 | **/android/local.properties 66 | **/android/**/GeneratedPluginRegistrant.java 67 | **/android/key.properties 68 | **/android/.idea/ 69 | *.jks 70 | 71 | # iOS/XCode related 72 | **/ios/**/*.mode1v3 73 | **/ios/**/*.mode2v3 74 | **/ios/**/*.moved-aside 75 | **/ios/**/*.pbxuser 76 | **/ios/**/*.perspectivev3 77 | **/ios/**/*sync/ 78 | **/ios/**/.sconsign.dblite 79 | **/ios/**/.tags* 80 | **/ios/**/.vagrant/ 81 | **/ios/**/DerivedData/ 82 | **/ios/**/Icon? 83 | **/ios/**/Pods/ 84 | **/ios/**/.symlinks/ 85 | **/ios/**/profile 86 | **/ios/**/xcuserdata 87 | **/ios/.generated/ 88 | **/ios/Flutter/App.framework 89 | **/ios/Flutter/Flutter.framework 90 | **/ios/Flutter/Flutter.podspec 91 | **/ios/Flutter/Generated.xcconfig 92 | **/ios/Flutter/app.flx 93 | **/ios/Flutter/app.zip 94 | **/ios/Flutter/.last_build_id 95 | **/ios/Flutter/flutter_assets/ 96 | **/ios/Flutter/flutter_export_environment.sh 97 | **/ios/ServiceDefinitions.json 98 | **/ios/Runner/GeneratedPluginRegistrant.* 99 | 100 | # Coverage 101 | coverage/ 102 | 103 | # Submodules 104 | !pubspec.lock 105 | packages/**/pubspec.lock 106 | 107 | # Web related 108 | lib/generated_plugin_registrant.dart 109 | 110 | # Symbolication related 111 | app.*.symbols 112 | 113 | # Obfuscation related 114 | app.*.map.json 115 | 116 | # Exceptions to the above rules. 117 | !**/ios/**/default.mode1v3 118 | !**/ios/**/default.mode2v3 119 | !**/ios/**/default.pbxuser 120 | !**/ios/**/default.perspectivev3 121 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 122 | !/dev/ci/**/Gemfile.lock 123 | !.vscode/extensions.json 124 | !.vscode/launch.json 125 | !.idea/codeStyles/ 126 | !.idea/dictionaries/ 127 | !.idea/runConfigurations/ 128 | -------------------------------------------------------------------------------- /packages/todos_api/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:very_good_analysis/analysis_options.2.4.0.yaml 2 | linter: 3 | rules: 4 | public_member_api_docs: false 5 | -------------------------------------------------------------------------------- /packages/todos_api/lib/src/models/models.dart: -------------------------------------------------------------------------------- 1 | export 'todo.dart'; 2 | export 'todo_serialize.dart'; 3 | -------------------------------------------------------------------------------- /packages/todos_api/lib/src/models/todo.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:flutter/cupertino.dart'; 3 | import 'package:json_annotation/json_annotation.dart'; 4 | import 'package:todos_api/src/models/todo_serialize.dart'; 5 | import 'package:uuid/uuid.dart'; 6 | 7 | @immutable 8 | @JsonSerializable() 9 | class Todo extends Equatable { 10 | Todo({ 11 | String? id, 12 | required this.title, 13 | this.description = '', 14 | this.isCompleted = false, 15 | this.date = '', 16 | this.startTime = '', 17 | this.repeat = '', 18 | this.notificationId = 0, 19 | }) : assert( 20 | id == null || id.isNotEmpty, 21 | 'id can not be null and should be empty', 22 | ), 23 | id = id ?? const Uuid().v4(); 24 | 25 | final String id; 26 | 27 | final String title; 28 | 29 | final String description; 30 | 31 | final bool isCompleted; 32 | 33 | final String date; 34 | 35 | final String startTime; 36 | 37 | final String repeat; 38 | 39 | final int notificationId; 40 | 41 | Todo copyWith({ 42 | String? id, 43 | String? title, 44 | String? description, 45 | bool? isCompleted, 46 | String? date, 47 | String? startTime, 48 | String? repeat, 49 | int? notificationId, 50 | }) { 51 | return Todo( 52 | id: id ?? this.id, 53 | title: title ?? this.title, 54 | description: description ?? this.description, 55 | isCompleted: isCompleted ?? this.isCompleted, 56 | date: date ?? this.date, 57 | startTime: startTime ?? this.startTime, 58 | repeat: repeat ?? this.repeat, 59 | notificationId: notificationId ?? this.notificationId, 60 | ); 61 | } 62 | 63 | static Todo fromJson(JsonMap json) => TodoFromJson(json); 64 | JsonMap toJson() => TodoToJson(this); 65 | 66 | @override 67 | List get props => [ 68 | id, 69 | title, 70 | description, 71 | isCompleted, 72 | ]; 73 | } 74 | 75 | typedef JsonMap = Map; 76 | -------------------------------------------------------------------------------- /packages/todos_api/lib/src/models/todo_serialize.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:todos_api/src/models/todo.dart'; 4 | 5 | Todo TodoFromJson(Map json) => Todo( 6 | id: json['id'] as String?, 7 | title: json['title'] as String, 8 | description: json['description'] as String? ?? '', 9 | isCompleted: json['isCompleted'] as bool? ?? false, 10 | date: json['date'] as String? ?? '', 11 | startTime: json['startTime'] as String? ?? '', 12 | repeat: json['repeat'] as String? ?? '', 13 | notificationId: json['notificationId'] as int? ?? 0, 14 | ); 15 | 16 | Map TodoToJson(Todo instance) => { 17 | 'id': instance.id, 18 | 'title': instance.title, 19 | 'description': instance.description, 20 | 'isCompleted': instance.isCompleted, 21 | 'date': instance.date, 22 | 'startTime': instance.startTime, 23 | 'repeat': instance.repeat, 24 | 'notificationId': instance.notificationId, 25 | }; 26 | -------------------------------------------------------------------------------- /packages/todos_api/lib/src/todos_api.dart: -------------------------------------------------------------------------------- 1 | import 'package:todos_api/todos_api.dart'; 2 | 3 | import 'models/todo.dart'; 4 | 5 | abstract class TodosApi { 6 | const TodosApi(); 7 | 8 | Stream> getTodos(); 9 | 10 | Future saveTodo(Todo todo); 11 | 12 | Future deleteTodo(String id); 13 | 14 | Future clearCompleted(); 15 | 16 | Future completeAll({required bool completed}); 17 | 18 | Future> getTodoFromCloud(); 19 | } 20 | 21 | class TodoNotFoundException implements Exception {} 22 | -------------------------------------------------------------------------------- /packages/todos_api/lib/todos_api.dart: -------------------------------------------------------------------------------- 1 | library todos_api; 2 | 3 | export 'src/models/models.dart'; 4 | export 'src/todos_api.dart'; 5 | -------------------------------------------------------------------------------- /packages/todos_api/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: todos_api 2 | description: A Very Good Project created by Very Good CLI. 3 | version: 1.0.0+1 4 | publish_to: none 5 | 6 | environment: 7 | sdk: ">=2.16.0 <3.0.0" 8 | 9 | dependencies: 10 | bloc: ^8.0.3 11 | flutter: 12 | sdk: flutter 13 | flutter_bloc: ^8.0.1 14 | flutter_localizations: 15 | sdk: flutter 16 | intl: ^0.17.0 17 | equatable: ^2.0.3 18 | json_annotation: ^4.4.0 19 | meta: ^1.3.0 20 | uuid: ^3.0.4 21 | 22 | dev_dependencies: 23 | bloc_test: ^9.0.3 24 | flutter_test: 25 | sdk: flutter 26 | mocktail: ^0.3.0 27 | very_good_analysis: ^2.4.0 28 | json_serializable: ^6.0.0 29 | build_runner: ^2.0.0 30 | 31 | flutter: 32 | uses-material-design: true 33 | generate: true 34 | -------------------------------------------------------------------------------- /packages/todos_repository/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:very_good_analysis/analysis_options.2.4.0.yaml 2 | linter: 3 | rules: 4 | public_member_api_docs: false 5 | -------------------------------------------------------------------------------- /packages/todos_repository/lib/src/todos_repository.dart: -------------------------------------------------------------------------------- 1 | import 'package:todos_api/todos_api.dart'; 2 | 3 | class TodoRepository { 4 | const TodoRepository({ 5 | required TodosApi todosApi, 6 | }) : _todosApi = todosApi; 7 | 8 | final TodosApi _todosApi; 9 | 10 | Stream> getTodos() => _todosApi.getTodos(); 11 | 12 | Future saveTodo(Todo todo) => _todosApi.saveTodo(todo); 13 | 14 | Future deleteTodo(String id) => _todosApi.deleteTodo(id); 15 | 16 | Future clearCompleted() => _todosApi.clearCompleted(); 17 | 18 | Future> getTodosFromCloud() => _todosApi.getTodoFromCloud(); 19 | 20 | Future completeAll({required bool isCompleted}) => 21 | _todosApi.completeAll(completed: isCompleted); 22 | } 23 | -------------------------------------------------------------------------------- /packages/todos_repository/lib/todo_repository.dart: -------------------------------------------------------------------------------- 1 | library todos_repository; 2 | 3 | export 'package:todos_api/todos_api.dart' show Todo; 4 | export 'src/todos_repository.dart'; 5 | -------------------------------------------------------------------------------- /packages/todos_repository/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: todos_repository 2 | description: A Very Good Project created by Very Good CLI. 3 | version: 1.0.0+1 4 | publish_to: none 5 | 6 | environment: 7 | sdk: ">=2.16.0 <3.0.0" 8 | 9 | dependencies: 10 | todos_api: 11 | path: ../todos_api 12 | 13 | dev_dependencies: 14 | bloc_test: ^9.0.3 15 | flutter_test: 16 | sdk: flutter 17 | mocktail: ^0.3.0 18 | very_good_analysis: ^2.4.0 19 | 20 | flutter: 21 | uses-material-design: true 22 | generate: true 23 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: todo 2 | description: A Very Good Project created by Very Good CLI. 3 | version: 1.0.0+1 4 | publish_to: none 5 | 6 | environment: 7 | sdk: ">=2.16.0 <3.0.0" 8 | 9 | dependencies: 10 | bloc: ^8.0.3 11 | flutter: 12 | sdk: flutter 13 | flutter_bloc: ^8.0.1 14 | flutter_localizations: 15 | sdk: flutter 16 | intl: ^0.17.0 17 | flutter_services_binding: ^0.1.0 18 | local_storage_todos_api: 19 | path: packages/local_storage_todos_api 20 | todos_api: 21 | path: packages/todos_api 22 | todos_repository: 23 | path: packages/todos_repository 24 | auth_repo: 25 | path: packages/auth_repo 26 | form_input: 27 | path: packages/form_input 28 | cloud_storage_todos_api: 29 | path: packages/cloud_storage_todos_api 30 | equatable: ^2.0.3 31 | json_annotation: ^4.4.0 32 | meta: ^1.3.0 33 | uuid: ^3.0.4 34 | flow_builder: ^0.0.4 35 | formz: ^0.4.0 36 | date_picker_timeline: 37 | flutter_local_notifications: 38 | flutter_native_timezone: 39 | url_launcher: 40 | 41 | 42 | dev_dependencies: 43 | bloc_test: ^9.0.3 44 | flutter_test: 45 | sdk: flutter 46 | mocktail: ^0.3.0 47 | very_good_analysis: ^2.4.0 48 | flutter_launcher_icons: "^0.9.2" 49 | 50 | flutter_icons: 51 | android: true 52 | ios: true 53 | image_path: "assets/icon.png" 54 | 55 | flutter: 56 | uses-material-design: true 57 | generate: true 58 | -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/web/favicon.png -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/web/icons/Icon-512.png -------------------------------------------------------------------------------- /web/icons/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/web/icons/favicon.png -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Todo", 3 | "short_name": "Todo", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A Very Good Project created by Very Good CLI.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /windows/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral/ 2 | 3 | # Visual Studio user-specific files. 4 | *.suo 5 | *.user 6 | *.userosscache 7 | *.sln.docstates 8 | 9 | # Visual Studio build-related files. 10 | x64/ 11 | x86/ 12 | 13 | # Visual Studio cache files 14 | # files ending in .cache can be ignored 15 | *.[Cc]ache 16 | # but keep track of directories ending in .cache 17 | !*.[Cc]ache/ 18 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | #include 10 | 11 | void RegisterPlugins(flutter::PluginRegistry* registry) { 12 | UrlLauncherWindowsRegisterWithRegistrar( 13 | registry->GetRegistrarForPlugin("UrlLauncherWindows")); 14 | } 15 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void RegisterPlugins(flutter::PluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | url_launcher_windows 7 | ) 8 | 9 | set(PLUGIN_BUNDLED_LIBRARIES) 10 | 11 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 12 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) 13 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 14 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 15 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 16 | endforeach(plugin) 17 | -------------------------------------------------------------------------------- /windows/runner/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | project(runner LANGUAGES CXX) 3 | 4 | add_executable(${BINARY_NAME} WIN32 5 | "flutter_window.cpp" 6 | "main.cpp" 7 | "utils.cpp" 8 | "win32_window.cpp" 9 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" 10 | "Runner.rc" 11 | "runner.exe.manifest" 12 | ) 13 | apply_standard_settings(${BINARY_NAME}) 14 | target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") 15 | target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) 16 | target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") 17 | add_dependencies(${BINARY_NAME} flutter_assemble) 18 | -------------------------------------------------------------------------------- /windows/runner/Runner.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #pragma code_page(65001) 4 | #include "resource.h" 5 | 6 | #define APSTUDIO_READONLY_SYMBOLS 7 | ///////////////////////////////////////////////////////////////////////////// 8 | // 9 | // Generated from the TEXTINCLUDE 2 resource. 10 | // 11 | #include "winres.h" 12 | 13 | ///////////////////////////////////////////////////////////////////////////// 14 | #undef APSTUDIO_READONLY_SYMBOLS 15 | 16 | ///////////////////////////////////////////////////////////////////////////// 17 | // English (United States) resources 18 | 19 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | 22 | #ifdef APSTUDIO_INVOKED 23 | ///////////////////////////////////////////////////////////////////////////// 24 | // 25 | // TEXTINCLUDE 26 | // 27 | 28 | 1 TEXTINCLUDE 29 | BEGIN 30 | "resource.h\0" 31 | END 32 | 33 | 2 TEXTINCLUDE 34 | BEGIN 35 | "#include ""winres.h""\r\n" 36 | "\0" 37 | END 38 | 39 | 3 TEXTINCLUDE 40 | BEGIN 41 | "\r\n" 42 | "\0" 43 | END 44 | 45 | #endif // APSTUDIO_INVOKED 46 | 47 | 48 | ///////////////////////////////////////////////////////////////////////////// 49 | // 50 | // Icon 51 | // 52 | 53 | // Icon with lowest ID value placed first to ensure application icon 54 | // remains consistent on all systems. 55 | IDI_APP_ICON ICON "resources\\app_icon.ico" 56 | 57 | 58 | ///////////////////////////////////////////////////////////////////////////// 59 | // 60 | // Version 61 | // 62 | 63 | #ifdef FLUTTER_BUILD_NUMBER 64 | #define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER 65 | #else 66 | #define VERSION_AS_NUMBER 1,0,0 67 | #endif 68 | 69 | #ifdef FLUTTER_BUILD_NAME 70 | #define VERSION_AS_STRING #FLUTTER_BUILD_NAME 71 | #else 72 | #define VERSION_AS_STRING "1.0.0" 73 | #endif 74 | 75 | VS_VERSION_INFO VERSIONINFO 76 | FILEVERSION VERSION_AS_NUMBER 77 | PRODUCTVERSION VERSION_AS_NUMBER 78 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 79 | #ifdef _DEBUG 80 | FILEFLAGS VS_FF_DEBUG 81 | #else 82 | FILEFLAGS 0x0L 83 | #endif 84 | FILEOS VOS__WINDOWS32 85 | FILETYPE VFT_APP 86 | FILESUBTYPE 0x0L 87 | BEGIN 88 | BLOCK "StringFileInfo" 89 | BEGIN 90 | BLOCK "040904e4" 91 | BEGIN 92 | VALUE "CompanyName", "com.example.verygoodcore.todo" "\0" 93 | VALUE "FileDescription", "todo" "\0" 94 | VALUE "FileVersion", VERSION_AS_STRING "\0" 95 | VALUE "InternalName", "todo" "\0" 96 | VALUE "LegalCopyright", "Copyright (C) 2022 com.example.verygoodcore.todo. All rights reserved." "\0" 97 | VALUE "OriginalFilename", "todo.exe" "\0" 98 | VALUE "ProductName", "Todo" "\0" 99 | VALUE "ProductVersion", VERSION_AS_STRING "\0" 100 | END 101 | END 102 | BLOCK "VarFileInfo" 103 | BEGIN 104 | VALUE "Translation", 0x409, 1252 105 | END 106 | END 107 | 108 | #endif // English (United States) resources 109 | ///////////////////////////////////////////////////////////////////////////// 110 | 111 | 112 | 113 | #ifndef APSTUDIO_INVOKED 114 | ///////////////////////////////////////////////////////////////////////////// 115 | // 116 | // Generated from the TEXTINCLUDE 3 resource. 117 | // 118 | 119 | 120 | ///////////////////////////////////////////////////////////////////////////// 121 | #endif // not APSTUDIO_INVOKED 122 | -------------------------------------------------------------------------------- /windows/runner/flutter_window.cpp: -------------------------------------------------------------------------------- 1 | #include "flutter_window.h" 2 | 3 | #include 4 | 5 | #include "flutter/generated_plugin_registrant.h" 6 | 7 | FlutterWindow::FlutterWindow(const flutter::DartProject& project) 8 | : project_(project) {} 9 | 10 | FlutterWindow::~FlutterWindow() {} 11 | 12 | bool FlutterWindow::OnCreate() { 13 | if (!Win32Window::OnCreate()) { 14 | return false; 15 | } 16 | 17 | RECT frame = GetClientArea(); 18 | 19 | // The size here must match the window dimensions to avoid unnecessary surface 20 | // creation / destruction in the startup path. 21 | flutter_controller_ = std::make_unique( 22 | frame.right - frame.left, frame.bottom - frame.top, project_); 23 | // Ensure that basic setup of the controller was successful. 24 | if (!flutter_controller_->engine() || !flutter_controller_->view()) { 25 | return false; 26 | } 27 | RegisterPlugins(flutter_controller_->engine()); 28 | SetChildContent(flutter_controller_->view()->GetNativeWindow()); 29 | return true; 30 | } 31 | 32 | void FlutterWindow::OnDestroy() { 33 | if (flutter_controller_) { 34 | flutter_controller_ = nullptr; 35 | } 36 | 37 | Win32Window::OnDestroy(); 38 | } 39 | 40 | LRESULT 41 | FlutterWindow::MessageHandler(HWND hwnd, UINT const message, 42 | WPARAM const wparam, 43 | LPARAM const lparam) noexcept { 44 | // Give Flutter, including plugins, an opportunity to handle window messages. 45 | if (flutter_controller_) { 46 | std::optional result = 47 | flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, 48 | lparam); 49 | if (result) { 50 | return *result; 51 | } 52 | } 53 | 54 | switch (message) { 55 | case WM_FONTCHANGE: 56 | flutter_controller_->engine()->ReloadSystemFonts(); 57 | break; 58 | } 59 | 60 | return Win32Window::MessageHandler(hwnd, message, wparam, lparam); 61 | } 62 | -------------------------------------------------------------------------------- /windows/runner/flutter_window.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_FLUTTER_WINDOW_H_ 2 | #define RUNNER_FLUTTER_WINDOW_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "win32_window.h" 10 | 11 | // A window that does nothing but host a Flutter view. 12 | class FlutterWindow : public Win32Window { 13 | public: 14 | // Creates a new FlutterWindow hosting a Flutter view running |project|. 15 | explicit FlutterWindow(const flutter::DartProject& project); 16 | virtual ~FlutterWindow(); 17 | 18 | protected: 19 | // Win32Window: 20 | bool OnCreate() override; 21 | void OnDestroy() override; 22 | LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, 23 | LPARAM const lparam) noexcept override; 24 | 25 | private: 26 | // The project to run. 27 | flutter::DartProject project_; 28 | 29 | // The Flutter instance hosted by this window. 30 | std::unique_ptr flutter_controller_; 31 | }; 32 | 33 | #endif // RUNNER_FLUTTER_WINDOW_H_ 34 | -------------------------------------------------------------------------------- /windows/runner/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "flutter_window.h" 6 | #include "utils.h" 7 | 8 | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, 9 | _In_ wchar_t *command_line, _In_ int show_command) { 10 | // Attach to console when present (e.g., 'flutter run') or create a 11 | // new console when running with a debugger. 12 | if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { 13 | CreateAndAttachConsole(); 14 | } 15 | 16 | // Initialize COM, so that it is available for use in the library and/or 17 | // plugins. 18 | ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); 19 | 20 | flutter::DartProject project(L"data"); 21 | 22 | std::vector command_line_arguments = 23 | GetCommandLineArguments(); 24 | 25 | project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); 26 | 27 | FlutterWindow window(project); 28 | Win32Window::Point origin(10, 10); 29 | Win32Window::Size size(1280, 720); 30 | if (!window.CreateAndShow(L"Todo", origin, size)) { 31 | return EXIT_FAILURE; 32 | } 33 | window.SetQuitOnClose(true); 34 | 35 | ::MSG msg; 36 | while (::GetMessage(&msg, nullptr, 0, 0)) { 37 | ::TranslateMessage(&msg); 38 | ::DispatchMessage(&msg); 39 | } 40 | 41 | ::CoUninitialize(); 42 | return EXIT_SUCCESS; 43 | } 44 | -------------------------------------------------------------------------------- /windows/runner/resource.h: -------------------------------------------------------------------------------- 1 | // 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Runner.rc 4 | // 5 | #define IDI_APP_ICON 101 6 | 7 | // Next default values for new objects 8 | // 9 | #ifdef APSTUDIO_INVOKED 10 | #ifndef APSTUDIO_READONLY_SYMBOLS 11 | #define _APS_NEXT_RESOURCE_VALUE 102 12 | #define _APS_NEXT_COMMAND_VALUE 40001 13 | #define _APS_NEXT_CONTROL_VALUE 1001 14 | #define _APS_NEXT_SYMED_VALUE 101 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /windows/runner/resources/app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chima94/flutter-bloc-design-pattern/489a97736ee9bcaddb45f97657c859ad3f13fb92/windows/runner/resources/app_icon.ico -------------------------------------------------------------------------------- /windows/runner/runner.exe.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PerMonitorV2 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /windows/runner/utils.cpp: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | void CreateAndAttachConsole() { 11 | if (::AllocConsole()) { 12 | FILE *unused; 13 | if (freopen_s(&unused, "CONOUT$", "w", stdout)) { 14 | _dup2(_fileno(stdout), 1); 15 | } 16 | if (freopen_s(&unused, "CONOUT$", "w", stderr)) { 17 | _dup2(_fileno(stdout), 2); 18 | } 19 | std::ios::sync_with_stdio(); 20 | FlutterDesktopResyncOutputStreams(); 21 | } 22 | } 23 | 24 | std::vector GetCommandLineArguments() { 25 | // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. 26 | int argc; 27 | wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); 28 | if (argv == nullptr) { 29 | return std::vector(); 30 | } 31 | 32 | std::vector command_line_arguments; 33 | 34 | // Skip the first argument as it's the binary name. 35 | for (int i = 1; i < argc; i++) { 36 | command_line_arguments.push_back(Utf8FromUtf16(argv[i])); 37 | } 38 | 39 | ::LocalFree(argv); 40 | 41 | return command_line_arguments; 42 | } 43 | 44 | std::string Utf8FromUtf16(const wchar_t* utf16_string) { 45 | if (utf16_string == nullptr) { 46 | return std::string(); 47 | } 48 | int target_length = ::WideCharToMultiByte( 49 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, 50 | -1, nullptr, 0, nullptr, nullptr); 51 | if (target_length == 0) { 52 | return std::string(); 53 | } 54 | std::string utf8_string; 55 | utf8_string.resize(target_length); 56 | int converted_length = ::WideCharToMultiByte( 57 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, 58 | -1, utf8_string.data(), 59 | target_length, nullptr, nullptr); 60 | if (converted_length == 0) { 61 | return std::string(); 62 | } 63 | return utf8_string; 64 | } 65 | -------------------------------------------------------------------------------- /windows/runner/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_UTILS_H_ 2 | #define RUNNER_UTILS_H_ 3 | 4 | #include 5 | #include 6 | 7 | // Creates a console for the process, and redirects stdout and stderr to 8 | // it for both the runner and the Flutter library. 9 | void CreateAndAttachConsole(); 10 | 11 | // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string 12 | // encoded in UTF-8. Returns an empty std::string on failure. 13 | std::string Utf8FromUtf16(const wchar_t* utf16_string); 14 | 15 | // Gets the command line arguments passed in as a std::vector, 16 | // encoded in UTF-8. Returns an empty std::vector on failure. 17 | std::vector GetCommandLineArguments(); 18 | 19 | #endif // RUNNER_UTILS_H_ 20 | --------------------------------------------------------------------------------