From 21e304e77605b36b1dd53d2b14b16091e5ca3e21 Mon Sep 17 00:00:00 2001 From: Hugo Pointcheval Date: Wed, 3 May 2023 15:47:20 +0200 Subject: [PATCH] feat(app): upgrade app brick --- .../wyatt_app_template/__brick__/.env.example | 0 bricks/wyatt_app_template/__brick__/README.md | 77 ++++++------ .../__brick__/analysis_options.yaml | 4 +- .../__brick__/automation/build.yml | 4 +- .../__brick__/automation/generator.yml | 7 -- .../__brick__/automation/run.yml | 33 +---- .../wyatt_app_template/__brick__/config.json | 8 ++ .../__brick__/lib/bootstrap.dart | 5 +- .../lib/core/constants/emulator.dart | 12 +- .../lib/core/dependency_injection/get_it.dart | 40 +++--- .../__brick__/lib/core/enums/build_mode.dart | 31 +++++ .../__brick__/lib/core/enums/dev_mode.dart | 9 +- .../lib/core/enums/page_protection.dart | 26 ++++ .../core/extensions/go_route_extension.dart | 53 ++++++++ .../__brick__/lib/core/flavors/flavor.dart | 62 +++++---- .../core/routes/go_router_refresh_stream.dart | 40 ++++++ .../__brick__/lib/core/routes/router.dart | 65 +++++----- .../lib/core/utils/firebase_emulator.dart | 61 +++++++++ .../data/models/integer_model.freezed.dart | 5 - .../__brick__/lib/gen/assets.gen.dart | 13 +- .../__brick__/lib/gen/colors.gen.dart | 2 +- .../__brick__/lib/main_development.dart | 2 +- .../__brick__/lib/main_production.dart | 2 +- .../__brick__/lib/main_staging.dart | 2 +- .../lib/presentation/features/app/app.dart | 74 +++++------ .../shared/widgets/flavor_banner.dart | 73 +++++++++++ .../wyatt_app_template/__brick__/package.json | 5 - .../wyatt_app_template/__brick__/pubspec.yaml | 118 ++++++++---------- .../wyatt_app_template/__brick__/trapeze.yaml | 36 ------ 29 files changed, 546 insertions(+), 323 deletions(-) delete mode 100644 bricks/wyatt_app_template/__brick__/.env.example create mode 100644 bricks/wyatt_app_template/__brick__/config.json create mode 100644 bricks/wyatt_app_template/__brick__/lib/core/enums/build_mode.dart create mode 100644 bricks/wyatt_app_template/__brick__/lib/core/enums/page_protection.dart create mode 100644 bricks/wyatt_app_template/__brick__/lib/core/extensions/go_route_extension.dart create mode 100644 bricks/wyatt_app_template/__brick__/lib/core/routes/go_router_refresh_stream.dart create mode 100644 bricks/wyatt_app_template/__brick__/lib/core/utils/firebase_emulator.dart create mode 100644 bricks/wyatt_app_template/__brick__/lib/presentation/shared/widgets/flavor_banner.dart delete mode 100644 bricks/wyatt_app_template/__brick__/package.json delete mode 100644 bricks/wyatt_app_template/__brick__/trapeze.yaml diff --git a/bricks/wyatt_app_template/__brick__/.env.example b/bricks/wyatt_app_template/__brick__/.env.example deleted file mode 100644 index e69de29..0000000 diff --git a/bricks/wyatt_app_template/__brick__/README.md b/bricks/wyatt_app_template/__brick__/README.md index 7bdb1d6..e6f9a20 100644 --- a/bricks/wyatt_app_template/__brick__/README.md +++ b/bricks/wyatt_app_template/__brick__/README.md @@ -6,54 +6,55 @@ * Flutter * Taskfile -* Trapeze (with `npm install` thanks to `package.json`) ### Configuration -Create `.env` file with +At the build time, the app will read the environment variables from `config.json` file. -```sh -cp .env.example .env +The important variable is `DEV_MODE` which can be `mock` , `local` or `real` . + +```json +{ + "DEV_MODE": "local" +} ``` +> **Note** `local` can refer to a local server or a local emulator. + ### Taskfile Available tasks: -| Command | Description | Aliases | -|----|-----|-----| -| `clean` | Cleans the environment.| `cl` | -| `format` |Formats the code.| `fmt` | -| `help` |Help dialog.| `h, default` | -| `lint` |Lints the code.| `l` | -| `start-emulators` | Start needed emulators.| `emu` | -| `build:android` | Building Android APK| `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` | -| `gen:trapeze` | Running Trapeze config| `gen:t` | -| `gen:watch` | Running build runner in watch mode| `gen:w` | -| `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:emu` | Run app in development with emulated environment| `run:e` | -| `run:logs` |Show log output for running Flutter apps| `run:l` | -| `run:mock` |Run app in development environment with mocks| `run:m` | -| `run:prod` |Run app in production environment| `run:p` | -| `run:release` | Run app in production environment and in release mode| `run:r` | -| `run:staging` | Run app in staging environment| `run:s` | +| 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 | -### Flavors +### Parameters -| Flavor | Details | -|-------|--------| -| Development | Use `--dart-define="dev_mode="` to choose between `mock` , `emulator` and `real` | -| Staging | With a green banner. Only `real` mode available (remote data sources) | -| Production | Only `real` mode available (remote data sources) | +You can pass flutter options to the build and run commands. -> In `lib/core/flavors/flavor.dart` you can customize flavors. +```sh +task run:staging -- -d chrome +``` + +> **Note** The `--` is required to pass options to the command. diff --git a/bricks/wyatt_app_template/__brick__/analysis_options.yaml b/bricks/wyatt_app_template/__brick__/analysis_options.yaml index 6b75b4c..96780ca 100644 --- a/bricks/wyatt_app_template/__brick__/analysis_options.yaml +++ b/bricks/wyatt_app_template/__brick__/analysis_options.yaml @@ -11,8 +11,8 @@ dart_code_metrics: metrics: cyclomatic-complexity: 20 maximum-nesting-level: 5 - number-of-parameters: 4 - source-lines-of-code: 50 + number-of-parameters: 5 + source-lines-of-code: 250 metrics-exclude: - test/** rules: diff --git a/bricks/wyatt_app_template/__brick__/automation/build.yml b/bricks/wyatt_app_template/__brick__/automation/build.yml index 7dbc051..21e22ca 100644 --- a/bricks/wyatt_app_template/__brick__/automation/build.yml +++ b/bricks/wyatt_app_template/__brick__/automation/build.yml @@ -27,7 +27,7 @@ tasks: aliases: [a] cmds: - echo -e "{{.GREEN}}{{.PREFIX}} Building Android APK...{{.COLOROFF}}" - - flutter build lib/main_production apk --no-pub --no-shrink + - flutter build apk --target=lib/main_production --no-pub --no-shrink ios: desc: Building iOS IPA @@ -35,4 +35,4 @@ tasks: aliases: [i] cmds: - echo -e "{{.GREEN}}{{.PREFIX}} Building iOS IPA...{{.COLOROFF}}" - - flutter build lib/main_production ipa --no-pub \ No newline at end of file + - flutter build ipa --target=lib/main_production --no-pub diff --git a/bricks/wyatt_app_template/__brick__/automation/generator.yml b/bricks/wyatt_app_template/__brick__/automation/generator.yml index 33cd1ea..6c86a1a 100644 --- a/bricks/wyatt_app_template/__brick__/automation/generator.yml +++ b/bricks/wyatt_app_template/__brick__/automation/generator.yml @@ -54,10 +54,3 @@ tasks: cmds: - echo -e "{{.GREEN}}{{.PREFIX}} Running build runner in watch mode...{{.COLOROFF}}" - flutter pub run build_runner watch - - trapeze: - desc: Running Trapeze config - aliases: [t] - cmds: - - echo -e "{{.GREEN}}{{.PREFIX}} Running Trapeze config...{{.COLOROFF}}" - - npx trapeze run trapeze.yaml --android-project android --ios-project ios diff --git a/bricks/wyatt_app_template/__brick__/automation/run.yml b/bricks/wyatt_app_template/__brick__/automation/run.yml index 3b1eb77..0ddc9c4 100644 --- a/bricks/wyatt_app_template/__brick__/automation/run.yml +++ b/bricks/wyatt_app_template/__brick__/automation/run.yml @@ -16,44 +16,23 @@ tasks: - echo -e "{{.GREEN}}{{.PREFIX}} Showing log output for running Flutter apps...{{.COLOROFF}}" - flutter logs - mock: - desc: Run app in development environment with mocks - aliases: [m] - cmds: - - echo -e "{{.GREEN}}{{.PREFIX}} Running the app (development/debug:mocks)...{{.COLOROFF}}" - - flutter run --target lib/main_development.dart --dart-define="dev_mode=mock" - - emu: - desc: Run app in development with emulated environment - aliases: [e] - cmds: - - echo -e "{{.GREEN}}{{.PREFIX}} Running the app (development/debug:emulator)...{{.COLOROFF}}" - - flutter run --target lib/main_development.dart --dart-define="dev_mode=emulator" - dev: desc: Run app in development environment aliases: [d] cmds: - - echo -e "{{.GREEN}}{{.PREFIX}} Running the app (development/debug:real)...{{.COLOROFF}}" - - flutter run --target lib/main_development.dart --dart-define="dev_mode=real" + - echo -e "{{.GREEN}}{{.PREFIX}} Running the app (development)...{{.COLOROFF}}" + - flutter run --target lib/main_development.dart --dart-define-from-file=config.json {{.CLI_ARGS}} staging: desc: Run app in staging environment aliases: [s] cmds: - - echo -e "{{.GREEN}}{{.PREFIX}} Running the app (staging/debug)...{{.COLOROFF}}" - - flutter run --target lib/main_staging.dart + - echo -e "{{.GREEN}}{{.PREFIX}} Running the app (staging)...{{.COLOROFF}}" + - flutter run --target lib/main_staging.dart --dart-define-from-file=config.json {{.CLI_ARGS}} prod: desc: Run app in production environment aliases: [p] cmds: - - echo -e "{{.GREEN}}{{.PREFIX}} Running the app (production/debug)...{{.COLOROFF}}" - - flutter run --target lib/main_production.dart - - release: - desc: Run app in production environment and in release mode - aliases: [r] - cmds: - - echo -e "{{.GREEN}}{{.PREFIX}} Running the app (production/release)...{{.COLOROFF}}" - - flutter run --target lib/main_production.dart --release + - echo -e "{{.GREEN}}{{.PREFIX}} Running the app (production)...{{.COLOROFF}}" + - flutter run --target lib/main_production.dart --dart-define-from-file=config.json {{.CLI_ARGS}} diff --git a/bricks/wyatt_app_template/__brick__/config.json b/bricks/wyatt_app_template/__brick__/config.json new file mode 100644 index 0000000..356801b --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/config.json @@ -0,0 +1,8 @@ +{ + "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" +} diff --git a/bricks/wyatt_app_template/__brick__/lib/bootstrap.dart b/bricks/wyatt_app_template/__brick__/lib/bootstrap.dart index 7f454b7..38f7462 100644 --- a/bricks/wyatt_app_template/__brick__/lib/bootstrap.dart +++ b/bricks/wyatt_app_template/__brick__/lib/bootstrap.dart @@ -7,12 +7,11 @@ import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/flavors/flavor import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/utils/app_bloc_observer.dart'; Future bootstrap(FutureOr Function() builder) async { - final widgetsBinding = WidgetsFlutterBinding.ensureInitialized(); - // FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding); + WidgetsFlutterBinding.ensureInitialized(); Bloc.observer = AppBlocObserver(); - debugPrint('Flavor: ${Flavor.get()}'); + debugPrint('${Flavor.instance}'); await GetItInitializer.init(); diff --git a/bricks/wyatt_app_template/__brick__/lib/core/constants/emulator.dart b/bricks/wyatt_app_template/__brick__/lib/core/constants/emulator.dart index 00258ff..0097c95 100644 --- a/bricks/wyatt_app_template/__brick__/lib/core/constants/emulator.dart +++ b/bricks/wyatt_app_template/__brick__/lib/core/constants/emulator.dart @@ -1,14 +1,14 @@ /// Firebase Emulator constants. -/// +/// /// If you don't use Firebase, it can be safely deleted. abstract class Emulator { static const String firebaseCloudFunctionEnvKey = - 'EMULATOR_FIREBASE_CLOUD_FUNCTION_PORT'; + 'FIREBASE_EMULATOR_CLOUD_FUNCTION_PORT'; static const String firebaseFirestoreEnvKey = - 'EMULATOR_FIREBASE_FIRESTORE_PORT'; - static const String firebaseAuthEnvKey = 'EMULATOR_FIREBASE_AUTH_PORT'; - static const String firebaseStorageEnvKey = 'EMULATOR_FIREBASE_STORAGE_PORT'; - static const String hostEnvKey = 'EMULATOR_HOST'; + '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; diff --git a/bricks/wyatt_app_template/__brick__/lib/core/dependency_injection/get_it.dart b/bricks/wyatt_app_template/__brick__/lib/core/dependency_injection/get_it.dart index 3ed791e..5c1103c 100644 --- a/bricks/wyatt_app_template/__brick__/lib/core/dependency_injection/get_it.dart +++ b/bricks/wyatt_app_template/__brick__/lib/core/dependency_injection/get_it.dart @@ -1,38 +1,50 @@ import 'dart:async'; +import 'package:flutter/foundation.dart'; import 'package:get_it/get_it.dart'; import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/enums/dev_mode.dart'; import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/flavors/flavor.dart'; -import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/data/data_sources/local/counter_data_source_impl.dart'; -import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/data_sources/local/counter_data_source.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/utils/firebase_emulator.dart'; final getIt = GetIt.I; /// Service and Data Source locator abstract class GetItInitializer { static FutureOr _initCommon() async { - // Initialize common sources/services - getIt.registerLazySingleton( - CounterDataSourceImpl.new, - ); + // TODO(wyatt): Initialize common sources/services } - static FutureOr _initMocks() async { - // Initialize mocked sources/services. + static FutureOr _initMock() async { + // TODO(wyatt): Initialize mocked sources/services. + } + + static FutureOr _initLocal() async { + // TODO(wyatt): Initialize local sources/services. + final emulator = FirebaseEmulator.fromEnv(); + debugPrint('Firebase Emulator: $emulator'); } static FutureOr _initReal() async { - // Initialize real sources/services + // TODO(wyatt): Initialize real sources/services } static FutureOr init() async { + // Initialize common sources/services await _initCommon(); - final flavor = Flavor.get(); - if (flavor.devMode == DevMode.mock) { - await _initMocks(); - } else { - await _initReal(); + // Initialize sources/services based on flavor + switch (Flavor.instance.devMode) { + case DevMode.mock: + await _initMock(); + break; + case DevMode.local: + await _initLocal(); + break; + case DevMode.real: + await _initReal(); + break; + case null: + throw Exception('DevMode not initialized!'); } await getIt.allReady(); diff --git a/bricks/wyatt_app_template/__brick__/lib/core/enums/build_mode.dart b/bricks/wyatt_app_template/__brick__/lib/core/enums/build_mode.dart new file mode 100644 index 0000000..0aa4421 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/core/enums/build_mode.dart @@ -0,0 +1,31 @@ +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; + } +} diff --git a/bricks/wyatt_app_template/__brick__/lib/core/enums/dev_mode.dart b/bricks/wyatt_app_template/__brick__/lib/core/enums/dev_mode.dart index bd4ad84..3a628f9 100644 --- a/bricks/wyatt_app_template/__brick__/lib/core/enums/dev_mode.dart +++ b/bricks/wyatt_app_template/__brick__/lib/core/enums/dev_mode.dart @@ -1,12 +1,17 @@ enum DevMode { + /// Mocked data sources and services mock, - emulator, + + /// 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 + /// 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) { diff --git a/bricks/wyatt_app_template/__brick__/lib/core/enums/page_protection.dart b/bricks/wyatt_app_template/__brick__/lib/core/enums/page_protection.dart new file mode 100644 index 0000000..63a846d --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/core/enums/page_protection.dart @@ -0,0 +1,26 @@ +// 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 . + +enum PageProtection { + /// The page can be accessed without authentication. + public, + + /// The page can only be accessed with authentication. + protected, + + /// The page protection is unknown, and the default one should be used. + none, +} diff --git a/bricks/wyatt_app_template/__brick__/lib/core/extensions/go_route_extension.dart b/bricks/wyatt_app_template/__brick__/lib/core/extensions/go_route_extension.dart new file mode 100644 index 0000000..98361cc --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/core/extensions/go_route_extension.dart @@ -0,0 +1,53 @@ +// 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 . + +import 'package:go_router/go_router.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/enums/page_protection.dart'; + +/// Defines if a GoRoute is public or not. +/// +/// By default, all routes are in the [PageProtection.none] state. +extension GoRouteGuard on GoRoute { + static final _guard = Expando(); + + /// Returns `true` if the route is public. + bool get isPublic => _guard[this] == PageProtection.public; + + /// Returns `true` if the route is protected. + bool get isProtected => _guard[this] == PageProtection.protected; + + /// Returns `true` if the route is neither public nor protected. + /// This is the default state. + bool get isNone => _guard[this] == PageProtection.none; + + /// Sets the route to be public. + /// This is useful for routes that should be accessible + /// without authentication. + /// ```dart + /// GoRoute( + /// path: '/sign_in', + /// ... + /// )..setPublic(), + /// ``` + void setPublic() => _guard[this] = PageProtection.public; + + /// Sets the route to be protected. + /// This is useful for routes that should only be accessible + /// with authentication. + void setProtected() => _guard[this] = PageProtection.protected; + + PageProtection get guard => _guard[this] ?? PageProtection.none; +} diff --git a/bricks/wyatt_app_template/__brick__/lib/core/flavors/flavor.dart b/bricks/wyatt_app_template/__brick__/lib/core/flavors/flavor.dart index 60f1f8c..dcb29a3 100644 --- a/bricks/wyatt_app_template/__brick__/lib/core/flavors/flavor.dart +++ b/bricks/wyatt_app_template/__brick__/lib/core/flavors/flavor.dart @@ -1,23 +1,38 @@ +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/enums/build_mode.dart'; import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/enums/dev_mode.dart'; -abstract class Flavor { +class Flavor { Flavor._({ - this.banner, - this.bannerColor = Colors.red, - this.devMode, + 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? banner; - final Color bannerColor; - final DevMode? devMode; + final String? flavorName; + final Color? bannerColor; + + late final DevMode? devMode; + late final BuildMode? buildMode; /// Returns [Flavor] instance. - static Flavor get() { + static Flavor get instance { if (_instance == null) { throw Exception('Flavor not initialized!'); } @@ -25,33 +40,26 @@ abstract class Flavor { return _instance!; } + String get name => flavorName ?? 'Unknown'; + Color get color => bannerColor ?? Colors.grey; + + static bool shouldShowBanner() => instance.buildMode != BuildMode.release; + @override - String toString() => runtimeType.toString().replaceAll('Flavor', ''); + String toString() => + 'Flavor: $flavorName, DevMode: $devMode, BuildMode: $buildMode'; } class DevelopmentFlavor extends Flavor { - factory DevelopmentFlavor() { - const modeString = String.fromEnvironment('dev_mode', defaultValue: 'mock'); - final mode = DevMode.fromString(modeString); - - return DevelopmentFlavor._(devMode: mode); - } - DevelopmentFlavor._({ - required DevMode devMode, - }) : super._( - banner: 'Dev', - devMode: devMode, - ); + DevelopmentFlavor() + : super._(flavorName: 'Development', bannerColor: Colors.red); } class StagingFlavor extends Flavor { - StagingFlavor() - : super._( - banner: 'Staging', - bannerColor: Colors.green, - ); + StagingFlavor() : super._(flavorName: 'Staging', bannerColor: Colors.orange); } class ProductionFlavor extends Flavor { - ProductionFlavor() : super._(); + ProductionFlavor() + : super._(flavorName: 'Production', bannerColor: Colors.green); } diff --git a/bricks/wyatt_app_template/__brick__/lib/core/routes/go_router_refresh_stream.dart b/bricks/wyatt_app_template/__brick__/lib/core/routes/go_router_refresh_stream.dart new file mode 100644 index 0000000..b37ca83 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/core/routes/go_router_refresh_stream.dart @@ -0,0 +1,40 @@ +// 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 . + +import 'dart:async'; + +import 'package:flutter/foundation.dart'; + +/// {@template go_router_refresh_stream} +/// A [ChangeNotifier] that notifies its listeners when a stream emits a value. +/// {@endtemplate} +class GoRouterRefreshStream extends ChangeNotifier { + /// {@macro go_router_refresh_stream} + GoRouterRefreshStream(Stream stream) { + notifyListeners(); + _subscription = stream.asBroadcastStream().listen( + (dynamic _) => notifyListeners(), + ); + } + + late final StreamSubscription _subscription; + + @override + void dispose() { + _subscription.cancel(); + super.dispose(); + } +} diff --git a/bricks/wyatt_app_template/__brick__/lib/core/routes/router.dart b/bricks/wyatt_app_template/__brick__/lib/core/routes/router.dart index 49679ce..014a959 100644 --- a/bricks/wyatt_app_template/__brick__/lib/core/routes/router.dart +++ b/bricks/wyatt_app_template/__brick__/lib/core/routes/router.dart @@ -1,6 +1,8 @@ import 'package:flutter/cupertino.dart'; import 'package:go_router/go_router.dart'; -import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/presentation/features/counter/counter.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/enums/page_protection.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/extensions/go_route_extension.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/routes/go_router_refresh_stream.dart'; import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/presentation/features/home/home.dart'; abstract class AppRouter { @@ -10,10 +12,7 @@ abstract class AppRouter { GoRouterState state, Widget child, ) => - CupertinoPage( - key: state.pageKey, - child: child, - ); + CupertinoPage(key: state.pageKey, child: child); /// Disable transition animation static Page noTransition( @@ -21,23 +20,7 @@ abstract class AppRouter { GoRouterState state, Widget child, ) => - CustomTransitionPage( - key: state.pageKey, - transitionsBuilder: (_, __, ___, child) => child, - child: child, - ); - - /// Defines public routes (no authentication needed). - /// - /// Example: - /// ```dart - /// static final publicRoutes = [ - /// '/', - /// '/sign_in', - /// '/sign_up', - /// ]; - /// ``` - static final List publicRoutes = []; + NoTransitionPage(key: state.pageKey, child: child); /// Defines GoRoute routes. static final List routes = [ @@ -46,20 +29,32 @@ abstract class AppRouter { name: Home.pageName, pageBuilder: (context, state) => defaultTransition(context, state, const Home()), - ), - GoRoute( - path: '/counter', - name: Counter.pageName, - pageBuilder: (context, state) => - defaultTransition(context, state, const Counter()), - ), + )..setPublic(), ]; /// Router - static GoRouter router = GoRouter( - initialLocation: '/', - routes: AppRouter.routes, - debugLogDiagnostics: true, - redirect: (context, state) => null, - ); + static GoRouter routerOf(BuildContext context) => GoRouter( + initialLocation: '/', + routes: AppRouter.routes, + debugLogDiagnostics: true, + // TODO(wyatt): Add authentication logic + redirect: (context, state) { + /// Define the default guard + /// This is the guard that will be used if the route + /// does not have a guard set. (It is set to [PageProtection.none]) + const defaultGuard = PageProtection.protected; + + // Compute current route + // Compute current route + final currentRoute = AppRouter.routes.firstWhere( + (route) => route.path == state.location, + ); + + // Get the guard of the current route + final guard = currentRoute.guard; + + return null; + }, + refreshListenable: GoRouterRefreshStream(const Stream.empty()), + ); } diff --git a/bricks/wyatt_app_template/__brick__/lib/core/utils/firebase_emulator.dart b/bricks/wyatt_app_template/__brick__/lib/core/utils/firebase_emulator.dart new file mode 100644 index 0000000..157880d --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/core/utils/firebase_emulator.dart @@ -0,0 +1,61 @@ +// 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 . + +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/constants/emulator.dart'; + +class FirebaseEmulator { + const FirebaseEmulator._({ + required this.cloudFunctionPort, + required this.firestorePort, + required this.authPort, + required this.storagePort, + required this.host, + }); + + factory FirebaseEmulator.fromEnv() => const FirebaseEmulator._( + cloudFunctionPort: int.fromEnvironment( + Emulator.firebaseCloudFunctionEnvKey, + defaultValue: Emulator.defaultFirebaseCloudFunctionPort, + ), + firestorePort: int.fromEnvironment( + Emulator.firebaseFirestoreEnvKey, + defaultValue: Emulator.defaultFirebaseFirestorePort, + ), + authPort: int.fromEnvironment( + Emulator.firebaseAuthEnvKey, + defaultValue: Emulator.defaultFirebaseAuthPort, + ), + storagePort: int.fromEnvironment( + Emulator.firebaseStorageEnvKey, + defaultValue: Emulator.defaultFirebaseStoragePort, + ), + host: String.fromEnvironment( + Emulator.hostEnvKey, + defaultValue: Emulator.defaultHost, + ), + ); + + final int cloudFunctionPort; + final int firestorePort; + final int authPort; + final int storagePort; + final String host; + + @override + String toString() => 'FirebaseEmulator(cloudFunctionPort: ' + '$cloudFunctionPort, firestorePort: $firestorePort, authPort: $authPort, ' + 'storagePort: $storagePort, host: $host)'; +} diff --git a/bricks/wyatt_app_template/__brick__/lib/data/models/integer_model.freezed.dart b/bricks/wyatt_app_template/__brick__/lib/data/models/integer_model.freezed.dart index bed9972..2fbb008 100644 --- a/bricks/wyatt_app_template/__brick__/lib/data/models/integer_model.freezed.dart +++ b/bricks/wyatt_app_template/__brick__/lib/data/models/integer_model.freezed.dart @@ -105,11 +105,6 @@ class _$_IntegerModel implements _IntegerModel { @override final int value; - @override - String toString() { - return 'IntegerModel(value: $value)'; - } - @override bool operator ==(dynamic other) { return identical(this, other) || diff --git a/bricks/wyatt_app_template/__brick__/lib/gen/assets.gen.dart b/bricks/wyatt_app_template/__brick__/lib/gen/assets.gen.dart index 3deea52..2bc44eb 100644 --- a/bricks/wyatt_app_template/__brick__/lib/gen/assets.gen.dart +++ b/bricks/wyatt_app_template/__brick__/lib/gen/assets.gen.dart @@ -5,7 +5,7 @@ // coverage:ignore-file // ignore_for_file: type=lint -// ignore_for_file: directives_ordering,unnecessary_import,implicit_dynamic_list_literal +// ignore_for_file: directives_ordering,unnecessary_import,implicit_dynamic_list_literal,deprecated_member_use import 'package:flutter/widgets.dart'; @@ -84,7 +84,16 @@ class AssetGenImage { ); } - ImageProvider provider() => AssetImage(_assetName); + ImageProvider provider({ + AssetBundle? bundle, + String? package, + }) { + return AssetImage( + _assetName, + bundle: bundle, + package: package, + ); + } String get path => _assetName; diff --git a/bricks/wyatt_app_template/__brick__/lib/gen/colors.gen.dart b/bricks/wyatt_app_template/__brick__/lib/gen/colors.gen.dart index 7140be2..9fb3e59 100644 --- a/bricks/wyatt_app_template/__brick__/lib/gen/colors.gen.dart +++ b/bricks/wyatt_app_template/__brick__/lib/gen/colors.gen.dart @@ -5,7 +5,7 @@ // coverage:ignore-file // ignore_for_file: type=lint -// ignore_for_file: directives_ordering,unnecessary_import,implicit_dynamic_list_literal +// ignore_for_file: directives_ordering,unnecessary_import,implicit_dynamic_list_literal,deprecated_member_use import 'package:flutter/painting.dart'; import 'package:flutter/material.dart'; diff --git a/bricks/wyatt_app_template/__brick__/lib/main_development.dart b/bricks/wyatt_app_template/__brick__/lib/main_development.dart index d327e4d..602ad95 100644 --- a/bricks/wyatt_app_template/__brick__/lib/main_development.dart +++ b/bricks/wyatt_app_template/__brick__/lib/main_development.dart @@ -3,7 +3,7 @@ import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/flavors/flavor import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/presentation/features/app/app.dart'; void main(List args) { - // Define environment + // Define flavor DevelopmentFlavor(); // Initialize environment and variables diff --git a/bricks/wyatt_app_template/__brick__/lib/main_production.dart b/bricks/wyatt_app_template/__brick__/lib/main_production.dart index f5f0bb4..4d355ab 100644 --- a/bricks/wyatt_app_template/__brick__/lib/main_production.dart +++ b/bricks/wyatt_app_template/__brick__/lib/main_production.dart @@ -3,7 +3,7 @@ import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/flavors/flavor import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/presentation/features/app/app.dart'; void main(List args) { - // Define environment + // Define flavor ProductionFlavor(); // Initialize environment and variables diff --git a/bricks/wyatt_app_template/__brick__/lib/main_staging.dart b/bricks/wyatt_app_template/__brick__/lib/main_staging.dart index d2d8017..9e8a7d4 100644 --- a/bricks/wyatt_app_template/__brick__/lib/main_staging.dart +++ b/bricks/wyatt_app_template/__brick__/lib/main_staging.dart @@ -3,7 +3,7 @@ import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/flavors/flavor import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/presentation/features/app/app.dart'; void main(List args) { - // Define environment + // Define flavor StagingFlavor(); // Initialize environment and variables diff --git a/bricks/wyatt_app_template/__brick__/lib/presentation/features/app/app.dart b/bricks/wyatt_app_template/__brick__/lib/presentation/features/app/app.dart index 510bf9c..917a6d5 100644 --- a/bricks/wyatt_app_template/__brick__/lib/presentation/features/app/app.dart +++ b/bricks/wyatt_app_template/__brick__/lib/presentation/features/app/app.dart @@ -1,63 +1,47 @@ -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/dependency_injection/get_it.dart'; -import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/flavors/flavor.dart'; import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/routes/router.dart'; import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/data/repositories/counter_repository_impl.dart'; import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/repositories/counter_repository.dart'; import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/gen/app_localizations.dart'; import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/presentation/features/counter/blocs/counter_bloc/counter_bloc.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/presentation/shared/widgets/flavor_banner.dart'; import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart'; class App extends StatelessWidget { const App({super.key}); - Widget _flavorBanner(Widget child) { - final flavor = Flavor.get(); - if (flavor.banner != null && !kReleaseMode) { - return Directionality( - textDirection: TextDirection.ltr, - child: Banner( - location: BannerLocation.topEnd, - message: flavor.banner!, - color: flavor.bannerColor, - child: child, - ), - ); - } - - return child; - } - @override Widget build(BuildContext context) => MultiProvider( - repositoryProviders: [ - RepositoryProvider( - create: (_) => CounterRepositoryImpl(counterDataSource: getIt()), + repositoryProviders: [ + RepositoryProvider( + create: (_) => CounterRepositoryImpl(counterDataSource: getIt()), + ), + ], + blocProviders: [ + BlocProvider( + create: (_) => CounterBloc(), + ), + ], + child: FlavorBanner( + child: MaterialApp.router( + title: '{{#titleCase}}{{display_name}}{{/titleCase}}', + debugShowCheckedModeBanner: false, + routerDelegate: AppRouter.routerOf(context).routerDelegate, + routeInformationParser: + AppRouter.routerOf(context).routeInformationParser, + routeInformationProvider: + AppRouter.routerOf(context).routeInformationProvider, + localizationsDelegates: const [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: AppLocalizations.supportedLocales, + ), ), - ], - blocProviders: [ - BlocProvider( - create: (_) => CounterBloc(), - ), - ], - child: _flavorBanner( - MaterialApp.router( - title: '{{#titleCase}}{{display_name}}{{/titleCase}}', - debugShowCheckedModeBanner: false, - routerDelegate: AppRouter.router.routerDelegate, - routeInformationParser: AppRouter.router.routeInformationParser, - routeInformationProvider: AppRouter.router.routeInformationProvider, - localizationsDelegates: const [ - AppLocalizations.delegate, - GlobalMaterialLocalizations.delegate, - GlobalWidgetsLocalizations.delegate, - GlobalCupertinoLocalizations.delegate, - ], - supportedLocales: AppLocalizations.supportedLocales, - ), - ), - ); + ); } diff --git a/bricks/wyatt_app_template/__brick__/lib/presentation/shared/widgets/flavor_banner.dart b/bricks/wyatt_app_template/__brick__/lib/presentation/shared/widgets/flavor_banner.dart new file mode 100644 index 0000000..e3b85c6 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/presentation/shared/widgets/flavor_banner.dart @@ -0,0 +1,73 @@ +// 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 . + +import 'package:flutter/material.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/flavors/flavor.dart'; + +/// {@template flavor_banner} +/// A banner that displays the current flavor. +/// This is useful for quickly identifying which flavor is currently running. +/// +/// When [Flavor.shouldShowBanner] is `false`, this widget will return [child]. +/// You can also override this behavior by setting [visible] to `true`. +/// +/// Wrap your [MaterialApp] with this widget to display the banner. +/// +/// Example: +/// +/// ```dart +/// FlavorBanner( +/// visible: true, // or null to use Flavor.shouldShowBanner() +/// child: const MaterialApp( +/// title: 'Starting Template', +/// ... +/// ), +/// ); +/// ``` +/// {@endtemplate} +class FlavorBanner extends StatelessWidget { + const FlavorBanner({ + this.child, + this.visible, + super.key, + }); + + final Widget? child; + + /// Defaults to [Flavor.shouldShowBanner]. + final bool? visible; + + @override + Widget build(BuildContext context) { + final visible = this.visible ?? Flavor.shouldShowBanner(); + + if (!visible) { + return child ?? const SizedBox.shrink(); + } + + final flavor = Flavor.instance; + + return Directionality( + textDirection: TextDirection.ltr, + child: Banner( + location: BannerLocation.topEnd, + message: flavor.name, + color: flavor.color, + child: child, + ), + ); + } +} diff --git a/bricks/wyatt_app_template/__brick__/package.json b/bricks/wyatt_app_template/__brick__/package.json deleted file mode 100644 index 3c8f622..0000000 --- a/bricks/wyatt_app_template/__brick__/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "@trapezedev/configure": "^7.0.5" - } -} diff --git a/bricks/wyatt_app_template/__brick__/pubspec.yaml b/bricks/wyatt_app_template/__brick__/pubspec.yaml index b96a2a5..55cdb5c 100644 --- a/bricks/wyatt_app_template/__brick__/pubspec.yaml +++ b/bricks/wyatt_app_template/__brick__/pubspec.yaml @@ -1,90 +1,82 @@ name: {{#snakeCase}}{{project_name}}{{/snakeCase}} -description: {{#sentenceCase}}{{description}}{{/sentenceCase}} - -publish_to: "none" - version: 1.0.0+1 - -environment: - sdk: ">=2.18.0 <3.0.0" - flutter: ">=3.0.0" - -dependencies: - flutter: { sdk: flutter } - flutter_localizations: { sdk: flutter } - intl: ^0.17.0 - go_router: ^6.0.1 - equatable: ^2.0.5 - freezed_annotation: ^2.2.0 - json_annotation: ^4.8.0 +publish_to: none +description: {{#sentenceCase}}{{description}}{{/sentenceCase}} +environment: + sdk: '>=2.18.0 <3.0.0' + flutter: '>=3.0.0' +dependencies: cupertino_icons: ^1.0.5 - get_it: ^7.2.0 - flutter_dotenv: ^5.0.2 - gap: ^2.0.1 + equatable: ^2.0.5 flutter_bloc: ^8.1.1 + flutter_native_splash: ^2.2.15 + freezed_annotation: ^2.2.0 + gap: ^2.0.1 + get_it: ^7.2.0 + go_router: ^6.0.1 + intl: ^0.17.0 + json_annotation: ^4.8.0 url_launcher: ^6.1.7 uuid: ^3.0.7 - flutter_native_splash: ^2.2.15 - wyatt_architecture: - hosted: - url: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + flutter: + sdk: flutter + flutter_localizations: + sdk: flutter + wyatt_architecture: + version: ^0.2.0 + hosted: name: wyatt_architecture - version: 0.1.0+1 - wyatt_bloc_helper: - hosted: url: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + wyatt_bloc_helper: + version: ^2.0.1 + hosted: name: wyatt_bloc_helper - version: 2.0.0 - wyatt_type_utils: - hosted: url: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + wyatt_type_utils: + version: ^0.0.5 + hosted: name: wyatt_type_utils - version: 0.0.4 - -dev_dependencies: - flutter_test: { sdk: flutter } - dependency_validator: ^3.2.2 + url: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ +dev_dependencies: build_runner: ^2.3.3 + dart_code_metrics: ^5.4.0 + dependency_validator: ^3.2.2 flutter_gen_runner: ^5.1.0+1 + flutter_launcher_icons: ^0.11.0 freezed: ^2.3.2 json_serializable: ^6.6.0 - flutter_launcher_icons: ^0.11.0 - dart_code_metrics: ^5.4.0 + pubspec_dependency_sorter: ^1.0.3 rename: ^2.1.1 - wyatt_analysis: - hosted: - url: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + flutter_test: + sdk: flutter + wyatt_analysis: + version: ^2.5.0 + hosted: name: wyatt_analysis - version: 2.4.1 - -flutter: - uses-material-design: true - generate: true - assets: - - .env + url: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ +flutter: + assets: - assets/images/ - -flutter_gen: + uses-material-design: true +flutter_gen: output: lib/gen/ - integrations: + integrations: flutter_svg: true flare_flutter: true rive: true lottie: true - colors: - inputs: + colors: + inputs: - assets/colors.xml - -flutter_icons: - android: "launcher_icon" - ios: true - image_path: "assets/images/wyatt_logo.jpeg" - adaptive_icon_background: "#FFFFFF" - -flutter_native_splash: - image: "assets/images/wyatt_logo.jpeg" - color: "#FFFFFF" - android: true +flutter_icons: + android: launcher_icon + image_path: assets/images/wyatt_logo.jpeg + adaptive_icon_background: '#FFFFFF' ios: true +flutter_native_splash: + image: assets/images/wyatt_logo.jpeg + color: '#FFFFFF' android_gravity: fill ios_content_mode: scaleAspectFit + android: true + ios: true diff --git a/bricks/wyatt_app_template/__brick__/trapeze.yaml b/bricks/wyatt_app_template/__brick__/trapeze.yaml deleted file mode 100644 index 2177b57..0000000 --- a/bricks/wyatt_app_template/__brick__/trapeze.yaml +++ /dev/null @@ -1,36 +0,0 @@ -vars: - PACKAGE_NAME: - default: {{#snakeCase}}{{project_name}}{{/snakeCase}} - BUNDLE_ID: - default: {{#dotCase}}{{bundle_id}}{{/dotCase}} - APP_NAME: - default: {{#titleCase}}{{display_name}}{{/titleCase}} - -platforms: - android: - appName: $APP_NAME - packageName: $BUNDLE_ID - # Uncomment to add some permissions - # manifest: - # - file: AndroidManifest.xml - # target: manifest/application - # inject: - # - ios: - targets: - Runner: - bundleId: $BUNDLE_ID - productName: $APP_NAME - displayName: $APP_NAME - entitlements: - replace: true - # Workaround for https://stackoverflow.com/questions/55167611/flutter-ios-app-submission-issue-warning-missing-push-notification-entitlement - entries: - - aps-environment: development - # Uncomment to add some permissions - # plist: - # - replace: true - # entries: - # - UISupportedInterfaceOrientations: - # - UIInterfaceOrientationPortrait -