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