feat: upgrade wyatt_app_template #9
| @ -17,7 +17,7 @@ | ||||
| name: wyatt_app_template | ||||
| description: New app template for Wyatt Studio projects. | ||||
| 
 | ||||
| version: 0.1.2 | ||||
| version: 0.2.0 | ||||
| 
 | ||||
| vars: | ||||
|   display_name: | ||||
|  | ||||
| @ -35,5 +35,38 @@ void removeGitKeepFiles(String targetPath) { | ||||
| 
 | ||||
| Future<void> run(HookContext context) async { | ||||
|   final workingDirectory = Directory.current.path; | ||||
| 
 | ||||
|   /// Remove .gitkeep files | ||||
|   print('Removing .gitkeep files'); | ||||
|   removeGitKeepFiles(workingDirectory); | ||||
| 
 | ||||
|   /// dart pub get | ||||
|   print('Running `dart pub get`'); | ||||
|   await Process.run('dart', ['pub', 'get'], runInShell: true); | ||||
| 
 | ||||
|   /// dart format . --fix && dart fix . --apply | ||||
|   print('Running `dart format . --fix && dart fix . --apply`'); | ||||
|   await Process.run('dart', ['format', '.', '--fix'], runInShell: true); | ||||
|   await Process.run('dart', ['fix', '.', '--apply'], runInShell: true); | ||||
| 
 | ||||
|   final bundleId = context.vars['bundle_id'] as String?; | ||||
|   final appName = bundleId?.split('.').last; | ||||
|   final org = bundleId?.replaceAll('.$appName', ''); | ||||
| 
 | ||||
|   /// flutter create --platforms android,ios --org com.example --project-name example . | ||||
|   print( | ||||
|       'Running `flutter create --platforms android,ios --org $org --project-name $appName .`'); | ||||
|   await Process.run( | ||||
|       'flutter', | ||||
|       [ | ||||
|         'create', | ||||
|         '--platforms', | ||||
|         'android,ios', | ||||
|         '--org', | ||||
|         org ?? 'com.example', | ||||
|         '--project-name', | ||||
|         appName ?? 'example', | ||||
|         '.' | ||||
|       ], | ||||
|       runInShell: true); | ||||
| } | ||||
|  | ||||
| @ -47,8 +47,17 @@ app.*.map.json | ||||
| /android/app/debug | ||||
| /android/app/profile | ||||
| /android/app/release | ||||
| .mason/ | ||||
| 
 | ||||
| # Custom | ||||
| .mason/ | ||||
| .env | ||||
| !.env.example | ||||
| node_modules/ | ||||
| lib/gen/ | ||||
| **/*.g.dart | ||||
| **/*.freezed.dart | ||||
| android/fastlane/report.xml | ||||
| pubspec_overrides.yaml | ||||
| .fvm/flutter_sdk | ||||
| *.apk | ||||
| *.apks | ||||
|  | ||||
| @ -5,36 +5,12 @@ | ||||
|     "version": "0.2.0", | ||||
|     "configurations": [ | ||||
|         { | ||||
|             "name": "Launch development/debug:mocks", | ||||
|             "name": "Launch development/debug", | ||||
|             "request": "launch", | ||||
|             "type": "dart", | ||||
|             "program": "lib/main_development.dart", | ||||
|             "args": [ | ||||
|                 "--dart-define=dev_mode=mock", | ||||
|                 "--target", | ||||
|                 "lib/main_development.dart" | ||||
|             ], | ||||
|             "flutterMode": "debug" | ||||
|         }, | ||||
|         { | ||||
|             "name": "Launch development/debug:emulator", | ||||
|             "request": "launch", | ||||
|             "type": "dart", | ||||
|             "program": "lib/main_development.dart", | ||||
|             "args": [ | ||||
|                 "--dart-define=dev_mode=emulator", | ||||
|                 "--target", | ||||
|                 "lib/main_development.dart" | ||||
|             ], | ||||
|             "flutterMode": "debug" | ||||
|         }, | ||||
|         { | ||||
|             "name": "Launch development/debug:real", | ||||
|             "request": "launch", | ||||
|             "type": "dart", | ||||
|             "program": "lib/main_development.dart", | ||||
|             "args": [ | ||||
|                 "--dart-define=dev_mode=real", | ||||
|                 "--dart-define-from-file=config.dev.json", | ||||
|                 "--target", | ||||
|                 "lib/main_development.dart" | ||||
|             ], | ||||
| @ -46,6 +22,7 @@ | ||||
|             "type": "dart", | ||||
|             "program": "lib/main_staging.dart", | ||||
|             "args": [ | ||||
|                 "--dart-define-from-file=config.staging.json", | ||||
|                 "--target", | ||||
|                 "lib/main_staging.dart" | ||||
|             ], | ||||
| @ -55,8 +32,9 @@ | ||||
|             "name": "Launch production/debug", | ||||
|             "request": "launch", | ||||
|             "type": "dart", | ||||
|             "program": "lib/main_production.dart", | ||||
|             "program": "lib/main_produdction.dart", | ||||
|             "args": [ | ||||
|                 "--dart-define-from-file=config.prod.json", | ||||
|                 "--target", | ||||
|                 "lib/main_production.dart" | ||||
|             ], | ||||
| @ -66,8 +44,9 @@ | ||||
|             "name": "Launch production/release", | ||||
|             "request": "launch", | ||||
|             "type": "dart", | ||||
|             "program": "lib/main_production.dart", | ||||
|             "program": "lib/main_produdction.dart", | ||||
|             "args": [ | ||||
|                 "--dart-define-from-file=config.prod.json", | ||||
|                 "--target", | ||||
|                 "lib/main_production.dart" | ||||
|             ], | ||||
|  | ||||
| @ -7,47 +7,82 @@ A short project description | ||||
| * Flutter <https://flutter.dev/> | ||||
| * Taskfile <https://taskfile.dev/> | ||||
| 
 | ||||
| ### Configuration | ||||
| > **Warning** Before anything, you need to generate some files | ||||
| 
 | ||||
| At the build time, the app will read the environment variables from `config.json` file. | ||||
| ```sh | ||||
| task bootstrap # to bootstrap the project | ||||
| ``` | ||||
| 
 | ||||
| The important variable is `DEV_MODE` which can be `mock` , `local` or `real` . | ||||
| ## Configuration | ||||
| 
 | ||||
| ### Environment variables | ||||
| 
 | ||||
| ```sh | ||||
| cp .env.example .env | ||||
| ``` | ||||
| 
 | ||||
| This file contains the secrets variables. You need to fill them. | ||||
| 
 | ||||
| At the build time, the app will read the environment variables from `config.<ENV>.json` file. | ||||
| 
 | ||||
| You can enable/disable some features | ||||
| 
 | ||||
| ```json | ||||
| { | ||||
|   "DEV_MODE": "local" | ||||
|   "FEATURE_FLAGS": "logger" // Separated by comma "," | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| > **Note** `local` can refer to a local server or a local emulator. | ||||
| You can also customize data source | ||||
| 
 | ||||
| ### Taskfile | ||||
| ```json | ||||
| { | ||||
|   "DATA_SOURCE": "mock" // Or "api" for example | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| Available tasks: | ||||
| ### Splash and icons | ||||
| 
 | ||||
| | Commande | Description | Alias | | ||||
| | --- | --- | --- | | ||||
| | clean | Nettoie l'environnement de travail | cl | | ||||
| | format | Formate le code | fmt | | ||||
| | help | Affiche la boîte de dialogue d'aide | h, default | | ||||
| | lint | Vérifie la qualité du code | l | | ||||
| | start-emulators | Démarre les émulateurs nécessaires | emu | | ||||
| | build:android | Construit le fichier APK pour Android | build:a | | ||||
| | build:ios | Construit le fichier IPA pour iOS | build:i | | ||||
| | gen:build | Exécute le générateur de build | gen:b | | ||||
| | gen:build-delete | Exécute le générateur de build et supprime les sorties en conflit | gen:d | | ||||
| | gen:clean | Nettoie le générateur de build | gen:c | | ||||
| | gen:intl | Génère un fichier d'internationalisation | gen:i | | ||||
| | gen:watch | Exécute le générateur de build en mode surveillance | gen:w | | ||||
| | pub:get | Obtient les dernières dépendances | pub:g | | ||||
| | pub:outdated | Vérifie les dépendances obsolètes | pub:o | | ||||
| | pub:upgrade | Met à jour les dépendances | pub:u | | ||||
| | pub:upgrade-major | Met à jour les dépendances majeures | pub:um | | ||||
| | pub:validate | Exécute le validateur de dépendances | pub:v | | ||||
| | run:dev | Lance l'application en environnement de développement | run:d | | ||||
| | run:logs | Affiche la sortie de journalisation pour les applications Flutter en cours d'exécution | run:l | | ||||
| | run:prod | Lance l'application en environnement de production | run:p | | ||||
| | run:staging | Lance l'application en environnement de pré-production | run:s | | ||||
| To generate splash screen and icons, you need to run the following command: | ||||
| 
 | ||||
| ```sh | ||||
| task gen:splash # to generate splash screen | ||||
| task gen:icons # to generate icons | ||||
| ``` | ||||
| 
 | ||||
| ## Taskfile | ||||
| 
 | ||||
| ### Commands | ||||
| 
 | ||||
| <details> | ||||
|    <summary>To display available commands run <code>task help</code></summary> | ||||
| 
 | ||||
| | Commande                  | Description                                                   | Aliases                        | | ||||
| |---------------------------|---------------------------------------------------------------|--------------------------------| | ||||
| | `bootstrap` | Bootstraps the project.                                      | `bs` | | ||||
| | `clean` | Cleans the environment.                                      | `cl` | | ||||
| | `decrypt-android-keys` | Decrypt Android keys                                         | `dak` | | ||||
| | `encrypt-android-keys` | Encrypt Android keys                                         | `eak` | | ||||
| | `format` | Formats the code.                                            | `fmt` | | ||||
| | `help` | Help dialog.                                                 | `h` , `default` | | ||||
| | `lint` | Lints the code.                                              | `l` | | ||||
| | `build:android` | Building Android AAB                                         | `build:a` | | ||||
| | `build:ios` | Building iOS IPA                                             | `build:i` | | ||||
| | `gen:build` | Running build runner                                         | `gen:b` | | ||||
| | `gen:build-delete` | Running build runner with deletion of conflicting outputs    | `gen:d` | | ||||
| | `gen:clean` | Cleaning build runner                                        | `gen:c` | | ||||
| | `gen:intl` | Generating internationalization file                         | `gen:i` | | ||||
| | `pub:get` | Getting latest dependencies                                  | `pub:g` | | ||||
| | `pub:outdated` | Checking for outdated dependencies                           | `pub:o` | | ||||
| | `pub:upgrade` | Upgrading dependencies                                       | `pub:u` | | ||||
| | `pub:upgrade-major` | Upgrading dependencies                                       | `pub:um` | | ||||
| | `pub:validate` | Running dependency validator                                 | `pub:v` | | ||||
| | `run:dev` | Run app in development environment                           | `run:d` | | ||||
| | `run:logs` | Show log output for running Flutter apps                     | `run:l` | | ||||
| | `run:prod` | Run app in production environment                            | `run:p` | | ||||
| | `run:staging` | Run app in staging environment                               | `run:s` | | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ### Parameters | ||||
| 
 | ||||
| @ -58,3 +93,13 @@ task run:staging -- -d chrome | ||||
| ``` | ||||
| 
 | ||||
| > **Note** The `--` is required to pass options to the command. | ||||
| 
 | ||||
| ### Secrets | ||||
| 
 | ||||
| Use: | ||||
| 
 | ||||
| ```sh | ||||
| task decrypt-android-keys | ||||
| ``` | ||||
| 
 | ||||
| to decrypt the android keys (this assumes you have the passphrase in your .env file). | ||||
|  | ||||
| @ -25,14 +25,14 @@ tasks: | ||||
|     desc: Cleans the environment. | ||||
|     aliases: [cl] | ||||
|     cmds: | ||||
|       - echo -e "{{.GREEN}}{{.PREFIX}} Cleaning the project...{{.COLOROFF}}" | ||||
|       - echo -e "{{#mustacheCase}}.GREEN{{/mustacheCase}}{{#mustacheCase}}.PREFIX{{/mustacheCase}} Cleaning the project...{{#mustacheCase}}.COLOROFF{{/mustacheCase}}" | ||||
|       - flutter clean | ||||
| 
 | ||||
|   format: | ||||
|     desc: Formats the code. | ||||
|     aliases: [fmt] | ||||
|     cmds: | ||||
|       - echo -e "{{.GREEN}}{{.PREFIX}} Formatting the code...{{.COLOROFF}}" | ||||
|       - echo -e "{{#mustacheCase}}.GREEN{{/mustacheCase}}{{#mustacheCase}}.PREFIX{{/mustacheCase}} Formatting the code...{{#mustacheCase}}.COLOROFF{{/mustacheCase}}" | ||||
|       - flutter format --fix | ||||
|       - dart fix --apply | ||||
| 
 | ||||
| @ -40,12 +40,34 @@ tasks: | ||||
|     desc: Lints the code. | ||||
|     aliases: [l] | ||||
|     cmds: | ||||
|       - echo -e "{{.GREEN}}{{.PREFIX}} Verifying code...{{.COLOROFF}}" | ||||
|       - echo -e "{{#mustacheCase}}.GREEN{{/mustacheCase}}{{#mustacheCase}}.PREFIX{{/mustacheCase}} Verifying code...{{#mustacheCase}}.COLOROFF{{/mustacheCase}}" | ||||
|       - dart analyze . || (echo "Error in project"; exit 1) | ||||
| 
 | ||||
|   start-emulators: | ||||
|     desc: Start needed emulators. | ||||
|     aliases: [emu] | ||||
|   bootstrap: | ||||
|     desc: Bootstraps the project. | ||||
|     aliases: [bs] | ||||
|     cmds: | ||||
|       - echo -e "{{.GREEN}}{{.PREFIX}} Start Firebase emulators...{{.COLOROFF}}" | ||||
|       - firebase emulators:start --only auth,functions,firestore,storage --import=./functions/saved-data --export-on-exit=./functions/saved-data | ||||
|       - melos bs || true | ||||
|       - flutter pub get | ||||
|       - dart run build_runner build --delete-conflicting-outputs | ||||
|       - flutter gen-l10n | ||||
|       - fluttergen || true | ||||
| 
 | ||||
|   encrypt-android-keys: | ||||
|     desc: Encrypt Android keys | ||||
|     aliases: [eak] | ||||
|     cmds: | ||||
|       - cd android && jar cfvM android_keys.zip android_keys | ||||
|       - source '.env' && gpg --quiet --batch --yes --symmetric --passphrase=$ANDROID_KEYS_SECRET_PASSPHRASE --output android/android_keys.zip.gpg android/android_keys.zip | ||||
|       - rm -rf android/android_keys | ||||
|       - rm android/android_keys.zip | ||||
| 
 | ||||
|   decrypt-android-keys: | ||||
|     desc: Decrypt Android keys | ||||
|     aliases: [dak] | ||||
|     cmds: | ||||
|       - source '.env' && gpg --quiet --batch --yes --decrypt --passphrase=$ANDROID_KEYS_SECRET_PASSPHRASE --output android/android_keys.zip android/android_keys.zip.gpg | ||||
|       - cd android && jar xvf android_keys.zip | ||||
|       - mv android/android_keys/* android/ | ||||
|       - rm -rf android/android_keys | ||||
|       - rm android/android_keys.zip | ||||
|  | ||||
| @ -11,8 +11,8 @@ dart_code_metrics: | ||||
|   metrics: | ||||
|     cyclomatic-complexity: 20 | ||||
|     maximum-nesting-level: 5 | ||||
|     number-of-parameters: 5 | ||||
|     source-lines-of-code: 250 | ||||
|     number-of-parameters: 10 | ||||
|     source-lines-of-code: 400 | ||||
|   metrics-exclude: | ||||
|     - test/** | ||||
|   rules: | ||||
|  | ||||
| @ -1,13 +0,0 @@ | ||||
| gradle-wrapper.jar | ||||
| /.gradle | ||||
| /captures/ | ||||
| /gradlew | ||||
| /gradlew.bat | ||||
| /local.properties | ||||
| GeneratedPluginRegistrant.java | ||||
| 
 | ||||
| # Remember to never publicly share your keystore. | ||||
| # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app | ||||
| key.properties | ||||
| **/*.keystore | ||||
| **/*.jks | ||||
| @ -1,71 +0,0 @@ | ||||
| def localProperties = new Properties() | ||||
| def localPropertiesFile = rootProject.file('local.properties') | ||||
| if (localPropertiesFile.exists()) { | ||||
|     localPropertiesFile.withReader('UTF-8') { reader -> | ||||
|         localProperties.load(reader) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| def flutterRoot = localProperties.getProperty('flutter.sdk') | ||||
| if (flutterRoot == null) { | ||||
|     throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") | ||||
| } | ||||
| 
 | ||||
| def flutterVersionCode = localProperties.getProperty('flutter.versionCode') | ||||
| if (flutterVersionCode == null) { | ||||
|     flutterVersionCode = '1' | ||||
| } | ||||
| 
 | ||||
| def flutterVersionName = localProperties.getProperty('flutter.versionName') | ||||
| if (flutterVersionName == null) { | ||||
|     flutterVersionName = '1.0' | ||||
| } | ||||
| 
 | ||||
| apply plugin: 'com.android.application' | ||||
| apply plugin: 'kotlin-android' | ||||
| apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" | ||||
| 
 | ||||
| android { | ||||
|     compileSdkVersion flutter.compileSdkVersion | ||||
|     ndkVersion flutter.ndkVersion | ||||
| 
 | ||||
|     compileOptions { | ||||
|         sourceCompatibility JavaVersion.VERSION_1_8 | ||||
|         targetCompatibility JavaVersion.VERSION_1_8 | ||||
|     } | ||||
| 
 | ||||
|     kotlinOptions { | ||||
|         jvmTarget = '1.8' | ||||
|     } | ||||
| 
 | ||||
|     sourceSets { | ||||
|         main.java.srcDirs += 'src/main/kotlin' | ||||
|     } | ||||
| 
 | ||||
|     defaultConfig { | ||||
|         // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). | ||||
|         applicationId "io.wyattapp.start" | ||||
|         // You can update the following values to match your application needs. | ||||
|         // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. | ||||
|         minSdkVersion flutter.minSdkVersion | ||||
|         targetSdkVersion flutter.targetSdkVersion | ||||
|         versionCode flutterVersionCode.toInteger() | ||||
|         versionName flutterVersionName | ||||
|     } | ||||
| 
 | ||||
|     buildTypes { | ||||
|         release { | ||||
|             // TODO: Add your own signing config for the release build. | ||||
|             // Signing with the debug keys for now, so `flutter run --release` works. | ||||
|             signingConfig signingConfigs.debug | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| flutter { | ||||
|     source '../..' | ||||
| } | ||||
| 
 | ||||
| dependencies { | ||||
|     implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" | ||||
| } | ||||
| @ -1,8 +0,0 @@ | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     package="io.wyattapp.start"> | ||||
|     <!-- The INTERNET permission is required for development. Specifically, | ||||
|          the Flutter tool needs it to communicate with the running application | ||||
|          to allow setting breakpoints, to provide hot reload, etc. | ||||
|     --> | ||||
|     <uses-permission android:name="android.permission.INTERNET"/> | ||||
| </manifest> | ||||
| @ -1,25 +0,0 @@ | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="io.wyattapp.start"> | ||||
|     <application android:label="Display Name" android:name="${applicationName}" android:icon="@mipmap/ic_launcher"> | ||||
|         <activity | ||||
|             android:name=".MainActivity" | ||||
|             android:exported="true" | ||||
|             android:launchMode="singleTop" | ||||
|             android:theme="@style/LaunchTheme" | ||||
|             android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" | ||||
|             android:hardwareAccelerated="true" | ||||
|             android:windowSoftInputMode="adjustResize"> | ||||
|             <!-- Specifies an Android theme to apply to this Activity as soon as | ||||
|                  the Android process has started. This theme is visible to the user | ||||
|                  while the Flutter UI initializes. After that, this theme continues | ||||
|                  to determine the Window background behind the Flutter UI. --> | ||||
|             <meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme" /> | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.MAIN" /> | ||||
|                 <category android:name="android.intent.category.LAUNCHER" /> | ||||
|             </intent-filter> | ||||
|         </activity> | ||||
|         <!-- Don't delete the meta-data below. | ||||
|              This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> | ||||
|         <meta-data android:name="flutterEmbedding" android:value="2" /> | ||||
|     </application> | ||||
| </manifest> | ||||
| @ -1,6 +0,0 @@ | ||||
| package io.wyattapp.start | ||||
| 
 | ||||
| import io.flutter.embedding.android.FlutterActivity | ||||
| 
 | ||||
| class MainActivity: FlutterActivity() { | ||||
| } | ||||
| @ -1,12 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <!-- Modify this file to customize your launch splash screen --> | ||||
| <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <item android:drawable="?android:colorBackground" /> | ||||
| 
 | ||||
|     <!-- You can insert your own image assets here --> | ||||
|     <!-- <item> | ||||
|         <bitmap | ||||
|             android:gravity="center" | ||||
|             android:src="@mipmap/launch_image" /> | ||||
|     </item> --> | ||||
| </layer-list> | ||||
| @ -1,12 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <!-- Modify this file to customize your launch splash screen --> | ||||
| <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <item android:drawable="@android:color/white" /> | ||||
| 
 | ||||
|     <!-- You can insert your own image assets here --> | ||||
|     <!-- <item> | ||||
|         <bitmap | ||||
|             android:gravity="center" | ||||
|             android:src="@mipmap/launch_image" /> | ||||
|     </item> --> | ||||
| </layer-list> | ||||
| Before Width: | Height: | Size: 544 B | 
| Before Width: | Height: | Size: 442 B | 
| Before Width: | Height: | Size: 721 B | 
| Before Width: | Height: | Size: 1.0 KiB | 
| Before Width: | Height: | Size: 1.4 KiB | 
| @ -1,18 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <resources> | ||||
|     <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on --> | ||||
|     <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar"> | ||||
|         <!-- Show a splash screen on the activity. Automatically removed when | ||||
|              the Flutter engine draws its first frame --> | ||||
|         <item name="android:windowBackground">@drawable/launch_background</item> | ||||
|     </style> | ||||
|     <!-- Theme applied to the Android Window as soon as the process has started. | ||||
|          This theme determines the color of the Android Window while your | ||||
|          Flutter UI initializes, as well as behind your Flutter UI while its | ||||
|          running. | ||||
| 
 | ||||
|          This Theme is only used starting with V2 of Flutter's Android embedding. --> | ||||
|     <style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar"> | ||||
|         <item name="android:windowBackground">?android:colorBackground</item> | ||||
|     </style> | ||||
| </resources> | ||||
| @ -1,18 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <resources> | ||||
|     <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off --> | ||||
|     <style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar"> | ||||
|         <!-- Show a splash screen on the activity. Automatically removed when | ||||
|              the Flutter engine draws its first frame --> | ||||
|         <item name="android:windowBackground">@drawable/launch_background</item> | ||||
|     </style> | ||||
|     <!-- Theme applied to the Android Window as soon as the process has started. | ||||
|          This theme determines the color of the Android Window while your | ||||
|          Flutter UI initializes, as well as behind your Flutter UI while its | ||||
|          running. | ||||
| 
 | ||||
|          This Theme is only used starting with V2 of Flutter's Android embedding. --> | ||||
|     <style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar"> | ||||
|         <item name="android:windowBackground">?android:colorBackground</item> | ||||
|     </style> | ||||
| </resources> | ||||
| @ -1,8 +0,0 @@ | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     package="io.wyattapp.start"> | ||||
|     <!-- The INTERNET permission is required for development. Specifically, | ||||
|          the Flutter tool needs it to communicate with the running application | ||||
|          to allow setting breakpoints, to provide hot reload, etc. | ||||
|     --> | ||||
|     <uses-permission android:name="android.permission.INTERNET"/> | ||||
| </manifest> | ||||
| @ -1,31 +0,0 @@ | ||||
| buildscript { | ||||
|     ext.kotlin_version = '1.6.10' | ||||
|     repositories { | ||||
|         google() | ||||
|         mavenCentral() | ||||
|     } | ||||
| 
 | ||||
|     dependencies { | ||||
|         classpath 'com.android.tools.build:gradle:7.1.2' | ||||
|         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| allprojects { | ||||
|     repositories { | ||||
|         google() | ||||
|         mavenCentral() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| rootProject.buildDir = '../build' | ||||
| subprojects { | ||||
|     project.buildDir = "${rootProject.buildDir}/${project.name}" | ||||
| } | ||||
| subprojects { | ||||
|     project.evaluationDependsOn(':app') | ||||
| } | ||||
| 
 | ||||
| task clean(type: Delete) { | ||||
|     delete rootProject.buildDir | ||||
| } | ||||
| @ -1,3 +0,0 @@ | ||||
| org.gradle.jvmargs=-Xmx1536M | ||||
| android.useAndroidX=true | ||||
| android.enableJetifier=true | ||||
| @ -1,5 +0,0 @@ | ||||
| distributionBase=GRADLE_USER_HOME | ||||
| distributionPath=wrapper/dists | ||||
| zipStoreBase=GRADLE_USER_HOME | ||||
| zipStorePath=wrapper/dists | ||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip | ||||
| @ -1,11 +0,0 @@ | ||||
| include ':app' | ||||
| 
 | ||||
| def localPropertiesFile = new File(rootProject.projectDir, "local.properties") | ||||
| def properties = new Properties() | ||||
| 
 | ||||
| assert localPropertiesFile.exists() | ||||
| localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } | ||||
| 
 | ||||
| def flutterSdkPath = properties.getProperty("flutter.sdk") | ||||
| assert flutterSdkPath != null, "flutter.sdk not set in local.properties" | ||||
| apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" | ||||
| @ -0,0 +1 @@ | ||||
| # just to keep empty folder in brick generation | ||||
| @ -22,17 +22,19 @@ tasks: | ||||
|       - flutter pub get | ||||
| 
 | ||||
|   android: | ||||
|     desc: Building Android APK | ||||
|     desc: Building Android AAB | ||||
|     deps: [clean, get] | ||||
|     aliases: [a] | ||||
|     cmds: | ||||
|       - echo -e "{{.GREEN}}{{.PREFIX}} Building Android APK...{{.COLOROFF}}" | ||||
|       - flutter build apk --target=lib/main_production --no-pub --no-shrink | ||||
|       - echo -e "{{#mustacheCase}}.GREEN{{/mustacheCase}}{{#mustacheCase}}.PREFIX{{/mustacheCase}} Building Android AAB...{{#mustacheCase}}.COLOROFF{{/mustacheCase}}" | ||||
|       - flutter build appbundle lib/main_production.dart --dart-define-from-file=config.prod.json --no-pub --obfuscate --split-debug-info="./build/app/outputs/bundle/release/" {{#mustacheCase}}.CLI_ARGS{{/mustacheCase}} | ||||
|       - open ./build/app/outputs/bundle/release/ | ||||
| 
 | ||||
|   ios: | ||||
|     desc: Building iOS IPA | ||||
|     deps: [clean, get] | ||||
|     aliases: [i] | ||||
|     cmds: | ||||
|       - echo -e "{{.GREEN}}{{.PREFIX}} Building iOS IPA...{{.COLOROFF}}" | ||||
|       - flutter build ipa --target=lib/main_production --no-pub | ||||
|       - echo -e "{{#mustacheCase}}.GREEN{{/mustacheCase}}{{#mustacheCase}}.PREFIX{{/mustacheCase}} Building iOS IPA...{{#mustacheCase}}.COLOROFF{{/mustacheCase}}" | ||||
|       - flutter build ipa lib/main_production.dart --dart-define-from-file=config.prod.json --no-pub --obfuscate --split-debug-info="./build/ios/archive" {{#mustacheCase}}.CLI_ARGS{{/mustacheCase}} | ||||
|       - find "./build/ios/archive" -name "*.xcarchive" -exec open {} \; | ||||
|  | ||||
| @ -13,7 +13,7 @@ tasks: | ||||
|     internal: true | ||||
|     desc: Gets dependencies. | ||||
|     cmds: | ||||
|       - echo -e "{{.GREEN}}{{.PREFIX}} Getting the dependencies...{{.COLOROFF}}" | ||||
|       - echo -e "{{#mustacheCase}}.GREEN{{/mustacheCase}}{{#mustacheCase}}.PREFIX{{/mustacheCase}} Getting the dependencies...{{#mustacheCase}}.COLOROFF{{/mustacheCase}}" | ||||
|       - flutter pub get | ||||
| 
 | ||||
|   build: | ||||
| @ -21,7 +21,7 @@ tasks: | ||||
|     deps: [get] | ||||
|     aliases: [b] | ||||
|     cmds: | ||||
|       - echo -e "{{.GREEN}}{{.PREFIX}} Running build runner...{{.COLOROFF}}" | ||||
|       - echo -e "{{#mustacheCase}}.GREEN{{/mustacheCase}}{{#mustacheCase}}.PREFIX{{/mustacheCase}} Running build runner...{{#mustacheCase}}.COLOROFF{{/mustacheCase}}" | ||||
|       - flutter pub run build_runner build | ||||
| 
 | ||||
|   intl: | ||||
| @ -29,28 +29,36 @@ tasks: | ||||
|     deps: [get] | ||||
|     aliases: [i] | ||||
|     cmds: | ||||
|       - echo -e "{{.GREEN}}{{.PREFIX}} Running intl generation...{{.COLOROFF}}" | ||||
|       - echo -e "{{#mustacheCase}}.GREEN{{/mustacheCase}}{{#mustacheCase}}.PREFIX{{/mustacheCase}} Running intl generation...{{#mustacheCase}}.COLOROFF{{/mustacheCase}}" | ||||
|       - flutter gen-l10n | ||||
|    | ||||
|   splash: | ||||
|     desc: Generating splash screen | ||||
|     deps: [get] | ||||
|     aliases: [s] | ||||
|     cmds: | ||||
|       - echo -e "{{#mustacheCase}}.GREEN{{/mustacheCase}}{{#mustacheCase}}.PREFIX{{/mustacheCase}} Running splash screen generation...{{#mustacheCase}}.COLOROFF{{/mustacheCase}}" | ||||
|       - dart run flutter_native_splash:create | ||||
|    | ||||
|   icons: | ||||
|     desc: Generating icons | ||||
|     deps: [get] | ||||
|     aliases: [ic] | ||||
|     cmds: | ||||
|       - echo -e "{{#mustacheCase}}.GREEN{{/mustacheCase}}{{#mustacheCase}}.PREFIX{{/mustacheCase}} Running icon generation...{{#mustacheCase}}.COLOROFF{{/mustacheCase}}" | ||||
|       - dart run flutter_launcher_icons | ||||
| 
 | ||||
|   build-delete: | ||||
|     desc: Running build runner with deletion of conflicting outputs | ||||
|     deps: [get] | ||||
|     aliases: [d] | ||||
|     cmds: | ||||
|       - echo -e "{{.GREEN}}{{.PREFIX}} Running build runner with deletion of conflicting outputs...{{.COLOROFF}}" | ||||
|       - echo -e "{{#mustacheCase}}.GREEN{{/mustacheCase}}{{#mustacheCase}}.PREFIX{{/mustacheCase}} Running build runner with deletion of conflicting outputs...{{#mustacheCase}}.COLOROFF{{/mustacheCase}}" | ||||
|       - flutter pub run build_runner build --delete-conflicting-outputs | ||||
| 
 | ||||
|   clean: | ||||
|     desc: Cleaning build runner | ||||
|     aliases: [c] | ||||
|     cmds: | ||||
|       - echo -e "{{.GREEN}}{{.PREFIX}} Cleaning build runner...{{.COLOROFF}}" | ||||
|       - echo -e "{{#mustacheCase}}.GREEN{{/mustacheCase}}{{#mustacheCase}}.PREFIX{{/mustacheCase}} Cleaning build runner...{{#mustacheCase}}.COLOROFF{{/mustacheCase}}" | ||||
|       - flutter pub run build_runner clean | ||||
| 
 | ||||
|   watch: | ||||
|     desc: Running build runner in watch mode | ||||
|     deps: [get] | ||||
|     aliases: [w] | ||||
|     cmds: | ||||
|       - echo -e "{{.GREEN}}{{.PREFIX}} Running build runner in watch mode...{{.COLOROFF}}" | ||||
|       - flutter pub run build_runner watch | ||||
|  | ||||
| @ -13,21 +13,21 @@ tasks: | ||||
|     desc: Getting latest dependencies | ||||
|     aliases: [g] | ||||
|     cmds: | ||||
|       - echo -e "{{.GREEN}}{{.PREFIX}} Getting latest dependencies...{{.COLOROFF}}" | ||||
|       - echo -e "{{#mustacheCase}}.GREEN{{/mustacheCase}}{{#mustacheCase}}.PREFIX{{/mustacheCase}} Getting latest dependencies...{{#mustacheCase}}.COLOROFF{{/mustacheCase}}" | ||||
|       - flutter pub get | ||||
| 
 | ||||
|   upgrade: | ||||
|     desc: Upgrading dependencies | ||||
|     aliases: [u] | ||||
|     cmds: | ||||
|       - echo -e "{{.GREEN}}{{.PREFIX}} Upgrading dependencies...{{.COLOROFF}}" | ||||
|       - echo -e "{{#mustacheCase}}.GREEN{{/mustacheCase}}{{#mustacheCase}}.PREFIX{{/mustacheCase}} Upgrading dependencies...{{#mustacheCase}}.COLOROFF{{/mustacheCase}}" | ||||
|       - flutter pub upgrade | ||||
| 
 | ||||
|   upgrade-major: | ||||
|     desc: Upgrading dependencies | ||||
|     aliases: [um] | ||||
|     cmds: | ||||
|       - echo -e "{{.GREEN}}{{.PREFIX}} Upgrading dependencies --major-versions...{{.COLOROFF}}" | ||||
|       - echo -e "{{#mustacheCase}}.GREEN{{/mustacheCase}}{{#mustacheCase}}.PREFIX{{/mustacheCase}} Upgrading dependencies --major-versions...{{#mustacheCase}}.COLOROFF{{/mustacheCase}}" | ||||
|       - flutter pub upgrade --major-versions | ||||
| 
 | ||||
|   outdated: | ||||
| @ -35,13 +35,5 @@ tasks: | ||||
|     deps: [upgrade] | ||||
|     aliases: [o] | ||||
|     cmds: | ||||
|       - echo -e "{{.GREEN}}{{.PREFIX}} Checking for outdated dependencies...{{.COLOROFF}}" | ||||
|       - echo -e "{{#mustacheCase}}.GREEN{{/mustacheCase}}{{#mustacheCase}}.PREFIX{{/mustacheCase}} Checking for outdated dependencies...{{#mustacheCase}}.COLOROFF{{/mustacheCase}}" | ||||
|       - flutter pub upgrade | ||||
|    | ||||
|   validate: | ||||
|     desc: Running dependency validator | ||||
|     deps: [get] | ||||
|     aliases: [v] | ||||
|     cmds: | ||||
|       - echo -e "{{.GREEN}}{{.PREFIX}} Validating dependencies...{{.COLOROFF}}" | ||||
|       - flutter pub run dependency_validator | ||||
|  | ||||
| @ -13,26 +13,26 @@ tasks: | ||||
|     desc: Show log output for running Flutter apps | ||||
|     aliases: [l] | ||||
|     cmds: | ||||
|       - echo -e "{{.GREEN}}{{.PREFIX}} Showing log output for running Flutter apps...{{.COLOROFF}}" | ||||
|       - echo -e "{{#mustacheCase}}.GREEN{{/mustacheCase}}{{#mustacheCase}}.PREFIX{{/mustacheCase}} Showing log output for running Flutter apps...{{#mustacheCase}}.COLOROFF{{/mustacheCase}}" | ||||
|       - flutter logs | ||||
| 
 | ||||
|   dev: | ||||
|     desc: Run app in development environment | ||||
|     aliases: [d] | ||||
|     cmds: | ||||
|       - echo -e "{{.GREEN}}{{.PREFIX}} Running the app (development)...{{.COLOROFF}}" | ||||
|       - flutter run --target lib/main_development.dart --dart-define-from-file=config.json {{.CLI_ARGS}} | ||||
|       - echo -e "{{#mustacheCase}}.GREEN{{/mustacheCase}}{{#mustacheCase}}.PREFIX{{/mustacheCase}} Running the app (development)...{{#mustacheCase}}.COLOROFF{{/mustacheCase}}" | ||||
|       - flutter run --target lib/main_development.dart --dart-define-from-file=config.dev.json {{#mustacheCase}}.CLI_ARGS{{/mustacheCase}} | ||||
| 
 | ||||
|   staging: | ||||
|     desc: Run app in staging environment | ||||
|     aliases: [s] | ||||
|     cmds: | ||||
|       - echo -e "{{.GREEN}}{{.PREFIX}} Running the app (staging)...{{.COLOROFF}}" | ||||
|       - flutter run --target lib/main_staging.dart --dart-define-from-file=config.json {{.CLI_ARGS}} | ||||
|       - echo -e "{{#mustacheCase}}.GREEN{{/mustacheCase}}{{#mustacheCase}}.PREFIX{{/mustacheCase}} Running the app (staging)...{{#mustacheCase}}.COLOROFF{{/mustacheCase}}" | ||||
|       - flutter run --target lib/main_staging.dart --dart-define-from-file=config.staging.json {{#mustacheCase}}.CLI_ARGS{{/mustacheCase}} | ||||
| 
 | ||||
|   prod: | ||||
|     desc: Run app in production environment | ||||
|     aliases: [p] | ||||
|     cmds: | ||||
|       - echo -e "{{.GREEN}}{{.PREFIX}} Running the app (production)...{{.COLOROFF}}" | ||||
|       - flutter run --target lib/main_production.dart --dart-define-from-file=config.json {{.CLI_ARGS}} | ||||
|       - echo -e "{{#mustacheCase}}.GREEN{{/mustacheCase}}{{#mustacheCase}}.PREFIX{{/mustacheCase}} Running the app (production)...{{#mustacheCase}}.COLOROFF{{/mustacheCase}}" | ||||
|       - flutter run --target lib/main_production.dart --dart-define-from-file=config.prod.json {{#mustacheCase}}.CLI_ARGS{{/mustacheCase}} | ||||
|  | ||||
| @ -0,0 +1,6 @@ | ||||
| { | ||||
|   "ENV_NAME": "dev", | ||||
|   "DATA_SOURCE": "api", | ||||
|   "LOGGER_LEVEL": "debug", | ||||
|   "FEATURE_FLAGS": "logger" | ||||
| } | ||||
| @ -1,8 +0,0 @@ | ||||
| { | ||||
|   "FIREBASE_EMULATOR_CLOUD_FUNCTION_PORT": 5001, | ||||
|   "FIREBASE_EMULATOR_FIRESTORE_PORT": 8080, | ||||
|   "FIREBASE_EMULATOR_AUTH_PORT": 9099, | ||||
|   "FIREBASE_EMULATOR_STORAGE_PORT": 919911, | ||||
|   "FIREBASE_EMULATOR_HOST": "localhost", | ||||
|   "DEV_MODE": "local" | ||||
| } | ||||
| @ -0,0 +1,4 @@ | ||||
| { | ||||
|   "ENV_NAME": "prod", | ||||
|   "DATA_SOURCE": "api" | ||||
| } | ||||
| @ -0,0 +1,5 @@ | ||||
| { | ||||
|   "ENV_NAME": "staging", | ||||
|   "DATA_SOURCE": "api", | ||||
|   "FEATURE_FLAGS": "logger" | ||||
| } | ||||
| @ -1,34 +0,0 @@ | ||||
| **/dgph | ||||
| *.mode1v3 | ||||
| *.mode2v3 | ||||
| *.moved-aside | ||||
| *.pbxuser | ||||
| *.perspectivev3 | ||||
| **/*sync/ | ||||
| .sconsign.dblite | ||||
| .tags* | ||||
| **/.vagrant/ | ||||
| **/DerivedData/ | ||||
| Icon? | ||||
| **/Pods/ | ||||
| **/.symlinks/ | ||||
| profile | ||||
| xcuserdata | ||||
| **/.generated/ | ||||
| Flutter/App.framework | ||||
| Flutter/Flutter.framework | ||||
| Flutter/Flutter.podspec | ||||
| Flutter/Generated.xcconfig | ||||
| Flutter/ephemeral/ | ||||
| Flutter/app.flx | ||||
| Flutter/app.zip | ||||
| Flutter/flutter_assets/ | ||||
| Flutter/flutter_export_environment.sh | ||||
| ServiceDefinitions.json | ||||
| Runner/GeneratedPluginRegistrant.* | ||||
| 
 | ||||
| # Exceptions to above rules. | ||||
| !default.mode1v3 | ||||
| !default.mode2v3 | ||||
| !default.pbxuser | ||||
| !default.perspectivev3 | ||||
| @ -1,26 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||||
| <plist version="1.0"> | ||||
| <dict> | ||||
|   <key>CFBundleDevelopmentRegion</key> | ||||
|   <string>en</string> | ||||
|   <key>CFBundleExecutable</key> | ||||
|   <string>App</string> | ||||
|   <key>CFBundleIdentifier</key> | ||||
|   <string>io.flutter.flutter.app</string> | ||||
|   <key>CFBundleInfoDictionaryVersion</key> | ||||
|   <string>6.0</string> | ||||
|   <key>CFBundleName</key> | ||||
|   <string>App</string> | ||||
|   <key>CFBundlePackageType</key> | ||||
|   <string>FMWK</string> | ||||
|   <key>CFBundleShortVersionString</key> | ||||
|   <string>1.0</string> | ||||
|   <key>CFBundleSignature</key> | ||||
|   <string>????</string> | ||||
|   <key>CFBundleVersion</key> | ||||
|   <string>1.0</string> | ||||
|   <key>MinimumOSVersion</key> | ||||
|   <string>11.0</string> | ||||
| </dict> | ||||
| </plist> | ||||
| @ -1,2 +0,0 @@ | ||||
| #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" | ||||
| #include "Generated.xcconfig" | ||||
| @ -1,2 +0,0 @@ | ||||
| #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" | ||||
| #include "Generated.xcconfig" | ||||
| @ -1,41 +0,0 @@ | ||||
| # Uncomment this line to define a global platform for your project | ||||
| # platform :ios, '11.0' | ||||
| 
 | ||||
| # CocoaPods analytics sends network stats synchronously affecting flutter build latency. | ||||
| ENV['COCOAPODS_DISABLE_STATS'] = 'true' | ||||
| 
 | ||||
| project 'Runner', { | ||||
|   'Debug' => :debug, | ||||
|   'Profile' => :release, | ||||
|   'Release' => :release, | ||||
| } | ||||
| 
 | ||||
| def flutter_root | ||||
|   generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) | ||||
|   unless File.exist?(generated_xcode_build_settings_path) | ||||
|     raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" | ||||
|   end | ||||
| 
 | ||||
|   File.foreach(generated_xcode_build_settings_path) do |line| | ||||
|     matches = line.match(/FLUTTER_ROOT\=(.*)/) | ||||
|     return matches[1].strip if matches | ||||
|   end | ||||
|   raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" | ||||
| end | ||||
| 
 | ||||
| require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) | ||||
| 
 | ||||
| flutter_ios_podfile_setup | ||||
| 
 | ||||
| target 'Runner' do | ||||
|   use_frameworks! | ||||
|   use_modular_headers! | ||||
| 
 | ||||
|   flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) | ||||
| end | ||||
| 
 | ||||
| post_install do |installer| | ||||
|   installer.pods_project.targets.each do |target| | ||||
|     flutter_additional_ios_build_settings(target) | ||||
|   end | ||||
| end | ||||
| @ -1,28 +0,0 @@ | ||||
| PODS: | ||||
|   - Flutter (1.0.0) | ||||
|   - flutter_native_splash (0.0.1): | ||||
|     - Flutter | ||||
|   - url_launcher_ios (0.0.1): | ||||
|     - Flutter | ||||
| 
 | ||||
| DEPENDENCIES: | ||||
|   - Flutter (from `Flutter`) | ||||
|   - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) | ||||
|   - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) | ||||
| 
 | ||||
| EXTERNAL SOURCES: | ||||
|   Flutter: | ||||
|     :path: Flutter | ||||
|   flutter_native_splash: | ||||
|     :path: ".symlinks/plugins/flutter_native_splash/ios" | ||||
|   url_launcher_ios: | ||||
|     :path: ".symlinks/plugins/url_launcher_ios/ios" | ||||
| 
 | ||||
| SPEC CHECKSUMS: | ||||
|   Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 | ||||
|   flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef | ||||
|   url_launcher_ios: ae1517e5e344f5544fb090b079e11f399dfbe4d2 | ||||
| 
 | ||||
| PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 | ||||
| 
 | ||||
| COCOAPODS: 1.11.3 | ||||
| @ -1,556 +0,0 @@ | ||||
| // !$*UTF8*$! | ||||
| { | ||||
| 	archiveVersion = 1; | ||||
| 	classes = { | ||||
| 	}; | ||||
| 	objectVersion = 54; | ||||
| 	objects = { | ||||
| 
 | ||||
| /* Begin PBXBuildFile section */ | ||||
| 		1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; | ||||
| 		3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; | ||||
| 		50F1D9CF301DADBFF7F91098 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F58D6DFA5E148E9B1E5401F /* Pods_Runner.framework */; }; | ||||
| 		74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; | ||||
| 		97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; | ||||
| 		97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; | ||||
| 		97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; | ||||
| /* End PBXBuildFile section */ | ||||
| 
 | ||||
| /* Begin PBXCopyFilesBuildPhase section */ | ||||
| 		9705A1C41CF9048500538489 /* Embed Frameworks */ = { | ||||
| 			isa = PBXCopyFilesBuildPhase; | ||||
| 			buildActionMask = 2147483647; | ||||
| 			dstPath = ""; | ||||
| 			dstSubfolderSpec = 10; | ||||
| 			files = ( | ||||
| 			); | ||||
| 			name = "Embed Frameworks"; | ||||
| 			runOnlyForDeploymentPostprocessing = 0; | ||||
| 		}; | ||||
| /* End PBXCopyFilesBuildPhase section */ | ||||
| 
 | ||||
| /* Begin PBXFileReference section */ | ||||
| 		01240B090F6ECE02483CB484 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; }; | ||||
| 		1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; | ||||
| 		1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; | ||||
| 		18B4FB2B44E101F10AB8D41B /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; }; | ||||
| 		1F58D6DFA5E148E9B1E5401F /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; | ||||
| 		3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; | ||||
| 		74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; | ||||
| 		74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; | ||||
| 		7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; | ||||
| 		9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; }; | ||||
| 		9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; }; | ||||
| 		97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; | ||||
| 		97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; | ||||
| 		97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; | ||||
| 		97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; | ||||
| 		97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; | ||||
| 		EA780011634A6BC46817CBE0 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; }; | ||||
| /* End PBXFileReference section */ | ||||
| 
 | ||||
| /* Begin PBXFrameworksBuildPhase section */ | ||||
| 		97C146EB1CF9000F007C117D /* Frameworks */ = { | ||||
| 			isa = PBXFrameworksBuildPhase; | ||||
| 			buildActionMask = 2147483647; | ||||
| 			files = ( | ||||
| 				50F1D9CF301DADBFF7F91098 /* Pods_Runner.framework in Frameworks */, | ||||
| 			); | ||||
| 			runOnlyForDeploymentPostprocessing = 0; | ||||
| 		}; | ||||
| /* End PBXFrameworksBuildPhase section */ | ||||
| 
 | ||||
| /* Begin PBXGroup section */ | ||||
| 		10872F84FB14C7DD915284C6 /* Pods */ = { | ||||
| 			isa = PBXGroup; | ||||
| 			children = ( | ||||
| 				18B4FB2B44E101F10AB8D41B /* Pods-Runner.debug.xcconfig */, | ||||
| 				01240B090F6ECE02483CB484 /* Pods-Runner.release.xcconfig */, | ||||
| 				EA780011634A6BC46817CBE0 /* Pods-Runner.profile.xcconfig */, | ||||
| 			); | ||||
| 			name = Pods; | ||||
| 			path = Pods; | ||||
| 			sourceTree = "<group>"; | ||||
| 		}; | ||||
| 		4204558B17A62367423769E8 /* Frameworks */ = { | ||||
| 			isa = PBXGroup; | ||||
| 			children = ( | ||||
| 				1F58D6DFA5E148E9B1E5401F /* Pods_Runner.framework */, | ||||
| 			); | ||||
| 			name = Frameworks; | ||||
| 			sourceTree = "<group>"; | ||||
| 		}; | ||||
| 		9740EEB11CF90186004384FC /* Flutter */ = { | ||||
| 			isa = PBXGroup; | ||||
| 			children = ( | ||||
| 				3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, | ||||
| 				9740EEB21CF90195004384FC /* Debug.xcconfig */, | ||||
| 				7AFA3C8E1D35360C0083082E /* Release.xcconfig */, | ||||
| 				9740EEB31CF90195004384FC /* Generated.xcconfig */, | ||||
| 			); | ||||
| 			name = Flutter; | ||||
| 			sourceTree = "<group>"; | ||||
| 		}; | ||||
| 		97C146E51CF9000F007C117D = { | ||||
| 			isa = PBXGroup; | ||||
| 			children = ( | ||||
| 				9740EEB11CF90186004384FC /* Flutter */, | ||||
| 				97C146F01CF9000F007C117D /* Runner */, | ||||
| 				97C146EF1CF9000F007C117D /* Products */, | ||||
| 				10872F84FB14C7DD915284C6 /* Pods */, | ||||
| 				4204558B17A62367423769E8 /* Frameworks */, | ||||
| 			); | ||||
| 			sourceTree = "<group>"; | ||||
| 		}; | ||||
| 		97C146EF1CF9000F007C117D /* Products */ = { | ||||
| 			isa = PBXGroup; | ||||
| 			children = ( | ||||
| 				97C146EE1CF9000F007C117D /* Runner.app */, | ||||
| 			); | ||||
| 			name = Products; | ||||
| 			sourceTree = "<group>"; | ||||
| 		}; | ||||
| 		97C146F01CF9000F007C117D /* Runner */ = { | ||||
| 			isa = PBXGroup; | ||||
| 			children = ( | ||||
| 				97C146FA1CF9000F007C117D /* Main.storyboard */, | ||||
| 				97C146FD1CF9000F007C117D /* Assets.xcassets */, | ||||
| 				97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, | ||||
| 				97C147021CF9000F007C117D /* Info.plist */, | ||||
| 				1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, | ||||
| 				1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, | ||||
| 				74858FAE1ED2DC5600515810 /* AppDelegate.swift */, | ||||
| 				74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, | ||||
| 			); | ||||
| 			path = Runner; | ||||
| 			sourceTree = "<group>"; | ||||
| 		}; | ||||
| /* End PBXGroup section */ | ||||
| 
 | ||||
| /* Begin PBXNativeTarget section */ | ||||
| 		97C146ED1CF9000F007C117D /* Runner */ = { | ||||
| 			isa = PBXNativeTarget; | ||||
| 			buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; | ||||
| 			buildPhases = ( | ||||
| 				B0C681F6443208846EBFB7D2 /* [CP] Check Pods Manifest.lock */, | ||||
| 				9740EEB61CF901F6004384FC /* Run Script */, | ||||
| 				97C146EA1CF9000F007C117D /* Sources */, | ||||
| 				97C146EB1CF9000F007C117D /* Frameworks */, | ||||
| 				97C146EC1CF9000F007C117D /* Resources */, | ||||
| 				9705A1C41CF9048500538489 /* Embed Frameworks */, | ||||
| 				3B06AD1E1E4923F5004D2608 /* Thin Binary */, | ||||
| 				CF936C6216E6F00FB5F73F4C /* [CP] Embed Pods Frameworks */, | ||||
| 			); | ||||
| 			buildRules = ( | ||||
| 			); | ||||
| 			dependencies = ( | ||||
| 			); | ||||
| 			name = Runner; | ||||
| 			productName = Runner; | ||||
| 			productReference = 97C146EE1CF9000F007C117D /* Runner.app */; | ||||
| 			productType = "com.apple.product-type.application"; | ||||
| 		}; | ||||
| /* End PBXNativeTarget section */ | ||||
| 
 | ||||
| /* Begin PBXProject section */ | ||||
| 		97C146E61CF9000F007C117D /* Project object */ = { | ||||
| 			isa = PBXProject; | ||||
| 			attributes = { | ||||
| 				LastUpgradeCheck = 1300; | ||||
| 				ORGANIZATIONNAME = ""; | ||||
| 				TargetAttributes = { | ||||
| 					97C146ED1CF9000F007C117D = { | ||||
| 						CreatedOnToolsVersion = 7.3.1; | ||||
| 						LastSwiftMigration = 1100; | ||||
| 					}; | ||||
| 				}; | ||||
| 			}; | ||||
| 			buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; | ||||
| 			compatibilityVersion = "Xcode 9.3"; | ||||
| 			developmentRegion = en; | ||||
| 			hasScannedForEncodings = 0; | ||||
| 			knownRegions = ( | ||||
| 				en, | ||||
| 				Base, | ||||
| 			); | ||||
| 			mainGroup = 97C146E51CF9000F007C117D; | ||||
| 			productRefGroup = 97C146EF1CF9000F007C117D /* Products */; | ||||
| 			projectDirPath = ""; | ||||
| 			projectRoot = ""; | ||||
| 			targets = ( | ||||
| 				97C146ED1CF9000F007C117D /* Runner */, | ||||
| 			); | ||||
| 		}; | ||||
| /* End PBXProject section */ | ||||
| 
 | ||||
| /* Begin PBXResourcesBuildPhase section */ | ||||
| 		97C146EC1CF9000F007C117D /* Resources */ = { | ||||
| 			isa = PBXResourcesBuildPhase; | ||||
| 			buildActionMask = 2147483647; | ||||
| 			files = ( | ||||
| 				97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, | ||||
| 				3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, | ||||
| 				97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, | ||||
| 				97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, | ||||
| 			); | ||||
| 			runOnlyForDeploymentPostprocessing = 0; | ||||
| 		}; | ||||
| /* End PBXResourcesBuildPhase section */ | ||||
| 
 | ||||
| /* Begin PBXShellScriptBuildPhase section */ | ||||
| 		3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { | ||||
| 			isa = PBXShellScriptBuildPhase; | ||||
| 			alwaysOutOfDate = 1; | ||||
| 			buildActionMask = 2147483647; | ||||
| 			files = ( | ||||
| 			); | ||||
| 			inputPaths = ( | ||||
| 			); | ||||
| 			name = "Thin Binary"; | ||||
| 			outputPaths = ( | ||||
| 			); | ||||
| 			runOnlyForDeploymentPostprocessing = 0; | ||||
| 			shellPath = /bin/sh; | ||||
| 			shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; | ||||
| 		}; | ||||
| 		9740EEB61CF901F6004384FC /* Run Script */ = { | ||||
| 			isa = PBXShellScriptBuildPhase; | ||||
| 			alwaysOutOfDate = 1; | ||||
| 			buildActionMask = 2147483647; | ||||
| 			files = ( | ||||
| 			); | ||||
| 			inputPaths = ( | ||||
| 			); | ||||
| 			name = "Run Script"; | ||||
| 			outputPaths = ( | ||||
| 			); | ||||
| 			runOnlyForDeploymentPostprocessing = 0; | ||||
| 			shellPath = /bin/sh; | ||||
| 			shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; | ||||
| 		}; | ||||
| 		B0C681F6443208846EBFB7D2 /* [CP] Check Pods Manifest.lock */ = { | ||||
| 			isa = PBXShellScriptBuildPhase; | ||||
| 			buildActionMask = 2147483647; | ||||
| 			files = ( | ||||
| 			); | ||||
| 			inputFileListPaths = ( | ||||
| 			); | ||||
| 			inputPaths = ( | ||||
| 				"${PODS_PODFILE_DIR_PATH}/Podfile.lock", | ||||
| 				"${PODS_ROOT}/Manifest.lock", | ||||
| 			); | ||||
| 			name = "[CP] Check Pods Manifest.lock"; | ||||
| 			outputFileListPaths = ( | ||||
| 			); | ||||
| 			outputPaths = ( | ||||
| 				"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", | ||||
| 			); | ||||
| 			runOnlyForDeploymentPostprocessing = 0; | ||||
| 			shellPath = /bin/sh; | ||||
| 			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; | ||||
| 			showEnvVarsInLog = 0; | ||||
| 		}; | ||||
| 		CF936C6216E6F00FB5F73F4C /* [CP] Embed Pods Frameworks */ = { | ||||
| 			isa = PBXShellScriptBuildPhase; | ||||
| 			buildActionMask = 2147483647; | ||||
| 			files = ( | ||||
| 			); | ||||
| 			inputFileListPaths = ( | ||||
| 				"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", | ||||
| 			); | ||||
| 			name = "[CP] Embed Pods Frameworks"; | ||||
| 			outputFileListPaths = ( | ||||
| 				"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", | ||||
| 			); | ||||
| 			runOnlyForDeploymentPostprocessing = 0; | ||||
| 			shellPath = /bin/sh; | ||||
| 			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; | ||||
| 			showEnvVarsInLog = 0; | ||||
| 		}; | ||||
| /* End PBXShellScriptBuildPhase section */ | ||||
| 
 | ||||
| /* Begin PBXSourcesBuildPhase section */ | ||||
| 		97C146EA1CF9000F007C117D /* Sources */ = { | ||||
| 			isa = PBXSourcesBuildPhase; | ||||
| 			buildActionMask = 2147483647; | ||||
| 			files = ( | ||||
| 				74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, | ||||
| 				1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, | ||||
| 			); | ||||
| 			runOnlyForDeploymentPostprocessing = 0; | ||||
| 		}; | ||||
| /* End PBXSourcesBuildPhase section */ | ||||
| 
 | ||||
| /* Begin PBXVariantGroup section */ | ||||
| 		97C146FA1CF9000F007C117D /* Main.storyboard */ = { | ||||
| 			isa = PBXVariantGroup; | ||||
| 			children = ( | ||||
| 				97C146FB1CF9000F007C117D /* Base */, | ||||
| 			); | ||||
| 			name = Main.storyboard; | ||||
| 			sourceTree = "<group>"; | ||||
| 		}; | ||||
| 		97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { | ||||
| 			isa = PBXVariantGroup; | ||||
| 			children = ( | ||||
| 				97C147001CF9000F007C117D /* Base */, | ||||
| 			); | ||||
| 			name = LaunchScreen.storyboard; | ||||
| 			sourceTree = "<group>"; | ||||
| 		}; | ||||
| /* End PBXVariantGroup section */ | ||||
| 
 | ||||
| /* Begin XCBuildConfiguration section */ | ||||
| 		249021D3217E4FDB00AE95B9 /* Profile */ = { | ||||
| 			isa = XCBuildConfiguration; | ||||
| 			buildSettings = { | ||||
| 				ALWAYS_SEARCH_USER_PATHS = NO; | ||||
| 				CLANG_ANALYZER_NONNULL = YES; | ||||
| 				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; | ||||
| 				CLANG_CXX_LIBRARY = "libc++"; | ||||
| 				CLANG_ENABLE_MODULES = YES; | ||||
| 				CLANG_ENABLE_OBJC_ARC = YES; | ||||
| 				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; | ||||
| 				CLANG_WARN_BOOL_CONVERSION = YES; | ||||
| 				CLANG_WARN_COMMA = YES; | ||||
| 				CLANG_WARN_CONSTANT_CONVERSION = YES; | ||||
| 				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; | ||||
| 				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; | ||||
| 				CLANG_WARN_EMPTY_BODY = YES; | ||||
| 				CLANG_WARN_ENUM_CONVERSION = YES; | ||||
| 				CLANG_WARN_INFINITE_RECURSION = YES; | ||||
| 				CLANG_WARN_INT_CONVERSION = YES; | ||||
| 				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; | ||||
| 				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; | ||||
| 				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; | ||||
| 				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; | ||||
| 				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; | ||||
| 				CLANG_WARN_STRICT_PROTOTYPES = YES; | ||||
| 				CLANG_WARN_SUSPICIOUS_MOVE = YES; | ||||
| 				CLANG_WARN_UNREACHABLE_CODE = YES; | ||||
| 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; | ||||
| 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; | ||||
| 				COPY_PHASE_STRIP = NO; | ||||
| 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; | ||||
| 				ENABLE_NS_ASSERTIONS = NO; | ||||
| 				ENABLE_STRICT_OBJC_MSGSEND = YES; | ||||
| 				GCC_C_LANGUAGE_STANDARD = gnu99; | ||||
| 				GCC_NO_COMMON_BLOCKS = YES; | ||||
| 				GCC_WARN_64_TO_32_BIT_CONVERSION = YES; | ||||
| 				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; | ||||
| 				GCC_WARN_UNDECLARED_SELECTOR = YES; | ||||
| 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | ||||
| 				GCC_WARN_UNUSED_FUNCTION = YES; | ||||
| 				GCC_WARN_UNUSED_VARIABLE = YES; | ||||
| 				IPHONEOS_DEPLOYMENT_TARGET = 11.0; | ||||
| 				MTL_ENABLE_DEBUG_INFO = NO; | ||||
| 				SDKROOT = iphoneos; | ||||
| 				SUPPORTED_PLATFORMS = iphoneos; | ||||
| 				TARGETED_DEVICE_FAMILY = "1,2"; | ||||
| 				VALIDATE_PRODUCT = YES; | ||||
| 			}; | ||||
| 			name = Profile; | ||||
| 		}; | ||||
| 		249021D4217E4FDB00AE95B9 /* Profile */ = { | ||||
| 			isa = XCBuildConfiguration; | ||||
| 			baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; | ||||
| 			buildSettings = { | ||||
| 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | ||||
| 				CLANG_ENABLE_MODULES = YES; | ||||
| 				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; | ||||
| 				DEVELOPMENT_TEAM = 6Z5P8GG96U; | ||||
| 				ENABLE_BITCODE = NO; | ||||
| 				INFOPLIST_FILE = Runner/Info.plist; | ||||
| 				LD_RUNPATH_SEARCH_PATHS = ( | ||||
| 					"$(inherited)", | ||||
| 					"@executable_path/Frameworks", | ||||
| 				); | ||||
| 				PRODUCT_BUNDLE_IDENTIFIER = io.wyattapp.start; | ||||
| 				PRODUCT_NAME = "Display Name"; | ||||
| 				SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; | ||||
| 				SWIFT_VERSION = 5.0; | ||||
| 				VERSIONING_SYSTEM = "apple-generic"; | ||||
| 			}; | ||||
| 			name = Profile; | ||||
| 		}; | ||||
| 		97C147031CF9000F007C117D /* Debug */ = { | ||||
| 			isa = XCBuildConfiguration; | ||||
| 			buildSettings = { | ||||
| 				ALWAYS_SEARCH_USER_PATHS = NO; | ||||
| 				CLANG_ANALYZER_NONNULL = YES; | ||||
| 				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; | ||||
| 				CLANG_CXX_LIBRARY = "libc++"; | ||||
| 				CLANG_ENABLE_MODULES = YES; | ||||
| 				CLANG_ENABLE_OBJC_ARC = YES; | ||||
| 				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; | ||||
| 				CLANG_WARN_BOOL_CONVERSION = YES; | ||||
| 				CLANG_WARN_COMMA = YES; | ||||
| 				CLANG_WARN_CONSTANT_CONVERSION = YES; | ||||
| 				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; | ||||
| 				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; | ||||
| 				CLANG_WARN_EMPTY_BODY = YES; | ||||
| 				CLANG_WARN_ENUM_CONVERSION = YES; | ||||
| 				CLANG_WARN_INFINITE_RECURSION = YES; | ||||
| 				CLANG_WARN_INT_CONVERSION = YES; | ||||
| 				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; | ||||
| 				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; | ||||
| 				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; | ||||
| 				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; | ||||
| 				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; | ||||
| 				CLANG_WARN_STRICT_PROTOTYPES = YES; | ||||
| 				CLANG_WARN_SUSPICIOUS_MOVE = YES; | ||||
| 				CLANG_WARN_UNREACHABLE_CODE = YES; | ||||
| 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; | ||||
| 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; | ||||
| 				COPY_PHASE_STRIP = NO; | ||||
| 				DEBUG_INFORMATION_FORMAT = dwarf; | ||||
| 				ENABLE_STRICT_OBJC_MSGSEND = YES; | ||||
| 				ENABLE_TESTABILITY = YES; | ||||
| 				GCC_C_LANGUAGE_STANDARD = gnu99; | ||||
| 				GCC_DYNAMIC_NO_PIC = NO; | ||||
| 				GCC_NO_COMMON_BLOCKS = YES; | ||||
| 				GCC_OPTIMIZATION_LEVEL = 0; | ||||
| 				GCC_PREPROCESSOR_DEFINITIONS = ( | ||||
| 					"DEBUG=1", | ||||
| 					"$(inherited)", | ||||
| 				); | ||||
| 				GCC_WARN_64_TO_32_BIT_CONVERSION = YES; | ||||
| 				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; | ||||
| 				GCC_WARN_UNDECLARED_SELECTOR = YES; | ||||
| 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | ||||
| 				GCC_WARN_UNUSED_FUNCTION = YES; | ||||
| 				GCC_WARN_UNUSED_VARIABLE = YES; | ||||
| 				IPHONEOS_DEPLOYMENT_TARGET = 11.0; | ||||
| 				MTL_ENABLE_DEBUG_INFO = YES; | ||||
| 				ONLY_ACTIVE_ARCH = YES; | ||||
| 				SDKROOT = iphoneos; | ||||
| 				TARGETED_DEVICE_FAMILY = "1,2"; | ||||
| 			}; | ||||
| 			name = Debug; | ||||
| 		}; | ||||
| 		97C147041CF9000F007C117D /* Release */ = { | ||||
| 			isa = XCBuildConfiguration; | ||||
| 			buildSettings = { | ||||
| 				ALWAYS_SEARCH_USER_PATHS = NO; | ||||
| 				CLANG_ANALYZER_NONNULL = YES; | ||||
| 				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; | ||||
| 				CLANG_CXX_LIBRARY = "libc++"; | ||||
| 				CLANG_ENABLE_MODULES = YES; | ||||
| 				CLANG_ENABLE_OBJC_ARC = YES; | ||||
| 				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; | ||||
| 				CLANG_WARN_BOOL_CONVERSION = YES; | ||||
| 				CLANG_WARN_COMMA = YES; | ||||
| 				CLANG_WARN_CONSTANT_CONVERSION = YES; | ||||
| 				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; | ||||
| 				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; | ||||
| 				CLANG_WARN_EMPTY_BODY = YES; | ||||
| 				CLANG_WARN_ENUM_CONVERSION = YES; | ||||
| 				CLANG_WARN_INFINITE_RECURSION = YES; | ||||
| 				CLANG_WARN_INT_CONVERSION = YES; | ||||
| 				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; | ||||
| 				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; | ||||
| 				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; | ||||
| 				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; | ||||
| 				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; | ||||
| 				CLANG_WARN_STRICT_PROTOTYPES = YES; | ||||
| 				CLANG_WARN_SUSPICIOUS_MOVE = YES; | ||||
| 				CLANG_WARN_UNREACHABLE_CODE = YES; | ||||
| 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; | ||||
| 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; | ||||
| 				COPY_PHASE_STRIP = NO; | ||||
| 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; | ||||
| 				ENABLE_NS_ASSERTIONS = NO; | ||||
| 				ENABLE_STRICT_OBJC_MSGSEND = YES; | ||||
| 				GCC_C_LANGUAGE_STANDARD = gnu99; | ||||
| 				GCC_NO_COMMON_BLOCKS = YES; | ||||
| 				GCC_WARN_64_TO_32_BIT_CONVERSION = YES; | ||||
| 				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; | ||||
| 				GCC_WARN_UNDECLARED_SELECTOR = YES; | ||||
| 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | ||||
| 				GCC_WARN_UNUSED_FUNCTION = YES; | ||||
| 				GCC_WARN_UNUSED_VARIABLE = YES; | ||||
| 				IPHONEOS_DEPLOYMENT_TARGET = 11.0; | ||||
| 				MTL_ENABLE_DEBUG_INFO = NO; | ||||
| 				SDKROOT = iphoneos; | ||||
| 				SUPPORTED_PLATFORMS = iphoneos; | ||||
| 				SWIFT_COMPILATION_MODE = wholemodule; | ||||
| 				SWIFT_OPTIMIZATION_LEVEL = "-O"; | ||||
| 				TARGETED_DEVICE_FAMILY = "1,2"; | ||||
| 				VALIDATE_PRODUCT = YES; | ||||
| 			}; | ||||
| 			name = Release; | ||||
| 		}; | ||||
| 		97C147061CF9000F007C117D /* Debug */ = { | ||||
| 			isa = XCBuildConfiguration; | ||||
| 			baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; | ||||
| 			buildSettings = { | ||||
| 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | ||||
| 				CLANG_ENABLE_MODULES = YES; | ||||
| 				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; | ||||
| 				DEVELOPMENT_TEAM = 6Z5P8GG96U; | ||||
| 				ENABLE_BITCODE = NO; | ||||
| 				INFOPLIST_FILE = Runner/Info.plist; | ||||
| 				LD_RUNPATH_SEARCH_PATHS = ( | ||||
| 					"$(inherited)", | ||||
| 					"@executable_path/Frameworks", | ||||
| 				); | ||||
| 				PRODUCT_BUNDLE_IDENTIFIER = io.wyattapp.start; | ||||
| 				PRODUCT_NAME = "Display Name"; | ||||
| 				SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; | ||||
| 				SWIFT_OPTIMIZATION_LEVEL = "-Onone"; | ||||
| 				SWIFT_VERSION = 5.0; | ||||
| 				VERSIONING_SYSTEM = "apple-generic"; | ||||
| 				CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; | ||||
| 			}; | ||||
| 			name = Debug; | ||||
| 		}; | ||||
| 		97C147071CF9000F007C117D /* Release */ = { | ||||
| 			isa = XCBuildConfiguration; | ||||
| 			baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; | ||||
| 			buildSettings = { | ||||
| 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | ||||
| 				CLANG_ENABLE_MODULES = YES; | ||||
| 				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; | ||||
| 				DEVELOPMENT_TEAM = 6Z5P8GG96U; | ||||
| 				ENABLE_BITCODE = NO; | ||||
| 				INFOPLIST_FILE = Runner/Info.plist; | ||||
| 				LD_RUNPATH_SEARCH_PATHS = ( | ||||
| 					"$(inherited)", | ||||
| 					"@executable_path/Frameworks", | ||||
| 				); | ||||
| 				PRODUCT_BUNDLE_IDENTIFIER = io.wyattapp.start; | ||||
| 				PRODUCT_NAME = "Display Name"; | ||||
| 				SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; | ||||
| 				SWIFT_VERSION = 5.0; | ||||
| 				VERSIONING_SYSTEM = "apple-generic"; | ||||
| 				CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; | ||||
| 			}; | ||||
| 			name = Release; | ||||
| 		}; | ||||
| /* End XCBuildConfiguration section */ | ||||
| 
 | ||||
| /* Begin XCConfigurationList section */ | ||||
| 		97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { | ||||
| 			isa = XCConfigurationList; | ||||
| 			buildConfigurations = ( | ||||
| 				97C147031CF9000F007C117D /* Debug */, | ||||
| 				97C147041CF9000F007C117D /* Release */, | ||||
| 				249021D3217E4FDB00AE95B9 /* Profile */, | ||||
| 			); | ||||
| 			defaultConfigurationIsVisible = 0; | ||||
| 			defaultConfigurationName = Release; | ||||
| 		}; | ||||
| 		97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { | ||||
| 			isa = XCConfigurationList; | ||||
| 			buildConfigurations = ( | ||||
| 				97C147061CF9000F007C117D /* Debug */, | ||||
| 				97C147071CF9000F007C117D /* Release */, | ||||
| 				249021D4217E4FDB00AE95B9 /* Profile */, | ||||
| 			); | ||||
| 			defaultConfigurationIsVisible = 0; | ||||
| 			defaultConfigurationName = Release; | ||||
| 		}; | ||||
| /* End XCConfigurationList section */ | ||||
| 	}; | ||||
| 	rootObject = 97C146E61CF9000F007C117D /* Project object */; | ||||
| } | ||||
| @ -1,7 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <Workspace | ||||
|    version = "1.0"> | ||||
|    <FileRef | ||||
|       location = "self:"> | ||||
|    </FileRef> | ||||
| </Workspace> | ||||
| @ -1,8 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||||
| <plist version="1.0"> | ||||
| <dict> | ||||
| 	<key>IDEDidComputeMac32BitWarning</key> | ||||
| 	<true/> | ||||
| </dict> | ||||
| </plist> | ||||
| @ -1,8 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||||
| <plist version="1.0"> | ||||
| <dict> | ||||
| 	<key>PreviewsEnabled</key> | ||||
| 	<false/> | ||||
| </dict> | ||||
| </plist> | ||||
| @ -1,87 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <Scheme | ||||
|    LastUpgradeVersion = "1300" | ||||
|    version = "1.3"> | ||||
|    <BuildAction | ||||
|       parallelizeBuildables = "YES" | ||||
|       buildImplicitDependencies = "YES"> | ||||
|       <BuildActionEntries> | ||||
|          <BuildActionEntry | ||||
|             buildForTesting = "YES" | ||||
|             buildForRunning = "YES" | ||||
|             buildForProfiling = "YES" | ||||
|             buildForArchiving = "YES" | ||||
|             buildForAnalyzing = "YES"> | ||||
|             <BuildableReference | ||||
|                BuildableIdentifier = "primary" | ||||
|                BlueprintIdentifier = "97C146ED1CF9000F007C117D" | ||||
|                BuildableName = "Runner.app" | ||||
|                BlueprintName = "Runner" | ||||
|                ReferencedContainer = "container:Runner.xcodeproj"> | ||||
|             </BuildableReference> | ||||
|          </BuildActionEntry> | ||||
|       </BuildActionEntries> | ||||
|    </BuildAction> | ||||
|    <TestAction | ||||
|       buildConfiguration = "Debug" | ||||
|       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||||
|       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||||
|       shouldUseLaunchSchemeArgsEnv = "YES"> | ||||
|       <MacroExpansion> | ||||
|          <BuildableReference | ||||
|             BuildableIdentifier = "primary" | ||||
|             BlueprintIdentifier = "97C146ED1CF9000F007C117D" | ||||
|             BuildableName = "Runner.app" | ||||
|             BlueprintName = "Runner" | ||||
|             ReferencedContainer = "container:Runner.xcodeproj"> | ||||
|          </BuildableReference> | ||||
|       </MacroExpansion> | ||||
|       <Testables> | ||||
|       </Testables> | ||||
|    </TestAction> | ||||
|    <LaunchAction | ||||
|       buildConfiguration = "Debug" | ||||
|       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||||
|       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||||
|       launchStyle = "0" | ||||
|       useCustomWorkingDirectory = "NO" | ||||
|       ignoresPersistentStateOnLaunch = "NO" | ||||
|       debugDocumentVersioning = "YES" | ||||
|       debugServiceExtension = "internal" | ||||
|       allowLocationSimulation = "YES"> | ||||
|       <BuildableProductRunnable | ||||
|          runnableDebuggingMode = "0"> | ||||
|          <BuildableReference | ||||
|             BuildableIdentifier = "primary" | ||||
|             BlueprintIdentifier = "97C146ED1CF9000F007C117D" | ||||
|             BuildableName = "Runner.app" | ||||
|             BlueprintName = "Runner" | ||||
|             ReferencedContainer = "container:Runner.xcodeproj"> | ||||
|          </BuildableReference> | ||||
|       </BuildableProductRunnable> | ||||
|    </LaunchAction> | ||||
|    <ProfileAction | ||||
|       buildConfiguration = "Profile" | ||||
|       shouldUseLaunchSchemeArgsEnv = "YES" | ||||
|       savedToolIdentifier = "" | ||||
|       useCustomWorkingDirectory = "NO" | ||||
|       debugDocumentVersioning = "YES"> | ||||
|       <BuildableProductRunnable | ||||
|          runnableDebuggingMode = "0"> | ||||
|          <BuildableReference | ||||
|             BuildableIdentifier = "primary" | ||||
|             BlueprintIdentifier = "97C146ED1CF9000F007C117D" | ||||
|             BuildableName = "Runner.app" | ||||
|             BlueprintName = "Runner" | ||||
|             ReferencedContainer = "container:Runner.xcodeproj"> | ||||
|          </BuildableReference> | ||||
|       </BuildableProductRunnable> | ||||
|    </ProfileAction> | ||||
|    <AnalyzeAction | ||||
|       buildConfiguration = "Debug"> | ||||
|    </AnalyzeAction> | ||||
|    <ArchiveAction | ||||
|       buildConfiguration = "Release" | ||||
|       revealArchiveInOrganizer = "YES"> | ||||
|    </ArchiveAction> | ||||
| </Scheme> | ||||
| @ -1,10 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <Workspace | ||||
|    version = "1.0"> | ||||
|    <FileRef | ||||
|       location = "group:Runner.xcodeproj"> | ||||
|    </FileRef> | ||||
|    <FileRef | ||||
|       location = "group:Pods/Pods.xcodeproj"> | ||||
|    </FileRef> | ||||
| </Workspace> | ||||
| @ -1,8 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||||
| <plist version="1.0"> | ||||
| <dict> | ||||
| 	<key>IDEDidComputeMac32BitWarning</key> | ||||
| 	<true/> | ||||
| </dict> | ||||
| </plist> | ||||
| @ -1,8 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||||
| <plist version="1.0"> | ||||
| <dict> | ||||
| 	<key>PreviewsEnabled</key> | ||||
| 	<false/> | ||||
| </dict> | ||||
| </plist> | ||||
| @ -1,13 +0,0 @@ | ||||
| import UIKit | ||||
| import Flutter | ||||
| 
 | ||||
| @UIApplicationMain | ||||
| @objc class AppDelegate: FlutterAppDelegate { | ||||
|   override func application( | ||||
|     _ application: UIApplication, | ||||
|     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? | ||||
|   ) -> Bool { | ||||
|     GeneratedPluginRegistrant.register(with: self) | ||||
|     return super.application(application, didFinishLaunchingWithOptions: launchOptions) | ||||
|   } | ||||
| } | ||||
| @ -1,122 +0,0 @@ | ||||
| { | ||||
|   "images" : [ | ||||
|     { | ||||
|       "size" : "20x20", | ||||
|       "idiom" : "iphone", | ||||
|       "filename" : "Icon-App-20x20@2x.png", | ||||
|       "scale" : "2x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "20x20", | ||||
|       "idiom" : "iphone", | ||||
|       "filename" : "Icon-App-20x20@3x.png", | ||||
|       "scale" : "3x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "29x29", | ||||
|       "idiom" : "iphone", | ||||
|       "filename" : "Icon-App-29x29@1x.png", | ||||
|       "scale" : "1x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "29x29", | ||||
|       "idiom" : "iphone", | ||||
|       "filename" : "Icon-App-29x29@2x.png", | ||||
|       "scale" : "2x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "29x29", | ||||
|       "idiom" : "iphone", | ||||
|       "filename" : "Icon-App-29x29@3x.png", | ||||
|       "scale" : "3x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "40x40", | ||||
|       "idiom" : "iphone", | ||||
|       "filename" : "Icon-App-40x40@2x.png", | ||||
|       "scale" : "2x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "40x40", | ||||
|       "idiom" : "iphone", | ||||
|       "filename" : "Icon-App-40x40@3x.png", | ||||
|       "scale" : "3x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "60x60", | ||||
|       "idiom" : "iphone", | ||||
|       "filename" : "Icon-App-60x60@2x.png", | ||||
|       "scale" : "2x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "60x60", | ||||
|       "idiom" : "iphone", | ||||
|       "filename" : "Icon-App-60x60@3x.png", | ||||
|       "scale" : "3x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "20x20", | ||||
|       "idiom" : "ipad", | ||||
|       "filename" : "Icon-App-20x20@1x.png", | ||||
|       "scale" : "1x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "20x20", | ||||
|       "idiom" : "ipad", | ||||
|       "filename" : "Icon-App-20x20@2x.png", | ||||
|       "scale" : "2x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "29x29", | ||||
|       "idiom" : "ipad", | ||||
|       "filename" : "Icon-App-29x29@1x.png", | ||||
|       "scale" : "1x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "29x29", | ||||
|       "idiom" : "ipad", | ||||
|       "filename" : "Icon-App-29x29@2x.png", | ||||
|       "scale" : "2x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "40x40", | ||||
|       "idiom" : "ipad", | ||||
|       "filename" : "Icon-App-40x40@1x.png", | ||||
|       "scale" : "1x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "40x40", | ||||
|       "idiom" : "ipad", | ||||
|       "filename" : "Icon-App-40x40@2x.png", | ||||
|       "scale" : "2x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "76x76", | ||||
|       "idiom" : "ipad", | ||||
|       "filename" : "Icon-App-76x76@1x.png", | ||||
|       "scale" : "1x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "76x76", | ||||
|       "idiom" : "ipad", | ||||
|       "filename" : "Icon-App-76x76@2x.png", | ||||
|       "scale" : "2x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "83.5x83.5", | ||||
|       "idiom" : "ipad", | ||||
|       "filename" : "Icon-App-83.5x83.5@2x.png", | ||||
|       "scale" : "2x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "1024x1024", | ||||
|       "idiom" : "ios-marketing", | ||||
|       "filename" : "Icon-App-1024x1024@1x.png", | ||||
|       "scale" : "1x" | ||||
|     } | ||||
|   ], | ||||
|   "info" : { | ||||
|     "version" : 1, | ||||
|     "author" : "xcode" | ||||
|   } | ||||
| } | ||||
| Before Width: | Height: | Size: 11 KiB | 
| Before Width: | Height: | Size: 564 B | 
| Before Width: | Height: | Size: 1.3 KiB | 
| Before Width: | Height: | Size: 1.6 KiB | 
| Before Width: | Height: | Size: 1.0 KiB | 
| Before Width: | Height: | Size: 1.7 KiB | 
| Before Width: | Height: | Size: 1.9 KiB | 
| Before Width: | Height: | Size: 1.3 KiB | 
| Before Width: | Height: | Size: 1.9 KiB | 
| Before Width: | Height: | Size: 2.6 KiB | 
| Before Width: | Height: | Size: 2.6 KiB | 
| Before Width: | Height: | Size: 3.7 KiB | 
| Before Width: | Height: | Size: 1.8 KiB | 
| Before Width: | Height: | Size: 3.2 KiB | 
| Before Width: | Height: | Size: 3.5 KiB | 
| @ -1,23 +0,0 @@ | ||||
| { | ||||
|   "images" : [ | ||||
|     { | ||||
|       "idiom" : "universal", | ||||
|       "filename" : "LaunchImage.png", | ||||
|       "scale" : "1x" | ||||
|     }, | ||||
|     { | ||||
|       "idiom" : "universal", | ||||
|       "filename" : "LaunchImage@2x.png", | ||||
|       "scale" : "2x" | ||||
|     }, | ||||
|     { | ||||
|       "idiom" : "universal", | ||||
|       "filename" : "LaunchImage@3x.png", | ||||
|       "scale" : "3x" | ||||
|     } | ||||
|   ], | ||||
|   "info" : { | ||||
|     "version" : 1, | ||||
|     "author" : "xcode" | ||||
|   } | ||||
| } | ||||
| Before Width: | Height: | Size: 68 B | 
| Before Width: | Height: | Size: 68 B | 
| Before Width: | Height: | Size: 68 B | 
| @ -1,5 +0,0 @@ | ||||
| # Launch Screen Assets | ||||
| 
 | ||||
| You can customize the launch screen with your own desired assets by replacing the image files in this directory. | ||||
| 
 | ||||
| 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. | ||||
| @ -1,37 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM"> | ||||
|     <dependencies> | ||||
|         <deployment identifier="iOS"/> | ||||
|         <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/> | ||||
|     </dependencies> | ||||
|     <scenes> | ||||
|         <!--View Controller--> | ||||
|         <scene sceneID="EHf-IW-A2E"> | ||||
|             <objects> | ||||
|                 <viewController id="01J-lp-oVM" sceneMemberID="viewController"> | ||||
|                     <layoutGuides> | ||||
|                         <viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/> | ||||
|                         <viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/> | ||||
|                     </layoutGuides> | ||||
|                     <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3"> | ||||
|                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | ||||
|                         <subviews> | ||||
|                             <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4"> | ||||
|                             </imageView> | ||||
|                         </subviews> | ||||
|                         <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> | ||||
|                         <constraints> | ||||
|                             <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/> | ||||
|                             <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/> | ||||
|                         </constraints> | ||||
|                     </view> | ||||
|                 </viewController> | ||||
|                 <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/> | ||||
|             </objects> | ||||
|             <point key="canvasLocation" x="53" y="375"/> | ||||
|         </scene> | ||||
|     </scenes> | ||||
|     <resources> | ||||
|         <image name="LaunchImage" width="168" height="185"/> | ||||
|     </resources> | ||||
| </document> | ||||
| @ -1,26 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r"> | ||||
|     <dependencies> | ||||
|         <deployment identifier="iOS"/> | ||||
|         <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/> | ||||
|     </dependencies> | ||||
|     <scenes> | ||||
|         <!--Flutter View Controller--> | ||||
|         <scene sceneID="tne-QT-ifu"> | ||||
|             <objects> | ||||
|                 <viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController"> | ||||
|                     <layoutGuides> | ||||
|                         <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/> | ||||
|                         <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/> | ||||
|                     </layoutGuides> | ||||
|                     <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC"> | ||||
|                         <rect key="frame" x="0.0" y="0.0" width="600" height="600"/> | ||||
|                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | ||||
|                         <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/> | ||||
|                     </view> | ||||
|                 </viewController> | ||||
|                 <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/> | ||||
|             </objects> | ||||
|         </scene> | ||||
|     </scenes> | ||||
| </document> | ||||
| @ -1,51 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||||
| <plist version="1.0"> | ||||
| <dict> | ||||
| 	<key>CFBundleDevelopmentRegion</key> | ||||
| 	<string>$(DEVELOPMENT_LANGUAGE)</string> | ||||
| 	<key>CFBundleDisplayName</key> | ||||
| 	<string>Display Name</string> | ||||
| 	<key>CFBundleExecutable</key> | ||||
| 	<string>$(EXECUTABLE_NAME)</string> | ||||
| 	<key>CFBundleIdentifier</key> | ||||
| 	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> | ||||
| 	<key>CFBundleInfoDictionaryVersion</key> | ||||
| 	<string>6.0</string> | ||||
| 	<key>CFBundleName</key> | ||||
| 	<string>Display Name</string> | ||||
| 	<key>CFBundlePackageType</key> | ||||
| 	<string>APPL</string> | ||||
| 	<key>CFBundleShortVersionString</key> | ||||
| 	<string>$(FLUTTER_BUILD_NAME)</string> | ||||
| 	<key>CFBundleSignature</key> | ||||
| 	<string>????</string> | ||||
| 	<key>CFBundleVersion</key> | ||||
| 	<string>$(FLUTTER_BUILD_NUMBER)</string> | ||||
| 	<key>LSRequiresIPhoneOS</key> | ||||
| 	<true/> | ||||
| 	<key>UILaunchStoryboardName</key> | ||||
| 	<string>LaunchScreen</string> | ||||
| 	<key>UIMainStoryboardFile</key> | ||||
| 	<string>Main</string> | ||||
| 	<key>UISupportedInterfaceOrientations</key> | ||||
| 	<array> | ||||
| 		<string>UIInterfaceOrientationPortrait</string> | ||||
| 		<string>UIInterfaceOrientationLandscapeLeft</string> | ||||
| 		<string>UIInterfaceOrientationLandscapeRight</string> | ||||
| 	</array> | ||||
| 	<key>UISupportedInterfaceOrientations~ipad</key> | ||||
| 	<array> | ||||
| 		<string>UIInterfaceOrientationPortrait</string> | ||||
| 		<string>UIInterfaceOrientationPortraitUpsideDown</string> | ||||
| 		<string>UIInterfaceOrientationLandscapeLeft</string> | ||||
| 		<string>UIInterfaceOrientationLandscapeRight</string> | ||||
| 	</array> | ||||
| 	<key>UIViewControllerBasedStatusBarAppearance</key> | ||||
| 	<false/> | ||||
| 	<key>CADisableMinimumFrameDurationOnPhone</key> | ||||
| 	<true/> | ||||
| 	<key>UIApplicationSupportsIndirectInputEvents</key> | ||||
| 	<true/> | ||||
| </dict> | ||||
| </plist> | ||||
| @ -1 +0,0 @@ | ||||
| #import "GeneratedPluginRegistrant.h" | ||||
| @ -1,8 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||||
| <plist version="1.0"> | ||||
| <dict> | ||||
| 	<key>aps-environment</key> | ||||
| 	<string>development</string> | ||||
| </dict> | ||||
| </plist> | ||||
| @ -5,4 +5,5 @@ output-dir: lib/gen/ | ||||
| nullable-getter: false | ||||
| use-deferred-loading: true | ||||
| synthetic-package: false | ||||
| use-escaping: false | ||||
| header: "/// Display Name, localized files. Automatically generated with `task gen:intl`." | ||||
| @ -2,18 +2,44 @@ import 'dart:async'; | ||||
| 
 | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:flutter_bloc/flutter_bloc.dart'; | ||||
| import 'package:logging/logging.dart'; | ||||
| import 'package:starting_template/core/dependency_injection/get_it.dart'; | ||||
| import 'package:starting_template/core/flavors/flavor.dart'; | ||||
| import 'package:starting_template/core/enums/feature_flag.dart'; | ||||
| import 'package:starting_template/core/logger/app_logger.dart'; | ||||
| import 'package:starting_template/core/logger/simple_log_printer.dart'; | ||||
| import 'package:starting_template/core/utils/app_bloc_observer.dart'; | ||||
| import 'package:starting_template/core/utils/env.dart'; | ||||
| 
 | ||||
| Future<void> bootstrap(FutureOr<Widget> Function() builder) async { | ||||
|   // Initialize logging | ||||
|   final logger = AppLogger(); | ||||
| 
 | ||||
|   await runZonedGuarded( | ||||
|     () async { | ||||
|       WidgetsFlutterBinding.ensureInitialized(); | ||||
| 
 | ||||
|       // Verify that we have the correct environment | ||||
|       Env.verify(); | ||||
| 
 | ||||
|       if (Env.isFeatureEnabled(FeatureFlag.logger)) { | ||||
|         logger | ||||
|           ..level = Env.loggerLevel | ||||
|           ..addPlugin(const SimpleLogPrinter()); | ||||
|       } else { | ||||
|         logger.level = Level.OFF; | ||||
|       } | ||||
| 
 | ||||
|       debugPrint(Env.summary); // Print even if logger is disabled | ||||
| 
 | ||||
|       Bloc.observer = AppBlocObserver(); | ||||
| 
 | ||||
|   debugPrint('${Flavor.instance}'); | ||||
| 
 | ||||
|       // Intialize dependencies injection | ||||
|       await GetItInitializer.init(); | ||||
| 
 | ||||
|       runApp(await builder()); | ||||
|     }, | ||||
|     (error, stackTrace) { | ||||
|       logger.error(error.toString(), stackTrace); | ||||
|     }, | ||||
|   ); | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,163 @@ | ||||
| const String _envName = 'ENV_NAME'; | ||||
| const String _dataSource = 'DATA_SOURCE'; | ||||
| const String _loggerLevel = 'LOGGER_LEVEL'; | ||||
| const String _featureFlags = 'FEATURE_FLAGS'; | ||||
| 
 | ||||
| enum BuildConfigKey { | ||||
|   envName(_envName, isRequired: true), | ||||
|   dataSource(_dataSource, isRequired: true), | ||||
|   loggerLevel(_loggerLevel), | ||||
|   featureFlags(_featureFlags); | ||||
| 
 | ||||
|   const BuildConfigKey(this.key, {this.isRequired = false}); | ||||
| 
 | ||||
|   final String key; | ||||
|   final bool isRequired; | ||||
| 
 | ||||
|   /// Returns true if the environment variable is defined | ||||
|   /// | ||||
|   /// Cannot use `const bool.hasEnvironment(key)` because it is not a | ||||
|   /// constant expression. This is why we need to use a switch statement. | ||||
|   bool get isDefined => switch (this) { | ||||
|         BuildConfigKey.envName => const bool.hasEnvironment(_envName), | ||||
|         BuildConfigKey.dataSource => const bool.hasEnvironment(_dataSource), | ||||
|         BuildConfigKey.loggerLevel => const bool.hasEnvironment(_loggerLevel), | ||||
|         BuildConfigKey.featureFlags => const bool.hasEnvironment(_featureFlags), | ||||
|       }; | ||||
| 
 | ||||
|   /// Returns the value of the environment variable | ||||
|   /// | ||||
|   /// Cannot use `const String.fromEnvironment(key)` because it is not a | ||||
|   /// constant expression. This is why we need to use a switch statement. | ||||
|   String get stringFromEnv => switch (this) { | ||||
|         BuildConfigKey.envName => const String.fromEnvironment(_envName), | ||||
|         BuildConfigKey.dataSource => const String.fromEnvironment(_dataSource), | ||||
|         BuildConfigKey.loggerLevel => | ||||
|           const String.fromEnvironment(_loggerLevel), | ||||
|         BuildConfigKey.featureFlags => | ||||
|           const String.fromEnvironment(_featureFlags), | ||||
|       }; | ||||
| 
 | ||||
|   /// Returns the values of the environment variables | ||||
|   static String get summary { | ||||
|     final summary = StringBuffer(); | ||||
|     for (final key in BuildConfigKey.values) { | ||||
|       if (key.isRequired && !key.isDefined) { | ||||
|         summary.writeln('${key.key} is not defined (required)'); | ||||
|         continue; | ||||
|       } | ||||
|       if (key.isDefined) { | ||||
|         summary.writeln('${key.key}: ${key.stringFromEnv}'); | ||||
|         continue; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     return summary.toString(); | ||||
|   } | ||||
| 
 | ||||
|   /// Returns the value of the environment variable | ||||
|   /// | ||||
|   /// If the environment variable is not defined, returns null | ||||
|   T? getOrNull<T>() { | ||||
|     try { | ||||
|       return get<T>(); | ||||
|     } catch (_) { | ||||
|       return null; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /// Returns the value of the environment variable | ||||
|   /// | ||||
|   /// If the environment variable is not defined, returns the value of [or] | ||||
|   T getOr<T>(T Function() or) { | ||||
|     switch (T) { | ||||
|       case String: | ||||
|         return _getStringOr(or as String Function()) as T; | ||||
|       case int: | ||||
|         return _getIntOr(or as int Function()) as T; | ||||
|       case double: | ||||
|         return _getDoubleOr(or as double Function()) as T; | ||||
|       case bool: | ||||
|         return _getBool() as T; | ||||
|       default: | ||||
|         throw Exception('Type $T is not supported'); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /// Returns the value of the environment variable | ||||
|   /// | ||||
|   /// Throws an exception if the environment variable is not defined | ||||
|   T get<T>() { | ||||
|     switch (T) { | ||||
|       case String: | ||||
|         return _getString() as T; | ||||
|       case int: | ||||
|         return _getInt() as T; | ||||
|       case double: | ||||
|         return _getDouble() as T; | ||||
|       case bool: | ||||
|         return _getBool() as T; | ||||
|       default: | ||||
|         throw Exception('Type $T is not supported'); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   String _getString() { | ||||
|     final value = stringFromEnv; | ||||
|     if (value.isEmpty) { | ||||
|       throw Exception('$key is not defined'); | ||||
|     } | ||||
| 
 | ||||
|     return value; | ||||
|   } | ||||
| 
 | ||||
|   int _getInt() { | ||||
|     // Use int.tryParse instead int.fromEnvironment because we want to | ||||
|     // support 0 as a value too. | ||||
|     final value = int.tryParse(stringFromEnv); | ||||
|     if (value == null) { | ||||
|       throw Exception('$key is not defined'); | ||||
|     } | ||||
| 
 | ||||
|     return value; | ||||
|   } | ||||
| 
 | ||||
|   double _getDouble() { | ||||
|     final value = double.tryParse(stringFromEnv); | ||||
|     if (value == null) { | ||||
|       throw Exception('$key is not defined'); | ||||
|     } | ||||
| 
 | ||||
|     return value; | ||||
|   } | ||||
| 
 | ||||
|   bool _getBool() { | ||||
|     final value = stringFromEnv.toLowerCase(); | ||||
| 
 | ||||
|     return value == 'true' || value == '1'; | ||||
|   } | ||||
| 
 | ||||
|   double _getDoubleOr(double Function() or) { | ||||
|     try { | ||||
|       return _getDouble(); | ||||
|     } catch (_) { | ||||
|       return or(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   String _getStringOr(String Function() or) { | ||||
|     try { | ||||
|       return _getString(); | ||||
|     } catch (_) { | ||||
|       return or(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   int _getIntOr(int Function() or) { | ||||
|     try { | ||||
|       return _getInt(); | ||||
|     } catch (_) { | ||||
|       return or(); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1 @@ | ||||
| const int kBlocObserverMessageLength = 100; | ||||
| @ -1,18 +0,0 @@ | ||||
| /// Firebase Emulator constants. | ||||
| /// | ||||
| /// If you don't use Firebase, it can be safely deleted. | ||||
| abstract class Emulator { | ||||
|   static const String firebaseCloudFunctionEnvKey = | ||||
|       'FIREBASE_EMULATOR_CLOUD_FUNCTION_PORT'; | ||||
|   static const String firebaseFirestoreEnvKey = | ||||
|       'FIREBASE_EMULATOR_FIRESTORE_PORT'; | ||||
|   static const String firebaseAuthEnvKey = 'FIREBASE_EMULATOR_AUTH_PORT'; | ||||
|   static const String firebaseStorageEnvKey = 'FIREBASE_EMULATOR_STORAGE_PORT'; | ||||
|   static const String hostEnvKey = 'FIREBASE_EMULATOR_HOST'; | ||||
| 
 | ||||
|   static const int defaultFirebaseCloudFunctionPort = 5001; | ||||
|   static const int defaultFirebaseFirestorePort = 8080; | ||||
|   static const int defaultFirebaseAuthPort = 9099; | ||||
|   static const int defaultFirebaseStoragePort = 9199; | ||||
|   static const defaultHost = 'localhost'; | ||||
| } | ||||
| @ -1,52 +1,56 @@ | ||||
| import 'dart:async'; | ||||
| 
 | ||||
| import 'package:flutter/foundation.dart'; | ||||
| import 'package:get_it/get_it.dart'; | ||||
| import 'package:starting_template/core/enums/dev_mode.dart'; | ||||
| import 'package:starting_template/core/flavors/flavor.dart'; | ||||
| import 'package:starting_template/core/utils/firebase_emulator.dart'; | ||||
| import 'package:starting_template/core/enums/data_source_type.dart'; | ||||
| import 'package:starting_template/core/logger/app_logger.dart'; | ||||
| import 'package:starting_template/core/utils/env.dart'; | ||||
| 
 | ||||
| final getIt = GetIt.I; | ||||
| 
 | ||||
| /// Service and Data Source locator | ||||
| abstract class GetItInitializer { | ||||
|   static AppLogger get logger => AppLogger('GetItInitializer'); | ||||
| 
 | ||||
|   static FutureOr<void> _initCommon() async { | ||||
|     // TODO(wyatt): Initialize common sources/services | ||||
|     logger.info('Initializing common sources/services'); | ||||
|   } | ||||
| 
 | ||||
|   static FutureOr<void> _initMock() async { | ||||
|     // TODO(wyatt): Initialize mocked sources/services. | ||||
|     logger.info('Initializing mock sources'); | ||||
|   } | ||||
| 
 | ||||
|   static FutureOr<void> _initLocal() async { | ||||
|     // TODO(wyatt): Initialize local sources/services. | ||||
|     final emulator = FirebaseEmulator.fromEnv(); | ||||
|     debugPrint('Firebase Emulator: $emulator'); | ||||
|   static FutureOr<void> _initApi() async { | ||||
|     logger.info('Initializing API sources'); | ||||
|   } | ||||
| 
 | ||||
|   static FutureOr<void> _initReal() async { | ||||
|     // TODO(wyatt): Initialize real sources/services | ||||
|   static FutureOr<void> _initRepositories() async { | ||||
|     logger.info('Initializing repositories'); | ||||
|   } | ||||
| 
 | ||||
|   static FutureOr<void> _initUseCases() async { | ||||
|     logger.info('Initializing use cases'); | ||||
|   } | ||||
| 
 | ||||
|   static FutureOr<void> init() async { | ||||
|     // Initialize common sources/services | ||||
|     await _initCommon(); | ||||
| 
 | ||||
|     // Initialize sources/services based on flavor | ||||
|     switch (Flavor.instance.devMode) { | ||||
|       case DevMode.mock: | ||||
|     // Initialize sources/services based on data source type | ||||
|     switch (Env.dataSource) { | ||||
|       case DataSourceType.mock: | ||||
|         await _initMock(); | ||||
|         break; | ||||
|       case DevMode.local: | ||||
|         await _initLocal(); | ||||
|       case DataSourceType.api: | ||||
|         await _initApi(); | ||||
|         break; | ||||
|       case DevMode.real: | ||||
|         await _initReal(); | ||||
|         break; | ||||
|       case null: | ||||
|         throw Exception('DevMode not initialized!'); | ||||
|     } | ||||
| 
 | ||||
|     // Initialize repositories | ||||
|     await _initRepositories(); | ||||
| 
 | ||||
|     // Initialize use cases | ||||
|     await _initUseCases(); | ||||
| 
 | ||||
|     await getIt.allReady(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,31 +0,0 @@ | ||||
| enum BuildMode { | ||||
|   /// Debug build mode. Pass `--debug` to `flutter run` or `flutter build` to | ||||
|   /// use this mode. | ||||
|   debug, | ||||
| 
 | ||||
|   /// Release build mode. Pass `--profile` to `flutter run` or `flutter build` | ||||
|   /// to use this mode. | ||||
|   profile, | ||||
| 
 | ||||
|   /// Release build mode. Pass `--release` to `flutter run` or `flutter build` | ||||
|   /// to use this mode. | ||||
|   release; | ||||
| 
 | ||||
|   @override | ||||
|   String toString() => name; | ||||
| 
 | ||||
|   /// Tries to parse String and returns mode. Fallback is returned if there | ||||
|   /// is an error during parsing. | ||||
|   static BuildMode fromString( | ||||
|     String? mode, { | ||||
|     BuildMode fallback = BuildMode.debug, | ||||
|   }) { | ||||
|     for (final m in values) { | ||||
|       if (m.name == mode) { | ||||
|         return m; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     return fallback; | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,16 @@ | ||||
| enum DataSourceType { | ||||
|   mock, | ||||
|   api; | ||||
| 
 | ||||
|   static DataSourceType fromString(String value) => DataSourceType.values | ||||
|       .firstWhere((e) => e.name == value.toLowerCase().trim()); | ||||
| 
 | ||||
|   static DataSourceType? fromStringOr(String value, {DataSourceType? or}) { | ||||
|     try { | ||||
|       return DataSourceType.values | ||||
|           .firstWhere((e) => e.name == value.toLowerCase().trim()); | ||||
|     } catch (_) { | ||||
|       return or; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -1,25 +0,0 @@ | ||||
| enum DevMode { | ||||
|   /// Mocked data sources and services | ||||
|   mock, | ||||
| 
 | ||||
|   /// Local data sources and services, like local database, or firebase emulator | ||||
|   local, | ||||
| 
 | ||||
|   /// Real data sources and services, like firebase or other cloud services | ||||
|   real; | ||||
| 
 | ||||
|   @override | ||||
|   String toString() => name; | ||||
| 
 | ||||
|   /// Tries to parse String and returns mode. Fallback is returned if there | ||||
|   /// is an error during parsing. | ||||
|   static DevMode fromString(String? mode, {DevMode fallback = DevMode.mock}) { | ||||
|     for (final m in values) { | ||||
|       if (m.name == mode) { | ||||
|         return m; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     return fallback; | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,17 @@ | ||||
| enum EnvType { | ||||
|   dev, | ||||
|   staging, | ||||
|   prod; | ||||
| 
 | ||||
|   static EnvType fromString(String value) => | ||||
|       EnvType.values.firstWhere((e) => e.name == value.toLowerCase().trim()); | ||||
| 
 | ||||
|   static EnvType? fromStringOr(String value, {EnvType? or}) { | ||||
|     try { | ||||
|       return EnvType.values | ||||
|           .firstWhere((e) => e.name == value.toLowerCase().trim()); | ||||
|     } catch (_) { | ||||
|       return or; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,18 @@ | ||||
| enum FeatureFlag { | ||||
|   logger; | ||||
| 
 | ||||
|   static FeatureFlag fromString(String value) => FeatureFlag.values | ||||
|       .firstWhere((e) => e.name == value.toLowerCase().trim()); | ||||
| 
 | ||||
|   static FeatureFlag? fromStringOr(String value, {FeatureFlag? or}) { | ||||
|     try { | ||||
|       return FeatureFlag.values | ||||
|           .firstWhere((e) => e.name == value.toLowerCase().trim()); | ||||
|     } catch (_) { | ||||
|       return or; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   String toString() => name; | ||||
| } | ||||
| @ -1,19 +1,3 @@ | ||||
| // Copyright (C) 2023 WYATT GROUP | ||||
| // Please see the AUTHORS file for details. | ||||
| // | ||||
| // This program is free software: you can redistribute it and/or modify | ||||
| // it under the terms of the GNU General Public License as published by | ||||
| // the Free Software Foundation, either version 3 of the License, or | ||||
| // any later version. | ||||
| // | ||||
| // This program is distributed in the hope that it will be useful, | ||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
| // GNU General Public License for more details. | ||||
| // | ||||
| // You should have received a copy of the GNU General Public License | ||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| enum PageProtection { | ||||
|   /// The page can be accessed without authentication. | ||||
|   public, | ||||
|  | ||||
| @ -2,5 +2,6 @@ import 'package:flutter/widgets.dart'; | ||||
| import 'package:starting_template/gen/app_localizations.dart'; | ||||
| 
 | ||||
| extension BuildContextExtension on BuildContext { | ||||
|   /// Returns the [AppLocalizations] instance | ||||
|   AppLocalizations get l10n => AppLocalizations.of(this); | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,19 @@ | ||||
| import 'package:flutter_bloc/flutter_bloc.dart'; | ||||
| 
 | ||||
| extension DebuggableBloc on BlocBase<dynamic> { | ||||
|   static final _showInObserver = Expando<bool>(); | ||||
| 
 | ||||
|   bool get showInObserver => _showInObserver[this] ?? true; | ||||
| 
 | ||||
|   set showInObserver(bool value) => _showInObserver[this] = value; | ||||
| 
 | ||||
|   /// Show the bloc in the observer | ||||
|   void show() { | ||||
|     showInObserver = true; | ||||
|   } | ||||
| 
 | ||||
|   /// Hide the bloc from the observer | ||||
|   void hide() { | ||||
|     showInObserver = false; | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,26 @@ | ||||
| import 'package:get_it/get_it.dart'; | ||||
| 
 | ||||
| extension GetItExtension on GetIt { | ||||
|   void injectInterface<T extends Object>( | ||||
|     T instanceToInject, { | ||||
|     String? instanceName, | ||||
|   }) { | ||||
|     registerSingleton(instanceToInject, instanceName: instanceName); | ||||
|   } | ||||
| 
 | ||||
|   void injectRepository<T extends Object>(FactoryFunc<T> func) { | ||||
|     registerLazySingleton(func); | ||||
|   } | ||||
| 
 | ||||
|   void injectDataSource<T extends Object>(FactoryFunc<T> func) { | ||||
|     registerLazySingleton(func); | ||||
|   } | ||||
| 
 | ||||
|   void injectUseCase<T extends Object>(FactoryFunc<T> func) { | ||||
|     registerLazySingleton(func); | ||||
|   } | ||||
| 
 | ||||
|   void injectBloc<T extends Object>(FactoryFunc<T> func) { | ||||
|     registerFactory(func); | ||||
|   } | ||||
| } | ||||
| @ -1,19 +1,3 @@ | ||||
| // Copyright (C) 2023 WYATT GROUP | ||||
| // Please see the AUTHORS file for details. | ||||
| // | ||||
| // This program is free software: you can redistribute it and/or modify | ||||
| // it under the terms of the GNU General Public License as published by | ||||
| // the Free Software Foundation, either version 3 of the License, or | ||||
| // any later version. | ||||
| // | ||||
| // This program is distributed in the hope that it will be useful, | ||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
| // GNU General Public License for more details. | ||||
| // | ||||
| // You should have received a copy of the GNU General Public License | ||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import 'package:go_router/go_router.dart'; | ||||
| import 'package:starting_template/core/enums/page_protection.dart'; | ||||
| 
 | ||||
| @ -0,0 +1,21 @@ | ||||
| import 'package:go_router/go_router.dart'; | ||||
| import 'package:starting_template/core/extensions/go_route_guard.dart'; | ||||
| 
 | ||||
| extension GoRouteListExtension on Iterable<GoRoute> { | ||||
|   /// Returns a list of public routes. | ||||
|   List<GoRoute> get publicRoutes => | ||||
|       where((route) => route.isPublic).toList(growable: false); | ||||
| 
 | ||||
|   /// Returns a list of protected routes. | ||||
|   List<GoRoute> get protectedRoutes => | ||||
|       where((route) => route.isProtected).toList(growable: false); | ||||
| 
 | ||||
|   /// Returns a list of routes that are neither public nor protected. | ||||
|   List<GoRoute> get noneRoutes => | ||||
|       where((route) => route.isNone).toList(growable: false); | ||||
| 
 | ||||
|   GoRoute fromName(String name) => firstWhere((route) => route.name == name); | ||||
|   GoRoute fromPath(String path) => firstWhere((route) => route.path == path); | ||||
| 
 | ||||
|   GoRoute operator [](String name) => fromName(name); | ||||
| } | ||||
| @ -0,0 +1,20 @@ | ||||
| import 'package:go_router/go_router.dart'; | ||||
| 
 | ||||
| /// Flatten the [GoRoute] tree. | ||||
| extension RouteBaseExtension on RouteBase { | ||||
|   List<GoRoute> flatten() { | ||||
|     final List<GoRoute> routes = []; | ||||
|     if (this is GoRoute) { | ||||
|       routes.add(this as GoRoute); | ||||
|     } else if (this is ShellRoute) { | ||||
|       routes.addAll( | ||||
|         (this as ShellRoute) | ||||
|             .routes | ||||
|             .map((route) => route.flatten()) | ||||
|             .expand((routeList) => routeList), | ||||
|       ); | ||||
|     } | ||||
| 
 | ||||
|     return routes; | ||||
|   } | ||||
| } | ||||
| @ -1,65 +0,0 @@ | ||||
| import 'package:flutter/foundation.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:starting_template/core/enums/build_mode.dart'; | ||||
| import 'package:starting_template/core/enums/dev_mode.dart'; | ||||
| 
 | ||||
| class Flavor { | ||||
|   Flavor._({ | ||||
|     this.flavorName, | ||||
|     this.bannerColor, | ||||
|   }) { | ||||
|     // Determine build mode | ||||
|     buildMode = kReleaseMode | ||||
|         ? BuildMode.release | ||||
|         : kProfileMode | ||||
|             ? BuildMode.profile | ||||
|             : BuildMode.debug; | ||||
| 
 | ||||
|     // Retrieve dev mode, fallback to mock | ||||
|     devMode = DevMode.fromString( | ||||
|       const String.fromEnvironment('DEV_MODE', defaultValue: 'mock'), | ||||
|     ); | ||||
| 
 | ||||
|     _instance = this; | ||||
|   } | ||||
| 
 | ||||
|   static Flavor? _instance; | ||||
| 
 | ||||
|   final String? flavorName; | ||||
|   final Color? bannerColor; | ||||
| 
 | ||||
|   late final DevMode? devMode; | ||||
|   late final BuildMode? buildMode; | ||||
| 
 | ||||
|   /// Returns [Flavor] instance. | ||||
|   static Flavor get instance { | ||||
|     if (_instance == null) { | ||||
|       throw Exception('Flavor not initialized!'); | ||||
|     } | ||||
| 
 | ||||
|     return _instance!; | ||||
|   } | ||||
| 
 | ||||
|   String get name => flavorName ?? 'Unknown'; | ||||
|   Color get color => bannerColor ?? Colors.grey; | ||||
| 
 | ||||
|   static bool shouldShowBanner() => instance.buildMode != BuildMode.release; | ||||
| 
 | ||||
|   @override | ||||
|   String toString() => | ||||
|       'Flavor: $flavorName, DevMode: $devMode, BuildMode: $buildMode'; | ||||
| } | ||||
| 
 | ||||
| class DevelopmentFlavor extends Flavor { | ||||
|   DevelopmentFlavor() | ||||
|       : super._(flavorName: 'Development', bannerColor: Colors.red); | ||||
| } | ||||
| 
 | ||||
| class StagingFlavor extends Flavor { | ||||
|   StagingFlavor() : super._(flavorName: 'Staging', bannerColor: Colors.orange); | ||||
| } | ||||
| 
 | ||||
| class ProductionFlavor extends Flavor { | ||||
|   ProductionFlavor() | ||||
|       : super._(flavorName: 'Production', bannerColor: Colors.green); | ||||
| } | ||||
| @ -0,0 +1,81 @@ | ||||
| import 'package:logging/logging.dart'; | ||||
| import 'package:starting_template/core/logger/app_logger_plugin.dart'; | ||||
| import 'package:starting_template/core/logger/log_level.dart'; | ||||
| import 'package:starting_template/core/mixins/debuggable.dart'; | ||||
| 
 | ||||
| class AppLogger with Debuggable { | ||||
|   /// Creates a top-level [AppLogger]. | ||||
|   factory AppLogger([String namespace = rootNamespace]) { | ||||
|     if (!namespace.startsWith(rootNamespace)) { | ||||
|       namespace = '$rootNamespace.$namespace'; | ||||
|     } | ||||
| 
 | ||||
|     return AppLogger.activeLoggers[namespace] ??= AppLogger._(namespace); | ||||
|   } | ||||
| 
 | ||||
|   AppLogger._(String namespace) : _logger = Logger(namespace); | ||||
| 
 | ||||
|   /// The root namespace for all [AppLogger]s. | ||||
|   static const rootNamespace = 'StartingTemplate'; | ||||
| 
 | ||||
|   static final Map<String, AppLogger> activeLoggers = {}; | ||||
| 
 | ||||
|   String get namespace => _logger.fullName; | ||||
| 
 | ||||
|   final Logger _logger; | ||||
| 
 | ||||
|   AppLogger createChild(String name) { | ||||
|     assert(name.isNotEmpty, 'Name should not be empty'); | ||||
| 
 | ||||
|     return AppLogger('$namespace.$name'); | ||||
|   } | ||||
| 
 | ||||
|   Level get level => _logger.level; | ||||
| 
 | ||||
|   set level(Level level) { | ||||
|     hierarchicalLoggingEnabled = true; | ||||
|     _logger.level = level; | ||||
|   } | ||||
| 
 | ||||
|   void addPlugin(AppLoggerPlugin plugin) { | ||||
|     _logger.onRecord.listen(plugin.handleLogRecord); | ||||
|   } | ||||
| 
 | ||||
|   /// Logs a [message] at the given [level]. | ||||
|   void log( | ||||
|     Level level, | ||||
|     String message, [ | ||||
|     Object? error, | ||||
|     StackTrace? stackTrace, | ||||
|   ]) { | ||||
|     _logger.log(level, message, error, stackTrace); | ||||
|   } | ||||
| 
 | ||||
|   /// Logs a message with level [LogLevel.verbose]. | ||||
|   void verbose(String message, [Object? error, StackTrace? stackTrace]) { | ||||
|     log(LogLevel.verbose, message, error, stackTrace); | ||||
|   } | ||||
| 
 | ||||
|   /// Logs a message with level [LogLevel.debug]. | ||||
|   void debug(String message, [Object? error, StackTrace? stackTrace]) { | ||||
|     log(LogLevel.debug, message, error, stackTrace); | ||||
|   } | ||||
| 
 | ||||
|   /// Logs a message with level [LogLevel.info]. | ||||
|   void info(String message, [Object? error, StackTrace? stackTrace]) { | ||||
|     log(LogLevel.info, message, error, stackTrace); | ||||
|   } | ||||
| 
 | ||||
|   /// Logs a message with level [LogLevel.warn]. | ||||
|   void warn(String message, [Object? error, StackTrace? stackTrace]) { | ||||
|     log(LogLevel.warn, message, error, stackTrace); | ||||
|   } | ||||
| 
 | ||||
|   /// Logs a message with level [LogLevel.error]. | ||||
|   void error(String message, [Object? error, StackTrace? stackTrace]) { | ||||
|     log(LogLevel.error, message, error, stackTrace); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   String get debugName => 'AppLogger'; | ||||
| } | ||||
| @ -0,0 +1,7 @@ | ||||
| import 'package:logging/logging.dart'; | ||||
| 
 | ||||
| abstract class AppLoggerPlugin { | ||||
|   const AppLoggerPlugin(); | ||||
| 
 | ||||
|   void handleLogRecord(LogRecord record); | ||||
| } | ||||
| @ -0,0 +1,20 @@ | ||||
| import 'package:logging/logging.dart'; | ||||
| 
 | ||||
| abstract class LogLevel { | ||||
|   static const Level verbose = Level('VERBOSE', 300); | ||||
|   static const Level bloc = Level('BLOC', 450); | ||||
|   static const Level debug = Level('DEBUG', 500); | ||||
|   static const Level info = Level.INFO; | ||||
|   static const Level warn = Level.WARNING; | ||||
|   static const Level error = Level('ERROR', 1000); | ||||
| 
 | ||||
|   static Level fromString(String value) => switch (value.toLowerCase()) { | ||||
|         'verbose' => verbose, | ||||
|         'bloc' => bloc, | ||||
|         'debug' => debug, | ||||
|         'info' => info, | ||||
|         'warn' || 'warning' => warn, | ||||
|         'error' || 'fail' || 'failure' => error, | ||||
|         _ => throw Exception('Unknown log level: $value'), | ||||
|       }; | ||||
| } | ||||
| @ -0,0 +1,40 @@ | ||||
| import 'package:logging/logging.dart'; | ||||
| import 'package:starting_template/core/logger/app_logger_plugin.dart'; | ||||
| 
 | ||||
| class SimpleLogPrinter implements AppLoggerPlugin { | ||||
|   const SimpleLogPrinter(); | ||||
| 
 | ||||
|   /// Formats [LogRecord] using level, namespace, and message components. | ||||
|   static String formatLogRecord(LogRecord record) { | ||||
|     final buffer = StringBuffer() | ||||
|       ..write(record.level.name.toUpperCase()) | ||||
|       ..write(' | '); | ||||
| 
 | ||||
|     final namespace = record.loggerName.split('.').lastOrNull; | ||||
|     if (namespace != null && namespace.isNotEmpty) { | ||||
|       buffer | ||||
|         ..write(namespace) | ||||
|         ..write(' | '); | ||||
|     } | ||||
| 
 | ||||
|     buffer.write(record.message); | ||||
|     final error = record.error; | ||||
|     if (error != null) { | ||||
|       buffer | ||||
|         ..write(': ') | ||||
|         ..writeln(error); | ||||
|     } | ||||
|     final stackTrace = record.stackTrace; | ||||
|     if (stackTrace != null) { | ||||
|       buffer.writeln(stackTrace); | ||||
|     } | ||||
| 
 | ||||
|     return buffer.toString(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   void handleLogRecord(LogRecord record) { | ||||
|     // ignore: avoid_print | ||||
|     print(formatLogRecord(record)); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,3 @@ | ||||
| mixin Debuggable { | ||||
|   String get debugName; | ||||
| } | ||||