├── .fvm ├── flutter_sdk └── fvm_config.json ├── .github ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── build.yml ├── .gitignore ├── .metadata ├── .run ├── production.run.xml └── staging.run.xml ├── .vscode └── launch.json ├── CONTRIBUTING.md ├── README.md ├── analysis_options.yaml ├── android ├── .gitignore ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ │ └── ps │ │ │ │ └── app │ │ │ │ └── bond │ │ │ │ └── MainActivity.kt │ │ └── res │ │ │ ├── drawable-hdpi │ │ │ └── ic_stat.png │ │ │ ├── drawable-mdpi │ │ │ └── ic_stat.png │ │ │ ├── drawable-v21 │ │ │ └── launch_background.xml │ │ │ ├── drawable-xhdpi │ │ │ └── ic_stat.png │ │ │ ├── drawable-xxhdpi │ │ │ └── ic_stat.png │ │ │ ├── drawable-xxxhdpi │ │ │ └── ic_stat.png │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── mipmap-hdpi │ │ │ └── launcher_icon.png │ │ │ ├── mipmap-mdpi │ │ │ └── launcher_icon.png │ │ │ ├── mipmap-xhdpi │ │ │ └── launcher_icon.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── launcher_icon.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── launcher_icon.png │ │ │ ├── values-night │ │ │ └── styles.xml │ │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ ├── production │ │ ├── google-services.json │ │ └── res │ │ │ ├── drawable-hdpi │ │ │ ├── ic_launcher_foreground.png │ │ │ └── splash.png │ │ │ ├── drawable-mdpi │ │ │ ├── ic_launcher_foreground.png │ │ │ └── splash.png │ │ │ ├── drawable-v21 │ │ │ ├── background.png │ │ │ └── launch_background.xml │ │ │ ├── drawable-xhdpi │ │ │ ├── ic_launcher_foreground.png │ │ │ └── splash.png │ │ │ ├── drawable-xxhdpi │ │ │ ├── ic_launcher_foreground.png │ │ │ └── splash.png │ │ │ ├── drawable-xxxhdpi │ │ │ ├── ic_launcher_foreground.png │ │ │ └── splash.png │ │ │ ├── drawable │ │ │ ├── background.png │ │ │ └── launch_background.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ └── launcher_icon.xml │ │ │ ├── mipmap-hdpi │ │ │ └── launcher_icon.png │ │ │ ├── mipmap-mdpi │ │ │ └── launcher_icon.png │ │ │ ├── mipmap-xhdpi │ │ │ └── launcher_icon.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── launcher_icon.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── launcher_icon.png │ │ │ ├── values-v31 │ │ │ └── styles.xml │ │ │ └── values │ │ │ ├── colors.xml │ │ │ └── styles.xml │ │ ├── profile │ │ └── AndroidManifest.xml │ │ └── staging │ │ ├── google-services.json │ │ └── res │ │ ├── drawable-hdpi │ │ ├── ic_launcher_foreground.png │ │ └── splash.png │ │ ├── drawable-mdpi │ │ ├── ic_launcher_foreground.png │ │ └── splash.png │ │ ├── drawable-v21 │ │ ├── background.png │ │ └── launch_background.xml │ │ ├── drawable-xhdpi │ │ ├── ic_launcher_foreground.png │ │ └── splash.png │ │ ├── drawable-xxhdpi │ │ ├── ic_launcher_foreground.png │ │ └── splash.png │ │ ├── drawable-xxxhdpi │ │ ├── ic_launcher_foreground.png │ │ └── splash.png │ │ ├── drawable │ │ ├── background.png │ │ └── launch_background.xml │ │ ├── mipmap-anydpi-v26 │ │ └── launcher_icon.xml │ │ ├── mipmap-hdpi │ │ └── launcher_icon.png │ │ ├── mipmap-mdpi │ │ └── launcher_icon.png │ │ ├── mipmap-xhdpi │ │ └── launcher_icon.png │ │ ├── mipmap-xxhdpi │ │ └── launcher_icon.png │ │ ├── mipmap-xxxhdpi │ │ └── launcher_icon.png │ │ ├── values-v31 │ │ └── styles.xml │ │ └── values │ │ ├── colors.xml │ │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── assets ├── icons │ ├── app-icon-staging.png │ ├── app-icon.png │ ├── close.svg │ └── share.svg └── images │ ├── app_logo.svg │ ├── force_update.png │ ├── home_bond.png │ ├── home_bond_arabic.png │ ├── home_bond_arabic_dark.png │ ├── home_bond_dark.png │ ├── splash_logo-staging.png │ └── splash_logo.png ├── env.example.json ├── firebase.json ├── firebase_config.bash ├── flutter_launcher_icons-production.yaml ├── flutter_launcher_icons-staging.yaml ├── flutter_native_splash-production.yaml ├── flutter_native_splash-staging.yaml ├── ios ├── .gitignore ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Podfile ├── Podfile.lock ├── Production │ └── GoogleService-Info.plist ├── 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-production.appiconset │ │ │ ├── AppIcon-production-1024x1024@1x.png │ │ │ ├── AppIcon-production-20x20@1x.png │ │ │ ├── AppIcon-production-20x20@2x.png │ │ │ ├── AppIcon-production-20x20@3x.png │ │ │ ├── AppIcon-production-29x29@1x.png │ │ │ ├── AppIcon-production-29x29@2x.png │ │ │ ├── AppIcon-production-29x29@3x.png │ │ │ ├── AppIcon-production-40x40@1x.png │ │ │ ├── AppIcon-production-40x40@2x.png │ │ │ ├── AppIcon-production-40x40@3x.png │ │ │ ├── AppIcon-production-50x50@1x.png │ │ │ ├── AppIcon-production-50x50@2x.png │ │ │ ├── AppIcon-production-57x57@1x.png │ │ │ ├── AppIcon-production-57x57@2x.png │ │ │ ├── AppIcon-production-60x60@2x.png │ │ │ ├── AppIcon-production-60x60@3x.png │ │ │ ├── AppIcon-production-72x72@1x.png │ │ │ ├── AppIcon-production-72x72@2x.png │ │ │ ├── AppIcon-production-76x76@1x.png │ │ │ ├── AppIcon-production-76x76@2x.png │ │ │ ├── AppIcon-production-83.5x83.5@2x.png │ │ │ └── Contents.json │ │ ├── AppIcon-staging.appiconset │ │ │ ├── AppIcon-staging-1024x1024@1x.png │ │ │ ├── AppIcon-staging-20x20@1x.png │ │ │ ├── AppIcon-staging-20x20@2x.png │ │ │ ├── AppIcon-staging-20x20@3x.png │ │ │ ├── AppIcon-staging-29x29@1x.png │ │ │ ├── AppIcon-staging-29x29@2x.png │ │ │ ├── AppIcon-staging-29x29@3x.png │ │ │ ├── AppIcon-staging-40x40@1x.png │ │ │ ├── AppIcon-staging-40x40@2x.png │ │ │ ├── AppIcon-staging-40x40@3x.png │ │ │ ├── AppIcon-staging-50x50@1x.png │ │ │ ├── AppIcon-staging-50x50@2x.png │ │ │ ├── AppIcon-staging-57x57@1x.png │ │ │ ├── AppIcon-staging-57x57@2x.png │ │ │ ├── AppIcon-staging-60x60@2x.png │ │ │ ├── AppIcon-staging-60x60@3x.png │ │ │ ├── AppIcon-staging-72x72@1x.png │ │ │ ├── AppIcon-staging-72x72@2x.png │ │ │ ├── AppIcon-staging-76x76@1x.png │ │ │ ├── AppIcon-staging-76x76@2x.png │ │ │ ├── AppIcon-staging-83.5x83.5@2x.png │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── LaunchBackgroundProduction.imageset │ │ │ ├── Contents.json │ │ │ └── background.png │ │ ├── LaunchBackgroundStaging.imageset │ │ │ ├── Contents.json │ │ │ └── background.png │ │ ├── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ │ ├── LaunchImageProduction.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ └── LaunchImage@3x.png │ │ └── LaunchImageStaging.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ └── LaunchImage@3x.png │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ ├── LaunchScreenProduction.storyboard │ │ ├── LaunchScreenStaging.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ └── Runner-Bridging-Header.h ├── Staging │ └── GoogleService-Info.plist ├── firebase_app_id_file_production.json ├── firebase_app_id_file_staging.json ├── production │ └── GoogleService-Info.plist └── staging │ └── GoogleService-Info.plist ├── l10n.yaml ├── lib ├── app │ ├── app.dart │ ├── app_run_tasks.dart │ ├── default_firebase_options.dart │ └── routes.dart ├── bond_app.dart ├── config │ ├── analytics.dart │ ├── api.dart │ ├── cache.dart │ ├── configs.dart │ ├── environments.dart │ └── notification.dart ├── core │ ├── app_analytics.dart │ ├── app_analytics_providers │ │ └── firebase_analytics_provider.dart │ ├── app_localizations.dart │ ├── app_notification_providers.dart │ ├── app_review.dart │ ├── app_theme.dart │ ├── app_utils.dart │ ├── app_widgets.dart │ ├── cache │ │ └── secure_storage_cache_driver.dart │ ├── localizations │ │ └── app_localizations_extension.dart │ ├── notifications │ │ ├── notification_center_remote_data_source.dart │ │ └── push_notifications_providers │ │ │ └── firebase_messaging_push_notification_provider.dart │ ├── resources │ │ ├── app_assets.dart │ │ └── app_icons.dart │ ├── route_helpers.dart │ ├── route_helpers │ │ └── modal_bottom_sheet_page.dart │ ├── theme │ │ ├── app_dark_theme_data.dart │ │ ├── app_light_theme_data.dart │ │ └── app_text_theme.dart │ ├── utils │ │ └── device_info.dart │ └── widgets │ │ ├── app_button.dart │ │ └── bond_pop_menu │ │ ├── bond_pop_menu_button.dart │ │ └── bond_popup_menu_item.dart ├── features │ ├── app │ │ ├── app_providers.dart │ │ └── notifiers │ │ │ ├── local_notifier.dart │ │ │ └── theme_notifier.dart │ ├── auth │ │ ├── auth.dart │ │ ├── auth_service_provider.dart │ │ ├── data │ │ │ ├── api.dart │ │ │ ├── errors │ │ │ │ ├── validation_error.dart │ │ │ │ └── validation_error.g.dart │ │ │ ├── events │ │ │ │ ├── sign_in_event.dart │ │ │ │ ├── sign_out_event.dart │ │ │ │ └── sign_up_event.dart │ │ │ └── models │ │ │ │ ├── user.dart │ │ │ │ ├── user.g.dart │ │ │ │ ├── user_meta.dart │ │ │ │ └── user_meta.g.dart │ │ ├── presentation │ │ │ ├── login_page.dart │ │ │ ├── providers │ │ │ │ ├── login_form_provider.dart │ │ │ │ └── register_form_provider.dart │ │ │ ├── register_page.dart │ │ │ └── views │ │ │ │ ├── login │ │ │ │ ├── login_form.dart │ │ │ │ └── new_account_view.dart │ │ │ │ └── register │ │ │ │ └── register_form.dart │ │ └── routes.dart │ ├── main │ │ ├── presentation │ │ │ └── main_page.dart │ │ └── routes.dart │ ├── more │ │ └── presentation │ │ │ └── more_page.dart │ ├── notification │ │ ├── presentations │ │ │ └── ui │ │ │ │ ├── notifications_page.dart │ │ │ │ └── widgets │ │ │ │ ├── badge_unread_notification.dart │ │ │ │ ├── header_title_image.dart │ │ │ │ └── notification_item.dart │ │ └── routes.dart │ ├── post │ │ ├── data │ │ │ ├── api.dart │ │ │ └── models │ │ │ │ ├── author.dart │ │ │ │ ├── post.dart │ │ │ │ ├── post.g.dart │ │ │ │ └── urls.dart │ │ ├── post_service_provider.dart │ │ ├── presentations │ │ │ ├── post_details_page.dart │ │ │ ├── posts_page.dart │ │ │ ├── providers │ │ │ │ ├── list_state.dart │ │ │ │ ├── post_provider.dart │ │ │ │ └── posts_provider.dart │ │ │ └── views │ │ │ │ ├── home_app_bar.dart │ │ │ │ ├── post_item.dart │ │ │ │ └── share_button.dart │ │ └── routes.dart │ └── update_app │ │ ├── data │ │ ├── models │ │ │ ├── current_version.dart │ │ │ ├── platform_version.dart │ │ │ ├── platform_version.g.dart │ │ │ └── update_app_default_value.dart │ │ └── update_app_service.dart │ │ ├── presentations │ │ └── page │ │ │ ├── soft_update_page.dart │ │ │ └── update_app_page.dart │ │ └── routes.dart ├── firebase_options_production.dart ├── firebase_options_staging.dart ├── l10n │ ├── app_ar.arb │ └── app_en.arb ├── main.dart └── providers │ ├── analytics_service_provider.dart │ ├── api_service_provider.dart │ ├── app_service_provider.dart │ ├── cache_service_provider.dart │ ├── firebase_service_provider.dart │ ├── forms_service_provider.dart │ └── notifications_service_provider.dart ├── macos ├── .gitignore ├── Flutter │ ├── Flutter-Debug.xcconfig │ ├── Flutter-Release.xcconfig │ └── GeneratedPluginRegistrant.swift ├── Podfile ├── Podfile.lock ├── Production │ └── GoogleService-Info.plist ├── Runner.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon-production.appiconset │ │ │ ├── Contents.json │ │ │ ├── app_icon_1024.png │ │ │ ├── app_icon_128.png │ │ │ ├── app_icon_16.png │ │ │ ├── app_icon_256.png │ │ │ ├── app_icon_32.png │ │ │ ├── app_icon_512.png │ │ │ └── app_icon_64.png │ │ ├── AppIcon-staging.appiconset │ │ │ ├── Contents.json │ │ │ ├── app_icon_1024.png │ │ │ ├── app_icon_128.png │ │ │ ├── app_icon_16.png │ │ │ ├── app_icon_256.png │ │ │ ├── app_icon_32.png │ │ │ ├── app_icon_512.png │ │ │ └── app_icon_64.png │ │ └── Contents.json │ ├── Base.lproj │ │ └── MainMenu.xib │ ├── Configs │ │ ├── AppInfo.xcconfig │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── Warnings.xcconfig │ ├── DebugProfile.entitlements │ ├── Info.plist │ ├── MainFlutterWindow.swift │ ├── Release.entitlements │ └── RunnerProfile Staging.entitlements ├── Staging │ └── GoogleService-Info.plist ├── firebase_app_id_file.json ├── production │ └── GoogleService-Info.plist └── staging │ └── GoogleService-Info.plist ├── pubspec.lock ├── pubspec.yaml ├── test └── example_test.dart └── web ├── favicon.png ├── icons ├── Icon-192.png ├── Icon-512.png ├── Icon-maskable-192.png └── Icon-maskable-512.png ├── index.html └── manifest.json /.fvm/flutter_sdk: -------------------------------------------------------------------------------- 1 | D:/Users/salahamassi/fvm/versions/3.10.4 -------------------------------------------------------------------------------- /.fvm/fvm_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "flutterSdkVersion": "3.19.0", 3 | "flavors": {} 4 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 9 | 10 | ## Description 11 | 12 | 13 | ## Steps to Reproduce 14 | 15 | 16 | 1. Step 1 17 | 2. Step 2 18 | 3. ... 19 | 20 | ## Expected Behavior 21 | 22 | 23 | ## Actual Behavior 24 | 25 | 26 | ## Screenshots/Code Snippets 27 | 28 | 29 | ## Version Info 30 | Please paste the output of running `flutter doctor -v` here (available from the command 31 | line or from `Tools > Flutter > Flutter Doctor`). It will provide the version of the 32 | Flutter framework as well as of the IntelliJ plugin. 33 | | | | 34 | |-------------------------|---------------------------| 35 | | Flutter version: | | 36 | | Android toolchain: | | 37 | | Xcode for iOS/macOS: | | 38 | | Chrome for web: | | 39 | | Android Studio: | | 40 | | VS Code: | | 41 | | Connected devices: | | 42 | | Issues summary: | | 43 | 44 | ## Related Issues/PRs 45 | 46 | 47 | ## Possible Solution 48 | 49 | 50 | ## Additional Information 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Pull Request Description 2 | 3 | **Summary:** [Provide a brief summary of the changes introduced by this pull request.] 4 | 5 | **Related Issue:** [Specify the issue number or describe the problem that this pull request addresses.] 6 | 7 | ## Proposed Changes 8 | 9 | **Description:** [Provide a detailed description of the changes made in this pull request.] 10 | 11 | **Motivation and Context:** [Explain the motivation behind these changes and the impact they have on the project.] 12 | 13 | ## Checklist 14 | 15 | Please review and check the following items before submitting your pull request: 16 | 17 | - [ ] I have executed the command `flutter pub run build_runner build` to generate the necessary auto routes files. 18 | - [ ] I have verified that the auto route generation did not introduce any errors or warnings. 19 | - [ ] I have tested the changes locally and they are functioning as expected. 20 | - [ ] My code follows the project's coding style and guidelines. 21 | - [ ] All existing and new tests are passing. 22 | - [ ] I have added necessary documentation or updated existing documentation (if applicable). 23 | - [ ] I have added appropriate unit tests or updated existing tests (if applicable). 24 | - [ ] My commits are descriptive and follow the project's commit message conventions. 25 | - [ ] I have rebased my branch on the latest `main` branch. 26 | 27 | ## Screenshots (if applicable) 28 | 29 | **Before:** 30 | [Add screenshots or GIFs showing the state before the changes (if applicable).] 31 | 32 | **After:** 33 | [Add screenshots or GIFs showing the state after the changes (if applicable).] 34 | 35 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | jobs: 10 | build-and-test: 11 | 12 | runs-on: macos-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v3 16 | - uses: actions/setup-java@v2 17 | with: 18 | distribution: 'zulu' 19 | java-version: '11' 20 | - uses: subosito/flutter-action@v2 21 | with: 22 | channel: 'stable' 23 | cache: true 24 | 25 | - name: Create env file 26 | env: 27 | API_BASE_URL: ${{ secrets.API_BASE_URL }} 28 | CONNECT_TIMEOUT: 100000 29 | SEND_TIMEOUT: 1000000 30 | RECEIVE_TIMEOUT: 1000000 31 | RECEIVE_DATA_WHEN_STATUS_ERROR: true 32 | run: | 33 | echo "{" >> .env.json 34 | echo "API_BASE_URL:$API_BASE_URL," >> .env.json 35 | echo "CONNECT_TIMEOUT:$CONNECT_TIMEOUT," >> .env.json 36 | echo "SEND_TIMEOUT:$SEND_TIMEOUT," >> .env.json 37 | echo "RECEIVE_TIMEOUT:$RECEIVE_TIMEOUT," >> .env.json 38 | echo "RECEIVE_DATA_WHEN_STATUS_ERROR:$RECEIVE_DATA_WHEN_STATUS_ERROR" >> .env.json 39 | echo "}" >> .env.json 40 | 41 | - name: Create Staging env file 42 | env: 43 | API_BASE_URL: ${{ secrets.STAGING_API_BASE_URL}} 44 | CONNECT_TIMEOUT: 100000 45 | SEND_TIMEOUT: 1000000 46 | RECEIVE_TIMEOUT: 1000000 47 | RECEIVE_DATA_WHEN_STATUS_ERROR: true 48 | run: | 49 | echo "{" >> .env.staging.json 50 | echo "API_BASE_URL:$API_BASE_URL," >> .env.staging.json 51 | echo "CONNECT_TIMEOUT:$CONNECT_TIMEOUT," >> .env.staging.json 52 | echo "SEND_TIMEOUT:$SEND_TIMEOUT," >> .env.staging.json 53 | echo "RECEIVE_TIMEOUT:$RECEIVE_TIMEOUT," >> .env.staging.json 54 | echo "RECEIVE_DATA_WHEN_STATUS_ERROR:$RECEIVE_DATA_WHEN_STATUS_ERROR" >> .env.staging.json 55 | echo "}" >> .env.staging.json 56 | 57 | - name: Install Dependencies 58 | run: flutter pub get 59 | 60 | - name: Analyze 61 | run: flutter analyze lib 62 | 63 | - name: Test 64 | run: flutter test -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | 48 | .mason 49 | mason-lock.json 50 | env.json 51 | env.staging.json 52 | /env.staging.json 53 | -------------------------------------------------------------------------------- /.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. 5 | 6 | version: 7 | revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66 8 | channel: stable 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66 17 | base_revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66 18 | - platform: web 19 | create_revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66 20 | base_revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66 21 | 22 | # User provided section 23 | 24 | # List of Local paths (relative to this file) that should be 25 | # ignored by the migrate tool. 26 | # 27 | # Files that are not part of the templates will be ignored by default. 28 | unmanaged_files: 29 | - 'lib/main.dart' 30 | - 'ios/Runner.xcodeproj/project.pbxproj' 31 | -------------------------------------------------------------------------------- /.run/production.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /.run/staging.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Flutter: Run production", 6 | "request": "launch", 7 | "type": "dart", 8 | "program": "${workspaceFolder}/lib/main.dart", 9 | "args": [ 10 | "--flavor", "Production", 11 | "--dart-define-from-file=env.json" 12 | ] 13 | }, 14 | { 15 | "name": "Flutter: Run staging", 16 | "request": "launch", 17 | "type": "dart", 18 | "program": "${workspaceFolder}/lib/main.dart", 19 | "args": [ 20 | "--flavor", "Staging", 21 | "--dart-define-from-file=env.staging.json" 22 | ] 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 2 | Please review our Contributing Guidelines for detailed instructions on contributing to Flutter Bond. We encourage contributions in the form of bug fixes, new features, and improvements to the codebase. 3 | 4 | ### Code Style 5 | 6 | We follow the coding guidelines outlined in the Flutter Style Guide. Consistent code style helps maintain readability and collaboration. 7 | 8 | ### Submitting a Pull Request 9 | 10 | When you're ready to submit your contribution: 11 | 12 | 1. **Create a New Branch:** Create a new branch for your changes: 13 | 14 | \```bash 15 | git checkout -b your-branch-name 16 | \``` 17 | 18 | 2. **Make Changes and Commit:** Make your changes, commit them with a meaningful message: 19 | 20 | \```bash 21 | git add . 22 | git commit -m "Your detailed commit message" 23 | \``` 24 | 25 | 3. **Push to Your Fork:** Push your changes to your forked repository: 26 | 27 | \```bash 28 | git push origin your-branch-name 29 | \``` 30 | 31 | 4. **Open a Pull Request:** Visit the original Flutter Bond repository and open a new pull request. We'll review your changes and provide feedback. 32 | EOF -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 14 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 29 | 32 | 33 | 36 | 37 | 40 | 41 | 44 | 45 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/ps/app/bond/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package ps.app.bond 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-hdpi/ic_stat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/main/res/drawable-hdpi/ic_stat.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-mdpi/ic_stat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/main/res/drawable-mdpi/ic_stat.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xhdpi/ic_stat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/main/res/drawable-xhdpi/ic_stat.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxhdpi/ic_stat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/main/res/drawable-xxhdpi/ic_stat.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxxhdpi/ic_stat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/main/res/drawable-xxxhdpi/ic_stat.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/main/res/mipmap-hdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/main/res/mipmap-mdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #322d78 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Bond 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/production/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "1077101979846", 4 | "project_id": "flutter-bond-8ae02", 5 | "storage_bucket": "flutter-bond-8ae02.appspot.com" 6 | }, 7 | "client": [ 8 | { 9 | "client_info": { 10 | "mobilesdk_app_id": "1:1077101979846:android:00afb3c0b4d1b8ae3a0fc7", 11 | "android_client_info": { 12 | "package_name": "ps.app.bond" 13 | } 14 | }, 15 | "oauth_client": [], 16 | "api_key": [ 17 | { 18 | "current_key": "AIzaSyCabR-NAV535DJ8NjcQhhllO3qR11q7mIM" 19 | } 20 | ], 21 | "services": { 22 | "appinvite_service": { 23 | "other_platform_oauth_client": [] 24 | } 25 | } 26 | } 27 | ], 28 | "configuration_version": "1" 29 | } -------------------------------------------------------------------------------- /android/app/src/production/res/drawable-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/production/res/drawable-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/production/res/drawable-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/production/res/drawable-hdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/production/res/drawable-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/production/res/drawable-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/production/res/drawable-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/production/res/drawable-mdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/production/res/drawable-v21/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/production/res/drawable-v21/background.png -------------------------------------------------------------------------------- /android/app/src/production/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/app/src/production/res/drawable-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/production/res/drawable-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/production/res/drawable-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/production/res/drawable-xhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/production/res/drawable-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/production/res/drawable-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/production/res/drawable-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/production/res/drawable-xxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/production/res/drawable-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/production/res/drawable-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/production/res/drawable-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/production/res/drawable-xxxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/production/res/drawable/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/production/res/drawable/background.png -------------------------------------------------------------------------------- /android/app/src/production/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/app/src/production/res/mipmap-anydpi-v26/launcher_icon.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /android/app/src/production/res/mipmap-hdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/production/res/mipmap-hdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/production/res/mipmap-mdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/production/res/mipmap-mdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/production/res/mipmap-xhdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/production/res/mipmap-xhdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/production/res/mipmap-xxhdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/production/res/mipmap-xxhdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/production/res/mipmap-xxxhdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/production/res/mipmap-xxxhdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/production/res/values-v31/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/production/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ffffff 4 | -------------------------------------------------------------------------------- /android/app/src/production/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 18 | 21 | 22 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/staging/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "390157281889", 4 | "project_id": "flutter-bond-staging-7dd42", 5 | "storage_bucket": "flutter-bond-staging-7dd42.appspot.com" 6 | }, 7 | "client": [ 8 | { 9 | "client_info": { 10 | "mobilesdk_app_id": "1:390157281889:android:bf4d85c3c9a51044ab9820", 11 | "android_client_info": { 12 | "package_name": "ps.app.bond.staging" 13 | } 14 | }, 15 | "oauth_client": [], 16 | "api_key": [ 17 | { 18 | "current_key": "AIzaSyA-AjzVELSPttuIp2k6kydk0RX-DORqPpg" 19 | } 20 | ], 21 | "services": { 22 | "appinvite_service": { 23 | "other_platform_oauth_client": [] 24 | } 25 | } 26 | } 27 | ], 28 | "configuration_version": "1" 29 | } -------------------------------------------------------------------------------- /android/app/src/staging/res/drawable-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/staging/res/drawable-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/staging/res/drawable-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/staging/res/drawable-hdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/staging/res/drawable-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/staging/res/drawable-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/staging/res/drawable-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/staging/res/drawable-mdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/staging/res/drawable-v21/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/staging/res/drawable-v21/background.png -------------------------------------------------------------------------------- /android/app/src/staging/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/app/src/staging/res/drawable-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/staging/res/drawable-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/staging/res/drawable-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/staging/res/drawable-xhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/staging/res/drawable-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/staging/res/drawable-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/staging/res/drawable-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/staging/res/drawable-xxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/staging/res/drawable-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/staging/res/drawable-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/staging/res/drawable-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/staging/res/drawable-xxxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/staging/res/drawable/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/staging/res/drawable/background.png -------------------------------------------------------------------------------- /android/app/src/staging/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/app/src/staging/res/mipmap-anydpi-v26/launcher_icon.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /android/app/src/staging/res/mipmap-hdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/staging/res/mipmap-hdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/staging/res/mipmap-mdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/staging/res/mipmap-mdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/staging/res/mipmap-xhdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/staging/res/mipmap-xhdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/staging/res/mipmap-xxhdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/staging/res/mipmap-xxhdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/staging/res/mipmap-xxxhdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/android/app/src/staging/res/mipmap-xxxhdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/staging/res/values-v31/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/staging/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #EB5C6C 4 | -------------------------------------------------------------------------------- /android/app/src/staging/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 18 | 21 | 22 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | allprojects { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | } 7 | 8 | rootProject.buildDir = '../build' 9 | subprojects { 10 | project.buildDir = "${rootProject.buildDir}/${project.name}" 11 | } 12 | subprojects { 13 | project.evaluationDependsOn(':app') 14 | } 15 | 16 | tasks.register("clean", Delete) { 17 | delete rootProject.buildDir 18 | } 19 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx4608m 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip 6 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | def flutterSdkPath = { 3 | def properties = new Properties() 4 | file("local.properties").withInputStream { properties.load(it) } 5 | def flutterSdkPath = properties.getProperty("flutter.sdk") 6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 7 | return flutterSdkPath 8 | } 9 | settings.ext.flutterSdkPath = flutterSdkPath() 10 | 11 | includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") 12 | 13 | repositories { 14 | google() 15 | mavenCentral() 16 | gradlePluginPortal() 17 | } 18 | } 19 | 20 | plugins { 21 | id "dev.flutter.flutter-plugin-loader" version "1.0.0" 22 | id "com.android.application" version "8.1.0" apply false 23 | id "org.jetbrains.kotlin.android" version "1.8.22" apply false 24 | id "com.google.gms.google-services" version "4.4.0" apply false 25 | id "com.google.firebase.crashlytics" version "2.9.9" apply false 26 | } 27 | 28 | include ":app" 29 | -------------------------------------------------------------------------------- /assets/icons/app-icon-staging.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/assets/icons/app-icon-staging.png -------------------------------------------------------------------------------- /assets/icons/app-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/assets/icons/app-icon.png -------------------------------------------------------------------------------- /assets/icons/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/icons/share.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /assets/images/force_update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/assets/images/force_update.png -------------------------------------------------------------------------------- /assets/images/home_bond.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/assets/images/home_bond.png -------------------------------------------------------------------------------- /assets/images/home_bond_arabic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/assets/images/home_bond_arabic.png -------------------------------------------------------------------------------- /assets/images/home_bond_arabic_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/assets/images/home_bond_arabic_dark.png -------------------------------------------------------------------------------- /assets/images/home_bond_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/assets/images/home_bond_dark.png -------------------------------------------------------------------------------- /assets/images/splash_logo-staging.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/assets/images/splash_logo-staging.png -------------------------------------------------------------------------------- /assets/images/splash_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/assets/images/splash_logo.png -------------------------------------------------------------------------------- /env.example.json: -------------------------------------------------------------------------------- 1 | { 2 | "API_BASE_URL": "https://2cec2c83-4fda-46d4-8aba-bd02cb21177e.mock.pstmn.io/api/", 3 | "CONNECT_TIMEOUT": "100000", 4 | "SEND_TIMEOUT": "1000000", 5 | "RECEIVE_TIMEOUT": "1000000", 6 | "RECEIVE_DATA_WHEN_STATUS_ERROR": "true" 7 | } -------------------------------------------------------------------------------- /firebase.json: -------------------------------------------------------------------------------- 1 | {"flutter":{"platforms":{"android":{"buildConfigurations":{"src/production":{"projectId":"flutter-bond-8ae02","appId":"1:1077101979846:android:00afb3c0b4d1b8ae3a0fc7","fileOutput":"android/app/src/production/google-services.json"},"src/staging":{"projectId":"flutter-bond-staging-7dd42","appId":"1:390157281889:android:bf4d85c3c9a51044ab9820","fileOutput":"android/app/src/staging/google-services.json"}}},"ios":{"buildConfigurations":{"Debug-Production":{"projectId":"flutter-bond-8ae02","appId":"1:1077101979846:ios:a2d61d584196a5be3a0fc7","uploadDebugSymbols":true,"fileOutput":"ios/Production/GoogleService-Info.plist"},"Release-Production":{"projectId":"flutter-bond-8ae02","appId":"1:1077101979846:ios:a2d61d584196a5be3a0fc7","uploadDebugSymbols":true,"fileOutput":"ios/Production/GoogleService-Info.plist"},"Debug-Staging":{"projectId":"flutter-bond-staging-7dd42","appId":"1:390157281889:ios:8c87b8875dcdd94aab9820","uploadDebugSymbols":true,"fileOutput":"ios/Staging/GoogleService-Info.plist"},"Release-Staging":{"projectId":"flutter-bond-staging-7dd42","appId":"1:390157281889:ios:8c87b8875dcdd94aab9820","uploadDebugSymbols":true,"fileOutput":"ios/Staging/GoogleService-Info.plist"}}},"macos":{"buildConfigurations":{"Debug-Production":{"projectId":"flutter-bond-8ae02","appId":"1:1077101979846:ios:bb43f2ef1264d0e03a0fc7","uploadDebugSymbols":true,"fileOutput":"macos/Production/GoogleService-Info.plist"},"Release-Production":{"projectId":"flutter-bond-8ae02","appId":"1:1077101979846:ios:bb43f2ef1264d0e03a0fc7","uploadDebugSymbols":true,"fileOutput":"macos/Production/GoogleService-Info.plist"},"Debug-Staging":{"projectId":"flutter-bond-staging-7dd42","appId":"1:390157281889:ios:ba7ec93993371072ab9820","uploadDebugSymbols":true,"fileOutput":"macos/Staging/GoogleService-Info.plist"},"Release-Staging":{"projectId":"flutter-bond-staging-7dd42","appId":"1:390157281889:ios:ba7ec93993371072ab9820","uploadDebugSymbols":true,"fileOutput":"macos/Staging/GoogleService-Info.plist"}}},"dart":{"lib/firebase_options_production.dart":{"projectId":"flutter-bond-8ae02","configurations":{"android":"1:1077101979846:android:00afb3c0b4d1b8ae3a0fc7","ios":"1:1077101979846:ios:a2d61d584196a5be3a0fc7","macos":"1:1077101979846:ios:bb43f2ef1264d0e03a0fc7"}},"lib/firebase_options_staging.dart":{"projectId":"flutter-bond-staging-7dd42","configurations":{"android":"1:390157281889:android:bf4d85c3c9a51044ab9820","ios":"1:390157281889:ios:8c87b8875dcdd94aab9820","macos":"1:390157281889:ios:ba7ec93993371072ab9820"}}}}}} -------------------------------------------------------------------------------- /flutter_launcher_icons-production.yaml: -------------------------------------------------------------------------------- 1 | flutter_launcher_icons: 2 | android: "launcher_icon" 3 | ios: true 4 | image_path: "assets/icons/app-icon.png" 5 | min_sdk_android: 21 6 | adaptive_icon_background: "#ffffff" 7 | adaptive_icon_foreground: "assets/icons/app-icon.png" 8 | macos: 9 | generate: true 10 | image_path: "assets/icons/app-icon.png" 11 | web: 12 | generate: true 13 | image_path: "assets/icons/app-icon.png" 14 | background_color: "#ffffff" 15 | theme_color: "#322E79" -------------------------------------------------------------------------------- /flutter_launcher_icons-staging.yaml: -------------------------------------------------------------------------------- 1 | flutter_launcher_icons: 2 | android: "launcher_icon" 3 | ios: true 4 | image_path: "assets/icons/app-icon-staging.png" 5 | min_sdk_android: 21 6 | adaptive_icon_background: "#EB5C6C" 7 | adaptive_icon_foreground: "assets/icons/app-icon-staging.png" 8 | macos: 9 | generate: true 10 | image_path: "assets/icons/app-icon-staging.png" 11 | web: 12 | generate: true 13 | image_path: "assets/icons/app-icon.png" 14 | background_color: "#EB5C6C" 15 | theme_color: "#F05D6E" -------------------------------------------------------------------------------- /flutter_native_splash-production.yaml: -------------------------------------------------------------------------------- 1 | flutter_native_splash: 2 | color: "#322E79" 3 | image: assets/images/splash_logo.png 4 | android_12: 5 | image: assets/images/splash_logo.png 6 | color: "#322E79" 7 | icon_background_color: "#322E79" 8 | web: true 9 | 10 | -------------------------------------------------------------------------------- /flutter_native_splash-staging.yaml: -------------------------------------------------------------------------------- 1 | flutter_native_splash: 2 | color: "#F05D6E" 3 | image: assets/images/splash_logo-staging.png 4 | android_12: 5 | image: assets/images/splash_logo-staging.png 6 | color: "#F05D6E" 7 | icon_background_color: "#F05D6E" 8 | web: true 9 | 10 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 12.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | platform :ios, '13.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 | end 41 | end 42 | -------------------------------------------------------------------------------- /ios/Production/GoogleService-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | API_KEY 6 | AIzaSyBC8Jb_W3UwqIVcq9OE7WrcF3sQerxDdsQ 7 | GCM_SENDER_ID 8 | 1077101979846 9 | PLIST_VERSION 10 | 1 11 | BUNDLE_ID 12 | ps.app.bond 13 | PROJECT_ID 14 | flutter-bond-8ae02 15 | STORAGE_BUCKET 16 | flutter-bond-8ae02.appspot.com 17 | IS_ADS_ENABLED 18 | 19 | IS_ANALYTICS_ENABLED 20 | 21 | IS_APPINVITE_ENABLED 22 | 23 | IS_GCM_ENABLED 24 | 25 | IS_SIGNIN_ENABLED 26 | 27 | GOOGLE_APP_ID 28 | 1:1077101979846:ios:a2d61d584196a5be3a0fc7 29 | 30 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @main 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-50x50@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-50x50@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-50x50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-50x50@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-57x57@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-57x57@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-57x57@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-57x57@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-72x72@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-72x72@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-72x72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-72x72@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-production.appiconset/AppIcon-production-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-50x50@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-50x50@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-50x50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-50x50@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-57x57@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-57x57@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-57x57@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-57x57@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-72x72@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-72x72@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-72x72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-72x72@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/AppIcon-staging.appiconset/AppIcon-staging-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchBackgroundProduction.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "background.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchBackgroundProduction.imageset/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/LaunchBackgroundProduction.imageset/background.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchBackgroundStaging.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "background.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchBackgroundStaging.imageset/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/LaunchBackgroundStaging.imageset/background.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImageProduction.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "LaunchImage.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "LaunchImage@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "LaunchImage@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImageProduction.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/LaunchImageProduction.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImageProduction.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/LaunchImageProduction.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImageProduction.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/LaunchImageProduction.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImageStaging.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "LaunchImage.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "LaunchImage@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "LaunchImage@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImageStaging.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/LaunchImageStaging.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImageStaging.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/LaunchImageStaging.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImageStaging.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Runner/Assets.xcassets/LaunchImageStaging.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CADisableMinimumFrameDurationOnPhone 6 | 7 | CFBundleDevelopmentRegion 8 | $(DEVELOPMENT_LANGUAGE) 9 | CFBundleDisplayName 10 | Bond 11 | CFBundleExecutable 12 | $(EXECUTABLE_NAME) 13 | CFBundleIdentifier 14 | $(PRODUCT_BUNDLE_IDENTIFIER) 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleLocalizations 18 | 19 | en 20 | ar 21 | 22 | CFBundleName 23 | bond 24 | CFBundlePackageType 25 | APPL 26 | CFBundleShortVersionString 27 | $(FLUTTER_BUILD_NAME) 28 | CFBundleSignature 29 | ???? 30 | CFBundleVersion 31 | $(FLUTTER_BUILD_NUMBER) 32 | LSRequiresIPhoneOS 33 | 34 | UIApplicationSupportsIndirectInputEvents 35 | 36 | UILaunchStoryboardName 37 | $(LAUNCH_SCREEN_STORYBOARD) 38 | UIMainStoryboardFile 39 | Main 40 | UIStatusBarHidden 41 | 42 | UISupportedInterfaceOrientations 43 | 44 | UIInterfaceOrientationPortrait 45 | 46 | UISupportedInterfaceOrientations~ipad 47 | 48 | UIInterfaceOrientationLandscapeLeft 49 | UIInterfaceOrientationLandscapeRight 50 | UIInterfaceOrientationPortrait 51 | UIInterfaceOrientationPortraitUpsideDown 52 | 53 | UIViewControllerBasedStatusBarAppearance 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /ios/Staging/GoogleService-Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/Staging/GoogleService-Info.plist -------------------------------------------------------------------------------- /ios/firebase_app_id_file_production.json: -------------------------------------------------------------------------------- 1 | { 2 | "file_generated_by": "FlutterFire CLI", 3 | "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", 4 | "GOOGLE_APP_ID": "1:766000556009:ios:c008c663168299bed0cd78", 5 | "FIREBASE_PROJECT_ID": "flutter-bond-87485", 6 | "GCM_SENDER_ID": "766000556009" 7 | } -------------------------------------------------------------------------------- /ios/firebase_app_id_file_staging.json: -------------------------------------------------------------------------------- 1 | { 2 | "file_generated_by": "FlutterFire CLI", 3 | "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", 4 | "GOOGLE_APP_ID": "1:1060161913171:ios:7e71769f5507f2b255a1a6", 5 | "FIREBASE_PROJECT_ID": "flutter-bond-staging", 6 | "GCM_SENDER_ID": "1060161913171" 7 | } -------------------------------------------------------------------------------- /ios/production/GoogleService-Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/production/GoogleService-Info.plist -------------------------------------------------------------------------------- /ios/staging/GoogleService-Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/ios/staging/GoogleService-Info.plist -------------------------------------------------------------------------------- /l10n.yaml: -------------------------------------------------------------------------------- 1 | arb-dir: lib/l10n 2 | template-arb-file: app_en.arb 3 | output-localization-file: app_localizations.dart 4 | -------------------------------------------------------------------------------- /lib/app/app.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond/providers/notifications_service_provider.dart'; 2 | import 'package:bond_core/bond_core.dart'; 3 | 4 | import '../features/auth/auth_service_provider.dart'; 5 | import '../features/post/post_service_provider.dart'; 6 | import '../providers/analytics_service_provider.dart'; 7 | import '../providers/api_service_provider.dart'; 8 | import '../providers/app_service_provider.dart'; 9 | import '../providers/cache_service_provider.dart'; 10 | import '../providers/firebase_service_provider.dart'; 11 | import '../providers/forms_service_provider.dart'; 12 | 13 | final List providers = [ 14 | // Framework Service Providers 15 | FirebaseServiceProvider(), 16 | AppServiceProvider(), 17 | CacheServiceProvider(), 18 | FormsServiceProvider(), 19 | AuthServiceProvider(), 20 | ApiServiceProvider(), 21 | AnalyticsServiceProvider(), 22 | NotificationsServiceProvider(), 23 | 24 | // Modules Service Providers 25 | PostServiceProvider(), 26 | ]; 27 | -------------------------------------------------------------------------------- /lib/app/app_run_tasks.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer'; 2 | 3 | import 'package:bond/features/auth/auth.dart'; 4 | import 'package:bond_core/bond_core.dart'; 5 | import 'package:bond_notifications/bond_notifications.dart'; 6 | import 'package:firebase_crashlytics/firebase_crashlytics.dart'; 7 | import 'package:flutter/material.dart'; 8 | import 'package:flutter_local_notifications/flutter_local_notifications.dart'; 9 | import 'package:flutter_native_splash/flutter_native_splash.dart'; 10 | import 'package:universal_platform/universal_platform.dart'; 11 | 12 | class RunAppTasks extends RunTasks { 13 | @override 14 | Future beforeRun(WidgetsBinding widgetsBinding) async { 15 | FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding); 16 | FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError; 17 | FlutterNativeSplash.remove(); 18 | } 19 | 20 | @override 21 | Future afterRun() async { 22 | if (UniversalPlatform.isAndroid) { 23 | const AndroidNotificationChannel channel = AndroidNotificationChannel( 24 | 'high_importance_channel', // id 25 | 'Bond', // title 26 | description: 27 | 'This channel is used for important notifications.', // description 28 | importance: Importance.max, 29 | ); 30 | 31 | final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); 32 | 33 | await flutterLocalNotificationsPlugin 34 | .resolvePlatformSpecificImplementation< 35 | AndroidFlutterLocalNotificationsPlugin>() 36 | ?.createNotificationChannel(channel); 37 | } 38 | sl().listen(); 39 | if (Auth.check()) { 40 | sl().load(); 41 | sl().listen(); 42 | final firebaseMessaging = 43 | sl(instanceName: 'firebase_messaging'); 44 | final fcmToken = await firebaseMessaging.token; 45 | if (fcmToken != null) { 46 | // TODO: send fcm token to server 47 | log('fcm token $fcmToken', name: 'RunAppTasks'); 48 | } 49 | } 50 | } 51 | 52 | @override 53 | void onError(Object error, StackTrace stack) { 54 | log('Error: $error', stackTrace: stack); 55 | FirebaseCrashlytics.instance.recordError(error, stack, fatal: true); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /lib/app/default_firebase_options.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond/config/environments.dart'; 2 | import 'package:firebase_core/firebase_core.dart'; 3 | 4 | import '../firebase_options_production.dart' as production; 5 | import '../firebase_options_staging.dart' as staging; 6 | 7 | class DefaultFirebaseOptions { 8 | static FirebaseOptions get currentPlatform { 9 | final currentEnvironment = Environments.current; 10 | switch (currentEnvironment) { 11 | case EnvironmentType.staging: 12 | return staging.DefaultFirebaseOptions.currentPlatform; 13 | case EnvironmentType.production: 14 | return production.DefaultFirebaseOptions.currentPlatform; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/app/routes.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond/features/auth/routes.dart'; 2 | import 'package:bond/features/main/routes.dart'; 3 | import 'package:bond/features/notification/routes.dart'; 4 | import 'package:bond/features/post/routes.dart'; 5 | import 'package:bond/features/update_app/routes.dart'; 6 | import 'package:bond_core/bond_core.dart'; 7 | import 'package:go_router/go_router.dart'; 8 | 9 | final goRouter = GoRouter( 10 | debugLogDiagnostics: true, 11 | initialLocation: '/home', 12 | navigatorKey: appKey, 13 | routes: [ 14 | ...mainRoutes, 15 | ...postRoutes, 16 | ...authRoutes, 17 | ...updateAppRoutes, 18 | ...notificationRoutes, 19 | ], 20 | ); 21 | -------------------------------------------------------------------------------- /lib/bond_app.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond/app/routes.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_gen/gen_l10n/app_localizations.dart'; 4 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 5 | 6 | import 'core/app_theme.dart'; 7 | import 'features/app/app_providers.dart'; 8 | 9 | class BondApp extends ConsumerWidget { 10 | const BondApp({super.key}); 11 | 12 | @override 13 | Widget build(BuildContext context, WidgetRef ref) { 14 | final locale = ref.watch(localProvider); 15 | final theme = ref.watch(themeProvider); 16 | return MaterialApp.router( 17 | routerConfig: goRouter, 18 | localizationsDelegates: AppLocalizations.localizationsDelegates, 19 | locale: locale, 20 | supportedLocales: AppLocalizations.supportedLocales, 21 | debugShowCheckedModeBanner: true, 22 | theme: appLightThemeData(), 23 | darkTheme: appDarkThemeData(), 24 | themeMode: theme, 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/config/analytics.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond/core/app_analytics.dart'; 2 | 3 | class AnalyticsConfig { 4 | static var providers = { 5 | 'firebase_analytics_provider': { 6 | 'driver': 'firebase_analytics_provider', 7 | 'class': FirebaseAnalyticsProvider, 8 | }, 9 | 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /lib/config/api.dart: -------------------------------------------------------------------------------- 1 | const apiConfigs = { 2 | 'API_BASE_URL': String.fromEnvironment('API_BASE_URL'), 3 | 'CONNECT_TIMEOUT': int.fromEnvironment('CONNECT_TIMEOUT', defaultValue: 10000), 4 | 'SEND_TIMEOUT': int.fromEnvironment('SEND_TIMEOUT'), 5 | 'RECEIVE_TIMEOUT': int.fromEnvironment('RECEIVE_TIMEOUT'), 6 | 'RECEIVE_DATA_WHEN_STATUS_ERROR': 7 | bool.fromEnvironment('RECEIVE_DATA_WHEN_STATUS_ERROR'), 8 | }; 9 | -------------------------------------------------------------------------------- /lib/config/cache.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond/core/cache/secure_storage_cache_driver.dart'; 2 | import 'package:bond_cache/bond_cache.dart'; 3 | 4 | class CacheConfig { 5 | static var defaultStore = 'shared_preference'; 6 | 7 | static var stores = { 8 | 'shared_preference': { 9 | 'driver': 'shared_preference', 10 | 'class': SharedPreferencesCacheDriver, 11 | }, 12 | 'in_memory': { 13 | 'driver': 'in_memory', 14 | 'class': InMemoryCacheDriver, 15 | }, 16 | 'secure_cache': { 17 | 'driver': 'secure_cache', 18 | 'class': SecureStorageCacheDriver, 19 | }, 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /lib/config/configs.dart: -------------------------------------------------------------------------------- 1 | import 'api.dart'; 2 | 3 | final configs = { 4 | ...apiConfigs, 5 | }; 6 | 7 | dynamic config(String key) { 8 | if (!configs.containsKey(key)) { 9 | throw Exception('Config $key not found'); 10 | } 11 | return configs[key]; 12 | } 13 | -------------------------------------------------------------------------------- /lib/config/environments.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond_core/bond_core.dart'; 2 | import 'package:package_info_plus/package_info_plus.dart'; 3 | 4 | enum EnvironmentType { staging, production } 5 | 6 | class Environments { 7 | static EnvironmentType get current => 8 | sl().packageName.contains('staging') 9 | ? EnvironmentType.staging 10 | : EnvironmentType.production; 11 | } 12 | -------------------------------------------------------------------------------- /lib/config/notification.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond/core/app_notification_providers.dart'; 2 | import 'package:bond_notifications/bond_notifications.dart'; 3 | 4 | class NotificationConfig { 5 | static var providers = { 6 | 'push_notification': { 7 | 'driver': 'push_notification', 8 | 'class': PushNotificationsProviders, 9 | 'channels': [ 10 | { 11 | 'name': 'firebase_messaging', 12 | 'class': FirebaseMessagingNotificationProvider, 13 | } 14 | ], 15 | }, 16 | 'server_notification': { 17 | 'driver': 'notification_center', 18 | 'data_source': { 19 | 'name': 'notification_center_remote_data_source', 20 | 'class': NotificationCenterRemoteDataSource, 21 | }, 22 | 'class': NotificationCenterProvider, 23 | } 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /lib/core/app_analytics.dart: -------------------------------------------------------------------------------- 1 | library; 2 | 3 | import 'dart:developer'; 4 | 5 | import 'package:bond_app_analytics/bond_app_analytics.dart'; 6 | import 'package:bond_core/bond_core.dart'; 7 | 8 | import '../config/analytics.dart'; 9 | 10 | export 'app_analytics_providers/firebase_analytics_provider.dart'; 11 | 12 | class AppAnalytics { 13 | static void fire(AnalyticsEvent event) { 14 | AnalyticsConfig.providers.forEach( 15 | (key, value) { 16 | final driver = value['driver'] as String; 17 | log('AppAnalytics provider $driver' 18 | ' fire log ${event.key} and params ${event.params}'); 19 | sl(instanceName: driver).log(event); 20 | }, 21 | ); 22 | } 23 | 24 | static void setUserId(int userId) { 25 | AnalyticsConfig.providers.forEach( 26 | (key, value) { 27 | final driver = value['driver'] as String; 28 | log('AppAnalytics provider $driver' 29 | ' set user userId $userId'); 30 | sl(instanceName: driver).setUserId(userId); 31 | }, 32 | ); 33 | } 34 | 35 | static void setUserAttributes(Map attributes) { 36 | AnalyticsConfig.providers.forEach( 37 | (key, value) { 38 | final driver = value['driver'] as String; 39 | log('AppAnalytics provider $driver' 40 | ' set user attributes $attributes'); 41 | sl(instanceName: driver).setUserAttributes(attributes); 42 | }, 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lib/core/app_localizations.dart: -------------------------------------------------------------------------------- 1 | library; 2 | 3 | export 'localizations/app_localizations_extension.dart'; 4 | -------------------------------------------------------------------------------- /lib/core/app_notification_providers.dart: -------------------------------------------------------------------------------- 1 | library; 2 | 3 | export 'notifications/notification_center_remote_data_source.dart'; 4 | export 'notifications/push_notifications_providers/firebase_messaging_push_notification_provider.dart'; 5 | -------------------------------------------------------------------------------- /lib/core/app_review.dart: -------------------------------------------------------------------------------- 1 | import 'package:in_app_review/in_app_review.dart'; 2 | 3 | class AppReviewHelper { 4 | static Future showAppReview() async { 5 | bool isAvailable = await InAppReview.instance.isAvailable(); 6 | if (isAvailable) { 7 | await InAppReview.instance.requestReview(); 8 | return true; 9 | } else { 10 | return false; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/core/app_theme.dart: -------------------------------------------------------------------------------- 1 | library; 2 | 3 | export 'theme/app_dark_theme_data.dart'; 4 | export 'theme/app_light_theme_data.dart'; 5 | export 'theme/app_text_theme.dart'; 6 | -------------------------------------------------------------------------------- /lib/core/app_utils.dart: -------------------------------------------------------------------------------- 1 | library; 2 | 3 | export 'utils/device_info.dart'; 4 | -------------------------------------------------------------------------------- /lib/core/app_widgets.dart: -------------------------------------------------------------------------------- 1 | library; 2 | 3 | export 'widgets/app_button.dart'; 4 | export 'widgets/bond_pop_menu/bond_pop_menu_button.dart'; 5 | -------------------------------------------------------------------------------- /lib/core/cache/secure_storage_cache_driver.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'dart:developer'; 3 | 4 | import 'package:bond_cache/bond_cache.dart'; 5 | import 'package:flutter_secure_storage/flutter_secure_storage.dart'; 6 | 7 | class SecureStorageCacheDriver extends CacheDriver { 8 | final FlutterSecureStorage _storage; 9 | 10 | SecureStorageCacheDriver(this._storage); 11 | 12 | var _cache = {}; 13 | 14 | Future loadAll() async { 15 | _cache = await _storage.readAll(); 16 | return this; 17 | } 18 | 19 | @override 20 | Map? retrieve(String key) { 21 | try { 22 | final jsonString = _cache[key]; 23 | if (jsonString == null) { 24 | return null; 25 | } 26 | return jsonDecode(jsonString); 27 | } catch (error, stack) { 28 | log('retrieve error: $error , stackTrace : $stack'); 29 | return null; 30 | } 31 | } 32 | 33 | @override 34 | Future store(String key, Map data) async { 35 | try { 36 | final jsonString = jsonEncode(data); 37 | await _storage.write(key: key, value: jsonString); 38 | return Future.value(true); 39 | } catch (error, stack) { 40 | log('store error: $error , stackTrace : $stack'); 41 | return Future.value(false); 42 | } finally { 43 | await loadAll(); 44 | } 45 | } 46 | 47 | @override 48 | bool has(String key) => _cache.containsKey(key); 49 | 50 | @override 51 | Future removeAll() async { 52 | try { 53 | await _storage.deleteAll(); 54 | return true; 55 | } catch (error, stack) { 56 | log('flush error: $error , stackTrace : $stack'); 57 | return false; 58 | } finally { 59 | await loadAll(); 60 | } 61 | } 62 | 63 | @override 64 | Future remove(String key) async { 65 | try { 66 | await _storage.delete(key: key); 67 | return true; 68 | } catch (error, stack) { 69 | log('forget error: $error , stackTrace : $stack'); 70 | return false; 71 | } finally { 72 | await loadAll(); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /lib/core/localizations/app_localizations_extension.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_gen/gen_l10n/app_localizations.dart'; 3 | 4 | extension Localizations on BuildContext { 5 | AppLocalizations get localizations => AppLocalizations.of(this)!; 6 | } 7 | -------------------------------------------------------------------------------- /lib/core/notifications/notification_center_remote_data_source.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond_network/bond_network.dart'; 2 | import 'package:bond_notifications/bond_notifications.dart'; 3 | import 'package:dio/dio.dart'; 4 | 5 | class NotificationCenterRemoteDataSource extends NotificationCenterDataSource { 6 | final ApiClient _client; 7 | 8 | NotificationCenterRemoteDataSource(this._client); 9 | 10 | @override 11 | Future> loadNotifications( 12 | {String? nextUrl}) async { 13 | final Response response = await _client.get( 14 | nextUrl ?? NotificationsApis.notifications, 15 | headers: Api.headers(), 16 | ); 17 | return mapListResponse(response); 18 | } 19 | 20 | @override 21 | Future read(String uuid) async { 22 | await _client.post( 23 | NotificationsApis.read(uuid), 24 | headers: Api.headers(), 25 | ); 26 | } 27 | 28 | @override 29 | Future readAll() async { 30 | await _client.post( 31 | NotificationsApis.readAll, 32 | headers: Api.headers(), 33 | ); 34 | } 35 | } 36 | 37 | extension NotificationsApis on Api { 38 | static String get notifications => 'notifications'; 39 | 40 | static String read(String id) => 'notifications/$id/read'; 41 | 42 | static String get readAll => 'notifications/read-all'; 43 | } 44 | -------------------------------------------------------------------------------- /lib/core/notifications/push_notifications_providers/firebase_messaging_push_notification_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond_notifications/bond_notifications.dart'; 2 | import 'package:firebase_messaging/firebase_messaging.dart'; 3 | 4 | class FirebaseMessagingNotificationProvider extends PushNotificationProvider { 5 | final FirebaseMessaging _firebaseMessaging; 6 | 7 | FirebaseMessagingNotificationProvider(this._firebaseMessaging); 8 | 9 | @override 10 | Future get initialNotification async => 11 | (await _firebaseMessaging.getInitialMessage())?.data; 12 | 13 | @override 14 | Stream get onNotification => 15 | FirebaseMessaging.onMessage.map( 16 | (event) => event.data 17 | ..putIfAbsent('title', () => event.notification?.title) 18 | ..putIfAbsent('body', () => event.notification?.body) 19 | ..putIfAbsent('image', () => event.notification?.android?.imageUrl), 20 | ); 21 | 22 | @override 23 | Stream get onNotificationTapped => 24 | FirebaseMessaging.onMessageOpenedApp.map( 25 | (event) => event.data, 26 | ); 27 | 28 | @override 29 | Stream get onTokenRefresh => _firebaseMessaging.onTokenRefresh; 30 | 31 | @override 32 | Future get token => _firebaseMessaging.getToken(); 33 | 34 | @override 35 | Future get apnsToken => _firebaseMessaging.getAPNSToken(); 36 | 37 | @override 38 | Future deleteToken() => _firebaseMessaging.deleteToken(); 39 | 40 | @override 41 | Stream get onNotificationDismiss => throw UnimplementedError(); 42 | } 43 | -------------------------------------------------------------------------------- /lib/core/resources/app_assets.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class AppImagesAssets { 4 | static const String logo = 'assets/images/app_logo.svg'; 5 | static const String forceUpdate = 'assets/images/force_update.png'; 6 | static const String _homeBondLight = 'assets/images/home_bond.png'; 7 | static const String _homeBondDark = 'assets/images/home_bond_dark.png'; 8 | 9 | static const String _homeBondArabicLight = 10 | 'assets/images/home_bond_arabic.png'; 11 | static const String _homeBondArabicDark = 12 | 'assets/images/home_bond_arabic_dark.png'; 13 | 14 | static String homeBond(Brightness mode, String locale) { 15 | if (mode == Brightness.light) { 16 | return locale == 'ar' ? _homeBondArabicLight : _homeBondLight; 17 | } else { 18 | return locale == 'ar' ? _homeBondArabicDark : _homeBondDark; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/core/resources/app_icons.dart: -------------------------------------------------------------------------------- 1 | class AppIcons { 2 | static const String test = 'assets/icons/test.svg'; 3 | static const String close = 'assets/icons/close.svg'; 4 | static const String share = 'assets/icons/share.svg'; 5 | } 6 | -------------------------------------------------------------------------------- /lib/core/route_helpers.dart: -------------------------------------------------------------------------------- 1 | library; 2 | 3 | export 'route_helpers/modal_bottom_sheet_page.dart'; 4 | -------------------------------------------------------------------------------- /lib/core/route_helpers/modal_bottom_sheet_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ModalBottomSheetPage extends Page { 4 | final Widget child; 5 | final bool isScrollControlled; 6 | 7 | const ModalBottomSheetPage({ 8 | required this.child, 9 | this.isScrollControlled = false, 10 | super.key, 11 | super.name, 12 | super.arguments, 13 | }); 14 | 15 | @override 16 | Route createRoute(BuildContext context) { 17 | return ModalBottomSheetRoute( 18 | builder: (BuildContext context) { 19 | return child; 20 | }, 21 | isScrollControlled: true, 22 | ); 23 | } 24 | } -------------------------------------------------------------------------------- /lib/core/theme/app_text_theme.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:google_fonts/google_fonts.dart'; 3 | 4 | // This code is copied from https://m2.material.io/design/typography/the-type-system.html#type-scale 5 | 6 | final appTextTheme = TextTheme( 7 | displayLarge: GoogleFonts.tajawal( 8 | fontSize: 112, 9 | fontWeight: FontWeight.w300, 10 | letterSpacing: -1.5, 11 | ), 12 | displayMedium: GoogleFonts.tajawal( 13 | fontSize: 70, 14 | fontWeight: FontWeight.w300, 15 | letterSpacing: -0.5, 16 | ), 17 | displaySmall: GoogleFonts.tajawal( 18 | fontSize: 56, 19 | fontWeight: FontWeight.w400, 20 | ), 21 | headlineMedium: GoogleFonts.tajawal( 22 | fontSize: 40, 23 | fontWeight: FontWeight.w400, 24 | letterSpacing: 0.25, 25 | ), 26 | headlineSmall: GoogleFonts.tajawal( 27 | fontSize: 28, 28 | fontWeight: FontWeight.w400, 29 | ), 30 | titleLarge: GoogleFonts.tajawal( 31 | fontSize: 23, 32 | fontWeight: FontWeight.w500, 33 | letterSpacing: 0.15, 34 | ), 35 | titleMedium: GoogleFonts.tajawal( 36 | fontSize: 19, 37 | fontWeight: FontWeight.w400, 38 | letterSpacing: 0.15, 39 | ), 40 | titleSmall: GoogleFonts.tajawal( 41 | fontSize: 16, fontWeight: FontWeight.w500, letterSpacing: 0.1), 42 | bodyLarge: GoogleFonts.tajawal( 43 | fontSize: 19, 44 | fontWeight: FontWeight.w400, 45 | letterSpacing: 0.5, 46 | ), 47 | bodyMedium: GoogleFonts.tajawal( 48 | fontSize: 16, 49 | fontWeight: FontWeight.w400, 50 | letterSpacing: 0.25, 51 | ), 52 | labelLarge: GoogleFonts.tajawal( 53 | fontSize: 16, 54 | fontWeight: FontWeight.w500, 55 | letterSpacing: 1.25, 56 | ), 57 | bodySmall: GoogleFonts.tajawal( 58 | fontSize: 14, 59 | fontWeight: FontWeight.w400, 60 | letterSpacing: 0.4, 61 | ), 62 | labelSmall: GoogleFonts.tajawal( 63 | fontSize: 12, 64 | fontWeight: FontWeight.w400, 65 | letterSpacing: 1.5, 66 | ), 67 | ); 68 | -------------------------------------------------------------------------------- /lib/core/utils/device_info.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:bond_cache/bond_cache.dart'; 4 | import 'package:bond_core/bond_core.dart'; 5 | import 'package:device_info_plus/device_info_plus.dart'; 6 | import 'package:package_info_plus/package_info_plus.dart'; 7 | import 'package:universal_platform/universal_platform.dart'; 8 | 9 | class DeviceInfo { 10 | Future> toJson() async { 11 | final deviceInfoPlugin = sl(); 12 | final packageInfo = sl(); 13 | final map = {}; 14 | map.addAll({ 15 | 'device_type': 'mobile', 16 | 'device_model': '', 17 | 'device_brand': getDeviceType(), 18 | 'os_version': packageInfo.buildNumber, 19 | 'app_version': packageInfo.buildNumber, 20 | 'language': Cache.get('language', defaultValue: 'en'), 21 | 'device_id': await deviceIdInfo(), 22 | }); 23 | if (UniversalPlatform.isAndroid) { 24 | final build = await deviceInfoPlugin.androidInfo; 25 | map.addAll(readAndroidBuildData(build)); 26 | } else if (UniversalPlatform.isIOS) { 27 | final build = await deviceInfoPlugin.iosInfo; 28 | map.addAll(readIosDeviceInfo(build)); 29 | } 30 | return map; 31 | } 32 | 33 | static Map readAndroidBuildData(AndroidDeviceInfo build) { 34 | return { 35 | 'os_version': build.version.release, 36 | 'device_model': build.model, 37 | }; 38 | } 39 | 40 | static Map readIosDeviceInfo(IosDeviceInfo data) { 41 | return { 42 | 'os_version': data.systemVersion, 43 | 'device_model': data.model, 44 | }; 45 | } 46 | 47 | static Future deviceIdInfo() async { 48 | final deviceInfo = DeviceInfoPlugin(); 49 | if (Platform.isAndroid) { 50 | return (await deviceInfo.androidInfo).id; 51 | } 52 | if (Platform.isIOS) { 53 | return (await deviceInfo.iosInfo).identifierForVendor ?? 54 | 'identifierForVendor is null'; 55 | } 56 | return 'unknown'; 57 | } 58 | 59 | static String getDeviceType() => 60 | Platform.isAndroid ? 'android' : (Platform.isIOS ? 'ios' : 'unknown'); 61 | } 62 | -------------------------------------------------------------------------------- /lib/core/widgets/app_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class AppButton extends StatelessWidget { 4 | const AppButton({ 5 | super.key, 6 | required this.title, 7 | this.enabled = true, 8 | this.loading = false, 9 | required this.onPressed, 10 | }); 11 | 12 | final String title; 13 | final bool enabled; 14 | final bool loading; 15 | final VoidCallback onPressed; 16 | 17 | @override 18 | Widget build(BuildContext context) { 19 | return ElevatedButton( 20 | onPressed: enabled ? onPressed : null, 21 | child: loading 22 | ? const CircularProgressIndicator( 23 | strokeWidth: 2, 24 | color: Colors.white, 25 | ) 26 | : Text(title), 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lib/core/widgets/bond_pop_menu/bond_popup_menu_item.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | enum Menu { theme, language, logout, notifications } 4 | 5 | class BondPopupBondMenuItem extends PopupMenuItem { 6 | BondPopupBondMenuItem({ 7 | super.key, 8 | required Menu value, 9 | required String title, 10 | required Icon icon, 11 | }) : super( 12 | value: value, 13 | child: Row( 14 | children: [ 15 | icon, 16 | const SizedBox(width: 8), 17 | Text(title), 18 | ], 19 | ), 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /lib/features/app/app_providers.dart: -------------------------------------------------------------------------------- 1 | library; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 5 | 6 | import 'notifiers/local_notifier.dart'; 7 | import 'notifiers/theme_notifier.dart'; 8 | 9 | export 'notifiers/local_notifier.dart'; 10 | export 'notifiers/theme_notifier.dart'; 11 | 12 | final localProvider = NotifierProvider(() { 13 | return LocalNotifier(); 14 | }); 15 | 16 | final themeProvider = NotifierProvider(() { 17 | return ThemeNotifier(); 18 | }); 19 | -------------------------------------------------------------------------------- /lib/features/app/notifiers/local_notifier.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:ui'; 3 | 4 | import 'package:bond_cache/bond_cache.dart'; 5 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 6 | 7 | class LocalNotifier extends Notifier { 8 | @override 9 | Locale build() => Locale( 10 | Cache.get( 11 | 'language', 12 | defaultValue: Platform.localeName, 13 | ), 14 | ); 15 | 16 | void update(Locale locale) { 17 | Cache.put('language', locale.languageCode); 18 | state = locale; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/features/app/notifiers/theme_notifier.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond_cache/bond_cache.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 4 | 5 | class ThemeNotifier extends Notifier { 6 | @override 7 | ThemeMode build() => XThemeMode.fromValue( 8 | Cache.get( 9 | 'theme', 10 | defaultValue: ThemeMode.system.value, 11 | ), 12 | ); 13 | 14 | void update(ThemeMode themeMode) { 15 | Cache.put('theme', themeMode.value); 16 | state = themeMode; 17 | } 18 | } 19 | 20 | extension XThemeMode on ThemeMode { 21 | String get value { 22 | switch (this) { 23 | case ThemeMode.dark: 24 | return 'dark'; 25 | case ThemeMode.light: 26 | return 'light'; 27 | case ThemeMode.system: 28 | return 'system'; 29 | } 30 | } 31 | 32 | static ThemeMode fromValue(String value) { 33 | switch (value) { 34 | case 'dark': 35 | return ThemeMode.dark; 36 | case 'light': 37 | return ThemeMode.light; 38 | case 'system': 39 | return ThemeMode.system; 40 | default: 41 | return ThemeMode.system; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/features/auth/auth.dart: -------------------------------------------------------------------------------- 1 | library; 2 | 3 | import 'package:bond_cache/bond_cache.dart'; 4 | 5 | import 'data/models/user.dart'; 6 | 7 | export 'data/models/user.dart'; 8 | export 'data/models/user_meta.dart'; 9 | export 'routes.dart'; 10 | 11 | class Auth { 12 | static bool check() => Cache.has('token'); 13 | 14 | static User user() => Cache.get('user'); 15 | 16 | static String token() => Cache.get('token'); 17 | } 18 | -------------------------------------------------------------------------------- /lib/features/auth/auth_service_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond_core/bond_core.dart'; 2 | import 'package:get_it/get_it.dart'; 3 | 4 | import 'data/api.dart'; 5 | import 'data/models/user.dart'; 6 | import 'data/models/user_meta.dart'; 7 | 8 | class AuthServiceProvider extends ServiceProvider with ResponseDecoding { 9 | @override 10 | Future register(GetIt it) async { 11 | it.registerFactory(() => AuthApi(it())); 12 | } 13 | 14 | @override 15 | Map get factories => { 16 | User: User.fromJson, 17 | UserMeta: UserMeta.fromJson, 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /lib/features/auth/data/api.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond/features/auth/auth.dart'; 2 | import 'package:bond_network/bond_network.dart'; 3 | 4 | import 'errors/validation_error.dart'; 5 | 6 | typedef UserMApiResult = SingleMResponse; 7 | typedef UserApiResult = SingleResponse; 8 | 9 | class AuthApi { 10 | final BondFire _bondFire; 11 | 12 | AuthApi(this._bondFire); 13 | 14 | Future me() => _bondFire 15 | .get('/users/me') 16 | .cache(cacheKey: 'user', cachePolicy: CachePolicy.cacheThenNetwork) 17 | .header(Api.headers()) 18 | .factory(User.fromJson) 19 | .errorFactory(ServerError.fromJson) 20 | .execute(); 21 | 22 | Future login(Map body) => _bondFire 23 | .post('/users/login') 24 | .body(body) 25 | .factory(UserMApiResult.fromJson) 26 | .errorFactory(ValidationError.fromJson) 27 | .cacheCustomKey('token', path: 'meta.token') 28 | .cacheCustomKey('user', path: 'data') 29 | .execute(); 30 | 31 | Future register(Map body) => _bondFire 32 | .post('/users/register') 33 | .body(body) 34 | .factory(UserMApiResult.fromJson) 35 | .errorFactory(ValidationError.fromJson) 36 | .cacheCustomKey('token', path: 'meta.token') 37 | .cacheCustomKey('user', path: 'data') 38 | .execute(); 39 | 40 | Future logout() => _bondFire 41 | .post('/users/logout') 42 | .header(Api.headers()) 43 | .factory(SuccessResponse.fromJson) 44 | .errorFactory(ServerError.fromJson) 45 | .execute(); 46 | } 47 | -------------------------------------------------------------------------------- /lib/features/auth/data/errors/validation_error.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'validation_error.g.dart'; 4 | 5 | @JsonSerializable() 6 | class ValidationError extends Error { 7 | final String message; 8 | final Map> errors; 9 | 10 | ValidationError({required this.message, required this.errors}); 11 | 12 | factory ValidationError.fromJson(Map json) => 13 | _$ValidationErrorFromJson(json); 14 | 15 | Map toJson() => _$ValidationErrorToJson(this); 16 | 17 | List? getFieldErrors(String field) => errors[field]; 18 | } 19 | -------------------------------------------------------------------------------- /lib/features/auth/data/errors/validation_error.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'validation_error.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ValidationError _$ValidationErrorFromJson(Map json) => 10 | ValidationError( 11 | message: json['message'] as String, 12 | errors: (json['errors'] as Map).map( 13 | (k, e) => 14 | MapEntry(k, (e as List).map((e) => e as String).toList()), 15 | ), 16 | ); 17 | 18 | Map _$ValidationErrorToJson(ValidationError instance) => 19 | { 20 | 'message': instance.message, 21 | 'errors': instance.errors, 22 | }; 23 | -------------------------------------------------------------------------------- /lib/features/auth/data/events/sign_in_event.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond_app_analytics/bond_app_analytics.dart'; 2 | 3 | class SignInEvent extends AnalyticsEvent with UserSignedIn { 4 | final int userId; 5 | final String channel; 6 | 7 | SignInEvent({required this.userId, required this.channel}); 8 | 9 | @override 10 | SystemEvents get systemEventType => SystemEvents.signedIn; 11 | 12 | @override 13 | String get key => 'User Sign In'; 14 | 15 | @override 16 | Map get params => {'Channel': channel}; 17 | 18 | @override 19 | int get id => userId; 20 | 21 | @override 22 | String get loginMethod => channel; 23 | } 24 | -------------------------------------------------------------------------------- /lib/features/auth/data/events/sign_out_event.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond_app_analytics/bond_app_analytics.dart'; 2 | 3 | class SignOutEvent extends AnalyticsEvent with UserSignedOut { 4 | @override 5 | SystemEvents get systemEventType => SystemEvents.signedOut; 6 | 7 | @override 8 | String get key => 'User Signed out'; 9 | 10 | @override 11 | Map get params => {}; 12 | } 13 | -------------------------------------------------------------------------------- /lib/features/auth/data/events/sign_up_event.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond_app_analytics/bond_app_analytics.dart'; 2 | 3 | class SignUpEvent extends AnalyticsEvent with UserSignedUp { 4 | final int userId; 5 | final String channel; 6 | 7 | SignUpEvent({required this.userId, required this.channel}); 8 | 9 | @override 10 | SystemEvents get systemEventType => SystemEvents.signedUp; 11 | 12 | @override 13 | String get key => 'User Signed Up'; 14 | 15 | @override 16 | Map get params => {'Channel': channel}; 17 | 18 | @override 19 | int get id => userId; 20 | 21 | @override 22 | String get signupMethod => channel; 23 | } 24 | -------------------------------------------------------------------------------- /lib/features/auth/data/models/user.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond_network/bond_network.dart'; 2 | import 'package:json_annotation/json_annotation.dart'; 3 | 4 | part 'user.g.dart'; 5 | 6 | @JsonSerializable(explicitToJson: true) 7 | class User extends Model { 8 | final String? name; 9 | final String? email; 10 | 11 | const User({ 12 | required super.id, 13 | this.name, 14 | this.email, 15 | }); 16 | 17 | factory User.fromJson(Map json) => _$UserFromJson(json); 18 | 19 | @override 20 | Map toJson() => _$UserToJson(this); 21 | 22 | @override 23 | List get props => [name, id, email]; 24 | } 25 | -------------------------------------------------------------------------------- /lib/features/auth/data/models/user.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'user.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | User _$UserFromJson(Map json) => User( 10 | id: json['id'] as int, 11 | name: json['name'] as String?, 12 | email: json['email'] as String?, 13 | ); 14 | 15 | Map _$UserToJson(User instance) => { 16 | 'id': instance.id, 17 | 'name': instance.name, 18 | 'email': instance.email, 19 | }; 20 | -------------------------------------------------------------------------------- /lib/features/auth/data/models/user_meta.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:json_annotation/json_annotation.dart'; 3 | import 'package:bond_core/bond_core.dart'; 4 | 5 | part 'user_meta.g.dart'; 6 | @JsonSerializable(explicitToJson: true) 7 | class UserMeta extends Equatable with Jsonable { 8 | final String token; 9 | 10 | const UserMeta({required this.token}); 11 | 12 | factory UserMeta.fromJson(Map json) => 13 | _$UserMetaFromJson(json); 14 | 15 | @override 16 | Map toJson() => _$UserMetaToJson(this); 17 | 18 | @override 19 | List get props => [token]; 20 | 21 | } -------------------------------------------------------------------------------- /lib/features/auth/data/models/user_meta.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'user_meta.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | UserMeta _$UserMetaFromJson(Map json) => UserMeta( 10 | token: json['token'] as String, 11 | ); 12 | 13 | Map _$UserMetaToJson(UserMeta instance) => { 14 | 'token': instance.token, 15 | }; 16 | -------------------------------------------------------------------------------- /lib/features/auth/presentation/login_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond/core/app_localizations.dart'; 2 | import 'package:bond/core/resources/app_assets.dart'; 3 | import 'package:bond/core/widgets/bond_pop_menu/bond_pop_menu_button.dart'; 4 | import 'package:bond/features/auth/presentation/views/login/login_form.dart'; 5 | import 'package:flutter/material.dart'; 6 | import 'package:flutter_svg/svg.dart'; 7 | 8 | import 'views/login/new_account_view.dart'; 9 | 10 | class LoginPage extends StatelessWidget { 11 | const LoginPage({super.key}); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return Scaffold( 16 | appBar: AppBar( 17 | title: Text(context.localizations.login_page_title), 18 | actions: const [BondPopMenuButton()], 19 | ), 20 | body: SingleChildScrollView( 21 | child: AutofillGroup( 22 | child: Center( 23 | child: Padding( 24 | padding: const EdgeInsets.symmetric(horizontal: 24), 25 | child: Column( 26 | mainAxisAlignment: MainAxisAlignment.center, 27 | crossAxisAlignment: CrossAxisAlignment.center, 28 | children: [ 29 | const SizedBox(height: 64), 30 | SvgPicture.asset( 31 | AppImagesAssets.logo, 32 | width: 95, 33 | height: 120, 34 | ), 35 | const SizedBox(height: 48), 36 | const LoginForm(), 37 | const SizedBox(height: 16), 38 | const NewAccountView(), 39 | ], 40 | ), 41 | ), 42 | ), 43 | ), 44 | ), 45 | ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/features/auth/presentation/providers/login_form_provider.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer'; 2 | 3 | import 'package:bond/core/app_localizations.dart'; 4 | import 'package:bond/features/auth/auth.dart'; 5 | import 'package:bond/features/auth/data/api.dart'; 6 | import 'package:bond_core/bond_core.dart'; 7 | import 'package:bond_form/bond_form.dart'; 8 | import 'package:bond_form_riverpod/bond_form_riverpod.dart'; 9 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 10 | 11 | class LoginFormController extends FormStateNotifier { 12 | final AuthApi authApi; 13 | 14 | LoginFormController(this.authApi); 15 | 16 | @override 17 | Map fields() => { 18 | 'email': TextFieldState( 19 | null, 20 | label: appContext.localizations.filed_email_label, 21 | rules: [ 22 | Rules.required(), 23 | Rules.email(), 24 | ], 25 | ), 26 | 'password': TextFieldState( 27 | null, 28 | label: appContext.localizations.filed_password_label, 29 | rules: [ 30 | Rules.required(), 31 | Rules.minLength(6), 32 | Rules.alphaNum(), 33 | ], 34 | ), 35 | }; 36 | 37 | @override 38 | Future onSubmit() async { 39 | final email = state.get('email').value; 40 | final password = state.get('password').value; 41 | log('email: $email, password: $password'); 42 | final body = { 43 | 'email': email, 44 | 'password': password, 45 | }; 46 | final response = await authApi.login(body); 47 | return response.data; 48 | } 49 | } 50 | 51 | final loginProvider = 52 | NotifierProvider>( 53 | () => LoginFormController( 54 | sl(), 55 | ), 56 | ); 57 | -------------------------------------------------------------------------------- /lib/features/auth/presentation/providers/register_form_provider.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer'; 2 | 3 | import 'package:bond/core/app_localizations.dart'; 4 | import 'package:bond/features/auth/auth.dart'; 5 | import 'package:bond/features/auth/data/api.dart'; 6 | import 'package:bond_core/bond_core.dart'; 7 | import 'package:bond_form/bond_form.dart'; 8 | import 'package:bond_form_riverpod/bond_form_riverpod.dart'; 9 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 10 | 11 | class RegisterFormController extends FormStateNotifier { 12 | final AuthApi authApi; 13 | 14 | RegisterFormController(this.authApi); 15 | 16 | @override 17 | Map fields() => { 18 | 'email': TextFieldState( 19 | null, 20 | label: appContext.localizations.filed_email_label, 21 | rules: [ 22 | Rules.required(), 23 | Rules.email(), 24 | ], 25 | ), 26 | 'password': TextFieldState( 27 | null, 28 | label: appContext.localizations.filed_password_label, 29 | rules: [ 30 | Rules.required(), 31 | Rules.minLength(6), 32 | Rules.alphaNum(), 33 | ], 34 | ), 35 | }; 36 | 37 | @override 38 | Future onSubmit() async { 39 | final email = state.get('email').value; 40 | final password = state.get('password').value; 41 | log('email: $email, password: $password'); 42 | final body = { 43 | 'email': email, 44 | 'password': password, 45 | }; 46 | final response = await authApi.register(body); 47 | return response.data; 48 | } 49 | } 50 | 51 | final registerProvider = 52 | NotifierProvider>( 53 | () => RegisterFormController( 54 | sl(), 55 | ), 56 | ); 57 | -------------------------------------------------------------------------------- /lib/features/auth/presentation/register_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond/core/app_localizations.dart'; 2 | import 'package:bond/core/app_widgets.dart'; 3 | import 'package:bond/core/resources/app_assets.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter_svg/svg.dart'; 6 | 7 | import 'views/register/register_form.dart'; 8 | 9 | class RegisterPage extends StatelessWidget { 10 | const RegisterPage({super.key}); 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | return Scaffold( 15 | appBar: AppBar( 16 | title: Text(context.localizations.register_page_title), 17 | actions: const [ 18 | BondPopMenuButton(), 19 | ], 20 | ), 21 | body: SingleChildScrollView( 22 | child: AutofillGroup( 23 | child: Center( 24 | child: Padding( 25 | padding: const EdgeInsets.symmetric(horizontal: 24), 26 | child: Column( 27 | mainAxisAlignment: MainAxisAlignment.center, 28 | crossAxisAlignment: CrossAxisAlignment.center, 29 | children: [ 30 | const SizedBox(height: 64), 31 | SvgPicture.asset( 32 | AppImagesAssets.logo, 33 | width: 95, 34 | height: 120, 35 | ), 36 | const SizedBox(height: 48), 37 | const RegisterForm(), 38 | const SizedBox(height: 16), 39 | ], 40 | ), 41 | ), 42 | ), 43 | ), 44 | ), 45 | ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/features/auth/presentation/views/login/new_account_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond/core/app_localizations.dart'; 2 | import 'package:flutter/gestures.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:bond_core/bond_core.dart'; 5 | import 'package:go_router/go_router.dart'; 6 | 7 | class NewAccountView extends StatelessWidget { 8 | const NewAccountView({super.key}); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return Container( 13 | alignment: Alignment.center, 14 | height: 56, 15 | child: RichText( 16 | strutStyle: StrutStyle.fromTextStyle( 17 | context.textTheme.labelLarge!, 18 | ), 19 | text: TextSpan( 20 | children: [ 21 | TextSpan( 22 | text: context.localizations.login_page_not_have_account, 23 | style: context.textTheme.bodySmall, 24 | ), 25 | TextSpan( 26 | recognizer: TapGestureRecognizer() 27 | ..onTap = () => context.push('/register'), 28 | text: context.localizations.login_page_new_account_button, 29 | style: context.textTheme.labelSmall, 30 | ), 31 | ], 32 | ), 33 | ), 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/features/auth/routes.dart: -------------------------------------------------------------------------------- 1 | library; 2 | 3 | import 'presentation/login_page.dart'; 4 | import 'presentation/register_page.dart'; 5 | 6 | import 'package:go_router/go_router.dart'; 7 | 8 | final authRoutes = [ 9 | GoRoute( 10 | path: '/login', 11 | builder: (context, state) => const LoginPage(), 12 | ), 13 | GoRoute( 14 | path: '/register', 15 | builder: (context, state) => const RegisterPage(), 16 | ), 17 | ]; 18 | -------------------------------------------------------------------------------- /lib/features/main/presentation/main_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond/core/app_localizations.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:go_router/go_router.dart'; 4 | 5 | class MainPage extends StatelessWidget { 6 | const MainPage({ 7 | super.key, 8 | required this.body, 9 | }); 10 | 11 | final StatefulNavigationShell body; 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return Scaffold( 16 | body: body, 17 | bottomNavigationBar: Container( 18 | decoration: const BoxDecoration( 19 | border: Border( 20 | top: BorderSide( 21 | color: Colors.grey, 22 | width: 0.5, 23 | ), 24 | ), 25 | ), 26 | child: BottomNavigationBar( 27 | currentIndex: body.currentIndex, 28 | onTap: body.goBranch, 29 | items: [ 30 | BottomNavigationBarItem( 31 | icon: const Icon(Icons.home), 32 | label: context.localizations.navigation_bar_home, 33 | ), 34 | BottomNavigationBarItem( 35 | icon: const Icon(Icons.collections), 36 | label: context.localizations.navigation_bar_collections, 37 | ), 38 | ], 39 | ), 40 | ), 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/features/main/routes.dart: -------------------------------------------------------------------------------- 1 | library; 2 | 3 | import 'package:bond/features/main/presentation/main_page.dart'; 4 | import 'package:bond/features/more/presentation/more_page.dart'; 5 | import 'package:go_router/go_router.dart'; 6 | 7 | import '../post/presentations/posts_page.dart'; 8 | 9 | final mainRoutes = [ 10 | StatefulShellRoute.indexedStack( 11 | builder: (context, state, navigationShell) { 12 | return MainPage(body: navigationShell); 13 | }, 14 | branches: [ 15 | StatefulShellBranch( 16 | routes: [ 17 | GoRoute( 18 | path: '/home', 19 | builder: (context, state) => const PostsPage(), 20 | ), 21 | ], 22 | ), 23 | StatefulShellBranch( 24 | routes: [ 25 | GoRoute( 26 | path: '/more', 27 | builder: (context, state) => const MorePage(), 28 | ), 29 | ], 30 | ), 31 | ], 32 | ), 33 | ]; 34 | -------------------------------------------------------------------------------- /lib/features/more/presentation/more_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 3 | 4 | class MorePage extends ConsumerWidget { 5 | const MorePage({super.key}); 6 | 7 | @override 8 | Widget build(BuildContext context, WidgetRef ref) { 9 | return Scaffold( 10 | appBar: AppBar( 11 | title: const Text("More"), 12 | ), 13 | body: const SizedBox(), 14 | ); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/features/notification/presentations/ui/widgets/badge_unread_notification.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:bond_core/bond_core.dart'; 3 | 4 | class BadgeUnreadNotification extends StatelessWidget { 5 | const BadgeUnreadNotification({ 6 | this.isRead = false, 7 | super.key, 8 | }); 9 | 10 | final bool isRead; 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | return !isRead 15 | ? Container( 16 | width: 10, 17 | height: 10, 18 | decoration: BoxDecoration( 19 | color: context.colorScheme.primary, 20 | shape: BoxShape.circle, 21 | ), 22 | ) 23 | : const SizedBox.shrink(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/features/notification/presentations/ui/widgets/header_title_image.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:bond_core/bond_core.dart'; 3 | 4 | class HeaderTitleImage extends StatelessWidget { 5 | const HeaderTitleImage({ 6 | required this.senderName, 7 | required this.senderImage, 8 | super.key, 9 | }); 10 | 11 | final String senderName; 12 | final String senderImage; 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | return Row( 17 | children: [ 18 | Expanded( 19 | child: Text( 20 | senderName, 21 | style: context.textTheme.titleSmall, 22 | overflow: TextOverflow.ellipsis, 23 | ), 24 | ), 25 | ], 26 | ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lib/features/notification/presentations/ui/widgets/notification_item.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:bond_core/bond_core.dart'; 3 | 4 | import 'badge_unread_notification.dart'; 5 | import 'header_title_image.dart'; 6 | 7 | class NotificationItem extends StatelessWidget { 8 | const NotificationItem({ 9 | required this.onTap, 10 | required this.senderName, 11 | required this.senderImage, 12 | required this.notificationTitle, 13 | required this.isRead, 14 | required this.createAt, 15 | super.key, 16 | }); 17 | 18 | final VoidCallback onTap; 19 | final String senderName; 20 | final String senderImage; 21 | final String notificationTitle; 22 | final bool isRead; 23 | final DateTime createAt; 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | return GestureDetector( 28 | onTap: onTap, 29 | child: Container( 30 | padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 17), 31 | child: Row( 32 | children: [ 33 | Expanded( 34 | child: Column( 35 | crossAxisAlignment: CrossAxisAlignment.start, 36 | children: [ 37 | /// Header Title Image 38 | HeaderTitleImage( 39 | senderName: senderName, 40 | senderImage: senderImage, 41 | ), 42 | const SizedBox(height: 4), 43 | 44 | /// Title 45 | Text( 46 | notificationTitle, 47 | style: context.textTheme.titleSmall, 48 | softWrap: true, 49 | ), 50 | 51 | /// Time Ago 52 | Text( 53 | createAt.toIso8601String(), 54 | style: context.textTheme.bodySmall, 55 | ) 56 | ], 57 | ), 58 | ), 59 | const SizedBox(width: 16), 60 | BadgeUnreadNotification(isRead: isRead) 61 | ], 62 | ), 63 | ), 64 | ); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /lib/features/notification/routes.dart: -------------------------------------------------------------------------------- 1 | library; 2 | 3 | import 'package:bond/features/auth/auth.dart'; 4 | import 'package:bond_core/bond_core.dart'; 5 | import 'package:bond_notifications/bond_notifications.dart'; 6 | import 'package:flutter/material.dart'; 7 | import 'package:go_router/go_router.dart'; 8 | 9 | import 'presentations/ui/notifications_page.dart'; 10 | 11 | final notificationRoutes = [ 12 | GoRoute( 13 | path: '/notifications', 14 | builder: (context, state) => NotificationsPage( 15 | notificationCenterProvider: sl(), 16 | ), 17 | redirect: (BuildContext context, GoRouterState state) => 18 | Auth.check() ? null : '/login', 19 | ), 20 | ]; 21 | -------------------------------------------------------------------------------- /lib/features/post/data/api.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond_network/bond_network.dart'; 2 | 3 | import 'models/post.dart'; 4 | 5 | class PostsApi { 6 | final BondFire _bondFire; 7 | 8 | PostsApi(this._bondFire); 9 | 10 | Future> posts([String? url]) => _bondFire 11 | .get>(url ?? '/posts') 12 | .cache() 13 | .header(Api.headers()) 14 | .factory(ListResponse.fromJson) 15 | .errorFactory(ServerError.fromJson) 16 | .execute(); 17 | 18 | Future> random() => _bondFire 19 | .get>('/posts') 20 | .factory(SingleResponse.fromJson) 21 | .header(Api.headers()) 22 | .errorFactory(ServerError.fromJson) 23 | .execute(); 24 | 25 | Future> post(String id) => _bondFire 26 | .get>('/posts/$id') 27 | .cache() 28 | .queryParameters({'id': id}) 29 | .factory(SingleResponse.fromJson) 30 | .header(Api.headers()) 31 | .errorFactory(ServerError.fromJson) 32 | .execute(); 33 | } 34 | -------------------------------------------------------------------------------- /lib/features/post/data/models/author.dart: -------------------------------------------------------------------------------- 1 | part of 'post.dart'; 2 | 3 | @JsonSerializable() 4 | class Author { 5 | final String uuid; 6 | @JsonKey(name: 'updated_at') 7 | final DateTime updatedAt; 8 | final String username; 9 | final String name; 10 | @JsonKey(name: 'first_name') 11 | final String firstName; 12 | @JsonKey(name: 'last_name') 13 | final String? lastName; 14 | final String avatar; 15 | @JsonKey(name: 'twitter_username') 16 | final String? twitterUsername; 17 | @JsonKey(name: 'instagram_username') 18 | final String? instagramUsername; 19 | final String? bio; 20 | @JsonKey(name: 'total_likes') 21 | final num totalLikes; 22 | @JsonKey(name: 'total_photos') 23 | final num totalPhotos; 24 | 25 | Author({ 26 | required this.uuid, 27 | required this.updatedAt, 28 | required this.username, 29 | required this.name, 30 | required this.firstName, 31 | this.lastName, 32 | required this.avatar, 33 | this.twitterUsername, 34 | this.instagramUsername, 35 | this.bio, 36 | required this.totalLikes, 37 | required this.totalPhotos, 38 | }); 39 | 40 | factory Author.fromJson(Map json) => _$AuthorFromJson(json); 41 | 42 | Map toJson() => _$AuthorToJson(this); 43 | } 44 | -------------------------------------------------------------------------------- /lib/features/post/data/models/post.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | import 'package:bond_network/bond_network.dart'; 3 | 4 | part 'author.dart'; 5 | part 'post.g.dart'; 6 | part 'urls.dart'; 7 | 8 | @JsonSerializable() 9 | class Post extends Model { 10 | final String uuid; 11 | @JsonKey(name: 'created_at') 12 | final DateTime createdAt; 13 | @JsonKey(name: 'updated_at') 14 | final DateTime updatedAt; 15 | final String color; 16 | final String? description; 17 | final Urls urls; 18 | final num likes; 19 | final Author author; 20 | final num views; 21 | final num downloads; 22 | 23 | const Post({ 24 | required this.uuid, 25 | required this.createdAt, 26 | required this.updatedAt, 27 | required this.color, 28 | this.description, 29 | required this.urls, 30 | required this.likes, 31 | required this.author, 32 | required this.views, 33 | required this.downloads, 34 | }) : super(id: -1); 35 | 36 | factory Post.fromJson(Map json) => _$PostFromJson(json); 37 | 38 | @override 39 | Map toJson() => _$PostToJson(this); 40 | } 41 | -------------------------------------------------------------------------------- /lib/features/post/data/models/urls.dart: -------------------------------------------------------------------------------- 1 | part of 'post.dart'; 2 | 3 | @JsonSerializable() 4 | class Urls { 5 | final String raw; 6 | final String full; 7 | final String regular; 8 | final String small; 9 | final String thumb; 10 | @JsonKey(name: 'small_s3') 11 | final String smallS3; 12 | 13 | Urls({ 14 | required this.raw, 15 | required this.full, 16 | required this.regular, 17 | required this.small, 18 | required this.thumb, 19 | required this.smallS3, 20 | }); 21 | 22 | factory Urls.fromJson(Map json) => _$UrlsFromJson(json); 23 | 24 | Map toJson() => _$UrlsToJson(this); 25 | } 26 | -------------------------------------------------------------------------------- /lib/features/post/post_service_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond_core/bond_core.dart'; 2 | import 'package:get_it/get_it.dart'; 3 | 4 | import 'data/api.dart'; 5 | import 'data/models/post.dart'; 6 | 7 | class PostServiceProvider extends ServiceProvider with ResponseDecoding { 8 | @override 9 | Future register(GetIt it) async { 10 | it.registerFactory(() => PostsApi(it())); 11 | } 12 | 13 | @override 14 | Map get factories => { 15 | Post: Post.fromJson, 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /lib/features/post/presentations/post_details_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond/features/post/data/models/post.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 4 | 5 | import 'providers/post_provider.dart'; 6 | import 'views/share_button.dart'; 7 | 8 | class PostDetailsPage extends ConsumerWidget { 9 | const PostDetailsPage({ 10 | super.key, 11 | required this.id, 12 | this.post, 13 | }); 14 | 15 | final String id; 16 | final Post? post; 17 | 18 | @override 19 | Widget build(BuildContext context, WidgetRef ref) { 20 | if (post != null) { 21 | return _PostDetailsView(post: post!); 22 | } else { 23 | final postProvider = ref.watch(postFeatureProvider(id)); 24 | return postProvider.when( 25 | data: (post) => _PostDetailsView( 26 | post: post, 27 | ), 28 | error: (error, stackTrace) => Center( 29 | child: Text(error.toString()), 30 | ), 31 | loading: () => const CircularProgressIndicator.adaptive(), 32 | ); 33 | } 34 | } 35 | } 36 | 37 | class _PostDetailsView extends StatelessWidget { 38 | final Post post; 39 | 40 | const _PostDetailsView({required this.post}); 41 | 42 | @override 43 | Widget build(BuildContext context) { 44 | return Scaffold( 45 | appBar: AppBar( 46 | title: Text(post.author.name), 47 | actions: [ 48 | ShareButton( 49 | postImageUrl: post.urls.full, // Pass the post image URL 50 | ) 51 | ], 52 | ), 53 | body: SizedBox( 54 | height: double.maxFinite, 55 | child: Hero( 56 | tag: post.uuid, 57 | child: ClipRRect( 58 | borderRadius: BorderRadius.circular(12), 59 | child: Image.network( 60 | post.urls.regular, 61 | fit: BoxFit.fill, 62 | ), 63 | ), 64 | ), 65 | ), 66 | ); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /lib/features/post/presentations/posts_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond/features/post/presentations/providers/posts_provider.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 4 | 5 | import 'views/home_app_bar.dart'; 6 | import 'views/post_item.dart'; 7 | 8 | class PostsPage extends ConsumerWidget { 9 | const PostsPage({super.key}); 10 | 11 | @override 12 | Widget build(BuildContext context, WidgetRef ref) { 13 | final postsState = ref.watch(postsProvider); 14 | final postsController = ref.read(postsProvider.notifier); 15 | return Scaffold( 16 | appBar: const HomeAppBar(), 17 | body: postsState.when( 18 | loading: () => const Center(child: CircularProgressIndicator()), 19 | data: (posts) => 20 | SingleChildScrollView( 21 | controller: postsController.scrollController, 22 | child: Column( 23 | children: [ 24 | GridView.count( 25 | shrinkWrap: true, 26 | physics: const NeverScrollableScrollPhysics(), 27 | padding: const EdgeInsets.all(16), 28 | crossAxisCount: 2, 29 | childAspectRatio: 0.6, 30 | mainAxisSpacing: 6.0, 31 | crossAxisSpacing: 6.0, 32 | children: posts.data.data.map((post) { 33 | return PostItem(post: post); 34 | }).toList(), 35 | ), 36 | if (posts.isLoading) const CircularProgressIndicator 37 | .adaptive(), 38 | ], 39 | ), 40 | ), 41 | error: (error, stackTrace) => Center(child: Text(error.toString())), 42 | ), 43 | ); 44 | } 45 | } -------------------------------------------------------------------------------- /lib/features/post/presentations/providers/list_state.dart: -------------------------------------------------------------------------------- 1 | // extract to bond network package 2 | import 'package:bond_network/bond_network.dart'; 3 | import 'package:equatable/equatable.dart'; 4 | import 'package:flutter/widgets.dart'; 5 | 6 | enum ListStatus { initial, loading, success, failed } 7 | 8 | class ListState extends Equatable { 9 | const ListState(this.data, this.status, this.error); 10 | 11 | final ListResponse data; 12 | 13 | final ListStatus status; 14 | 15 | final String? error; 16 | 17 | bool get hasMoreData => data.links?.next != null; 18 | 19 | bool get isLoading => status == ListStatus.loading; 20 | 21 | factory ListState.initial() => ListState( 22 | ListResponse(data: List.empty(growable: true)), 23 | ListStatus.initial, 24 | null, 25 | ); 26 | 27 | factory ListState.data(ListResponse data) => ListState( 28 | data, 29 | ListStatus.success, 30 | null, 31 | ); 32 | 33 | ListState loading() => copyWith(status: ListStatus.loading); 34 | 35 | ListState success(ListResponse newData) => copyWith( 36 | status: ListStatus.success, 37 | data: data.copyWith( 38 | data: List.of(data.data.followedBy(newData.data)), 39 | meta: newData.meta, 40 | links: newData.links, 41 | ), 42 | ); 43 | 44 | ListState failed(String error) => copyWith( 45 | status: ListStatus.failed, 46 | error: error, 47 | ); 48 | 49 | Widget when({ 50 | required Widget Function() initial, 51 | required Widget Function(List, bool loading) success, 52 | required Widget Function(String) failed, 53 | }) { 54 | switch (status) { 55 | case ListStatus.initial: 56 | return initial(); 57 | case ListStatus.loading: 58 | return success(data.data, true); 59 | case ListStatus.success: 60 | return success(data.data, false); 61 | case ListStatus.failed: 62 | return failed(error!); 63 | } 64 | } 65 | 66 | ListState copyWith({ 67 | ListResponse? data, 68 | ListStatus? status, 69 | String? error, 70 | }) { 71 | return ListState( 72 | data ?? this.data, 73 | status ?? this.status, 74 | error ?? this.error, 75 | ); 76 | } 77 | 78 | @override 79 | List get props => [ 80 | data, 81 | data.hashCode, 82 | data.data.length, 83 | status, 84 | error, 85 | ]; 86 | } 87 | -------------------------------------------------------------------------------- /lib/features/post/presentations/providers/post_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond/features/post/data/api.dart'; 2 | import 'package:bond/features/post/data/models/post.dart'; 3 | import 'package:bond_core/bond_core.dart'; 4 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 5 | 6 | final postFeatureProvider = 7 | FutureProvider.autoDispose.family((ref, id) async { 8 | final api = sl(); 9 | final response = await api.post(id); 10 | return response.data; 11 | }); 12 | -------------------------------------------------------------------------------- /lib/features/post/presentations/providers/posts_provider.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer'; 2 | 3 | import 'package:bond/features/post/data/api.dart'; 4 | import 'package:bond/features/post/data/models/post.dart'; 5 | import 'package:bond_core/bond_core.dart'; 6 | import 'package:flutter/material.dart'; 7 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 8 | 9 | import 'list_state.dart'; 10 | 11 | final postsProvider = 12 | AsyncNotifierProvider.autoDispose>( 13 | () { 14 | final scrollController = ScrollController(); 15 | 16 | return PostController(sl(), scrollController); 17 | }, 18 | ); 19 | 20 | class PostController extends AutoDisposeAsyncNotifier> { 21 | PostController(this._api, this.scrollController) : super(); 22 | 23 | final PostsApi _api; 24 | final ScrollController scrollController; 25 | 26 | @override 27 | Future> build() async { 28 | _initialize(); 29 | final response = await _api.posts(); 30 | return ListState.data(response); 31 | } 32 | 33 | void _initialize() { 34 | scrollController.addListener(_scrollControllerListener); 35 | ref.onDispose( 36 | () { 37 | scrollController.dispose(); 38 | scrollController.removeListener(_scrollControllerListener); 39 | }, 40 | ); 41 | } 42 | 43 | void _loadMore() async { 44 | if (!state.requireValue.hasMoreData) { 45 | log('_loadMore no more data', name: 'PostController'); 46 | return; 47 | } 48 | final nextUrl = state.requireValue.data.links?.next; 49 | state = AsyncData(state.requireValue.loading()); 50 | state = await AsyncValue.guard(() async { 51 | final response = await _api.posts(nextUrl); 52 | return state.requireValue.success(response); 53 | }); 54 | } 55 | 56 | void _scrollControllerListener() { 57 | final maxScroll = scrollController.position.maxScrollExtent; 58 | final currentScroll = scrollController.position.pixels; 59 | const delta = 200.0; 60 | if (maxScroll - currentScroll <= delta && 61 | state.value?.status != ListStatus.loading) { 62 | _loadMore(); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /lib/features/post/presentations/views/home_app_bar.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond/core/app_widgets.dart'; 2 | import 'package:bond/core/resources/app_assets.dart'; 3 | import 'package:flutter/material.dart'; 4 | 5 | class HomeAppBar extends StatelessWidget implements PreferredSizeWidget { 6 | const HomeAppBar({super.key}); 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return AppBar( 11 | centerTitle: false, 12 | title: Image.asset( 13 | AppImagesAssets.homeBond( 14 | Theme.of(context).brightness, 15 | Localizations.localeOf(context).languageCode, 16 | ), 17 | width: 90, 18 | ), 19 | actions: const [ 20 | BondPopMenuButton(), 21 | ], 22 | bottom: const PreferredSize( 23 | preferredSize: Size.fromHeight(4), 24 | child: Divider( 25 | height: 0.5, 26 | color: Colors.grey, 27 | ), 28 | ), 29 | ); 30 | } 31 | 32 | @override 33 | Size get preferredSize => const Size.fromHeight(kToolbarHeight + 4); 34 | } 35 | -------------------------------------------------------------------------------- /lib/features/post/presentations/views/post_item.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond/features/post/data/models/post.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:go_router/go_router.dart'; 4 | 5 | class PostItem extends StatelessWidget { 6 | const PostItem({super.key, required this.post}); 7 | 8 | final Post post; 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return GridTile( 13 | child: GestureDetector( 14 | onTap: () => context.push('/post/${post.uuid}', extra: post), 15 | child: Hero( 16 | tag: post.uuid, 17 | child: ClipRRect( 18 | borderRadius: BorderRadius.circular(12), 19 | child: Image.network( 20 | post.urls.regular, 21 | fit: BoxFit.cover, 22 | ), 23 | ), 24 | ), 25 | ), 26 | ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lib/features/post/presentations/views/share_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond/core/app_localizations.dart'; 2 | import 'package:bond/core/resources/app_icons.dart'; 3 | import 'package:bond_core/bond_core.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter_svg/flutter_svg.dart'; 6 | import 'package:share_plus/share_plus.dart'; 7 | 8 | class ShareButton extends StatelessWidget { 9 | const ShareButton({ 10 | required this.postImageUrl, 11 | super.key, 12 | }); 13 | 14 | final String postImageUrl; 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return IconButton( 19 | splashRadius: 20, 20 | onPressed: () => _onShare(context), 21 | icon: SvgPicture.asset( 22 | AppIcons.share, 23 | colorFilter: ColorFilter.mode( 24 | context.colorScheme.primary, 25 | BlendMode.srcIn, 26 | ), 27 | ), 28 | ); 29 | } 30 | 31 | void _onShare(BuildContext context) { 32 | Share.share(postImageUrl, subject: context.localizations.share_post_image); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /lib/features/post/routes.dart: -------------------------------------------------------------------------------- 1 | library; 2 | 3 | import 'package:go_router/go_router.dart'; 4 | 5 | import 'data/models/post.dart'; 6 | import 'presentations/post_details_page.dart'; 7 | 8 | final postRoutes = [ 9 | GoRoute( 10 | path: '/post/:id', 11 | builder: (context, state) => PostDetailsPage( 12 | id: state.pathParameters['id'].toString(), 13 | post: state.extra as Post?, 14 | ), 15 | ), 16 | ]; 17 | -------------------------------------------------------------------------------- /lib/features/update_app/data/models/current_version.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'platform_version.dart'; 4 | 5 | 6 | class CurrentVersion { 7 | const CurrentVersion({ 8 | required this.ios, 9 | required this.android, 10 | }); 11 | 12 | final PlatformVersion ios; 13 | 14 | final PlatformVersion android; 15 | 16 | factory CurrentVersion.fromJson(Map json) => CurrentVersion( 17 | ios: PlatformVersion.fromJson(json['ios'] as Map), 18 | android: 19 | PlatformVersion.fromJson(json['android'] as Map), 20 | ); 21 | 22 | Map toJson() => { 23 | 'ios': ios.toJson(), 24 | 'android': android.toJson(), 25 | }; 26 | 27 | PlatformVersion get platformVersion { 28 | if (Platform.isAndroid) { 29 | return android; 30 | } else { 31 | return ios; 32 | } 33 | } 34 | 35 | String get message { 36 | if (Platform.isAndroid) { 37 | return android.message; 38 | } else { 39 | return ios.message; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/features/update_app/data/models/platform_version.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'platform_version.g.dart'; 4 | 5 | @JsonSerializable() 6 | class PlatformVersion { 7 | const PlatformVersion({ 8 | required this.minVersion, 9 | required this.maxVersion, 10 | required this.message, 11 | }); 12 | @JsonKey(name: 'min_version') 13 | final int minVersion; 14 | @JsonKey(name: 'max_version') 15 | final int maxVersion; 16 | final String message; 17 | 18 | factory PlatformVersion.fromJson(Map json) => 19 | _$PlatformVersionFromJson(json); 20 | 21 | Map toJson() => _$PlatformVersionToJson(this); 22 | } 23 | -------------------------------------------------------------------------------- /lib/features/update_app/data/models/platform_version.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'platform_version.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | PlatformVersion _$PlatformVersionFromJson(Map json) => 10 | PlatformVersion( 11 | minVersion: json['min_version'] as int, 12 | maxVersion: json['max_version'] as int, 13 | message: json['message'] as String, 14 | ); 15 | 16 | Map _$PlatformVersionToJson(PlatformVersion instance) => 17 | { 18 | 'min_version': instance.minVersion, 19 | 'max_version': instance.maxVersion, 20 | 'message': instance.message, 21 | }; 22 | -------------------------------------------------------------------------------- /lib/features/update_app/data/models/update_app_default_value.dart: -------------------------------------------------------------------------------- 1 | class UpdateAppDefaultValue { 2 | static const Map defaultParameters = { 3 | 'appCurrentVersion': 4 | '{"ios":{"min_version":0,"max_version":0,"message":"حماية خصوصيتك تهمنا وأن تحصل على أفضل تجربة استخدام من أولوياتنا، يرجى تحديث نسختك الحالية"},"android":{"min_version":0,"max_version":0,"message":"حماية خصوصيتك تهمنا وأن تحصل على أفضل تجربة استخدام من أولوياتنا، يرجى تحديث نسختك الحالية"}}' 5 | }; 6 | static const fetchTimeout = Duration(minutes: 1); 7 | static const minimumFetchInterval = Duration(minutes: 5); 8 | } 9 | -------------------------------------------------------------------------------- /lib/features/update_app/data/update_app_service.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:bond/app/routes.dart'; 4 | import 'package:firebase_remote_config/firebase_remote_config.dart'; 5 | import 'package:flutter/material.dart'; 6 | import 'package:package_info_plus/package_info_plus.dart'; 7 | 8 | import 'models/current_version.dart'; 9 | import 'models/platform_version.dart'; 10 | 11 | class UpdateAppService { 12 | UpdateAppService({required this.remoteConfig, required this.packageInfo}); 13 | 14 | final FirebaseRemoteConfig remoteConfig; 15 | final PackageInfo packageInfo; 16 | 17 | void call() async { 18 | try { 19 | await remoteConfig.fetchAndActivate(); 20 | final jsonString = remoteConfig.getString('appCurrentVersion'); 21 | final remoteConfigVersion = 22 | CurrentVersion.fromJson(json.decode(jsonString)); 23 | final currentVersion = int.tryParse(packageInfo.buildNumber) ?? 0; 24 | final mustForceUpdate = checkForceUpdate( 25 | currentVersion, 26 | remoteConfigVersion.platformVersion, 27 | ); 28 | if (mustForceUpdate) { 29 | showForceUpdate(remoteConfigVersion); 30 | } 31 | } catch (e) { 32 | debugPrint('error initRemoteConfig $e'); 33 | } 34 | } 35 | 36 | void showForceUpdate(CurrentVersion remoteConfigVersion) { 37 | goRouter.push('/update_app?=message${remoteConfigVersion.message}'); 38 | } 39 | 40 | void showSoftUpdate() { 41 | final jsonString = remoteConfig.getString('appCurrentVersion'); 42 | final remoteConfigVersion = 43 | CurrentVersion.fromJson(json.decode(jsonString)); 44 | final currentVersion = int.tryParse(packageInfo.buildNumber) ?? 0; 45 | final isSoftUpdateApp = checkSoftUpdate( 46 | currentVersion, 47 | remoteConfigVersion.platformVersion, 48 | ); 49 | if (isSoftUpdateApp) { 50 | goRouter.push('/soft_update?=message${remoteConfigVersion.message}'); 51 | } 52 | } 53 | 54 | bool checkForceUpdate(int currentVersion, PlatformVersion platformVersion) => 55 | currentVersion < platformVersion.minVersion; 56 | 57 | bool checkSoftUpdate(int currentVersion, PlatformVersion platformVersion) => 58 | currentVersion < platformVersion.maxVersion; 59 | } 60 | -------------------------------------------------------------------------------- /lib/features/update_app/routes.dart: -------------------------------------------------------------------------------- 1 | library; 2 | 3 | import 'package:bond/core/route_helpers.dart'; 4 | import 'package:go_router/go_router.dart'; 5 | 6 | import 'presentations/page/soft_update_page.dart'; 7 | import 'presentations/page/update_app_page.dart'; 8 | 9 | final updateAppRoutes = [ 10 | GoRoute( 11 | path: '/update_app', 12 | builder: (context, state) => UpdateAppPage( 13 | message: state.uri.queryParameters['message'] as String, 14 | ), 15 | ), 16 | GoRoute( 17 | path: '/soft_update', 18 | pageBuilder: (context, state) { 19 | return ModalBottomSheetPage( 20 | child: SoftUpdatePage( 21 | message: state.uri.queryParameters['message'] as String, 22 | ), 23 | isScrollControlled: true, 24 | ); 25 | }, 26 | ), 27 | ]; 28 | -------------------------------------------------------------------------------- /lib/l10n/app_ar.arb: -------------------------------------------------------------------------------- 1 | { 2 | "login_page_title": "تسجيل الدخول", 3 | "filed_name_label": "الاسم", 4 | "filed_email_label": "البريد الإلكتروني", 5 | "filed_password_label": "كلمة المرور", 6 | "filed_confirm_password_label": "تأكيد كلمة المرور", 7 | "field_validator_required": "الحقل مطلوب", 8 | "field_validator_email": "البريد الإلكتروني غير صحيح", 9 | "field_validator_password": "كلمة المرور يجب أن تكون أكثر من 6 أحرف", 10 | "field_validator_confirm_password": "كلمة المرور غير متطابقة", 11 | "field_login": "هناك خطأ في تسجيل الدخول يرجى المحاولة لاحقا", 12 | "login_page_login_button": "تسجيل الدخول", 13 | "login_page_not_have_account": "ليس لديك حساب؟", 14 | "login_page_new_account_button": " حساب جديد ", 15 | "register_page_title": "حساب جديد", 16 | "login_page_register_button": "تسجيل", 17 | "home_page_title": "BOND", 18 | "notification_page_title": "مركز التنبيهات", 19 | "popup_menu_language_title": "تغيير اللغة", 20 | "popup_menu_theme": "تغيير المظهر", 21 | "popup_menu_logout": "تسجيل الخروج", 22 | "popup_menu_notification_center": "مركز التنبيهات", 23 | "navigation_bar_home": "الرئيسية", 24 | "navigation_bar_collections": "المجموعات", 25 | "navigation_bar_more": "المزيد", 26 | "update_app" : "حان وقت التحديث", 27 | "update_app_text" : "ليصلك كل جديد يتم إضافته، قم بتحديث تطبيق راسل", 28 | "update_app_now" : "تحديث الآن", 29 | "share_post_image": "مشاركة الصورة" 30 | } -------------------------------------------------------------------------------- /lib/l10n/app_en.arb: -------------------------------------------------------------------------------- 1 | { 2 | "login_page_title": "Login", 3 | "filed_name_label": "Name", 4 | "filed_email_label": "Email", 5 | "filed_password_label": "Password", 6 | "filed_confirm_password_label": "Confirm Password", 7 | "field_validator_required": "Field is required", 8 | "field_validator_email": "Invalid email address", 9 | "field_validator_password": "Password must be at least 6 characters long", 10 | "field_validator_confirm_password": "Passwords do not match", 11 | "field_login": "There was an error logging in, please try again later", 12 | "login_page_login_button": "Login", 13 | "login_page_not_have_account": "Don't have an account?", 14 | "login_page_new_account_button": " Create an account ", 15 | "register_page_title": "New Account", 16 | "login_page_register_button": "Register", 17 | "home_page_title": "BOND", 18 | "notification_page_title": "Notifications Center", 19 | "popup_menu_language_title": "Change Language", 20 | "popup_menu_theme": "Change Theme", 21 | "popup_menu_logout": "Logout", 22 | "popup_menu_notification_center": "Notifications Center", 23 | "navigation_bar_home": "Home", 24 | "navigation_bar_collections": "Collections", 25 | "navigation_bar_more": "More", 26 | "update_app" : "It's time to update", 27 | "update_app_text" : "To receive all new updates, update the Bond app", 28 | "update_app_now" : "Update now", 29 | "share_post_image": "Share image" 30 | 31 | } -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond_core/bond_core.dart'; 2 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 3 | 4 | import 'app/app.dart'; 5 | import 'app/app_run_tasks.dart'; 6 | import 'bond_app.dart'; 7 | 8 | void main() => run( 9 | () => const ProviderScope( 10 | child: BondApp(), 11 | ), 12 | tasks: RunAppTasks(), 13 | providers: providers, 14 | ); 15 | -------------------------------------------------------------------------------- /lib/providers/analytics_service_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond/core/app_analytics.dart'; 2 | import 'package:bond_app_analytics/bond_app_analytics.dart'; 3 | import 'package:firebase_analytics/firebase_analytics.dart'; 4 | import 'package:get_it/get_it.dart'; 5 | import 'package:bond_core/bond_core.dart'; 6 | 7 | import '../config/analytics.dart'; 8 | 9 | class AnalyticsServiceProvider extends ServiceProvider { 10 | @override 11 | Future register(GetIt it) async { 12 | AnalyticsConfig.providers.forEach( 13 | (key, value) { 14 | if (value['driver'] == 'firebase_analytics_provider') { 15 | it.registerFactory( 16 | () => FirebaseAnalyticsProvider(FirebaseAnalytics.instance), 17 | instanceName: 'firebase_analytics_provider', 18 | ); 19 | } 20 | }, 21 | ); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/providers/api_service_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond/config/configs.dart'; 2 | import 'package:bond/features/auth/auth.dart'; 3 | import 'package:bond_core/bond_core.dart'; 4 | import 'package:bond_network/bond_network.dart'; 5 | import 'package:dio/dio.dart'; 6 | import 'package:flutter/foundation.dart'; 7 | import 'package:get_it/get_it.dart'; 8 | import 'package:pretty_dio_logger/pretty_dio_logger.dart'; 9 | 10 | class ApiServiceProvider extends ServiceProvider { 11 | @override 12 | Future register(GetIt it) async { 13 | final baseOptions = BaseOptions( 14 | connectTimeout: Duration(seconds: config('CONNECT_TIMEOUT')), 15 | sendTimeout: Duration(seconds: config('SEND_TIMEOUT')), 16 | receiveTimeout: Duration(seconds: config('RECEIVE_TIMEOUT')), 17 | receiveDataWhenStatusError: config('RECEIVE_DATA_WHEN_STATUS_ERROR'), 18 | baseUrl: config('API_BASE_URL'), 19 | ); 20 | Api.extraHeaders = () { 21 | return { 22 | if (Auth.check()) 'Authorization': 'Bearer ${Auth.token()}', 23 | }; 24 | }; 25 | baseOptions.headers = Api.headers(); 26 | final dio = Dio(baseOptions); 27 | if (kDebugMode) { 28 | dio.interceptors.add( 29 | PrettyDioLogger( 30 | requestHeader: true, 31 | requestBody: true, 32 | responseBody: true, 33 | responseHeader: false, 34 | error: true, 35 | compact: true, 36 | maxWidth: 90), 37 | ); 38 | } 39 | it.registerLazySingleton(() => dio); 40 | it.registerLazySingleton(() => BondFire()); 41 | it.registerLazySingleton(() => ApiClient(it())); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/providers/app_service_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond/features/update_app/data/update_app_service.dart'; 2 | import 'package:bond_core/bond_core.dart'; 3 | import 'package:flutter/foundation.dart'; 4 | import 'package:get_it/get_it.dart'; 5 | import 'package:shared_preferences/shared_preferences.dart'; 6 | 7 | class AppServiceProvider extends ServiceProvider { 8 | @override 9 | Future register(GetIt it) async { 10 | final sharedPreferences = await SharedPreferences.getInstance(); 11 | it.registerLazySingleton(() => sharedPreferences); 12 | 13 | if (!kIsWeb) { 14 | it.registerSingleton( 15 | UpdateAppService(remoteConfig: it(), packageInfo: it())..call(), 16 | ); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/providers/cache_service_provider.dart: -------------------------------------------------------------------------------- 1 | import 'dart:core'; 2 | 3 | import 'package:bond/core/cache/secure_storage_cache_driver.dart'; 4 | import 'package:bond_cache/bond_cache.dart'; 5 | import 'package:bond_core/bond_core.dart'; 6 | import 'package:flutter_secure_storage/flutter_secure_storage.dart'; 7 | import 'package:get_it/get_it.dart'; 8 | 9 | import '../config/cache.dart'; 10 | 11 | class CacheServiceProvider extends ServiceProvider { 12 | @override 13 | Future register(GetIt it) async { 14 | final store = CacheConfig.defaultStore; 15 | final defaultStoreDriver = CacheConfig.stores[store]?['driver']; 16 | 17 | CacheConfig.stores.forEach((key, value) { 18 | if (value['driver'] == defaultStoreDriver) { 19 | it.registerFactory( 20 | () => SharedPreferencesCacheDriver(it())); 21 | } else { 22 | if (value['driver'] == 'in_memory') { 23 | it.registerFactory( 24 | InMemoryCacheDriver.new, 25 | instanceName: 'in_memory', 26 | ); 27 | } else if (value['driver'] == 'secure_cache') { 28 | it.registerFactory(() => const FlutterSecureStorage()); 29 | it.registerSingletonAsync( 30 | () => SecureStorageCacheDriver(it()).loadAll(), 31 | instanceName: 'secure_cache', 32 | ); 33 | } 34 | } 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /lib/providers/firebase_service_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:bond/app/default_firebase_options.dart'; 2 | import 'package:bond/features/update_app/data/models/update_app_default_value.dart'; 3 | import 'package:bond_core/bond_core.dart'; 4 | import 'package:firebase_core/firebase_core.dart'; 5 | import 'package:firebase_remote_config/firebase_remote_config.dart'; 6 | import 'package:flutter/foundation.dart'; 7 | import 'package:get_it/get_it.dart'; 8 | import 'package:package_info_plus/package_info_plus.dart'; 9 | 10 | class FirebaseServiceProvider extends ServiceProvider { 11 | @override 12 | Future register(GetIt it) async { 13 | final packageInfo = await PackageInfo.fromPlatform(); 14 | it.registerSingleton(packageInfo); 15 | final firebaseApp = await Firebase.initializeApp( 16 | options: DefaultFirebaseOptions.currentPlatform, 17 | ); 18 | it.registerSingleton(firebaseApp); 19 | 20 | if (!kIsWeb) { 21 | final remoteConfig = FirebaseRemoteConfig.instance; 22 | remoteConfig.setDefaults(UpdateAppDefaultValue.defaultParameters); 23 | await remoteConfig.fetchAndActivate(); 24 | 25 | it.registerLazySingleton(() => remoteConfig); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lib/providers/forms_service_provider.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui'; 2 | 3 | import 'package:bond_cache/bond_cache.dart'; 4 | import 'package:bond_core/bond_core.dart'; 5 | import 'package:bond_form/validator_localizations.dart'; 6 | import 'package:get_it/get_it.dart'; 7 | 8 | class FormsServiceProvider extends ServiceProvider { 9 | @override 10 | Future register(GetIt it) async { 11 | //TODO: How to force this to reload when language changes? 12 | final local = Locale(Cache.get('language', defaultValue: 'en')); 13 | it.registerSingletonAsync( 14 | () async => ValidatorLocalizations.load(local), 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/dgph 7 | **/xcuserdata/ 8 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | import device_info_plus 9 | import firebase_analytics 10 | import firebase_core 11 | import firebase_crashlytics 12 | import firebase_messaging 13 | import firebase_remote_config 14 | import flutter_local_notifications 15 | import flutter_secure_storage_macos 16 | import in_app_review 17 | import package_info_plus 18 | import path_provider_foundation 19 | import share_plus 20 | import shared_preferences_foundation 21 | import url_launcher_macos 22 | 23 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 24 | DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) 25 | FLTFirebaseAnalyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAnalyticsPlugin")) 26 | FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) 27 | FLTFirebaseCrashlyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCrashlyticsPlugin")) 28 | FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin")) 29 | FLTFirebaseRemoteConfigPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseRemoteConfigPlugin")) 30 | FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) 31 | FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) 32 | InAppReviewPlugin.register(with: registry.registrar(forPlugin: "InAppReviewPlugin")) 33 | FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) 34 | PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) 35 | SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) 36 | SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) 37 | UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) 38 | } 39 | -------------------------------------------------------------------------------- /macos/Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.14' 2 | 3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 5 | 6 | project 'Runner', { 7 | 'Debug' => :debug, 8 | 'Profile' => :release, 9 | 'Release' => :release, 10 | } 11 | 12 | def flutter_root 13 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) 14 | unless File.exist?(generated_xcode_build_settings_path) 15 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" 16 | end 17 | 18 | File.foreach(generated_xcode_build_settings_path) do |line| 19 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 20 | return matches[1].strip if matches 21 | end 22 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" 23 | end 24 | 25 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 26 | 27 | flutter_macos_podfile_setup 28 | 29 | target 'Runner' do 30 | use_frameworks! 31 | use_modular_headers! 32 | 33 | flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) 34 | end 35 | 36 | post_install do |installer| 37 | installer.pods_project.targets.each do |target| 38 | flutter_additional_macos_build_settings(target) 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /macos/Production/GoogleService-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | API_KEY 6 | AIzaSyBC8Jb_W3UwqIVcq9OE7WrcF3sQerxDdsQ 7 | GCM_SENDER_ID 8 | 1077101979846 9 | PLIST_VERSION 10 | 1 11 | BUNDLE_ID 12 | ps.app.flutterBond 13 | PROJECT_ID 14 | flutter-bond-8ae02 15 | STORAGE_BUCKET 16 | flutter-bond-8ae02.appspot.com 17 | IS_ADS_ENABLED 18 | 19 | IS_ANALYTICS_ENABLED 20 | 21 | IS_APPINVITE_ENABLED 22 | 23 | IS_GCM_ENABLED 24 | 25 | IS_SIGNIN_ENABLED 26 | 27 | GOOGLE_APP_ID 28 | 1:1077101979846:ios:bb43f2ef1264d0e03a0fc7 29 | 30 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @NSApplicationMain 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon-production.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "app_icon_16.png", 5 | "idiom" : "mac", 6 | "scale" : "1x", 7 | "size" : "16x16" 8 | }, 9 | { 10 | "filename" : "app_icon_32.png", 11 | "idiom" : "mac", 12 | "scale" : "2x", 13 | "size" : "16x16" 14 | }, 15 | { 16 | "filename" : "app_icon_32.png", 17 | "idiom" : "mac", 18 | "scale" : "1x", 19 | "size" : "32x32" 20 | }, 21 | { 22 | "filename" : "app_icon_64.png", 23 | "idiom" : "mac", 24 | "scale" : "2x", 25 | "size" : "32x32" 26 | }, 27 | { 28 | "filename" : "app_icon_128.png", 29 | "idiom" : "mac", 30 | "scale" : "1x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "filename" : "app_icon_256.png", 35 | "idiom" : "mac", 36 | "scale" : "2x", 37 | "size" : "128x128" 38 | }, 39 | { 40 | "filename" : "app_icon_256.png", 41 | "idiom" : "mac", 42 | "scale" : "1x", 43 | "size" : "256x256" 44 | }, 45 | { 46 | "filename" : "app_icon_512.png", 47 | "idiom" : "mac", 48 | "scale" : "2x", 49 | "size" : "256x256" 50 | }, 51 | { 52 | "filename" : "app_icon_512.png", 53 | "idiom" : "mac", 54 | "scale" : "1x", 55 | "size" : "512x512" 56 | }, 57 | { 58 | "filename" : "app_icon_1024.png", 59 | "idiom" : "mac", 60 | "scale" : "2x", 61 | "size" : "512x512" 62 | } 63 | ], 64 | "info" : { 65 | "author" : "xcode", 66 | "version" : 1 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon-production.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/macos/Runner/Assets.xcassets/AppIcon-production.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon-production.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/macos/Runner/Assets.xcassets/AppIcon-production.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon-production.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/macos/Runner/Assets.xcassets/AppIcon-production.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon-production.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/macos/Runner/Assets.xcassets/AppIcon-production.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon-production.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/macos/Runner/Assets.xcassets/AppIcon-production.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon-production.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/macos/Runner/Assets.xcassets/AppIcon-production.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon-production.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/macos/Runner/Assets.xcassets/AppIcon-production.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon-staging.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "author": "xcode", 4 | "version": 1 5 | }, 6 | "images": [ 7 | { 8 | "size": "16x16", 9 | "idiom": "mac", 10 | "filename": "app_icon_16.png", 11 | "scale": "1x" 12 | }, 13 | { 14 | "size": "16x16", 15 | "idiom": "mac", 16 | "filename": "app_icon_32.png", 17 | "scale": "2x" 18 | }, 19 | { 20 | "size": "32x32", 21 | "idiom": "mac", 22 | "filename": "app_icon_32.png", 23 | "scale": "1x" 24 | }, 25 | { 26 | "size": "32x32", 27 | "idiom": "mac", 28 | "filename": "app_icon_64.png", 29 | "scale": "2x" 30 | }, 31 | { 32 | "size": "128x128", 33 | "idiom": "mac", 34 | "filename": "app_icon_128.png", 35 | "scale": "1x" 36 | }, 37 | { 38 | "size": "128x128", 39 | "idiom": "mac", 40 | "filename": "app_icon_256.png", 41 | "scale": "2x" 42 | }, 43 | { 44 | "size": "256x256", 45 | "idiom": "mac", 46 | "filename": "app_icon_256.png", 47 | "scale": "1x" 48 | }, 49 | { 50 | "size": "256x256", 51 | "idiom": "mac", 52 | "filename": "app_icon_512.png", 53 | "scale": "2x" 54 | }, 55 | { 56 | "size": "512x512", 57 | "idiom": "mac", 58 | "filename": "app_icon_512.png", 59 | "scale": "1x" 60 | }, 61 | { 62 | "size": "512x512", 63 | "idiom": "mac", 64 | "filename": "app_icon_1024.png", 65 | "scale": "2x" 66 | } 67 | ] 68 | } -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon-staging.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/macos/Runner/Assets.xcassets/AppIcon-staging.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon-staging.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/macos/Runner/Assets.xcassets/AppIcon-staging.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon-staging.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/macos/Runner/Assets.xcassets/AppIcon-staging.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon-staging.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/macos/Runner/Assets.xcassets/AppIcon-staging.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon-staging.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/macos/Runner/Assets.xcassets/AppIcon-staging.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon-staging.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/macos/Runner/Assets.xcassets/AppIcon-staging.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon-staging.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/macos/Runner/Assets.xcassets/AppIcon-staging.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = flutter_bond 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = ps.app.flutterBond 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2023 ps.app. All rights reserved. 15 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.network.client 8 | 9 | com.apple.security.network.server 10 | 11 | keychain-access-groups 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController.init() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.network.client 8 | 9 | com.apple.security.network.server 10 | 11 | keychain-access-groups 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /macos/Runner/RunnerProfile Staging.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.network.client 8 | 9 | com.apple.security.network.server 10 | 11 | keychain-access-groups 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /macos/Staging/GoogleService-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | API_KEY 6 | AIzaSyCz95QyOlPlhPWZFUrduUsS5Q8g5boiQgc 7 | GCM_SENDER_ID 8 | 390157281889 9 | PLIST_VERSION 10 | 1 11 | BUNDLE_ID 12 | ps.app.flutterBond.staging 13 | PROJECT_ID 14 | flutter-bond-staging-7dd42 15 | STORAGE_BUCKET 16 | flutter-bond-staging-7dd42.appspot.com 17 | IS_ADS_ENABLED 18 | 19 | IS_ANALYTICS_ENABLED 20 | 21 | IS_APPINVITE_ENABLED 22 | 23 | IS_GCM_ENABLED 24 | 25 | IS_SIGNIN_ENABLED 26 | 27 | GOOGLE_APP_ID 28 | 1:390157281889:ios:ba7ec93993371072ab9820 29 | 30 | -------------------------------------------------------------------------------- /macos/firebase_app_id_file.json: -------------------------------------------------------------------------------- 1 | { 2 | "file_generated_by": "FlutterFire CLI", 3 | "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", 4 | "GOOGLE_APP_ID": "1:1060161913171:ios:a2ddfea873792ada55a1a6", 5 | "FIREBASE_PROJECT_ID": "flutter-bond-staging", 6 | "GCM_SENDER_ID": "1060161913171" 7 | } -------------------------------------------------------------------------------- /macos/production/GoogleService-Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/macos/production/GoogleService-Info.plist -------------------------------------------------------------------------------- /macos/staging/GoogleService-Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/macos/staging/GoogleService-Info.plist -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: bond 2 | description: Bond project. 3 | publish_to: 'none' 4 | version: 1.0.0+1 5 | 6 | environment: 7 | sdk: ">=3.3.0 <4.0.0" 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | 13 | flutter_localizations: 14 | sdk: flutter 15 | 16 | 17 | # Bond packages 18 | bond_core: ^0.0.3 19 | bond_cache: ^0.0.4+1 20 | bond_network: ^0.0.6 21 | bond_form: ^0.0.4+1 22 | bond_form_riverpod: ^0.0.2+7 23 | bond_app_analytics: ^0.1.0 24 | bond_notifications: ^0.1.0 25 | 26 | 27 | get_it: ^8.0.3 28 | open_store: ^0.5.0 29 | 30 | 31 | # network 32 | dio: ^5.8.0+1 33 | pretty_dio_logger: ^1.4.0 34 | 35 | # serialization 36 | json_serializable: ^6.9.3 37 | json_annotation: ^4.9.0 38 | 39 | #ui 40 | flutter_svg: ^2.0.17 41 | google_fonts: ^6.2.1 42 | 43 | # state management 44 | flutter_riverpod: ^2.6.1 45 | equatable: ^2.0.7 46 | 47 | # navigation 48 | go_router: ^14.8.0 49 | 50 | # utils 51 | flutter_native_splash: ^2.4.4 52 | device_info_plus: ^11.3.0 53 | faker: ^2.2.0 54 | 55 | # platforms packages 56 | universal_platform: ^1.1.0 57 | shared_preferences: ^2.5.2 58 | flutter_secure_storage: ^9.2.4 59 | package_info_plus: ^8.2.1 60 | flutter_local_notifications: ^18.0.1 61 | in_app_review: ^2.0.10 62 | share_plus: ^10.1.4 63 | 64 | # Firebase 65 | firebase_analytics: ^11.4.2 66 | firebase_core: ^3.11.0 67 | firebase_messaging: ^15.2.2 68 | firebase_crashlytics: ^4.3.2 69 | firebase_remote_config: ^5.4.0 70 | 71 | # localization 72 | intl: ^0.19.0 73 | 74 | dev_dependencies: 75 | flutter_test: 76 | sdk: flutter 77 | flutter_lints: ^5.0.0 78 | build_runner: ^2.4.14 79 | flutter_launcher_icons: ^0.14.3 80 | 81 | flutter: 82 | uses-material-design: true 83 | generate: true 84 | 85 | assets: 86 | - assets/icons/ 87 | - assets/images/ -------------------------------------------------------------------------------- /test/example_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | 3 | void main() { 4 | test('Counter value should be incremented', () { 5 | final counter = Counter(); 6 | 7 | counter.increment(); 8 | 9 | expect(counter.value, 1); 10 | }); 11 | } 12 | 13 | class Counter { 14 | int value = 0; 15 | 16 | void increment() => value++; 17 | 18 | void decrement() => value--; 19 | } 20 | -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/web/favicon.png -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/web/icons/Icon-512.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/web/icons/Icon-maskable-192.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onestudio-co/flutter-bond/822ac78fc9de1f5c0134ccdfebb537aba8f65bc9/web/icons/Icon-maskable-512.png -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | flutter_bond 33 | 34 | 35 | 39 | 40 | 41 | 42 | 43 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flutter_bond", 3 | "short_name": "flutter_bond", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#EB5C6C", 7 | "theme_color": "#F05D6E", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | }, 22 | { 23 | "src": "icons/Icon-maskable-192.png", 24 | "sizes": "192x192", 25 | "type": "image/png", 26 | "purpose": "maskable" 27 | }, 28 | { 29 | "src": "icons/Icon-maskable-512.png", 30 | "sizes": "512x512", 31 | "type": "image/png", 32 | "purpose": "maskable" 33 | } 34 | ] 35 | } --------------------------------------------------------------------------------