diff --git a/assets/images/icons/add.svg b/assets/images/icons/add.svg new file mode 100644 index 00000000..02e4a95b --- /dev/null +++ b/assets/images/icons/add.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/icons/android/add.svg b/assets/images/icons/android/add.svg deleted file mode 100644 index ca2fbd67..00000000 --- a/assets/images/icons/android/add.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/images/icons/android/back.svg b/assets/images/icons/android/back.svg deleted file mode 100644 index 5bba7586..00000000 --- a/assets/images/icons/android/back.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/images/icons/android/close.svg b/assets/images/icons/android/close.svg deleted file mode 100644 index 350d4fdc..00000000 --- a/assets/images/icons/android/close.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/images/icons/android/done.svg b/assets/images/icons/android/done.svg deleted file mode 100644 index 784eb128..00000000 --- a/assets/images/icons/android/done.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/images/icons/android/download.svg b/assets/images/icons/android/download.svg deleted file mode 100644 index de915ffc..00000000 --- a/assets/images/icons/android/download.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/images/icons/android/list.svg b/assets/images/icons/android/list.svg deleted file mode 100644 index f57ea6b1..00000000 --- a/assets/images/icons/android/list.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/images/icons/android/settings.svg b/assets/images/icons/android/settings.svg deleted file mode 100644 index ef27416a..00000000 --- a/assets/images/icons/android/settings.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/images/icons/animation.svg b/assets/images/icons/animation.svg new file mode 100644 index 00000000..bb7d7027 --- /dev/null +++ b/assets/images/icons/animation.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/icons/arrow_left.svg b/assets/images/icons/arrow_left.svg new file mode 100644 index 00000000..5142d836 --- /dev/null +++ b/assets/images/icons/arrow_left.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/icons/box.svg b/assets/images/icons/box.svg new file mode 100644 index 00000000..74d0ddd6 --- /dev/null +++ b/assets/images/icons/box.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/icons/check.svg b/assets/images/icons/check.svg new file mode 100644 index 00000000..53747a5c --- /dev/null +++ b/assets/images/icons/check.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/icons/chevron_right.svg b/assets/images/icons/chevron_right.svg new file mode 100644 index 00000000..5ef325bf --- /dev/null +++ b/assets/images/icons/chevron_right.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/icons/download.svg b/assets/images/icons/download.svg new file mode 100644 index 00000000..02ba39df --- /dev/null +++ b/assets/images/icons/download.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/icons/file.svg b/assets/images/icons/file.svg new file mode 100644 index 00000000..54a8fec8 --- /dev/null +++ b/assets/images/icons/file.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/icons/ios/add.svg b/assets/images/icons/ios/add.svg deleted file mode 100644 index ca2fbd67..00000000 --- a/assets/images/icons/ios/add.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/images/icons/ios/back.svg b/assets/images/icons/ios/back.svg deleted file mode 100644 index 22c492c0..00000000 --- a/assets/images/icons/ios/back.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/images/icons/ios/close.svg b/assets/images/icons/ios/close.svg deleted file mode 100644 index 350d4fdc..00000000 --- a/assets/images/icons/ios/close.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/images/icons/ios/done.svg b/assets/images/icons/ios/done.svg deleted file mode 100644 index 784eb128..00000000 --- a/assets/images/icons/ios/done.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/images/icons/ios/download.svg b/assets/images/icons/ios/download.svg deleted file mode 100644 index de915ffc..00000000 --- a/assets/images/icons/ios/download.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/images/icons/ios/list.svg b/assets/images/icons/ios/list.svg deleted file mode 100644 index f57ea6b1..00000000 --- a/assets/images/icons/ios/list.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/images/icons/ios/settings.svg b/assets/images/icons/ios/settings.svg deleted file mode 100644 index ef27416a..00000000 --- a/assets/images/icons/ios/settings.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/images/icons/license.svg b/assets/images/icons/license.svg new file mode 100644 index 00000000..0eca634d --- /dev/null +++ b/assets/images/icons/license.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/icons/list.svg b/assets/images/icons/list.svg new file mode 100644 index 00000000..d3386b92 --- /dev/null +++ b/assets/images/icons/list.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/icons/lock_open.svg b/assets/images/icons/lock_open.svg new file mode 100644 index 00000000..fb81600c --- /dev/null +++ b/assets/images/icons/lock_open.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/icons/settings_active.svg b/assets/images/icons/settings_active.svg new file mode 100644 index 00000000..5cfc0526 --- /dev/null +++ b/assets/images/icons/settings_active.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/icons/settings_inactive.svg b/assets/images/icons/settings_inactive.svg new file mode 100644 index 00000000..3498bf54 --- /dev/null +++ b/assets/images/icons/settings_inactive.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/icons/theme.svg b/assets/images/icons/theme.svg new file mode 100644 index 00000000..d4c7b155 --- /dev/null +++ b/assets/images/icons/theme.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/icons/todo_active.svg b/assets/images/icons/todo_active.svg new file mode 100644 index 00000000..76c58b67 --- /dev/null +++ b/assets/images/icons/todo_active.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/icons/todo_inactive.svg b/assets/images/icons/todo_inactive.svg new file mode 100644 index 00000000..fc4d81f3 --- /dev/null +++ b/assets/images/icons/todo_inactive.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/icons/translations.svg b/assets/images/icons/translations.svg new file mode 100644 index 00000000..683237f7 --- /dev/null +++ b/assets/images/icons/translations.svg @@ -0,0 +1,3 @@ + + + diff --git a/ios/Podfile.lock b/ios/Podfile.lock index ba42cc57..f5eea6c6 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -17,6 +17,9 @@ PODS: - Firebase/RemoteConfig (10.25.0): - Firebase/CoreOnly - FirebaseRemoteConfig (~> 10.25.0) + - Firebase/Storage (10.25.0): + - Firebase/CoreOnly + - FirebaseStorage (~> 10.25.0) - firebase_analytics (10.10.7): - Firebase/Analytics (= 10.25.0) - firebase_core @@ -32,6 +35,10 @@ PODS: - Firebase/RemoteConfig (= 10.25.0) - firebase_core - Flutter + - firebase_storage (11.7.7): + - Firebase/Storage (= 10.25.0) + - firebase_core + - Flutter - FirebaseABTesting (10.29.0): - FirebaseCore (~> 10.0) - FirebaseAnalytics (10.25.0): @@ -52,6 +59,8 @@ PODS: - GoogleUtilities/Network (~> 7.11) - "GoogleUtilities/NSData+zlib (~> 7.11)" - nanopb (< 2.30911.0, >= 2.30908.0) + - FirebaseAppCheckInterop (10.29.0) + - FirebaseAuthInterop (10.29.0) - FirebaseCore (10.25.0): - FirebaseCoreInternal (~> 10.0) - GoogleUtilities/Environment (~> 7.12) @@ -93,7 +102,18 @@ PODS: - nanopb (< 2.30911.0, >= 2.30908.0) - PromisesSwift (~> 2.1) - FirebaseSharedSwift (10.29.0) + - FirebaseStorage (10.25.0): + - FirebaseAppCheckInterop (~> 10.0) + - FirebaseAuthInterop (~> 10.25) + - FirebaseCore (~> 10.0) + - FirebaseCoreExtension (~> 10.0) + - GoogleUtilities/Environment (~> 7.12) + - GTMSessionFetcher/Core (< 4.0, >= 2.1) - Flutter (1.0.0) + - flutter_key_value_file_storage (0.0.1): + - Flutter + - flutter_secure_file_storage (0.0.1): + - Flutter - flutter_secure_storage (6.0.0): - Flutter - GoogleAppMeasurement (10.25.0): @@ -148,6 +168,7 @@ PODS: - GoogleUtilities/UserDefaults (7.13.3): - GoogleUtilities/Logger - GoogleUtilities/Privacy + - GTMSessionFetcher/Core (3.5.0) - nanopb (2.30910.0): - nanopb/decode (= 2.30910.0) - nanopb/encode (= 2.30910.0) @@ -194,7 +215,10 @@ DEPENDENCIES: - firebase_core (from `.symlinks/plugins/firebase_core/ios`) - firebase_crashlytics (from `.symlinks/plugins/firebase_crashlytics/ios`) - firebase_remote_config (from `.symlinks/plugins/firebase_remote_config/ios`) + - firebase_storage (from `.symlinks/plugins/firebase_storage/ios`) - Flutter (from `Flutter`) + - flutter_key_value_file_storage (from `.symlinks/plugins/flutter_key_value_file_storage/ios`) + - flutter_secure_file_storage (from `.symlinks/plugins/flutter_secure_file_storage/ios`) - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) @@ -207,6 +231,8 @@ SPEC REPOS: - Firebase - FirebaseABTesting - FirebaseAnalytics + - FirebaseAppCheckInterop + - FirebaseAuthInterop - FirebaseCore - FirebaseCoreExtension - FirebaseCoreInternal @@ -216,9 +242,11 @@ SPEC REPOS: - FirebaseRemoteConfigInterop - FirebaseSessions - FirebaseSharedSwift + - FirebaseStorage - GoogleAppMeasurement - GoogleDataTransport - GoogleUtilities + - GTMSessionFetcher - nanopb - PromisesObjC - PromisesSwift @@ -238,8 +266,14 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/firebase_crashlytics/ios" firebase_remote_config: :path: ".symlinks/plugins/firebase_remote_config/ios" + firebase_storage: + :path: ".symlinks/plugins/firebase_storage/ios" Flutter: :path: Flutter + flutter_key_value_file_storage: + :path: ".symlinks/plugins/flutter_key_value_file_storage/ios" + flutter_secure_file_storage: + :path: ".symlinks/plugins/flutter_secure_file_storage/ios" flutter_secure_storage: :path: ".symlinks/plugins/flutter_secure_storage/ios" path_provider_foundation: @@ -261,8 +295,11 @@ SPEC CHECKSUMS: firebase_core: a626d00494efa398e7c54f25f1454a64c8abf197 firebase_crashlytics: 17e856fabec68d993662abaf2f6fe2413f0abece firebase_remote_config: 7b05c80210ab558c80f7a756681022b4ee98eea0 + firebase_storage: 5c0f552d6b27d621429d7fd16ebab4be94a3c954 FirebaseABTesting: d87f56707159bae64e269757a6e963d490f2eebe FirebaseAnalytics: ec00fe8b93b41dc6fe4a28784b8e51da0647a248 + FirebaseAppCheckInterop: 6a1757cfd4067d8e00fccd14fcc1b8fd78cfac07 + FirebaseAuthInterop: 17db81e9b198afb0f95ce48c133825727eed55d3 FirebaseCore: 7ec4d0484817f12c3373955bc87762d96842d483 FirebaseCoreExtension: 705ca5b14bf71d2564a0ddc677df1fc86ffa600f FirebaseCoreInternal: df84dd300b561c27d5571684f389bf60b0a5c934 @@ -272,11 +309,15 @@ SPEC CHECKSUMS: FirebaseRemoteConfigInterop: 6efda51fb5e2f15b16585197e26eaa09574e8a4d FirebaseSessions: dbd14adac65ce996228652c1fc3a3f576bdf3ecc FirebaseSharedSwift: 20530f495084b8d840f78a100d8c5ee613375f6e + FirebaseStorage: 44f4e25073f6fa0d4d8c09f5bec299ee9e4eb985 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 + flutter_key_value_file_storage: b91fb1747ffa3e36810c752a1763655fda0b9f3d + flutter_secure_file_storage: cdf659810f1849916ea5371ed5df339a3aaa802c flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12 GoogleAppMeasurement: 9abf64b682732fed36da827aa2a68f0221fd2356 GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a GoogleUtilities: ea963c370a38a8069cc5f7ba4ca849a60b6d7d15 + GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6 nanopb: 438bc412db1928dac798aa6fd75726007be04262 path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index e857b1b4..d346eed5 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -299,6 +299,8 @@ inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", "${BUILT_PRODUCTS_DIR}/FirebaseABTesting/FirebaseABTesting.framework", + "${BUILT_PRODUCTS_DIR}/FirebaseAppCheckInterop/FirebaseAppCheckInterop.framework", + "${BUILT_PRODUCTS_DIR}/FirebaseAuthInterop/FirebaseAuthInterop.framework", "${BUILT_PRODUCTS_DIR}/FirebaseCore/FirebaseCore.framework", "${BUILT_PRODUCTS_DIR}/FirebaseCoreExtension/FirebaseCoreExtension.framework", "${BUILT_PRODUCTS_DIR}/FirebaseCoreInternal/FirebaseCoreInternal.framework", @@ -308,6 +310,8 @@ "${BUILT_PRODUCTS_DIR}/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop.framework", "${BUILT_PRODUCTS_DIR}/FirebaseSessions/FirebaseSessions.framework", "${BUILT_PRODUCTS_DIR}/FirebaseSharedSwift/FirebaseSharedSwift.framework", + "${BUILT_PRODUCTS_DIR}/FirebaseStorage/FirebaseStorage.framework", + "${BUILT_PRODUCTS_DIR}/GTMSessionFetcher/GTMSessionFetcher.framework", "${BUILT_PRODUCTS_DIR}/GoogleDataTransport/GoogleDataTransport.framework", "${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework", "${BUILT_PRODUCTS_DIR}/PromisesObjC/FBLPromises.framework", @@ -315,6 +319,8 @@ "${BUILT_PRODUCTS_DIR}/ReachabilitySwift/Reachability.framework", "${BUILT_PRODUCTS_DIR}/connectivity_plus/connectivity_plus.framework", "${BUILT_PRODUCTS_DIR}/device_info_plus/device_info_plus.framework", + "${BUILT_PRODUCTS_DIR}/flutter_key_value_file_storage/flutter_key_value_file_storage.framework", + "${BUILT_PRODUCTS_DIR}/flutter_secure_file_storage/flutter_secure_file_storage.framework", "${BUILT_PRODUCTS_DIR}/flutter_secure_storage/flutter_secure_storage.framework", "${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework", "${BUILT_PRODUCTS_DIR}/path_provider_foundation/path_provider_foundation.framework", @@ -327,6 +333,8 @@ name = "[CP] Embed Pods Frameworks"; outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseABTesting.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseAppCheckInterop.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseAuthInterop.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCore.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCoreExtension.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCoreInternal.framework", @@ -336,6 +344,8 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseRemoteConfigInterop.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseSessions.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseSharedSwift.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseStorage.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GTMSessionFetcher.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleDataTransport.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBLPromises.framework", @@ -343,6 +353,8 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Reachability.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/connectivity_plus.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/device_info_plus.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_key_value_file_storage.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_secure_file_storage.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_secure_storage.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_foundation.framework", diff --git a/lib/app.dart b/lib/app.dart index bd18443c..7b36d407 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -3,6 +3,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_template/di/injectable.dart'; import 'package:flutter_template/navigator/main_navigator.dart'; +import 'package:flutter_template/repository/logging/logging_repository.dart'; import 'package:flutter_template/styles/theme_data.dart'; import 'package:flutter_template/util/locale/localization_fallback_cupertino_delegate.dart'; import 'package:flutter_template/viewmodel/global/global_viewmodel.dart'; @@ -23,6 +24,10 @@ class MyApp extends StatelessWidget { systemNavigationBarColor: Colors.transparent, )); SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); + + // init logger + getIt.get().startLogging(); + return const InternalApp(); } } diff --git a/lib/di/db/setup_drift_io.dart b/lib/di/db/setup_drift_io.dart index cdb979c0..9a891ff6 100644 --- a/lib/di/db/setup_drift_io.dart +++ b/lib/di/db/setup_drift_io.dart @@ -5,7 +5,7 @@ import 'package:drift/drift.dart'; import 'package:drift/isolate.dart'; import 'package:drift/native.dart'; import 'package:flutter_template/util/env/flavor_config.dart'; -import 'package:icapps_architecture/icapps_architecture.dart'; +import 'package:flutter_template/util/logging/flutter_template_logger.dart'; import 'package:path/path.dart'; import 'package:path_provider/path_provider.dart'; @@ -17,7 +17,7 @@ Future createDriftDatabaseConnection(String name) async { final file = File(join(dbFolder.path, '$name.sqlite')); if ((FlavorConfig.isDev() || FlavorConfig.isDummy()) && file.existsSync()) { file.deleteSync(); - staticLogger.debug('Databasefile `db.sqlite` is deleted'); + FlutterTemplateLogger.logDebug('Databasefile `db.sqlite` is deleted'); } final receivePort = ReceivePort(); diff --git a/lib/di/db/setup_drift_web.dart b/lib/di/db/setup_drift_web.dart index ae97d317..d38cd7b3 100644 --- a/lib/di/db/setup_drift_web.dart +++ b/lib/di/db/setup_drift_web.dart @@ -1,6 +1,6 @@ import 'package:drift/drift.dart'; import 'package:drift/wasm.dart'; -import 'package:icapps_architecture/icapps_architecture.dart'; +import 'package:flutter_template/util/logging/flutter_template_logger.dart'; // If you want to use web workers, see https://drift.simonbinder.eu/web/ Future createDriftDatabaseConnection(String name) async { @@ -11,7 +11,7 @@ Future createDriftDatabaseConnection(String name) async { ); if (executor.missingFeatures.isNotEmpty) { - staticLogger.d('Using ${executor.chosenImplementation} due to missing browser features: ${executor.missingFeatures}'); + FlutterTemplateLogger.logDebug('Using ${executor.chosenImplementation} due to missing browser features: ${executor.missingFeatures}'); } return DatabaseConnection(executor.resolvedExecutor); diff --git a/lib/di/injectable.config.dart b/lib/di/injectable.config.dart index 35628d0e..ef2feb35 100644 --- a/lib/di/injectable.config.dart +++ b/lib/di/injectable.config.dart @@ -8,80 +8,88 @@ // coverage:ignore-file // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'package:dio/dio.dart' as _i46; +import 'package:dio/dio.dart' as _i52; import 'package:drift/drift.dart' as _i6; import 'package:firebase_analytics/firebase_analytics.dart' as _i8; -import 'package:firebase_remote_config/firebase_remote_config.dart' as _i9; -import 'package:flutter_secure_storage/flutter_secure_storage.dart' as _i10; +import 'package:firebase_crashlytics/firebase_crashlytics.dart' as _i9; +import 'package:firebase_remote_config/firebase_remote_config.dart' as _i10; +import 'package:firebase_storage/firebase_storage.dart' as _i11; +import 'package:flutter_secure_storage/flutter_secure_storage.dart' as _i12; import 'package:flutter_template/database/flutter_template_database.dart' - as _i11; -import 'package:flutter_template/database/todo/todo_dao_storage.dart' as _i22; -import 'package:flutter_template/di/injectable.dart' as _i48; -import 'package:flutter_template/navigator/main_navigator.dart' as _i14; -import 'package:flutter_template/navigator/onboarding_navigator.dart' as _i35; + as _i13; +import 'package:flutter_template/database/todo/todo_dao_storage.dart' as _i24; +import 'package:flutter_template/di/injectable.dart' as _i54; +import 'package:flutter_template/navigator/main_navigator.dart' as _i16; +import 'package:flutter_template/navigator/onboarding_navigator.dart' as _i39; import 'package:flutter_template/repository/analytics/firebase_analytics_repository.dart' - as _i26; + as _i27; import 'package:flutter_template/repository/debug/debug_repository.dart' - as _i30; -import 'package:flutter_template/repository/locale/locale_repository.dart' as _i32; +import 'package:flutter_template/repository/locale/locale_repository.dart' + as _i34; +import 'package:flutter_template/repository/logging/logging_repository.dart' + as _i35; import 'package:flutter_template/repository/login/login_repository.dart' - as _i33; -import 'package:flutter_template/repository/refresh/refresh_repository.dart' as _i36; +import 'package:flutter_template/repository/refresh/refresh_repository.dart' + as _i40; import 'package:flutter_template/repository/remote_config/remote_config.dart' - as _i17; + as _i19; import 'package:flutter_template/repository/remote_config/remote_config_repository.dart' - as _i18; + as _i20; import 'package:flutter_template/repository/secure_storage/auth/auth_storage.dart' - as _i29; + as _i31; import 'package:flutter_template/repository/secure_storage/secure_storage.dart' - as _i19; + as _i21; import 'package:flutter_template/repository/shared_prefs/local/local_storage.dart' - as _i31; -import 'package:flutter_template/repository/todo/todo_repository.dart' as _i28; + as _i33; +import 'package:flutter_template/repository/todo/todo_repository.dart' as _i30; import 'package:flutter_template/util/cache/cache_controller.dart' as _i4; import 'package:flutter_template/util/cache/cache_controlling.dart' as _i3; import 'package:flutter_template/util/interceptor/network_auth_interceptor.dart' - as _i34; + as _i38; import 'package:flutter_template/util/interceptor/network_error_interceptor.dart' - as _i15; + as _i17; import 'package:flutter_template/util/interceptor/network_log_interceptor.dart' - as _i16; + as _i18; import 'package:flutter_template/util/interceptor/network_refresh_interceptor.dart' - as _i44; + as _i49; import 'package:flutter_template/util/locale/localization_overrides.dart' - as _i12; + as _i14; import 'package:flutter_template/util/locale/localization_overrides_impl.dart' - as _i13; + as _i15; import 'package:flutter_template/util/snackbar/error_util.dart' as _i7; -import 'package:flutter_template/util/theme/theme_config.dart' as _i21; +import 'package:flutter_template/util/theme/theme_config.dart' as _i23; import 'package:flutter_template/viewmodel/debug/debug_platform_selector_viewmodel.dart' - as _i25; + as _i50; import 'package:flutter_template/viewmodel/debug/debug_theme_selector_viewmodel.dart' - as _i45; -import 'package:flutter_template/viewmodel/debug/debug_viewmodel.dart' as _i41; + as _i51; +import 'package:flutter_template/viewmodel/debug/debug_viewmodel.dart' as _i45; import 'package:flutter_template/viewmodel/global/global_viewmodel.dart' - as _i42; + as _i46; import 'package:flutter_template/viewmodel/license/license_viewmodel.dart' - as _i27; -import 'package:flutter_template/viewmodel/login/login_viewmodel.dart' as _i43; + as _i28; +import 'package:flutter_template/viewmodel/log_detail/log_detail_viewmodel.dart' + as _i47; +import 'package:flutter_template/viewmodel/login/login_viewmodel.dart' as _i48; +import 'package:flutter_template/viewmodel/logs/logs_viewmodel.dart' as _i37; import 'package:flutter_template/viewmodel/permission/analytics_permission_viewmodel.dart' - as _i40; + as _i44; import 'package:flutter_template/viewmodel/splash/splash_viewmodel.dart' - as _i37; + as _i41; import 'package:flutter_template/viewmodel/todo/todo_add/todo_add_viewmodel.dart' - as _i38; + as _i42; import 'package:flutter_template/viewmodel/todo/todo_list/todo_list_viewmodel.dart' - as _i39; + as _i43; import 'package:flutter_template/webservice/todo/todo_dummy_service.dart' - as _i24; -import 'package:flutter_template/webservice/todo/todo_service.dart' as _i23; -import 'package:flutter_template/webservice/todo/todo_webservice.dart' as _i47; + as _i26; +import 'package:flutter_template/webservice/todo/todo_service.dart' as _i25; +import 'package:flutter_template/webservice/todo/todo_webservice.dart' as _i53; import 'package:get_it/get_it.dart' as _i1; import 'package:icapps_architecture/icapps_architecture.dart' as _i5; import 'package:injectable/injectable.dart' as _i2; -import 'package:shared_preferences/shared_preferences.dart' as _i20; +import 'package:log_to_secure_file/log_to_secure_file.dart' as _i29; +import 'package:shared_preferences/shared_preferences.dart' as _i22; const String _dummy = 'dummy'; const String _dev = 'dev'; @@ -109,130 +117,151 @@ extension GetItInjectableX on _i1.GetIt { gh.lazySingleton<_i7.ErrorUtil>(() => _i7.ErrorUtil()); gh.lazySingleton<_i8.FirebaseAnalytics>( () => registerModule.provideFirebaseAnalytics()); - gh.lazySingleton<_i9.FirebaseRemoteConfig>( + gh.lazySingleton<_i9.FirebaseCrashlytics>( + () => registerModule.provideFirebaseCrashlytics()); + gh.lazySingleton<_i10.FirebaseRemoteConfig>( () => registerModule.provideFirebaseRemoteConfig()); - gh.lazySingleton<_i10.FlutterSecureStorage>(() => registerModule.storage()); - gh.lazySingleton<_i11.FlutterTemplateDatabase>(() => registerModule + gh.lazySingleton<_i11.FirebaseStorage>( + () => registerModule.provideFirebaseStorage()); + gh.lazySingleton<_i12.FlutterSecureStorage>(() => registerModule.storage()); + gh.lazySingleton<_i13.FlutterTemplateDatabase>(() => registerModule .provideFlutterTemplateDatabase(gh<_i6.DatabaseConnection>())); - gh.lazySingleton<_i12.LocalizationOverrides>( - () => _i13.LocalizationOverridesImpl()); - gh.lazySingleton<_i14.MainNavigator>( - () => _i14.MainNavigator(gh<_i7.ErrorUtil>())); - gh.singleton<_i15.NetworkErrorInterceptor>( - () => _i15.NetworkErrorInterceptor(gh<_i5.ConnectivityHelper>())); - gh.singleton<_i16.NetworkLogInterceptor>( - () => _i16.NetworkLogInterceptor()); - gh.lazySingleton<_i17.RemoteConfig>(() => _i17.RemoteConfig()); - gh.lazySingleton<_i18.RemoteConfigRepository>( - () => _i18.RemoteConfigRepository(gh<_i9.FirebaseRemoteConfig>())); - gh.lazySingleton<_i19.SecureStorage>( - () => _i19.SecureStorage(gh<_i10.FlutterSecureStorage>())); - await gh.singletonAsync<_i20.SharedPreferences>( + gh.lazySingleton<_i14.LocalizationOverrides>( + () => _i15.LocalizationOverridesImpl()); + gh.lazySingleton<_i16.MainNavigator>( + () => _i16.MainNavigator(gh<_i7.ErrorUtil>())); + gh.singleton<_i17.NetworkErrorInterceptor>( + () => _i17.NetworkErrorInterceptor(gh<_i5.ConnectivityHelper>())); + gh.singleton<_i18.NetworkLogInterceptor>( + () => _i18.NetworkLogInterceptor()); + gh.lazySingleton<_i19.RemoteConfig>(() => _i19.RemoteConfig()); + gh.lazySingleton<_i20.RemoteConfigRepository>( + () => _i20.RemoteConfigRepository(gh<_i10.FirebaseRemoteConfig>())); + gh.lazySingleton<_i21.SecureStorage>( + () => _i21.SecureStorage(gh<_i12.FlutterSecureStorage>())); + await gh.singletonAsync<_i22.SharedPreferences>( () => registerModule.prefs(), preResolve: true, ); - gh.lazySingleton<_i21.ThemeConfigUtil>(() => _i21.ThemeConfigUtil()); - gh.lazySingleton<_i22.TodoDaoStorage>( - () => _i22.TodoDaoStorage(gh<_i11.FlutterTemplateDatabase>())); - gh.singleton<_i23.TodoService>( - () => _i24.TodoDummyService(), + gh.lazySingleton<_i23.ThemeConfigUtil>(() => _i23.ThemeConfigUtil()); + gh.lazySingleton<_i24.TodoDaoStorage>( + () => _i24.TodoDaoStorage(gh<_i13.FlutterTemplateDatabase>())); + gh.singleton<_i25.TodoService>( + () => _i26.TodoDummyService(), registerFor: {_dummy}, ); - gh.factory<_i25.DebugPlatformSelectorViewModel>( - () => _i25.DebugPlatformSelectorViewModel(gh<_i14.MainNavigator>())); - gh.lazySingleton<_i26.FireBaseAnalyticsRepository>( - () => _i26.FireBaseAnalyticsRepository(gh<_i8.FirebaseAnalytics>())); - gh.factory<_i27.LicenseViewModel>( - () => _i27.LicenseViewModel(gh<_i14.MainNavigator>())); + gh.lazySingleton<_i27.FireBaseAnalyticsRepository>( + () => _i27.FireBaseAnalyticsRepository(gh<_i8.FirebaseAnalytics>())); + gh.factory<_i28.LicenseViewModel>( + () => _i28.LicenseViewModel(gh<_i16.MainNavigator>())); + gh.lazySingleton<_i29.SecureLogStorage>( + () => registerModule.provideSecureLogStorage(gh<_i21.SecureStorage>())); gh.lazySingleton<_i5.SharedPreferenceStorage>( - () => registerModule.sharedPreferences(gh<_i20.SharedPreferences>())); + () => registerModule.sharedPreferences(gh<_i22.SharedPreferences>())); gh.lazySingleton<_i5.SimpleKeyValueStorage>( () => registerModule.keyValueStorage( gh<_i5.SharedPreferenceStorage>(), - gh<_i19.SecureStorage>(), + gh<_i21.SecureStorage>(), )); - gh.lazySingleton<_i28.TodoRepository>(() => _i28.TodoRepository( - gh<_i23.TodoService>(), - gh<_i22.TodoDaoStorage>(), + gh.lazySingleton<_i30.TodoRepository>(() => _i30.TodoRepository( + gh<_i25.TodoService>(), + gh<_i24.TodoDaoStorage>(), )); - gh.lazySingleton<_i29.AuthStorage>( - () => _i29.AuthStorage(gh<_i5.SimpleKeyValueStorage>())); - gh.lazySingleton<_i30.DebugRepository>( - () => _i30.DebugRepository(gh<_i5.SharedPreferenceStorage>())); - gh.lazySingleton<_i31.LocalStorage>(() => _i31.LocalStorage( - gh<_i29.AuthStorage>(), + gh.lazySingleton<_i31.AuthStorage>( + () => _i31.AuthStorage(gh<_i5.SimpleKeyValueStorage>())); + gh.lazySingleton<_i32.DebugRepository>( + () => _i32.DebugRepository(gh<_i5.SharedPreferenceStorage>())); + gh.lazySingleton<_i33.LocalStorage>(() => _i33.LocalStorage( + gh<_i31.AuthStorage>(), gh<_i5.SharedPreferenceStorage>(), )); - gh.lazySingleton<_i32.LocaleRepository>( - () => _i32.LocaleRepository(gh<_i5.SharedPreferenceStorage>())); - gh.lazySingleton<_i33.LoginRepository>( - () => _i33.LoginRepository(gh<_i29.AuthStorage>())); - gh.singleton<_i34.NetworkAuthInterceptor>( - () => _i34.NetworkAuthInterceptor(gh<_i29.AuthStorage>())); - gh.lazySingleton<_i35.OnboardingNavigator>(() => _i35.OnboardingNavigator( - gh<_i14.MainNavigator>(), - gh<_i31.LocalStorage>(), - gh<_i33.LoginRepository>(), + gh.lazySingleton<_i34.LocaleRepository>( + () => _i34.LocaleRepository(gh<_i5.SharedPreferenceStorage>())); + gh.lazySingleton<_i35.LoggingRepository>(() => _i35.LoggingRepository( + gh<_i11.FirebaseStorage>(), + gh<_i29.SecureLogStorage>(), )); - gh.lazySingleton<_i36.RefreshRepository>( - () => _i36.RefreshRepository(gh<_i29.AuthStorage>())); - gh.factory<_i37.SplashViewModel>(() => _i37.SplashViewModel( - gh<_i31.LocalStorage>(), - gh<_i35.OnboardingNavigator>(), - gh<_i18.RemoteConfigRepository>(), + gh.lazySingleton<_i36.LoginRepository>( + () => _i36.LoginRepository(gh<_i31.AuthStorage>())); + gh.factory<_i37.LogsViewModel>(() => _i37.LogsViewModel( + gh<_i16.MainNavigator>(), + gh<_i29.SecureLogStorage>(), )); - gh.factory<_i38.TodoAddViewModel>(() => _i38.TodoAddViewModel( - gh<_i28.TodoRepository>(), - gh<_i14.MainNavigator>(), + gh.singleton<_i38.NetworkAuthInterceptor>( + () => _i38.NetworkAuthInterceptor(gh<_i31.AuthStorage>())); + gh.lazySingleton<_i39.OnboardingNavigator>(() => _i39.OnboardingNavigator( + gh<_i16.MainNavigator>(), + gh<_i33.LocalStorage>(), + gh<_i36.LoginRepository>(), )); - gh.factory<_i39.TodoListViewModel>(() => _i39.TodoListViewModel( - gh<_i28.TodoRepository>(), - gh<_i14.MainNavigator>(), + gh.lazySingleton<_i40.RefreshRepository>( + () => _i40.RefreshRepository(gh<_i31.AuthStorage>())); + gh.factory<_i41.SplashViewModel>(() => _i41.SplashViewModel( + gh<_i33.LocalStorage>(), + gh<_i39.OnboardingNavigator>(), + gh<_i20.RemoteConfigRepository>(), )); - gh.factory<_i40.AnalyticsPermissionViewModel>( - () => _i40.AnalyticsPermissionViewModel( - gh<_i35.OnboardingNavigator>(), - gh<_i31.LocalStorage>(), + gh.factory<_i42.TodoAddViewModel>(() => _i42.TodoAddViewModel( + gh<_i30.TodoRepository>(), + gh<_i16.MainNavigator>(), + )); + gh.factory<_i43.TodoListViewModel>(() => _i43.TodoListViewModel( + gh<_i30.TodoRepository>(), + gh<_i16.MainNavigator>(), + )); + gh.factory<_i44.AnalyticsPermissionViewModel>( + () => _i44.AnalyticsPermissionViewModel( + gh<_i39.OnboardingNavigator>(), + gh<_i33.LocalStorage>(), )); - gh.factory<_i41.DebugViewModel>(() => _i41.DebugViewModel( - gh<_i30.DebugRepository>(), - gh<_i14.MainNavigator>(), - gh<_i11.FlutterTemplateDatabase>(), - gh<_i31.LocalStorage>(), + gh.factory<_i45.DebugViewModel>(() => _i45.DebugViewModel( + gh<_i32.DebugRepository>(), + gh<_i16.MainNavigator>(), + gh<_i13.FlutterTemplateDatabase>(), + gh<_i33.LocalStorage>(), )); - gh.lazySingleton<_i42.GlobalViewModel>(() => _i42.GlobalViewModel( - gh<_i32.LocaleRepository>(), - gh<_i30.DebugRepository>(), - gh<_i31.LocalStorage>(), - gh<_i21.ThemeConfigUtil>(), - gh<_i12.LocalizationOverrides>(), + gh.lazySingleton<_i46.GlobalViewModel>(() => _i46.GlobalViewModel( + gh<_i34.LocaleRepository>(), + gh<_i32.DebugRepository>(), + gh<_i33.LocalStorage>(), + gh<_i23.ThemeConfigUtil>(), + gh<_i14.LocalizationOverrides>(), )); - gh.factory<_i43.LoginViewModel>(() => _i43.LoginViewModel( - gh<_i33.LoginRepository>(), - gh<_i14.MainNavigator>(), - gh<_i35.OnboardingNavigator>(), + gh.factory<_i47.LogDetailViewModel>(() => _i47.LogDetailViewModel( + gh<_i29.SecureLogStorage>(), + gh<_i35.LoggingRepository>(), )); - gh.singleton<_i44.NetworkRefreshInterceptor>( - () => _i44.NetworkRefreshInterceptor( - gh<_i29.AuthStorage>(), - gh<_i36.RefreshRepository>(), + gh.factory<_i48.LoginViewModel>(() => _i48.LoginViewModel( + gh<_i36.LoginRepository>(), + gh<_i16.MainNavigator>(), + gh<_i39.OnboardingNavigator>(), + )); + gh.singleton<_i49.NetworkRefreshInterceptor>( + () => _i49.NetworkRefreshInterceptor( + gh<_i31.AuthStorage>(), + gh<_i40.RefreshRepository>(), )); gh.lazySingleton<_i5.CombiningSmartInterceptor>( () => registerModule.provideCombiningSmartInterceptor( - gh<_i16.NetworkLogInterceptor>(), - gh<_i34.NetworkAuthInterceptor>(), - gh<_i15.NetworkErrorInterceptor>(), - gh<_i44.NetworkRefreshInterceptor>(), + gh<_i18.NetworkLogInterceptor>(), + gh<_i38.NetworkAuthInterceptor>(), + gh<_i17.NetworkErrorInterceptor>(), + gh<_i49.NetworkRefreshInterceptor>(), + )); + gh.factory<_i50.DebugPlatformSelectorViewModel>( + () => _i50.DebugPlatformSelectorViewModel( + gh<_i46.GlobalViewModel>(), + gh<_i16.MainNavigator>(), )); - gh.factory<_i45.DebugThemeSelectorViewModel>( - () => _i45.DebugThemeSelectorViewModel( - gh<_i14.MainNavigator>(), - gh<_i42.GlobalViewModel>(), + gh.factory<_i51.DebugThemeSelectorViewModel>( + () => _i51.DebugThemeSelectorViewModel( + gh<_i16.MainNavigator>(), + gh<_i46.GlobalViewModel>(), )); - gh.lazySingleton<_i46.Dio>( + gh.lazySingleton<_i52.Dio>( () => registerModule.provideDio(gh<_i5.CombiningSmartInterceptor>())); - gh.singleton<_i23.TodoService>( - () => _i47.TodoWebService(gh<_i46.Dio>()), + gh.singleton<_i25.TodoService>( + () => _i53.TodoWebService(gh<_i52.Dio>()), registerFor: { _dev, _prod, @@ -242,4 +271,4 @@ extension GetItInjectableX on _i1.GetIt { } } -class _$RegisterModule extends _i48.RegisterModule {} +class _$RegisterModule extends _i54.RegisterModule {} diff --git a/lib/di/injectable.dart b/lib/di/injectable.dart index e7856551..93043573 100644 --- a/lib/di/injectable.dart +++ b/lib/di/injectable.dart @@ -3,7 +3,9 @@ import 'dart:convert'; import 'package:dio/dio.dart'; import 'package:drift/drift.dart'; import 'package:firebase_analytics/firebase_analytics.dart'; +import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:firebase_remote_config/firebase_remote_config.dart'; +import 'package:firebase_storage/firebase_storage.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_template/database/flutter_template_database.dart'; @@ -20,6 +22,7 @@ import 'package:flutter_template/util/interceptor/network_refresh_interceptor.da import 'package:get_it/get_it.dart'; import 'package:icapps_architecture/icapps_architecture.dart'; import 'package:injectable/injectable.dart'; +import 'package:log_to_secure_file/log_to_secure_file.dart'; import 'package:shared_preferences/shared_preferences.dart'; final getIt = GetIt.asNewInstance(); @@ -59,9 +62,18 @@ abstract class RegisterModule { return createDriftDatabaseConnection('db'); } + @lazySingleton + SecureLogStorage provideSecureLogStorage(SecureStorage secureStorage) => SecureLogStorage(); + @lazySingleton FirebaseAnalytics provideFirebaseAnalytics() => FirebaseAnalytics.instance; + @lazySingleton + FirebaseCrashlytics provideFirebaseCrashlytics() => FirebaseCrashlytics.instance; + + @lazySingleton + FirebaseStorage provideFirebaseStorage() => FirebaseStorage.instance; + @lazySingleton FlutterSecureStorage storage() => const FlutterSecureStorage(); diff --git a/lib/main_common.dart b/lib/main_common.dart index f00d2037..b816f416 100644 --- a/lib/main_common.dart +++ b/lib/main_common.dart @@ -5,8 +5,8 @@ import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_template/architecture.dart'; +import 'package:flutter_template/util/logging/flutter_template_logger.dart'; import 'package:flutter_template/util/web/app_configurator.dart' if (dart.library.html) 'package:flutter_template/util/web/app_configurator_web.dart'; -import 'package:icapps_architecture/icapps_architecture.dart'; Future _setupCrashLogging() async { await Firebase.initializeApp(); @@ -27,7 +27,7 @@ FutureOr? wrapMain(FutureOr Function() appCode) async { } catch (_) {} try { - staticLogger.e('Uncaught platform error', error: error, stackTrace: trace); + FlutterTemplateLogger.logError('Uncaught platform error', error: error, stackTrace: trace); } catch (_) { // ignore: avoid_print print(error); diff --git a/lib/model/bottom_navigation/bottom_navigation_tab.dart b/lib/model/bottom_navigation/bottom_navigation_tab.dart index dd88aaf8..4a75ecc2 100644 --- a/lib/model/bottom_navigation/bottom_navigation_tab.dart +++ b/lib/model/bottom_navigation/bottom_navigation_tab.dart @@ -1,17 +1,28 @@ import 'package:flutter/material.dart'; import 'package:flutter_template/screen/debug/debug_screen.dart'; import 'package:flutter_template/screen/todo/todo_list/todo_list_screen.dart'; +import 'package:flutter_template/styles/theme_assets.dart'; import 'package:flutter_template/util/locale/localization_keys.dart'; enum BottomNavigationTab { - todo(icon: Icons.list, labelKey: LocalizationKeys.todoTitle), - settings(icon: Icons.settings, labelKey: LocalizationKeys.settingsTitle); + todo( + iconActive: ThemeAssets.todoIconActive, + iconInactive: ThemeAssets.todoIconInactive, + labelKey: LocalizationKeys.todoTitle, + ), + settings( + iconActive: ThemeAssets.settingsIconActive, + iconInactive: ThemeAssets.settingsIconInactive, + labelKey: LocalizationKeys.settingsTitle, + ); - final IconData icon; + final String iconActive; + final String iconInactive; final String labelKey; const BottomNavigationTab({ - required this.icon, + required this.iconActive, + required this.iconInactive, required this.labelKey, }); diff --git a/lib/navigator/main_navigator.dart b/lib/navigator/main_navigator.dart index 9af72c80..43ade5e5 100644 --- a/lib/navigator/main_navigator.dart +++ b/lib/navigator/main_navigator.dart @@ -21,6 +21,8 @@ class MainNavigator with BaseNavigator { static String get initialRoute => FlavorConfig.isInTest() ? 'test_route' : RouteNames.splashScreen; + BuildContext get context => navigatorKey.currentContext!; + static List get navigatorObservers => _navigatorObservers; Future goToDatabase(GeneratedDatabase db) async => _navigator.push(MaterialPageRoute(builder: (context) => DriftDbViewer(db))); diff --git a/lib/navigator/main_navigator.navigator.dart b/lib/navigator/main_navigator.navigator.dart index 658cf52d..870362b7 100644 --- a/lib/navigator/main_navigator.navigator.dart +++ b/lib/navigator/main_navigator.navigator.dart @@ -16,7 +16,9 @@ import '../screen/debug/debug_platform_selector_screen.dart'; import '../screen/debug/debug_screen.dart'; import '../screen/home/home_screen.dart'; import '../screen/license/license_screen.dart'; +import '../screen/log_detail/log_detail_screen.dart'; import '../screen/login/login_screen.dart'; +import '../screen/logs/logs_screen.dart'; import '../screen/permission/analytics_permission_screen.dart'; import '../screen/splash/splash_screen.dart'; import '../screen/theme_mode/theme_mode_selector.dart'; @@ -58,6 +60,15 @@ mixin BaseNavigator { settings: settings, fullscreenDialog: false, ); + case RouteNames.logDetailScreen: + return MaterialPageRoute( + builder: (_) => LogDetailScreen( + date: arguments['date'] as String, + key: arguments['key'] as Key?, + ), + settings: settings, + fullscreenDialog: false, + ); case RouteNames.todoAddScreen: return MaterialPageRoute( builder: (_) => TodoAddScreen( @@ -66,6 +77,14 @@ mixin BaseNavigator { settings: settings, fullscreenDialog: false, ); + case RouteNames.logsScreen: + return MaterialPageRoute( + builder: (_) => LogsScreen( + key: arguments['key'] as Key?, + ), + settings: settings, + fullscreenDialog: false, + ); case RouteNames.analyticsPermissionScreen: return MaterialPageRoute( builder: (_) => AnalyticsPermissionScreen( @@ -127,11 +146,27 @@ mixin BaseNavigator { RouteNames.licenseScreen, arguments: {'key': key}, ); + Future goToLogDetailScreen({ + required String date, + _i1.Key? key, + }) async => + navigatorKey.currentState?.pushNamed( + Uri( + path: RouteNames.logDetailScreen, + queryParameters: {'date': date}, + ).toString(), + arguments: {'date': date, 'key': key}, + ); Future goToTodoAddScreen({_i1.Key? key}) async => navigatorKey.currentState?.pushNamed( RouteNames.todoAddScreen, arguments: {'key': key}, ); + Future goToLogsScreen({_i1.Key? key}) async => + navigatorKey.currentState?.pushNamed( + RouteNames.logsScreen, + arguments: {'key': key}, + ); Future goToAnalyticsPermissionScreen({_i1.Key? key}) async => navigatorKey.currentState?.pushNamed( RouteNames.analyticsPermissionScreen, @@ -186,9 +221,15 @@ class RouteNames { /// /license static const licenseScreen = '/license'; + /// /log-detail + static const logDetailScreen = '/log-detail'; + /// /todo-add static const todoAddScreen = '/todo-add'; + /// /logs + static const logsScreen = '/logs'; + /// /analytics-permission static const analyticsPermissionScreen = '/analytics-permission'; diff --git a/lib/repository/logging/base_logging_repository.dart b/lib/repository/logging/base_logging_repository.dart new file mode 100644 index 00000000..cedbdfb8 --- /dev/null +++ b/lib/repository/logging/base_logging_repository.dart @@ -0,0 +1,40 @@ +import 'dart:io'; + +import 'package:icapps_architecture/icapps_architecture.dart'; +import 'package:log_to_secure_file/log_to_secure_file.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:synchronized/synchronized.dart'; + +abstract class BaseLoggingRepository { + final SecureLogStorage _secureLogStorage; + + BaseLoggingRepository( + this._secureLogStorage, + ); + + final _loggerLock = Lock(); + + String tempLogPath = '/logs'; + + void startLogging() { + _secureLogStorage.init(); + LoggingFactory.configure(LoggingConfiguration(onLog: (value) => storeLogLine(value))); + } + + void storeLogLine(String line) => _loggerLock.synchronized(() => _secureLogStorage.storeLogLine(line)); + + Future uploadLog(DateTime date) async { + final applicationDirectory = await getApplicationCacheDirectory(); + final file = File('${applicationDirectory.path}$tempLogPath'); + if (file.existsSync()) { + file.deleteSync(); + file.createSync(); + } + final log = await _secureLogStorage.getLogFromDate(date); + await file.writeAsString(log.join('\n')); + await uploadFile(file, date); + file.deleteSync(); + } + + Future uploadFile(File file, DateTime date); +} diff --git a/lib/repository/logging/logging_repository.dart b/lib/repository/logging/logging_repository.dart new file mode 100644 index 00000000..0ebf6aa1 --- /dev/null +++ b/lib/repository/logging/logging_repository.dart @@ -0,0 +1,23 @@ +import 'dart:io'; + +import 'package:firebase_storage/firebase_storage.dart'; +import 'package:flutter_template/repository/logging/base_logging_repository.dart'; +import 'package:flutter_template/util/extension/date_time_extension.dart'; +import 'package:injectable/injectable.dart'; + +@lazySingleton +class LoggingRepository extends BaseLoggingRepository { + final FirebaseStorage _firebaseStorage; + + LoggingRepository( + this._firebaseStorage, + super.secureLogStorage, + ); + + @override + Future uploadFile(File file, DateTime date) async { + const userId = 'TestUser'; + final ref = _firebaseStorage.ref('logs/$userId-${date.dottedShortDateFormat}.txt'); + await ref.putFile(file); + } +} diff --git a/lib/repository/login/login_repository.dart b/lib/repository/login/login_repository.dart index 064724dc..e4622c17 100644 --- a/lib/repository/login/login_repository.dart +++ b/lib/repository/login/login_repository.dart @@ -1,5 +1,5 @@ import 'package:flutter_template/repository/secure_storage/auth/auth_storage.dart'; -import 'package:icapps_architecture/icapps_architecture.dart'; +import 'package:flutter_template/util/logging/flutter_template_logger.dart'; import 'package:injectable/injectable.dart'; @lazySingleton @@ -22,11 +22,11 @@ class _LoginRepository implements LoginRepository { Future get isLoggedIn => _storage.hasLoggedInUser(); @override - Future get isNotLoggedIn async=> !(await _storage.hasLoggedInUser()); + Future get isNotLoggedIn async => !(await _storage.hasLoggedInUser()); @override Future login({required String email, required String password}) async { await _storage.saveUserCredentials(accessToken: 'test_access_token', refreshToken: 'test_refresh_token'); - logger.debug('Login should be implemented'); + FlutterTemplateLogger.logDebug('Login should be implemented'); } } diff --git a/lib/repository/refresh/refresh_repository.dart b/lib/repository/refresh/refresh_repository.dart index 3d273b2f..144f830e 100644 --- a/lib/repository/refresh/refresh_repository.dart +++ b/lib/repository/refresh/refresh_repository.dart @@ -2,7 +2,7 @@ import 'package:dio/dio.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_template/model/exceptions/un_authorized_error.dart'; import 'package:flutter_template/repository/secure_storage/auth/auth_storage.dart'; -import 'package:icapps_architecture/icapps_architecture.dart'; +import 'package:flutter_template/util/logging/flutter_template_logger.dart'; import 'package:injectable/injectable.dart'; import 'package:synchronized/synchronized.dart' as synchronized; @@ -39,7 +39,7 @@ class _RefreshRepository implements RefreshRepository { await _lock.synchronized(() async { final newAccessToken = await _authStorage.getAccessToken(); if (accessToken != newAccessToken) { - logger.debug('ACCESS TOKEN was already renewed'); + FlutterTemplateLogger.logDebug('ACCESS TOKEN was already renewed'); return; } if (_failure) { diff --git a/lib/repository/remote_config/remote_config.dart b/lib/repository/remote_config/remote_config.dart index 1dd6458a..531adca6 100644 --- a/lib/repository/remote_config/remote_config.dart +++ b/lib/repository/remote_config/remote_config.dart @@ -14,5 +14,7 @@ class RemoteConfig { int get reviewBuild => _remoteConfig?.getOptionalInt('review_build') ?? 1; + bool get sendBlockedErrorsToFirebase => _remoteConfig?.getOptionalBool('send_blocked_errors_to_firebase') ?? false; + Map get overriddenTranslations => _remoteConfig?.getCustomObjectMap('overridden_translations', LocalizedMessage.fromJson) ?? {}; } diff --git a/lib/repository/remote_config/remote_config_repository.dart b/lib/repository/remote_config/remote_config_repository.dart index df31acb3..e5802f16 100644 --- a/lib/repository/remote_config/remote_config_repository.dart +++ b/lib/repository/remote_config/remote_config_repository.dart @@ -3,7 +3,7 @@ import 'package:flutter_template/di/injectable.dart'; import 'package:flutter_template/repository/remote_config/base_remote_config_repository.dart'; import 'package:flutter_template/styles/theme_durations.dart'; import 'package:flutter_template/util/locale/localization_overrides.dart'; -import 'package:icapps_architecture/icapps_architecture.dart'; +import 'package:flutter_template/util/logging/flutter_template_logger.dart'; import 'package:injectable/injectable.dart'; @lazySingleton @@ -24,7 +24,7 @@ class RemoteConfigRepository extends BaseRemoteConfigRepo { await _remoteConfig.fetchAndActivate(); await getIt.get().refreshOverrideLocalizations(); } catch (error, trace) { - logger.error('Unable to fetch remote config. Cached or default values will be used', error: error, stackTrace: trace); + FlutterTemplateLogger.logError('Unable to fetch remote config. Cached or default values will be used', error: error, stackTrace: trace); } } diff --git a/lib/repository/secure_storage/secure_storage.dart b/lib/repository/secure_storage/secure_storage.dart index 1e226d81..b1647962 100644 --- a/lib/repository/secure_storage/secure_storage.dart +++ b/lib/repository/secure_storage/secure_storage.dart @@ -21,7 +21,7 @@ abstract class SecureStorage implements SimpleKeyValueStorage { class _SecureStorage implements SecureStorage { final FlutterSecureStorage _storage; - final iOSOptions = const IOSOptions(accessibility: KeychainAccessibility.first_unlock); + final iOSOptions = const IOSOptions(accessibility: KeychainAccessibility.unlocked); _SecureStorage(this._storage); diff --git a/lib/screen/debug/debug_platform_selector_screen.dart b/lib/screen/debug/debug_platform_selector_screen.dart index 8b4df3d5..ad5c75de 100644 --- a/lib/screen/debug/debug_platform_selector_screen.dart +++ b/lib/screen/debug/debug_platform_selector_screen.dart @@ -1,13 +1,10 @@ import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_navigation_generator_annotations/flutter_navigation_generator_annotations.dart'; import 'package:flutter_template/di/injectable.dart'; import 'package:flutter_template/viewmodel/debug/debug_platform_selector_viewmodel.dart'; -import 'package:flutter_template/viewmodel/global/global_viewmodel.dart'; import 'package:flutter_template/widget/debug/selector_item.dart'; -import 'package:flutter_template/widget/general/styled/flutter_template_back_button.dart'; +import 'package:flutter_template/widget/general/base_screen/base_screen.dart'; import 'package:flutter_template/widget/provider/provider_widget.dart'; -import 'package:provider/provider.dart'; @flutterRoute class DebugPlatformSelectorScreen extends StatefulWidget { @@ -23,35 +20,28 @@ class DebugPlatformSelectorScreenState extends State( create: getIt.call, - consumerWithThemeAndLocalization: (context, value, _, theme, localization) => Scaffold( - backgroundColor: theme.colorsTheme.background, - appBar: AppBar( - systemOverlayStyle: SystemUiOverlayStyle.light, - leading: FlutterTemplateBackButton.light(onClick: value.onBackClicked), - title: const Text('Select a platform'), - backgroundColor: theme.colorsTheme.primary, - ), - body: Consumer( - builder: (context, viewModel, child) => ListView( - children: [ - SelectorItem( - title: localization.generalLabelSystemDefault, - onClick: viewModel.setSelectedPlatformToDefault, - selected: viewModel.targetPlatform == null, - ), - SelectorItem( - title: localization.generalLabelAndroid, - onClick: viewModel.setSelectedPlatformToAndroid, - selected: viewModel.targetPlatform == TargetPlatform.android, - ), - SelectorItem( - title: localization.generalLabelIos, - onClick: viewModel.setSelectedPlatformToIOS, - selected: viewModel.targetPlatform == TargetPlatform.iOS, - ), - ], + consumerWithThemeAndLocalization: (context, viewModel, _, theme, localization) => BaseScreen( + title: 'Select a platform', + isScrollable: true, + children: [ + SelectorItem( + title: localization.generalLabelSystemDefault, + onClick: viewModel.setSelectedPlatformToDefault, + selected: viewModel.selectedPlatform == null, ), - ), + const SizedBox(height: 8), + SelectorItem( + title: localization.generalLabelAndroid, + onClick: viewModel.setSelectedPlatformToAndroid, + selected: viewModel.selectedPlatform == TargetPlatform.android, + ), + const SizedBox(height: 8), + SelectorItem( + title: localization.generalLabelIos, + onClick: viewModel.setSelectedPlatformToIOS, + selected: viewModel.selectedPlatform == TargetPlatform.iOS, + ) + ], ), ); } diff --git a/lib/screen/debug/debug_screen.dart b/lib/screen/debug/debug_screen.dart index 9dd752fb..ca876ea5 100644 --- a/lib/screen/debug/debug_screen.dart +++ b/lib/screen/debug/debug_screen.dart @@ -1,13 +1,14 @@ import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_navigation_generator_annotations/flutter_navigation_generator_annotations.dart'; import 'package:flutter_template/di/injectable.dart'; +import 'package:flutter_template/styles/theme_assets.dart'; import 'package:flutter_template/util/keys.dart'; import 'package:flutter_template/viewmodel/debug/debug_viewmodel.dart'; import 'package:flutter_template/viewmodel/global/global_viewmodel.dart'; import 'package:flutter_template/widget/debug/debug_row_item.dart'; -import 'package:flutter_template/widget/debug/debug_row_title.dart'; +import 'package:flutter_template/widget/debug/debug_section.dart'; import 'package:flutter_template/widget/debug/debug_switch_row_item.dart'; +import 'package:flutter_template/widget/general/base_screen/base_screen.dart'; import 'package:flutter_template/widget/provider/provider_widget.dart'; import 'package:provider/provider.dart'; @@ -25,73 +26,115 @@ class DebugScreenState extends State { Widget build(BuildContext context) { return ProviderWidget( create: () => getIt()..init(), - consumerWithThemeAndLocalization: (context, viewModel, child, theme, localization) => Scaffold( - backgroundColor: theme.colorsTheme.background, - appBar: AppBar( - systemOverlayStyle: SystemUiOverlayStyle.light, - title: Text(localization.settingsTitle), - backgroundColor: theme.colorsTheme.primary, - ), - body: ListView( - children: [ - DebugRowTitle(title: localization.debugAnimationsTitle), - DebugRowSwitchItem( - key: Keys.debugSlowAnimations, - title: localization.debugSlowAnimations, - value: viewModel.slowAnimationsEnabled, - onChanged: viewModel.onSlowAnimationsChanged, - ), - DebugRowTitle(title: localization.debugThemeTitle), - DebugRowItem( - key: Keys.debugTargetPlatform, - title: localization.debugTargetPlatformTitle, - subTitle: localization.debugTargetPlatformSubtitle(localization.getTranslation(Provider.of(context).getCurrentPlatform())), - onClick: viewModel.onTargetPlatformClicked, - ), - DebugRowItem( - key: Keys.debugThemeMode, - title: localization.debugThemeModeTitle, - subTitle: localization.debugThemeModeSubtitle, - onClick: viewModel.onThemeModeClicked, - ), - DebugRowTitle(title: localization.debugLocaleTitle), - DebugRowItem( - key: Keys.debugSelectLanguage, - title: localization.debugLocaleSelector, - subTitle: localization.debugLocaleCurrentLanguage(Provider.of(context).getCurrentLanguage()), - onClick: viewModel.onSelectLanguageClicked, - ), - DebugRowSwitchItem( - key: Keys.debugShowTranslations, - title: localization.debugShowTranslations, - value: Provider.of(context, listen: false).showsTranslationKeys, - onChanged: (_) => Provider.of(context, listen: false).toggleTranslationKeys(), - ), - DebugRowTitle(title: localization.debugLicensesTitle), - DebugRowItem( - key: Keys.debugLicense, - title: localization.debugLicensesGoTo, - onClick: viewModel.onLicensesClicked, - ), - DebugRowTitle(title: localization.debugDatabase), - DebugRowItem( - key: Keys.debugDatabase, - title: localization.debugViewDatabase, - onClick: viewModel.goToDatabase, - ), - DebugRowTitle(title: localization.debugPermissionsTitle), - DebugRowItem( - key: Keys.debugPermissionAnalytics, - title: localization.debugPermissionsShowAnalyticsPermission, - onClick: viewModel.goToAnalyticsPermissionScreen, - ), - DebugRowItem( - key: Keys.debugPermissionAnalyticsReset, - title: localization.debugPermissionResetAnalytics, - onClick: viewModel.resetAnalyticsPermission, - ), - ], - ), + consumerWithThemeAndLocalization: (context, viewModel, child, theme, localization) => BaseScreen( + title: localization.settingsTitle, + padding: const EdgeInsets.all(24), + isScrollable: true, + children: [ + DebugSection( + title: localization.debugAnimationsTitle, + icon: ThemeAssets.animationIcon, + children: [ + DebugRowSwitchItem( + key: Keys.debugSlowAnimations, + title: localization.debugSlowAnimations, + value: viewModel.slowAnimationsEnabled, + onChanged: viewModel.onSlowAnimationsChanged, + ), + ], + ), + const SizedBox(height: 24), + DebugSection( + title: localization.debugThemeTitle, + icon: ThemeAssets.themeIcon, + children: [ + DebugRowItem( + key: Keys.debugTargetPlatform, + title: localization.debugTargetPlatformTitle, + subTitle: localization.debugTargetPlatformSubtitle(localization.getTranslation(Provider.of(context).getCurrentPlatform())), + onClick: viewModel.onTargetPlatformClicked, + ), + DebugRowItem( + key: Keys.debugThemeMode, + title: localization.debugThemeModeTitle, + subTitle: localization.debugThemeModeSubtitle, + onClick: viewModel.onThemeModeClicked, + ), + ], + ), + const SizedBox(height: 24), + DebugSection( + title: localization.debugLocaleTitle, + icon: ThemeAssets.translationsIcon, + children: [ + DebugRowItem( + key: Keys.debugSelectLanguage, + title: localization.debugLocaleSelector, + subTitle: localization.debugLocaleCurrentLanguage(Provider.of(context).getCurrentLanguage()), + onClick: viewModel.onSelectLanguageClicked, + ), + DebugRowSwitchItem( + key: Keys.debugShowTranslations, + title: localization.debugShowTranslations, + value: Provider.of(context, listen: false).showsTranslationKeys, + onChanged: (_) => Provider.of(context, listen: false).toggleTranslationKeys(), + ), + ], + ), + const SizedBox(height: 24), + DebugSection( + title: localization.debugLicensesTitle, + icon: ThemeAssets.licenseIcon, + children: [ + DebugRowItem( + key: Keys.debugLicense, + title: localization.debugLicensesGoTo, + onClick: viewModel.onLicensesClicked, + ), + ], + ), + const SizedBox(height: 24), + DebugSection( + title: localization.debugDatabase, + icon: ThemeAssets.boxIcon, + children: [ + DebugRowItem( + key: Keys.debugDatabase, + title: localization.debugViewDatabase, + onClick: viewModel.goToDatabase, + ), + ], + ), + const SizedBox(height: 24), + DebugSection( + title: localization.debugPermissionsTitle, + icon: ThemeAssets.lockOpenIcon, + children: [ + DebugRowItem( + key: Keys.debugPermissionAnalytics, + title: localization.debugPermissionsShowAnalyticsPermission, + onClick: viewModel.goToAnalyticsPermissionScreen, + ), + DebugRowItem( + key: Keys.debugPermissionAnalyticsReset, + title: localization.debugPermissionResetAnalytics, + onClick: viewModel.resetAnalyticsPermission, + ), + ], + ), + const SizedBox(height: 24), + DebugSection( + title: 'logs', + icon: ThemeAssets.listIcon, + children: [ + DebugRowItem( + key: Keys.debugPermissionAnalyticsReset, + title: 'Show logs', + onClick: viewModel.onLogsTapped, + ), + ], + ), + ], ), ); } diff --git a/lib/screen/license/license_screen.dart b/lib/screen/license/license_screen.dart index 477b52ff..3ea8b6fa 100644 --- a/lib/screen/license/license_screen.dart +++ b/lib/screen/license/license_screen.dart @@ -1,10 +1,9 @@ import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_navigation_generator_annotations/flutter_navigation_generator_annotations.dart'; import 'package:flutter_template/di/injectable.dart'; -import 'package:flutter_template/styles/theme_dimens.dart'; +import 'package:flutter_template/styles/theme_data.dart'; import 'package:flutter_template/viewmodel/license/license_viewmodel.dart'; -import 'package:flutter_template/widget/general/styled/flutter_template_back_button.dart'; +import 'package:flutter_template/widget/general/base_screen/base_screen.dart'; import 'package:flutter_template/widget/provider/provider_widget.dart'; @flutterRoute @@ -21,41 +20,32 @@ class LicenseScreenState extends State { Widget build(BuildContext context) { return ProviderWidget( create: getIt.call, - consumerWithThemeAndLocalization: (context, viewModel, child, theme, localization) => Scaffold( - backgroundColor: theme.colorsTheme.background, - appBar: AppBar( - systemOverlayStyle: SystemUiOverlayStyle.light, - leading: FlutterTemplateBackButton.light(onClick: viewModel.onBackClicked), - title: Text(localization.debugLicensesTitle), - backgroundColor: theme.colorsTheme.primary, - ), - body: ListView.builder( - padding: const EdgeInsets.all(ThemeDimens.padding16), - itemCount: viewModel.licenses.length, - itemBuilder: (context, index) { - final item = viewModel.licenses[index]; - return Card( - color: theme.colorsTheme.background, - child: Padding( - padding: const EdgeInsets.all(ThemeDimens.padding16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - item.name, - style: theme.coreTextTheme.titleNormal, - ), - Container(height: ThemeDimens.padding8), - Text( - item.license, - style: theme.coreTextTheme.bodySmall, - ), - ], - ), + consumerWithThemeAndLocalization: (context, viewModel, child, theme, localization) => BaseScreen.builder( + title: localization.debugLicensesTitle, + itemCount: viewModel.licenses.length, + itemBuilder: (context, index) { + final item = viewModel.licenses[index]; + return Card( + color: theme.background, + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + item.name, + style: theme.text.titleNormal, + ), + Container(height: 8), + Text( + item.license, + style: theme.text.bodySmall, + ), + ], ), - ); - }, - ), + ), + ); + }, ), ); } diff --git a/lib/screen/log_detail/log_detail_screen.dart b/lib/screen/log_detail/log_detail_screen.dart new file mode 100644 index 00000000..fea3b981 --- /dev/null +++ b/lib/screen/log_detail/log_detail_screen.dart @@ -0,0 +1,52 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_navigation_generator_annotations/flutter_navigation_generator_annotations.dart'; +import 'package:flutter_template/di/injectable.dart'; +import 'package:flutter_template/styles/theme_data.dart'; +import 'package:flutter_template/viewmodel/log_detail/log_detail_viewmodel.dart'; +import 'package:flutter_template/widget/general/base_screen/base_screen.dart'; +import 'package:flutter_template/widget/general/styled/flutter_template_button.dart'; +import 'package:flutter_template/widget/provider/provider_widget.dart'; + +@flutterRoute +class LogDetailScreen extends StatefulWidget { + final String date; + + const LogDetailScreen({ + required this.date, + super.key, + }); + + @override + LogDetailScreenState createState() => LogDetailScreenState(); +} + +class LogDetailScreenState extends State { + @override + Widget build(BuildContext context) { + return ProviderWidget( + create: () => getIt()..init(widget.date), + childBuilderWithViewModel: (context, viewModel, theme, localization) => BaseScreen( + children: [ + Expanded( + child: ListView.builder( + reverse: true, + itemCount: viewModel.logs.length, + itemBuilder: (context, index) { + final log = viewModel.logs.reversed.toList()[index]; + return Text( + log, + style: theme.text.bodySmall, + ); + }, + ), + ), + FlutterTemplateButton( + isEnabled: !viewModel.isLoading, + text: 'Upload log', + onClick: viewModel.uploadLog, + ), + ], + ), + ); + } +} diff --git a/lib/screen/login/login_screen.dart b/lib/screen/login/login_screen.dart index 4e79a707..696284d9 100644 --- a/lib/screen/login/login_screen.dart +++ b/lib/screen/login/login_screen.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_navigation_generator_annotations/flutter_navigation_generator_annotations.dart'; import 'package:flutter_template/di/injectable.dart'; -import 'package:flutter_template/styles/theme_dimens.dart'; +import 'package:flutter_template/styles/theme_data.dart'; import 'package:flutter_template/util/keys.dart'; import 'package:flutter_template/viewmodel/login/login_viewmodel.dart'; -import 'package:flutter_template/widget/general/status_bar.dart'; +import 'package:flutter_template/widget/general/base_screen/base_screen.dart'; import 'package:flutter_template/widget/general/styled/flutter_template_button.dart'; import 'package:flutter_template/widget/general/styled/flutter_template_input_field.dart'; import 'package:flutter_template/widget/general/styled/flutter_template_progress_indicator.dart'; @@ -26,56 +26,49 @@ class LoginScreenState extends State { Widget build(BuildContext context) { return ProviderWidget( create: () => getIt()..init(), - consumerWithThemeAndLocalization: (context, viewModel, child, theme, localization) => StatusBar.animated( - isDarkStyle: theme.isDarkTheme, - child: Scaffold( - backgroundColor: theme.colorsTheme.background, - body: SafeArea( - child: Container( - width: double.infinity, - padding: const EdgeInsets.all(ThemeDimens.padding16), - child: Column( - children: [ - Container(height: ThemeDimens.padding16), - Text( - 'Login', - style: theme.coreTextTheme.titleNormal, - textAlign: TextAlign.center, - ), - Container(height: ThemeDimens.padding32), - Text( - 'Just fill in some text. There is no validator for the login', - style: theme.coreTextTheme.labelButtonSmall, - ), - Container(height: ThemeDimens.padding32), - FlutterTemplateInputField( - key: Keys.emailInput, - enabled: !viewModel.isLoading, - onChanged: viewModel.onEmailUpdated, - hint: 'Email', - ), - Container(height: ThemeDimens.padding16), - FlutterTemplateInputField( - key: Keys.passwordInput, - enabled: !viewModel.isLoading, - onChanged: viewModel.onPasswordUpdated, - hint: 'Password', - ), - Container(height: ThemeDimens.padding16), - if (viewModel.isLoading) ...[ - const FlutterTemplateProgressIndicator.light(), - ] else ...[ - FlutterTemplateButton( - key: Keys.loginButton, - isEnabled: viewModel.isLoginEnabled, - text: 'Login', - onClick: viewModel.onLoginClicked, - ), - ], - ], - ), + consumerWithThemeAndLocalization: (context, viewModel, child, theme, localization) => AutofillGroup( + child: BaseScreen( + showHeader: false, + children: [ + Container(height: 16), + Text( + 'Login', + style: theme.text.titleNormal, + textAlign: TextAlign.center, + ), + Container(height: 32), + Text( + 'Just fill in some text. There is no validator for the login', + style: theme.text.labelButtonSmall, + ), + Container(height: 32), + FlutterTemplateInputField( + key: Keys.emailInput, + enabled: !viewModel.isLoading, + onChanged: viewModel.onEmailUpdated, + hint: 'Email', + autoFillHints: const [AutofillHints.email], ), - ), + Container(height: 16), + FlutterTemplateInputField( + key: Keys.passwordInput, + enabled: !viewModel.isLoading, + onChanged: viewModel.onPasswordUpdated, + hint: 'Password', + autoFillHints: const [AutofillHints.password], + ), + Container(height: 16), + if (viewModel.isLoading) ...[ + const FlutterTemplateProgressIndicator.light(), + ] else ...[ + FlutterTemplateButton( + key: Keys.loginButton, + isEnabled: viewModel.isLoginEnabled, + text: 'Login', + onClick: viewModel.onLoginClicked, + ), + ], + ], ), ), ); diff --git a/lib/screen/logs/logs_screen.dart b/lib/screen/logs/logs_screen.dart new file mode 100644 index 00000000..8cdb8f33 --- /dev/null +++ b/lib/screen/logs/logs_screen.dart @@ -0,0 +1,73 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_navigation_generator_annotations/flutter_navigation_generator_annotations.dart'; +import 'package:flutter_template/di/injectable.dart'; +import 'package:flutter_template/styles/theme_assets.dart'; +import 'package:flutter_template/styles/theme_data.dart'; +import 'package:flutter_template/util/extension/date_time_extension.dart'; +import 'package:flutter_template/viewmodel/logs/logs_viewmodel.dart'; +import 'package:flutter_template/widget/general/base_screen/base_screen.dart'; +import 'package:flutter_template/widget/general/styled/flutter_template_button.dart'; +import 'package:flutter_template/widget/general/svg_icon.dart'; +import 'package:flutter_template/widget/provider/provider_widget.dart'; +import 'package:icapps_architecture/icapps_architecture.dart'; + +@flutterRoute +class LogsScreen extends StatefulWidget { + const LogsScreen({super.key}); + + @override + LogsScreenState createState() => LogsScreenState(); +} + +class LogsScreenState extends State { + @override + Widget build(BuildContext context) { + return ProviderWidget( + create: () => getIt()..init(), + childBuilderWithViewModel: (context, viewModel, theme, localization) => BaseScreen.child( + title: 'Logs', + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + children: [ + Expanded( + child: ListView.separated( + padding: const EdgeInsets.symmetric(vertical: 16), + itemCount: viewModel.availableDates.length, + separatorBuilder: (context, index) => const SizedBox(height: 8), + itemBuilder: (context, index) { + final item = viewModel.availableDates[index]; + return TouchFeedBack( + onTapped: () => viewModel.onLogTapped(item), + color: theme.cardBackground, + borderRadius: BorderRadius.circular(12), + child: Padding( + padding: const EdgeInsets.all(16), + child: Row( + children: [ + Expanded( + child: Text( + item.shortDateWeekdayFormat, + style: theme.text.bodyBig, + ), + ), + SvgIcon( + svgAsset: ThemeAssets.chevronRightIcon, + color: theme.icon, + ) + ], + ), + ), + ); + }, + ), + ), + FlutterTemplateButton( + text: 'Trigger crash', + onClick: viewModel.triggerError, + ), + ], + ), + ), + ); + } +} diff --git a/lib/screen/permission/analytics_permission_screen.dart b/lib/screen/permission/analytics_permission_screen.dart index 2adcf420..e6bd6e53 100644 --- a/lib/screen/permission/analytics_permission_screen.dart +++ b/lib/screen/permission/analytics_permission_screen.dart @@ -1,10 +1,11 @@ import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_navigation_generator_annotations/flutter_navigation_generator_annotations.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_template/di/injectable.dart'; import 'package:flutter_template/styles/theme_assets.dart'; +import 'package:flutter_template/styles/theme_data.dart'; import 'package:flutter_template/viewmodel/permission/analytics_permission_viewmodel.dart'; +import 'package:flutter_template/widget/general/base_screen/base_screen.dart'; import 'package:flutter_template/widget/general/styled/flutter_template_button.dart'; import 'package:flutter_template/widget/provider/provider_widget.dart'; @@ -16,62 +17,51 @@ class AnalyticsPermissionScreen extends StatelessWidget { Widget build(BuildContext context) { return ProviderWidget( create: () => getIt()..init(), - childBuilderWithViewModel: (context, viewModel, theme, localization) => AnnotatedRegion( - value: theme.isDarkTheme ? SystemUiOverlayStyle.light : SystemUiOverlayStyle.dark, - child: Scaffold( - backgroundColor: theme.colorsTheme.permissionScreenBackground, - body: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 16.0, - vertical: 32, - ), - child: Column( - children: [ - Expanded( - child: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const Spacer(), - Expanded( - flex: 5, - child: SvgPicture.asset( - ThemeAssets.analyticsImage(context), - alignment: Alignment.center, - fit: BoxFit.scaleDown, - ), - ), - const Spacer(), - const SizedBox(height: 32), - Text( - localization.permissionAnalyticsTitle, - style: theme.coreTextTheme.titleNormal, - ), - const SizedBox(height: 16), - Text( - localization.permissionAnalyticsDescription, - textAlign: TextAlign.center, - style: theme.coreTextTheme.bodyNormal, - ), - const Spacer(), - ], + childBuilderWithViewModel: (context, viewModel, theme, localization) => BaseScreen( + showHeader: false, + children: [ + Expanded( + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Spacer(), + Expanded( + flex: 5, + child: SvgPicture.asset( + ThemeAssets.analyticsImage, + alignment: Alignment.center, + fit: BoxFit.scaleDown, ), ), - ), - const SizedBox(height: 8), - FlutterTemplateButton( - text: localization.permissionButtonAccept, - onClick: viewModel.onAcceptClicked, - ), - const SizedBox(height: 8), - FlutterTemplateButton.text( - text: localization.permissionButtonMoreInfo, - onClick: viewModel.onMoreInfoClicked, - ), - ], + const Spacer(), + const SizedBox(height: 32), + Text( + localization.permissionAnalyticsTitle, + style: theme.text.titleNormal, + ), + const SizedBox(height: 16), + Text( + localization.permissionAnalyticsDescription, + textAlign: TextAlign.center, + style: theme.text.bodyNormal, + ), + const Spacer(), + ], + ), ), ), - ), + const SizedBox(height: 8), + FlutterTemplateButton( + text: localization.permissionButtonAccept, + onClick: viewModel.onAcceptClicked, + ), + const SizedBox(height: 8), + FlutterTemplateButton.text( + text: localization.permissionButtonMoreInfo, + onClick: viewModel.onMoreInfoClicked, + ), + ], ), ); } diff --git a/lib/screen/splash/splash_screen.dart b/lib/screen/splash/splash_screen.dart index 7e44af58..757b63bd 100644 --- a/lib/screen/splash/splash_screen.dart +++ b/lib/screen/splash/splash_screen.dart @@ -25,7 +25,7 @@ class SplashScreenState extends State { consumerWithThemeAndLocalization: (context, viewModel, child, theme, localization) => StatusBar.animated( isDarkStyle: theme.isDarkTheme, child: Scaffold( - backgroundColor: theme.colorsTheme.primary, + backgroundColor: theme.primary, body: const Center( child: FlutterTemplateProgressIndicator.light(), ), diff --git a/lib/screen/theme_mode/theme_mode_selector.dart b/lib/screen/theme_mode/theme_mode_selector.dart index d0922554..bc77f2da 100644 --- a/lib/screen/theme_mode/theme_mode_selector.dart +++ b/lib/screen/theme_mode/theme_mode_selector.dart @@ -1,10 +1,9 @@ import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_navigation_generator_annotations/flutter_navigation_generator_annotations.dart'; import 'package:flutter_template/di/injectable.dart'; import 'package:flutter_template/viewmodel/debug/debug_theme_selector_viewmodel.dart'; import 'package:flutter_template/widget/debug/selector_item.dart'; -import 'package:flutter_template/widget/general/styled/flutter_template_back_button.dart'; +import 'package:flutter_template/widget/general/base_screen/base_screen.dart'; import 'package:flutter_template/widget/provider/provider_widget.dart'; @flutterRoute @@ -21,33 +20,28 @@ class ThemeModeSelectorScreenState extends State { Widget build(BuildContext context) { return ProviderWidget( create: getIt.call, - childBuilderWithViewModel: (context, viewModel, theme, localization) => Scaffold( - backgroundColor: theme.colorsTheme.background, - appBar: AppBar( - systemOverlayStyle: SystemUiOverlayStyle.light, - leading: FlutterTemplateBackButton.light(onClick: viewModel.onBackClicked), - title: const Text('Select a theme mode'), - backgroundColor: theme.colorsTheme.primary, - ), - body: ListView( - children: [ - SelectorItem( - title: localization.generalLabelSystemDefault, - onClick: () => viewModel.updateThemeMode(ThemeMode.system), - selected: viewModel.themeMode == ThemeMode.system, - ), - SelectorItem( - title: localization.themeModeLabelLight, - onClick: () => viewModel.updateThemeMode(ThemeMode.light), - selected: viewModel.themeMode == ThemeMode.light, - ), - SelectorItem( - title: localization.themeModeLabelDark, - onClick: () => viewModel.updateThemeMode(ThemeMode.dark), - selected: viewModel.themeMode == ThemeMode.dark, - ), - ], - ), + childBuilderWithViewModel: (context, viewModel, theme, localization) => BaseScreen( + title: 'Select a theme mode', + isScrollable: true, + children: [ + SelectorItem( + title: localization.generalLabelSystemDefault, + onClick: () => viewModel.updateThemeMode(ThemeMode.system), + selected: viewModel.themeMode == ThemeMode.system, + ), + const SizedBox(height: 8), + SelectorItem( + title: localization.themeModeLabelLight, + onClick: () => viewModel.updateThemeMode(ThemeMode.light), + selected: viewModel.themeMode == ThemeMode.light, + ), + const SizedBox(height: 8), + SelectorItem( + title: localization.themeModeLabelDark, + onClick: () => viewModel.updateThemeMode(ThemeMode.dark), + selected: viewModel.themeMode == ThemeMode.dark, + ), + ], ), ); } diff --git a/lib/screen/todo/todo_add/todo_add_screen.dart b/lib/screen/todo/todo_add/todo_add_screen.dart index e760b898..532ded82 100644 --- a/lib/screen/todo/todo_add/todo_add_screen.dart +++ b/lib/screen/todo/todo_add/todo_add_screen.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_navigation_generator_annotations/flutter_navigation_generator_annotations.dart'; import 'package:flutter_template/di/injectable.dart'; -import 'package:flutter_template/styles/theme_dimens.dart'; import 'package:flutter_template/viewmodel/todo/todo_add/todo_add_viewmodel.dart'; import 'package:flutter_template/widget/general/styled/flutter_template_back_button.dart'; import 'package:flutter_template/widget/general/styled/flutter_template_button.dart'; @@ -25,27 +24,27 @@ class TodoAddScreenState extends State { return ProviderWidget( create: getIt.call, childBuilderWithViewModel: (context, viewModel, theme, localization) => Scaffold( - backgroundColor: theme.colorsTheme.background, + backgroundColor: theme.background, appBar: AppBar( systemOverlayStyle: SystemUiOverlayStyle.light, leading: FlutterTemplateBackButton.light( onClick: viewModel.onBackClicked, ), title: Text(localization.todoAddTitle), - backgroundColor: theme.colorsTheme.primary, + backgroundColor: theme.primary, ), body: ScrollConfiguration( behavior: ScrollWhenNeededBehavior(), child: Scrollbar( child: ListView( physics: ScrollWhenNeededPhysics(targetPlatform: Theme.of(context).platform), - padding: const EdgeInsets.all(ThemeDimens.padding16), + padding: const EdgeInsets.all(16), children: [ FlutterTemplateInputField( hint: localization.todoAddInputHint, onChanged: viewModel.onTodoChanged, ), - Container(height: ThemeDimens.padding16), + Container(height: 16), FlutterTemplateButton( text: localization.generalLabelSave, isEnabled: viewModel.isSaveEnabled, diff --git a/lib/screen/todo/todo_list/todo_list_screen.dart b/lib/screen/todo/todo_list/todo_list_screen.dart index cb34a475..6ec6a974 100644 --- a/lib/screen/todo/todo_list/todo_list_screen.dart +++ b/lib/screen/todo/todo_list/todo_list_screen.dart @@ -1,16 +1,16 @@ import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_template/di/injectable.dart'; import 'package:flutter_template/model/webservice/todo/todo.dart'; import 'package:flutter_template/styles/theme_assets.dart'; -import 'package:flutter_template/styles/theme_dimens.dart'; +import 'package:flutter_template/styles/theme_data.dart'; import 'package:flutter_template/util/keys.dart'; import 'package:flutter_template/viewmodel/todo/todo_list/todo_list_viewmodel.dart'; import 'package:flutter_template/widget/general/action/action_item.dart'; +import 'package:flutter_template/widget/general/base_screen/base_screen.dart'; import 'package:flutter_template/widget/general/styled/flutter_template_progress_indicator.dart'; +import 'package:flutter_template/widget/general/svg_icon.dart'; import 'package:flutter_template/widget/provider/provider_widget.dart'; import 'package:flutter_template/widget/todo/todo_row_item.dart'; -import 'package:icapps_architecture/icapps_architecture.dart'; class TodoListScreen extends StatefulWidget { const TodoListScreen({super.key}); @@ -27,36 +27,31 @@ class TodoListScreenState extends State { create: () => getIt()..init(), consumerWithThemeAndLocalization: (context, viewModel, child, theme, localization) { final errorKey = viewModel.errorKey; - return Scaffold( - backgroundColor: theme.colorsTheme.background, - appBar: AppBar( - title: Text(localization.todoTitle), - systemOverlayStyle: SystemUiOverlayStyle.light, - centerTitle: context.isIOSTheme, - backgroundColor: theme.colorsTheme.primary, - actions: [ - ActionItem( - key: Keys.downloadAction, - svgAsset: ThemeAssets.downloadIcon(context), - onClick: viewModel.onDownloadClicked, - color: theme.colorsTheme.appBarAction, - ), - ActionItem( - key: Keys.addAction, - svgAsset: ThemeAssets.addIcon(context), - onClick: viewModel.onAddClicked, - color: theme.colorsTheme.appBarAction, - ), - ], - ), - body: Builder( + return BaseScreen.child( + padding: EdgeInsets.zero, + title: localization.todoTitle, + actions: [ + ActionItem( + key: Keys.downloadAction, + svgAsset: ThemeAssets.downloadIcon, + onClick: viewModel.onDownloadClicked, + color: theme.appBarAction, + ), + ActionItem( + key: Keys.addAction, + svgAsset: ThemeAssets.addIcon, + onClick: viewModel.onAddClicked, + color: theme.appBarAction, + ), + ], + child: Builder( builder: (context) { if (viewModel.isLoading) return Center(child: FlutterTemplateProgressIndicator(dark: theme.isLightTheme)); if (errorKey != null) { return Center( child: Text( localization.getTranslation(errorKey), - style: theme.coreTextTheme.bodyNormal.copyWith(color: theme.colorsTheme.errorText), + style: theme.errorText.bodyNormal, ), ); } @@ -70,11 +65,28 @@ class TodoListScreenState extends State { if (data.isEmpty) { return Center( child: Padding( - padding: const EdgeInsets.all(ThemeDimens.padding32), - child: Text( - localization.todoEmptyState, - textAlign: TextAlign.center, - style: theme.coreTextTheme.bodyNormal, + padding: const EdgeInsets.all(32), + child: Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: theme.fillInformative, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SvgIcon( + svgAsset: ThemeAssets.fileIcon, + color: theme.accent, + ), + const SizedBox(height: 8), + Text( + localization.todoEmptyState, + textAlign: TextAlign.center, + style: theme.text.bodyNormal, + ), + ], + ), ), ), ); @@ -90,10 +102,10 @@ class TodoListScreenState extends State { ); }, separatorBuilder: (context, index) => Padding( - padding: const EdgeInsets.symmetric(horizontal: ThemeDimens.padding16), + padding: const EdgeInsets.symmetric(horizontal: 16), child: Container( height: 1, - color: theme.colorsTheme.primary.withOpacity(0.1), + color: theme.primary.withOpacity(0.1), ), ), ); diff --git a/lib/styles/theme_assets.dart b/lib/styles/theme_assets.dart index f87172c9..3e4a1c6c 100644 --- a/lib/styles/theme_assets.dart +++ b/lib/styles/theme_assets.dart @@ -1,33 +1,43 @@ -import 'package:flutter/material.dart'; -import 'package:icapps_architecture/icapps_architecture.dart'; - class ThemeAssets { ThemeAssets._(); - static String _getIcon(BuildContext context, String name) { - if (context.isIOSTheme) { - return 'assets/images/icons/ios/$name.svg'; - } - return 'assets/images/icons/android/$name.svg'; - } + static const _assetPrefix = 'assets'; + static const _imageAssetPrefix = '$_assetPrefix/images'; + static const _iconsAssetPrefix = '$_imageAssetPrefix/icons'; + + static const addIcon = '$_iconsAssetPrefix/add.svg'; + + static const downloadIcon = '$_iconsAssetPrefix/download.svg'; + + static const animationIcon = '$_iconsAssetPrefix/animation.svg'; + + static const arrowLeftIcon = '$_iconsAssetPrefix/arrow_left.svg'; + + static const checkIcon = '$_iconsAssetPrefix/check.svg'; + + static const chevronRightIcon = '$_iconsAssetPrefix/chevron_right.svg'; + + static const fileIcon = '$_iconsAssetPrefix/file.svg'; + + static const licenseIcon = '$_iconsAssetPrefix/license.svg'; + + static const settingsIconActive = '$_iconsAssetPrefix/settings_active.svg'; - static String _getImage(BuildContext context, String name) { - return 'assets/images/$name.svg'; - } + static const settingsIconInactive = '$_iconsAssetPrefix/settings_inactive.svg'; - static String listIcon(BuildContext context) => _getIcon(context, 'list'); + static const themeIcon = '$_iconsAssetPrefix/theme.svg'; - static String settingsIcon(BuildContext context) => _getIcon(context, 'settings'); + static const todoIconActive = '$_iconsAssetPrefix/todo_active.svg'; - static String addIcon(BuildContext context) => _getIcon(context, 'add'); + static const todoIconInactive = '$_iconsAssetPrefix/todo_inactive.svg'; - static String downloadIcon(BuildContext context) => _getIcon(context, 'download'); + static const translationsIcon = '$_iconsAssetPrefix/translations.svg'; - static String closeIcon(BuildContext context) => _getIcon(context, 'close'); + static const boxIcon = '$_iconsAssetPrefix/box.svg'; - static String backIcon(BuildContext context) => _getIcon(context, 'back'); + static const listIcon = '$_iconsAssetPrefix/list.svg'; - static String doneIcon(BuildContext context) => _getIcon(context, 'done'); + static const lockOpenIcon = '$_iconsAssetPrefix/lock_open.svg'; - static String analyticsImage(BuildContext context) => _getImage(context, 'analytics'); + static const analyticsImage = '$_imageAssetPrefix/analytics.svg'; } diff --git a/lib/styles/theme_colors.dart b/lib/styles/theme_colors.dart index 215bfe9b..e8cb3d4a 100644 --- a/lib/styles/theme_colors.dart +++ b/lib/styles/theme_colors.dart @@ -6,17 +6,20 @@ class ThemeColors { static const primary = Color(0xFF002548); static const primaryDark = Color(0xFF001223); static const accent = Color(0xFF009AC7); - static const accentDark = Color(0xFF0080A8); + static const lightAccent = Color(0xFFECF5FE); + static const darkAccent = Color(0xFF005780); + static const darkBackground = Color(0xFF1B4162); static const white = Color(0xFFFFFFFF); static const white20 = Color(0x33FFFFFF); static const white50 = Color(0x80FFFFFF); static const black = Color(0xFF000000); static const grey = Color(0xB3000000); //black 70% + static const fadedGrey = Color(0xFF6C7B89); static const mediumGrey = Color(0x80000000); //black 50% - static const lightGrey = Color(0x33000000); //black 20% - static const backgroundGrey = Color(0xFFF1F2F3); + static const lightGrey = Color(0xFFDDE1E4); + static const backgroundGrey = Color(0xFFF9FAFC); static const disabledGrey = Color(0xFFE6E6E6); - static const shadow = Color(0x1e000000); //black 12% + static const shadow = Color.fromARGB(255, 0, 0, 0); //black 12% static const error = Color(0xFFE30000); static const success = Color(0xFF3E9103); -} +} \ No newline at end of file diff --git a/lib/styles/theme_data.dart b/lib/styles/theme_data.dart index e9d5bcd1..7c3ec552 100644 --- a/lib/styles/theme_data.dart +++ b/lib/styles/theme_data.dart @@ -81,12 +81,16 @@ class FlutterTemplateTextTheme { }); } -class FlutterTemplateTextThemeExceptions { - const FlutterTemplateTextThemeExceptions(); +enum FlutterTemplateThemeStyle { + dark, + light, } -class FlutterTemplateColorsTheme { +class FlutterTemplateTheme { + final bool isDarkTheme; final Color text; + final Color lightText; + final Color fadedText; final Color inverseText; final Color errorText; final Color buttonTextDisabled; @@ -107,6 +111,9 @@ class FlutterTemplateColorsTheme { final Color buttonText; final Color inverseButtonText; final Color textButtonText; + final Color fillInformative; + final Color cardBackground; + final Color switchBackground; final Color bottomNavbarBackground; final Color bottomNavbarItemActive; @@ -121,16 +128,101 @@ class FlutterTemplateColorsTheme { final Color debugTitleBackground; - const FlutterTemplateColorsTheme({ + bool get isLightTheme => !isDarkTheme; + + static final _instanceDark = FlutterTemplateTheme._( + isDarkTheme: true, + text: ThemeColors.white, + fadedText: ThemeColors.lightGrey, + inverseText: ThemeColors.black, + errorText: ThemeColors.error, + primary: ThemeColors.primary, + accent: ThemeColors.accent, + secondary: ThemeColors.white, + background: ThemeColors.primary, + permissionScreenBackground: ThemeColors.primary, + inverseBackground: ThemeColors.white, + disabled: ThemeColors.disabledGrey, + icon: ThemeColors.white, + appBarAction: ThemeColors.white, + inverseIcon: ThemeColors.black, + progressIndicator: ThemeColors.primary, + inverseProgressIndicator: ThemeColors.white, + shadow: ThemeColors.shadow, + buttonText: ThemeColors.primary, + inverseButtonText: ThemeColors.white, + buttonTextDisabled: ThemeColors.lightGrey, + buttonColor: ThemeColors.accent, + textButtonText: ThemeColors.white, + bottomNavbarBackground: ThemeColors.darkBackground, + bottomNavbarItemActive: ThemeColors.white, + bottomNavbarItemInactive: ThemeColors.white50, + inputFieldFill: ThemeColors.black, + inputFieldHint: ThemeColors.white50, + inputFieldBorderEnabled: ThemeColors.white50, + inputFieldBorderFocused: ThemeColors.white, + inputFieldBorderIdle: ThemeColors.white50, + inputFieldCursor: ThemeColors.accent, + debugTitleBackground: ThemeColors.white20, + fillInformative: ThemeColors.darkAccent, + cardBackground: ThemeColors.darkBackground, + lightText: ThemeColors.white, + switchBackground: ThemeColors.fadedGrey, + ); + + static final _instanceLight = FlutterTemplateTheme._( + isDarkTheme: false, + text: ThemeColors.primary, + fadedText: ThemeColors.fadedGrey, + inverseText: ThemeColors.white, + errorText: ThemeColors.error, + primary: ThemeColors.primary, + accent: ThemeColors.accent, + secondary: ThemeColors.black, + background: ThemeColors.backgroundGrey, + permissionScreenBackground: ThemeColors.white, + inverseBackground: ThemeColors.white, + inputFieldFill: ThemeColors.white, + inputFieldHint: ThemeColors.mediumGrey, + disabled: ThemeColors.disabledGrey, + icon: ThemeColors.primary, + appBarAction: ThemeColors.primary, + inverseIcon: ThemeColors.black, + progressIndicator: ThemeColors.primary, + inverseProgressIndicator: ThemeColors.white, + shadow: ThemeColors.shadow, + buttonText: ThemeColors.white, + inverseButtonText: ThemeColors.primary, + buttonTextDisabled: ThemeColors.lightGrey, + buttonColor: ThemeColors.primary, + textButtonText: ThemeColors.primary, + bottomNavbarBackground: ThemeColors.white, + bottomNavbarItemActive: ThemeColors.primary, + bottomNavbarItemInactive: ThemeColors.mediumGrey, + inputFieldBorderEnabled: ThemeColors.mediumGrey, + inputFieldBorderFocused: ThemeColors.primary, + inputFieldBorderIdle: ThemeColors.mediumGrey, + inputFieldCursor: ThemeColors.accent, + debugTitleBackground: ThemeColors.lightGrey, + fillInformative: ThemeColors.lightAccent, + cardBackground: ThemeColors.white, + lightText: ThemeColors.white, + switchBackground: ThemeColors.disabledGrey, + ); + + FlutterTemplateTheme._({ + required this.isDarkTheme, + required this.text, + required this.fadedText, + required this.inverseText, + required this.errorText, + required this.buttonTextDisabled, required this.primary, required this.secondary, required this.accent, required this.background, required this.permissionScreenBackground, required this.inverseBackground, - required this.text, - required this.inverseText, - required this.errorText, required this.disabled, required this.icon, required this.appBarAction, @@ -141,7 +233,6 @@ class FlutterTemplateColorsTheme { required this.buttonColor, required this.buttonText, required this.inverseButtonText, - required this.buttonTextDisabled, required this.textButtonText, required this.bottomNavbarBackground, required this.bottomNavbarItemActive, @@ -153,136 +244,10 @@ class FlutterTemplateColorsTheme { required this.inputFieldBorderIdle, required this.inputFieldCursor, required this.debugTitleBackground, - }); -} - -enum FlutterTemplateThemeStyle { - dark, - light, -} - -class FlutterTemplateTheme { - final FlutterTemplateTextTheme coreTextTheme; - final FlutterTemplateTextTheme inverseCoreTextTheme; - final FlutterTemplateTextTheme accentTextTheme; - final FlutterTemplateTextTheme disabledTextTheme; - final FlutterTemplateTextThemeExceptions exceptionsTextTheme; - final FlutterTemplateColorsTheme colorsTheme; - final bool isDarkTheme; - - bool get isLightTheme => !isDarkTheme; - - static final _instanceDark = _fromColorTheme( - isDarkTheme: true, - colorTheme: const FlutterTemplateColorsTheme( - text: ThemeColors.white, - inverseText: ThemeColors.black, - errorText: ThemeColors.error, - primary: ThemeColors.primary, - accent: ThemeColors.accent, - secondary: ThemeColors.white, - background: ThemeColors.black, - permissionScreenBackground: ThemeColors.primary, - inverseBackground: ThemeColors.white, - disabled: ThemeColors.disabledGrey, - icon: ThemeColors.white, - appBarAction: ThemeColors.white, - inverseIcon: ThemeColors.black, - progressIndicator: ThemeColors.primary, - inverseProgressIndicator: ThemeColors.white, - shadow: ThemeColors.shadow, - buttonText: ThemeColors.primary, - inverseButtonText: ThemeColors.white, - buttonTextDisabled: ThemeColors.lightGrey, - buttonColor: ThemeColors.white, - textButtonText: ThemeColors.white, - bottomNavbarBackground: ThemeColors.primary, - bottomNavbarItemActive: ThemeColors.white, - bottomNavbarItemInactive: ThemeColors.white50, - inputFieldFill: ThemeColors.black, - inputFieldHint: ThemeColors.white50, - inputFieldBorderEnabled: ThemeColors.white50, - inputFieldBorderFocused: ThemeColors.white, - inputFieldBorderIdle: ThemeColors.white50, - inputFieldCursor: ThemeColors.accent, - debugTitleBackground: ThemeColors.white20, - ), - ); - - static final _instanceLight = _fromColorTheme( - isDarkTheme: false, - colorTheme: const FlutterTemplateColorsTheme( - text: ThemeColors.black, - inverseText: ThemeColors.white, - errorText: ThemeColors.error, - primary: ThemeColors.primary, - accent: ThemeColors.accent, - secondary: ThemeColors.black, - background: ThemeColors.white, - permissionScreenBackground: ThemeColors.white, - inverseBackground: ThemeColors.white, - inputFieldFill: ThemeColors.white, - inputFieldHint: ThemeColors.mediumGrey, - disabled: ThemeColors.disabledGrey, - icon: ThemeColors.primary, - appBarAction: ThemeColors.white, - inverseIcon: ThemeColors.black, - progressIndicator: ThemeColors.primary, - inverseProgressIndicator: ThemeColors.white, - shadow: ThemeColors.shadow, - buttonText: ThemeColors.white, - inverseButtonText: ThemeColors.primary, - buttonTextDisabled: ThemeColors.lightGrey, - buttonColor: ThemeColors.primary, - textButtonText: ThemeColors.primary, - bottomNavbarBackground: ThemeColors.white, - bottomNavbarItemActive: ThemeColors.primary, - bottomNavbarItemInactive: ThemeColors.mediumGrey, - inputFieldBorderEnabled: ThemeColors.mediumGrey, - inputFieldBorderFocused: ThemeColors.primary, - inputFieldBorderIdle: ThemeColors.mediumGrey, - inputFieldCursor: ThemeColors.accent, - debugTitleBackground: ThemeColors.lightGrey, - ), - ); - - static FlutterTemplateTheme _fromColorTheme({ - required FlutterTemplateColorsTheme colorTheme, - required bool isDarkTheme, - }) => - FlutterTemplateTheme._( - isDarkTheme: isDarkTheme, - colorsTheme: colorTheme, - disabledTextTheme: _getTextThemeFromColor(colorTheme.disabled), - coreTextTheme: _getTextThemeFromColor(colorTheme.text), - inverseCoreTextTheme: _getTextThemeFromColor(colorTheme.inverseText), - accentTextTheme: _getTextThemeFromColor(colorTheme.accent), - exceptionsTextTheme: const FlutterTemplateTextThemeExceptions(), - ); - - static FlutterTemplateTextTheme _getTextThemeFromColor(Color color) => FlutterTemplateTextTheme( - titleHuge: TextStyle(fontSize: 40, color: color, fontFamily: ThemeFonts.title, height: 1.2), - titleBig: TextStyle(fontSize: 30, color: color, fontFamily: ThemeFonts.title, height: 1.2), - titleNormal: TextStyle(fontSize: 24, color: color, fontFamily: ThemeFonts.title), - titleSmall: TextStyle(fontSize: 18, color: color, fontFamily: ThemeFonts.title), - titleListItem: TextStyle(fontSize: 18, color: color, fontFamily: ThemeFonts.title, fontWeight: FontWeight.bold), - labelButtonBig: TextStyle(fontSize: 16, color: color, fontFamily: ThemeFonts.button, fontWeight: FontWeight.bold), - labelButtonSmall: TextStyle(fontSize: 14, color: color, fontFamily: ThemeFonts.button, fontWeight: FontWeight.bold), - bodyBig: TextStyle(fontSize: 18, color: color, fontFamily: ThemeFonts.body), - bodyNormal: TextStyle(fontSize: 16, color: color, fontFamily: ThemeFonts.body), - bodySmall: TextStyle(fontSize: 14, color: color, fontFamily: ThemeFonts.body), - bodyUltraSmall: TextStyle(fontSize: 12, color: color, fontFamily: ThemeFonts.body), - infoBodySubHeader: TextStyle(fontSize: 14, color: color, fontFamily: ThemeFonts.body, fontWeight: FontWeight.w600), - ); - - const FlutterTemplateTheme._({ - required this.coreTextTheme, - required this.inverseCoreTextTheme, - required this.accentTextTheme, - required this.disabledTextTheme, - required this.exceptionsTextTheme, - required this.colorsTheme, - required this.isDarkTheme, + required this.fillInformative, + required this.cardBackground, + required this.lightText, + required this.switchBackground, }); static FlutterTemplateTheme of(BuildContext context, {bool forceDark = false, bool forceLight = false}) { @@ -303,3 +268,64 @@ class FlutterTemplateTheme { return _instanceLight; } } + +extension TextThemeExtension on Color { + TextStyle get titleHuge => TextStyle(fontSize: 40, color: this, fontFamily: ThemeFonts.title, height: 1.2); + + TextStyle get titleBig => TextStyle(fontSize: 30, color: this, fontFamily: ThemeFonts.title, height: 1.2); + + TextStyle get titleNormal => TextStyle(fontSize: 24, color: this, fontFamily: ThemeFonts.title); + + TextStyle get titleSmall => TextStyle(fontSize: 18, color: this, fontFamily: ThemeFonts.title); + + TextStyle get titleListItem => TextStyle(fontSize: 18, color: this, fontFamily: ThemeFonts.title, fontWeight: FontWeight.bold); + + TextStyle get labelButtonBig => TextStyle(fontSize: 16, color: this, fontFamily: ThemeFonts.button, fontWeight: FontWeight.bold); + + TextStyle get labelButtonSmall => TextStyle(fontSize: 14, color: this, fontFamily: ThemeFonts.button, fontWeight: FontWeight.bold); + + TextStyle get bodyBig => TextStyle(fontSize: 18, color: this, fontFamily: ThemeFonts.body); + + TextStyle get bodyNormal => TextStyle(fontSize: 16, color: this, fontFamily: ThemeFonts.body); + + TextStyle get bodySmall => TextStyle(fontSize: 14, color: this, fontFamily: ThemeFonts.body); + + TextStyle get bodyUltraSmall => TextStyle(fontSize: 12, color: this, fontFamily: ThemeFonts.body); + + TextStyle get infoBodySubHeader => TextStyle(fontSize: 14, color: this, fontFamily: ThemeFonts.body, fontWeight: FontWeight.w600); +} + +extension TextStyleExtension on TextStyle { + TextStyle get medium => copyWith(fontWeight: FontWeight.w400); + + TextStyle get strong => copyWith(fontWeight: FontWeight.w600); + + TextStyle get black => copyWith(fontWeight: FontWeight.w900); + + TextStyle get underLine => copyWith(decoration: TextDecoration.underline); + + TextStyle get italic => copyWith(fontStyle: FontStyle.italic); +} + +extension ShadowsExtension on Color { + List get bottomNavShadow => [ + BoxShadow( + offset: const Offset(0, -29), + spreadRadius: 0, + blurRadius: 29, + color: withOpacity(0.02), + ), + BoxShadow( + offset: const Offset(0, -65), + spreadRadius: 0, + blurRadius: 39, + color: withOpacity(0.01), + ), + BoxShadow( + offset: const Offset(0, -115), + spreadRadius: 0, + blurRadius: 46, + color: withOpacity(0.01), + ), + ]; +} diff --git a/lib/styles/theme_dimens.dart b/lib/styles/theme_dimens.dart index ecb8c907..d0585d34 100644 --- a/lib/styles/theme_dimens.dart +++ b/lib/styles/theme_dimens.dart @@ -1,25 +1,16 @@ +import 'package:flutter/material.dart'; + class ThemeDimens { ThemeDimens._(); - static const double padding4 = 4; - static const double padding8 = 8; - static const double padding12 = 12; - static const double padding16 = 16; - static const double padding24 = 24; - static const double padding32 = 32; - static const double padding40 = 40; - static const double padding48 = 48; - static const double padding56 = 56; - static const double padding64 = 64; - static const double padding72 = 72; - static const double padding80 = 80; - static const double padding96 = 96; - static const double padding128 = 128; static const double cardBorderRadius = 5; static const double enabledOpacity = 1; static const double disabledOpacity = 0.24; + static const double smallIconSize = 20; static const double iconSize = 24; static const double largeIcon = 32; + + static BorderRadius circularBorderRadius = BorderRadius.circular(9999); } diff --git a/lib/util/api/dummy_api_util.dart b/lib/util/api/dummy_api_util.dart index 08bcd69d..43b932e7 100644 --- a/lib/util/api/dummy_api_util.dart +++ b/lib/util/api/dummy_api_util.dart @@ -2,7 +2,7 @@ import 'dart:convert'; import 'package:flutter/services.dart'; import 'package:flutter_template/util/env/flavor_config.dart'; -import 'package:icapps_architecture/icapps_architecture.dart'; +import 'package:flutter_template/util/logging/flutter_template_logger.dart'; class DummyApiUtil { static const _apiAssetPath = 'assets/api'; @@ -13,13 +13,13 @@ class DummyApiUtil { } final path = '$_apiAssetPath/$url.json'; try { - staticLogger.debug('---------------> GET - url: file://$path'); + FlutterTemplateLogger.logDebug('---------------> GET - url: file://$path'); final jsonString = await rootBundle.loadString(path); - staticLogger.debug('<--------------- GET - url: file://$path - statucode: 200'); + FlutterTemplateLogger.logDebug('<--------------- GET - url: file://$path - statucode: 200'); return json.decode(jsonString) as T; } catch (e, stack) { - staticLogger.error( + FlutterTemplateLogger.logError( '<--------------- GET - url: $path - statucode: 404', error: e, stackTrace: stack, diff --git a/lib/util/extension/date_time_extension.dart b/lib/util/extension/date_time_extension.dart new file mode 100644 index 00000000..9e20239b --- /dev/null +++ b/lib/util/extension/date_time_extension.dart @@ -0,0 +1,21 @@ +import 'package:flutter/widgets.dart'; +import 'package:flutter_template/di/injectable.dart'; +import 'package:flutter_template/navigator/main_navigator.dart'; +import 'package:flutter_template/util/locale/localization.dart'; +import 'package:intl/intl.dart'; + +extension DateTimeExtentions on DateTime { + BuildContext get _context => getIt().context; + + String get shortDateFormat => _formatDateWithFormatString(formatString: 'dd/MM/yyyy'); + + String get dottedShortDateFormat => _formatDateWithFormatString(formatString: 'dd.MM.yyyy'); + + String get shortDateWeekdayFormat => _formatDateWithFormatString(formatString: 'EEEE dd/MM/yyyy'); + + String _formatDateWithFormatString({required String formatString}) { + final languageTag = Localization.of(_context).locale?.languageCode; + final dateFormat = DateFormat(formatString, languageTag); + return dateFormat.format(toLocal()); + } +} diff --git a/lib/util/inspector/local_storage_inspector.dart b/lib/util/inspector/local_storage_inspector.dart index e6389cbb..1c462bc3 100644 --- a/lib/util/inspector/local_storage_inspector.dart +++ b/lib/util/inspector/local_storage_inspector.dart @@ -4,7 +4,7 @@ import 'package:file_local_storage_inspector/file_local_storage_inspector.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_template/di/injectable.dart'; -import 'package:icapps_architecture/icapps_architecture.dart'; +import 'package:flutter_template/util/logging/flutter_template_logger.dart'; import 'package:path_provider/path_provider.dart'; import 'package:preferences_local_storage_inspector/preferences_local_storage_inspector.dart'; import 'package:secure_storage_local_storage_inspector/secure_storage_local_storage_inspector.dart'; @@ -36,7 +36,7 @@ Future _initLocalStorageInspector( await configureServers(driver); const paused = bool.fromEnvironment('storage_inspector_wait'); - staticLogger.d('Starting local storage inspector. Waiting for unpause? $paused'); + FlutterTemplateLogger.logDebug('Starting local storage inspector. Waiting for unpause? $paused'); await driver.start(paused: paused); } diff --git a/lib/util/inspector/niddler.dart b/lib/util/inspector/niddler.dart index aa9a5244..1a71acda 100644 --- a/lib/util/inspector/niddler.dart +++ b/lib/util/inspector/niddler.dart @@ -1,4 +1,4 @@ -import 'package:icapps_architecture/icapps_architecture.dart'; +import 'package:flutter_template/util/logging/flutter_template_logger.dart'; import 'package:niddler_dart/niddler_dart.dart'; Future initNiddler() async { @@ -11,12 +11,12 @@ Future initNiddler() async { final niddler = niddlerBuilder.build(); const debugger = bool.fromEnvironment('niddler_wait'); - staticLogger.d('Starting niddler. Waiting for debugger? $debugger'); + FlutterTemplateLogger.logDebug('Starting niddler. Waiting for debugger? $debugger'); await niddler.start(waitForDebugger: debugger); niddler.install(); - staticLogger.d('Niddler is running'); + FlutterTemplateLogger.logDebug('Niddler is running'); return niddler; } diff --git a/lib/util/interceptor/network_error_interceptor.dart b/lib/util/interceptor/network_error_interceptor.dart index 4f297533..f70c3571 100644 --- a/lib/util/interceptor/network_error_interceptor.dart +++ b/lib/util/interceptor/network_error_interceptor.dart @@ -6,6 +6,7 @@ import 'package:flutter_template/model/exceptions/general_network_error.dart'; import 'package:flutter_template/model/exceptions/internal_server_error.dart'; import 'package:flutter_template/model/exceptions/no_internet_error.dart'; import 'package:flutter_template/model/exceptions/un_authorized_error.dart'; +import 'package:flutter_template/util/logging/flutter_template_logger.dart'; import 'package:icapps_architecture/icapps_architecture.dart'; import 'package:injectable/injectable.dart'; @@ -42,7 +43,7 @@ class NetworkErrorInterceptor extends SimpleInterceptor { return GeneralNetworkError(error); } } catch (e, stack) { - logger.error('Failed to get correct error', error: e, stackTrace: stack); + FlutterTemplateLogger.logError('Failed to get correct error', error: e, stackTrace: stack); return CodeError(); } } diff --git a/lib/util/interceptor/network_log_interceptor.dart b/lib/util/interceptor/network_log_interceptor.dart index 8099cc66..a4f8b24d 100644 --- a/lib/util/interceptor/network_log_interceptor.dart +++ b/lib/util/interceptor/network_log_interceptor.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:dio/dio.dart'; import 'package:flutter_template/model/exceptions/general_network_error.dart'; +import 'package:flutter_template/util/logging/flutter_template_logger.dart'; import 'package:icapps_architecture/icapps_architecture.dart'; import 'package:injectable/injectable.dart'; @@ -9,13 +10,13 @@ import 'package:injectable/injectable.dart'; class NetworkLogInterceptor extends SimpleInterceptor { @override Future onRequest(RequestOptions options) async { - logger.logNetworkRequest(options); + FlutterTemplateLogger.logNetworkRequest(options); return super.onRequest(options); } @override Future onResponse(Response response) async { - logger.logNetworkResponse(response); + FlutterTemplateLogger.logNetworkResponse(response); return super.onResponse(response); } @@ -23,13 +24,13 @@ class NetworkLogInterceptor extends SimpleInterceptor { Future onError(DioException error) async { final response = error.response; if (response != null && response.statusCode == HttpStatus.notModified) { - logger.logNetworkResponse(response); + FlutterTemplateLogger.logNetworkResponse(response); return super.onError(error); } if (error is NetworkError) { - logger.logNetworkError(error); + FlutterTemplateLogger.logNetworkError(error); } else { - logger.logNetworkError(GeneralNetworkError(error)); + FlutterTemplateLogger.logNetworkError(GeneralNetworkError(error)); } return super.onError(error); } diff --git a/lib/util/interceptor/network_refresh_interceptor.dart b/lib/util/interceptor/network_refresh_interceptor.dart index 8d155b88..8cd7e100 100644 --- a/lib/util/interceptor/network_refresh_interceptor.dart +++ b/lib/util/interceptor/network_refresh_interceptor.dart @@ -3,6 +3,7 @@ import 'package:flutter_template/di/injectable.dart'; import 'package:flutter_template/model/exceptions/un_authorized_error.dart'; import 'package:flutter_template/repository/refresh/refresh_repository.dart'; import 'package:flutter_template/repository/secure_storage/auth/auth_storage.dart'; +import 'package:flutter_template/util/logging/flutter_template_logger.dart'; import 'package:icapps_architecture/icapps_architecture.dart'; import 'package:injectable/injectable.dart'; @@ -32,7 +33,7 @@ class NetworkRefreshInterceptor extends SimpleInterceptor { Future onError(DioException error) async { final request = error.requestOptions; if (_excludedPaths.contains(request.path)) { - logger.debug('Network refresh interceptor should not intercept'); + FlutterTemplateLogger.logDebug('Network refresh interceptor should not intercept'); return super.onError(error); } @@ -40,7 +41,7 @@ class NetworkRefreshInterceptor extends SimpleInterceptor { return super.onError(error); } - logger.debug('Refreshing'); + FlutterTemplateLogger.logDebug('Refreshing'); await _refreshRepo.refresh(error); final authorizationHeader = '${AppConstants.protectedAuthenticationHeaderPrefix} ${await _authStorage.getAccessToken()}'; diff --git a/lib/util/logging/flutter_template_logger.dart b/lib/util/logging/flutter_template_logger.dart new file mode 100644 index 00000000..bcbf1f13 --- /dev/null +++ b/lib/util/logging/flutter_template_logger.dart @@ -0,0 +1,48 @@ +import 'package:dio/dio.dart'; +import 'package:firebase_crashlytics/firebase_crashlytics.dart'; +import 'package:flutter_template/di/injectable.dart'; +import 'package:flutter_template/model/exceptions/forbidden_error.dart'; +import 'package:flutter_template/model/exceptions/no_internet_error.dart'; +import 'package:flutter_template/model/exceptions/un_authorized_error.dart'; +import 'package:flutter_template/repository/remote_config/remote_config.dart'; +import 'package:icapps_architecture/icapps_architecture.dart'; + +class FlutterTemplateLogger { + static FirebaseCrashlytics get _firebaseCrashlytics => getIt(); + + FlutterTemplateLogger._(); + + static void logWarning(String message) => staticLogger.warning(message); + + static void logNetworkRequest(RequestOptions request) => staticLogger.logNetworkRequest(request); + + static void logNetworkError(NetworkError error) => staticLogger.logNetworkError(error); + + static void logNetworkResponse(Response response) => staticLogger.logNetworkResponse(response); + + static void logDebug(String message) => staticLogger.debug(message); + + static void logError( + String message, { + bool sendToFirebase = true, + required dynamic error, + required StackTrace? stackTrace, + }) { + staticLogger.error(message, error: error, stackTrace: stackTrace); + _recordToFirebase(message, error: error, stackTrace: stackTrace); + } + + static Future _recordToFirebase( + String message, { + required dynamic error, + required StackTrace? stackTrace, + }) async { + try { + final shouldNotSendError = error is UnAuthorizedError || error is ForbiddenError || error is NoInternetError || isInDebug; + if (shouldNotSendError && !getIt.get().sendBlockedErrorsToFirebase) return; + await _firebaseCrashlytics.recordError(error, stackTrace, reason: message); + } catch (error, trace) { + staticLogger.error('Failed to log to firebase', error: error, stackTrace: trace); + } + } +} diff --git a/lib/util/snackbar/error_util.dart b/lib/util/snackbar/error_util.dart index 809a2751..88e101fc 100644 --- a/lib/util/snackbar/error_util.dart +++ b/lib/util/snackbar/error_util.dart @@ -4,6 +4,7 @@ import 'package:flutter_template/model/snackbar/snackbar_data.dart'; import 'package:flutter_template/navigator/main_navigator.dart'; import 'package:flutter_template/util/env/flavor_config.dart'; import 'package:flutter_template/util/locale/localization_keys.dart'; +import 'package:flutter_template/util/logging/flutter_template_logger.dart'; import 'package:icapps_architecture/icapps_architecture.dart'; import 'package:injectable/injectable.dart'; @@ -40,7 +41,7 @@ class ErrorUtil { } else if (error is LocalizedError) { key = error.getLocalizedKey(); } else { - logger.warning('Caught an error that is not handled by the FlutterTemplateError $error'); + FlutterTemplateLogger.logWarning('Caught an error that is not handled by the FlutterTemplateError $error'); key = LocalizationKeys.errorGeneral; } showErrorWithLocaleKey( diff --git a/lib/viewmodel/debug/debug_platform_selector_viewmodel.dart b/lib/viewmodel/debug/debug_platform_selector_viewmodel.dart index db544081..2d71ee38 100644 --- a/lib/viewmodel/debug/debug_platform_selector_viewmodel.dart +++ b/lib/viewmodel/debug/debug_platform_selector_viewmodel.dart @@ -1,12 +1,26 @@ +import 'package:flutter/foundation.dart'; import 'package:flutter_template/navigator/main_navigator.dart'; +import 'package:flutter_template/viewmodel/global/global_viewmodel.dart'; import 'package:icapps_architecture/icapps_architecture.dart'; import 'package:injectable/injectable.dart'; @injectable class DebugPlatformSelectorViewModel with ChangeNotifierEx { final MainNavigator _navigator; + final GlobalViewModel _globalViewModel; - DebugPlatformSelectorViewModel(this._navigator); + TargetPlatform? get selectedPlatform => _globalViewModel.targetPlatform; + + DebugPlatformSelectorViewModel( + this._globalViewModel, + this._navigator, + ); void onBackClicked() => _navigator.goBack(); + + void setSelectedPlatformToDefault() => _globalViewModel.setSelectedPlatformToDefault(); + + void setSelectedPlatformToAndroid() => _globalViewModel.setSelectedPlatformToAndroid(); + + void setSelectedPlatformToIOS() => _globalViewModel.setSelectedPlatformToIOS(); } diff --git a/lib/viewmodel/debug/debug_viewmodel.dart b/lib/viewmodel/debug/debug_viewmodel.dart index d1c22086..c6a8716a 100644 --- a/lib/viewmodel/debug/debug_viewmodel.dart +++ b/lib/viewmodel/debug/debug_viewmodel.dart @@ -50,4 +50,6 @@ class DebugViewModel with ChangeNotifierEx { void goToAnalyticsPermissionScreen() => _navigator.goToAnalyticsPermissionScreen(); void resetAnalyticsPermission() => _localStorage.updateHasAnalyticsPermission(null); + + void onLogsTapped() => _navigator.goToLogsScreen(); } diff --git a/lib/viewmodel/log_detail/log_detail_viewmodel.dart b/lib/viewmodel/log_detail/log_detail_viewmodel.dart new file mode 100644 index 00000000..6be8b4ac --- /dev/null +++ b/lib/viewmodel/log_detail/log_detail_viewmodel.dart @@ -0,0 +1,40 @@ +import 'package:flutter_template/repository/logging/logging_repository.dart'; +import 'package:icapps_architecture/icapps_architecture.dart'; +import 'package:injectable/injectable.dart'; +import 'package:log_to_secure_file/log_to_secure_file.dart'; + +@injectable +class LogDetailViewModel with ChangeNotifierEx { + late final DateTime _date; + final SecureLogStorage _secureLogStorage; + final LoggingRepository _loggingRepository; + + final List _logs = []; + + bool _isLoading = false; + + List get logs => _logs; + + bool get isLoading => _isLoading; + + LogDetailViewModel( + this._secureLogStorage, + this._loggingRepository, + ); + + Future init(String date) async { + _date = DateTime.parse(date); + _logs.replaceAll(await _secureLogStorage.getLogFromDate(_date)); + if (disposed) return; + notifyListeners(); + } + + Future uploadLog() async { + _isLoading = true; + notifyListeners(); + await _loggingRepository.uploadLog(_date); + _isLoading = false; + if (disposed) return; + notifyListeners(); + } +} diff --git a/lib/viewmodel/login/login_viewmodel.dart b/lib/viewmodel/login/login_viewmodel.dart index b4f5f290..7933fb39 100644 --- a/lib/viewmodel/login/login_viewmodel.dart +++ b/lib/viewmodel/login/login_viewmodel.dart @@ -1,7 +1,9 @@ +import 'package:flutter/services.dart'; import 'package:flutter_template/navigator/main_navigator.dart'; import 'package:flutter_template/navigator/onboarding_navigator.dart'; import 'package:flutter_template/repository/login/login_repository.dart'; import 'package:flutter_template/util/locale/localization_keys.dart'; +import 'package:flutter_template/util/logging/flutter_template_logger.dart'; import 'package:icapps_architecture/icapps_architecture.dart'; import 'package:injectable/injectable.dart'; @@ -41,9 +43,10 @@ class LoginViewModel with ChangeNotifierEx { try { _isLoading = true; await _loginRepo.login(email: _email, password: _password); + TextInput.finishAutofillContext(); return _onboardingNavigator.goToNextScreen(); } catch (e, stack) { - logger.error('Failed to login', error: e, stackTrace: stack); + FlutterTemplateLogger.logError('Failed to login', error: e, stackTrace: stack); if (e is LocalizedError) { _navigator.showErrorWithLocaleKey(messageKey: e.getLocalizedKey()); } else { diff --git a/lib/viewmodel/logs/logs_viewmodel.dart b/lib/viewmodel/logs/logs_viewmodel.dart new file mode 100644 index 00000000..5ae32cc7 --- /dev/null +++ b/lib/viewmodel/logs/logs_viewmodel.dart @@ -0,0 +1,41 @@ +import 'package:flutter_template/navigator/main_navigator.dart'; +import 'package:flutter_template/util/logging/flutter_template_logger.dart'; +import 'package:icapps_architecture/icapps_architecture.dart'; +import 'package:injectable/injectable.dart'; +import 'package:log_to_secure_file/log_to_secure_file.dart'; + +@injectable +class LogsViewModel with ChangeNotifierEx { + final MainNavigator _navigator; + final SecureLogStorage _secureLogStorage; + + final List _dates = []; + + List get availableDates => _dates; + + LogsViewModel( + this._navigator, + this._secureLogStorage, + ); + + Future init() async { + _dates.replaceAll(await _secureLogStorage.availableDates()); + if (disposed) return; + notifyListeners(); + } + + void triggerError() { + try { + throw Exception('This is a test error'); + } catch (e, trace) { + FlutterTemplateLogger.logError( + 'Error', + error: e, + stackTrace: trace, + sendToFirebase: false, + ); + } + } + + void onLogTapped(DateTime date) => _navigator.goToLogDetailScreen(date: date.toIso8601String()); +} diff --git a/lib/viewmodel/todo/todo_list/todo_list_viewmodel.dart b/lib/viewmodel/todo/todo_list/todo_list_viewmodel.dart index 5e7503e1..c13ac6b4 100644 --- a/lib/viewmodel/todo/todo_list/todo_list_viewmodel.dart +++ b/lib/viewmodel/todo/todo_list/todo_list_viewmodel.dart @@ -2,6 +2,7 @@ import 'package:flutter_template/model/webservice/todo/todo.dart'; import 'package:flutter_template/navigator/main_navigator.dart'; import 'package:flutter_template/repository/todo/todo_repository.dart'; import 'package:flutter_template/util/locale/localization_keys.dart'; +import 'package:flutter_template/util/logging/flutter_template_logger.dart'; import 'package:icapps_architecture/icapps_architecture.dart'; import 'package:injectable/injectable.dart'; @@ -37,7 +38,7 @@ class TodoListViewModel with ChangeNotifierEx { notifyListeners(); await _todoRepo.fetchTodos(); } catch (e, stack) { - logger.error('failed to get todos', error: e, stackTrace: stack); + FlutterTemplateLogger.logError('failed to get todos', error: e, stackTrace: stack); if (e is LocalizedError) { _errorKey = e.getLocalizedKey(); } else { diff --git a/lib/widget/debug/debug_row_item.dart b/lib/widget/debug/debug_row_item.dart index 9b838f6e..5c72de95 100644 --- a/lib/widget/debug/debug_row_item.dart +++ b/lib/widget/debug/debug_row_item.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:flutter_template/styles/theme_dimens.dart'; +import 'package:flutter_template/styles/theme_assets.dart'; +import 'package:flutter_template/styles/theme_data.dart'; +import 'package:flutter_template/widget/general/svg_icon.dart'; import 'package:flutter_template/widget/provider/data_provider_widget.dart'; import 'package:icapps_architecture/icapps_architecture.dart'; @@ -17,35 +19,39 @@ class DebugRowItem extends StatelessWidget { @override Widget build(BuildContext context) { - return DataProviderWidget(childBuilderTheme: (context, theme) { - return TouchFeedBack( - onTapped: onClick, - child: Padding( - padding: const EdgeInsets.all(ThemeDimens.padding16), - child: Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - title, - style: theme.coreTextTheme.bodyBig, - ), - if (subTitle != null) ...[ - Container(height: ThemeDimens.padding4), + return DataProviderWidget( + childBuilderTheme: (context, theme) => TouchFeedBack( + onTapped: onClick, + child: Padding( + padding: const EdgeInsets.all(16), + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ Text( - subTitle!, - style: theme.coreTextTheme.bodySmall, + title, + style: theme.text.bodyBig, ), + if (subTitle != null) ...[ + Container(height: 8), + Text( + subTitle!, + style: theme.text.bodySmall, + ), + ], ], - ], + ), ), - ), - ], + SvgIcon( + svgAsset: ThemeAssets.chevronRightIcon, + color: theme.icon, + ), + ], + ), ), ), - ); - }); + ); } } diff --git a/lib/widget/debug/debug_row_title.dart b/lib/widget/debug/debug_row_title.dart index b6f98ca8..3f7e30d3 100644 --- a/lib/widget/debug/debug_row_title.dart +++ b/lib/widget/debug/debug_row_title.dart @@ -1,28 +1,35 @@ import 'package:flutter/material.dart'; +import 'package:flutter_template/styles/theme_data.dart'; import 'package:flutter_template/styles/theme_dimens.dart'; +import 'package:flutter_template/widget/general/svg_icon.dart'; import 'package:flutter_template/widget/provider/data_provider_widget.dart'; class DebugRowTitle extends StatelessWidget { final String title; + final String icon; const DebugRowTitle({ required this.title, + required this.icon, super.key, }); @override Widget build(BuildContext context) { return DataProviderWidget( - childBuilderTheme: (context, theme) => Container( - padding: const EdgeInsets.symmetric( - horizontal: ThemeDimens.padding16, - vertical: ThemeDimens.padding8, - ), - color: theme.colorsTheme.debugTitleBackground, - child: Text( - title, - style: theme.coreTextTheme.titleNormal, - ), + childBuilderTheme: (context, theme) => Row( + children: [ + SvgIcon( + svgAsset: icon, + color: theme.fadedText, + size: ThemeDimens.smallIconSize, + ), + const SizedBox(width: 4), + Text( + title, + style: theme.fadedText.bodySmall, + ), + ], ), ); } diff --git a/lib/widget/debug/debug_section.dart b/lib/widget/debug/debug_section.dart new file mode 100644 index 00000000..604e7259 --- /dev/null +++ b/lib/widget/debug/debug_section.dart @@ -0,0 +1,58 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_template/widget/debug/debug_row_title.dart'; +import 'package:flutter_template/widget/provider/data_provider_widget.dart'; +import 'package:icapps_architecture/icapps_architecture.dart'; + +class DebugSection extends StatelessWidget { + final String title; + final String icon; + final List children; + + const DebugSection({ + required this.title, + required this.icon, + required this.children, + super.key, + }); + + @override + Widget build(BuildContext context) { + return DataProviderWidget( + childBuilder: (context, theme, localization) => Column( + mainAxisSize: MainAxisSize.min, + children: [ + DebugRowTitle( + title: title, + icon: icon, + ), + const SizedBox(height: 8), + Container( + decoration: BoxDecoration( + color: theme.cardBackground, + borderRadius: BorderRadius.circular(12), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: children + .mapIndexed((index, child) { + final isLast = index == children.length - 1; + return [ + child, + if (!isLast) ...[ + Container( + margin: const EdgeInsets.symmetric(horizontal: 8), + height: 1, + color: theme.debugTitleBackground, + ), + ], + ]; + }) + .expand((item) => item) + .toList(), + ), + ), + ], + ), + ); + } +} diff --git a/lib/widget/debug/debug_switch_row_item.dart b/lib/widget/debug/debug_switch_row_item.dart index 455f28e0..72d976c0 100644 --- a/lib/widget/debug/debug_switch_row_item.dart +++ b/lib/widget/debug/debug_switch_row_item.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:flutter_template/styles/theme_dimens.dart'; +import 'package:flutter_template/styles/theme_data.dart'; import 'package:flutter_template/widget/general/styled/flutter_template_switch.dart'; import 'package:flutter_template/widget/provider/data_provider_widget.dart'; import 'package:icapps_architecture/icapps_architecture.dart'; @@ -24,7 +24,7 @@ class DebugRowSwitchItem extends StatelessWidget { return TouchFeedBack( onTapped: () => onChanged(!value), child: Padding( - padding: const EdgeInsets.all(ThemeDimens.padding16), + padding: const EdgeInsets.all(16), child: Row( children: [ Expanded( @@ -33,12 +33,12 @@ class DebugRowSwitchItem extends StatelessWidget { children: [ Text( title, - style: theme.coreTextTheme.bodyBig, + style: theme.text.bodyBig, ), if (subTitle != null) Text( subTitle!, - style: theme.coreTextTheme.bodySmall, + style: theme.text.bodySmall, ), ], ), diff --git a/lib/widget/debug/select_language_dialog.dart b/lib/widget/debug/select_language_dialog.dart index c5e6ffa4..420b82f7 100644 --- a/lib/widget/debug/select_language_dialog.dart +++ b/lib/widget/debug/select_language_dialog.dart @@ -17,7 +17,7 @@ class SelectLanguageDialog extends StatelessWidget { final globalViewModel = Provider.of(context); return DataProviderWidget( childBuilder: (context, theme, localization) => AlertDialog( - backgroundColor: theme.colorsTheme.background, + backgroundColor: theme.background, title: Text(localization.debugLocaleSelector), content: SizedBox( height: 150, diff --git a/lib/widget/debug/selector_item.dart b/lib/widget/debug/selector_item.dart index 6cf6cb17..7e8e9cf2 100644 --- a/lib/widget/debug/selector_item.dart +++ b/lib/widget/debug/selector_item.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_template/styles/theme_assets.dart'; -import 'package:flutter_template/styles/theme_dimens.dart'; +import 'package:flutter_template/styles/theme_data.dart'; import 'package:flutter_template/widget/general/svg_icon.dart'; import 'package:flutter_template/widget/provider/data_provider_widget.dart'; import 'package:icapps_architecture/icapps_architecture.dart'; @@ -22,24 +22,35 @@ class SelectorItem extends StatelessWidget { return DataProviderWidget( childBuilderTheme: (context, theme) => TouchFeedBack( onTapped: onClick, - child: Padding( - padding: const EdgeInsets.all(ThemeDimens.padding16), - child: Row( - children: [ - Expanded( - child: Text( - title, - style: theme.coreTextTheme.bodyNormal, + borderRadius: BorderRadius.circular(12), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: selected ? theme.fillInformative : theme.cardBackground, + border: Border.all( + color: selected ? theme.accent : theme.cardBackground, + width: 1, + ), + ), + child: Padding( + padding: const EdgeInsets.all(16), + child: Row( + children: [ + Expanded( + child: Text( + title, + style: theme.text.bodyNormal, + ), ), - ), - Opacity( - opacity: selected ? 1 : 0, - child: SvgIcon( - svgAsset: ThemeAssets.doneIcon(context), - color: theme.colorsTheme.accent, + Opacity( + opacity: selected ? 1 : 0, + child: SvgIcon( + svgAsset: ThemeAssets.checkIcon, + color: theme.accent, + ), ), - ), - ], + ], + ), ), ), ), diff --git a/lib/widget/general/action/action_item.dart b/lib/widget/general/action/action_item.dart index 06c9a559..6c97122a 100644 --- a/lib/widget/general/action/action_item.dart +++ b/lib/widget/general/action/action_item.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter_template/styles/theme_dimens.dart'; import 'package:flutter_template/widget/general/svg_icon.dart'; import 'package:flutter_template/widget/provider/data_provider_widget.dart'; import 'package:icapps_architecture/icapps_architecture.dart'; @@ -20,20 +19,20 @@ class ActionItem extends StatelessWidget { Widget build(BuildContext context) { return DataProviderWidget( childBuilderTheme: (context, theme) => SizedBox( - height: ThemeDimens.padding56, - width: ThemeDimens.padding56, + height: 48, + width: 48, child: Center( child: SizedBox( - height: ThemeDimens.padding48, - width: ThemeDimens.padding48, + height: 48, + width: 48, child: TouchFeedBack( - borderRadius: BorderRadius.circular(ThemeDimens.padding48), + borderRadius: BorderRadius.circular(48), onTapped: onClick, child: Center( child: SvgIcon( svgAsset: svgAsset, - size: ThemeDimens.padding24, - color: color ?? theme.colorsTheme.icon, + size: 24, + color: color ?? theme.icon, ), ), ), diff --git a/lib/widget/general/action/text_action_item.dart b/lib/widget/general/action/text_action_item.dart index 36056bdb..ed28e821 100644 --- a/lib/widget/general/action/text_action_item.dart +++ b/lib/widget/general/action/text_action_item.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:flutter_template/styles/theme_dimens.dart'; +import 'package:flutter_template/styles/theme_data.dart'; import 'package:flutter_template/styles/theme_durations.dart'; import 'package:flutter_template/widget/provider/data_provider_widget.dart'; import 'package:icapps_architecture/icapps_architecture.dart'; @@ -23,12 +23,12 @@ class TextActionItem extends StatelessWidget { return DataProviderWidget( childBuilderTheme: (context, theme) => Center( child: TouchFeedBack( - borderRadius: BorderRadius.circular(ThemeDimens.padding4), + borderRadius: BorderRadius.circular(4), onTapped: enabled ? onClick : null, child: Padding( - padding: const EdgeInsets.symmetric(horizontal: ThemeDimens.padding16, vertical: ThemeDimens.padding8), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: AnimatedDefaultTextStyle( - style: style ?? theme.inverseCoreTextTheme.labelButtonSmall, + style: style ?? theme.inverseText.labelButtonSmall, duration: ThemeDurations.shortAnimationDuration, child: Text(text), ), diff --git a/lib/widget/general/base_screen/base_screen.dart b/lib/widget/general/base_screen/base_screen.dart new file mode 100644 index 00000000..5ab21461 --- /dev/null +++ b/lib/widget/general/base_screen/base_screen.dart @@ -0,0 +1,159 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_template/widget/general/base_screen/base_screen_content.dart'; +import 'package:flutter_template/widget/general/base_screen/base_screen_header.dart'; +import 'package:flutter_template/widget/general/status_bar.dart'; +import 'package:flutter_template/widget/general/styled/flutter_template_progress_indicator.dart'; +import 'package:flutter_template/widget/provider/data_provider_widget.dart'; + +class BaseScreen extends StatelessWidget { + final bool isScrollable; + final bool useSlivers; + final bool showHeader; + final bool isLoading; + final bool hasBottomSafeSpace; + final bool reversed; + final int? itemCount; + final Color? background; + final String? title; + final Widget? child; + final EdgeInsets padding; + final List children; + final List? actions; + final VoidCallback? onBackTapped; + final AsyncCallback? onRefresh; + final IndexedWidgetBuilder? itemBuilder; + + const BaseScreen({ + required this.children, + this.reversed = false, + this.actions, + this.onRefresh, + this.isLoading = false, + this.hasBottomSafeSpace = true, + this.onBackTapped, + this.title, + this.showHeader = true, + this.isScrollable = false, + this.useSlivers = false, + this.padding = const EdgeInsets.all(16), + this.background, + super.key, + }) : child = null, + itemBuilder = null, + itemCount = null; + + const BaseScreen.builder({ + required this.itemBuilder, + required this.itemCount, + this.reversed = false, + this.actions, + this.onRefresh, + this.isLoading = false, + this.hasBottomSafeSpace = true, + this.onBackTapped, + this.title, + this.showHeader = true, + this.padding = const EdgeInsets.all(16), + this.background, + super.key, + }) : children = const [], + child = null, + useSlivers = false, + isScrollable = true; + + const BaseScreen.slivers({ + required this.children, + this.reversed = false, + this.actions, + this.onRefresh, + this.hasBottomSafeSpace = true, + this.onBackTapped, + this.isLoading = false, + this.title, + this.showHeader = true, + this.padding = const EdgeInsets.all(16), + this.background, + super.key, + }) : child = null, + useSlivers = true, + isScrollable = true, + itemBuilder = null, + itemCount = null; + + const BaseScreen.child({ + required this.child, + this.actions, + this.onRefresh, + this.isLoading = false, + this.hasBottomSafeSpace = true, + this.onBackTapped, + this.title, + this.showHeader = true, + this.padding = const EdgeInsets.all(16), + this.background, + super.key, + }) : children = const [], + isScrollable = false, + useSlivers = false, + itemBuilder = null, + itemCount = null, + reversed = false; + + @override + Widget build(BuildContext context) { + return DataProviderWidget( + childBuilder: (context, theme, localization) => StatusBar.dark( + child: Scaffold( + backgroundColor: background ?? theme.background, + body: GestureDetector( + onTap: FocusManager.instance.primaryFocus?.unfocus, + child: SafeArea( + top: !showHeader, + bottom: hasBottomSafeSpace, + child: Column( + children: [ + if (showHeader) ...[ + BaseScreenHeader( + title: title, + onBackTapped: onBackTapped, + trailingItems: actions ?? [], + ), + ], + Expanded( + child: Builder( + builder: (context) { + if (isLoading) { + return const Center( + child: FlutterTemplateProgressIndicator.dark(), + ); + } + + final content = BaseScreenContent( + isScrollable: isScrollable, + padding: padding, + useSlivers: useSlivers, + children: children, + child: child, + itemBuilder: itemBuilder, + itemCount: itemCount, + reversed: reversed, + ); + if (onRefresh == null) return content; + + return RefreshIndicator( + onRefresh: onRefresh!, + child: content, + ); + }, + ), + ), + ], + ), + ), + ), + ), + ), + ); + } +} diff --git a/lib/widget/general/base_screen/base_screen_content.dart b/lib/widget/general/base_screen/base_screen_content.dart new file mode 100644 index 00000000..a7fa84a6 --- /dev/null +++ b/lib/widget/general/base_screen/base_screen_content.dart @@ -0,0 +1,65 @@ +import 'package:flutter/material.dart'; + +class BaseScreenContent extends StatelessWidget { + final bool useSlivers; + final bool isScrollable; + final bool reversed; + final int? itemCount; + final Widget? child; + final EdgeInsets padding; + final List children; + final IndexedWidgetBuilder? itemBuilder; + + const BaseScreenContent({ + required this.useSlivers, + required this.isScrollable, + required this.padding, + required this.children, + required this.itemBuilder, + required this.itemCount, + required this.reversed, + this.child, + super.key, + }); + + @override + Widget build(BuildContext context) { + if (itemBuilder != null) { + return ListView.builder( + padding: padding, + itemBuilder: itemBuilder!, + itemCount: itemCount, + reverse: reversed, + ); + } + + if (children.isNotEmpty) { + if (useSlivers) { + return CustomScrollView( + slivers: children, + reverse: reversed, + ); + } + if (isScrollable) { + return ListView( + padding: padding, + reverse: reversed, + children: children, + ); + } + + return Padding( + padding: padding, + child: Column( + verticalDirection: reversed ? VerticalDirection.up : VerticalDirection.down, + children: children, + ), + ); + } + + return Padding( + padding: padding, + child: child, + ); + } +} diff --git a/lib/widget/general/base_screen/base_screen_header.dart b/lib/widget/general/base_screen/base_screen_header.dart new file mode 100644 index 00000000..cf07fc5d --- /dev/null +++ b/lib/widget/general/base_screen/base_screen_header.dart @@ -0,0 +1,78 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_template/styles/theme_data.dart'; +import 'package:flutter_template/util/platform/platform_util.dart'; +import 'package:flutter_template/widget/general/base_screen/base_screen_header_safe_area.dart'; +import 'package:flutter_template/widget/general/styled/flutter_template_back_button.dart'; +import 'package:flutter_template/widget/provider/data_provider_widget.dart'; + +class BaseScreenHeader extends StatelessWidget { + final bool? centerTitle; + final String? title; + final List trailingItems; + final VoidCallback? onBackTapped; + + const BaseScreenHeader({ + this.onBackTapped, + this.centerTitle, + this.title, + this.trailingItems = const [], + super.key, + }); + + @override + Widget build(BuildContext context) { + return DataProviderWidget( + childBuilder: (context, theme, localization) { + final leading = [ + if (ModalRoute.of(context)?.impliesAppBarDismissal ?? false) ...[ + FlutterTemplateBackButton.dark(onClick: onBackTapped ?? Navigator.of(context).pop), + const SizedBox(width: 24), + ], + ]; + final isTitleCentered = centerTitle ?? PlatformUtil.isIOS; + final titleWidget = title == null + ? null + : Text( + title!.toUpperCase(), + style: theme.text.bodyNormal, + textAlign: isTitleCentered ? TextAlign.center : TextAlign.start, + ); + + return Container( + padding: const EdgeInsets.symmetric( + horizontal: 16, + vertical: 12, + ), + child: SafeArea( + bottom: false, + child: Stack( + alignment: Alignment.center, + children: [ + Row( + children: [ + ...leading, + if (titleWidget != null && !isTitleCentered) ...[ + Expanded( + child: titleWidget, + ), + ] else ...[ + const Spacer(), + ], + ...trailingItems, + ], + ), + if (isTitleCentered && titleWidget != null) ...[ + BaseScreenHeaderSafeArea( + leading: leading, + actions: trailingItems, + child: titleWidget, + ), + ], + ], + ), + ), + ); + }, + ); + } +} diff --git a/lib/widget/general/base_screen/base_screen_header_safe_area.dart b/lib/widget/general/base_screen/base_screen_header_safe_area.dart new file mode 100644 index 00000000..fc221c72 --- /dev/null +++ b/lib/widget/general/base_screen/base_screen_header_safe_area.dart @@ -0,0 +1,37 @@ +import 'package:flutter/material.dart'; + +class BaseScreenHeaderSafeArea extends StatelessWidget { + final Widget child; + final List leading; + final List actions; + + const BaseScreenHeaderSafeArea({ + required this.leading, + required this.actions, + required this.child, + super.key, + }); + + @override + Widget build(BuildContext context) { + final content = Opacity( + opacity: 0, + child: IgnorePointer( + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + ...leading, + ...actions, + ], + ), + ), + ); + return Row( + children: [ + content, + Expanded(child: child), + content, + ], + ); + } +} diff --git a/lib/widget/general/bottom_navigation/bottom_navigation.dart b/lib/widget/general/bottom_navigation/bottom_navigation.dart index 183dfad6..dfecdeaf 100644 --- a/lib/widget/general/bottom_navigation/bottom_navigation.dart +++ b/lib/widget/general/bottom_navigation/bottom_navigation.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_template/model/bottom_navigation/bottom_navigation_tab.dart'; +import 'package:flutter_template/styles/theme_data.dart'; import 'package:flutter_template/widget/general/bottom_navigation/bottom_navigation_item.dart'; import 'package:flutter_template/widget/provider/data_provider_widget.dart'; @@ -19,32 +20,29 @@ class BottomNavigation extends StatelessWidget { childBuilder: (context, theme, localization) => Container( padding: const EdgeInsets.symmetric(horizontal: 8), decoration: BoxDecoration( - color: theme.colorsTheme.bottomNavbarBackground, - boxShadow: [ - BoxShadow( - spreadRadius: 2, - blurRadius: 8, - color: theme.colorsTheme.shadow, - ), - ], + color: theme.bottomNavbarBackground, + boxShadow: theme.shadow.bottomNavShadow, ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - SafeArea( - top: false, - child: Row( - children: BottomNavigationTab.values - .map((tab) => BottomNavigationItem( - isSelected: selectedTab == tab, - icon: tab.icon, - labelKey: tab.labelKey, - onTap: () => onItemTapped(tab), - )) - .toList(), + child: ClipRect( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SafeArea( + top: false, + child: Row( + children: BottomNavigationTab.values + .map((tab) => BottomNavigationItem( + isSelected: selectedTab == tab, + iconActive: tab.iconActive, + iconInactive: tab.iconInactive, + labelKey: tab.labelKey, + onTap: () => onItemTapped(tab), + )) + .toList(), + ), ), - ), - ], + ], + ), ), ), ); diff --git a/lib/widget/general/bottom_navigation/bottom_navigation_item.dart b/lib/widget/general/bottom_navigation/bottom_navigation_item.dart index 5e198002..91369469 100644 --- a/lib/widget/general/bottom_navigation/bottom_navigation_item.dart +++ b/lib/widget/general/bottom_navigation/bottom_navigation_item.dart @@ -1,15 +1,17 @@ import 'package:flutter/material.dart'; +import 'package:flutter_template/styles/theme_data.dart'; import 'package:flutter_template/styles/theme_dimens.dart'; import 'package:flutter_template/styles/theme_durations.dart'; import 'package:flutter_template/util/extension/text_scaler_extensions.dart'; -import 'package:flutter_template/widget/animation/animated_color_filter.dart'; +import 'package:flutter_template/widget/general/svg_icon.dart'; import 'package:flutter_template/widget/provider/data_provider_widget.dart'; import 'package:icapps_architecture/icapps_architecture.dart'; class BottomNavigationItem extends StatelessWidget { final bool isSelected; final String labelKey; - final IconData icon; + final String iconActive; + final String iconInactive; final VoidCallback onTap; static const _itemHeight = 56.0; @@ -17,7 +19,8 @@ class BottomNavigationItem extends StatelessWidget { const BottomNavigationItem({ required this.isSelected, required this.labelKey, - required this.icon, + required this.iconActive, + required this.iconInactive, required this.onTap, super.key, }); @@ -30,21 +33,25 @@ class BottomNavigationItem extends StatelessWidget { child: Column( mainAxisSize: MainAxisSize.min, children: [ - AnimatedColorFilter( - color: isSelected ? theme.colorsTheme.bottomNavbarItemActive : theme.colorsTheme.bottomNavbarItemInactive, - builder: (context, color) => Icon( - icon, - color: color, + AnimatedCrossFade( + duration: ThemeDurations.shortAnimationDuration, + firstChild: SvgIcon( + svgAsset: iconActive, + color: theme.bottomNavbarItemActive, size: hasSpaceForLabel ? ThemeDimens.iconSize : ThemeDimens.largeIcon, ), + secondChild: SvgIcon( + svgAsset: iconInactive, + color: theme.bottomNavbarItemInactive, + size: hasSpaceForLabel ? ThemeDimens.iconSize : ThemeDimens.largeIcon, + ), + crossFadeState: isSelected ? CrossFadeState.showFirst : CrossFadeState.showSecond, ), if (hasSpaceForLabel) ...[ const SizedBox(height: 2), AnimatedDefaultTextStyle( duration: ThemeDurations.shortAnimationDuration, - style: isSelected - ? theme.coreTextTheme.bodySmall.copyWith(color: theme.colorsTheme.bottomNavbarItemActive) - : theme.coreTextTheme.bodySmall.copyWith(color: theme.colorsTheme.bottomNavbarItemInactive), + style: isSelected ? theme.bottomNavbarItemActive.bodySmall.strong : theme.bottomNavbarItemInactive.bodySmall, child: Text( localization.getTranslation(labelKey), maxLines: 1, diff --git a/lib/widget/general/styled/flutter_template_back_button.dart b/lib/widget/general/styled/flutter_template_back_button.dart index c41f1c55..55e575b2 100644 --- a/lib/widget/general/styled/flutter_template_back_button.dart +++ b/lib/widget/general/styled/flutter_template_back_button.dart @@ -28,7 +28,7 @@ class FlutterTemplateBackButton extends StatelessWidget { childBuilderTheme: (context, theme) => ActionItem( key: Keys.backButton, svgAsset: getCorrectIcon(context), - color: isLight ? ThemeColors.white : theme.colorsTheme.primary, + color: isLight ? ThemeColors.white : theme.appBarAction, onClick: onClick, ), ); @@ -36,8 +36,8 @@ class FlutterTemplateBackButton extends StatelessWidget { String getCorrectIcon(BuildContext context) { if (fullScreen) { - return ThemeAssets.closeIcon(context); + return ThemeAssets.arrowLeftIcon; } - return ThemeAssets.backIcon(context); + return ThemeAssets.arrowLeftIcon; } } diff --git a/lib/widget/general/styled/flutter_template_button.dart b/lib/widget/general/styled/flutter_template_button.dart index 6f768384..a75b8991 100644 --- a/lib/widget/general/styled/flutter_template_button.dart +++ b/lib/widget/general/styled/flutter_template_button.dart @@ -37,25 +37,25 @@ class FlutterTemplateButton extends StatelessWidget { TextStyle _enabledTextStyle(FlutterTemplateTheme theme) { switch (buttonType) { case ButtonType.regular: - return theme.inverseCoreTextTheme.labelButtonSmall; + return theme.lightText.labelButtonSmall; case ButtonType.text: - return theme.accentTextTheme.labelButtonSmall; + return theme.accent.labelButtonSmall; } } TextStyle _disabledTextStyle(FlutterTemplateTheme theme) { switch (buttonType) { case ButtonType.regular: - return theme.inverseCoreTextTheme.labelButtonSmall; + return theme.inverseText.labelButtonSmall; case ButtonType.text: - return theme.disabledTextTheme.labelButtonSmall; + return theme.disabled.labelButtonSmall; } } Color? _enabledButtonColor(FlutterTemplateTheme theme) { switch (buttonType) { case ButtonType.regular: - return theme.colorsTheme.buttonColor; + return theme.buttonColor; case ButtonType.text: return null; } @@ -64,7 +64,7 @@ class FlutterTemplateButton extends StatelessWidget { Color? _disabledButtonColor(FlutterTemplateTheme theme) { switch (buttonType) { case ButtonType.regular: - return theme.colorsTheme.disabled; + return theme.disabled; case ButtonType.text: return null; } @@ -93,18 +93,26 @@ class FlutterTemplateButton extends StatelessWidget { ); if (context.isIOSTheme) { return TouchFeedBack( + borderRadius: BorderRadius.circular(12), onTapped: isEnabled ? onClick : null, child: AnimatedContainer( - color: isEnabled ? _enabledButtonColor(theme) : _disabledButtonColor(theme), + decoration: BoxDecoration( + color: isEnabled ? _enabledButtonColor(theme) : _disabledButtonColor(theme), + borderRadius: BorderRadius.circular(12), + ), duration: ThemeDurations.shortAnimationDuration, child: content, ), ); } return AnimatedContainer( - color: isEnabled ? _enabledButtonColor(theme) : _disabledButtonColor(theme), + decoration: BoxDecoration( + color: isEnabled ? _enabledButtonColor(theme) : _disabledButtonColor(theme), + borderRadius: BorderRadius.circular(12), + ), duration: ThemeDurations.shortAnimationDuration, child: TouchFeedBack( + borderRadius: BorderRadius.circular(12), onTapped: isEnabled ? onClick : null, child: content, ), diff --git a/lib/widget/general/styled/flutter_template_checkbox.dart b/lib/widget/general/styled/flutter_template_checkbox.dart index 78cda93e..a1af0c06 100644 --- a/lib/widget/general/styled/flutter_template_checkbox.dart +++ b/lib/widget/general/styled/flutter_template_checkbox.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:flutter_template/styles/theme_assets.dart'; -import 'package:flutter_template/styles/theme_dimens.dart'; import 'package:flutter_template/widget/general/svg_icon.dart'; import 'package:flutter_template/widget/provider/data_provider_widget.dart'; import 'package:icapps_architecture/icapps_architecture.dart'; @@ -23,14 +22,14 @@ class FlutterTemplateCheckBox extends StatelessWidget { onTap: () => onChanged(!value), child: Container( color: Colors.transparent, - height: ThemeDimens.padding48, - width: ThemeDimens.padding48, + height: 48, + width: 48, child: value ? Center( child: SvgIcon( - svgAsset: ThemeAssets.doneIcon(context), - color: theme.colorsTheme.accent, - size: ThemeDimens.padding24, + svgAsset: ThemeAssets.checkIcon, + color: theme.accent, + size: 24, ), ) : Container(), @@ -42,7 +41,7 @@ class FlutterTemplateCheckBox extends StatelessWidget { childBuilderTheme: (context, theme) => Checkbox( value: value, onChanged: (value) => onChanged(value ?? false), - activeColor: theme.colorsTheme.accent, + activeColor: theme.accent, ), ); } diff --git a/lib/widget/general/styled/flutter_template_input_field.dart b/lib/widget/general/styled/flutter_template_input_field.dart index 80d8b2e5..346a5909 100644 --- a/lib/widget/general/styled/flutter_template_input_field.dart +++ b/lib/widget/general/styled/flutter_template_input_field.dart @@ -1,15 +1,19 @@ import 'package:flutter/material.dart'; +import 'package:flutter_template/styles/theme_data.dart'; import 'package:flutter_template/widget/provider/data_provider_widget.dart'; class FlutterTemplateInputField extends StatelessWidget { - final String hint; final bool enabled; + final String hint; + final List? autoFillHints; final ValueChanged onChanged; final TextEditingController? controller; + const FlutterTemplateInputField({ required this.hint, required this.onChanged, + this.autoFillHints, this.enabled = true, this.controller, super.key, @@ -19,23 +23,24 @@ class FlutterTemplateInputField extends StatelessWidget { Widget build(BuildContext context) { return DataProviderWidget( childBuilderTheme: (context, theme) => TextField( - style: theme.coreTextTheme.bodyNormal, + style: theme.text.bodyNormal, controller: controller, enabled: enabled, onChanged: onChanged, + autofillHints: autoFillHints, decoration: InputDecoration( filled: true, hintText: hint, - hintStyle: theme.coreTextTheme.bodyNormal.copyWith(color: theme.colorsTheme.inputFieldHint), - fillColor: theme.colorsTheme.inputFieldFill, + hintStyle: theme.inputFieldHint.bodyNormal, + fillColor: theme.inputFieldFill, enabledBorder: UnderlineInputBorder( - borderSide: BorderSide(color: theme.colorsTheme.inputFieldBorderEnabled), + borderSide: BorderSide(color: theme.inputFieldBorderEnabled), ), focusedBorder: UnderlineInputBorder( - borderSide: BorderSide(color: theme.colorsTheme.inputFieldBorderFocused), + borderSide: BorderSide(color: theme.inputFieldBorderFocused), ), border: UnderlineInputBorder( - borderSide: BorderSide(color: theme.colorsTheme.bottomNavbarItemInactive), + borderSide: BorderSide(color: theme.bottomNavbarItemInactive), ), ), ), diff --git a/lib/widget/general/styled/flutter_template_network_image.dart b/lib/widget/general/styled/flutter_template_network_image.dart index 5a9f8daf..1eba61a7 100644 --- a/lib/widget/general/styled/flutter_template_network_image.dart +++ b/lib/widget/general/styled/flutter_template_network_image.dart @@ -6,7 +6,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_template/di/injectable.dart'; import 'package:flutter_template/util/cache/cache_controlling.dart'; import 'package:flutter_template/util/env/flavor_config.dart'; -import 'package:icapps_architecture/icapps_architecture.dart'; +import 'package:flutter_template/util/logging/flutter_template_logger.dart'; class FlutterTemplateNetworkImage extends StatelessWidget { final String? url; @@ -112,7 +112,7 @@ class _FlutterTemplateBetterNetworkImageState extends State<_FlutterTemplateBett return; } if (widgetWidth == double.infinity || widgetHeight == double.infinity || widgetWidth == null || widgetHeight == null) { - logger.warning('IMAGE-ERROR: $originalUrl ($widgetWidth/$widgetHeight'); + FlutterTemplateLogger.logWarning('IMAGE-ERROR: $originalUrl ($widgetWidth/$widgetHeight'); setState(() => _hasError = true); return; } @@ -147,7 +147,12 @@ class _FlutterTemplateBetterNetworkImageState extends State<_FlutterTemplateBett _image = data?.buffer.asUint8List(); unawaited(_cacheImage(url)); } catch (e, stack) { - logger.error('Failed to parse image: $originalUrl', error: e, stackTrace: stack); + FlutterTemplateLogger.logError( + 'Failed to parse image: $originalUrl', + error: e, + stackTrace: stack, + sendToFirebase: false, + ); _hasError = true; } finally { _isLoading = false; @@ -164,7 +169,7 @@ class _FlutterTemplateBetterNetworkImageState extends State<_FlutterTemplateBett try { await _cacheController.putFile(url, img, fileExtension: 'png'); } catch (e, stack) { - logger.error('Failed to cache image: $url', error: e, stackTrace: stack); + FlutterTemplateLogger.logError('Failed to cache image: $url', error: e, stackTrace: stack); } } diff --git a/lib/widget/general/styled/flutter_template_progress_indicator.dart b/lib/widget/general/styled/flutter_template_progress_indicator.dart index 04941106..db1564e3 100644 --- a/lib/widget/general/styled/flutter_template_progress_indicator.dart +++ b/lib/widget/general/styled/flutter_template_progress_indicator.dart @@ -20,7 +20,7 @@ class FlutterTemplateProgressIndicator extends StatelessWidget { childBuilderTheme: (context, theme) { if (FlavorConfig.isInTest()) { return Container( - color: theme.colorsTheme.accent, + color: theme.accent, height: 50, width: 50, child: const Text( @@ -30,7 +30,7 @@ class FlutterTemplateProgressIndicator extends StatelessWidget { ); } return CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation(dark ? theme.colorsTheme.progressIndicator : theme.colorsTheme.inverseProgressIndicator), + valueColor: AlwaysStoppedAnimation(dark ? theme.progressIndicator : theme.inverseProgressIndicator), ); }, ); diff --git a/lib/widget/general/styled/flutter_template_switch.dart b/lib/widget/general/styled/flutter_template_switch.dart index bb6e2954..4bd4523f 100644 --- a/lib/widget/general/styled/flutter_template_switch.dart +++ b/lib/widget/general/styled/flutter_template_switch.dart @@ -1,5 +1,8 @@ import 'package:flutter/material.dart'; +import 'package:flutter_template/styles/theme_dimens.dart'; +import 'package:flutter_template/styles/theme_durations.dart'; import 'package:flutter_template/widget/provider/data_provider_widget.dart'; +import 'package:icapps_architecture/icapps_architecture.dart'; class FlutterTemplateSwitch extends StatelessWidget { final bool value; @@ -14,11 +17,29 @@ class FlutterTemplateSwitch extends StatelessWidget { @override Widget build(BuildContext context) { return DataProviderWidget( - childBuilderTheme: (context, theme) => Switch.adaptive( - value: value, - onChanged: onChanged, - activeColor: theme.colorsTheme.accent, - inactiveTrackColor: theme.colorsTheme.disabled, + childBuilderTheme: (context, theme) => TouchFeedBack( + onTapped: () => onChanged(!value), + child: Container( + height: 24, + width: 42, + decoration: BoxDecoration( + color: value ? theme.accent : theme.switchBackground, + borderRadius: ThemeDimens.circularBorderRadius, + ), + child: AnimatedAlign( + duration: ThemeDurations.shortAnimationDuration, + alignment: value ? Alignment.centerRight : Alignment.centerLeft, + child: Container( + margin: const EdgeInsets.all(2), + height: 20, + width: 20, + decoration: BoxDecoration( + color: theme.lightText, + borderRadius: ThemeDimens.circularBorderRadius, + ), + ), + ), + ), ), ); } diff --git a/lib/widget/todo/todo_row_item.dart b/lib/widget/todo/todo_row_item.dart index 0028ce93..f599f351 100644 --- a/lib/widget/todo/todo_row_item.dart +++ b/lib/widget/todo/todo_row_item.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:flutter_template/styles/theme_dimens.dart'; +import 'package:flutter_template/styles/theme_data.dart'; import 'package:flutter_template/widget/general/styled/flutter_template_checkbox.dart'; import 'package:flutter_template/widget/provider/data_provider_widget.dart'; @@ -23,15 +23,15 @@ class TodoRowItem extends StatelessWidget { child: Container( color: Colors.transparent, padding: const EdgeInsets.symmetric( - horizontal: ThemeDimens.padding16, - vertical: ThemeDimens.padding8, + horizontal: 16, + vertical: 8, ), child: Row( children: [ Expanded( child: Text( title, - style: theme.coreTextTheme.bodyNormal, + style: theme.text.bodyNormal, ), ), FlutterTemplateCheckBox( diff --git a/pubspec.lock b/pubspec.lock index d09ff617..60cbff4d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -457,6 +457,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.6.7" + firebase_storage: + dependency: "direct main" + description: + name: firebase_storage + sha256: "2ae478ceec9f458c1bcbf0ee3e0100e4e909708979e83f16d5d9fba35a5b42c1" + url: "https://pub.dev" + source: hosted + version: "11.7.7" + firebase_storage_platform_interface: + dependency: transitive + description: + name: firebase_storage_platform_interface + sha256: "4e18662e6a66e2e0e181c06f94707de06d5097d70cfe2b5141bf64660c5b5da9" + url: "https://pub.dev" + source: hosted + version: "5.1.22" + firebase_storage_web: + dependency: transitive + description: + name: firebase_storage_web + sha256: "3a44aacd38a372efb159f6fe36bb4a7d79823949383816457fd43d3d47602a53" + url: "https://pub.dev" + source: hosted + version: "3.9.7" fixnum: dependency: transitive description: @@ -478,6 +502,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.4.1" + flutter_key_value_file_storage: + dependency: transitive + description: + name: flutter_key_value_file_storage + sha256: a39cb3814eae20aa58747c874235d94411955df4bb287afb3aab12f1f2bbdfe6 + url: "https://pub.dev" + source: hosted + version: "0.0.8" flutter_launcher_icons: dependency: "direct dev" description: @@ -515,6 +547,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" + flutter_secure_file_storage: + dependency: transitive + description: + name: flutter_secure_file_storage + sha256: ea582e959c9ab8916041bf39c93ce0e5ccbd9e93c38d8424ef48b4cb4dd6a0c6 + url: "https://pub.dev" + source: hosted + version: "1.1.0" flutter_secure_storage: dependency: "direct main" description: @@ -678,7 +718,7 @@ packages: source: hosted version: "2.4.2" intl: - dependency: transitive + dependency: "direct main" description: name: intl sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf @@ -765,6 +805,15 @@ packages: url: "https://pub.dev" source: hosted version: "12.1.3" + log_to_secure_file: + dependency: "direct main" + description: + path: "." + ref: main + resolved-ref: "44e7f61a7c31e474274f613fcdd15bdd758e8a50" + url: "https://github.com/icapps/log_to_secure_file.git" + source: git + version: "1.0.0" logger: dependency: transitive description: @@ -949,6 +998,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + pointycastle: + dependency: transitive + description: + name: pointycastle + sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" + url: "https://pub.dev" + source: hosted + version: "3.9.1" pool: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index b7c96448..8c225a79 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,6 +2,8 @@ name: flutter_template description: A Flutter Template to get started quickly version: 1.0.0+1 +publish_to: none + environment: sdk: ">=3.0.0 <4.0.0" @@ -21,6 +23,7 @@ dependencies: firebase_core_web: ^2.1.0 firebase_crashlytics: ^3.0.10 firebase_remote_config: ^4.4.7 + firebase_storage: ^11.7.7 flutter: sdk: flutter flutter_cache_manager: ^3.3.0 @@ -35,7 +38,12 @@ dependencies: get_it: ^7.2.0 icapps_architecture: ^2.1.0 injectable: ^2.1.0 + intl: ^0.19.0 json_annotation: ^4.7.0 + log_to_secure_file: + git: + url: https://github.com/icapps/log_to_secure_file.git + ref: main niddler_dart: ^1.6.0 path: ^1.8.2 path_provider: ^2.0.11 @@ -49,7 +57,7 @@ dependencies: sprintf: ^7.0.0 sqlite3_flutter_libs: ^0.5.12 storage_inspector: ^0.4.0 - synchronized: ^3.0.1 + synchronized: ^3.3.0+3 url_launcher: ^6.3.1 dev_dependencies: @@ -77,8 +85,6 @@ flutter: - assets/locale/ - assets/images/ - assets/images/icons/ - - assets/images/icons/android/ - - assets/images/icons/ios/ fonts: - family: OpenSans fonts: diff --git a/test/database/drift_schemas/drift_schema_v1.json b/test/database/drift_schemas/drift_schema_v1.json new file mode 100644 index 00000000..a2d2981f --- /dev/null +++ b/test/database/drift_schemas/drift_schema_v1.json @@ -0,0 +1 @@ +{"_meta":{"description":"This file contains a serialized version of schema entities for drift.","version":"1.1.0"},"options":{"store_date_time_values_as_text":false},"entities":[{"id":0,"references":[],"type":"table","data":{"name":"db_todo_table","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"title","getter_name":"title","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"completed","getter_name":"completed","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"completed\" IN (0, 1))","default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}}]} \ No newline at end of file diff --git a/test/database/flutter_template_database_test.dart b/test/database/flutter_template_database_test.dart index bb38268d..2a1d8f46 100644 --- a/test/database/flutter_template_database_test.dart +++ b/test/database/flutter_template_database_test.dart @@ -3,6 +3,11 @@ import 'package:drift/native.dart'; import 'package:flutter_template/database/flutter_template_database.dart'; import 'package:flutter_test/flutter_test.dart'; +/// The schema version of the database that is being tested. +/// Update this when a new migration is added. +/// Also run ./tool/save_database_schema.sh to create the latest version schema file. +const schemaVersion = 1; + void main() { late FlutterTemplateDatabase sut; @@ -16,7 +21,7 @@ void main() { }); test('FlutterTemplateDatabase should have the correct version', () { - expect(sut.schemaVersion, 1); + expect(sut.schemaVersion, schemaVersion); }); test('FlutterTemplateDatabase should delete all tables', () async { diff --git a/test/database/flutter_template_migration_test.dart b/test/database/flutter_template_migration_test.dart new file mode 100644 index 00000000..bd46eb5d --- /dev/null +++ b/test/database/flutter_template_migration_test.dart @@ -0,0 +1,33 @@ +// ignore_for_file: avoid_print + +import 'package:drift_dev/api/migrations.dart'; +import 'package:flutter_template/database/flutter_template_database.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'flutter_template_database_test.dart'; +import 'schema_versions/schema.dart'; + + +void main() { + group('database migration tests', () { + late SchemaVerifier verifier; + + setUpAll(() { + verifier = SchemaVerifier(GeneratedHelper()); + }); + + test('upgrade from any to latest', () async { + for (var start = schemaVersion; start >= 1; start--) { + final connection = await verifier.startAt(start); + final db = FlutterTemplateDatabase(connection); + try { + await verifier.migrateAndValidate(db, schemaVersion); + } catch (e) { + print('Failed to migrate from $start to $schemaVersion'); + rethrow; + } + await db.close(); + } + }); + }); +} diff --git a/test/database/schema_versions/schema.dart b/test/database/schema_versions/schema.dart new file mode 100644 index 00000000..c9320642 --- /dev/null +++ b/test/database/schema_versions/schema.dart @@ -0,0 +1,18 @@ +// GENERATED CODE, DO NOT EDIT BY HAND. +// ignore_for_file: type=lint +//@dart=2.12 +import 'package:drift/drift.dart'; +import 'package:drift/internal/migrations.dart'; +import 'schema_v1.dart' as v1; + +class GeneratedHelper implements SchemaInstantiationHelper { + @override + GeneratedDatabase databaseForVersion(QueryExecutor db, int version) { + switch (version) { + case 1: + return v1.DatabaseAtV1(db); + default: + throw MissingSchemaException(version, const {1}); + } + } +} diff --git a/test/database/schema_versions/schema_v1.dart b/test/database/schema_versions/schema_v1.dart new file mode 100644 index 00000000..19ec0c78 --- /dev/null +++ b/test/database/schema_versions/schema_v1.dart @@ -0,0 +1,57 @@ +// GENERATED CODE, DO NOT EDIT BY HAND. +// ignore_for_file: type=lint +//@dart=2.12 +import 'package:drift/drift.dart'; + +class DbTodoTable extends Table with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + DbTodoTable(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', aliasedName, false, + hasAutoIncrement: true, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultConstraints: + GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT')); + late final GeneratedColumn title = GeneratedColumn( + 'title', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); + late final GeneratedColumn completed = GeneratedColumn( + 'completed', aliasedName, false, + type: DriftSqlType.bool, + requiredDuringInsert: true, + defaultConstraints: + GeneratedColumn.constraintIsAlways('CHECK ("completed" IN (0, 1))')); + @override + List get $columns => [id, title, completed]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'db_todo_table'; + @override + Set get $primaryKey => {id}; + @override + Never map(Map data, {String? tablePrefix}) { + throw UnsupportedError('TableInfo.map in schema verification code'); + } + + @override + DbTodoTable createAlias(String alias) { + return DbTodoTable(attachedDatabase, alias); + } +} + +class DatabaseAtV1 extends GeneratedDatabase { + DatabaseAtV1(QueryExecutor e) : super(e); + late final DbTodoTable dbTodoTable = DbTodoTable(this); + @override + Iterable> get allTables => + allSchemaEntities.whereType>(); + @override + List get allSchemaEntities => [dbTodoTable]; + @override + int get schemaVersion => 1; +} diff --git a/test/screen/debug/debug_platform_selector_screen_test.dart b/test/screen/debug/debug_platform_selector_screen_test.dart index 3d5125c0..68813f5d 100644 --- a/test/screen/debug/debug_platform_selector_screen_test.dart +++ b/test/screen/debug/debug_platform_selector_screen_test.dart @@ -1,10 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_template/di/injectable.dart'; import 'package:flutter_template/screen/debug/debug_platform_selector_screen.dart'; -import 'package:flutter_template/util/keys.dart'; import 'package:flutter_template/util/locale/localization_keys.dart'; import 'package:flutter_template/viewmodel/debug/debug_platform_selector_viewmodel.dart'; -import 'package:flutter_template/viewmodel/global/global_viewmodel.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; @@ -15,17 +13,13 @@ import '../seed.dart'; import 'debug_platform_selector_screen_test.mocks.dart'; @GenerateMocks([ - GlobalViewModel, DebugPlatformSelectorViewModel, ]) void main() { - late MockGlobalViewModel globalViewModel; late MockDebugPlatformSelectorViewModel platformViewModel; setUp(() async { platformViewModel = MockDebugPlatformSelectorViewModel(); - globalViewModel = MockGlobalViewModel(); - getIt.registerSingleton(globalViewModel); getIt.registerSingleton(platformViewModel); }); @@ -34,7 +28,7 @@ void main() { }); testWidgets('Test debug select platform screen initial state light mode', (tester) async { - seedGlobalViewModel(); + when(platformViewModel.selectedPlatform).thenReturn(TargetPlatform.android); const sut = DebugPlatformSelectorScreen(); final testWidget = await TestUtil.loadScreen(tester, sut); @@ -43,7 +37,7 @@ void main() { }); testWidgets('Test debug select platform screen initial state dark mode', (tester) async { - seedGlobalViewModel(); + when(platformViewModel.selectedPlatform).thenReturn(TargetPlatform.android); const sut = DebugPlatformSelectorScreen(); final testWidget = await TestUtil.loadScreen(tester, sut, themeMode: ThemeMode.dark); @@ -52,28 +46,26 @@ void main() { }); testWidgets('Test debug screen select platform and select correct platform', (tester) async { - seedGlobalViewModel(); - when(globalViewModel.targetPlatform).thenReturn(TargetPlatform.android); + when(platformViewModel.selectedPlatform).thenReturn(TargetPlatform.android); const sut = DebugPlatformSelectorScreen(); final testWidget = await TestUtil.loadScreen(tester, sut); await TestUtil.takeScreenshotForAllSizes(tester, testWidget, 'debug_platform_selector_screen_selected_android'); - when(globalViewModel.targetPlatform).thenReturn(TargetPlatform.iOS); - globalViewModel.notifyListeners(); + when(platformViewModel.selectedPlatform).thenReturn(TargetPlatform.iOS); + platformViewModel.notifyListeners(); await tester.pumpAndSettle(); await TestUtil.takeScreenshotForAllSizes(tester, testWidget, 'debug_platform_selector_screen_selected_ios'); - when(globalViewModel.targetPlatform).thenReturn(null); - globalViewModel.notifyListeners(); + when(platformViewModel.selectedPlatform).thenReturn(null); + platformViewModel.notifyListeners(); await tester.pumpAndSettle(); await TestUtil.takeScreenshotForAllSizes(tester, testWidget, 'debug_platform_selector_screen_selected_system'); }); group('setCorrectPlatform', () { testWidgets('Test debug screen select platform click on system', (tester) async { - seedGlobalViewModel(); - when(globalViewModel.targetPlatform).thenReturn(null); + when(platformViewModel.selectedPlatform).thenReturn(null); // ignore: void_checks when(platformViewModel.dispose()).thenReturn(1); @@ -88,13 +80,12 @@ void main() { await tester.tap(target); await tester.pumpAndSettle(); - verify(globalViewModel.setSelectedPlatformToDefault()).calledOnce(); + verify(platformViewModel.setSelectedPlatformToDefault()).calledOnce(); verifyGlobalViewModel(); }); testWidgets('Test debug select platform screen select ios', (tester) async { - seedGlobalViewModel(); - when(globalViewModel.targetPlatform).thenReturn(TargetPlatform.iOS); + when(platformViewModel.selectedPlatform).thenReturn(TargetPlatform.iOS); const sut = DebugPlatformSelectorScreen(); await TestUtil.loadScreen(tester, sut); @@ -107,13 +98,12 @@ void main() { await tester.tap(target); await tester.pumpAndSettle(); - verify(globalViewModel.setSelectedPlatformToIOS()).calledOnce(); + verify(platformViewModel.setSelectedPlatformToIOS()).calledOnce(); verifyGlobalViewModel(); }); testWidgets('Test debug select platform screen select android', (tester) async { - seedGlobalViewModel(); - when(globalViewModel.targetPlatform).thenReturn(null); + when(platformViewModel.selectedPlatform).thenReturn(null); const sut = DebugPlatformSelectorScreen(); await TestUtil.loadScreen(tester, sut); @@ -125,29 +115,8 @@ void main() { await tester.tap(target); await tester.pumpAndSettle(); - verify(globalViewModel.setSelectedPlatformToAndroid()).calledOnce(); + verify(platformViewModel.setSelectedPlatformToAndroid()).calledOnce(); verifyGlobalViewModel(); }); }); - - group('Actions', () { - testWidgets('Test debug select platform screen on back clicked', (tester) async { - seedGlobalViewModel(); - when(globalViewModel.targetPlatform).thenReturn(null); - - const sut = DebugPlatformSelectorScreen(); - await TestUtil.loadScreen(tester, sut); - // ignore: void_checks - when(platformViewModel.dispose()).thenReturn(1); - // ignore: void_checks - when(platformViewModel.onBackClicked()).thenReturn(1); - - final target = find.byKey(Keys.backButton); - expect(target, findsOneWidget); - await tester.tap(target); - await tester.pumpAndSettle(); - - verify(platformViewModel.onBackClicked()).calledOnce(); - }); - }); } diff --git a/test/screen/debug/debug_platform_selector_screen_test.mocks.dart b/test/screen/debug/debug_platform_selector_screen_test.mocks.dart index 40edc74e..91697a25 100644 --- a/test/screen/debug/debug_platform_selector_screen_test.mocks.dart +++ b/test/screen/debug/debug_platform_selector_screen_test.mocks.dart @@ -6,14 +6,10 @@ import 'dart:async' as _i5; import 'dart:ui' as _i3; -import 'package:flutter/material.dart' as _i4; -import 'package:flutter_template/util/locale/localization.dart' as _i7; import 'package:flutter_template/viewmodel/debug/debug_platform_selector_viewmodel.dart' - as _i9; -import 'package:flutter_template/viewmodel/global/global_viewmodel.dart' as _i2; -import 'package:icapps_architecture/icapps_architecture.dart' as _i8; + as _i2; +import 'package:icapps_architecture/icapps_architecture.dart' as _i4; import 'package:mockito/mockito.dart' as _i1; -import 'package:mockito/src/dummies.dart' as _i6; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -28,32 +24,15 @@ import 'package:mockito/src/dummies.dart' as _i6; // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class -/// A class which mocks [GlobalViewModel]. +/// A class which mocks [DebugPlatformSelectorViewModel]. /// /// See the documentation for Mockito's code generation for more information. -class MockGlobalViewModel extends _i1.Mock implements _i2.GlobalViewModel { - MockGlobalViewModel() { +class MockDebugPlatformSelectorViewModel extends _i1.Mock + implements _i2.DebugPlatformSelectorViewModel { + MockDebugPlatformSelectorViewModel() { _i1.throwOnMissingStub(this); } - @override - List<_i3.Locale> get supportedLocales => (super.noSuchMethod( - Invocation.getter(#supportedLocales), - returnValue: <_i3.Locale>[], - ) as List<_i3.Locale>); - - @override - _i4.ThemeMode get themeMode => (super.noSuchMethod( - Invocation.getter(#themeMode), - returnValue: _i4.ThemeMode.system, - ) as _i4.ThemeMode); - - @override - bool get showsTranslationKeys => (super.noSuchMethod( - Invocation.getter(#showsTranslationKeys), - returnValue: false, - ) as bool); - @override bool get disposed => (super.noSuchMethod( Invocation.getter(#disposed), @@ -67,240 +46,36 @@ class MockGlobalViewModel extends _i1.Mock implements _i2.GlobalViewModel { ) as bool); @override - _i5.Future init() => (super.noSuchMethod( - Invocation.method( - #init, - [], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); - - @override - _i5.Future updateThemeMode(_i4.ThemeMode? themeMode) => - (super.noSuchMethod( - Invocation.method( - #updateThemeMode, - [themeMode], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); - - @override - _i5.Future onSwitchToDutch() => (super.noSuchMethod( - Invocation.method( - #onSwitchToDutch, - [], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); - - @override - _i5.Future onSwitchToEnglish() => (super.noSuchMethod( - Invocation.method( - #onSwitchToEnglish, - [], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); - - @override - _i5.Future onSwitchToSystemLanguage() => (super.noSuchMethod( - Invocation.method( - #onSwitchToSystemLanguage, - [], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); - - @override - _i5.Future setSelectedPlatformToAndroid() => (super.noSuchMethod( - Invocation.method( - #setSelectedPlatformToAndroid, - [], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); - - @override - _i5.Future setSelectedPlatformToIOS() => (super.noSuchMethod( - Invocation.method( - #setSelectedPlatformToIOS, - [], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); - - @override - _i5.Future setSelectedPlatformToDefault() => (super.noSuchMethod( - Invocation.method( - #setSelectedPlatformToDefault, - [], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); - - @override - String getCurrentPlatform() => (super.noSuchMethod( - Invocation.method( - #getCurrentPlatform, - [], - ), - returnValue: _i6.dummyValue( - this, - Invocation.method( - #getCurrentPlatform, - [], - ), - ), - ) as String); - - @override - String getAppearanceValue(_i7.Localization? localization) => - (super.noSuchMethod( - Invocation.method( - #getAppearanceValue, - [localization], - ), - returnValue: _i6.dummyValue( - this, - Invocation.method( - #getAppearanceValue, - [localization], - ), - ), - ) as String); - - @override - String getCurrentLanguage() => (super.noSuchMethod( - Invocation.method( - #getCurrentLanguage, - [], - ), - returnValue: _i6.dummyValue( - this, - Invocation.method( - #getCurrentLanguage, - [], - ), - ), - ) as String); - - @override - bool isLanguageSelected(String? languageCode) => (super.noSuchMethod( - Invocation.method( - #isLanguageSelected, - [languageCode], - ), - returnValue: false, - ) as bool); - - @override - void toggleTranslationKeys() => super.noSuchMethod( - Invocation.method( - #toggleTranslationKeys, - [], - ), - returnValueForMissingStub: null, - ); - - @override - void overrideLocalizations() => super.noSuchMethod( + void onBackClicked() => super.noSuchMethod( Invocation.method( - #overrideLocalizations, + #onBackClicked, [], ), returnValueForMissingStub: null, ); @override - void dispose() => super.noSuchMethod( + void setSelectedPlatformToDefault() => super.noSuchMethod( Invocation.method( - #dispose, + #setSelectedPlatformToDefault, [], ), returnValueForMissingStub: null, ); @override - void addListener(_i3.VoidCallback? listener) => super.noSuchMethod( - Invocation.method( - #addListener, - [listener], - ), - returnValueForMissingStub: null, - ); - - @override - void removeListener(_i3.VoidCallback? listener) => super.noSuchMethod( + void setSelectedPlatformToAndroid() => super.noSuchMethod( Invocation.method( - #removeListener, - [listener], - ), - returnValueForMissingStub: null, - ); - - @override - void registerDispose(_i8.DisposeAware? toDispose) => super.noSuchMethod( - Invocation.method( - #registerDispose, - [toDispose], - ), - returnValueForMissingStub: null, - ); - - @override - void registerDisposeStream(_i5.StreamSubscription? subscription) => - super.noSuchMethod( - Invocation.method( - #registerDisposeStream, - [subscription], - ), - returnValueForMissingStub: null, - ); - - @override - void notifyListeners() => super.noSuchMethod( - Invocation.method( - #notifyListeners, + #setSelectedPlatformToAndroid, [], ), returnValueForMissingStub: null, ); -} - -/// A class which mocks [DebugPlatformSelectorViewModel]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockDebugPlatformSelectorViewModel extends _i1.Mock - implements _i9.DebugPlatformSelectorViewModel { - MockDebugPlatformSelectorViewModel() { - _i1.throwOnMissingStub(this); - } - - @override - bool get disposed => (super.noSuchMethod( - Invocation.getter(#disposed), - returnValue: false, - ) as bool); @override - bool get hasListeners => (super.noSuchMethod( - Invocation.getter(#hasListeners), - returnValue: false, - ) as bool); - - @override - void onBackClicked() => super.noSuchMethod( + void setSelectedPlatformToIOS() => super.noSuchMethod( Invocation.method( - #onBackClicked, + #setSelectedPlatformToIOS, [], ), returnValueForMissingStub: null, @@ -334,7 +109,7 @@ class MockDebugPlatformSelectorViewModel extends _i1.Mock ); @override - void registerDispose(_i8.DisposeAware? toDispose) => super.noSuchMethod( + void registerDispose(_i4.DisposeAware? toDispose) => super.noSuchMethod( Invocation.method( #registerDispose, [toDispose], diff --git a/test/screen/debug/debug_screen_test.mocks.dart b/test/screen/debug/debug_screen_test.mocks.dart index c6382915..19845d3f 100644 --- a/test/screen/debug/debug_screen_test.mocks.dart +++ b/test/screen/debug/debug_screen_test.mocks.dart @@ -146,6 +146,15 @@ class MockDebugViewModel extends _i1.Mock implements _i2.DebugViewModel { returnValueForMissingStub: null, ); + @override + void onLogsTapped() => super.noSuchMethod( + Invocation.method( + #onLogsTapped, + [], + ), + returnValueForMissingStub: null, + ); + @override void dispose() => super.noSuchMethod( Invocation.method( diff --git a/test/screen/debug/img/debug_platform_selector_screen_inital_state_darkmode_ipad_pro.png b/test/screen/debug/img/debug_platform_selector_screen_inital_state_darkmode_ipad_pro.png index 4c905893..83fb66bd 100644 Binary files a/test/screen/debug/img/debug_platform_selector_screen_inital_state_darkmode_ipad_pro.png and b/test/screen/debug/img/debug_platform_selector_screen_inital_state_darkmode_ipad_pro.png differ diff --git a/test/screen/debug/img/debug_platform_selector_screen_inital_state_darkmode_iphone_11.png b/test/screen/debug/img/debug_platform_selector_screen_inital_state_darkmode_iphone_11.png index 7dcb3305..2ede885a 100644 Binary files a/test/screen/debug/img/debug_platform_selector_screen_inital_state_darkmode_iphone_11.png and b/test/screen/debug/img/debug_platform_selector_screen_inital_state_darkmode_iphone_11.png differ diff --git a/test/screen/debug/img/debug_platform_selector_screen_inital_state_lightmode_ipad_pro.png b/test/screen/debug/img/debug_platform_selector_screen_inital_state_lightmode_ipad_pro.png index a2ee015e..cb05c778 100644 Binary files a/test/screen/debug/img/debug_platform_selector_screen_inital_state_lightmode_ipad_pro.png and b/test/screen/debug/img/debug_platform_selector_screen_inital_state_lightmode_ipad_pro.png differ diff --git a/test/screen/debug/img/debug_platform_selector_screen_inital_state_lightmode_iphone_11.png b/test/screen/debug/img/debug_platform_selector_screen_inital_state_lightmode_iphone_11.png index 572c8f3c..a0df3692 100644 Binary files a/test/screen/debug/img/debug_platform_selector_screen_inital_state_lightmode_iphone_11.png and b/test/screen/debug/img/debug_platform_selector_screen_inital_state_lightmode_iphone_11.png differ diff --git a/test/screen/debug/img/debug_platform_selector_screen_selected_android_ipad_pro.png b/test/screen/debug/img/debug_platform_selector_screen_selected_android_ipad_pro.png index a2ee015e..cb05c778 100644 Binary files a/test/screen/debug/img/debug_platform_selector_screen_selected_android_ipad_pro.png and b/test/screen/debug/img/debug_platform_selector_screen_selected_android_ipad_pro.png differ diff --git a/test/screen/debug/img/debug_platform_selector_screen_selected_android_iphone_11.png b/test/screen/debug/img/debug_platform_selector_screen_selected_android_iphone_11.png index 572c8f3c..a0df3692 100644 Binary files a/test/screen/debug/img/debug_platform_selector_screen_selected_android_iphone_11.png and b/test/screen/debug/img/debug_platform_selector_screen_selected_android_iphone_11.png differ diff --git a/test/screen/debug/img/debug_platform_selector_screen_selected_ios_ipad_pro.png b/test/screen/debug/img/debug_platform_selector_screen_selected_ios_ipad_pro.png index a2ee015e..cb05c778 100644 Binary files a/test/screen/debug/img/debug_platform_selector_screen_selected_ios_ipad_pro.png and b/test/screen/debug/img/debug_platform_selector_screen_selected_ios_ipad_pro.png differ diff --git a/test/screen/debug/img/debug_platform_selector_screen_selected_ios_iphone_11.png b/test/screen/debug/img/debug_platform_selector_screen_selected_ios_iphone_11.png index 572c8f3c..a0df3692 100644 Binary files a/test/screen/debug/img/debug_platform_selector_screen_selected_ios_iphone_11.png and b/test/screen/debug/img/debug_platform_selector_screen_selected_ios_iphone_11.png differ diff --git a/test/screen/debug/img/debug_platform_selector_screen_selected_system_ipad_pro.png b/test/screen/debug/img/debug_platform_selector_screen_selected_system_ipad_pro.png index a2ee015e..cb05c778 100644 Binary files a/test/screen/debug/img/debug_platform_selector_screen_selected_system_ipad_pro.png and b/test/screen/debug/img/debug_platform_selector_screen_selected_system_ipad_pro.png differ diff --git a/test/screen/debug/img/debug_platform_selector_screen_selected_system_iphone_11.png b/test/screen/debug/img/debug_platform_selector_screen_selected_system_iphone_11.png index 572c8f3c..a0df3692 100644 Binary files a/test/screen/debug/img/debug_platform_selector_screen_selected_system_iphone_11.png and b/test/screen/debug/img/debug_platform_selector_screen_selected_system_iphone_11.png differ diff --git a/test/screen/debug/img/debug_screen_inital_state_ipad_pro.png b/test/screen/debug/img/debug_screen_inital_state_ipad_pro.png index 22399d3b..90a52528 100644 Binary files a/test/screen/debug/img/debug_screen_inital_state_ipad_pro.png and b/test/screen/debug/img/debug_screen_inital_state_ipad_pro.png differ diff --git a/test/screen/debug/img/debug_screen_inital_state_iphone_11.png b/test/screen/debug/img/debug_screen_inital_state_iphone_11.png index 3d7215a5..64408fd8 100644 Binary files a/test/screen/debug/img/debug_screen_inital_state_iphone_11.png and b/test/screen/debug/img/debug_screen_inital_state_iphone_11.png differ diff --git a/test/screen/debug/img/debug_screen_show_locale_key_disabled_ipad_pro.png b/test/screen/debug/img/debug_screen_show_locale_key_disabled_ipad_pro.png index 22399d3b..90a52528 100644 Binary files a/test/screen/debug/img/debug_screen_show_locale_key_disabled_ipad_pro.png and b/test/screen/debug/img/debug_screen_show_locale_key_disabled_ipad_pro.png differ diff --git a/test/screen/debug/img/debug_screen_show_locale_key_disabled_iphone_11.png b/test/screen/debug/img/debug_screen_show_locale_key_disabled_iphone_11.png index 3d7215a5..64408fd8 100644 Binary files a/test/screen/debug/img/debug_screen_show_locale_key_disabled_iphone_11.png and b/test/screen/debug/img/debug_screen_show_locale_key_disabled_iphone_11.png differ diff --git a/test/screen/debug/img/debug_screen_show_locale_key_enabled_ipad_pro.png b/test/screen/debug/img/debug_screen_show_locale_key_enabled_ipad_pro.png index f3dc46cc..342e2448 100644 Binary files a/test/screen/debug/img/debug_screen_show_locale_key_enabled_ipad_pro.png and b/test/screen/debug/img/debug_screen_show_locale_key_enabled_ipad_pro.png differ diff --git a/test/screen/debug/img/debug_screen_show_locale_key_enabled_iphone_11.png b/test/screen/debug/img/debug_screen_show_locale_key_enabled_iphone_11.png index afca11a2..8ade57fc 100644 Binary files a/test/screen/debug/img/debug_screen_show_locale_key_enabled_iphone_11.png and b/test/screen/debug/img/debug_screen_show_locale_key_enabled_iphone_11.png differ diff --git a/test/screen/debug/img/debug_screen_slow_animations_disabled_ipad_pro.png b/test/screen/debug/img/debug_screen_slow_animations_disabled_ipad_pro.png index 22399d3b..90a52528 100644 Binary files a/test/screen/debug/img/debug_screen_slow_animations_disabled_ipad_pro.png and b/test/screen/debug/img/debug_screen_slow_animations_disabled_ipad_pro.png differ diff --git a/test/screen/debug/img/debug_screen_slow_animations_disabled_iphone_11.png b/test/screen/debug/img/debug_screen_slow_animations_disabled_iphone_11.png index 3d7215a5..64408fd8 100644 Binary files a/test/screen/debug/img/debug_screen_slow_animations_disabled_iphone_11.png and b/test/screen/debug/img/debug_screen_slow_animations_disabled_iphone_11.png differ diff --git a/test/screen/debug/img/debug_screen_slow_animations_enabled_ipad_pro.png b/test/screen/debug/img/debug_screen_slow_animations_enabled_ipad_pro.png index c195278d..447775c7 100644 Binary files a/test/screen/debug/img/debug_screen_slow_animations_enabled_ipad_pro.png and b/test/screen/debug/img/debug_screen_slow_animations_enabled_ipad_pro.png differ diff --git a/test/screen/debug/img/debug_screen_slow_animations_enabled_iphone_11.png b/test/screen/debug/img/debug_screen_slow_animations_enabled_iphone_11.png index b2bc47ae..dd03d5d5 100644 Binary files a/test/screen/debug/img/debug_screen_slow_animations_enabled_iphone_11.png and b/test/screen/debug/img/debug_screen_slow_animations_enabled_iphone_11.png differ diff --git a/test/screen/home/home_screen_test.dart b/test/screen/home/home_screen_test.dart index e357bed7..d2481b15 100644 --- a/test/screen/home/home_screen_test.dart +++ b/test/screen/home/home_screen_test.dart @@ -5,6 +5,7 @@ import 'package:flutter_template/screen/home/home_screen.dart'; import 'package:flutter_template/viewmodel/debug/debug_viewmodel.dart'; import 'package:flutter_template/viewmodel/global/global_viewmodel.dart'; import 'package:flutter_template/viewmodel/todo/todo_list/todo_list_viewmodel.dart'; +import 'package:flutter_template/widget/general/bottom_navigation/bottom_navigation_item.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; @@ -46,15 +47,13 @@ void main() { verifyGlobalViewModelForDebugScreen(); verifyGlobalViewModel(); - final firstTab = find.byIcon(Icons.list); - expect(firstTab, findsOneWidget); - await tester.tap(firstTab); + final firstTab = find.byType(BottomNavigationItem); + await tester.tap(firstTab.first); await tester.pumpAndSettle(); await TestUtil.takeScreenshotForAllSizes(tester, testWidget, 'home_screen_initial_state_first_tab'); - final secondTab = find.byIcon(Icons.settings); - expect(secondTab, findsOneWidget); - await tester.tap(firstTab); + final secondTab = find.byType(BottomNavigationItem); + await tester.tap(secondTab.last); await tester.pumpAndSettle(); await TestUtil.takeScreenshotForAllSizes(tester, testWidget, 'home_screen_initial_state_second_tab'); }); @@ -74,15 +73,13 @@ void main() { verifyGlobalViewModelForDebugScreen(); verifyGlobalViewModel(); - final firstTab = find.byIcon(Icons.list); - expect(firstTab, findsOneWidget); - await tester.tap(firstTab); + final firstTab = find.byType(BottomNavigationItem); + await tester.tap(firstTab.first); await tester.pumpAndSettle(); await TestUtil.takeScreenshotForAllSizes(tester, testWidget, 'home_screen_initial_state_first_tab_darkmode'); - final secondTab = find.byIcon(Icons.settings); - expect(secondTab, findsOneWidget); - await tester.tap(firstTab); + final secondTab = find.byType(BottomNavigationItem); + await tester.tap(secondTab.last); await tester.pumpAndSettle(); await TestUtil.takeScreenshotForAllSizes(tester, testWidget, 'home_screen_initial_state_second_tab_darkmode'); }); diff --git a/test/screen/home/home_screen_test.mocks.dart b/test/screen/home/home_screen_test.mocks.dart index ec37842e..48830a0f 100644 --- a/test/screen/home/home_screen_test.mocks.dart +++ b/test/screen/home/home_screen_test.mocks.dart @@ -534,6 +534,15 @@ class MockDebugViewModel extends _i1.Mock implements _i11.DebugViewModel { returnValueForMissingStub: null, ); + @override + void onLogsTapped() => super.noSuchMethod( + Invocation.method( + #onLogsTapped, + [], + ), + returnValueForMissingStub: null, + ); + @override void dispose() => super.noSuchMethod( Invocation.method( diff --git a/test/screen/home/img/home_screen_initial_state_darkmode_ipad_pro.png b/test/screen/home/img/home_screen_initial_state_darkmode_ipad_pro.png index bd20306d..3bb0e917 100644 Binary files a/test/screen/home/img/home_screen_initial_state_darkmode_ipad_pro.png and b/test/screen/home/img/home_screen_initial_state_darkmode_ipad_pro.png differ diff --git a/test/screen/home/img/home_screen_initial_state_darkmode_iphone_11.png b/test/screen/home/img/home_screen_initial_state_darkmode_iphone_11.png index 52098888..e01a3468 100644 Binary files a/test/screen/home/img/home_screen_initial_state_darkmode_iphone_11.png and b/test/screen/home/img/home_screen_initial_state_darkmode_iphone_11.png differ diff --git a/test/screen/home/img/home_screen_initial_state_first_tab_darkmode_ipad_pro.png b/test/screen/home/img/home_screen_initial_state_first_tab_darkmode_ipad_pro.png index bd20306d..3bb0e917 100644 Binary files a/test/screen/home/img/home_screen_initial_state_first_tab_darkmode_ipad_pro.png and b/test/screen/home/img/home_screen_initial_state_first_tab_darkmode_ipad_pro.png differ diff --git a/test/screen/home/img/home_screen_initial_state_first_tab_darkmode_iphone_11.png b/test/screen/home/img/home_screen_initial_state_first_tab_darkmode_iphone_11.png index 52098888..e01a3468 100644 Binary files a/test/screen/home/img/home_screen_initial_state_first_tab_darkmode_iphone_11.png and b/test/screen/home/img/home_screen_initial_state_first_tab_darkmode_iphone_11.png differ diff --git a/test/screen/home/img/home_screen_initial_state_first_tab_ipad_pro.png b/test/screen/home/img/home_screen_initial_state_first_tab_ipad_pro.png index 5e9c2fd4..f6195eb0 100644 Binary files a/test/screen/home/img/home_screen_initial_state_first_tab_ipad_pro.png and b/test/screen/home/img/home_screen_initial_state_first_tab_ipad_pro.png differ diff --git a/test/screen/home/img/home_screen_initial_state_first_tab_iphone_11.png b/test/screen/home/img/home_screen_initial_state_first_tab_iphone_11.png index 4997ae35..f9511091 100644 Binary files a/test/screen/home/img/home_screen_initial_state_first_tab_iphone_11.png and b/test/screen/home/img/home_screen_initial_state_first_tab_iphone_11.png differ diff --git a/test/screen/home/img/home_screen_initial_state_ipad_pro.png b/test/screen/home/img/home_screen_initial_state_ipad_pro.png index 5e9c2fd4..f6195eb0 100644 Binary files a/test/screen/home/img/home_screen_initial_state_ipad_pro.png and b/test/screen/home/img/home_screen_initial_state_ipad_pro.png differ diff --git a/test/screen/home/img/home_screen_initial_state_iphone_11.png b/test/screen/home/img/home_screen_initial_state_iphone_11.png index 4997ae35..f9511091 100644 Binary files a/test/screen/home/img/home_screen_initial_state_iphone_11.png and b/test/screen/home/img/home_screen_initial_state_iphone_11.png differ diff --git a/test/screen/home/img/home_screen_initial_state_second_tab_darkmode_ipad_pro.png b/test/screen/home/img/home_screen_initial_state_second_tab_darkmode_ipad_pro.png index bd20306d..0ce65696 100644 Binary files a/test/screen/home/img/home_screen_initial_state_second_tab_darkmode_ipad_pro.png and b/test/screen/home/img/home_screen_initial_state_second_tab_darkmode_ipad_pro.png differ diff --git a/test/screen/home/img/home_screen_initial_state_second_tab_darkmode_iphone_11.png b/test/screen/home/img/home_screen_initial_state_second_tab_darkmode_iphone_11.png index 52098888..eb81a13c 100644 Binary files a/test/screen/home/img/home_screen_initial_state_second_tab_darkmode_iphone_11.png and b/test/screen/home/img/home_screen_initial_state_second_tab_darkmode_iphone_11.png differ diff --git a/test/screen/home/img/home_screen_initial_state_second_tab_ipad_pro.png b/test/screen/home/img/home_screen_initial_state_second_tab_ipad_pro.png index 5e9c2fd4..1d7195b6 100644 Binary files a/test/screen/home/img/home_screen_initial_state_second_tab_ipad_pro.png and b/test/screen/home/img/home_screen_initial_state_second_tab_ipad_pro.png differ diff --git a/test/screen/home/img/home_screen_initial_state_second_tab_iphone_11.png b/test/screen/home/img/home_screen_initial_state_second_tab_iphone_11.png index 4997ae35..049369bb 100644 Binary files a/test/screen/home/img/home_screen_initial_state_second_tab_iphone_11.png and b/test/screen/home/img/home_screen_initial_state_second_tab_iphone_11.png differ diff --git a/test/screen/license/img/license_screen_empty_list_ipad_pro.png b/test/screen/license/img/license_screen_empty_list_ipad_pro.png index 30900d4b..20fbbdc9 100644 Binary files a/test/screen/license/img/license_screen_empty_list_ipad_pro.png and b/test/screen/license/img/license_screen_empty_list_ipad_pro.png differ diff --git a/test/screen/license/img/license_screen_empty_list_iphone_11.png b/test/screen/license/img/license_screen_empty_list_iphone_11.png index 573cb762..03415aa7 100644 Binary files a/test/screen/license/img/license_screen_empty_list_iphone_11.png and b/test/screen/license/img/license_screen_empty_list_iphone_11.png differ diff --git a/test/screen/license/img/license_screen_inital_state_dark_mode_ipad_pro.png b/test/screen/license/img/license_screen_inital_state_dark_mode_ipad_pro.png index 49105b56..c1a764c9 100644 Binary files a/test/screen/license/img/license_screen_inital_state_dark_mode_ipad_pro.png and b/test/screen/license/img/license_screen_inital_state_dark_mode_ipad_pro.png differ diff --git a/test/screen/license/img/license_screen_inital_state_dark_mode_iphone_11.png b/test/screen/license/img/license_screen_inital_state_dark_mode_iphone_11.png index b8b8e5dc..110cdebf 100644 Binary files a/test/screen/license/img/license_screen_inital_state_dark_mode_iphone_11.png and b/test/screen/license/img/license_screen_inital_state_dark_mode_iphone_11.png differ diff --git a/test/screen/license/img/license_screen_inital_state_ipad_pro.png b/test/screen/license/img/license_screen_inital_state_ipad_pro.png index e275ddd9..5850646d 100644 Binary files a/test/screen/license/img/license_screen_inital_state_ipad_pro.png and b/test/screen/license/img/license_screen_inital_state_ipad_pro.png differ diff --git a/test/screen/license/img/license_screen_inital_state_iphone_11.png b/test/screen/license/img/license_screen_inital_state_iphone_11.png index 4b1d07f5..5f38a0b3 100644 Binary files a/test/screen/license/img/license_screen_inital_state_iphone_11.png and b/test/screen/license/img/license_screen_inital_state_iphone_11.png differ diff --git a/test/screen/license/license_screen_test.dart b/test/screen/license/license_screen_test.dart index aac8626a..9a7791cd 100644 --- a/test/screen/license/license_screen_test.dart +++ b/test/screen/license/license_screen_test.dart @@ -1,14 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_template/di/injectable.dart'; import 'package:flutter_template/screen/license/license_screen.dart'; -import 'package:flutter_template/util/keys.dart'; import 'package:flutter_template/viewmodel/global/global_viewmodel.dart'; import 'package:flutter_template/viewmodel/license/license_viewmodel.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; -import '../../util/test_extensions.dart'; import '../../util/test_util.dart'; import '../seed.dart'; import 'license_screen_test.mocks.dart'; @@ -57,19 +55,6 @@ void main() { await TestUtil.takeScreenshotForAllSizes(tester, testWidget, 'license_screen_empty_list'); }); - - group('Actions', () { - testWidgets('Test license screen on back clicked', (tester) async { - const sut = LicenseScreen(); - await TestUtil.loadScreen(tester, sut); - - final target = find.byKey(Keys.backButton); - expect(target, findsOneWidget); - await tester.tap(target); - await tester.pumpAndSettle(); - verify(licenseViewModel.onBackClicked()).calledOnce(); - }); - }); } void verifyLicenseViewModel() { diff --git a/test/screen/login/img/login_screen_initial_state_dark_mode_ipad_pro.png b/test/screen/login/img/login_screen_initial_state_dark_mode_ipad_pro.png index 594cc7e5..31aeab45 100644 Binary files a/test/screen/login/img/login_screen_initial_state_dark_mode_ipad_pro.png and b/test/screen/login/img/login_screen_initial_state_dark_mode_ipad_pro.png differ diff --git a/test/screen/login/img/login_screen_initial_state_dark_mode_iphone_11.png b/test/screen/login/img/login_screen_initial_state_dark_mode_iphone_11.png index 577f7fac..3a0be798 100644 Binary files a/test/screen/login/img/login_screen_initial_state_dark_mode_iphone_11.png and b/test/screen/login/img/login_screen_initial_state_dark_mode_iphone_11.png differ diff --git a/test/screen/login/img/login_screen_initial_state_ipad_pro.png b/test/screen/login/img/login_screen_initial_state_ipad_pro.png index a93a7a5e..f785ecda 100644 Binary files a/test/screen/login/img/login_screen_initial_state_ipad_pro.png and b/test/screen/login/img/login_screen_initial_state_ipad_pro.png differ diff --git a/test/screen/login/img/login_screen_initial_state_iphone_11.png b/test/screen/login/img/login_screen_initial_state_iphone_11.png index ea15aa0c..b500ea42 100644 Binary files a/test/screen/login/img/login_screen_initial_state_iphone_11.png and b/test/screen/login/img/login_screen_initial_state_iphone_11.png differ diff --git a/test/screen/login/img/login_screen_login_button_disabled_ipad_pro.png b/test/screen/login/img/login_screen_login_button_disabled_ipad_pro.png index 81d2ff32..2be31ce0 100644 Binary files a/test/screen/login/img/login_screen_login_button_disabled_ipad_pro.png and b/test/screen/login/img/login_screen_login_button_disabled_ipad_pro.png differ diff --git a/test/screen/login/img/login_screen_login_button_disabled_iphone_11.png b/test/screen/login/img/login_screen_login_button_disabled_iphone_11.png index a7d8a0f8..6e029465 100644 Binary files a/test/screen/login/img/login_screen_login_button_disabled_iphone_11.png and b/test/screen/login/img/login_screen_login_button_disabled_iphone_11.png differ diff --git a/test/screen/permission/img/analytics_permission_screen_initial_state_dark_mode_ipad_pro.png b/test/screen/permission/img/analytics_permission_screen_initial_state_dark_mode_ipad_pro.png index 168e9d29..049ac764 100644 Binary files a/test/screen/permission/img/analytics_permission_screen_initial_state_dark_mode_ipad_pro.png and b/test/screen/permission/img/analytics_permission_screen_initial_state_dark_mode_ipad_pro.png differ diff --git a/test/screen/permission/img/analytics_permission_screen_initial_state_dark_mode_iphone_11.png b/test/screen/permission/img/analytics_permission_screen_initial_state_dark_mode_iphone_11.png index eabe42d6..d4e67bb4 100644 Binary files a/test/screen/permission/img/analytics_permission_screen_initial_state_dark_mode_iphone_11.png and b/test/screen/permission/img/analytics_permission_screen_initial_state_dark_mode_iphone_11.png differ diff --git a/test/screen/permission/img/analytics_permission_screen_initial_state_light_mode_ipad_pro.png b/test/screen/permission/img/analytics_permission_screen_initial_state_light_mode_ipad_pro.png index 168e9d29..049ac764 100644 Binary files a/test/screen/permission/img/analytics_permission_screen_initial_state_light_mode_ipad_pro.png and b/test/screen/permission/img/analytics_permission_screen_initial_state_light_mode_ipad_pro.png differ diff --git a/test/screen/permission/img/analytics_permission_screen_initial_state_light_mode_iphone_11.png b/test/screen/permission/img/analytics_permission_screen_initial_state_light_mode_iphone_11.png index eabe42d6..d4e67bb4 100644 Binary files a/test/screen/permission/img/analytics_permission_screen_initial_state_light_mode_iphone_11.png and b/test/screen/permission/img/analytics_permission_screen_initial_state_light_mode_iphone_11.png differ diff --git a/test/screen/todo/todo_add/img/todo_add_screen_enabled_ipad_pro.png b/test/screen/todo/todo_add/img/todo_add_screen_enabled_ipad_pro.png index d8e71c76..05ba8625 100644 Binary files a/test/screen/todo/todo_add/img/todo_add_screen_enabled_ipad_pro.png and b/test/screen/todo/todo_add/img/todo_add_screen_enabled_ipad_pro.png differ diff --git a/test/screen/todo/todo_add/img/todo_add_screen_enabled_iphone_11.png b/test/screen/todo/todo_add/img/todo_add_screen_enabled_iphone_11.png index be51712c..c23a0ebb 100644 Binary files a/test/screen/todo/todo_add/img/todo_add_screen_enabled_iphone_11.png and b/test/screen/todo/todo_add/img/todo_add_screen_enabled_iphone_11.png differ diff --git a/test/screen/todo/todo_add/img/todo_add_screen_inital_state_darkmode_ipad_pro.png b/test/screen/todo/todo_add/img/todo_add_screen_inital_state_darkmode_ipad_pro.png index e47c7dbf..368f2001 100644 Binary files a/test/screen/todo/todo_add/img/todo_add_screen_inital_state_darkmode_ipad_pro.png and b/test/screen/todo/todo_add/img/todo_add_screen_inital_state_darkmode_ipad_pro.png differ diff --git a/test/screen/todo/todo_add/img/todo_add_screen_inital_state_darkmode_iphone_11.png b/test/screen/todo/todo_add/img/todo_add_screen_inital_state_darkmode_iphone_11.png index 341df7f5..b5dd1472 100644 Binary files a/test/screen/todo/todo_add/img/todo_add_screen_inital_state_darkmode_iphone_11.png and b/test/screen/todo/todo_add/img/todo_add_screen_inital_state_darkmode_iphone_11.png differ diff --git a/test/screen/todo/todo_add/img/todo_add_screen_inital_state_ipad_pro.png b/test/screen/todo/todo_add/img/todo_add_screen_inital_state_ipad_pro.png index f0e2643d..8d87ab74 100644 Binary files a/test/screen/todo/todo_add/img/todo_add_screen_inital_state_ipad_pro.png and b/test/screen/todo/todo_add/img/todo_add_screen_inital_state_ipad_pro.png differ diff --git a/test/screen/todo/todo_add/img/todo_add_screen_inital_state_iphone_11.png b/test/screen/todo/todo_add/img/todo_add_screen_inital_state_iphone_11.png index d0d94e02..e3b7e87a 100644 Binary files a/test/screen/todo/todo_add/img/todo_add_screen_inital_state_iphone_11.png and b/test/screen/todo/todo_add/img/todo_add_screen_inital_state_iphone_11.png differ diff --git a/test/screen/todo/todo_list/img/todo_list_screen_empty_state_ipad_pro.png b/test/screen/todo/todo_list/img/todo_list_screen_empty_state_ipad_pro.png index 9fbcc929..90f4c588 100644 Binary files a/test/screen/todo/todo_list/img/todo_list_screen_empty_state_ipad_pro.png and b/test/screen/todo/todo_list/img/todo_list_screen_empty_state_ipad_pro.png differ diff --git a/test/screen/todo/todo_list/img/todo_list_screen_empty_state_iphone_11.png b/test/screen/todo/todo_list/img/todo_list_screen_empty_state_iphone_11.png index 58465552..f2fa661a 100644 Binary files a/test/screen/todo/todo_list/img/todo_list_screen_empty_state_iphone_11.png and b/test/screen/todo/todo_list/img/todo_list_screen_empty_state_iphone_11.png differ diff --git a/test/screen/todo/todo_list/img/todo_list_screen_error_state_ipad_pro.png b/test/screen/todo/todo_list/img/todo_list_screen_error_state_ipad_pro.png index fcfc8348..e4b976e0 100644 Binary files a/test/screen/todo/todo_list/img/todo_list_screen_error_state_ipad_pro.png and b/test/screen/todo/todo_list/img/todo_list_screen_error_state_ipad_pro.png differ diff --git a/test/screen/todo/todo_list/img/todo_list_screen_error_state_iphone_11.png b/test/screen/todo/todo_list/img/todo_list_screen_error_state_iphone_11.png index 8b2965e1..1d1b4854 100644 Binary files a/test/screen/todo/todo_list/img/todo_list_screen_error_state_iphone_11.png and b/test/screen/todo/todo_list/img/todo_list_screen_error_state_iphone_11.png differ diff --git a/test/screen/todo/todo_list/img/todo_list_screen_inital_state_dark_mode_ipad_pro.png b/test/screen/todo/todo_list/img/todo_list_screen_inital_state_dark_mode_ipad_pro.png index f06cbbfc..474b7bab 100644 Binary files a/test/screen/todo/todo_list/img/todo_list_screen_inital_state_dark_mode_ipad_pro.png and b/test/screen/todo/todo_list/img/todo_list_screen_inital_state_dark_mode_ipad_pro.png differ diff --git a/test/screen/todo/todo_list/img/todo_list_screen_inital_state_dark_mode_iphone_11.png b/test/screen/todo/todo_list/img/todo_list_screen_inital_state_dark_mode_iphone_11.png index 6ea9f9cd..4b6a0a55 100644 Binary files a/test/screen/todo/todo_list/img/todo_list_screen_inital_state_dark_mode_iphone_11.png and b/test/screen/todo/todo_list/img/todo_list_screen_inital_state_dark_mode_iphone_11.png differ diff --git a/test/screen/todo/todo_list/img/todo_list_screen_inital_state_ipad_pro.png b/test/screen/todo/todo_list/img/todo_list_screen_inital_state_ipad_pro.png index 4e96e7be..df3a6fd8 100644 Binary files a/test/screen/todo/todo_list/img/todo_list_screen_inital_state_ipad_pro.png and b/test/screen/todo/todo_list/img/todo_list_screen_inital_state_ipad_pro.png differ diff --git a/test/screen/todo/todo_list/img/todo_list_screen_inital_state_iphone_11.png b/test/screen/todo/todo_list/img/todo_list_screen_inital_state_iphone_11.png index 7c6caf2b..abb6e020 100644 Binary files a/test/screen/todo/todo_list/img/todo_list_screen_inital_state_iphone_11.png and b/test/screen/todo/todo_list/img/todo_list_screen_inital_state_iphone_11.png differ diff --git a/test/screen/todo/todo_list/img/todo_list_screen_loading_state_ipad_pro.png b/test/screen/todo/todo_list/img/todo_list_screen_loading_state_ipad_pro.png index 39dc113e..4a96eba7 100644 Binary files a/test/screen/todo/todo_list/img/todo_list_screen_loading_state_ipad_pro.png and b/test/screen/todo/todo_list/img/todo_list_screen_loading_state_ipad_pro.png differ diff --git a/test/screen/todo/todo_list/img/todo_list_screen_loading_state_iphone_11.png b/test/screen/todo/todo_list/img/todo_list_screen_loading_state_iphone_11.png index b6b98bd1..9cdb18ac 100644 Binary files a/test/screen/todo/todo_list/img/todo_list_screen_loading_state_iphone_11.png and b/test/screen/todo/todo_list/img/todo_list_screen_loading_state_iphone_11.png differ diff --git a/test/styles/img/theme_asset_add_android.png b/test/styles/img/theme_asset_add_android.png index 5fb76dec..51387a17 100644 Binary files a/test/styles/img/theme_asset_add_android.png and b/test/styles/img/theme_asset_add_android.png differ diff --git a/test/styles/img/theme_asset_add_ios.png b/test/styles/img/theme_asset_add_ios.png index 5fb76dec..51387a17 100644 Binary files a/test/styles/img/theme_asset_add_ios.png and b/test/styles/img/theme_asset_add_ios.png differ diff --git a/test/styles/img/theme_asset_back_android.png b/test/styles/img/theme_asset_back_android.png index 8444c875..40b3132a 100644 Binary files a/test/styles/img/theme_asset_back_android.png and b/test/styles/img/theme_asset_back_android.png differ diff --git a/test/styles/img/theme_asset_back_ios.png b/test/styles/img/theme_asset_back_ios.png index 2ae138e0..40b3132a 100644 Binary files a/test/styles/img/theme_asset_back_ios.png and b/test/styles/img/theme_asset_back_ios.png differ diff --git a/test/styles/img/theme_asset_close_android.png b/test/styles/img/theme_asset_close_android.png index 1cf6e2eb..40b3132a 100644 Binary files a/test/styles/img/theme_asset_close_android.png and b/test/styles/img/theme_asset_close_android.png differ diff --git a/test/styles/img/theme_asset_close_ios.png b/test/styles/img/theme_asset_close_ios.png index 1cf6e2eb..40b3132a 100644 Binary files a/test/styles/img/theme_asset_close_ios.png and b/test/styles/img/theme_asset_close_ios.png differ diff --git a/test/styles/img/theme_asset_done_android.png b/test/styles/img/theme_asset_done_android.png index 0ac767cf..45e087ed 100644 Binary files a/test/styles/img/theme_asset_done_android.png and b/test/styles/img/theme_asset_done_android.png differ diff --git a/test/styles/img/theme_asset_done_ios.png b/test/styles/img/theme_asset_done_ios.png index 0ac767cf..45e087ed 100644 Binary files a/test/styles/img/theme_asset_done_ios.png and b/test/styles/img/theme_asset_done_ios.png differ diff --git a/test/styles/img/theme_asset_download_android.png b/test/styles/img/theme_asset_download_android.png index 06a057de..7e3752cd 100644 Binary files a/test/styles/img/theme_asset_download_android.png and b/test/styles/img/theme_asset_download_android.png differ diff --git a/test/styles/img/theme_asset_download_ios.png b/test/styles/img/theme_asset_download_ios.png index 06a057de..7e3752cd 100644 Binary files a/test/styles/img/theme_asset_download_ios.png and b/test/styles/img/theme_asset_download_ios.png differ diff --git a/test/styles/img/theme_asset_list_android.png b/test/styles/img/theme_asset_list_android.png index ef8c1eec..e9009e8e 100644 Binary files a/test/styles/img/theme_asset_list_android.png and b/test/styles/img/theme_asset_list_android.png differ diff --git a/test/styles/img/theme_asset_list_ios.png b/test/styles/img/theme_asset_list_ios.png index ef8c1eec..e9009e8e 100644 Binary files a/test/styles/img/theme_asset_list_ios.png and b/test/styles/img/theme_asset_list_ios.png differ diff --git a/test/styles/img/theme_asset_settings_android.png b/test/styles/img/theme_asset_settings_android.png index 542242f7..e9009e8e 100644 Binary files a/test/styles/img/theme_asset_settings_android.png and b/test/styles/img/theme_asset_settings_android.png differ diff --git a/test/styles/img/theme_asset_settings_ios.png b/test/styles/img/theme_asset_settings_ios.png index 542242f7..6e99e9cb 100644 Binary files a/test/styles/img/theme_asset_settings_ios.png and b/test/styles/img/theme_asset_settings_ios.png differ diff --git a/test/styles/theme_assets_test.dart b/test/styles/theme_assets_test.dart index 45aca0e8..cb06035f 100644 --- a/test/styles/theme_assets_test.dart +++ b/test/styles/theme_assets_test.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_template/styles/theme_assets.dart'; import 'package:flutter_template/styles/theme_data.dart'; -import 'package:flutter_template/styles/theme_dimens.dart'; import 'package:flutter_test/flutter_test.dart'; import '../util/test_util.dart'; @@ -10,49 +9,49 @@ import '../util/test_util.dart'; void main() { group('Android Asset icons', () { testWidgets('ThemeAsset list', (tester) async { - const sut = IconAssetTesterAndroid(getAsset: ThemeAssets.listIcon); + const sut = IconAssetTesterAndroid(asset: ThemeAssets.todoIconActive); await TestUtil.loadWidgetWithText(tester, sut); await TestUtil.takeScreenshot(tester, 'theme_asset_list_android'); }); testWidgets('ThemeAsset settings', (tester) async { - const sut = IconAssetTesterAndroid(getAsset: ThemeAssets.settingsIcon); + const sut = IconAssetTesterAndroid(asset: ThemeAssets.todoIconActive); await TestUtil.loadWidgetWithText(tester, sut); await TestUtil.takeScreenshot(tester, 'theme_asset_settings_android'); }); testWidgets('ThemeAsset add', (tester) async { - const sut = IconAssetTesterAndroid(getAsset: ThemeAssets.addIcon); + const sut = IconAssetTesterAndroid(asset: ThemeAssets.addIcon); await TestUtil.loadWidgetWithText(tester, sut); await TestUtil.takeScreenshot(tester, 'theme_asset_add_android'); }); testWidgets('ThemeAsset download', (tester) async { - const sut = IconAssetTesterAndroid(getAsset: ThemeAssets.downloadIcon); + const sut = IconAssetTesterAndroid(asset: ThemeAssets.downloadIcon); await TestUtil.loadWidgetWithText(tester, sut); await TestUtil.takeScreenshot(tester, 'theme_asset_download_android'); }); testWidgets('ThemeAsset close', (tester) async { - const sut = IconAssetTesterAndroid(getAsset: ThemeAssets.closeIcon); + const sut = IconAssetTesterAndroid(asset: ThemeAssets.arrowLeftIcon); await TestUtil.loadWidgetWithText(tester, sut); await TestUtil.takeScreenshot(tester, 'theme_asset_close_android'); }); testWidgets('ThemeAsset back', (tester) async { - const sut = IconAssetTesterAndroid(getAsset: ThemeAssets.backIcon); + const sut = IconAssetTesterAndroid(asset: ThemeAssets.arrowLeftIcon); await TestUtil.loadWidgetWithText(tester, sut); await TestUtil.takeScreenshot(tester, 'theme_asset_back_android'); }); testWidgets('ThemeAsset done', (tester) async { - const sut = IconAssetTesterAndroid(getAsset: ThemeAssets.doneIcon); + const sut = IconAssetTesterAndroid(asset: ThemeAssets.checkIcon); await TestUtil.loadWidgetWithText(tester, sut); await TestUtil.takeScreenshot(tester, 'theme_asset_done_android'); @@ -61,49 +60,49 @@ void main() { group('IOS Asset icons', () { testWidgets('ThemeAsset list', (tester) async { - const sut = IconAssetTesterIOS(getAsset: ThemeAssets.listIcon); + const sut = IconAssetTesterIOS(asset: ThemeAssets.todoIconActive); await TestUtil.loadWidgetWithText(tester, sut); await TestUtil.takeScreenshot(tester, 'theme_asset_list_ios'); }); testWidgets('ThemeAsset settings', (tester) async { - const sut = IconAssetTesterIOS(getAsset: ThemeAssets.settingsIcon); + const sut = IconAssetTesterIOS(asset: ThemeAssets.settingsIconActive); await TestUtil.loadWidgetWithText(tester, sut); await TestUtil.takeScreenshot(tester, 'theme_asset_settings_ios'); }); testWidgets('ThemeAsset add', (tester) async { - const sut = IconAssetTesterIOS(getAsset: ThemeAssets.addIcon); + const sut = IconAssetTesterIOS(asset: ThemeAssets.addIcon); await TestUtil.loadWidgetWithText(tester, sut); await TestUtil.takeScreenshot(tester, 'theme_asset_add_ios'); }); testWidgets('ThemeAsset download', (tester) async { - const sut = IconAssetTesterIOS(getAsset: ThemeAssets.downloadIcon); + const sut = IconAssetTesterIOS(asset: ThemeAssets.downloadIcon); await TestUtil.loadWidgetWithText(tester, sut); await TestUtil.takeScreenshot(tester, 'theme_asset_download_ios'); }); testWidgets('ThemeAsset close', (tester) async { - const sut = IconAssetTesterIOS(getAsset: ThemeAssets.closeIcon); + const sut = IconAssetTesterIOS(asset: ThemeAssets.arrowLeftIcon); await TestUtil.loadWidgetWithText(tester, sut); await TestUtil.takeScreenshot(tester, 'theme_asset_close_ios'); }); testWidgets('ThemeAsset back', (tester) async { - const sut = IconAssetTesterIOS(getAsset: ThemeAssets.backIcon); + const sut = IconAssetTesterIOS(asset: ThemeAssets.arrowLeftIcon); await TestUtil.loadWidgetWithText(tester, sut); await TestUtil.takeScreenshot(tester, 'theme_asset_back_ios'); }); testWidgets('ThemeAsset done', (tester) async { - const sut = IconAssetTesterIOS(getAsset: ThemeAssets.doneIcon); + const sut = IconAssetTesterIOS(asset: ThemeAssets.checkIcon); await TestUtil.loadWidgetWithText(tester, sut); await TestUtil.takeScreenshot(tester, 'theme_asset_done_ios'); @@ -112,10 +111,10 @@ void main() { } class IconAssetTesterAndroid extends StatelessWidget { - final String Function(BuildContext context) getAsset; + final String asset; const IconAssetTesterAndroid({ - required this.getAsset, + required this.asset, super.key, }); @@ -125,9 +124,9 @@ class IconAssetTesterAndroid extends StatelessWidget { data: FlutterTemplateThemeData.lightTheme(TargetPlatform.android), child: LayoutBuilder( builder: (context, constraint) => SvgPicture.asset( - getAsset(context), - height: ThemeDimens.padding64, - width: ThemeDimens.padding64, + asset, + height: 64, + width: 64, colorFilter: const ColorFilter.mode(Colors.black, BlendMode.srcIn), ), ), @@ -136,10 +135,10 @@ class IconAssetTesterAndroid extends StatelessWidget { } class IconAssetTesterIOS extends StatelessWidget { - final String Function(BuildContext context) getAsset; + final String asset; const IconAssetTesterIOS({ - required this.getAsset, + required this.asset, super.key, }); @@ -149,9 +148,9 @@ class IconAssetTesterIOS extends StatelessWidget { data: FlutterTemplateThemeData.lightTheme(TargetPlatform.iOS), child: LayoutBuilder( builder: (context, constraint) => SvgPicture.asset( - getAsset(context), - height: ThemeDimens.padding64, - width: ThemeDimens.padding64, + asset, + height: 64, + width: 64, colorFilter: const ColorFilter.mode(Colors.black, BlendMode.srcIn), ), ), diff --git a/test/util/test_util.dart b/test/util/test_util.dart index 7382a093..e2b46179 100644 --- a/test/util/test_util.dart +++ b/test/util/test_util.dart @@ -12,6 +12,7 @@ import 'package:flutter_template/styles/theme_fonts.dart'; import 'package:flutter_template/util/locale/localization.dart'; import 'package:flutter_template/util/locale/localization_delegate.dart'; import 'package:flutter_template/util/locale/localization_fallback_cupertino_delegate.dart'; +import 'package:flutter_template/util/logging/flutter_template_logger.dart'; import 'package:flutter_template/util/snackbar/error_util.dart'; import 'package:flutter_template/util/theme/theme_config.dart'; import 'package:flutter_template/viewmodel/global/global_viewmodel.dart'; @@ -69,7 +70,7 @@ class TestUtil { static Future loadScreen(WidgetTester tester, Widget widget, {ThemeMode themeMode = ThemeMode.light}) async { await initArchitecture(); if (getIt.isRegistered()) { - staticLogger.debug('GlobalViewModel already registered'); + FlutterTemplateLogger.logDebug('GlobalViewModel already registered'); } else { getIt.registerLazySingleton(() => MockGlobalViewModel()); seedGlobalViewModel(); diff --git a/test/util/test_util.mocks.dart b/test/util/test_util.mocks.dart index e7ea7676..71672f00 100644 --- a/test/util/test_util.mocks.dart +++ b/test/util/test_util.mocks.dart @@ -7,14 +7,14 @@ import 'dart:async' as _i5; import 'dart:ui' as _i4; import 'package:drift/drift.dart' as _i11; -import 'package:flutter/material.dart' as _i1; +import 'package:flutter/material.dart' as _i2; import 'package:flutter_template/model/snackbar/snackbar_data.dart' as _i12; import 'package:flutter_template/navigator/main_navigator.dart' as _i10; import 'package:flutter_template/util/locale/localization.dart' as _i7; import 'package:flutter_template/util/snackbar/error_util.dart' as _i9; import 'package:flutter_template/viewmodel/global/global_viewmodel.dart' as _i3; import 'package:icapps_architecture/icapps_architecture.dart' as _i8; -import 'package:mockito/mockito.dart' as _i2; +import 'package:mockito/mockito.dart' as _i1; import 'package:mockito/src/dummies.dart' as _i6; // ignore_for_file: type=lint @@ -30,9 +30,19 @@ import 'package:mockito/src/dummies.dart' as _i6; // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class -class _FakeGlobalKey_0> - extends _i2.SmartFake implements _i1.GlobalKey { - _FakeGlobalKey_0( +class _FakeBuildContext_0 extends _i1.SmartFake implements _i2.BuildContext { + _FakeBuildContext_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeGlobalKey_1> + extends _i1.SmartFake implements _i2.GlobalKey { + _FakeGlobalKey_1( Object parent, Invocation parentInvocation, ) : super( @@ -44,9 +54,9 @@ class _FakeGlobalKey_0> /// A class which mocks [GlobalViewModel]. /// /// See the documentation for Mockito's code generation for more information. -class MockGlobalViewModel extends _i2.Mock implements _i3.GlobalViewModel { +class MockGlobalViewModel extends _i1.Mock implements _i3.GlobalViewModel { MockGlobalViewModel() { - _i2.throwOnMissingStub(this); + _i1.throwOnMissingStub(this); } @override @@ -56,10 +66,10 @@ class MockGlobalViewModel extends _i2.Mock implements _i3.GlobalViewModel { ) as List<_i4.Locale>); @override - _i1.ThemeMode get themeMode => (super.noSuchMethod( + _i2.ThemeMode get themeMode => (super.noSuchMethod( Invocation.getter(#themeMode), - returnValue: _i1.ThemeMode.system, - ) as _i1.ThemeMode); + returnValue: _i2.ThemeMode.system, + ) as _i2.ThemeMode); @override bool get showsTranslationKeys => (super.noSuchMethod( @@ -90,7 +100,7 @@ class MockGlobalViewModel extends _i2.Mock implements _i3.GlobalViewModel { ) as _i5.Future); @override - _i5.Future updateThemeMode(_i1.ThemeMode? themeMode) => + _i5.Future updateThemeMode(_i2.ThemeMode? themeMode) => (super.noSuchMethod( Invocation.method( #updateThemeMode, @@ -292,15 +302,15 @@ class MockGlobalViewModel extends _i2.Mock implements _i3.GlobalViewModel { /// A class which mocks [ErrorUtil]. /// /// See the documentation for Mockito's code generation for more information. -class MockErrorUtil extends _i2.Mock implements _i9.ErrorUtil { +class MockErrorUtil extends _i1.Mock implements _i9.ErrorUtil { MockErrorUtil() { - _i2.throwOnMissingStub(this); + _i1.throwOnMissingStub(this); } @override String? showError({ required dynamic error, - required _i1.BuildContext? context, + required _i2.BuildContext? context, }) => (super.noSuchMethod(Invocation.method( #showError, @@ -314,7 +324,7 @@ class MockErrorUtil extends _i2.Mock implements _i9.ErrorUtil { @override void showErrorWithLocaleKey({ required String? messageKey, - required _i1.BuildContext? context, + required _i2.BuildContext? context, String? titleKey, List? args, }) => @@ -336,19 +346,28 @@ class MockErrorUtil extends _i2.Mock implements _i9.ErrorUtil { /// A class which mocks [MainNavigator]. /// /// See the documentation for Mockito's code generation for more information. -class MockMainNavigator extends _i2.Mock implements _i10.MainNavigator { +class MockMainNavigator extends _i1.Mock implements _i10.MainNavigator { MockMainNavigator() { - _i2.throwOnMissingStub(this); + _i1.throwOnMissingStub(this); } @override - _i1.GlobalKey<_i1.NavigatorState> get navigatorKey => (super.noSuchMethod( + _i2.BuildContext get context => (super.noSuchMethod( + Invocation.getter(#context), + returnValue: _FakeBuildContext_0( + this, + Invocation.getter(#context), + ), + ) as _i2.BuildContext); + + @override + _i2.GlobalKey<_i2.NavigatorState> get navigatorKey => (super.noSuchMethod( Invocation.getter(#navigatorKey), - returnValue: _FakeGlobalKey_0<_i1.NavigatorState>( + returnValue: _FakeGlobalKey_1<_i2.NavigatorState>( this, Invocation.getter(#navigatorKey), ), - ) as _i1.GlobalKey<_i1.NavigatorState>); + ) as _i2.GlobalKey<_i2.NavigatorState>); @override _i5.Future goToDatabase(_i11.GeneratedDatabase? db) => @@ -410,14 +429,14 @@ class MockMainNavigator extends _i2.Mock implements _i10.MainNavigator { ) as _i5.Future); @override - _i1.Route? onGenerateRoute(_i1.RouteSettings? settings) => + _i2.Route? onGenerateRoute(_i2.RouteSettings? settings) => (super.noSuchMethod(Invocation.method( #onGenerateRoute, [settings], - )) as _i1.Route?); + )) as _i2.Route?); @override - void goToHomeScreen({_i1.Key? key}) => super.noSuchMethod( + void goToHomeScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToHomeScreen, [], @@ -427,7 +446,7 @@ class MockMainNavigator extends _i2.Mock implements _i10.MainNavigator { ); @override - void goToSplashScreen({_i1.Key? key}) => super.noSuchMethod( + void goToSplashScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToSplashScreen, [], @@ -437,7 +456,7 @@ class MockMainNavigator extends _i2.Mock implements _i10.MainNavigator { ); @override - _i5.Future goToLicenseScreen({_i1.Key? key}) => (super.noSuchMethod( + _i5.Future goToLicenseScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToLicenseScreen, [], @@ -448,7 +467,25 @@ class MockMainNavigator extends _i2.Mock implements _i10.MainNavigator { ) as _i5.Future); @override - _i5.Future goToTodoAddScreen({_i1.Key? key}) => (super.noSuchMethod( + _i5.Future goToLogDetailScreen({ + required String? date, + _i2.Key? key, + }) => + (super.noSuchMethod( + Invocation.method( + #goToLogDetailScreen, + [], + { + #date: date, + #key: key, + }, + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future goToTodoAddScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToTodoAddScreen, [], @@ -459,7 +496,18 @@ class MockMainNavigator extends _i2.Mock implements _i10.MainNavigator { ) as _i5.Future); @override - _i5.Future goToAnalyticsPermissionScreen({_i1.Key? key}) => + _i5.Future goToLogsScreen({_i2.Key? key}) => (super.noSuchMethod( + Invocation.method( + #goToLogsScreen, + [], + {#key: key}, + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future goToAnalyticsPermissionScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToAnalyticsPermissionScreen, @@ -471,7 +519,7 @@ class MockMainNavigator extends _i2.Mock implements _i10.MainNavigator { ) as _i5.Future); @override - void goToLoginScreen({_i1.Key? key}) => super.noSuchMethod( + void goToLoginScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToLoginScreen, [], @@ -481,7 +529,7 @@ class MockMainNavigator extends _i2.Mock implements _i10.MainNavigator { ); @override - _i5.Future goToThemeModeSelectorScreen({_i1.Key? key}) => + _i5.Future goToThemeModeSelectorScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToThemeModeSelectorScreen, @@ -493,7 +541,7 @@ class MockMainNavigator extends _i2.Mock implements _i10.MainNavigator { ) as _i5.Future); @override - _i5.Future goToDebugPlatformSelectorScreen({_i1.Key? key}) => + _i5.Future goToDebugPlatformSelectorScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToDebugPlatformSelectorScreen, @@ -505,7 +553,7 @@ class MockMainNavigator extends _i2.Mock implements _i10.MainNavigator { ) as _i5.Future); @override - _i5.Future goToDebugScreen({_i1.Key? key}) => (super.noSuchMethod( + _i5.Future goToDebugScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToDebugScreen, [], @@ -535,7 +583,7 @@ class MockMainNavigator extends _i2.Mock implements _i10.MainNavigator { ); @override - void popUntil(bool Function(_i1.Route)? predicate) => + void popUntil(bool Function(_i2.Route)? predicate) => super.noSuchMethod( Invocation.method( #popUntil, @@ -554,7 +602,7 @@ class MockMainNavigator extends _i2.Mock implements _i10.MainNavigator { ); @override - _i5.Future showCustomDialog({_i1.Widget? widget}) => + _i5.Future showCustomDialog({_i2.Widget? widget}) => (super.noSuchMethod( Invocation.method( #showCustomDialog, @@ -565,7 +613,7 @@ class MockMainNavigator extends _i2.Mock implements _i10.MainNavigator { ) as _i5.Future); @override - _i5.Future showBottomSheet({_i1.Widget? widget}) => + _i5.Future showBottomSheet({_i2.Widget? widget}) => (super.noSuchMethod( Invocation.method( #showBottomSheet, diff --git a/test/viewmodel/debug/debug_platform_selector_viewmodel_test.dart b/test/viewmodel/debug/debug_platform_selector_viewmodel_test.dart index 261c8386..6900b900 100644 --- a/test/viewmodel/debug/debug_platform_selector_viewmodel_test.dart +++ b/test/viewmodel/debug/debug_platform_selector_viewmodel_test.dart @@ -1,5 +1,6 @@ import 'package:flutter_template/navigator/main_navigator.dart'; import 'package:flutter_template/viewmodel/debug/debug_platform_selector_viewmodel.dart'; +import 'package:flutter_template/viewmodel/global/global_viewmodel.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; @@ -9,14 +10,20 @@ import 'debug_platform_selector_viewmodel_test.mocks.dart'; @GenerateMocks([ MainNavigator, + GlobalViewModel, ]) void main() { late DebugPlatformSelectorViewModel sut; late MainNavigator navigator; + late MockGlobalViewModel globalViewModel; setUp(() async { navigator = MockMainNavigator(); - sut = DebugPlatformSelectorViewModel(navigator); + globalViewModel = MockGlobalViewModel(); + sut = DebugPlatformSelectorViewModel( + globalViewModel, + navigator, + ); }); group('After init', () { diff --git a/test/viewmodel/debug/debug_platform_selector_viewmodel_test.mocks.dart b/test/viewmodel/debug/debug_platform_selector_viewmodel_test.mocks.dart index 798655b7..f424452b 100644 --- a/test/viewmodel/debug/debug_platform_selector_viewmodel_test.mocks.dart +++ b/test/viewmodel/debug/debug_platform_selector_viewmodel_test.mocks.dart @@ -4,12 +4,17 @@ // ignore_for_file: no_leading_underscores_for_library_prefixes import 'dart:async' as _i4; +import 'dart:ui' as _i8; import 'package:drift/drift.dart' as _i5; -import 'package:flutter/material.dart' as _i1; +import 'package:flutter/material.dart' as _i2; import 'package:flutter_template/model/snackbar/snackbar_data.dart' as _i6; import 'package:flutter_template/navigator/main_navigator.dart' as _i3; -import 'package:mockito/mockito.dart' as _i2; +import 'package:flutter_template/util/locale/localization.dart' as _i10; +import 'package:flutter_template/viewmodel/global/global_viewmodel.dart' as _i7; +import 'package:icapps_architecture/icapps_architecture.dart' as _i11; +import 'package:mockito/mockito.dart' as _i1; +import 'package:mockito/src/dummies.dart' as _i9; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -24,9 +29,19 @@ import 'package:mockito/mockito.dart' as _i2; // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class -class _FakeGlobalKey_0> - extends _i2.SmartFake implements _i1.GlobalKey { - _FakeGlobalKey_0( +class _FakeBuildContext_0 extends _i1.SmartFake implements _i2.BuildContext { + _FakeBuildContext_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeGlobalKey_1> + extends _i1.SmartFake implements _i2.GlobalKey { + _FakeGlobalKey_1( Object parent, Invocation parentInvocation, ) : super( @@ -38,19 +53,28 @@ class _FakeGlobalKey_0> /// A class which mocks [MainNavigator]. /// /// See the documentation for Mockito's code generation for more information. -class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { +class MockMainNavigator extends _i1.Mock implements _i3.MainNavigator { MockMainNavigator() { - _i2.throwOnMissingStub(this); + _i1.throwOnMissingStub(this); } @override - _i1.GlobalKey<_i1.NavigatorState> get navigatorKey => (super.noSuchMethod( + _i2.BuildContext get context => (super.noSuchMethod( + Invocation.getter(#context), + returnValue: _FakeBuildContext_0( + this, + Invocation.getter(#context), + ), + ) as _i2.BuildContext); + + @override + _i2.GlobalKey<_i2.NavigatorState> get navigatorKey => (super.noSuchMethod( Invocation.getter(#navigatorKey), - returnValue: _FakeGlobalKey_0<_i1.NavigatorState>( + returnValue: _FakeGlobalKey_1<_i2.NavigatorState>( this, Invocation.getter(#navigatorKey), ), - ) as _i1.GlobalKey<_i1.NavigatorState>); + ) as _i2.GlobalKey<_i2.NavigatorState>); @override _i4.Future goToDatabase(_i5.GeneratedDatabase? db) => @@ -112,14 +136,14 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ) as _i4.Future); @override - _i1.Route? onGenerateRoute(_i1.RouteSettings? settings) => + _i2.Route? onGenerateRoute(_i2.RouteSettings? settings) => (super.noSuchMethod(Invocation.method( #onGenerateRoute, [settings], - )) as _i1.Route?); + )) as _i2.Route?); @override - void goToHomeScreen({_i1.Key? key}) => super.noSuchMethod( + void goToHomeScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToHomeScreen, [], @@ -129,7 +153,7 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ); @override - void goToSplashScreen({_i1.Key? key}) => super.noSuchMethod( + void goToSplashScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToSplashScreen, [], @@ -139,7 +163,7 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ); @override - _i4.Future goToLicenseScreen({_i1.Key? key}) => (super.noSuchMethod( + _i4.Future goToLicenseScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToLicenseScreen, [], @@ -150,7 +174,25 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ) as _i4.Future); @override - _i4.Future goToTodoAddScreen({_i1.Key? key}) => (super.noSuchMethod( + _i4.Future goToLogDetailScreen({ + required String? date, + _i2.Key? key, + }) => + (super.noSuchMethod( + Invocation.method( + #goToLogDetailScreen, + [], + { + #date: date, + #key: key, + }, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future goToTodoAddScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToTodoAddScreen, [], @@ -161,7 +203,18 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ) as _i4.Future); @override - _i4.Future goToAnalyticsPermissionScreen({_i1.Key? key}) => + _i4.Future goToLogsScreen({_i2.Key? key}) => (super.noSuchMethod( + Invocation.method( + #goToLogsScreen, + [], + {#key: key}, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future goToAnalyticsPermissionScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToAnalyticsPermissionScreen, @@ -173,7 +226,7 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ) as _i4.Future); @override - void goToLoginScreen({_i1.Key? key}) => super.noSuchMethod( + void goToLoginScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToLoginScreen, [], @@ -183,7 +236,7 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ); @override - _i4.Future goToThemeModeSelectorScreen({_i1.Key? key}) => + _i4.Future goToThemeModeSelectorScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToThemeModeSelectorScreen, @@ -195,7 +248,7 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ) as _i4.Future); @override - _i4.Future goToDebugPlatformSelectorScreen({_i1.Key? key}) => + _i4.Future goToDebugPlatformSelectorScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToDebugPlatformSelectorScreen, @@ -207,7 +260,7 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ) as _i4.Future); @override - _i4.Future goToDebugScreen({_i1.Key? key}) => (super.noSuchMethod( + _i4.Future goToDebugScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToDebugScreen, [], @@ -237,7 +290,7 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ); @override - void popUntil(bool Function(_i1.Route)? predicate) => + void popUntil(bool Function(_i2.Route)? predicate) => super.noSuchMethod( Invocation.method( #popUntil, @@ -256,7 +309,7 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ); @override - _i4.Future showCustomDialog({_i1.Widget? widget}) => + _i4.Future showCustomDialog({_i2.Widget? widget}) => (super.noSuchMethod( Invocation.method( #showCustomDialog, @@ -267,7 +320,7 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ) as _i4.Future); @override - _i4.Future showBottomSheet({_i1.Widget? widget}) => + _i4.Future showBottomSheet({_i2.Widget? widget}) => (super.noSuchMethod( Invocation.method( #showBottomSheet, @@ -277,3 +330,251 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { returnValue: _i4.Future.value(), ) as _i4.Future); } + +/// A class which mocks [GlobalViewModel]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockGlobalViewModel extends _i1.Mock implements _i7.GlobalViewModel { + MockGlobalViewModel() { + _i1.throwOnMissingStub(this); + } + + @override + List<_i8.Locale> get supportedLocales => (super.noSuchMethod( + Invocation.getter(#supportedLocales), + returnValue: <_i8.Locale>[], + ) as List<_i8.Locale>); + + @override + _i2.ThemeMode get themeMode => (super.noSuchMethod( + Invocation.getter(#themeMode), + returnValue: _i2.ThemeMode.system, + ) as _i2.ThemeMode); + + @override + bool get showsTranslationKeys => (super.noSuchMethod( + Invocation.getter(#showsTranslationKeys), + returnValue: false, + ) as bool); + + @override + bool get disposed => (super.noSuchMethod( + Invocation.getter(#disposed), + returnValue: false, + ) as bool); + + @override + bool get hasListeners => (super.noSuchMethod( + Invocation.getter(#hasListeners), + returnValue: false, + ) as bool); + + @override + _i4.Future init() => (super.noSuchMethod( + Invocation.method( + #init, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future updateThemeMode(_i2.ThemeMode? themeMode) => + (super.noSuchMethod( + Invocation.method( + #updateThemeMode, + [themeMode], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future onSwitchToDutch() => (super.noSuchMethod( + Invocation.method( + #onSwitchToDutch, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future onSwitchToEnglish() => (super.noSuchMethod( + Invocation.method( + #onSwitchToEnglish, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future onSwitchToSystemLanguage() => (super.noSuchMethod( + Invocation.method( + #onSwitchToSystemLanguage, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setSelectedPlatformToAndroid() => (super.noSuchMethod( + Invocation.method( + #setSelectedPlatformToAndroid, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setSelectedPlatformToIOS() => (super.noSuchMethod( + Invocation.method( + #setSelectedPlatformToIOS, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setSelectedPlatformToDefault() => (super.noSuchMethod( + Invocation.method( + #setSelectedPlatformToDefault, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + String getCurrentPlatform() => (super.noSuchMethod( + Invocation.method( + #getCurrentPlatform, + [], + ), + returnValue: _i9.dummyValue( + this, + Invocation.method( + #getCurrentPlatform, + [], + ), + ), + ) as String); + + @override + String getAppearanceValue(_i10.Localization? localization) => + (super.noSuchMethod( + Invocation.method( + #getAppearanceValue, + [localization], + ), + returnValue: _i9.dummyValue( + this, + Invocation.method( + #getAppearanceValue, + [localization], + ), + ), + ) as String); + + @override + String getCurrentLanguage() => (super.noSuchMethod( + Invocation.method( + #getCurrentLanguage, + [], + ), + returnValue: _i9.dummyValue( + this, + Invocation.method( + #getCurrentLanguage, + [], + ), + ), + ) as String); + + @override + bool isLanguageSelected(String? languageCode) => (super.noSuchMethod( + Invocation.method( + #isLanguageSelected, + [languageCode], + ), + returnValue: false, + ) as bool); + + @override + void toggleTranslationKeys() => super.noSuchMethod( + Invocation.method( + #toggleTranslationKeys, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void overrideLocalizations() => super.noSuchMethod( + Invocation.method( + #overrideLocalizations, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void dispose() => super.noSuchMethod( + Invocation.method( + #dispose, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void addListener(_i8.VoidCallback? listener) => super.noSuchMethod( + Invocation.method( + #addListener, + [listener], + ), + returnValueForMissingStub: null, + ); + + @override + void removeListener(_i8.VoidCallback? listener) => super.noSuchMethod( + Invocation.method( + #removeListener, + [listener], + ), + returnValueForMissingStub: null, + ); + + @override + void registerDispose(_i11.DisposeAware? toDispose) => super.noSuchMethod( + Invocation.method( + #registerDispose, + [toDispose], + ), + returnValueForMissingStub: null, + ); + + @override + void registerDisposeStream(_i4.StreamSubscription? subscription) => + super.noSuchMethod( + Invocation.method( + #registerDisposeStream, + [subscription], + ), + returnValueForMissingStub: null, + ); + + @override + void notifyListeners() => super.noSuchMethod( + Invocation.method( + #notifyListeners, + [], + ), + returnValueForMissingStub: null, + ); +} diff --git a/test/viewmodel/debug/debug_viewmodel_test.mocks.dart b/test/viewmodel/debug/debug_viewmodel_test.mocks.dart index 8fbfb6d2..ecd068eb 100644 --- a/test/viewmodel/debug/debug_viewmodel_test.mocks.dart +++ b/test/viewmodel/debug/debug_viewmodel_test.mocks.dart @@ -7,7 +7,7 @@ import 'dart:async' as _i6; import 'package:drift/drift.dart' as _i4; import 'package:drift/src/runtime/executor/stream_queries.dart' as _i5; -import 'package:flutter/material.dart' as _i1; +import 'package:flutter/material.dart' as _i2; import 'package:flutter_template/database/flutter_template_database.dart' as _i3; import 'package:flutter_template/model/snackbar/snackbar_data.dart' as _i8; @@ -15,7 +15,7 @@ import 'package:flutter_template/navigator/main_navigator.dart' as _i7; import 'package:flutter_template/repository/debug/debug_repository.dart' as _i9; import 'package:flutter_template/repository/shared_prefs/local/local_storage.dart' as _i10; -import 'package:mockito/mockito.dart' as _i2; +import 'package:mockito/mockito.dart' as _i1; import 'package:mockito/src/dummies.dart' as _i11; // ignore_for_file: type=lint @@ -31,9 +31,8 @@ import 'package:mockito/src/dummies.dart' as _i11; // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class -class _FakeGlobalKey_0> - extends _i2.SmartFake implements _i1.GlobalKey { - _FakeGlobalKey_0( +class _FakeBuildContext_0 extends _i1.SmartFake implements _i2.BuildContext { + _FakeBuildContext_0( Object parent, Invocation parentInvocation, ) : super( @@ -42,9 +41,20 @@ class _FakeGlobalKey_0> ); } -class _Fake$DbTodoTableTable_1 extends _i2.SmartFake +class _FakeGlobalKey_1> + extends _i1.SmartFake implements _i2.GlobalKey { + _FakeGlobalKey_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _Fake$DbTodoTableTable_2 extends _i1.SmartFake implements _i3.$DbTodoTableTable { - _Fake$DbTodoTableTable_1( + _Fake$DbTodoTableTable_2( Object parent, Invocation parentInvocation, ) : super( @@ -53,9 +63,9 @@ class _Fake$DbTodoTableTable_1 extends _i2.SmartFake ); } -class _FakeGeneratedDatabase_2 extends _i2.SmartFake +class _FakeGeneratedDatabase_3 extends _i1.SmartFake implements _i4.GeneratedDatabase { - _FakeGeneratedDatabase_2( + _FakeGeneratedDatabase_3( Object parent, Invocation parentInvocation, ) : super( @@ -64,9 +74,9 @@ class _FakeGeneratedDatabase_2 extends _i2.SmartFake ); } -class _FakeDriftDatabaseOptions_3 extends _i2.SmartFake +class _FakeDriftDatabaseOptions_4 extends _i1.SmartFake implements _i4.DriftDatabaseOptions { - _FakeDriftDatabaseOptions_3( + _FakeDriftDatabaseOptions_4( Object parent, Invocation parentInvocation, ) : super( @@ -75,9 +85,9 @@ class _FakeDriftDatabaseOptions_3 extends _i2.SmartFake ); } -class _FakeMigrationStrategy_4 extends _i2.SmartFake +class _FakeMigrationStrategy_5 extends _i1.SmartFake implements _i4.MigrationStrategy { - _FakeMigrationStrategy_4( + _FakeMigrationStrategy_5( Object parent, Invocation parentInvocation, ) : super( @@ -86,9 +96,9 @@ class _FakeMigrationStrategy_4 extends _i2.SmartFake ); } -class _FakeStreamQueryUpdateRules_5 extends _i2.SmartFake +class _FakeStreamQueryUpdateRules_6 extends _i1.SmartFake implements _i4.StreamQueryUpdateRules { - _FakeStreamQueryUpdateRules_5( + _FakeStreamQueryUpdateRules_6( Object parent, Invocation parentInvocation, ) : super( @@ -97,9 +107,9 @@ class _FakeStreamQueryUpdateRules_5 extends _i2.SmartFake ); } -class _FakeDatabaseConnection_6 extends _i2.SmartFake +class _FakeDatabaseConnection_7 extends _i1.SmartFake implements _i4.DatabaseConnection { - _FakeDatabaseConnection_6( + _FakeDatabaseConnection_7( Object parent, Invocation parentInvocation, ) : super( @@ -108,8 +118,8 @@ class _FakeDatabaseConnection_6 extends _i2.SmartFake ); } -class _FakeQueryExecutor_7 extends _i2.SmartFake implements _i4.QueryExecutor { - _FakeQueryExecutor_7( +class _FakeQueryExecutor_8 extends _i1.SmartFake implements _i4.QueryExecutor { + _FakeQueryExecutor_8( Object parent, Invocation parentInvocation, ) : super( @@ -118,9 +128,9 @@ class _FakeQueryExecutor_7 extends _i2.SmartFake implements _i4.QueryExecutor { ); } -class _FakeStreamQueryStore_8 extends _i2.SmartFake +class _FakeStreamQueryStore_9 extends _i1.SmartFake implements _i5.StreamQueryStore { - _FakeStreamQueryStore_8( + _FakeStreamQueryStore_9( Object parent, Invocation parentInvocation, ) : super( @@ -129,9 +139,9 @@ class _FakeStreamQueryStore_8 extends _i2.SmartFake ); } -class _FakeDatabaseConnectionUser_9 extends _i2.SmartFake +class _FakeDatabaseConnectionUser_10 extends _i1.SmartFake implements _i4.DatabaseConnectionUser { - _FakeDatabaseConnectionUser_9( + _FakeDatabaseConnectionUser_10( Object parent, Invocation parentInvocation, ) : super( @@ -140,8 +150,8 @@ class _FakeDatabaseConnectionUser_9 extends _i2.SmartFake ); } -class _FakeMigrator_10 extends _i2.SmartFake implements _i4.Migrator { - _FakeMigrator_10( +class _FakeMigrator_11 extends _i1.SmartFake implements _i4.Migrator { + _FakeMigrator_11( Object parent, Invocation parentInvocation, ) : super( @@ -150,8 +160,8 @@ class _FakeMigrator_10 extends _i2.SmartFake implements _i4.Migrator { ); } -class _FakeFuture_11 extends _i2.SmartFake implements _i6.Future { - _FakeFuture_11( +class _FakeFuture_12 extends _i1.SmartFake implements _i6.Future { + _FakeFuture_12( Object parent, Invocation parentInvocation, ) : super( @@ -160,9 +170,9 @@ class _FakeFuture_11 extends _i2.SmartFake implements _i6.Future { ); } -class _FakeInsertStatement_12 extends _i2.SmartFake +class _FakeInsertStatement_13 extends _i1.SmartFake implements _i4.InsertStatement { - _FakeInsertStatement_12( + _FakeInsertStatement_13( Object parent, Invocation parentInvocation, ) : super( @@ -171,9 +181,9 @@ class _FakeInsertStatement_12 extends _i2.SmartFake ); } -class _FakeUpdateStatement_13 extends _i2.SmartFake +class _FakeUpdateStatement_14 extends _i1.SmartFake implements _i4.UpdateStatement { - _FakeUpdateStatement_13( + _FakeUpdateStatement_14( Object parent, Invocation parentInvocation, ) : super( @@ -182,9 +192,9 @@ class _FakeUpdateStatement_13 extends _i2.SmartFake ); } -class _FakeSimpleSelectStatement_14 - extends _i2.SmartFake implements _i4.SimpleSelectStatement { - _FakeSimpleSelectStatement_14( +class _FakeSimpleSelectStatement_15 + extends _i1.SmartFake implements _i4.SimpleSelectStatement { + _FakeSimpleSelectStatement_15( Object parent, Invocation parentInvocation, ) : super( @@ -193,9 +203,9 @@ class _FakeSimpleSelectStatement_14 ); } -class _FakeJoinedSelectStatement_15 - extends _i2.SmartFake implements _i4.JoinedSelectStatement { - _FakeJoinedSelectStatement_15( +class _FakeJoinedSelectStatement_16 + extends _i1.SmartFake implements _i4.JoinedSelectStatement { + _FakeJoinedSelectStatement_16( Object parent, Invocation parentInvocation, ) : super( @@ -204,9 +214,9 @@ class _FakeJoinedSelectStatement_15 ); } -class _FakeDeleteStatement_16 extends _i2.SmartFake +class _FakeDeleteStatement_17 extends _i1.SmartFake implements _i4.DeleteStatement { - _FakeDeleteStatement_16( + _FakeDeleteStatement_17( Object parent, Invocation parentInvocation, ) : super( @@ -215,8 +225,8 @@ class _FakeDeleteStatement_16 extends _i2.SmartFake ); } -class _FakeSelectable_17 extends _i2.SmartFake implements _i4.Selectable { - _FakeSelectable_17( +class _FakeSelectable_18 extends _i1.SmartFake implements _i4.Selectable { + _FakeSelectable_18( Object parent, Invocation parentInvocation, ) : super( @@ -225,9 +235,9 @@ class _FakeSelectable_17 extends _i2.SmartFake implements _i4.Selectable { ); } -class _FakeGenerationContext_18 extends _i2.SmartFake +class _FakeGenerationContext_19 extends _i1.SmartFake implements _i4.GenerationContext { - _FakeGenerationContext_18( + _FakeGenerationContext_19( Object parent, Invocation parentInvocation, ) : super( @@ -239,19 +249,28 @@ class _FakeGenerationContext_18 extends _i2.SmartFake /// A class which mocks [MainNavigator]. /// /// See the documentation for Mockito's code generation for more information. -class MockMainNavigator extends _i2.Mock implements _i7.MainNavigator { +class MockMainNavigator extends _i1.Mock implements _i7.MainNavigator { MockMainNavigator() { - _i2.throwOnMissingStub(this); + _i1.throwOnMissingStub(this); } @override - _i1.GlobalKey<_i1.NavigatorState> get navigatorKey => (super.noSuchMethod( + _i2.BuildContext get context => (super.noSuchMethod( + Invocation.getter(#context), + returnValue: _FakeBuildContext_0( + this, + Invocation.getter(#context), + ), + ) as _i2.BuildContext); + + @override + _i2.GlobalKey<_i2.NavigatorState> get navigatorKey => (super.noSuchMethod( Invocation.getter(#navigatorKey), - returnValue: _FakeGlobalKey_0<_i1.NavigatorState>( + returnValue: _FakeGlobalKey_1<_i2.NavigatorState>( this, Invocation.getter(#navigatorKey), ), - ) as _i1.GlobalKey<_i1.NavigatorState>); + ) as _i2.GlobalKey<_i2.NavigatorState>); @override _i6.Future goToDatabase(_i4.GeneratedDatabase? db) => @@ -313,14 +332,14 @@ class MockMainNavigator extends _i2.Mock implements _i7.MainNavigator { ) as _i6.Future); @override - _i1.Route? onGenerateRoute(_i1.RouteSettings? settings) => + _i2.Route? onGenerateRoute(_i2.RouteSettings? settings) => (super.noSuchMethod(Invocation.method( #onGenerateRoute, [settings], - )) as _i1.Route?); + )) as _i2.Route?); @override - void goToHomeScreen({_i1.Key? key}) => super.noSuchMethod( + void goToHomeScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToHomeScreen, [], @@ -330,7 +349,7 @@ class MockMainNavigator extends _i2.Mock implements _i7.MainNavigator { ); @override - void goToSplashScreen({_i1.Key? key}) => super.noSuchMethod( + void goToSplashScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToSplashScreen, [], @@ -340,7 +359,7 @@ class MockMainNavigator extends _i2.Mock implements _i7.MainNavigator { ); @override - _i6.Future goToLicenseScreen({_i1.Key? key}) => (super.noSuchMethod( + _i6.Future goToLicenseScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToLicenseScreen, [], @@ -351,7 +370,25 @@ class MockMainNavigator extends _i2.Mock implements _i7.MainNavigator { ) as _i6.Future); @override - _i6.Future goToTodoAddScreen({_i1.Key? key}) => (super.noSuchMethod( + _i6.Future goToLogDetailScreen({ + required String? date, + _i2.Key? key, + }) => + (super.noSuchMethod( + Invocation.method( + #goToLogDetailScreen, + [], + { + #date: date, + #key: key, + }, + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future goToTodoAddScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToTodoAddScreen, [], @@ -362,7 +399,18 @@ class MockMainNavigator extends _i2.Mock implements _i7.MainNavigator { ) as _i6.Future); @override - _i6.Future goToAnalyticsPermissionScreen({_i1.Key? key}) => + _i6.Future goToLogsScreen({_i2.Key? key}) => (super.noSuchMethod( + Invocation.method( + #goToLogsScreen, + [], + {#key: key}, + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future goToAnalyticsPermissionScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToAnalyticsPermissionScreen, @@ -374,7 +422,7 @@ class MockMainNavigator extends _i2.Mock implements _i7.MainNavigator { ) as _i6.Future); @override - void goToLoginScreen({_i1.Key? key}) => super.noSuchMethod( + void goToLoginScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToLoginScreen, [], @@ -384,7 +432,7 @@ class MockMainNavigator extends _i2.Mock implements _i7.MainNavigator { ); @override - _i6.Future goToThemeModeSelectorScreen({_i1.Key? key}) => + _i6.Future goToThemeModeSelectorScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToThemeModeSelectorScreen, @@ -396,7 +444,7 @@ class MockMainNavigator extends _i2.Mock implements _i7.MainNavigator { ) as _i6.Future); @override - _i6.Future goToDebugPlatformSelectorScreen({_i1.Key? key}) => + _i6.Future goToDebugPlatformSelectorScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToDebugPlatformSelectorScreen, @@ -408,7 +456,7 @@ class MockMainNavigator extends _i2.Mock implements _i7.MainNavigator { ) as _i6.Future); @override - _i6.Future goToDebugScreen({_i1.Key? key}) => (super.noSuchMethod( + _i6.Future goToDebugScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToDebugScreen, [], @@ -438,7 +486,7 @@ class MockMainNavigator extends _i2.Mock implements _i7.MainNavigator { ); @override - void popUntil(bool Function(_i1.Route)? predicate) => + void popUntil(bool Function(_i2.Route)? predicate) => super.noSuchMethod( Invocation.method( #popUntil, @@ -457,7 +505,7 @@ class MockMainNavigator extends _i2.Mock implements _i7.MainNavigator { ); @override - _i6.Future showCustomDialog({_i1.Widget? widget}) => + _i6.Future showCustomDialog({_i2.Widget? widget}) => (super.noSuchMethod( Invocation.method( #showCustomDialog, @@ -468,7 +516,7 @@ class MockMainNavigator extends _i2.Mock implements _i7.MainNavigator { ) as _i6.Future); @override - _i6.Future showBottomSheet({_i1.Widget? widget}) => + _i6.Future showBottomSheet({_i2.Widget? widget}) => (super.noSuchMethod( Invocation.method( #showBottomSheet, @@ -482,9 +530,9 @@ class MockMainNavigator extends _i2.Mock implements _i7.MainNavigator { /// A class which mocks [DebugRepository]. /// /// See the documentation for Mockito's code generation for more information. -class MockDebugRepository extends _i2.Mock implements _i9.DebugRepository { +class MockDebugRepository extends _i1.Mock implements _i9.DebugRepository { MockDebugRepository() { - _i2.throwOnMissingStub(this); + _i1.throwOnMissingStub(this); } @override @@ -523,9 +571,9 @@ class MockDebugRepository extends _i2.Mock implements _i9.DebugRepository { /// A class which mocks [LocalStorage]. /// /// See the documentation for Mockito's code generation for more information. -class MockLocalStorage extends _i2.Mock implements _i10.LocalStorage { +class MockLocalStorage extends _i1.Mock implements _i10.LocalStorage { MockLocalStorage() { - _i2.throwOnMissingStub(this); + _i1.throwOnMissingStub(this); } @override @@ -539,7 +587,7 @@ class MockLocalStorage extends _i2.Mock implements _i10.LocalStorage { ) as _i6.Future); @override - _i6.Future updateThemeMode(_i1.ThemeMode? themeMode) => + _i6.Future updateThemeMode(_i2.ThemeMode? themeMode) => (super.noSuchMethod( Invocation.method( #updateThemeMode, @@ -564,10 +612,10 @@ class MockLocalStorage extends _i2.Mock implements _i10.LocalStorage { /// A class which mocks [FlutterTemplateDatabase]. /// /// See the documentation for Mockito's code generation for more information. -class MockFlutterTemplateDatabase extends _i2.Mock +class MockFlutterTemplateDatabase extends _i1.Mock implements _i3.FlutterTemplateDatabase { MockFlutterTemplateDatabase() { - _i2.throwOnMissingStub(this); + _i1.throwOnMissingStub(this); } @override @@ -579,7 +627,7 @@ class MockFlutterTemplateDatabase extends _i2.Mock @override _i3.$DbTodoTableTable get dbTodoTable => (super.noSuchMethod( Invocation.getter(#dbTodoTable), - returnValue: _Fake$DbTodoTableTable_1( + returnValue: _Fake$DbTodoTableTable_2( this, Invocation.getter(#dbTodoTable), ), @@ -605,7 +653,7 @@ class MockFlutterTemplateDatabase extends _i2.Mock @override _i4.GeneratedDatabase get attachedDatabase => (super.noSuchMethod( Invocation.getter(#attachedDatabase), - returnValue: _FakeGeneratedDatabase_2( + returnValue: _FakeGeneratedDatabase_3( this, Invocation.getter(#attachedDatabase), ), @@ -614,7 +662,7 @@ class MockFlutterTemplateDatabase extends _i2.Mock @override _i4.DriftDatabaseOptions get options => (super.noSuchMethod( Invocation.getter(#options), - returnValue: _FakeDriftDatabaseOptions_3( + returnValue: _FakeDriftDatabaseOptions_4( this, Invocation.getter(#options), ), @@ -623,7 +671,7 @@ class MockFlutterTemplateDatabase extends _i2.Mock @override _i4.MigrationStrategy get migration => (super.noSuchMethod( Invocation.getter(#migration), - returnValue: _FakeMigrationStrategy_4( + returnValue: _FakeMigrationStrategy_5( this, Invocation.getter(#migration), ), @@ -632,7 +680,7 @@ class MockFlutterTemplateDatabase extends _i2.Mock @override _i4.StreamQueryUpdateRules get streamUpdateRules => (super.noSuchMethod( Invocation.getter(#streamUpdateRules), - returnValue: _FakeStreamQueryUpdateRules_5( + returnValue: _FakeStreamQueryUpdateRules_6( this, Invocation.getter(#streamUpdateRules), ), @@ -641,7 +689,7 @@ class MockFlutterTemplateDatabase extends _i2.Mock @override _i4.DatabaseConnection get connection => (super.noSuchMethod( Invocation.getter(#connection), - returnValue: _FakeDatabaseConnection_6( + returnValue: _FakeDatabaseConnection_7( this, Invocation.getter(#connection), ), @@ -659,7 +707,7 @@ class MockFlutterTemplateDatabase extends _i2.Mock @override _i4.QueryExecutor get executor => (super.noSuchMethod( Invocation.getter(#executor), - returnValue: _FakeQueryExecutor_7( + returnValue: _FakeQueryExecutor_8( this, Invocation.getter(#executor), ), @@ -668,7 +716,7 @@ class MockFlutterTemplateDatabase extends _i2.Mock @override _i5.StreamQueryStore get streamQueries => (super.noSuchMethod( Invocation.getter(#streamQueries), - returnValue: _FakeStreamQueryStore_8( + returnValue: _FakeStreamQueryStore_9( this, Invocation.getter(#streamQueries), ), @@ -677,7 +725,7 @@ class MockFlutterTemplateDatabase extends _i2.Mock @override _i4.DatabaseConnectionUser get resolvedEngine => (super.noSuchMethod( Invocation.getter(#resolvedEngine), - returnValue: _FakeDatabaseConnectionUser_9( + returnValue: _FakeDatabaseConnectionUser_10( this, Invocation.getter(#resolvedEngine), ), @@ -699,7 +747,7 @@ class MockFlutterTemplateDatabase extends _i2.Mock #createMigrator, [], ), - returnValue: _FakeMigrator_10( + returnValue: _FakeMigrator_11( this, Invocation.method( #createMigrator, @@ -819,7 +867,7 @@ class MockFlutterTemplateDatabase extends _i2.Mock ), (T v) => _i6.Future.value(v), ) ?? - _FakeFuture_11( + _FakeFuture_12( this, Invocation.method( #doWhenOpened, @@ -836,7 +884,7 @@ class MockFlutterTemplateDatabase extends _i2.Mock #into, [table], ), - returnValue: _FakeInsertStatement_12( + returnValue: _FakeInsertStatement_13( this, Invocation.method( #into, @@ -853,7 +901,7 @@ class MockFlutterTemplateDatabase extends _i2.Mock #update, [table], ), - returnValue: _FakeUpdateStatement_13( + returnValue: _FakeUpdateStatement_14( this, Invocation.method( #update, @@ -873,7 +921,7 @@ class MockFlutterTemplateDatabase extends _i2.Mock [table], {#distinct: distinct}, ), - returnValue: _FakeSimpleSelectStatement_14( + returnValue: _FakeSimpleSelectStatement_15( this, Invocation.method( #select, @@ -894,7 +942,7 @@ class MockFlutterTemplateDatabase extends _i2.Mock [table], {#distinct: distinct}, ), - returnValue: _FakeJoinedSelectStatement_15( + returnValue: _FakeJoinedSelectStatement_16( this, Invocation.method( #selectOnly, @@ -912,7 +960,7 @@ class MockFlutterTemplateDatabase extends _i2.Mock #delete, [table], ), - returnValue: _FakeDeleteStatement_16( + returnValue: _FakeDeleteStatement_17( this, Invocation.method( #delete, @@ -994,7 +1042,7 @@ class MockFlutterTemplateDatabase extends _i2.Mock #readsFrom: readsFrom, }, ), - returnValue: _FakeSelectable_17<_i4.QueryRow>( + returnValue: _FakeSelectable_18<_i4.QueryRow>( this, Invocation.method( #customSelect, @@ -1022,7 +1070,7 @@ class MockFlutterTemplateDatabase extends _i2.Mock #readsFrom: readsFrom, }, ), - returnValue: _FakeSelectable_17<_i4.QueryRow>( + returnValue: _FakeSelectable_18<_i4.QueryRow>( this, Invocation.method( #customSelectQuery, @@ -1074,7 +1122,7 @@ class MockFlutterTemplateDatabase extends _i2.Mock ), (T v) => _i6.Future.value(v), ) ?? - _FakeFuture_11( + _FakeFuture_12( this, Invocation.method( #transaction, @@ -1110,7 +1158,7 @@ class MockFlutterTemplateDatabase extends _i2.Mock #startIndex: startIndex, }, ), - returnValue: _FakeGenerationContext_18( + returnValue: _FakeGenerationContext_19( this, Invocation.method( #$write, @@ -1138,7 +1186,7 @@ class MockFlutterTemplateDatabase extends _i2.Mock ], {#startIndex: startIndex}, ), - returnValue: _FakeGenerationContext_18( + returnValue: _FakeGenerationContext_19( this, Invocation.method( #$writeInsertable, diff --git a/test/viewmodel/license/license_viewmodel_test.mocks.dart b/test/viewmodel/license/license_viewmodel_test.mocks.dart index d9388163..1aef81c2 100644 --- a/test/viewmodel/license/license_viewmodel_test.mocks.dart +++ b/test/viewmodel/license/license_viewmodel_test.mocks.dart @@ -6,10 +6,10 @@ import 'dart:async' as _i4; import 'package:drift/drift.dart' as _i5; -import 'package:flutter/material.dart' as _i1; +import 'package:flutter/material.dart' as _i2; import 'package:flutter_template/model/snackbar/snackbar_data.dart' as _i6; import 'package:flutter_template/navigator/main_navigator.dart' as _i3; -import 'package:mockito/mockito.dart' as _i2; +import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -24,9 +24,19 @@ import 'package:mockito/mockito.dart' as _i2; // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class -class _FakeGlobalKey_0> - extends _i2.SmartFake implements _i1.GlobalKey { - _FakeGlobalKey_0( +class _FakeBuildContext_0 extends _i1.SmartFake implements _i2.BuildContext { + _FakeBuildContext_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeGlobalKey_1> + extends _i1.SmartFake implements _i2.GlobalKey { + _FakeGlobalKey_1( Object parent, Invocation parentInvocation, ) : super( @@ -38,19 +48,28 @@ class _FakeGlobalKey_0> /// A class which mocks [MainNavigator]. /// /// See the documentation for Mockito's code generation for more information. -class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { +class MockMainNavigator extends _i1.Mock implements _i3.MainNavigator { MockMainNavigator() { - _i2.throwOnMissingStub(this); + _i1.throwOnMissingStub(this); } @override - _i1.GlobalKey<_i1.NavigatorState> get navigatorKey => (super.noSuchMethod( + _i2.BuildContext get context => (super.noSuchMethod( + Invocation.getter(#context), + returnValue: _FakeBuildContext_0( + this, + Invocation.getter(#context), + ), + ) as _i2.BuildContext); + + @override + _i2.GlobalKey<_i2.NavigatorState> get navigatorKey => (super.noSuchMethod( Invocation.getter(#navigatorKey), - returnValue: _FakeGlobalKey_0<_i1.NavigatorState>( + returnValue: _FakeGlobalKey_1<_i2.NavigatorState>( this, Invocation.getter(#navigatorKey), ), - ) as _i1.GlobalKey<_i1.NavigatorState>); + ) as _i2.GlobalKey<_i2.NavigatorState>); @override _i4.Future goToDatabase(_i5.GeneratedDatabase? db) => @@ -112,14 +131,14 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ) as _i4.Future); @override - _i1.Route? onGenerateRoute(_i1.RouteSettings? settings) => + _i2.Route? onGenerateRoute(_i2.RouteSettings? settings) => (super.noSuchMethod(Invocation.method( #onGenerateRoute, [settings], - )) as _i1.Route?); + )) as _i2.Route?); @override - void goToHomeScreen({_i1.Key? key}) => super.noSuchMethod( + void goToHomeScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToHomeScreen, [], @@ -129,7 +148,7 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ); @override - void goToSplashScreen({_i1.Key? key}) => super.noSuchMethod( + void goToSplashScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToSplashScreen, [], @@ -139,7 +158,7 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ); @override - _i4.Future goToLicenseScreen({_i1.Key? key}) => (super.noSuchMethod( + _i4.Future goToLicenseScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToLicenseScreen, [], @@ -150,7 +169,25 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ) as _i4.Future); @override - _i4.Future goToTodoAddScreen({_i1.Key? key}) => (super.noSuchMethod( + _i4.Future goToLogDetailScreen({ + required String? date, + _i2.Key? key, + }) => + (super.noSuchMethod( + Invocation.method( + #goToLogDetailScreen, + [], + { + #date: date, + #key: key, + }, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future goToTodoAddScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToTodoAddScreen, [], @@ -161,7 +198,18 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ) as _i4.Future); @override - _i4.Future goToAnalyticsPermissionScreen({_i1.Key? key}) => + _i4.Future goToLogsScreen({_i2.Key? key}) => (super.noSuchMethod( + Invocation.method( + #goToLogsScreen, + [], + {#key: key}, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future goToAnalyticsPermissionScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToAnalyticsPermissionScreen, @@ -173,7 +221,7 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ) as _i4.Future); @override - void goToLoginScreen({_i1.Key? key}) => super.noSuchMethod( + void goToLoginScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToLoginScreen, [], @@ -183,7 +231,7 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ); @override - _i4.Future goToThemeModeSelectorScreen({_i1.Key? key}) => + _i4.Future goToThemeModeSelectorScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToThemeModeSelectorScreen, @@ -195,7 +243,7 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ) as _i4.Future); @override - _i4.Future goToDebugPlatformSelectorScreen({_i1.Key? key}) => + _i4.Future goToDebugPlatformSelectorScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToDebugPlatformSelectorScreen, @@ -207,7 +255,7 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ) as _i4.Future); @override - _i4.Future goToDebugScreen({_i1.Key? key}) => (super.noSuchMethod( + _i4.Future goToDebugScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToDebugScreen, [], @@ -237,7 +285,7 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ); @override - void popUntil(bool Function(_i1.Route)? predicate) => + void popUntil(bool Function(_i2.Route)? predicate) => super.noSuchMethod( Invocation.method( #popUntil, @@ -256,7 +304,7 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ); @override - _i4.Future showCustomDialog({_i1.Widget? widget}) => + _i4.Future showCustomDialog({_i2.Widget? widget}) => (super.noSuchMethod( Invocation.method( #showCustomDialog, @@ -267,7 +315,7 @@ class MockMainNavigator extends _i2.Mock implements _i3.MainNavigator { ) as _i4.Future); @override - _i4.Future showBottomSheet({_i1.Widget? widget}) => + _i4.Future showBottomSheet({_i2.Widget? widget}) => (super.noSuchMethod( Invocation.method( #showBottomSheet, diff --git a/test/viewmodel/login/login_viewmodel_test.dart b/test/viewmodel/login/login_viewmodel_test.dart index 98ea28e5..95ac269a 100644 --- a/test/viewmodel/login/login_viewmodel_test.dart +++ b/test/viewmodel/login/login_viewmodel_test.dart @@ -28,6 +28,7 @@ void main() { navigator = MockMainNavigator(); onboardingNavigator = MockOnboardingNavigator(); sut = LoginViewModel(loginRepo, navigator, onboardingNavigator); + TestWidgetsFlutterBinding.ensureInitialized(); }); test('LoginViewModel init with loggedin user', () async { diff --git a/test/viewmodel/login/login_viewmodel_test.mocks.dart b/test/viewmodel/login/login_viewmodel_test.mocks.dart index 080e701b..aa3ddd62 100644 --- a/test/viewmodel/login/login_viewmodel_test.mocks.dart +++ b/test/viewmodel/login/login_viewmodel_test.mocks.dart @@ -6,12 +6,12 @@ import 'dart:async' as _i4; import 'package:drift/drift.dart' as _i6; -import 'package:flutter/material.dart' as _i1; +import 'package:flutter/material.dart' as _i2; import 'package:flutter_template/model/snackbar/snackbar_data.dart' as _i7; import 'package:flutter_template/navigator/main_navigator.dart' as _i5; import 'package:flutter_template/navigator/onboarding_navigator.dart' as _i8; import 'package:flutter_template/repository/login/login_repository.dart' as _i3; -import 'package:mockito/mockito.dart' as _i2; +import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -26,9 +26,19 @@ import 'package:mockito/mockito.dart' as _i2; // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class -class _FakeGlobalKey_0> - extends _i2.SmartFake implements _i1.GlobalKey { - _FakeGlobalKey_0( +class _FakeBuildContext_0 extends _i1.SmartFake implements _i2.BuildContext { + _FakeBuildContext_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeGlobalKey_1> + extends _i1.SmartFake implements _i2.GlobalKey { + _FakeGlobalKey_1( Object parent, Invocation parentInvocation, ) : super( @@ -40,9 +50,9 @@ class _FakeGlobalKey_0> /// A class which mocks [LoginRepository]. /// /// See the documentation for Mockito's code generation for more information. -class MockLoginRepository extends _i2.Mock implements _i3.LoginRepository { +class MockLoginRepository extends _i1.Mock implements _i3.LoginRepository { MockLoginRepository() { - _i2.throwOnMissingStub(this); + _i1.throwOnMissingStub(this); } @override @@ -79,19 +89,28 @@ class MockLoginRepository extends _i2.Mock implements _i3.LoginRepository { /// A class which mocks [MainNavigator]. /// /// See the documentation for Mockito's code generation for more information. -class MockMainNavigator extends _i2.Mock implements _i5.MainNavigator { +class MockMainNavigator extends _i1.Mock implements _i5.MainNavigator { MockMainNavigator() { - _i2.throwOnMissingStub(this); + _i1.throwOnMissingStub(this); } @override - _i1.GlobalKey<_i1.NavigatorState> get navigatorKey => (super.noSuchMethod( + _i2.BuildContext get context => (super.noSuchMethod( + Invocation.getter(#context), + returnValue: _FakeBuildContext_0( + this, + Invocation.getter(#context), + ), + ) as _i2.BuildContext); + + @override + _i2.GlobalKey<_i2.NavigatorState> get navigatorKey => (super.noSuchMethod( Invocation.getter(#navigatorKey), - returnValue: _FakeGlobalKey_0<_i1.NavigatorState>( + returnValue: _FakeGlobalKey_1<_i2.NavigatorState>( this, Invocation.getter(#navigatorKey), ), - ) as _i1.GlobalKey<_i1.NavigatorState>); + ) as _i2.GlobalKey<_i2.NavigatorState>); @override _i4.Future goToDatabase(_i6.GeneratedDatabase? db) => @@ -153,14 +172,14 @@ class MockMainNavigator extends _i2.Mock implements _i5.MainNavigator { ) as _i4.Future); @override - _i1.Route? onGenerateRoute(_i1.RouteSettings? settings) => + _i2.Route? onGenerateRoute(_i2.RouteSettings? settings) => (super.noSuchMethod(Invocation.method( #onGenerateRoute, [settings], - )) as _i1.Route?); + )) as _i2.Route?); @override - void goToHomeScreen({_i1.Key? key}) => super.noSuchMethod( + void goToHomeScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToHomeScreen, [], @@ -170,7 +189,7 @@ class MockMainNavigator extends _i2.Mock implements _i5.MainNavigator { ); @override - void goToSplashScreen({_i1.Key? key}) => super.noSuchMethod( + void goToSplashScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToSplashScreen, [], @@ -180,7 +199,7 @@ class MockMainNavigator extends _i2.Mock implements _i5.MainNavigator { ); @override - _i4.Future goToLicenseScreen({_i1.Key? key}) => (super.noSuchMethod( + _i4.Future goToLicenseScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToLicenseScreen, [], @@ -191,7 +210,25 @@ class MockMainNavigator extends _i2.Mock implements _i5.MainNavigator { ) as _i4.Future); @override - _i4.Future goToTodoAddScreen({_i1.Key? key}) => (super.noSuchMethod( + _i4.Future goToLogDetailScreen({ + required String? date, + _i2.Key? key, + }) => + (super.noSuchMethod( + Invocation.method( + #goToLogDetailScreen, + [], + { + #date: date, + #key: key, + }, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future goToTodoAddScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToTodoAddScreen, [], @@ -202,7 +239,18 @@ class MockMainNavigator extends _i2.Mock implements _i5.MainNavigator { ) as _i4.Future); @override - _i4.Future goToAnalyticsPermissionScreen({_i1.Key? key}) => + _i4.Future goToLogsScreen({_i2.Key? key}) => (super.noSuchMethod( + Invocation.method( + #goToLogsScreen, + [], + {#key: key}, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future goToAnalyticsPermissionScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToAnalyticsPermissionScreen, @@ -214,7 +262,7 @@ class MockMainNavigator extends _i2.Mock implements _i5.MainNavigator { ) as _i4.Future); @override - void goToLoginScreen({_i1.Key? key}) => super.noSuchMethod( + void goToLoginScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToLoginScreen, [], @@ -224,7 +272,7 @@ class MockMainNavigator extends _i2.Mock implements _i5.MainNavigator { ); @override - _i4.Future goToThemeModeSelectorScreen({_i1.Key? key}) => + _i4.Future goToThemeModeSelectorScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToThemeModeSelectorScreen, @@ -236,7 +284,7 @@ class MockMainNavigator extends _i2.Mock implements _i5.MainNavigator { ) as _i4.Future); @override - _i4.Future goToDebugPlatformSelectorScreen({_i1.Key? key}) => + _i4.Future goToDebugPlatformSelectorScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToDebugPlatformSelectorScreen, @@ -248,7 +296,7 @@ class MockMainNavigator extends _i2.Mock implements _i5.MainNavigator { ) as _i4.Future); @override - _i4.Future goToDebugScreen({_i1.Key? key}) => (super.noSuchMethod( + _i4.Future goToDebugScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToDebugScreen, [], @@ -278,7 +326,7 @@ class MockMainNavigator extends _i2.Mock implements _i5.MainNavigator { ); @override - void popUntil(bool Function(_i1.Route)? predicate) => + void popUntil(bool Function(_i2.Route)? predicate) => super.noSuchMethod( Invocation.method( #popUntil, @@ -297,7 +345,7 @@ class MockMainNavigator extends _i2.Mock implements _i5.MainNavigator { ); @override - _i4.Future showCustomDialog({_i1.Widget? widget}) => + _i4.Future showCustomDialog({_i2.Widget? widget}) => (super.noSuchMethod( Invocation.method( #showCustomDialog, @@ -308,7 +356,7 @@ class MockMainNavigator extends _i2.Mock implements _i5.MainNavigator { ) as _i4.Future); @override - _i4.Future showBottomSheet({_i1.Widget? widget}) => + _i4.Future showBottomSheet({_i2.Widget? widget}) => (super.noSuchMethod( Invocation.method( #showBottomSheet, @@ -322,10 +370,10 @@ class MockMainNavigator extends _i2.Mock implements _i5.MainNavigator { /// A class which mocks [OnboardingNavigator]. /// /// See the documentation for Mockito's code generation for more information. -class MockOnboardingNavigator extends _i2.Mock +class MockOnboardingNavigator extends _i1.Mock implements _i8.OnboardingNavigator { MockOnboardingNavigator() { - _i2.throwOnMissingStub(this); + _i1.throwOnMissingStub(this); } @override diff --git a/test/viewmodel/theme_selector/theme_selector_viewmodel_test.mocks.dart b/test/viewmodel/theme_selector/theme_selector_viewmodel_test.mocks.dart index 33da3243..f6d9506c 100644 --- a/test/viewmodel/theme_selector/theme_selector_viewmodel_test.mocks.dart +++ b/test/viewmodel/theme_selector/theme_selector_viewmodel_test.mocks.dart @@ -7,13 +7,13 @@ import 'dart:async' as _i5; import 'dart:ui' as _i4; import 'package:drift/drift.dart' as _i10; -import 'package:flutter/material.dart' as _i1; +import 'package:flutter/material.dart' as _i2; import 'package:flutter_template/model/snackbar/snackbar_data.dart' as _i11; import 'package:flutter_template/navigator/main_navigator.dart' as _i9; import 'package:flutter_template/util/locale/localization.dart' as _i7; import 'package:flutter_template/viewmodel/global/global_viewmodel.dart' as _i3; import 'package:icapps_architecture/icapps_architecture.dart' as _i8; -import 'package:mockito/mockito.dart' as _i2; +import 'package:mockito/mockito.dart' as _i1; import 'package:mockito/src/dummies.dart' as _i6; // ignore_for_file: type=lint @@ -29,9 +29,19 @@ import 'package:mockito/src/dummies.dart' as _i6; // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class -class _FakeGlobalKey_0> - extends _i2.SmartFake implements _i1.GlobalKey { - _FakeGlobalKey_0( +class _FakeBuildContext_0 extends _i1.SmartFake implements _i2.BuildContext { + _FakeBuildContext_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeGlobalKey_1> + extends _i1.SmartFake implements _i2.GlobalKey { + _FakeGlobalKey_1( Object parent, Invocation parentInvocation, ) : super( @@ -43,9 +53,9 @@ class _FakeGlobalKey_0> /// A class which mocks [GlobalViewModel]. /// /// See the documentation for Mockito's code generation for more information. -class MockGlobalViewModel extends _i2.Mock implements _i3.GlobalViewModel { +class MockGlobalViewModel extends _i1.Mock implements _i3.GlobalViewModel { MockGlobalViewModel() { - _i2.throwOnMissingStub(this); + _i1.throwOnMissingStub(this); } @override @@ -55,10 +65,10 @@ class MockGlobalViewModel extends _i2.Mock implements _i3.GlobalViewModel { ) as List<_i4.Locale>); @override - _i1.ThemeMode get themeMode => (super.noSuchMethod( + _i2.ThemeMode get themeMode => (super.noSuchMethod( Invocation.getter(#themeMode), - returnValue: _i1.ThemeMode.system, - ) as _i1.ThemeMode); + returnValue: _i2.ThemeMode.system, + ) as _i2.ThemeMode); @override bool get showsTranslationKeys => (super.noSuchMethod( @@ -89,7 +99,7 @@ class MockGlobalViewModel extends _i2.Mock implements _i3.GlobalViewModel { ) as _i5.Future); @override - _i5.Future updateThemeMode(_i1.ThemeMode? themeMode) => + _i5.Future updateThemeMode(_i2.ThemeMode? themeMode) => (super.noSuchMethod( Invocation.method( #updateThemeMode, @@ -291,19 +301,28 @@ class MockGlobalViewModel extends _i2.Mock implements _i3.GlobalViewModel { /// A class which mocks [MainNavigator]. /// /// See the documentation for Mockito's code generation for more information. -class MockMainNavigator extends _i2.Mock implements _i9.MainNavigator { +class MockMainNavigator extends _i1.Mock implements _i9.MainNavigator { MockMainNavigator() { - _i2.throwOnMissingStub(this); + _i1.throwOnMissingStub(this); } @override - _i1.GlobalKey<_i1.NavigatorState> get navigatorKey => (super.noSuchMethod( + _i2.BuildContext get context => (super.noSuchMethod( + Invocation.getter(#context), + returnValue: _FakeBuildContext_0( + this, + Invocation.getter(#context), + ), + ) as _i2.BuildContext); + + @override + _i2.GlobalKey<_i2.NavigatorState> get navigatorKey => (super.noSuchMethod( Invocation.getter(#navigatorKey), - returnValue: _FakeGlobalKey_0<_i1.NavigatorState>( + returnValue: _FakeGlobalKey_1<_i2.NavigatorState>( this, Invocation.getter(#navigatorKey), ), - ) as _i1.GlobalKey<_i1.NavigatorState>); + ) as _i2.GlobalKey<_i2.NavigatorState>); @override _i5.Future goToDatabase(_i10.GeneratedDatabase? db) => @@ -365,14 +384,14 @@ class MockMainNavigator extends _i2.Mock implements _i9.MainNavigator { ) as _i5.Future); @override - _i1.Route? onGenerateRoute(_i1.RouteSettings? settings) => + _i2.Route? onGenerateRoute(_i2.RouteSettings? settings) => (super.noSuchMethod(Invocation.method( #onGenerateRoute, [settings], - )) as _i1.Route?); + )) as _i2.Route?); @override - void goToHomeScreen({_i1.Key? key}) => super.noSuchMethod( + void goToHomeScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToHomeScreen, [], @@ -382,7 +401,7 @@ class MockMainNavigator extends _i2.Mock implements _i9.MainNavigator { ); @override - void goToSplashScreen({_i1.Key? key}) => super.noSuchMethod( + void goToSplashScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToSplashScreen, [], @@ -392,7 +411,7 @@ class MockMainNavigator extends _i2.Mock implements _i9.MainNavigator { ); @override - _i5.Future goToLicenseScreen({_i1.Key? key}) => (super.noSuchMethod( + _i5.Future goToLicenseScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToLicenseScreen, [], @@ -403,7 +422,25 @@ class MockMainNavigator extends _i2.Mock implements _i9.MainNavigator { ) as _i5.Future); @override - _i5.Future goToTodoAddScreen({_i1.Key? key}) => (super.noSuchMethod( + _i5.Future goToLogDetailScreen({ + required String? date, + _i2.Key? key, + }) => + (super.noSuchMethod( + Invocation.method( + #goToLogDetailScreen, + [], + { + #date: date, + #key: key, + }, + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future goToTodoAddScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToTodoAddScreen, [], @@ -414,7 +451,18 @@ class MockMainNavigator extends _i2.Mock implements _i9.MainNavigator { ) as _i5.Future); @override - _i5.Future goToAnalyticsPermissionScreen({_i1.Key? key}) => + _i5.Future goToLogsScreen({_i2.Key? key}) => (super.noSuchMethod( + Invocation.method( + #goToLogsScreen, + [], + {#key: key}, + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future goToAnalyticsPermissionScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToAnalyticsPermissionScreen, @@ -426,7 +474,7 @@ class MockMainNavigator extends _i2.Mock implements _i9.MainNavigator { ) as _i5.Future); @override - void goToLoginScreen({_i1.Key? key}) => super.noSuchMethod( + void goToLoginScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToLoginScreen, [], @@ -436,7 +484,7 @@ class MockMainNavigator extends _i2.Mock implements _i9.MainNavigator { ); @override - _i5.Future goToThemeModeSelectorScreen({_i1.Key? key}) => + _i5.Future goToThemeModeSelectorScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToThemeModeSelectorScreen, @@ -448,7 +496,7 @@ class MockMainNavigator extends _i2.Mock implements _i9.MainNavigator { ) as _i5.Future); @override - _i5.Future goToDebugPlatformSelectorScreen({_i1.Key? key}) => + _i5.Future goToDebugPlatformSelectorScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToDebugPlatformSelectorScreen, @@ -460,7 +508,7 @@ class MockMainNavigator extends _i2.Mock implements _i9.MainNavigator { ) as _i5.Future); @override - _i5.Future goToDebugScreen({_i1.Key? key}) => (super.noSuchMethod( + _i5.Future goToDebugScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToDebugScreen, [], @@ -490,7 +538,7 @@ class MockMainNavigator extends _i2.Mock implements _i9.MainNavigator { ); @override - void popUntil(bool Function(_i1.Route)? predicate) => + void popUntil(bool Function(_i2.Route)? predicate) => super.noSuchMethod( Invocation.method( #popUntil, @@ -509,7 +557,7 @@ class MockMainNavigator extends _i2.Mock implements _i9.MainNavigator { ); @override - _i5.Future showCustomDialog({_i1.Widget? widget}) => + _i5.Future showCustomDialog({_i2.Widget? widget}) => (super.noSuchMethod( Invocation.method( #showCustomDialog, @@ -520,7 +568,7 @@ class MockMainNavigator extends _i2.Mock implements _i9.MainNavigator { ) as _i5.Future); @override - _i5.Future showBottomSheet({_i1.Widget? widget}) => + _i5.Future showBottomSheet({_i2.Widget? widget}) => (super.noSuchMethod( Invocation.method( #showBottomSheet, diff --git a/test/viewmodel/todo/todo_add/todo_add_viewmodel_test.mocks.dart b/test/viewmodel/todo/todo_add/todo_add_viewmodel_test.mocks.dart index d6fea5d6..ff1a0bb2 100644 --- a/test/viewmodel/todo/todo_add/todo_add_viewmodel_test.mocks.dart +++ b/test/viewmodel/todo/todo_add/todo_add_viewmodel_test.mocks.dart @@ -6,12 +6,12 @@ import 'dart:async' as _i4; import 'package:drift/drift.dart' as _i7; -import 'package:flutter/material.dart' as _i1; +import 'package:flutter/material.dart' as _i2; import 'package:flutter_template/model/snackbar/snackbar_data.dart' as _i8; import 'package:flutter_template/model/webservice/todo/todo.dart' as _i5; import 'package:flutter_template/navigator/main_navigator.dart' as _i6; import 'package:flutter_template/repository/todo/todo_repository.dart' as _i3; -import 'package:mockito/mockito.dart' as _i2; +import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -26,9 +26,19 @@ import 'package:mockito/mockito.dart' as _i2; // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class -class _FakeGlobalKey_0> - extends _i2.SmartFake implements _i1.GlobalKey { - _FakeGlobalKey_0( +class _FakeBuildContext_0 extends _i1.SmartFake implements _i2.BuildContext { + _FakeBuildContext_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeGlobalKey_1> + extends _i1.SmartFake implements _i2.GlobalKey { + _FakeGlobalKey_1( Object parent, Invocation parentInvocation, ) : super( @@ -40,9 +50,9 @@ class _FakeGlobalKey_0> /// A class which mocks [TodoRepository]. /// /// See the documentation for Mockito's code generation for more information. -class MockTodoRepository extends _i2.Mock implements _i3.TodoRepository { +class MockTodoRepository extends _i1.Mock implements _i3.TodoRepository { MockTodoRepository() { - _i2.throwOnMissingStub(this); + _i1.throwOnMissingStub(this); } @override @@ -95,19 +105,28 @@ class MockTodoRepository extends _i2.Mock implements _i3.TodoRepository { /// A class which mocks [MainNavigator]. /// /// See the documentation for Mockito's code generation for more information. -class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { +class MockMainNavigator extends _i1.Mock implements _i6.MainNavigator { MockMainNavigator() { - _i2.throwOnMissingStub(this); + _i1.throwOnMissingStub(this); } @override - _i1.GlobalKey<_i1.NavigatorState> get navigatorKey => (super.noSuchMethod( + _i2.BuildContext get context => (super.noSuchMethod( + Invocation.getter(#context), + returnValue: _FakeBuildContext_0( + this, + Invocation.getter(#context), + ), + ) as _i2.BuildContext); + + @override + _i2.GlobalKey<_i2.NavigatorState> get navigatorKey => (super.noSuchMethod( Invocation.getter(#navigatorKey), - returnValue: _FakeGlobalKey_0<_i1.NavigatorState>( + returnValue: _FakeGlobalKey_1<_i2.NavigatorState>( this, Invocation.getter(#navigatorKey), ), - ) as _i1.GlobalKey<_i1.NavigatorState>); + ) as _i2.GlobalKey<_i2.NavigatorState>); @override _i4.Future goToDatabase(_i7.GeneratedDatabase? db) => @@ -169,14 +188,14 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ) as _i4.Future); @override - _i1.Route? onGenerateRoute(_i1.RouteSettings? settings) => + _i2.Route? onGenerateRoute(_i2.RouteSettings? settings) => (super.noSuchMethod(Invocation.method( #onGenerateRoute, [settings], - )) as _i1.Route?); + )) as _i2.Route?); @override - void goToHomeScreen({_i1.Key? key}) => super.noSuchMethod( + void goToHomeScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToHomeScreen, [], @@ -186,7 +205,7 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ); @override - void goToSplashScreen({_i1.Key? key}) => super.noSuchMethod( + void goToSplashScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToSplashScreen, [], @@ -196,7 +215,7 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ); @override - _i4.Future goToLicenseScreen({_i1.Key? key}) => (super.noSuchMethod( + _i4.Future goToLicenseScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToLicenseScreen, [], @@ -207,7 +226,25 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ) as _i4.Future); @override - _i4.Future goToTodoAddScreen({_i1.Key? key}) => (super.noSuchMethod( + _i4.Future goToLogDetailScreen({ + required String? date, + _i2.Key? key, + }) => + (super.noSuchMethod( + Invocation.method( + #goToLogDetailScreen, + [], + { + #date: date, + #key: key, + }, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future goToTodoAddScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToTodoAddScreen, [], @@ -218,7 +255,18 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ) as _i4.Future); @override - _i4.Future goToAnalyticsPermissionScreen({_i1.Key? key}) => + _i4.Future goToLogsScreen({_i2.Key? key}) => (super.noSuchMethod( + Invocation.method( + #goToLogsScreen, + [], + {#key: key}, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future goToAnalyticsPermissionScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToAnalyticsPermissionScreen, @@ -230,7 +278,7 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ) as _i4.Future); @override - void goToLoginScreen({_i1.Key? key}) => super.noSuchMethod( + void goToLoginScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToLoginScreen, [], @@ -240,7 +288,7 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ); @override - _i4.Future goToThemeModeSelectorScreen({_i1.Key? key}) => + _i4.Future goToThemeModeSelectorScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToThemeModeSelectorScreen, @@ -252,7 +300,7 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ) as _i4.Future); @override - _i4.Future goToDebugPlatformSelectorScreen({_i1.Key? key}) => + _i4.Future goToDebugPlatformSelectorScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToDebugPlatformSelectorScreen, @@ -264,7 +312,7 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ) as _i4.Future); @override - _i4.Future goToDebugScreen({_i1.Key? key}) => (super.noSuchMethod( + _i4.Future goToDebugScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToDebugScreen, [], @@ -294,7 +342,7 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ); @override - void popUntil(bool Function(_i1.Route)? predicate) => + void popUntil(bool Function(_i2.Route)? predicate) => super.noSuchMethod( Invocation.method( #popUntil, @@ -313,7 +361,7 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ); @override - _i4.Future showCustomDialog({_i1.Widget? widget}) => + _i4.Future showCustomDialog({_i2.Widget? widget}) => (super.noSuchMethod( Invocation.method( #showCustomDialog, @@ -324,7 +372,7 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ) as _i4.Future); @override - _i4.Future showBottomSheet({_i1.Widget? widget}) => + _i4.Future showBottomSheet({_i2.Widget? widget}) => (super.noSuchMethod( Invocation.method( #showBottomSheet, diff --git a/test/viewmodel/todo/todo_list/todo_list_viewmodel_test.mocks.dart b/test/viewmodel/todo/todo_list/todo_list_viewmodel_test.mocks.dart index ed816be2..52e169ce 100644 --- a/test/viewmodel/todo/todo_list/todo_list_viewmodel_test.mocks.dart +++ b/test/viewmodel/todo/todo_list/todo_list_viewmodel_test.mocks.dart @@ -6,12 +6,12 @@ import 'dart:async' as _i4; import 'package:drift/drift.dart' as _i7; -import 'package:flutter/material.dart' as _i1; +import 'package:flutter/material.dart' as _i2; import 'package:flutter_template/model/snackbar/snackbar_data.dart' as _i8; import 'package:flutter_template/model/webservice/todo/todo.dart' as _i5; import 'package:flutter_template/navigator/main_navigator.dart' as _i6; import 'package:flutter_template/repository/todo/todo_repository.dart' as _i3; -import 'package:mockito/mockito.dart' as _i2; +import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -26,9 +26,19 @@ import 'package:mockito/mockito.dart' as _i2; // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class -class _FakeGlobalKey_0> - extends _i2.SmartFake implements _i1.GlobalKey { - _FakeGlobalKey_0( +class _FakeBuildContext_0 extends _i1.SmartFake implements _i2.BuildContext { + _FakeBuildContext_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeGlobalKey_1> + extends _i1.SmartFake implements _i2.GlobalKey { + _FakeGlobalKey_1( Object parent, Invocation parentInvocation, ) : super( @@ -40,9 +50,9 @@ class _FakeGlobalKey_0> /// A class which mocks [TodoRepository]. /// /// See the documentation for Mockito's code generation for more information. -class MockTodoRepository extends _i2.Mock implements _i3.TodoRepository { +class MockTodoRepository extends _i1.Mock implements _i3.TodoRepository { MockTodoRepository() { - _i2.throwOnMissingStub(this); + _i1.throwOnMissingStub(this); } @override @@ -95,19 +105,28 @@ class MockTodoRepository extends _i2.Mock implements _i3.TodoRepository { /// A class which mocks [MainNavigator]. /// /// See the documentation for Mockito's code generation for more information. -class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { +class MockMainNavigator extends _i1.Mock implements _i6.MainNavigator { MockMainNavigator() { - _i2.throwOnMissingStub(this); + _i1.throwOnMissingStub(this); } @override - _i1.GlobalKey<_i1.NavigatorState> get navigatorKey => (super.noSuchMethod( + _i2.BuildContext get context => (super.noSuchMethod( + Invocation.getter(#context), + returnValue: _FakeBuildContext_0( + this, + Invocation.getter(#context), + ), + ) as _i2.BuildContext); + + @override + _i2.GlobalKey<_i2.NavigatorState> get navigatorKey => (super.noSuchMethod( Invocation.getter(#navigatorKey), - returnValue: _FakeGlobalKey_0<_i1.NavigatorState>( + returnValue: _FakeGlobalKey_1<_i2.NavigatorState>( this, Invocation.getter(#navigatorKey), ), - ) as _i1.GlobalKey<_i1.NavigatorState>); + ) as _i2.GlobalKey<_i2.NavigatorState>); @override _i4.Future goToDatabase(_i7.GeneratedDatabase? db) => @@ -169,14 +188,14 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ) as _i4.Future); @override - _i1.Route? onGenerateRoute(_i1.RouteSettings? settings) => + _i2.Route? onGenerateRoute(_i2.RouteSettings? settings) => (super.noSuchMethod(Invocation.method( #onGenerateRoute, [settings], - )) as _i1.Route?); + )) as _i2.Route?); @override - void goToHomeScreen({_i1.Key? key}) => super.noSuchMethod( + void goToHomeScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToHomeScreen, [], @@ -186,7 +205,7 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ); @override - void goToSplashScreen({_i1.Key? key}) => super.noSuchMethod( + void goToSplashScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToSplashScreen, [], @@ -196,7 +215,7 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ); @override - _i4.Future goToLicenseScreen({_i1.Key? key}) => (super.noSuchMethod( + _i4.Future goToLicenseScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToLicenseScreen, [], @@ -207,7 +226,25 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ) as _i4.Future); @override - _i4.Future goToTodoAddScreen({_i1.Key? key}) => (super.noSuchMethod( + _i4.Future goToLogDetailScreen({ + required String? date, + _i2.Key? key, + }) => + (super.noSuchMethod( + Invocation.method( + #goToLogDetailScreen, + [], + { + #date: date, + #key: key, + }, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future goToTodoAddScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToTodoAddScreen, [], @@ -218,7 +255,18 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ) as _i4.Future); @override - _i4.Future goToAnalyticsPermissionScreen({_i1.Key? key}) => + _i4.Future goToLogsScreen({_i2.Key? key}) => (super.noSuchMethod( + Invocation.method( + #goToLogsScreen, + [], + {#key: key}, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future goToAnalyticsPermissionScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToAnalyticsPermissionScreen, @@ -230,7 +278,7 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ) as _i4.Future); @override - void goToLoginScreen({_i1.Key? key}) => super.noSuchMethod( + void goToLoginScreen({_i2.Key? key}) => super.noSuchMethod( Invocation.method( #goToLoginScreen, [], @@ -240,7 +288,7 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ); @override - _i4.Future goToThemeModeSelectorScreen({_i1.Key? key}) => + _i4.Future goToThemeModeSelectorScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToThemeModeSelectorScreen, @@ -252,7 +300,7 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ) as _i4.Future); @override - _i4.Future goToDebugPlatformSelectorScreen({_i1.Key? key}) => + _i4.Future goToDebugPlatformSelectorScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToDebugPlatformSelectorScreen, @@ -264,7 +312,7 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ) as _i4.Future); @override - _i4.Future goToDebugScreen({_i1.Key? key}) => (super.noSuchMethod( + _i4.Future goToDebugScreen({_i2.Key? key}) => (super.noSuchMethod( Invocation.method( #goToDebugScreen, [], @@ -294,7 +342,7 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ); @override - void popUntil(bool Function(_i1.Route)? predicate) => + void popUntil(bool Function(_i2.Route)? predicate) => super.noSuchMethod( Invocation.method( #popUntil, @@ -313,7 +361,7 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ); @override - _i4.Future showCustomDialog({_i1.Widget? widget}) => + _i4.Future showCustomDialog({_i2.Widget? widget}) => (super.noSuchMethod( Invocation.method( #showCustomDialog, @@ -324,7 +372,7 @@ class MockMainNavigator extends _i2.Mock implements _i6.MainNavigator { ) as _i4.Future); @override - _i4.Future showBottomSheet({_i1.Widget? widget}) => + _i4.Future showBottomSheet({_i2.Widget? widget}) => (super.noSuchMethod( Invocation.method( #showBottomSheet, diff --git a/test/widget/debug/debug_row_title_test.dart b/test/widget/debug/debug_row_title_test.dart index a8300901..9b9c2223 100644 --- a/test/widget/debug/debug_row_title_test.dart +++ b/test/widget/debug/debug_row_title_test.dart @@ -1,3 +1,4 @@ +import 'package:flutter_template/styles/theme_assets.dart'; import 'package:flutter_template/widget/debug/debug_row_title.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -5,7 +6,10 @@ import '../../util/test_util.dart'; void main() { testWidgets('DebugRowTitle default', (tester) async { - final widget = DebugRowTitle(title: TestUtil.getVariableString()); + final widget = DebugRowTitle( + title: TestUtil.getVariableString(), + icon: ThemeAssets.fileIcon, + ); await TestUtil.loadWidgetWithText(tester, widget); await TestUtil.takeScreenshot(tester, 'debug_row_title_default_state'); diff --git a/test/widget/debug/img/debug_row_item_with_subtitle.png b/test/widget/debug/img/debug_row_item_with_subtitle.png index 3fd85455..b493754c 100644 Binary files a/test/widget/debug/img/debug_row_item_with_subtitle.png and b/test/widget/debug/img/debug_row_item_with_subtitle.png differ diff --git a/test/widget/debug/img/debug_row_item_with_title.png b/test/widget/debug/img/debug_row_item_with_title.png index 45346905..c5d2f136 100644 Binary files a/test/widget/debug/img/debug_row_item_with_title.png and b/test/widget/debug/img/debug_row_item_with_title.png differ diff --git a/test/widget/debug/img/debug_row_title_default_state.png b/test/widget/debug/img/debug_row_title_default_state.png index 368dad9d..98b8bf9b 100644 Binary files a/test/widget/debug/img/debug_row_title_default_state.png and b/test/widget/debug/img/debug_row_title_default_state.png differ diff --git a/test/widget/debug/img/debug_switch_row_item_selected_state.png b/test/widget/debug/img/debug_switch_row_item_selected_state.png index 9eca959c..39986ddc 100644 Binary files a/test/widget/debug/img/debug_switch_row_item_selected_state.png and b/test/widget/debug/img/debug_switch_row_item_selected_state.png differ diff --git a/test/widget/debug/img/debug_switch_row_item_selected_state_subtitle.png b/test/widget/debug/img/debug_switch_row_item_selected_state_subtitle.png index 7389e5a9..def71278 100644 Binary files a/test/widget/debug/img/debug_switch_row_item_selected_state_subtitle.png and b/test/widget/debug/img/debug_switch_row_item_selected_state_subtitle.png differ diff --git a/test/widget/debug/img/debug_switch_row_item_unselected_state.png b/test/widget/debug/img/debug_switch_row_item_unselected_state.png index 202d7534..efcb5ff7 100644 Binary files a/test/widget/debug/img/debug_switch_row_item_unselected_state.png and b/test/widget/debug/img/debug_switch_row_item_unselected_state.png differ diff --git a/test/widget/debug/img/debug_switch_row_item_unselected_state_subtitle.png b/test/widget/debug/img/debug_switch_row_item_unselected_state_subtitle.png index 06dd7a16..938ea9a0 100644 Binary files a/test/widget/debug/img/debug_switch_row_item_unselected_state_subtitle.png and b/test/widget/debug/img/debug_switch_row_item_unselected_state_subtitle.png differ diff --git a/test/widget/debug/img/select_language_dialog_en_selected.png b/test/widget/debug/img/select_language_dialog_en_selected.png index b7f73cdd..880a9a8c 100644 Binary files a/test/widget/debug/img/select_language_dialog_en_selected.png and b/test/widget/debug/img/select_language_dialog_en_selected.png differ diff --git a/test/widget/debug/img/select_language_dialog_initial_state.png b/test/widget/debug/img/select_language_dialog_initial_state.png index b7f73cdd..880a9a8c 100644 Binary files a/test/widget/debug/img/select_language_dialog_initial_state.png and b/test/widget/debug/img/select_language_dialog_initial_state.png differ diff --git a/test/widget/debug/img/select_language_dialog_nl_selected.png b/test/widget/debug/img/select_language_dialog_nl_selected.png index 1d643745..44effaa4 100644 Binary files a/test/widget/debug/img/select_language_dialog_nl_selected.png and b/test/widget/debug/img/select_language_dialog_nl_selected.png differ diff --git a/test/widget/debug/img/select_language_dialog_system_defaults_selected.png b/test/widget/debug/img/select_language_dialog_system_defaults_selected.png index d9e49f2d..f7c5f306 100644 Binary files a/test/widget/debug/img/select_language_dialog_system_defaults_selected.png and b/test/widget/debug/img/select_language_dialog_system_defaults_selected.png differ diff --git a/test/widget/debug/img/selector_item_initial_state.png b/test/widget/debug/img/selector_item_initial_state.png index fde1b4a7..aefd97d2 100644 Binary files a/test/widget/debug/img/selector_item_initial_state.png and b/test/widget/debug/img/selector_item_initial_state.png differ diff --git a/test/widget/debug/img/selector_item_selected_state.png b/test/widget/debug/img/selector_item_selected_state.png index 2bb8843c..ac575c43 100644 Binary files a/test/widget/debug/img/selector_item_selected_state.png and b/test/widget/debug/img/selector_item_selected_state.png differ diff --git a/test/widget/general/action/action_item_test.dart b/test/widget/general/action/action_item_test.dart index 53296183..028c279d 100644 --- a/test/widget/general/action/action_item_test.dart +++ b/test/widget/general/action/action_item_test.dart @@ -12,7 +12,7 @@ void main() { data: FlutterTemplateThemeData.lightTheme(TargetPlatform.android), child: LayoutBuilder( builder: (context, constraint) => ActionItem( - svgAsset: ThemeAssets.addIcon(context), + svgAsset: ThemeAssets.addIcon, onClick: () {}, ), ), @@ -27,7 +27,7 @@ void main() { data: FlutterTemplateThemeData.lightTheme(TargetPlatform.android), child: LayoutBuilder( builder: (context, constraint) => ActionItem( - svgAsset: ThemeAssets.addIcon(context), + svgAsset: ThemeAssets.addIcon, color: Colors.black, onClick: () {}, ), @@ -45,7 +45,7 @@ void main() { data: FlutterTemplateThemeData.lightTheme(TargetPlatform.android), child: LayoutBuilder( builder: (context, constraint) => ActionItem( - svgAsset: ThemeAssets.addIcon(context), + svgAsset: ThemeAssets.addIcon, onClick: () { clicked = true; }, diff --git a/test/widget/general/action/img/action_item_after_click.png b/test/widget/general/action/img/action_item_after_click.png index 2a715c9e..9b25170e 100644 Binary files a/test/widget/general/action/img/action_item_after_click.png and b/test/widget/general/action/img/action_item_after_click.png differ diff --git a/test/widget/general/action/img/action_item_before_click.png b/test/widget/general/action/img/action_item_before_click.png index 2a715c9e..9b25170e 100644 Binary files a/test/widget/general/action/img/action_item_before_click.png and b/test/widget/general/action/img/action_item_before_click.png differ diff --git a/test/widget/general/action/img/action_item_custom_color.png b/test/widget/general/action/img/action_item_custom_color.png index 1ca4c791..f90aec44 100644 Binary files a/test/widget/general/action/img/action_item_custom_color.png and b/test/widget/general/action/img/action_item_custom_color.png differ diff --git a/test/widget/general/action/img/action_item_default_state.png b/test/widget/general/action/img/action_item_default_state.png index 2a715c9e..9b25170e 100644 Binary files a/test/widget/general/action/img/action_item_default_state.png and b/test/widget/general/action/img/action_item_default_state.png differ diff --git a/test/widget/general/img/svg_icon_custom_color.png b/test/widget/general/img/svg_icon_custom_color.png index dd902fb3..5d7bfbc7 100644 Binary files a/test/widget/general/img/svg_icon_custom_color.png and b/test/widget/general/img/svg_icon_custom_color.png differ diff --git a/test/widget/general/img/svg_icon_custom_size.png b/test/widget/general/img/svg_icon_custom_size.png index 0ac767cf..51387a17 100644 Binary files a/test/widget/general/img/svg_icon_custom_size.png and b/test/widget/general/img/svg_icon_custom_size.png differ diff --git a/test/widget/general/img/svg_icon_custom_size_and_color.png b/test/widget/general/img/svg_icon_custom_size_and_color.png index d7802d97..0a90dde6 100644 Binary files a/test/widget/general/img/svg_icon_custom_size_and_color.png and b/test/widget/general/img/svg_icon_custom_size_and_color.png differ diff --git a/test/widget/general/img/svg_icon_initial_state.png b/test/widget/general/img/svg_icon_initial_state.png index bed48634..f90aec44 100644 Binary files a/test/widget/general/img/svg_icon_initial_state.png and b/test/widget/general/img/svg_icon_initial_state.png differ diff --git a/test/widget/general/img/svg_icon_prod_initial_state.png b/test/widget/general/img/svg_icon_prod_initial_state.png index 0d651229..128801a1 100644 Binary files a/test/widget/general/img/svg_icon_prod_initial_state.png and b/test/widget/general/img/svg_icon_prod_initial_state.png differ diff --git a/test/widget/general/styled/img/flutter_template_back_button_dark.png b/test/widget/general/styled/img/flutter_template_back_button_dark.png index 6b6ea139..4e9ba818 100644 Binary files a/test/widget/general/styled/img/flutter_template_back_button_dark.png and b/test/widget/general/styled/img/flutter_template_back_button_dark.png differ diff --git a/test/widget/general/styled/img/flutter_template_back_button_full_screen_dark.png b/test/widget/general/styled/img/flutter_template_back_button_full_screen_dark.png index 747d06dd..4e9ba818 100644 Binary files a/test/widget/general/styled/img/flutter_template_back_button_full_screen_dark.png and b/test/widget/general/styled/img/flutter_template_back_button_full_screen_dark.png differ diff --git a/test/widget/general/styled/img/flutter_template_back_button_full_screen_light.png b/test/widget/general/styled/img/flutter_template_back_button_full_screen_light.png index 64197673..1a602b68 100644 Binary files a/test/widget/general/styled/img/flutter_template_back_button_full_screen_light.png and b/test/widget/general/styled/img/flutter_template_back_button_full_screen_light.png differ diff --git a/test/widget/general/styled/img/flutter_template_back_button_light.png b/test/widget/general/styled/img/flutter_template_back_button_light.png index 60735754..1a602b68 100644 Binary files a/test/widget/general/styled/img/flutter_template_back_button_light.png and b/test/widget/general/styled/img/flutter_template_back_button_light.png differ diff --git a/test/widget/general/styled/img/flutter_template_button_default_state_android.png b/test/widget/general/styled/img/flutter_template_button_default_state_android.png index 4a04b7a3..499d033a 100644 Binary files a/test/widget/general/styled/img/flutter_template_button_default_state_android.png and b/test/widget/general/styled/img/flutter_template_button_default_state_android.png differ diff --git a/test/widget/general/styled/img/flutter_template_button_default_state_ios.png b/test/widget/general/styled/img/flutter_template_button_default_state_ios.png index 4a04b7a3..499d033a 100644 Binary files a/test/widget/general/styled/img/flutter_template_button_default_state_ios.png and b/test/widget/general/styled/img/flutter_template_button_default_state_ios.png differ diff --git a/test/widget/general/styled/img/flutter_template_button_not_enabled_android.png b/test/widget/general/styled/img/flutter_template_button_not_enabled_android.png index 3f14a084..95422802 100644 Binary files a/test/widget/general/styled/img/flutter_template_button_not_enabled_android.png and b/test/widget/general/styled/img/flutter_template_button_not_enabled_android.png differ diff --git a/test/widget/general/styled/img/flutter_template_button_not_enabled_ios.png b/test/widget/general/styled/img/flutter_template_button_not_enabled_ios.png index 3f14a084..95422802 100644 Binary files a/test/widget/general/styled/img/flutter_template_button_not_enabled_ios.png and b/test/widget/general/styled/img/flutter_template_button_not_enabled_ios.png differ diff --git a/test/widget/general/styled/img/flutter_template_button_not_expanded_android.png b/test/widget/general/styled/img/flutter_template_button_not_expanded_android.png index 11217cdf..b3fbe285 100644 Binary files a/test/widget/general/styled/img/flutter_template_button_not_expanded_android.png and b/test/widget/general/styled/img/flutter_template_button_not_expanded_android.png differ diff --git a/test/widget/general/styled/img/flutter_template_button_not_expanded_ios.png b/test/widget/general/styled/img/flutter_template_button_not_expanded_ios.png index 11217cdf..b3fbe285 100644 Binary files a/test/widget/general/styled/img/flutter_template_button_not_expanded_ios.png and b/test/widget/general/styled/img/flutter_template_button_not_expanded_ios.png differ diff --git a/test/widget/general/styled/img/flutter_template_button_with_key_android.png b/test/widget/general/styled/img/flutter_template_button_with_key_android.png index 4a04b7a3..499d033a 100644 Binary files a/test/widget/general/styled/img/flutter_template_button_with_key_android.png and b/test/widget/general/styled/img/flutter_template_button_with_key_android.png differ diff --git a/test/widget/general/styled/img/flutter_template_button_with_key_ios.png b/test/widget/general/styled/img/flutter_template_button_with_key_ios.png index 4a04b7a3..499d033a 100644 Binary files a/test/widget/general/styled/img/flutter_template_button_with_key_ios.png and b/test/widget/general/styled/img/flutter_template_button_with_key_ios.png differ diff --git a/test/widget/general/styled/img/flutter_template_checkbox_true_ios.png b/test/widget/general/styled/img/flutter_template_checkbox_true_ios.png index 0de01030..5eba9941 100644 Binary files a/test/widget/general/styled/img/flutter_template_checkbox_true_ios.png and b/test/widget/general/styled/img/flutter_template_checkbox_true_ios.png differ diff --git a/test/widget/general/styled/img/flutter_template_input_field_type_text_after.png b/test/widget/general/styled/img/flutter_template_input_field_type_text_after.png index 9edee52d..725339e9 100644 Binary files a/test/widget/general/styled/img/flutter_template_input_field_type_text_after.png and b/test/widget/general/styled/img/flutter_template_input_field_type_text_after.png differ diff --git a/test/widget/general/styled/img/flutter_template_switch_false_android.png b/test/widget/general/styled/img/flutter_template_switch_false_android.png index d608b397..79370c94 100644 Binary files a/test/widget/general/styled/img/flutter_template_switch_false_android.png and b/test/widget/general/styled/img/flutter_template_switch_false_android.png differ diff --git a/test/widget/general/styled/img/flutter_template_switch_false_ios.png b/test/widget/general/styled/img/flutter_template_switch_false_ios.png index 032f57de..79370c94 100644 Binary files a/test/widget/general/styled/img/flutter_template_switch_false_ios.png and b/test/widget/general/styled/img/flutter_template_switch_false_ios.png differ diff --git a/test/widget/general/styled/img/flutter_template_switch_true_android.png b/test/widget/general/styled/img/flutter_template_switch_true_android.png index ee01c385..7a0e1599 100644 Binary files a/test/widget/general/styled/img/flutter_template_switch_true_android.png and b/test/widget/general/styled/img/flutter_template_switch_true_android.png differ diff --git a/test/widget/general/styled/img/flutter_template_switch_true_ios.png b/test/widget/general/styled/img/flutter_template_switch_true_ios.png index bbd4106f..7a0e1599 100644 Binary files a/test/widget/general/styled/img/flutter_template_switch_true_ios.png and b/test/widget/general/styled/img/flutter_template_switch_true_ios.png differ diff --git a/test/widget/general/svg_icon_test.dart b/test/widget/general/svg_icon_test.dart index 290ce143..e3bd1a5d 100644 --- a/test/widget/general/svg_icon_test.dart +++ b/test/widget/general/svg_icon_test.dart @@ -1,6 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter_template/styles/theme_assets.dart'; -import 'package:flutter_template/styles/theme_dimens.dart'; import 'package:flutter_template/widget/general/svg_icon.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -8,7 +6,7 @@ import '../../util/test_util.dart'; void main() { testWidgets('SvgIcon initial state', (tester) async { - const sut = SvgIcon(svgAsset: 'assets/images/icons/android/done.svg'); + const sut = SvgIcon(svgAsset: 'assets/images/icons/add.svg'); await TestUtil.loadWidgetWithText(tester, sut); await TestUtil.takeScreenshot(tester, 'svg_icon_initial_state'); @@ -16,7 +14,7 @@ void main() { testWidgets('SvgIcon custom color', (tester) async { const sut = SvgIcon( - svgAsset: 'assets/images/icons/android/done.svg', + svgAsset: 'assets/images/icons/add.svg', color: Colors.purple, ); @@ -26,8 +24,8 @@ void main() { testWidgets('SvgIcon custom size', (tester) async { const sut = SvgIcon( - svgAsset: 'assets/images/icons/android/done.svg', - size: ThemeDimens.padding64, + svgAsset: 'assets/images/icons/add.svg', + size: 64, ); await TestUtil.loadWidgetWithText(tester, sut); @@ -36,22 +34,11 @@ void main() { testWidgets('SvgIcon custom size and color', (tester) async { const sut = SvgIcon( - svgAsset: 'assets/images/icons/android/done.svg', + svgAsset: 'assets/images/icons/add.svg', color: Colors.purple, - size: ThemeDimens.padding64, + size: 64, ); - await TestUtil.loadWidgetWithText(tester, sut); - await TestUtil.takeScreenshot(tester, 'svg_icon_custom_size_and_color'); - }); - testWidgets('SvgIcon custom size and color', (tester) async { - final sut = LayoutBuilder( - builder: (context, constraints) => SvgIcon( - svgAsset: ThemeAssets.doneIcon(context), - color: Colors.purple, - size: ThemeDimens.padding64, - )); - await TestUtil.loadWidgetWithText(tester, sut); await TestUtil.takeScreenshot(tester, 'svg_icon_custom_size_and_color'); }); diff --git a/test/widget/todo/img/todo_row_item_selected_state.png b/test/widget/todo/img/todo_row_item_selected_state.png index 5d556e3d..5b980662 100644 Binary files a/test/widget/todo/img/todo_row_item_selected_state.png and b/test/widget/todo/img/todo_row_item_selected_state.png differ diff --git a/test/widget/todo/img/todo_row_item_unselected_state.png b/test/widget/todo/img/todo_row_item_unselected_state.png index df96fd72..c39de2d3 100644 Binary files a/test/widget/todo/img/todo_row_item_unselected_state.png and b/test/widget/todo/img/todo_row_item_unselected_state.png differ diff --git a/tool/save_database_schema.sh b/tool/save_database_schema.sh new file mode 100755 index 00000000..78dc015b --- /dev/null +++ b/tool/save_database_schema.sh @@ -0,0 +1,12 @@ +CURRENT=`pwd` +DIR_NAME=`basename "$CURRENT"` +if [ $DIR_NAME == 'tool' ] +then + cd .. +fi + +echo What is the current database version? +read version + +fvm dart run drift_dev schema dump lib/database/flutter_template_database.dart test/database/drift_schemas/drift_schema_v$version.json +fvm dart run drift_dev schema generate test/database/drift_schemas/ test/database/schema_versions