├── .github
├── CODEOWNERS
├── ISSUE_TEMPLATE
│ ├── bug_template.md
│ ├── chore_template.md
│ ├── config.yml
│ ├── feature_template.md
│ └── story_template.md
├── PULL_REQUEST_TEMPLATE.md
├── PULL_REQUEST_TEMPLATE
│ └── release_template.md
├── images
│ └── table-of-contents.png
├── wiki
│ ├── Deployment.md
│ ├── Home.md
│ └── _Sidebar.md
└── workflows
│ ├── android_deploy_production.yml
│ ├── android_deploy_production_to_playstore.yml
│ ├── android_deploy_staging.yml
│ ├── bump_version.yml
│ ├── configs
│ └── changelog-config.json
│ ├── ios_deploy_staging_to_firebase.yml
│ ├── ios_deploy_to_app_store.yml
│ ├── ios_deploy_to_testflight.yml
│ ├── publish_docs_to_wiki.yml
│ └── test.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── bricks
├── permission_handler
│ ├── README.md
│ ├── __brick__
│ │ ├── lib
│ │ │ └── utils
│ │ │ │ └── wrappers
│ │ │ │ └── permission_wrapper.dart
│ │ ├── {{~ _Podfile_build_configurations }}
│ │ └── {{~ _pubspec_dependency.yaml }}
│ └── brick.yaml
└── template
│ ├── CHANGELOG.md
│ ├── LICENSE
│ ├── README.md
│ ├── __brick__
│ ├── .env.sample
│ ├── .github
│ │ ├── CODEOWNERS
│ │ ├── ISSUE_TEMPLATE
│ │ │ ├── bug_template.md
│ │ │ ├── chore_template.md
│ │ │ ├── feature_template.md
│ │ │ └── story_template.md
│ │ ├── PULL_REQUEST_TEMPLATE.md
│ │ ├── PULL_REQUEST_TEMPLATE
│ │ │ └── release_template.md
│ │ ├── wiki
│ │ │ └── .keep
│ │ └── workflows
│ │ │ ├── android_deploy_production.yml
│ │ │ ├── android_deploy_production_to_playstore.yml
│ │ │ ├── android_deploy_staging.yml
│ │ │ ├── bump_version.yml
│ │ │ ├── configs
│ │ │ └── changelog-config.json
│ │ │ ├── ios_deploy_staging_to_firebase.yml
│ │ │ ├── ios_deploy_to_app_store.yml
│ │ │ ├── ios_deploy_to_testflight.yml
│ │ │ ├── publish_wiki.yml
│ │ │ ├── test.yml
│ │ │ └── whatsnew
│ │ │ └── whatsnew-en-US
│ ├── .gitignore
│ ├── .metadata
│ ├── README.md
│ ├── analysis_options.yaml
│ ├── android
│ │ ├── .gitignore
│ │ ├── app
│ │ │ ├── build.gradle
│ │ │ ├── proguard-rules.pro
│ │ │ └── src
│ │ │ │ ├── debug
│ │ │ │ └── AndroidManifest.xml
│ │ │ │ ├── main
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ ├── kotlin
│ │ │ │ │ └── {{package_name.pathCase()}}
│ │ │ │ │ │ └── MainActivity.kt
│ │ │ │ └── res
│ │ │ │ │ ├── drawable-v21
│ │ │ │ │ └── launch_background.xml
│ │ │ │ │ ├── drawable
│ │ │ │ │ └── launch_background.xml
│ │ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── values-night
│ │ │ │ │ └── styles.xml
│ │ │ │ │ └── values
│ │ │ │ │ ├── strings.xml
│ │ │ │ │ └── styles.xml
│ │ │ │ ├── profile
│ │ │ │ └── AndroidManifest.xml
│ │ │ │ └── staging
│ │ │ │ └── res
│ │ │ │ └── values
│ │ │ │ └── strings.xml
│ │ ├── build.gradle
│ │ ├── config
│ │ │ └── debug.keystore
│ │ ├── gradle.properties
│ │ ├── gradle
│ │ │ └── wrapper
│ │ │ │ └── gradle-wrapper.properties
│ │ ├── settings.gradle
│ │ └── signing.properties.sample
│ ├── assets
│ │ ├── fonts
│ │ │ └── neuzeit.otf
│ │ ├── images
│ │ │ └── nimble_logo.png
│ │ └── svg
│ │ │ └── flutter_logo.svg
│ ├── build.yaml
│ ├── codecov.yml
│ ├── integration_test
│ │ ├── real_app_test.dart
│ │ ├── screens
│ │ │ └── home_screen_test.dart
│ │ └── utils
│ │ │ └── test_util.dart
│ ├── ios
│ │ ├── .gitignore
│ │ ├── Flutter
│ │ │ ├── AppFrameworkInfo.plist
│ │ │ ├── Debug.xcconfig
│ │ │ └── Release.xcconfig
│ │ ├── Gemfile
│ │ ├── Gemfile.lock
│ │ ├── Podfile
│ │ ├── Podfile.lock
│ │ ├── Runner.xcodeproj
│ │ │ ├── project.pbxproj
│ │ │ ├── project.xcworkspace
│ │ │ │ ├── contents.xcworkspacedata
│ │ │ │ └── xcshareddata
│ │ │ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ │ │ └── WorkspaceSettings.xcsettings
│ │ │ └── xcshareddata
│ │ │ │ └── xcschemes
│ │ │ │ ├── production.xcscheme
│ │ │ │ └── staging.xcscheme
│ │ ├── Runner.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ │ └── WorkspaceSettings.xcsettings
│ │ ├── Runner
│ │ │ ├── AppDelegate.swift
│ │ │ ├── Assets.xcassets
│ │ │ │ ├── AppIcon.appiconset
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ │ │ ├── Icon-App-20x20@1x.png
│ │ │ │ │ ├── Icon-App-20x20@2x.png
│ │ │ │ │ ├── Icon-App-20x20@3x.png
│ │ │ │ │ ├── Icon-App-29x29@1x.png
│ │ │ │ │ ├── Icon-App-29x29@2x.png
│ │ │ │ │ ├── Icon-App-29x29@3x.png
│ │ │ │ │ ├── Icon-App-40x40@1x.png
│ │ │ │ │ ├── Icon-App-40x40@2x.png
│ │ │ │ │ ├── Icon-App-40x40@3x.png
│ │ │ │ │ ├── Icon-App-60x60@2x.png
│ │ │ │ │ ├── Icon-App-60x60@3x.png
│ │ │ │ │ ├── Icon-App-76x76@1x.png
│ │ │ │ │ ├── Icon-App-76x76@2x.png
│ │ │ │ │ └── Icon-App-83.5x83.5@2x.png
│ │ │ │ └── LaunchImage.imageset
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ ├── LaunchImage.png
│ │ │ │ │ ├── LaunchImage@2x.png
│ │ │ │ │ ├── LaunchImage@3x.png
│ │ │ │ │ └── README.md
│ │ │ ├── Base.lproj
│ │ │ │ ├── LaunchScreen.storyboard
│ │ │ │ └── Main.storyboard
│ │ │ ├── Info.plist
│ │ │ └── Runner-Bridging-Header.h
│ │ ├── RunnerTests
│ │ │ └── RunnerTests.swift
│ │ └── fastlane
│ │ │ ├── Constants
│ │ │ ├── Constants.rb
│ │ │ └── Environments.rb
│ │ │ ├── Fastfile
│ │ │ ├── Gymfile
│ │ │ ├── Managers
│ │ │ ├── BuildManager.rb
│ │ │ ├── DistributionManager.rb
│ │ │ └── MatchManager.rb
│ │ │ ├── Matchfile
│ │ │ └── Pluginfile
│ ├── l10n.yaml
│ ├── lib
│ │ ├── app
│ │ │ ├── resources
│ │ │ │ └── app_colors.dart
│ │ │ └── screens
│ │ │ │ └── home
│ │ │ │ ├── home_screen.dart
│ │ │ │ ├── home_view_model.dart
│ │ │ │ └── home_view_state.dart
│ │ ├── data
│ │ │ ├── local
│ │ │ │ └── secure_storage.dart
│ │ │ ├── remote
│ │ │ │ ├── datasources
│ │ │ │ │ └── api_service.dart
│ │ │ │ └── models
│ │ │ │ │ ├── requests
│ │ │ │ │ └── .keep
│ │ │ │ │ └── responses
│ │ │ │ │ └── user_response.dart
│ │ │ └── repositories
│ │ │ │ └── credential_repository_impl.dart
│ │ ├── di
│ │ │ ├── di.dart
│ │ │ ├── interceptor
│ │ │ │ └── app_interceptor.dart
│ │ │ ├── module
│ │ │ │ ├── network_module.dart
│ │ │ │ └── storage_module.dart
│ │ │ └── provider
│ │ │ │ └── dio_provider.dart
│ │ ├── domain
│ │ │ ├── exceptions
│ │ │ │ └── network_exceptions.dart
│ │ │ ├── models
│ │ │ │ └── user.dart
│ │ │ ├── repositories
│ │ │ │ └── credential_repository.dart
│ │ │ └── usecases
│ │ │ │ ├── base
│ │ │ │ ├── base_use_case.dart
│ │ │ │ └── use_case_result.dart
│ │ │ │ └── get_users_use_case.dart
│ │ ├── env.dart
│ │ ├── l10n
│ │ │ ├── app_en.arb
│ │ │ ├── app_th.arb
│ │ │ └── app_vi.arb
│ │ └── main.dart
│ ├── pubspec.lock
│ ├── pubspec.yaml
│ ├── test
│ │ ├── app
│ │ │ └── screens
│ │ │ │ └── home
│ │ │ │ └── home_view_model_test.dart
│ │ ├── data
│ │ │ └── repositories
│ │ │ │ └── credential_repository_test.dart
│ │ ├── domain
│ │ │ └── usecases
│ │ │ │ └── get_users_use_case_test.dart
│ │ └── mocks
│ │ │ ├── data
│ │ │ └── remote
│ │ │ │ └── models
│ │ │ │ └── responses
│ │ │ │ └── user_response_mocks.dart
│ │ │ └── generate_mocks.dart
│ └── test_driver
│ │ └── integration_test.dart
│ ├── brick.yaml
│ └── hooks
│ ├── .gitignore
│ ├── bundles
│ └── permission_handler_bundle.dart
│ ├── hooks_util.dart
│ ├── post_gen.dart
│ ├── pre_gen.dart
│ ├── pubspec.lock
│ └── pubspec.yaml
├── mason-config.json
├── mason.yaml
└── sample
├── .env.sample
├── .github
├── CODEOWNERS
├── ISSUE_TEMPLATE
│ ├── bug_template.md
│ ├── chore_template.md
│ ├── feature_template.md
│ └── story_template.md
├── PULL_REQUEST_TEMPLATE.md
├── PULL_REQUEST_TEMPLATE
│ └── release_template.md
├── wiki
│ └── .keep
└── workflows
│ ├── android_deploy_production.yml
│ ├── android_deploy_production_to_playstore.yml
│ ├── android_deploy_staging.yml
│ ├── bump_version.yml
│ ├── configs
│ └── changelog-config.json
│ ├── ios_deploy_staging_to_firebase.yml
│ ├── ios_deploy_to_app_store.yml
│ ├── ios_deploy_to_testflight.yml
│ ├── publish_wiki.yml
│ ├── test.yml
│ └── whatsnew
│ └── whatsnew-en-US
├── .gitignore
├── .metadata
├── README.md
├── analysis_options.yaml
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ │ └── co
│ │ │ │ └── nimblehq
│ │ │ │ └── flutter
│ │ │ │ └── template
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable-v21
│ │ │ └── launch_background.xml
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── values-night
│ │ │ └── styles.xml
│ │ │ └── values
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ ├── profile
│ │ └── AndroidManifest.xml
│ │ └── staging
│ │ └── res
│ │ └── values
│ │ └── strings.xml
├── build.gradle
├── config
│ └── debug.keystore
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
├── settings.gradle
└── signing.properties.sample
├── assets
├── fonts
│ └── neuzeit.otf
├── images
│ └── nimble_logo.png
└── svg
│ └── flutter_logo.svg
├── build.yaml
├── codecov.yml
├── integration_test
├── real_app_test.dart
├── screens
│ └── home_screen_test.dart
└── utils
│ └── test_util.dart
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Gemfile
├── Gemfile.lock
├── Podfile
├── Podfile.lock
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata
│ │ └── xcschemes
│ │ ├── production.xcscheme
│ │ └── staging.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
├── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ └── Icon-App-83.5x83.5@2x.png
│ │ └── LaunchImage.imageset
│ │ │ ├── Contents.json
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ └── README.md
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── Info.plist
│ └── Runner-Bridging-Header.h
├── RunnerTests
│ └── RunnerTests.swift
└── fastlane
│ ├── Constants
│ ├── Constants.rb
│ └── Environments.rb
│ ├── Fastfile
│ ├── Gymfile
│ ├── Managers
│ ├── BuildManager.rb
│ ├── DistributionManager.rb
│ └── MatchManager.rb
│ ├── Matchfile
│ └── Pluginfile
├── l10n.yaml
├── lib
├── app
│ ├── resources
│ │ └── app_colors.dart
│ └── screens
│ │ └── home
│ │ ├── home_screen.dart
│ │ ├── home_view_model.dart
│ │ └── home_view_state.dart
├── data
│ ├── local
│ │ └── secure_storage.dart
│ ├── remote
│ │ ├── datasources
│ │ │ └── api_service.dart
│ │ └── models
│ │ │ ├── requests
│ │ │ └── .keep
│ │ │ └── responses
│ │ │ └── user_response.dart
│ └── repositories
│ │ └── credential_repository_impl.dart
├── di
│ ├── di.dart
│ ├── interceptor
│ │ └── app_interceptor.dart
│ ├── module
│ │ ├── network_module.dart
│ │ └── storage_module.dart
│ └── provider
│ │ └── dio_provider.dart
├── domain
│ ├── exceptions
│ │ └── network_exceptions.dart
│ ├── models
│ │ └── user.dart
│ ├── repositories
│ │ └── credential_repository.dart
│ └── usecases
│ │ ├── base
│ │ ├── base_use_case.dart
│ │ └── use_case_result.dart
│ │ └── get_users_use_case.dart
├── env.dart
├── l10n
│ ├── app_en.arb
│ ├── app_th.arb
│ └── app_vi.arb
├── main.dart
└── utils
│ └── wrappers
│ └── permission_wrapper.dart
├── pubspec.lock
├── pubspec.yaml
├── test
├── app
│ └── screens
│ │ └── home
│ │ └── home_view_model_test.dart
├── data
│ └── repositories
│ │ └── credential_repository_test.dart
├── domain
│ └── usecases
│ │ └── get_users_use_case_test.dart
└── mocks
│ ├── data
│ └── remote
│ │ └── models
│ │ └── responses
│ │ └── user_response_mocks.dart
│ └── generate_mocks.dart
└── test_driver
└── integration_test.dart
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Team
2 | # @luongvo is the Team Lead
3 | * @luongvo @manh-t @markgravity @sleepylee @chornerman @doannimble @hoangnguyen92dn @nmint8m @ducbm051291 @thiennguyen0196 @kaungkhantsoe @Shayokh144 @toby-thanathip @Wadeewee
4 |
5 | # Engineering Leads
6 | CODEOWNERS @nimblehq/engineering-leads
7 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_template.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "Bug Report"
3 | about: "You found something that is not working. Report it so that it can be fixed. 👷"
4 | title: "Fix: "
5 | labels: "type : bug"
6 | ---
7 |
8 | ## Issue
9 |
10 | Describe the issue you are facing. Show us the implementation: screenshots, GIFs, etc.
11 |
12 | ## Expected
13 |
14 | Describe what should be the correct behavior.
15 |
16 | ## Steps to reproduce
17 |
18 | 1.
19 | 2.
20 | 3.
21 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/chore_template.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "Chore"
3 | about: "Open a chore issue for a minor update."
4 | title: "Update "
5 | labels: "type : chore"
6 | ---
7 |
8 | ## Why
9 |
10 | Describe the update in detail and why it is needed.
11 |
12 | ## Who Benefits?
13 |
14 | Describe who will be the beneficiaries e.g. everyone, specific chapters, clients...
15 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 |
3 | contact_links:
4 | - name: Request For Comments (RFC)
5 | about: When having an idea on how to improve our processes, propose the idea so that the team can provide feedback.
6 | # URL to create an RFC with the template
7 | url: https://github.com/nimblehq/flutter-templates/discussions/new?category=rfcs&title=+&body=%23%23+Issue%0D%0A%0D%0ADescribe+the+issue+the+team+is+currently+facing.+Provide+as+much+content+as+possible.%0D%0A%0D%0A%23%23+Solution%0D%0A%0D%0ADescribe+the+solution+you+are+prescribing+for+the+issue%0D%0A%0D%0A%23%23+Who+Benefits%3F%0D%0A%0D%0ADescribe+who+will+be+the+beneficiaries+e.g.+everyone,+specific+chapters,+clients...%0D%0A%0D%0A%23%23+What%27s+Next%3F%0D%0A%0D%0AProvide+an+actionable+list+of+things+that+must+happen+in+order+to+implement+the+solution:%0D%0A%0D%0A-+[+]%0D%0A-+[+]%0D%0A-+[+]
8 |
9 | - name: Ask a question
10 | about: When having a question about a pull request, issue, or problem, create a Q&A discussion to get help from the team.
11 | url: https://github.com/nimblehq/flutter-templates/discussions/new?category=q-a
12 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_template.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "Feature"
3 | about: "Open a feature issue to add new functionalities."
4 | title: "Add "
5 | labels: "type : feature"
6 | ---
7 |
8 | ## Why
9 |
10 | Describe the big picture of the feature and why it is needed.
11 |
12 | ## Who Benefits?
13 |
14 | Describe who will be the beneficiaries e.g. everyone, specific chapters, clients...
15 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/story_template.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "Story"
3 | about: "Open a feature story"
4 | title: "[Type] As a user, I can "
5 | labels: "type : feature"
6 | ---
7 |
8 | ## Why
9 |
10 | Describe the idea of the user story as in what the motive of the user story is.
11 |
12 | ## Acceptance Criteria
13 |
14 | List down how the user story will be tested and what criteria are necessary for the user story to be accepted.
15 |
16 | ## Design
17 |
18 | (Optional) Add design screenshots or Figma links for UI/UX-related stories.
19 |
20 | ## Resources
21 |
22 | (Optional) Add useful resources such as links to documentation, implementation ideas, or best practices.
23 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | Note: for a release PR, append this parameter `?template=release_template.md` to the current URL to apply the release PR
2 | template, e.g. `{Github PR URL}?template=release_template.md`
3 |
4 | --
5 |
6 | - Close #
7 |
8 | ## What happened 👀
9 |
10 | Provide a description of the **changes** this pull request brings to the codebase. Additionally, when the pull request is still being worked on, a checklist of the planned changes is welcome to track progress.
11 |
12 | ## Insight 📝
13 |
14 | Describe in detail why this solution is the most appropriate, which solution you tried but did not go with, and how to test the changes. References to relevant documentation are welcome as well.
15 |
16 | ## Proof Of Work 📹
17 |
18 | Show us the implementation: screenshots, GIFs, etc.
19 |
20 |
21 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE/release_template.md:
--------------------------------------------------------------------------------
1 | https://github.com/nimblehq/flutter-templates/milestone/?
2 |
3 | ## Features
4 |
5 | Provide the ID and title of the issue in the section for each type (feature, chore and bug). The link is optional.
6 |
7 | - #
8 |
9 | ## Chores
10 |
11 | - #
12 |
13 | ## Bugs
14 |
15 | - #
16 |
--------------------------------------------------------------------------------
/.github/images/table-of-contents.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/.github/images/table-of-contents.png
--------------------------------------------------------------------------------
/.github/wiki/Home.md:
--------------------------------------------------------------------------------
1 | Welcome to the Flutter-Templates wiki!
2 |
--------------------------------------------------------------------------------
/.github/wiki/_Sidebar.md:
--------------------------------------------------------------------------------
1 | # Table of Contents
2 |
3 | - [[Home]]
4 |
5 | ## Infrastructure
6 |
7 | - [[Deployment]]
8 |
--------------------------------------------------------------------------------
/.github/workflows/android_deploy_production_to_playstore.yml:
--------------------------------------------------------------------------------
1 | name: Android - Deploy Production build to Play Store
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | jobs:
9 | build_and_deploy_android:
10 | name: Android - Deploy Production build to Play Store
11 | runs-on: ubuntu-latest
12 | environment: production
13 | timeout-minutes: 30
14 | steps:
15 | - name: Check out
16 | uses: actions/checkout@v3
17 |
18 | - name: Set up Java JDK
19 | uses: actions/setup-java@v3
20 | with:
21 | distribution: 'adopt'
22 | java-version: '11'
23 |
24 | - name: Set up Flutter environment
25 | uses: subosito/flutter-action@v2
26 | with:
27 | channel: 'stable'
28 | flutter-version: '3.10.5'
29 |
30 | - name: Generate new project
31 | run: |
32 | dart pub global activate mason_cli
33 | mason get
34 | mason make template -c mason-config.json
35 |
36 | - name: Get Flutter dependencies
37 | run: flutter pub get
38 |
39 | - name: Run code generator
40 | run: flutter packages pub run build_runner build --delete-conflicting-outputs
41 |
42 | - name: Set up .env
43 | env:
44 | ENV: ${{ secrets.ENV }}
45 | run: |
46 | echo -e "$ENV" > .env
47 |
48 | - name: Set up release signing configs
49 | env:
50 | ANDROID_RELEASE_KEYSTORE_BASE64: ${{ secrets.ANDROID_RELEASE_KEYSTORE_BASE64 }}
51 | ANDROID_SIGNING_PROPERTIES: ${{ secrets.ANDROID_SIGNING_PROPERTIES }}
52 | run: |
53 | echo $ANDROID_RELEASE_KEYSTORE_BASE64 | base64 --decode > android/config/release.keystore
54 | echo "$ANDROID_SIGNING_PROPERTIES" > android/signing.properties
55 |
56 | - name: Build Production App Bundle
57 | run: flutter build appbundle --flavor production --release --build-number $GITHUB_RUN_NUMBER
58 |
59 | # TODO We will enable this step later when having a shared Service Account on our organization
60 | # Basically, this step will work properly after providing a valid Service Account.
61 | # - name: Upload Android Production Release bundle to Play Store
62 | # uses: r0adkll/upload-google-play@v1
63 | # with:
64 | # serviceAccountJson: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }}
65 | # packageName: co.nimblehq.flutter.template
66 | # releaseFile: build/app/outputs/bundle/productionRelease/app-production-release.aab
67 | # track: internal
68 | # userFraction: 1.0
69 | # whatsNewDirectory: .github/workflows/whatsnew
70 |
--------------------------------------------------------------------------------
/.github/workflows/bump_version.yml:
--------------------------------------------------------------------------------
1 | name: Bump Version
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | newVersion:
7 | description: "New version"
8 | required: true
9 | type: string
10 |
11 | jobs:
12 | bump_version:
13 | name: Bump version
14 | runs-on: ubuntu-latest
15 | timeout-minutes: 5
16 | steps:
17 | - name: Check out
18 | uses: actions/checkout@v3
19 |
20 | - name: Set new version
21 | uses: jossef/action-set-json-field@v2.1
22 | with:
23 | file: mason-config.json
24 | field: app_version
25 | value: ${{ github.event.inputs.newVersion }}
26 |
27 | - name: Create pull request
28 | uses: peter-evans/create-pull-request@v4
29 | with:
30 | assignees: ${{ secrets.GITHUB_USER }}
31 | token: ${{ secrets.WIKI_ACTION_TOKEN }}
32 | commit-message: Bump version to ${{ github.event.inputs.newVersion }}
33 | committer: Nimble Bot
34 | branch: chore/bump-version-to-${{ github.event.inputs.newVersion }}
35 | delete-branch: true
36 | title: '[Chore] Bump version to ${{ github.event.inputs.newVersion }}'
37 | labels: |
38 | type : chore
39 | body: |
40 | ## What happened 👀
41 |
42 | Bump version to ${{ github.event.inputs.newVersion }}
43 |
44 | ## Insight 📝
45 |
46 | Automatically created by the Bump Version workflow.
47 |
48 | ## Proof Of Work 📹
49 |
50 | On the Files changed tab
51 |
--------------------------------------------------------------------------------
/.github/workflows/configs/changelog-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "categories": [
3 | {
4 | "title": "## ✨ Features",
5 | "labels": [
6 | "type : feature"
7 | ]
8 | },
9 | {
10 | "title": "## 🐛 Bug fixes",
11 | "labels": [
12 | "type : bug"
13 | ]
14 | },
15 | {
16 | "title": "## 🧹 Chores",
17 | "labels": [
18 | "type : chore"
19 | ]
20 | },
21 | {
22 | "title": "## Others",
23 | "exclude_labels": [
24 | "type : feature",
25 | "type : bug",
26 | "type : chore",
27 | "type : release"
28 | ]
29 | }
30 | ],
31 | "max_pull_requests": 200
32 | }
33 |
--------------------------------------------------------------------------------
/.github/workflows/publish_docs_to_wiki.yml:
--------------------------------------------------------------------------------
1 | # For setup instruction, refer to https://github.com/nimblehq/github-actions-workflows/blob/main/.github/workflows/publish_wiki.yml
2 | name: Publish Wiki
3 |
4 | on:
5 | push:
6 | paths:
7 | - .github/wiki/**
8 | branches:
9 | - develop
10 |
11 | jobs:
12 | publish_wiki:
13 | name: Publish Wiki
14 | uses: nimblehq/github-actions-workflows/.github/workflows/publish_wiki.yml@0.1.0
15 | with:
16 | USER_NAME: team-nimblehq
17 | USER_EMAIL: bot@nimblehq.co
18 | secrets:
19 | USER_TOKEN: ${{ secrets.WIKI_ACTION_TOKEN }}
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | .DS_Store
3 |
4 | # VSCode
5 | .vscode
6 |
7 | # Intellij
8 | *.iml
9 | .idea/*
10 |
11 | # Mason
12 | mason-lock.json
13 | .mason/
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014 and onwards Nimble.
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/bricks/permission_handler/README.md:
--------------------------------------------------------------------------------
1 | # permission_handler
2 |
3 | [](https://github.com/felangel/mason)
4 |
5 | A new brick created with the Mason CLI.
6 |
7 | ## Description 🚀
8 |
9 | This brick has the simple implementation of [permission_handler](https://pub.dev/packages/permission_handler) package.
10 |
--------------------------------------------------------------------------------
/bricks/permission_handler/__brick__/lib/utils/wrappers/permission_wrapper.dart:
--------------------------------------------------------------------------------
1 | import 'package:permission_handler/permission_handler.dart'
2 | as permission_handler;
3 |
4 | abstract class PermissionWrapper {
5 | Future requestCameraPermission();
6 |
7 | Future isCameraPermissionDenied();
8 |
9 | Future isCameraPermissionPermanentlyDenied();
10 | }
11 |
12 | class PermissionWrapperImpl extends PermissionWrapper {
13 | @override
14 | Future requestCameraPermission() {
15 | return permission_handler.Permission.camera.request().then(
16 | (status) => status == permission_handler.PermissionStatus.granted);
17 | }
18 |
19 | @override
20 | Future isCameraPermissionDenied() {
21 | return permission_handler.Permission.camera.isDenied;
22 | }
23 |
24 | @override
25 | Future isCameraPermissionPermanentlyDenied() {
26 | return permission_handler.Permission.camera.isPermanentlyDenied;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/bricks/permission_handler/__brick__/{{~ _Podfile_build_configurations }}:
--------------------------------------------------------------------------------
1 | # TODO You can enable the permissions needed here.
2 | # permission, just remove the `#` character in front so it looks like this:
3 | #
4 | # ## dart: PermissionGroup.camera
5 | #'PERMISSION_CAMERA=1'
6 | #
7 | # Preprocessor definitions can be found in: https://github.com/Baseflow/flutter-permission-handler/blob/master/permission_handler/ios/Classes/PermissionHandlerEnums.h
8 | config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
9 | '$(inherited)',
10 |
11 | ## dart: PermissionGroup.calendar
12 | # 'PERMISSION_EVENTS=1',
13 |
14 | ## dart: PermissionGroup.reminders
15 | # 'PERMISSION_REMINDERS=1',
16 |
17 | ## dart: PermissionGroup.contacts
18 | # 'PERMISSION_CONTACTS=1',
19 |
20 | ## dart: PermissionGroup.camera
21 | # 'PERMISSION_CAMERA=1',
22 |
23 | ## dart: PermissionGroup.microphone
24 | # 'PERMISSION_MICROPHONE=1',
25 |
26 | ## dart: PermissionGroup.speech
27 | # 'PERMISSION_SPEECH_RECOGNIZER=1',
28 |
29 | ## dart: PermissionGroup.photos
30 | # 'PERMISSION_PHOTOS=1',
31 |
32 | ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
33 | # 'PERMISSION_LOCATION=1',
34 |
35 | ## dart: PermissionGroup.notification
36 | # 'PERMISSION_NOTIFICATIONS=1',
37 |
38 | ## dart: PermissionGroup.mediaLibrary
39 | # 'PERMISSION_MEDIA_LIBRARY=1',
40 |
41 | ## dart: PermissionGroup.sensors
42 | # 'PERMISSION_SENSORS=1',
43 |
44 | ## dart: PermissionGroup.bluetooth
45 | # 'PERMISSION_BLUETOOTH=1',
46 |
47 | ## dart: PermissionGroup.appTrackingTransparency
48 | # 'PERMISSION_APP_TRACKING_TRANSPARENCY=1',
49 |
50 | ## dart: PermissionGroup.criticalAlerts
51 | # 'PERMISSION_CRITICAL_ALERTS=1'
52 | ]
--------------------------------------------------------------------------------
/bricks/permission_handler/__brick__/{{~ _pubspec_dependency.yaml }}:
--------------------------------------------------------------------------------
1 |
2 | permission_handler: ^10.2.0
--------------------------------------------------------------------------------
/bricks/permission_handler/brick.yaml:
--------------------------------------------------------------------------------
1 | name: permission_handler
2 | description: A new brick created with the Mason CLI.
3 |
4 | # The following defines the version and build number for your brick.
5 | # A version number is three numbers separated by dots, like 1.2.34
6 | # followed by an optional build number (separated by a +).
7 | version: 0.1.0+1
8 |
9 | # The following defines the environment for the current brick.
10 | # It includes the version of mason that the brick requires.
11 | environment:
12 | mason: ">=0.1.0-dev.41 <0.1.0"
13 |
14 | # Variables specify dynamic values that your brick depends on.
15 | # Zero or more variables can be specified for a given brick.
16 | # Each variable has:
17 | # * a type (string, number, boolean, enum, or array)
18 | # * an optional short description
19 | # * an optional default value
20 | # * an optional list of default values (array only)
21 | # * an optional prompt phrase used when asking for the variable
22 | # * a list of values (enums only)
23 | vars:
24 | # Injected from the root brick by post_gen hook
25 | project_name:
26 | type: string
27 |
--------------------------------------------------------------------------------
/bricks/template/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # 0.1.0+1
2 |
3 | - TODO: Describe initial release.
4 |
--------------------------------------------------------------------------------
/bricks/template/LICENSE:
--------------------------------------------------------------------------------
1 | TODO: Add your license here.
2 |
--------------------------------------------------------------------------------
/bricks/template/README.md:
--------------------------------------------------------------------------------
1 | # template
2 |
3 | [](https://github.com/felangel/mason)
4 |
5 | A new brick created with the Mason CLI.
6 |
7 | _Generated by [mason][1] 🧱_
8 |
9 | ## Getting Started 🚀
10 |
11 | This is a starting point for a new brick.
12 | A few resources to get you started if this is your first brick template:
13 |
14 | - [Official Mason Documentation][2]
15 | - [Code generation with Mason Blog][3]
16 | - [Very Good Livestream: Felix Angelov Demos Mason][4]
17 |
18 | [1]: https://github.com/felangel/mason
19 | [2]: https://github.com/felangel/mason/tree/master/packages/mason_cli#readme
20 | [3]: https://verygood.ventures/blog/code-generation-with-mason
21 | [4]: https://youtu.be/G4PTjA6tpTU
22 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/.env.sample:
--------------------------------------------------------------------------------
1 | SECRET=
2 | REST_API_ENDPOINT=
3 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Team
2 | # @teamlead is the Team Lead
3 | * @teammember1 @teammember2
4 |
5 | # Engineering Leads
6 | CODEOWNERS @nimblehq/engineering-leads
7 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/.github/ISSUE_TEMPLATE/bug_template.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "Bug Report"
3 | about: "You found something that is not working. Report it so that it can be fixed. 👷"
4 | title: "Fix: "
5 | labels: "type : bug"
6 | ---
7 |
8 | ## Issue
9 |
10 | Describe the issue you are facing. Show us the implementation: screenshots, GIFs, etc.
11 |
12 | ## Expected
13 |
14 | Describe what should be the correct behavior.
15 |
16 | ## Steps to reproduce
17 |
18 | 1.
19 | 2.
20 | 3.
21 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/.github/ISSUE_TEMPLATE/chore_template.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "Chore"
3 | about: "Open a chore issue for a minor update."
4 | title: "Update "
5 | labels: "type : chore"
6 | ---
7 |
8 | ## Why
9 |
10 | Describe the update in detail and why it is needed.
11 |
12 | ## Who Benefits?
13 |
14 | Describe who will be the beneficiaries e.g. everyone, specific chapters, clients...
15 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/.github/ISSUE_TEMPLATE/feature_template.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "Feature"
3 | about: "Open a feature issue to add new functionalities."
4 | title: "Add "
5 | labels: "type : feature"
6 | ---
7 |
8 | ## Why
9 |
10 | Describe the big picture of the feature and why it is needed.
11 |
12 | ## Who Benefits?
13 |
14 | Describe who will be the beneficiaries e.g. everyone, specific chapters, clients...
15 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/.github/ISSUE_TEMPLATE/story_template.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "Story"
3 | about: "Open a feature story"
4 | title: "[Type] As a user, I can "
5 | labels: "type : feature"
6 | ---
7 |
8 | ## Why
9 |
10 | Describe the idea of the user story as in what the motive of the user story is.
11 |
12 | ## Acceptance Criteria
13 |
14 | List down how the user story will be tested and what criteria are necessary for the user story to be accepted.
15 |
16 | ## Design
17 |
18 | (Optional) Add design screenshots or Figma links for UI/UX-related stories.
19 |
20 | ## Resources
21 |
22 | (Optional) Add useful resources such as links to documentation, implementation ideas, or best practices.
23 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | - Close #
2 |
3 | ## What happened 👀
4 |
5 | Provide a description of the **changes** this pull request brings to the codebase. Additionally, when the pull request is still being worked on, a checklist of the planned changes is welcome to track progress.
6 |
7 | ## Insight 📝
8 |
9 | Describe in detail why this solution is the most appropriate, which solution you tried but did not go with, and how to test the changes. References to relevant documentation are welcome as well.
10 |
11 | ## Proof Of Work 📹
12 |
13 | Show us the implementation: screenshots, GIFs, etc.
14 |
15 |
16 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/.github/PULL_REQUEST_TEMPLATE/release_template.md:
--------------------------------------------------------------------------------
1 | Link to the milestone on Github e.g. https://github.com/nimblehq/{{project_name.paramCase()}}/milestone/41?closed=1
2 | or Link to the project management tool for the release
3 |
4 | ## Features
5 |
6 | Provide the ID and title of the issue in the section for each type (feature, chore and bug). The link is optional.
7 |
8 | - [#1] As a user, I can log in or
9 | - [[#1](https://github.com/nimblehq/{{project_name.paramCase()}}/issues/1)] As a user, I can log in
10 |
11 | ## Chores
12 | - Same structure as in ## Feature
13 |
14 | ## Bugs
15 | - Same structure as in ## Feature
16 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/.github/wiki/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/.github/wiki/.keep
--------------------------------------------------------------------------------
/bricks/template/__brick__/.github/workflows/android_deploy_production_to_playstore.yml:
--------------------------------------------------------------------------------
1 | name: Android - Deploy Production build to Play Store
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | jobs:
9 | build_and_deploy_android:
10 | name: Android - Deploy Production build to Play Store
11 | runs-on: ubuntu-latest
12 | environment: production
13 | timeout-minutes: 30
14 | steps:
15 | - name: Check out
16 | uses: actions/checkout@v3
17 |
18 | - name: Set up Java JDK
19 | uses: actions/setup-java@v3
20 | with:
21 | distribution: 'adopt'
22 | java-version: '11'
23 |
24 | - name: Set up Flutter environment
25 | uses: subosito/flutter-action@v2
26 | with:
27 | channel: 'stable'
28 | flutter-version: '3.10.5'
29 |
30 | - name: Get Flutter dependencies
31 | run: flutter pub get
32 |
33 | - name: Run code generator
34 | run: flutter packages pub run build_runner build --delete-conflicting-outputs
35 |
36 | - name: Set up .env
37 | env:
38 | ENV: ${{#mustacheCase}}secrets.ENV{{/mustacheCase}}
39 | run: |
40 | echo -e "$ENV" > .env
41 |
42 | - name: Set up release signing configs
43 | env:
44 | ANDROID_RELEASE_KEYSTORE_BASE64: ${{#mustacheCase}}secrets.ANDROID_RELEASE_KEYSTORE_BASE64{{/mustacheCase}}
45 | ANDROID_SIGNING_PROPERTIES: ${{#mustacheCase}}secrets.ANDROID_SIGNING_PROPERTIES{{/mustacheCase}}
46 | run: |
47 | echo $ANDROID_RELEASE_KEYSTORE_BASE64 | base64 --decode > android/config/release.keystore
48 | echo "$ANDROID_SIGNING_PROPERTIES" > android/signing.properties
49 |
50 | - name: Build Production App Bundle
51 | run: flutter build appbundle --flavor production --release --build-number $GITHUB_RUN_NUMBER
52 |
53 | - name: Upload Android Production Release bundle to Play Store
54 | uses: r0adkll/upload-google-play@v1
55 | with:
56 | serviceAccountJson: ${{#mustacheCase}}secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON{{/mustacheCase}}
57 | packageName: {{package_name.dotCase()}}
58 | releaseFile: build/app/outputs/bundle/productionRelease/app-production-release.aab
59 | track: internal
60 | userFraction: 1.0
61 | whatsNewDirectory: .github/workflows/whatsnew
62 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/.github/workflows/bump_version.yml:
--------------------------------------------------------------------------------
1 | name: Bump Version
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | newVersion:
7 | description: "New version"
8 | required: true
9 | type: string
10 |
11 | jobs:
12 | bump_version:
13 | name: Bump version
14 | runs-on: ubuntu-latest
15 | timeout-minutes: 5
16 | steps:
17 | - name: Check out
18 | uses: actions/checkout@v3
19 |
20 | - name: Set new version
21 | run: |
22 | perl -i -pe 's/^(version:\s+\d+\.\d+\.\d+\+)(\d+)$/"version: ${{#mustacheCase}}github.event.inputs.newVersion{{/mustacheCase}}+".($2+1)/e' ./pubspec.yaml
23 |
24 | - name: Create pull request
25 | uses: peter-evans/create-pull-request@v4
26 | with:
27 | assignees: ${{#mustacheCase}}secrets.GITHUB_USER{{/mustacheCase}}
28 | token: ${{#mustacheCase}}secrets.WIKI_ACTION_TOKEN{{/mustacheCase}}
29 | commit-message: Bump version to ${{#mustacheCase}}github.event.inputs.newVersion{{/mustacheCase}}
30 | committer: Nimble Bot
31 | branch: chore/bump-version-to-${{#mustacheCase}}github.event.inputs.newVersion{{/mustacheCase}}
32 | delete-branch: true
33 | title: '[Chore] Bump version to ${{#mustacheCase}}github.event.inputs.newVersion{{/mustacheCase}}'
34 | labels: |
35 | type : chore
36 | body: |
37 | ## What happened 👀
38 |
39 | Bump version to ${{#mustacheCase}}github.event.inputs.newVersion{{/mustacheCase}}
40 |
41 | ## Insight 📝
42 |
43 | Automatically created by the Bump Version workflow.
44 |
45 | ## Proof Of Work 📹
46 |
47 | On the Files changed tab
48 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/.github/workflows/configs/changelog-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "categories": [
3 | {
4 | "title": "## ✨ Features",
5 | "labels": [
6 | "type : feature"
7 | ]
8 | },
9 | {
10 | "title": "## 🐛 Bug fixes",
11 | "labels": [
12 | "type : bug"
13 | ]
14 | },
15 | {
16 | "title": "## 🧹 Chores",
17 | "labels": [
18 | "type : chore"
19 | ]
20 | },
21 | {
22 | "title": "## Others",
23 | "exclude_labels": [
24 | "type : feature",
25 | "type : bug",
26 | "type : chore",
27 | "type : release"
28 | ]
29 | }
30 | ],
31 | "max_pull_requests": 200
32 | }
33 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/.github/workflows/publish_wiki.yml:
--------------------------------------------------------------------------------
1 | # For setup instruction, refer to https://github.com/nimblehq/github-actions-workflows/blob/main/.github/workflows/publish_wiki.yml
2 | name: Publish Wiki
3 |
4 | on:
5 | push:
6 | paths:
7 | - .github/wiki/**
8 | branches:
9 | - develop
10 |
11 | jobs:
12 | publish:
13 | name: Publish Wiki
14 | uses: nimblehq/github-actions-workflows/.github/workflows/publish_wiki.yml@0.1.0
15 | with:
16 | USER_NAME: github-wiki-workflow
17 | USER_EMAIL: ${{#mustacheCase}}secrets.GH_EMAIL{{/mustacheCase}}
18 | secrets:
19 | USER_TOKEN: ${{#mustacheCase}}secrets.GH_TOKEN{{/mustacheCase}}
20 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 | on:
3 | # Trigger the workflow on push or pull request,
4 | # but push action is only for the feature branch
5 | pull_request:
6 | types: [ opened, synchronize, edited, reopened ]
7 | push:
8 | branches-ignore:
9 | - develop
10 | - 'release/**'
11 | jobs:
12 | lint_and_test:
13 | name: Static code analyze & Unit test
14 | runs-on: ubuntu-latest
15 | timeout-minutes: 30
16 | environment: staging
17 | steps:
18 | - name: Check out
19 | uses: actions/checkout@v3
20 |
21 | - name: Set up Flutter environment
22 | uses: subosito/flutter-action@v2
23 | with:
24 | channel: 'stable'
25 | flutter-version: '3.10.5'
26 |
27 | - name: Get Flutter dependencies
28 | run: flutter pub get
29 |
30 | - name: Run code generator
31 | run: flutter packages pub run build_runner build --delete-conflicting-outputs
32 |
33 | - name: Check for any formatting issues in the code
34 | run: dart format --set-exit-if-changed .
35 |
36 | - name: Statically analyze the Dart code for any errors
37 | run: flutter analyze .
38 |
39 | - name: Run widget tests, unit tests
40 | run: flutter test --machine --coverage
41 |
42 | - name: Upload coverage to codecov
43 | uses: codecov/codecov-action@v2
44 | with:
45 | files: ./coverage/lcov.info
46 | flags: unittests # optional
47 | token: ${{#mustacheCase}}secrets.CODECOV_TOKEN{{/mustacheCase}} # not required for public repos
48 | fail_ci_if_error: false
49 | verbose: true
50 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/.github/workflows/whatsnew/whatsnew-en-US:
--------------------------------------------------------------------------------
1 |
2 | Enter or paste your release notes for en-US here
3 |
4 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/.gitignore:
--------------------------------------------------------------------------------
1 | # Used by dotenv library to load environment variables.
2 | .env
3 | .env.staging
4 |
5 | # Miscellaneous
6 | *.class
7 | *.log
8 | *.pyc
9 | *.swp
10 | .DS_Store
11 | .atom/
12 | .buildlog/
13 | .history
14 | .svn/
15 | migrate_working_dir/
16 |
17 | # IntelliJ related
18 | *.iml
19 | *.ipr
20 | *.iws
21 | .idea/
22 |
23 | # The .vscode folder contains launch configuration and tasks you configure in
24 | # VS Code which you may wish to be included in version control, so this line
25 | # is commented out by default.
26 | .vscode/
27 |
28 | # Flutter version manager related
29 | .fvm/
30 |
31 | # Flutter/Dart/Pub related
32 | **/doc/api/
33 | **/ios/Flutter/.last_build_id
34 | **/ios/.envfile
35 | **/ios/Flutter/tmp.xcconfig
36 | .dart_tool/
37 | .flutter-plugins
38 | .flutter-plugins-dependencies
39 | .packages
40 | .pub-cache/
41 | .pub/
42 | /build/
43 |
44 | # Web related
45 | lib/generated_plugin_registrant.dart
46 |
47 | # Symbolication related
48 | app.*.symbols
49 |
50 | # Obfuscation related
51 | app.*.map.json
52 |
53 | # Android Studio will place build artifacts here
54 | /android/app/debug
55 | /android/app/profile
56 | /android/app/release
57 |
58 | # Flutter generated files
59 | *.g.dart
60 | *.gen.dart
61 | *.config.dart
62 | *.freezed.dart
63 | *.mocks.dart
64 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/.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: f4abaa0735eba4dfd8f33f73363911d63931fe03
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/README.md:
--------------------------------------------------------------------------------
1 | # {{app_name.titleCase()}}
2 |
3 | [}}/branch/main/graph/badge.svg?token=ATUNXDX218)](https://codecov.io/gh/nimblehq/{{project_name.paramCase()}})
4 |
5 | ## Prerequisite
6 |
7 | - Flutter 3.10.5
8 | - Flutter version manager (recommend): [fvm](https://fvm.app/)
9 |
10 | ## Getting Started
11 |
12 | ### Setup
13 |
14 | - Create these `.env` files in the root directory according to the flavors and add the required
15 | environment variables. The example file is `.env.sample`.
16 |
17 | - Staging: `.env.staging`
18 |
19 | - Production: `.env`
20 |
21 | - To make the Android release build,
22 |
23 | - put the `release.keystore` at the `android/config` folder,
24 |
25 | - create the `signing.properties` file to provide keystore credentials in the `android` folder. The example file is `signing.properties.sample`.
26 |
27 | ### Run
28 |
29 | - Run code generator for JSON models, DI dependencies, etc:
30 |
31 | - `$ fvm flutter packages pub run build_runner build --delete-conflicting-outputs`
32 |
33 | - Run the app with the desired app flavor:
34 |
35 | - `$ fvm flutter run --flavor staging`
36 | - `$ fvm flutter run --flavor production`
37 |
38 | - Check code formatting & static code analyzing:
39 |
40 | - `$ dart format --set-exit-if-changed .`
41 | - `$ fvm flutter analyze .`
42 |
43 | ### Test
44 |
45 | - Run unit testing:
46 |
47 | - `$ fvm flutter test`
48 | - `$ fvm flutter test --machine --coverage`
49 |
50 | - Run integration testing:
51 |
52 | - `$ fvm flutter drive --driver=test_driver/integration_test.dart --target=integration_test/{test_file}.dart --flavor staging`
53 |
54 | - For example:
55 |
56 | `$ fvm flutter drive --driver=test_driver/integration_test.dart --target=integration_test/my_home_page_test.dart --flavor staging`
57 |
58 | ## License
59 |
60 | This project is Copyright (c) 2014 and onwards. It is free software,
61 | and may be redistributed under the terms specified in the [LICENSE] file.
62 |
63 | [LICENSE]: /LICENSE
64 |
65 | ## About
66 |
67 | 
68 |
69 | This project is maintained and funded by Nimble.
70 |
71 | We love open source and do our part in sharing our work with the community!
72 | See [our other projects][community] or [hire our team][hire] to help build your product.
73 |
74 | [community]: https://github.com/nimblehq
75 | [hire]: https://nimblehq.co/
76 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # This file configures the analyzer, which statically analyzes Dart code to
2 | # check for errors, warnings, and lints.
3 | #
4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled
5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
6 | # invoked from the command line by running `flutter analyze`.
7 |
8 | # The following line activates a set of recommended lints for Flutter apps,
9 | # packages, and plugins designed to encourage good coding practices.
10 | include: package:flutter_lints/flutter.yaml
11 |
12 | linter:
13 | # The lint rules applied to this project can be customized in the
14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml`
15 | # included above or to enable additional rules. A list of all available lints
16 | # and their documentation is published at
17 | # https://dart-lang.github.io/linter/lints/index.html.
18 | #
19 | # Instead of disabling a lint rule for the entire project in the
20 | # section below, it can also be suppressed for a single line of code
21 | # or a specific dart file by using the `// ignore: name_of_lint` and
22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file
23 | # producing the lint.
24 | rules:
25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule
26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
27 |
28 | # Additional information about this file can be found at
29 | # https://dart.dev/guides/language/analysis-options
30 |
31 | analyzer:
32 | exclude: [
33 | lib/**.g.dart,
34 | lib/**.gen.dart,
35 | lib/**.config.dart,
36 | lib/**.freezed.dart,
37 | test/**.mocks.dart
38 | ]
39 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/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 | signing.properties
12 | config/release.keystore
13 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.kts.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
23 | # Keep BuildConfig for Flutter Config https://github.com/ByneappLLC/flutter_config/blob/master/doc/ANDROID.md#android-setup
24 | -keep class {{package_name.dotCase()}}.BuildConfig { *; }
25 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
14 |
18 |
22 |
23 |
24 |
25 |
26 |
27 |
29 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/android/app/src/main/kotlin/{{package_name.pathCase()}}/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package {{package_name.dotCase()}}
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{app_name.titleCase()}}
4 |
5 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/android/app/src/staging/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{app_name.titleCase()}} Staging
4 |
5 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.7.10'
3 | repositories {
4 | google()
5 | mavenCentral()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:7.3.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | mavenCentral()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | }
25 | subprojects {
26 | project.evaluationDependsOn(':app')
27 | }
28 |
29 | tasks.register("clean", Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/android/config/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/android/config/debug.keystore
--------------------------------------------------------------------------------
/bricks/template/__brick__/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
6 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/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 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/android/signing.properties.sample:
--------------------------------------------------------------------------------
1 | KEYSTORE_PASSWORD=
2 | KEY_ALIAS=
3 | KEY_PASSWORD=
4 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/assets/fonts/neuzeit.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/assets/fonts/neuzeit.otf
--------------------------------------------------------------------------------
/bricks/template/__brick__/assets/images/nimble_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/assets/images/nimble_logo.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/build.yaml:
--------------------------------------------------------------------------------
1 | targets:
2 | $default:
3 | builders:
4 | json_serializable:
5 | options:
6 | # Full FieldRename's options, refer https://github.com/google/json_serializable.dart/blob/2185e8b80d8d0c12e2adbf897d920b6f5725cded/json_annotation/lib/src/json_serializable.dart#L16-L32
7 | field_rename: "{{json_field_rename_format}}"
8 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/codecov.yml:
--------------------------------------------------------------------------------
1 | codecov:
2 | bot: [bot_username] # For the private repository, set up a TeamBot https://docs.codecov.com/docs/team-bot, e.g., bob
3 | require_ci_to_pass: yes
4 |
5 | coverage:
6 | status:
7 | project: off
8 | patch: off
9 |
10 | parsers:
11 | gcov:
12 | branch_detection:
13 | conditional: yes
14 | loop: yes
15 | method: no
16 | macro: no
17 |
18 | comment:
19 | layout: "reach,diff,flags,files,tree"
20 | behavior: default
21 | require_changes: no
22 |
23 | ignore:
24 | - "lib/di"
25 | - "lib/gen"
26 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/integration_test/real_app_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_test/flutter_test.dart';
3 | import 'package:integration_test/integration_test.dart';
4 |
5 | import 'utils/test_util.dart';
6 |
7 | void main() {
8 | IntegrationTestWidgetsFlutterBinding.ensureInitialized();
9 |
10 | testWidgets('Real App', (WidgetTester tester) async {
11 | await tester.pumpWidget(TestUtil.pumpWidgetWithRealApp('/'));
12 | await tester.pumpAndSettle();
13 |
14 | expect(find.widgetWithText(AppBar, '{{app_name.titleCase()}} testing'),
15 | findsOneWidget);
16 | expect(find.text('This is only for testing'), findsOneWidget);
17 | });
18 | }
19 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/integration_test/screens/home_screen_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:{{project_name.snakeCase()}}/app/screens/home/home_screen.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 | import 'package:integration_test/integration_test.dart';
5 |
6 | import '../utils/test_util.dart';
7 |
8 | void main() {
9 | IntegrationTestWidgetsFlutterBinding.ensureInitialized();
10 |
11 | testWidgets('My Home Page widget', (WidgetTester tester) async {
12 | await tester
13 | .pumpWidget(TestUtil.pumpWidgetWithShellApp(const HomeScreen()));
14 | await tester.pumpAndSettle();
15 |
16 | expect(find.widgetWithText(AppBar, '{{app_name.titleCase()}} testing'),
17 | findsOneWidget);
18 | expect(find.text('This is only for testing'), findsOneWidget);
19 | });
20 | }
21 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/integration_test/utils/test_util.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_config/flutter_config.dart';
3 | import 'package:flutter_gen/gen_l10n/app_localizations.dart';
4 | import 'package:package_info_plus/package_info_plus.dart';
5 | import 'package:{{project_name.snakeCase()}}/main.dart';
6 |
7 | class TestUtil {
8 | /// This is useful when we test the whole app with the real configs(styling,
9 | /// localization, routes, etc)
10 | static Widget pumpWidgetWithRealApp(String initialRoute) {
11 | _initDependencies();
12 | return MyApp();
13 | }
14 |
15 | /// We normally use this function to test a specific [widget] without
16 | /// considering much about theming.
17 | static Widget pumpWidgetWithShellApp(Widget widget) {
18 | _initDependencies();
19 | return MaterialApp(
20 | localizationsDelegates: AppLocalizations.localizationsDelegates,
21 | supportedLocales: AppLocalizations.supportedLocales,
22 | home: widget,
23 | );
24 | }
25 |
26 | static void _initDependencies() {
27 | PackageInfo.setMockInitialValues(
28 | appName: '{{app_name.titleCase()}} testing',
29 | packageName: '',
30 | version: '',
31 | buildNumber: '',
32 | buildSignature: '');
33 | FlutterConfig.loadValueForTesting({'SECRET': 'This is only for testing'});
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/.gitignore:
--------------------------------------------------------------------------------
1 | **/dgph
2 | *.mode1v3
3 | *.mode2v3
4 | *.moved-aside
5 | *.pbxuser
6 | *.perspectivev3
7 | **/*sync/
8 | .sconsign.dblite
9 | .tags*
10 | **/.vagrant/
11 | **/DerivedData/
12 | Icon?
13 | **/Pods/
14 | **/.symlinks/
15 | profile
16 | xcuserdata
17 | **/.generated/
18 | Flutter/App.framework
19 | Flutter/Flutter.framework
20 | Flutter/Flutter.podspec
21 | Flutter/Generated.xcconfig
22 | Flutter/ephemeral/
23 | Flutter/app.flx
24 | Flutter/app.zip
25 | Flutter/flutter_assets/
26 | Flutter/flutter_export_environment.sh
27 | Flutter/tmp.xcconfig
28 | Flutter/.last_build_id
29 | ServiceDefinitions.json
30 | Runner/GeneratedPluginRegistrant.*
31 | Build/
32 | DerivedData/
33 | fastlane/README.md
34 | fastlane/report.xml
35 | .envfile
36 |
37 | # Exceptions to above rules.
38 | !default.mode1v3
39 | !default.mode2v3
40 | !default.pbxuser
41 | !default.perspectivev3
42 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 11.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 | #include? "tmp.xcconfig"
4 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 | #include? "tmp.xcconfig"
4 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | gem "fastlane"
4 | gem "cocoapods"
5 |
6 | plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
7 | eval_gemfile(plugins_path) if File.exist?(plugins_path)
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | platform :ios, '11.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def flutter_root
14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15 | unless File.exist?(generated_xcode_build_settings_path)
16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17 | end
18 |
19 | File.foreach(generated_xcode_build_settings_path) do |line|
20 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
21 | return matches[1].strip if matches
22 | end
23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24 | end
25 |
26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27 |
28 | flutter_ios_podfile_setup
29 |
30 | target 'Runner' do
31 | use_frameworks!
32 | use_modular_headers!
33 |
34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
35 | end
36 |
37 | post_install do |installer|
38 | installer.pods_project.targets.each do |target|
39 | flutter_additional_ios_build_settings(target)
40 | target.build_configurations.each do |config|
41 | {{#add_permission_handler}}{{{ _Podfile_build_configurations }}}{{/add_permission_handler}}
42 | end
43 | end
44 | end
45 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Flutter (1.0.0)
3 | - flutter_config (0.0.1):
4 | - Flutter
5 | - integration_test (0.0.1):
6 | - Flutter
7 | - package_info_plus (0.4.5):
8 | - Flutter
9 |
10 | DEPENDENCIES:
11 | - Flutter (from `Flutter`)
12 | - flutter_config (from `.symlinks/plugins/flutter_config/ios`)
13 | - integration_test (from `.symlinks/plugins/integration_test/ios`)
14 | - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
15 |
16 | EXTERNAL SOURCES:
17 | Flutter:
18 | :path: Flutter
19 | flutter_config:
20 | :path: ".symlinks/plugins/flutter_config/ios"
21 | integration_test:
22 | :path: ".symlinks/plugins/integration_test/ios"
23 | package_info_plus:
24 | :path: ".symlinks/plugins/package_info_plus/ios"
25 |
26 | SPEC CHECKSUMS:
27 | Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
28 | flutter_config: 2226c1df19c78fe34a05eb7f1363445f18e76fc1
29 | integration_test: 13825b8a9334a850581300559b8839134b124670
30 | package_info_plus: fd030dabf36271f146f1f3beacd48f564b0f17f7
31 |
32 | PODFILE CHECKSUM: 22cb4141f6291ab800e0ca928cc1f87e9a69bf64
33 |
34 | COCOAPODS: 1.11.3
35 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/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 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/bricks/template/__brick__/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.
--------------------------------------------------------------------------------
/bricks/template/__brick__/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 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/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 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | $(APP_DISPLAY_NAME)
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | {{project_name.snakeCase()}}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(FLUTTER_BUILD_NUMBER)
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 | UIViewControllerBasedStatusBarAppearance
45 |
46 | CADisableMinimumFrameDurationOnPhone
47 |
48 | UIApplicationSupportsIndirectInputEvents
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/RunnerTests/RunnerTests.swift:
--------------------------------------------------------------------------------
1 | import Flutter
2 | import UIKit
3 | import XCTest
4 |
5 | class RunnerTests: XCTestCase {
6 |
7 | func testExample() {
8 | // If you add code to the Runner application, consider adding tests here.
9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest.
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/fastlane/Constants/Constants.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Constants
4 | #################
5 | #### PROJECT ####
6 | #################
7 |
8 | # Workspace path
9 | def self.WORKSPACE_PATH
10 | './Runner.xcworkspace'
11 | end
12 |
13 | # Project path
14 | def self.PROJECT_PATH
15 | './Runner.xcodeproj'
16 | end
17 |
18 | # bundle ID for Staging app
19 | def self.BUNDLE_ID_STAGING
20 | '{{package_name.dotCase()}}.staging'
21 | end
22 |
23 | # bundle ID for Production app
24 | def self.BUNDLE_ID_PRODUCTION
25 | '{{package_name.dotCase()}}'
26 | end
27 |
28 | #################
29 | #### BUILDING ###
30 | #################
31 |
32 | # a derived data path
33 | def self.DERIVED_DATA_PATH
34 | './DerivedData'
35 | end
36 |
37 | # a build path
38 | def self.BUILD_PATH
39 | './Build'
40 | end
41 |
42 | #################
43 | #### KEYCHAIN ####
44 | #################
45 |
46 | # Keychain name
47 | def self.KEYCHAIN_NAME
48 | 'github_action_keychain'
49 | end
50 |
51 | def self.KEYCHAIN_PASSWORD
52 | 'password'
53 | end
54 |
55 | #################
56 | ### ARCHIVING ###
57 | #################
58 | # an staging environment scheme name
59 | def self.SCHEME_NAME_STAGING
60 | 'staging'
61 | end
62 |
63 | # a Production environment scheme name
64 | def self.SCHEME_NAME_PRODUCTION
65 | 'production'
66 | end
67 |
68 | # an staging product name
69 | def self.PRODUCT_NAME_STAGING
70 | '{{app_name.titleCase()}} Staging'
71 | end
72 |
73 | # a staging TestFlight product name
74 | def self.PRODUCT_NAME_STAGING_TEST_FLIGHT
75 | '{{app_name.titleCase()}} Staging'
76 | end
77 |
78 | # a Production product name
79 | def self.PRODUCT_NAME_PRODUCTION
80 | '{{app_name.titleCase()}}'
81 | end
82 |
83 | # a main target name
84 | def self.MAIN_TARGET_NAME
85 | 'Runner'
86 | end
87 | end
88 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/fastlane/Constants/Environments.rb:
--------------------------------------------------------------------------------
1 | class Environments
2 | def self.CI
3 | ENV['CI']
4 | end
5 |
6 | def self.MANUAL_VERSION
7 | ENV['MANUAL_VERSION']
8 | end
9 |
10 | def self.FASTLANE_USER
11 | ENV['FASTLANE_USER']
12 | end
13 |
14 | def self.TEAM_ID
15 | ENV['TEAM_ID']
16 | end
17 |
18 | def self.APP_STORE_KEY_ID
19 | ENV['APP_STORE_KEY_ID']
20 | end
21 |
22 | def self.APP_STORE_ISSUER_ID
23 | ENV['APP_STORE_ISSUER_ID']
24 | end
25 |
26 | def self.APP_STORE_CONNECT_API_KEY_BASE64
27 | ENV['APP_STORE_CONNECT_API_KEY_BASE64']
28 | end
29 |
30 | #################
31 | ### Firebase ###
32 | #################
33 |
34 | def self.FIREBASE_CLI_TOKEN
35 | ENV['FIREBASE_CLI_TOKEN']
36 | end
37 |
38 | def self.FIREBASE_APP_ID
39 | ENV['FIREBASE_APP_ID']
40 | end
41 |
42 | def self.FIREBASE_TESTER_GROUPS
43 | ENV['FIREBASE_DISTRIBUTION_TESTER_GROUPS']
44 | end
45 |
46 | def self.GITHUB_RUN_NUMBER
47 | ENV['GITHUB_RUN_NUMBER']
48 | end
49 |
50 | def self.RELEASE_NOTE_CONTENT
51 | ENV['RELEASE_NOTE_CONTENT']
52 | end
53 | end
54 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/fastlane/Gymfile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | clean(true)
4 | export_team_id(Environments.TEAM_ID)
5 | output_directory(Constants.BUILD_PATH) # .ipa
6 | build_path(Constants.BUILD_PATH) # .xcarchive is stored
7 | derived_data_path(Constants.DERIVED_DATA_PATH) # .app
8 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/fastlane/Managers/BuildManager.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class BuildManager
4 | def initialize(fastlane:)
5 | @fastlane = fastlane
6 | end
7 |
8 | def build_app_store(scheme, product_name, bundle_identifier, include_bitcode)
9 | @fastlane.gym(
10 | scheme: scheme,
11 | export_method: 'app-store',
12 | export_options: {
13 | provisioningProfiles: {
14 | @bundle_identifier_staging.to_s => "match AppStore #{bundle_identifier}"
15 | }
16 | },
17 | include_bitcode: include_bitcode,
18 | output_name: product_name
19 | )
20 | end
21 |
22 | def build_ad_hoc(scheme, product_name, bundle_identifier)
23 | @fastlane.gym(
24 | scheme: scheme,
25 | export_method: 'ad-hoc',
26 | export_options: {
27 | provisioningProfiles: {
28 | @bundle_identifier_staging.to_s => "match Adhoc #{bundle_identifier}"
29 | }
30 | },
31 | include_bitcode: false,
32 | output_name: product_name,
33 | disable_xcpretty: true
34 | )
35 | end
36 | end
37 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/fastlane/Managers/DistributionManager.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class DistributionManager
4 | def initialize(fastlane:, build_path:, firebase_token:)
5 | @fastlane = fastlane
6 | @build_path = build_path
7 | @firebase_token = firebase_token
8 | end
9 |
10 | def upload_to_testflight(product_name:, bundle_identifier:)
11 | @fastlane.pilot(
12 | ipa: "#{@build_path}/#{product_name}.ipa",
13 | app_identifier: bundle_identifier,
14 | notify_external_testers: false,
15 | skip_waiting_for_build_processing: true
16 | )
17 | end
18 |
19 | def upload_to_app_store_connect(product_name:, bundle_identifier:)
20 | @fastlane.deliver(
21 | ipa: "#{@build_path}/#{product_name}.ipa",
22 | app_identifier: bundle_identifier,
23 | force: true,
24 | skip_metadata: true,
25 | skip_screenshots: true,
26 | run_precheck_before_submit: false
27 | )
28 | end
29 |
30 | def upload_to_firebase(product_name:, firebase_app_id:, notes:, tester_groups:)
31 | ipa_path = "#{@build_path}/#{product_name}.ipa"
32 | @fastlane.firebase_app_distribution(
33 | app: firebase_app_id,
34 | ipa_path: ipa_path,
35 | groups: tester_groups,
36 | firebase_cli_token: @firebase_token,
37 | release_notes: notes
38 | )
39 | end
40 | end
41 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/fastlane/Managers/MatchManager.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class MatchManager
4 | def initialize(
5 | fastlane:,
6 | keychain_name:,
7 | keychain_password:,
8 | is_ci:
9 | )
10 | @fastlane = fastlane
11 | @keychain_name = keychain_name
12 | @keychain_password = keychain_password
13 | @is_ci = is_ci
14 | end
15 |
16 | def sync_adhoc_signing(app_identifier:)
17 | if @is_ci
18 | create_ci_keychain
19 | @fastlane.match(
20 | type: 'adhoc',
21 | keychain_name: @keychain_name,
22 | keychain_password: @keychain_password,
23 | app_identifier: app_identifier,
24 | readonly: true
25 | )
26 | else
27 | @fastlane.match(type: 'adhoc', app_identifier: app_identifier, readonly: true)
28 | end
29 | end
30 |
31 | def sync_app_store_signing(app_identifier:)
32 | if @is_ci
33 | create_ci_keychain
34 | @fastlane.match(
35 | type: 'appstore',
36 | keychain_name: @keychain_name,
37 | keychain_password: @keychain_password,
38 | app_identifier: app_identifier,
39 | readonly: true
40 | )
41 | else
42 | @fastlane.match(type: 'appstore', app_identifier: app_identifier, readonly: true)
43 | end
44 | end
45 |
46 | def create_ci_keychain
47 | @fastlane.create_keychain(
48 | name: @keychain_name,
49 | password: @keychain_password,
50 | default_keychain: true,
51 | unlock: true,
52 | timeout: 3600,
53 | lock_when_sleeps: false
54 | )
55 | end
56 | end
57 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/fastlane/Matchfile:
--------------------------------------------------------------------------------
1 | git_url("git@github.com:nimblehq/match-certificates.git")
2 |
3 | storage_mode("git")
4 |
5 | # type("appstore") # The default type, can be: appstore, adhoc, enterprise or development
6 |
7 | # app_identifier(["tools.fastlane.app", "tools.fastlane.app2"])
8 | # username("user@fastlane.tools") # Your Apple Developer Portal username
9 |
10 | # For all available options run `fastlane match --help`
11 | # Remove the # in the beginning of the line to enable the other options
12 |
13 | # The docs are available on https://docs.fastlane.tools/actions/match
14 | readonly(true)
15 | force(false)
16 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/ios/fastlane/Pluginfile:
--------------------------------------------------------------------------------
1 | # Autogenerated by fastlane
2 | #
3 | # Ensure this file is checked in to source control!
4 |
5 | gem 'fastlane-plugin-firebase_app_distribution'
6 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/l10n.yaml:
--------------------------------------------------------------------------------
1 | arb-dir: lib/l10n
2 | template-arb-file: app_en.arb
3 | output-localization-file: app_localizations.dart
4 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/lib/app/resources/app_colors.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class AppColors {
4 | static const Color nimblePrimaryBlue = Color(0xFF201547);
5 | }
6 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/lib/app/screens/home/home_view_model.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'package:{{project_name.snakeCase()}}/app/screens/home/home_view_state.dart';
3 | import 'package:{{project_name.snakeCase()}}/domain/usecases/base/base_use_case.dart';
4 | import 'package:{{project_name.snakeCase()}}/domain/usecases/get_users_use_case.dart';
5 | import 'package:{{project_name.snakeCase()}}/domain/models/user.dart';
6 | import 'package:flutter_riverpod/flutter_riverpod.dart';
7 |
8 | class HomeViewModel extends StateNotifier {
9 | final GetUsersUseCase _getUsersUseCase;
10 |
11 | HomeViewModel(
12 | this._getUsersUseCase,
13 | ) : super(const HomeViewState.init());
14 |
15 | final StreamController> _usersStream = StreamController();
16 |
17 | Stream> get usersStream => _usersStream.stream;
18 |
19 | Future getUsers() async {
20 | final result = await _getUsersUseCase.call();
21 | if (result is Success>) {
22 | _usersStream.add(result.value);
23 | } else {
24 | // TODO handle error
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/lib/app/screens/home/home_view_state.dart:
--------------------------------------------------------------------------------
1 | import 'package:freezed_annotation/freezed_annotation.dart';
2 |
3 | part 'home_view_state.freezed.dart';
4 |
5 | @freezed
6 | class HomeViewState with _$HomeViewState {
7 | const factory HomeViewState.init() = _Init;
8 | }
9 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/lib/data/local/secure_storage.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_secure_storage/flutter_secure_storage.dart';
2 | import 'package:injectable/injectable.dart';
3 |
4 | const _keyAccessToken = 'KEY_ACCESS_TOKEN';
5 |
6 | abstract class SecureStorage {
7 | Future get accessToken;
8 |
9 | Future storeAccessToken(String accessToken);
10 |
11 | Future clearAll();
12 | }
13 |
14 | @Singleton(as: SecureStorage)
15 | class SecureStorageImpl extends SecureStorage {
16 | final FlutterSecureStorage _storage;
17 |
18 | SecureStorageImpl(this._storage);
19 |
20 | @override
21 | Future get accessToken => _storage.read(key: _keyAccessToken);
22 |
23 | @override
24 | Future storeAccessToken(String accessToken) {
25 | return _storage.write(key: _keyAccessToken, value: accessToken);
26 | }
27 |
28 | @override
29 | Future clearAll() {
30 | return _storage.deleteAll();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/lib/data/remote/datasources/api_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:dio/dio.dart';
2 | import 'package:{{project_name.snakeCase()}}/data/remote/models/responses/user_response.dart';
3 | import 'package:retrofit/retrofit.dart';
4 |
5 | part 'api_service.g.dart';
6 |
7 | abstract class BaseApiService {
8 | Future> getUsers();
9 | }
10 |
11 | @RestApi()
12 | abstract class ApiService extends BaseApiService {
13 | factory ApiService(Dio dio, {String baseUrl}) = _ApiService;
14 |
15 | // TODO add API endpoint
16 | @override
17 | @GET('users')
18 | Future> getUsers();
19 | }
20 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/lib/data/remote/models/requests/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nimblehq/flutter-templates/7ea62bed55bcd0424b915ef6d4796911ad62d4cc/bricks/template/__brick__/lib/data/remote/models/requests/.keep
--------------------------------------------------------------------------------
/bricks/template/__brick__/lib/data/remote/models/responses/user_response.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 | import 'package:{{project_name.snakeCase()}}/domain/models/user.dart';
3 |
4 | part 'user_response.g.dart';
5 |
6 | @JsonSerializable()
7 | class UserResponse {
8 | final String email;
9 | final String username;
10 |
11 | UserResponse(this.email, this.username);
12 |
13 | factory UserResponse.fromJson(Map json) =>
14 | _$UserResponseFromJson(json);
15 |
16 | Map toJson() => _$UserResponseToJson(this);
17 |
18 | User toUser() => User(
19 | email: email,
20 | username: username,
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/lib/data/repositories/credential_repository_impl.dart:
--------------------------------------------------------------------------------
1 | import 'package:{{project_name.snakeCase()}}/data/remote/datasources/api_service.dart';
2 | import 'package:{{project_name.snakeCase()}}/domain/exceptions/network_exceptions.dart';
3 | import 'package:{{project_name.snakeCase()}}/domain/models/user.dart';
4 | import 'package:{{project_name.snakeCase()}}/domain/repositories/credential_repository.dart';
5 | import 'package:injectable/injectable.dart';
6 |
7 | @LazySingleton(as: CredentialRepository)
8 | class CredentialRepositoryImpl extends CredentialRepository {
9 | final BaseApiService _apiService;
10 |
11 | CredentialRepositoryImpl(this._apiService);
12 |
13 | @override
14 | Future> getUsers() async {
15 | try {
16 | final userResponses = await _apiService.getUsers();
17 | return userResponses
18 | .map((userResponse) => userResponse.toUser())
19 | .toList();
20 | } catch (exception) {
21 | throw NetworkExceptions.fromDioException(exception);
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/lib/di/di.dart:
--------------------------------------------------------------------------------
1 | import 'package:get_it/get_it.dart';
2 | import 'package:injectable/injectable.dart';
3 |
4 | import 'di.config.dart';
5 |
6 | final GetIt getIt = GetIt.instance;
7 |
8 | @injectableInit
9 | Future configureInjection() async => getIt.init();
10 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/lib/di/interceptor/app_interceptor.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:dio/dio.dart';
4 |
5 | class AppInterceptor extends Interceptor {
6 | final bool _requireAuthenticate;
7 | final Dio _dio;
8 |
9 | AppInterceptor(
10 | this._requireAuthenticate,
11 | this._dio,
12 | );
13 |
14 | @override
15 | Future onRequest(
16 | RequestOptions options, RequestInterceptorHandler handler) async {
17 | if (_requireAuthenticate) {
18 | // TODO header authorization here
19 | // options.headers
20 | // .putIfAbsent(HEADER_AUTHORIZATION, () => "");
21 | }
22 | return super.onRequest(options, handler);
23 | }
24 |
25 | @override
26 | void onError(DioError err, ErrorInterceptorHandler handler) {
27 | final statusCode = err.response?.statusCode;
28 | if ((statusCode == HttpStatus.forbidden ||
29 | statusCode == HttpStatus.unauthorized) &&
30 | _requireAuthenticate) {
31 | _doRefreshToken(err, handler);
32 | } else {
33 | handler.next(err);
34 | }
35 | }
36 |
37 | Future _doRefreshToken(
38 | DioError err,
39 | ErrorInterceptorHandler handler,
40 | ) async {
41 | try {
42 | // TODO Request new token
43 |
44 | // if (result is Success) {
45 | // TODO Update new token header
46 | // err.requestOptions.headers[_headerAuthorization] = newToken;
47 |
48 | // Create request with new access token
49 | final options = Options(
50 | method: err.requestOptions.method,
51 | headers: err.requestOptions.headers);
52 | final newRequest = await _dio.request(
53 | "${err.requestOptions.baseUrl}${err.requestOptions.path}",
54 | options: options,
55 | data: err.requestOptions.data,
56 | queryParameters: err.requestOptions.queryParameters);
57 | handler.resolve(newRequest);
58 | // } else {
59 | // handler.next(err);
60 | // }
61 | } catch (exception) {
62 | if (exception is DioError) {
63 | handler.next(exception);
64 | } else {
65 | handler.next(err);
66 | }
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/lib/di/module/network_module.dart:
--------------------------------------------------------------------------------
1 | import 'package:{{project_name.snakeCase()}}/data/remote/datasources/api_service.dart';
2 | import 'package:{{project_name.snakeCase()}}/env.dart';
3 | import 'package:{{project_name.snakeCase()}}/di/provider/dio_provider.dart';
4 | import 'package:injectable/injectable.dart';
5 |
6 | @module
7 | abstract class NetworkModule {
8 | @Singleton(as: BaseApiService)
9 | ApiService provideApiService(DioProvider dioProvider) {
10 | return ApiService(
11 | dioProvider.getDio(),
12 | baseUrl: Env.restApiEndpoint,
13 | );
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/lib/di/module/storage_module.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_secure_storage/flutter_secure_storage.dart';
2 | import 'package:injectable/injectable.dart';
3 |
4 | @module
5 | abstract class StorageModule {
6 | @singleton
7 | FlutterSecureStorage get flutterSecureStorage => const FlutterSecureStorage(
8 | aOptions: AndroidOptions(encryptedSharedPreferences: true));
9 | }
10 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/lib/di/provider/dio_provider.dart:
--------------------------------------------------------------------------------
1 | import 'package:dio/dio.dart';
2 | import 'package:flutter/foundation.dart';
3 | import 'package:{{project_name.snakeCase()}}/di/interceptor/app_interceptor.dart';
4 | import 'package:injectable/injectable.dart';
5 |
6 | const String headerContentType = 'Content-Type';
7 | const String defaultContentType = 'application/json; charset=utf-8';
8 |
9 | @Singleton()
10 | class DioProvider {
11 | Dio? _dio;
12 |
13 | Dio getDio() {
14 | _dio ??= _createDio();
15 | return _dio!;
16 | }
17 |
18 | Dio _createDio({bool requireAuthenticate = false}) {
19 | final dio = Dio();
20 | final appInterceptor = AppInterceptor(
21 | requireAuthenticate,
22 | dio,
23 | );
24 | final interceptors = [];
25 | interceptors.add(appInterceptor);
26 | if (!kReleaseMode) {
27 | interceptors.add(LogInterceptor(
28 | request: true,
29 | responseBody: true,
30 | requestBody: true,
31 | requestHeader: true,
32 | ));
33 | }
34 |
35 | return dio
36 | ..options.connectTimeout = const Duration(seconds: 3000)
37 | ..options.receiveTimeout = const Duration(seconds: 5000)
38 | ..options.headers = {headerContentType: defaultContentType}
39 | ..interceptors.addAll(interceptors);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/bricks/template/__brick__/lib/domain/models/user.dart:
--------------------------------------------------------------------------------
1 | import 'package:equatable/equatable.dart';
2 |
3 | class User extends Equatable {
4 | final String email;
5 | final String username;
6 |
7 | const User({
8 | required this.email,
9 | required this.username,
10 | });
11 |
12 | @override
13 | bool? get stringify => true;
14 |
15 | @override
16 | List