From 6b8cd9afae2a66ae46c26c8b7900bf85934fa662 Mon Sep 17 00:00:00 2001 From: Oleksii Shtanko Date: Sun, 27 Aug 2023 02:30:27 +0200 Subject: [PATCH] WIP Refactor --- analysis_options.yaml | 3 +- lib/bloc/theme/app_theme.dart | 8 ++- lib/config/build_type.dart | 8 +++ lib/config/environment.dart | 41 +++++++++---- lib/repository/email_list_repository.dart | 2 +- lib/view/email_list/email_list_screen.dart | 4 +- lib/view/email_list/view/email_list_view.dart | 1 + test/config/environment_test.dart | 59 +++++++++++++++++++ 8 files changed, 109 insertions(+), 17 deletions(-) create mode 100644 test/config/environment_test.dart diff --git a/analysis_options.yaml b/analysis_options.yaml index fb8229c..f5f7f90 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -65,10 +65,9 @@ linter: - empty_statements - hash_and_equals - implementation_imports - - iterable_contains_unrelated_type + - collection_methods_unrelated_type - library_names - library_prefixes - - list_remove_unrelated_type - lines_longer_than_80_chars - no_adjacent_strings_in_list - no_duplicate_case_values diff --git a/lib/bloc/theme/app_theme.dart b/lib/bloc/theme/app_theme.dart index 3969559..f1dc936 100644 --- a/lib/bloc/theme/app_theme.dart +++ b/lib/bloc/theme/app_theme.dart @@ -1 +1,7 @@ -enum AppTheme { light, dark, yellow, system, experimental } +enum AppTheme { + light, + dark, + yellow, + system, + experimental, +} diff --git a/lib/config/build_type.dart b/lib/config/build_type.dart index a273c59..d47087d 100644 --- a/lib/config/build_type.dart +++ b/lib/config/build_type.dart @@ -1,6 +1,14 @@ +/// Represents different build types for the application. enum BuildType { + /// The debug build type is used during development for debugging purposes. debug, + + /// The staging build type is used for testing in a staging environment. staging, + + /// The QA build type is used for quality assurance testing. qa, + + /// The release build type is the final production build. release, } diff --git a/lib/config/environment.dart b/lib/config/environment.dart index a584df5..5b51ff9 100644 --- a/lib/config/environment.dart +++ b/lib/config/environment.dart @@ -1,43 +1,62 @@ import 'package:flutter/foundation.dart'; import 'package:flutter_bloc_app_template/config/build_type.dart'; -/// Environment configuration. +/// A class for managing environment configurations based on different +/// build types. class Environment implements Listenable { Environment._(this._currentBuildType, T config) - : _config = ValueNotifier(config); + : _config = ValueNotifier(config), + _listeners = []; - /// Provides instance [Environment]. + /// Creates a new instance of [Environment]. factory Environment.instance() => _instance as Environment; + + /// The singleton instance of the [Environment]. static Environment? _instance; + final BuildType _currentBuildType; + final List _listeners; - /// Configuration. T get config => _config.value; - set config(T c) => _config.value = c; + set config(T c) { + _config.value = c; + _notifyListeners(); // Notify listeners when the config changes + } - /// Is this application running in debug mode. + /// Checks if the current build type is debug. bool get isDebug => _currentBuildType == BuildType.debug; - /// Is this application running in release mode. + /// Checks if the current build type is release. bool get isRelease => _currentBuildType == BuildType.release; - /// App build type. + /// Returns the current build type. BuildType get buildType => _currentBuildType; ValueNotifier _config; @override void addListener(VoidCallback listener) { - _config.addListener(listener); + _listeners.add(listener); } @override void removeListener(VoidCallback listener) { - _config.removeListener(listener); + _listeners.remove(listener); + } + + /// Notifies all registered listeners that the environment configuration + /// has changed. + void _notifyListeners() { + for (final listener in _listeners) { + listener(); + } } - /// Initializing the environment. + /// Initializes the singleton instance of [Environment]. + /// + /// This method should be called once at the app's initialization to set up + /// the environment configuration. static void init({ required BuildType buildType, required T config, diff --git a/lib/repository/email_list_repository.dart b/lib/repository/email_list_repository.dart index d4956f6..cebe1a9 100644 --- a/lib/repository/email_list_repository.dart +++ b/lib/repository/email_list_repository.dart @@ -1,7 +1,7 @@ import 'package:flutter_bloc_app_template/data/storage.dart'; import 'package:flutter_bloc_app_template/models/email.dart'; -const _delay = Duration(milliseconds: 1000); +const _delay = Duration(milliseconds: 3000); class EmailListRepository { Future> loadData() { diff --git a/lib/view/email_list/email_list_screen.dart b/lib/view/email_list/email_list_screen.dart index ecec432..e2f2532 100644 --- a/lib/view/email_list/email_list_screen.dart +++ b/lib/view/email_list/email_list_screen.dart @@ -19,8 +19,8 @@ class EmailListScreen extends StatelessWidget { onRefresh: () async { await Future.delayed(const Duration(seconds: 1)); }, - child: SingleChildScrollView( - physics: const BouncingScrollPhysics(), + child: SizedBox( + height: MediaQuery.of(context).size.height, child: EmailListView(), ), ), diff --git a/lib/view/email_list/view/email_list_view.dart b/lib/view/email_list/view/email_list_view.dart index 5e5d53e..dd6e38e 100644 --- a/lib/view/email_list/view/email_list_view.dart +++ b/lib/view/email_list/view/email_list_view.dart @@ -30,6 +30,7 @@ class EmailListView extends StatelessWidget { var messages = state.messages; return ListView.builder( + physics: const BouncingScrollPhysics(), padding: EdgeInsets.zero, shrinkWrap: true, primary: false, diff --git a/test/config/environment_test.dart b/test/config/environment_test.dart new file mode 100644 index 0000000..8e22b9b --- /dev/null +++ b/test/config/environment_test.dart @@ -0,0 +1,59 @@ +import 'package:flutter_bloc_app_template/config/build_type.dart'; +import 'package:flutter_bloc_app_template/config/environment.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('Environment Tests', () { + test('Initialization and Properties', () { + Environment.init( + buildType: BuildType.debug, + config: 'Debug Config', + ); + + final environment = Environment.instance(); + + expect(environment.config, 'Debug Config'); + expect(environment.isDebug, true); + expect(environment.isRelease, false); + expect(environment.buildType, BuildType.debug); + }); + + test('Config Update', () { + Environment.init( + buildType: BuildType.debug, + config: 'Initial Config', + ); + + final environment = Environment.instance() + ..config = 'Updated Config'; + + expect(environment.config, 'Updated Config'); + }); + + test('Listener Notification', () { + Environment.init( + buildType: BuildType.debug, + config: 'Debug Config', + ); + + final environment = Environment.instance(); + + var listenerCallCount = 0; + void listenerCallback() { + listenerCallCount++; + } + + environment..addListener(listenerCallback) + ..config = 'Updated Config'; + + // Ensure that the listener has been notified + expect(listenerCallCount, 1); + + environment..removeListener(listenerCallback) + ..config = 'Another Update'; + + // Listener should not be called after removal + expect(listenerCallCount, 1); + }); + }); +}