feat: upgrade wyatt_app_template

This commit is contained in:
Hugo Pointcheval 2023-09-15 17:39:33 +02:00
parent b92d2a588d
commit c00ebcdb4a
Signed by: hugo
GPG Key ID: 3AAC487E131E00BC
299 changed files with 1991 additions and 5345 deletions

View File

@ -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:

View File

@ -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);
}

View File

@ -47,8 +47,17 @@ app.*.map.json
/android/app/debug
/android/app/profile
/android/app/release
.mason/
# Custom
.mason/
.env
!.env.example
node_modules/
node_modules/
lib/gen/
**/*.g.dart
**/*.freezed.dart
android/fastlane/report.xml
pubspec_overrides.yaml
.fvm/flutter_sdk
*.apk
*.apks

View File

@ -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,12 +44,13 @@
"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"
],
"flutterMode": "release"
},
]
}
}

View File

@ -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).

View 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

View File

@ -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:

View File

@ -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

View File

@ -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"
}

View File

@ -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>

View File

@ -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>

View File

@ -1,6 +0,0 @@
package io.wyattapp.start
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
}

View File

@ -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>

View File

@ -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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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
}

View File

@ -1,3 +0,0 @@
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true

View File

@ -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

View File

@ -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"

View File

@ -0,0 +1 @@
# just to keep empty folder in brick generation

View File

@ -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 {} \;

View File

@ -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

View File

@ -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

View File

@ -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}}

View File

@ -0,0 +1,6 @@
{
"ENV_NAME": "dev",
"DATA_SOURCE": "api",
"LOGGER_LEVEL": "debug",
"FEATURE_FLAGS": "logger"
}

View File

@ -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"
}

View File

@ -0,0 +1,4 @@
{
"ENV_NAME": "prod",
"DATA_SOURCE": "api"
}

View File

@ -0,0 +1,5 @@
{
"ENV_NAME": "staging",
"DATA_SOURCE": "api",
"FEATURE_FLAGS": "logger"
}

View File

@ -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

View File

@ -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>

View File

@ -1,2 +0,0 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

View File

@ -1,2 +0,0 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

View File

@ -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

View File

@ -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

View File

@ -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 */;
}

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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)
}
}

View File

@ -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"
}
}

View File

@ -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"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 B

View File

@ -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.

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -1 +0,0 @@
#import "GeneratedPluginRegistrant.h"

View File

@ -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>

View File

@ -5,4 +5,5 @@ output-dir: lib/gen/
nullable-getter: false
use-deferred-loading: true
synthetic-package: false
header: "/// Display Name, localized files. Automatically generated with `task gen:intl`."
use-escaping: false
header: "/// Display Name, localized files. Automatically generated with `task gen:intl`."

View File

@ -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 {
WidgetsFlutterBinding.ensureInitialized();
// Initialize logging
final logger = AppLogger();
Bloc.observer = AppBlocObserver();
await runZonedGuarded(
() async {
WidgetsFlutterBinding.ensureInitialized();
debugPrint('${Flavor.instance}');
// Verify that we have the correct environment
Env.verify();
await GetItInitializer.init();
if (Env.isFeatureEnabled(FeatureFlag.logger)) {
logger
..level = Env.loggerLevel
..addPlugin(const SimpleLogPrinter());
} else {
logger.level = Level.OFF;
}
runApp(await builder());
debugPrint(Env.summary); // Print even if logger is disabled
Bloc.observer = AppBlocObserver();
// Intialize dependencies injection
await GetItInitializer.init();
runApp(await builder());
},
(error, stackTrace) {
logger.error(error.toString(), stackTrace);
},
);
}

View File

@ -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();
}
}
}

View File

@ -0,0 +1 @@
const int kBlocObserverMessageLength = 100;

View File

@ -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';
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}

View File

@ -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,

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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';

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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';
}

View File

@ -0,0 +1,7 @@
import 'package:logging/logging.dart';
abstract class AppLoggerPlugin {
const AppLoggerPlugin();
void handleLogRecord(LogRecord record);
}

View File

@ -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'),
};
}

View File

@ -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));
}
}

View File

@ -0,0 +1,3 @@
mixin Debuggable {
String get debugName;
}

Some files were not shown because too many files have changed in this diff Show More