From d1250e03c9a5e1583e0a00f72d2b1f3645c04979 Mon Sep 17 00:00:00 2001 From: Lukas Hermann Date: Fri, 25 Apr 2025 08:19:19 +0200 Subject: [PATCH 1/4] feat: CustomSystemBarsTheme update --- lib/app/theme/custom_system_bars_theme.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/app/theme/custom_system_bars_theme.dart b/lib/app/theme/custom_system_bars_theme.dart index ef031d8..0e229b2 100644 --- a/lib/app/theme/custom_system_bars_theme.dart +++ b/lib/app/theme/custom_system_bars_theme.dart @@ -89,19 +89,19 @@ class CustomSystemBarsTheme { originalCallback?.call(); final themeMode = await providerContainer.read(themeModeNotifierProvider.future); if (themeMode == ThemeMode.system) { - setSystemBarsTheme(brightness: PlatformDispatcher.instance.platformBrightness); + await setSystemBarsTheme(brightness: PlatformDispatcher.instance.platformBrightness); } }; // HotFix for API 28, that need SystemBarsTheme applied on each app resume! if (AppPlatform.isAndroid) { - final AndroidDeviceInfo androidInfo = await DeviceInfoPlugin().androidInfo; + final AndroidDeviceInfo androidInfo = Configuration.instance.androidDeviceInfo!; if (androidInfo.version.sdkInt == 28) { SystemChannels.lifecycle.setMessageHandler((msg) async { if (msg == AppLifecycleState.resumed.toString()) { final themeMode = await providerContainer.read(themeModeNotifierProvider.future); if (themeMode == ThemeMode.system) { - setSystemBarsTheme(brightness: PlatformDispatcher.instance.platformBrightness); + await setSystemBarsTheme(brightness: PlatformDispatcher.instance.platformBrightness); } } return Future.value(msg); From d156813e2892e845b362bb741f565ec8b9bcc945 Mon Sep 17 00:00:00 2001 From: Lukas Hermann Date: Thu, 15 May 2025 14:31:52 +0200 Subject: [PATCH 2/4] feat: Polishing of TextValidatorController --- .../text_validator_controller_general.dart | 34 +++++++++++-------- .../validator/text_validator_controller.dart | 21 +++++++----- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/lib/common/validator/controller/text_validator_controller_general.dart b/lib/common/validator/controller/text_validator_controller_general.dart index 66ba3a8..8c11e56 100644 --- a/lib/common/validator/controller/text_validator_controller_general.dart +++ b/lib/common/validator/controller/text_validator_controller_general.dart @@ -15,17 +15,15 @@ class TextValidatorControllerGeneral extends TextValidatorController { this.condition, this.conditionText, }) { - if (tooShortText != null && minLength == null) throw Exception('minLength must be also set when tooShortText is set.'); - if (minLength != null && tooShortText == null) throw Exception('tooShortText must be also set when minLength is set.'); - - if (tooLongText != null && maxLength == null) throw Exception('maxLength must be also set when tooLongText is set.'); - if (maxLength != null && tooLongText == null) throw Exception('tooLongText must be also set when maxLength is set.'); - - if (regexText != null && regex == null) throw Exception('regex must be also set when regexText is set.'); - if (regex != null && regexText == null) throw Exception('regexText must be also set when regex is set.'); - - if (conditionText != null && condition == null) throw Exception('condition must be also set when conditionText is set.'); - if (condition != null && conditionText == null) throw Exception('conditionText must be also set when condition is set.'); + if ((tooShortText != null && minLength == null) || (minLength != null && tooShortText == null)) { + throw Exception('minLength and tooShortText must be set together.'); + } else if ((tooLongText != null && maxLength == null) || (maxLength != null && tooLongText == null)) { + throw Exception('maxLength and tooLongText must be set together.'); + } else if ((regexText != null && regex == null) || (regex != null && regexText == null)) { + throw Exception('regex and regexText must be set together.'); + } else if ((conditionText != null && condition == null) || (condition != null && conditionText == null)) { + throw Exception('condition and conditionText must be set together.'); + } } final String Function(BuildContext context)? emptyText; @@ -35,7 +33,7 @@ class TextValidatorControllerGeneral extends TextValidatorController { final String Function(BuildContext context)? tooLongText; final RegExp? regex; final String Function(BuildContext context)? regexText; - final bool Function(String text)? condition; + final Future Function(String text)? condition; final String Function(BuildContext context)? conditionText; TextFieldValidatorState _state = const TextFieldValidatorState.initial(); @@ -44,7 +42,7 @@ class TextValidatorControllerGeneral extends TextValidatorController { TextFieldValidatorState get state => _state; @override - void validate() { + Future validate() async { if (!canValidate) return; final text = controller.text; @@ -57,7 +55,7 @@ class TextValidatorControllerGeneral extends TextValidatorController { _state = TextFieldValidatorState.invalid(exception: ValidatorException.generalIsTooLong(tooLongText!)); } else if (regex != null && !regex!.hasMatch(text)) { _state = TextFieldValidatorState.invalid(exception: ValidatorException.generalIsInvalid(regexText!)); - } else if (condition?.call(text) ?? false) { + } else if (await condition?.call(text) ?? false) { _state = TextFieldValidatorState.invalid(exception: ValidatorException.generalIsInvalid(conditionText!)); } else { _state = const TextFieldValidatorState.valid(); @@ -65,4 +63,12 @@ class TextValidatorControllerGeneral extends TextValidatorController { notifyListeners(); } + + bool isValid() { + return _state is TextFieldValidatorStateValid; + } + + bool isInvalid() { + return _state is TextFieldValidatorStateInvalid; + } } diff --git a/lib/common/validator/text_validator_controller.dart b/lib/common/validator/text_validator_controller.dart index 8c0074a..0de58c0 100644 --- a/lib/common/validator/text_validator_controller.dart +++ b/lib/common/validator/text_validator_controller.dart @@ -18,16 +18,19 @@ abstract class TextValidatorController extends ChangeNotifier { }); } - /// Indicates, if form is validated immediatelly. It's due to postponing validation until some action button is selected. - bool canValidate; + /// Text field controller. final controller = TextEditingController(); + + /// Indicates, if form is validated immediately. It's due to postponing validation until some action button is selected. + bool canValidate; + + /// State of the validator. TextFieldValidatorState get state; - Timer? _debounceTimer; - String get text { - return controller.text; - } + /// Debounce timer to postpone validation. + Timer? _debounceTimer; + String get text => controller.text; set text(String text) { controller.text = text; } @@ -49,10 +52,10 @@ abstract class TextValidatorController extends ChangeNotifier { } /// Sets `canValidate` to `true` and calls `validate()` function. - void forceValidate() { + Future forceValidate() async { canValidate = true; - validate(); + await validate(); } - void validate(); + Future validate(); } From 637af9686e98cc768e34f305eeb80fea88720721 Mon Sep 17 00:00:00 2001 From: Lukas Hermann Date: Wed, 21 May 2025 11:21:37 +0200 Subject: [PATCH 3/4] feat: Update CustomSystemBarsTheme --- lib/app/theme/custom_system_bars_theme.dart | 23 ++++++++------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/lib/app/theme/custom_system_bars_theme.dart b/lib/app/theme/custom_system_bars_theme.dart index 0e229b2..1affbb0 100644 --- a/lib/app/theme/custom_system_bars_theme.dart +++ b/lib/app/theme/custom_system_bars_theme.dart @@ -26,14 +26,9 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; class CustomSystemBarsTheme { static Future setupSystemBarsTheme({required ProviderContainer providerContainer}) async { final brightness = providerContainer.read(themeModeNotifierProvider.notifier).brightness; - await SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); - await _setupSystemBarsUpdateCallback(providerContainer: providerContainer); - await setSystemBarsTheme(brightness: brightness); - } - static Future setSystemBarsTheme({required Brightness brightness}) async { - final brightness = PlatformDispatcher.instance.platformBrightness; - SystemChrome.setSystemUIOverlayStyle((getSystemBarsTheme(brightness: brightness))); + await _setupSystemBarsUpdateCallback(providerContainer: providerContainer); + await _setSystemBarsTheme(brightness: brightness); } static SystemUiOverlayStyle getSystemBarsTheme({required Brightness brightness}) { @@ -46,6 +41,10 @@ class CustomSystemBarsTheme { } } + static Future _setSystemBarsTheme({required Brightness brightness}) async { + SystemChrome.setSystemUIOverlayStyle((getSystemBarsTheme(brightness: brightness))); + } + static SystemUiOverlayStyle _getAndroidSystemBarsTheme({required Brightness brightness}) { final AndroidDeviceInfo androidInfo = Configuration.instance.androidDeviceInfo!; final bool canUseTransparentNavigation = androidInfo.version.sdkInt >= 29; // Enabled by default for iOS @@ -54,7 +53,7 @@ class CustomSystemBarsTheme { // StatusBar systemStatusBarContrastEnforced: false, statusBarColor: Colors.transparent, - statusBarIconBrightness: brightness.inverse, // For Android + statusBarIconBrightness: brightness.inverse, // NavigationBar systemNavigationBarContrastEnforced: false, @@ -72,14 +71,10 @@ class CustomSystemBarsTheme { return SystemUiOverlayStyle( // StatusBar systemStatusBarContrastEnforced: false, - statusBarColor: Colors.transparent, statusBarBrightness: brightness, // For iOS // NavigationBar systemNavigationBarContrastEnforced: false, - systemNavigationBarColor: Colors.transparent, - systemNavigationBarDividerColor: Colors.transparent, - systemNavigationBarIconBrightness: brightness, ); } @@ -89,7 +84,7 @@ class CustomSystemBarsTheme { originalCallback?.call(); final themeMode = await providerContainer.read(themeModeNotifierProvider.future); if (themeMode == ThemeMode.system) { - await setSystemBarsTheme(brightness: PlatformDispatcher.instance.platformBrightness); + await _setSystemBarsTheme(brightness: PlatformDispatcher.instance.platformBrightness); } }; @@ -101,7 +96,7 @@ class CustomSystemBarsTheme { if (msg == AppLifecycleState.resumed.toString()) { final themeMode = await providerContainer.read(themeModeNotifierProvider.future); if (themeMode == ThemeMode.system) { - await setSystemBarsTheme(brightness: PlatformDispatcher.instance.platformBrightness); + await _setSystemBarsTheme(brightness: PlatformDispatcher.instance.platformBrightness); } } return Future.value(msg); From 831c69da66f72d94cf0fb7f36d46eb1f256bf5c6 Mon Sep 17 00:00:00 2001 From: Lukas Hermann Date: Wed, 21 May 2025 11:36:17 +0200 Subject: [PATCH 4/4] fix: Potential issues --- lib/app/theme/custom_system_bars_theme.dart | 10 +++++----- .../controller/text_validator_controller_general.dart | 10 +++------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/lib/app/theme/custom_system_bars_theme.dart b/lib/app/theme/custom_system_bars_theme.dart index 1affbb0..6c2ea46 100644 --- a/lib/app/theme/custom_system_bars_theme.dart +++ b/lib/app/theme/custom_system_bars_theme.dart @@ -28,7 +28,7 @@ class CustomSystemBarsTheme { final brightness = providerContainer.read(themeModeNotifierProvider.notifier).brightness; await _setupSystemBarsUpdateCallback(providerContainer: providerContainer); - await _setSystemBarsTheme(brightness: brightness); + _setSystemBarsTheme(brightness: brightness); } static SystemUiOverlayStyle getSystemBarsTheme({required Brightness brightness}) { @@ -41,8 +41,8 @@ class CustomSystemBarsTheme { } } - static Future _setSystemBarsTheme({required Brightness brightness}) async { - SystemChrome.setSystemUIOverlayStyle((getSystemBarsTheme(brightness: brightness))); + static void _setSystemBarsTheme({required Brightness brightness}) { + SystemChrome.setSystemUIOverlayStyle(getSystemBarsTheme(brightness: brightness)); } static SystemUiOverlayStyle _getAndroidSystemBarsTheme({required Brightness brightness}) { @@ -84,7 +84,7 @@ class CustomSystemBarsTheme { originalCallback?.call(); final themeMode = await providerContainer.read(themeModeNotifierProvider.future); if (themeMode == ThemeMode.system) { - await _setSystemBarsTheme(brightness: PlatformDispatcher.instance.platformBrightness); + _setSystemBarsTheme(brightness: PlatformDispatcher.instance.platformBrightness); } }; @@ -96,7 +96,7 @@ class CustomSystemBarsTheme { if (msg == AppLifecycleState.resumed.toString()) { final themeMode = await providerContainer.read(themeModeNotifierProvider.future); if (themeMode == ThemeMode.system) { - await _setSystemBarsTheme(brightness: PlatformDispatcher.instance.platformBrightness); + _setSystemBarsTheme(brightness: PlatformDispatcher.instance.platformBrightness); } } return Future.value(msg); diff --git a/lib/common/validator/controller/text_validator_controller_general.dart b/lib/common/validator/controller/text_validator_controller_general.dart index 8c11e56..3d2fbfa 100644 --- a/lib/common/validator/controller/text_validator_controller_general.dart +++ b/lib/common/validator/controller/text_validator_controller_general.dart @@ -55,7 +55,7 @@ class TextValidatorControllerGeneral extends TextValidatorController { _state = TextFieldValidatorState.invalid(exception: ValidatorException.generalIsTooLong(tooLongText!)); } else if (regex != null && !regex!.hasMatch(text)) { _state = TextFieldValidatorState.invalid(exception: ValidatorException.generalIsInvalid(regexText!)); - } else if (await condition?.call(text) ?? false) { + } else if (condition != null && await condition!(text)) { _state = TextFieldValidatorState.invalid(exception: ValidatorException.generalIsInvalid(conditionText!)); } else { _state = const TextFieldValidatorState.valid(); @@ -64,11 +64,7 @@ class TextValidatorControllerGeneral extends TextValidatorController { notifyListeners(); } - bool isValid() { - return _state is TextFieldValidatorStateValid; - } + bool get isValid => _state is TextFieldValidatorStateValid; - bool isInvalid() { - return _state is TextFieldValidatorStateInvalid; - } + bool get isInvalid => _state is TextFieldValidatorStateInvalid; }