diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0454fc5b..2f408a45 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,8 +10,9 @@ To better foster an open, innovative and inclusive community please refer to our ### Report a bug -If you think you've found a bug, please log a new issue in the [GitHub issue -tracker. When filing issues, please use our [issue +If you think you've found a bug, please log a new issue in the +[GitHub issue tracker](https://github.com/nventive/FlutterApplicationTemplate/issues). +When filing issues, please use our [issue template](.github/ISSUE_TEMPLATE.md). The best way to get your bug fixed is to be as detailed as you can be about the problem. Providing a minimal project with steps to reproduce the problem is ideal. Here are questions you can answer diff --git a/build/templates/replace-firebase-config.yml b/build/templates/replace-firebase-config.yml index 67edea47..4e95cd64 100644 --- a/build/templates/replace-firebase-config.yml +++ b/build/templates/replace-firebase-config.yml @@ -11,19 +11,19 @@ parameters: steps: - task: DownloadSecureFile@1 name: firebaseJson - displayName: "Download Keystore from Secure Files" + displayName: "Download firebaseJson from Secure Files" inputs: secureFile: ${{ parameters.firebaseJsonFile }} - task: DownloadSecureFile@1 name: firebaseOptionsDart - displayName: "Download Keystore from Secure Files" + displayName: "Download firebaseOptionsDart from Secure Files" inputs: secureFile: ${{ parameters.firebaseOptionsDartFile }} - task: DownloadSecureFile@1 name: googleServicesJson - displayName: "Download Keystore from Secure Files" + displayName: "Download googleServicesJson from Secure Files" inputs: secureFile: ${{ parameters.googleServicesJsonFile }} diff --git a/build/templates/validate-commits.yaml b/build/templates/validate-commits.yaml index 774c3bbd..c65af6af 100644 --- a/build/templates/validate-commits.yaml +++ b/build/templates/validate-commits.yaml @@ -39,7 +39,7 @@ steps: } if($invalidCommits.count -gt 0) { - Write-Error "The following commit messages do no follow the Conventional Commits standard: `n$($invalidCommits -join "`n")" + Write-Error "The following commit messages do not follow the Conventional Commits standard: `n$($invalidCommits -join "`n")" exit 1 } else { Write-Host "All commit messages are valid." diff --git a/build/variables.yml b/build/variables.yml index 2a059848..fbe9bea5 100644 --- a/build/variables.yml +++ b/build/variables.yml @@ -68,7 +68,7 @@ DockerVersion: '25.0.5' # MobSF Auth key. - # Corrresponds to the key used for authenticating requests to the MobSF API. In this pipeline setup, MobSF runs in a docker container and by + # Corresponds to the key used for authenticating requests to the MobSF API. In this pipeline setup, MobSF runs in a docker container and by # default the API key is randomly generated by MobSF itself when running it in a dedicated server, but because we're automating the process # we need to manually set it beforehand so we can authenticate further requests. Can be set to any string. More info: # - https://mobsf.github.io/docs/#/extras?id=extra-features @@ -80,8 +80,8 @@ macOSHostedAgentImage: 'macOS-15' ubuntuHostedAgentImage: 'ubuntu-22.04' - # Name of the folder where the artefacts will be placed. Variable used in build and release phases. - # We make seperate folders so that releases can each download only the folder they need. + # Name of the folder where the artifacts will be placed. Variable used in build and release phases. + # We make separate folders so that releases can each download only the folder they need. AndroidArtifactName: Android iOSArtifactName: iOS WindowsArtifactName: Windows diff --git a/doc/Architecture.md b/doc/Architecture.md index 797e2a68..b21f9f11 100644 --- a/doc/Architecture.md +++ b/doc/Architecture.md @@ -82,7 +82,7 @@ See [ForcedUpdate.md](ForcedUpdate.md) for more details. ### Kill Switch -This application contains Kill switch feature. +This application contains a kill switch feature. See [KillSwitch.md](KillSwitch.md) for more details. @@ -96,7 +96,7 @@ See [HTTP.md](HTTP.md) for more details. ### Local Storage -This applications uses [Shared Preferences](https://pub.dev/packages/shared_preferences) to store data locally. +This application uses [Shared Preferences](https://pub.dev/packages/shared_preferences) to store data locally. ### JSON Serialization diff --git a/doc/AzurePipelines.md b/doc/AzurePipelines.md index eac17823..dd3772d7 100644 --- a/doc/AzurePipelines.md +++ b/doc/AzurePipelines.md @@ -72,7 +72,7 @@ This is where the exact build steps are defined. These vary depending on the pla 1. Push the built artifacts (.ipa, .apk/.aab, release notes, etc.). 1. Cleanup. -The release stages are even more straigtforward than the build ones. One thing to note is that, for the same reason as it is done at the end of the build steps, a clean-up step is included in every stage. +The release stages are even more straightforward than the build ones. One thing to note is that, for the same reason as it is done at the end of the build steps, a clean-up step is included in every stage. ### Firebase App Distribution Release Stage ([stage-release-firebase-app-distribution.yml](../build/stage-release-firebase-app-distribution.yml)) @@ -89,5 +89,11 @@ This should only be run for configurations that properly sign the application. Similar to the App Store stage, this stage pushes the **AAB** produced by the build to the Google Play Store. This is also meant for a properly signed AAB. +### Security Scan Stage ([stage-security-scan.yml](../build/stage-security-scan.yml)) + +This stage runs a static application security testing (SAST) scan on the built application binaries using MobSF. + +See [SecurityScan.md](SecurityScan.md) for more details. + This pipeline should be setup as a **scheduled pipeline** that runs every night and **should NOT be part of build validation**. PRs should not be blocked when APIs are down. diff --git a/doc/Diagnostics.md b/doc/Diagnostics.md index 8b840f72..255a5de5 100644 --- a/doc/Diagnostics.md +++ b/doc/Diagnostics.md @@ -15,7 +15,7 @@ This is useful when you want to see something happening live. The default buttons include commands such as the following. - **Expand/Minimize** opens or closes the expanded view of the overlay. - **Move** moves the overlay left or right. -- **X** hides the overlay for the remaining of the app cycle. +- **X** hides the overlay for the remainder of the app cycle. - If you want to permanently hide the diagnostic, go to the environment section within the expanded overlay. ## Expanded overlay widgets @@ -23,6 +23,6 @@ The default buttons include commands such as the following. The expanded diagnostics overlay has by default two widgets. The navigation widget has some buttons with commands on them that allow you to do some navigation in the app. -The DeviceInfo widgets contains some information on the device and the app. +The DeviceInfo widget contains some information on the device and the app. The environment widget which lets the user change the environment. See [Environment.md](./Environment.md) for more details. The loggers widget which lets the user test logging and modify logging configuration. See [Logging.md](./Logging.md) for more details. \ No newline at end of file diff --git a/doc/Environment.md b/doc/Environment.md index 2257a68b..e0b7ea10 100644 --- a/doc/Environment.md +++ b/doc/Environment.md @@ -1,6 +1,6 @@ # Environments -We use `.env` files to store environment configuration with the help of [dotenv](https://pub.dev/packages/dotenv). +We use `.env` files to store environment configuration with the help of [flutter_dotenv](https://pub.dev/packages/flutter_dotenv). ## Runtime environments @@ -42,6 +42,6 @@ Multiple environment features can be tested from the diagnostics overlay. This is configured in [EnvironmentPickerWidget](../src/app/lib/presentation/diagnostic/environment_picker_widget.dart). - You can see the current runtime environment. -- You can see what the environment will be overriden to. +- You can see what the environment will be overridden to. - You can switch to another runtime environment. - You can reset the environment to its default value. \ No newline at end of file diff --git a/doc/ForcedUpdate.md b/doc/ForcedUpdate.md index 44bc47d3..d57a2d9f 100644 --- a/doc/ForcedUpdate.md +++ b/doc/ForcedUpdate.md @@ -3,7 +3,7 @@ The forced update feature is for when you want to force the user to update the app. You could use this, for example, when the backend changes and you do not want the users to still use the old API. -To force an update, we wait for a `Future` `checkUpdateRequired()` to be resolved from the `UpdateRequiredservice` in the [main file of the app.](../src/app/lib/main.dart). +To force an update, we wait for a `Future` `waitForUpdateRequired()` to be resolved from the `UpdateRequiredService` in the [main file of the app.](../src/app/lib/main.dart). This will redirect the user to [a page](../src/app/lib/presentation/forced_update/forced_update_page.dart) from which they cannot navigate back. The minimum update required is defined in a [Firebase Remote Config](/doc/FirebaseRemoteConfig.md). diff --git a/doc/KillSwitch.md b/doc/KillSwitch.md index b4844e50..47ce416a 100644 --- a/doc/KillSwitch.md +++ b/doc/KillSwitch.md @@ -5,7 +5,7 @@ This could be used for example when the server is down for some time, to avoid t To trigger the kill switch, we subscribe to the `isKillSwitchActivatedStream` `stream` from the `KillSwitchService` in the [Main](../src/app/lib/main.dart). -If the kill switch is activated, the user is brought to the `KillSwitchPage` where he can see a message that tells him the app is currently unavailable. -If the kill switch is deactivated afterwards, the user is brought back to the initial navigation flow, which means he will be in the login page if he is not connected and to the home page if he is connected. +If the kill switch is activated, the user is brought to the `KillSwitchPage` where they can see a message that tells them the app is currently unavailable. +If the kill switch is deactivated afterwards, the user is brought back to the initial navigation flow, which means they will be on the login page if they are not connected and on the home page if they are connected. Whether the kill switch is activated or not on mobile and web platforms is defined in a [remote config](FirebaseRemoteConfig.md). diff --git a/doc/Logging.md b/doc/Logging.md index 733f41b0..e3e72b90 100644 --- a/doc/Logging.md +++ b/doc/Logging.md @@ -17,11 +17,11 @@ We use the following convention for log levels: ## Log providers -- We've implemented [CustomFileOutput](../src/app/lib/business/logger/custom_file_output.dart) for file logging. -- We've implemented [CustomConsoleOutput](../src/app/lib/business/logger/custom_file_output.dart) to workaround this issue https://github.com/flutter/flutter/issues/64491. +- We've implemented [CustomFileOutput](../src/app/lib/access/logger/custom_file_output.dart) for file logging. +- We've implemented [CustomConsoleOutput](../src/app/lib/access/logger/custom_console_output.dart) to workaround this issue https://github.com/flutter/flutter/issues/64491. - We've implemented [LevelLogFilter](../src/app/lib/business/logger/level_log_filter.dart) to ensure that logs are filtered for a given log level. -The loggers are configured inside the [LoggerManager.cs](../src/app/lib/business/logger/logger_manager.dart) file. +The loggers are configured inside the [LoggerManager.dart](../src/app/lib/business/logger/logger_manager.dart) file. ## Logging diff --git a/doc/SecurityScan.md b/doc/SecurityScan.md index be509ee0..ae873fab 100644 --- a/doc/SecurityScan.md +++ b/doc/SecurityScan.md @@ -43,7 +43,7 @@ This job mirrors the iOS security scan job but targets Android applications. It - `artifactName`: The name of the Android artifact, appended with the specified applicationEnvironment. ## Usage -### How to Add the the new Stage for Security Scan +### How to Add the new Stage for Security Scan > 1. Create a new `stage`. (*stage: Security_Scan_Build_[Environment]*) > 2. Configure the `dependsOn` property to the stage is creating the build, like `Build_Staging` and `Build_Production`. diff --git a/doc/Testing.md b/doc/Testing.md index 4414b874..9409ee1b 100644 --- a/doc/Testing.md +++ b/doc/Testing.md @@ -27,7 +27,7 @@ For more documentation on testing, read the references listed at the bottom. dynamic matcher, { // added in case of failure String? reason, - // true or a String with the reasion to skip + // true or a String with the reason to skip dynamic skip, } ) @@ -127,11 +127,11 @@ For more documentation on testing, read the references listed at the bottom. } ``` -## Functionnal/Integration Testing +## Functional/Integration Testing -- We use [integration_test](https://docs.flutter.dev/testing/integration-tests) to create functionnal/integration tests. You can create a test like this : +- We use [integration_test](https://docs.flutter.dev/testing/integration-tests) to create functional/integration tests. You can create a test like this : - ```cs + ```dart // Import the test package import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; @@ -163,17 +163,17 @@ For more documentation on testing, read the references listed at the bottom. They are all run in the same `main` because of [this issue](https://github.com/flutter/flutter/issues/135673). To test different behaviors and interactions between the components of the app you need to simulate user interactions with the tester.tap(target) method like this: - ```cs + ```dart await tester.tap(dadJokes.first); ``` - To assert the result of a test, use `expect()` exactly like with unit tests. -- tester.pumpAndSettle() is used both to trigger a frame change and to wait for the last pump to have settled before moving on. For example, we use it after pumping the app widget and we also use it when we naviguated and we want to update the UI. +- tester.pumpAndSettle() is used both to trigger a frame change and to wait for the last pump to have settled before moving on. For example, we use it after pumping the app widget and we also use it when we navigated and we want to update the UI. ### Mocking -For functionnal testing we use the decorator pattern because we are testing the actual behavior of the app so we don't wanna use mockito to mock the logic of the classes of the app. +For functional testing we use the decorator pattern because we are testing the actual behavior of the app so we don't want to use mockito to mock the logic of the classes of the app. To use the decorator pattern you simply call the mocking repository and the method called setMocking(true). It's important to set the mocking in the main function before the tests otherwise the mocking doesn't take effect. In most cases, except for api tests, the data sources (repositories) should be mocked for integration testing. diff --git a/src/app/ios/Podfile b/src/app/ios/Podfile index f344bd9c..92e19543 100644 --- a/src/app/ios/Podfile +++ b/src/app/ios/Podfile @@ -46,5 +46,26 @@ post_install do |installer| config.build_settings['CODE_SIGNING_REQUIRED'] = "NO" config.build_settings['CODE_SIGNING_ALLOWED'] = "NO" end + + # Workaround: move .xcprivacy files from Sources to Resources build phase. + # Some pods (e.g. bugsee_flutter) incorrectly place PrivacyInfo.xcprivacy in + # the Sources phase, causing "no rule to process file ... of type 'text.xml'" + # during xcodebuild archive. + sources_phase = target.build_phases.find { |p| p.is_a?(Xcodeproj::Project::Object::PBXSourcesBuildPhase) } + next unless sources_phase + + xcprivacy_files = sources_phase.files.select { |f| f.file_ref&.path&.end_with?('.xcprivacy') } + next if xcprivacy_files.empty? + + resources_phase = target.build_phases.find { |p| p.is_a?(Xcodeproj::Project::Object::PBXResourcesBuildPhase) } + resources_phase ||= target.new_resources_build_phase + + xcprivacy_files.each do |build_file| + file_ref = build_file.file_ref + sources_phase.remove_file_reference(file_ref) + unless resources_phase.files.map(&:file_ref).include?(file_ref) + resources_phase.add_file_reference(file_ref) + end + end end end diff --git a/src/app/lib/access/diagnostics/diagnostics_repository.dart b/src/app/lib/access/diagnostics/diagnostics_repository.dart index 7a2f01f6..547282ea 100644 --- a/src/app/lib/access/diagnostics/diagnostics_repository.dart +++ b/src/app/lib/access/diagnostics/diagnostics_repository.dart @@ -12,7 +12,7 @@ abstract interface class DiagnosticsRepository { Future disableDiagnostics(); } -/// Implementation of [DiagnosticRepository]. +/// Implementation of [DiagnosticsRepository]. final class _DiagnosticsRepository implements DiagnosticsRepository { /// The key used to store the diagnostic dismissed state in shared preferences. final String _diagnosticDisabledKey = 'diagnosticDisabled'; diff --git a/src/app/lib/access/firebase/firebase_repository.dart b/src/app/lib/access/firebase/firebase_repository.dart index 94f0fa4b..2117cf86 100644 --- a/src/app/lib/access/firebase/firebase_repository.dart +++ b/src/app/lib/access/firebase/firebase_repository.dart @@ -43,7 +43,7 @@ class FirebaseRemoteConfigRepository "is_kill_switch_active": false, }); - _logger.i("Firebase has been Initialized and registered in the container."); + _logger.i("Firebase has been initialized and registered in the container."); // Listen to updates to the remote config. This is only available on mobile platforms. if (Platform.isAndroid || Platform.isIOS) { @@ -54,7 +54,7 @@ class FirebaseRemoteConfigRepository }); } - // Fetch and activate gets the data from the server and makes it available trough the singleton. + // Fetch and activate gets the data from the server and makes it available through the singleton. remoteConfig.fetchAndActivate().then((_) { _updateRemoteConfig(); }); diff --git a/src/app/lib/access/logger/custom_file_output.dart b/src/app/lib/access/logger/custom_file_output.dart index 537196e8..31842c1d 100644 --- a/src/app/lib/access/logger/custom_file_output.dart +++ b/src/app/lib/access/logger/custom_file_output.dart @@ -9,7 +9,7 @@ final class CustomFileOutput extends LogOutput { final bool _overrideExisting; final Encoding _encoding; - /// Regex used to remove ansi color codes from from log files. + /// Regex used to remove ansi color codes from log files. final _ansiPattern = RegExp(r'\x1B\[\d+(;\d+)*m'); /// It's a reference to [_file] used to write logs inside. diff --git a/src/app/lib/access/logger/logger_repository.dart b/src/app/lib/access/logger/logger_repository.dart index f1057170..35cad9f1 100644 --- a/src/app/lib/access/logger/logger_repository.dart +++ b/src/app/lib/access/logger/logger_repository.dart @@ -18,16 +18,16 @@ abstract interface class LoggerRepository { /// Implementation of [LoggerRepository]. final class _LoggerRepository implements LoggerRepository { - /// The key used to store the selected environment in shared preferences. + /// The key used to store the logging configuration in shared preferences. final String _consoleLoggingKey = 'consoleLogging'; - final String _fileloggingKey = 'fileLogging'; + final String _fileLoggingKey = 'fileLogging'; @override Future getLoggingConfiguration() async { final sharedPreferences = await SharedPreferences.getInstance(); return LoggingConfigurationData( isConsoleLoggingEnabled: sharedPreferences.getBool(_consoleLoggingKey), - isFileLoggingEnabled: sharedPreferences.getBool(_fileloggingKey), + isFileLoggingEnabled: sharedPreferences.getBool(_fileLoggingKey), ); } @@ -48,7 +48,7 @@ final class _LoggerRepository implements LoggerRepository { Future setIsFileLoggingEnabled(bool isFileLoggingEnabled) async { final sharedPreferences = await SharedPreferences.getInstance(); var isSaved = await sharedPreferences.setBool( - _fileloggingKey, + _fileLoggingKey, isFileLoggingEnabled, ); diff --git a/src/app/lib/business/logger/logger_manager.dart b/src/app/lib/business/logger/logger_manager.dart index 47f0a8d7..7bdbebe1 100644 --- a/src/app/lib/business/logger/logger_manager.dart +++ b/src/app/lib/business/logger/logger_manager.dart @@ -24,10 +24,10 @@ abstract interface class LoggerManager { /// Gets whether file logging is enabled. bool get isFileLoggingEnabled; - /// Gets whether logging configuration been changed via either [setIsConsoleLoggingEnabled] or [setIsFileLoggingEnabled]. + /// Gets whether logging configuration has been changed via either [setIsConsoleLoggingEnabled] or [setIsFileLoggingEnabled]. bool get hasConfigurationBeenChanged; - /// Create an instancee of [Logger]. + /// Create an instance of [Logger]. Future createLogInstance(); /// Deletes log file @@ -178,7 +178,7 @@ final class _LoggerManager implements LoggerManager { await _loggerRepository.setIsConsoleLoggingEnabled(isConsoleLoggingEnabled); this.isConsoleLoggingEnabled = isConsoleLoggingEnabled; - hasConfigurationBeenChanged = _checkIfChangesHasBeenMade(); + hasConfigurationBeenChanged = _checkIfChangesHaveBeenMade(); } @override @@ -186,10 +186,10 @@ final class _LoggerManager implements LoggerManager { await _loggerRepository.setIsFileLoggingEnabled(isFileLoggingEnabled); this.isFileLoggingEnabled = isFileLoggingEnabled; - hasConfigurationBeenChanged = _checkIfChangesHasBeenMade(); + hasConfigurationBeenChanged = _checkIfChangesHaveBeenMade(); } - bool _checkIfChangesHasBeenMade() => + bool _checkIfChangesHaveBeenMade() => isConsoleLoggingEnabled != _initialIsConsoleLoggingEnabled || isFileLoggingEnabled != _initialIsFileLoggingEnabled; } diff --git a/src/app/lib/business/mocking/mocking_manager.dart b/src/app/lib/business/mocking/mocking_manager.dart index bda38a06..1209abeb 100644 --- a/src/app/lib/business/mocking/mocking_manager.dart +++ b/src/app/lib/business/mocking/mocking_manager.dart @@ -4,10 +4,10 @@ import 'package:app/access/mocking/mocking_repository.dart'; abstract interface class MockingManager { factory MockingManager(MockingRepository mockingRepository) = _MockingManager; - /// Gets whether file logging is enabled. + /// Gets whether mocking is enabled. bool get isMockingEnabled; - /// Gets whether mocking configuration been changed via either [setIsConsoleLoggingEnabled]. + /// Gets whether mocking configuration has been changed via [setIsMockingEnabled]. bool get hasConfigurationBeenChanged; /// Sets whether mocking should be enabled on next app launch. diff --git a/src/app/lib/main.dart b/src/app/lib/main.dart index c3b91f12..ec259f32 100644 --- a/src/app/lib/main.dart +++ b/src/app/lib/main.dart @@ -51,14 +51,14 @@ Future initializeComponents({bool? isMocked}) async { _logger.d("Initialized environment and logger."); _registerHttpClient(); - _logger.i("HttpClient has been Initialized and registered in the container."); + _logger.i("HttpClient has been initialized and registered in the container."); await _registerRepositories(isMocked); _logger - .i("Repositories has been Initialized and registered in the container."); + .i("Repositories have been initialized and registered in the container."); _registerServices(); - _logger.i("Services has been Initialized and registered in the container."); + _logger.i("Services have been initialized and registered in the container."); GetIt.I.get().waitForUpdateRequired().then((value) { _logger.d("Force update is now required."); diff --git a/src/app/lib/presentation/diagnostic/environment_picker_widget.dart b/src/app/lib/presentation/diagnostic/environment_picker_widget.dart index af9d7975..d3d3d8b6 100644 --- a/src/app/lib/presentation/diagnostic/environment_picker_widget.dart +++ b/src/app/lib/presentation/diagnostic/environment_picker_widget.dart @@ -16,12 +16,12 @@ class _EnvironmentPickerWidgetState extends State { final _environmentManager = GetIt.I(); bool _restartRequired = false; - late Enum selectedEnviroment; + late Enum selectedEnvironment; _EnvironmentPickerWidgetState() { - selectedEnviroment = + selectedEnvironment = _environmentManager.next ?? _environmentManager.current; - _restartRequired = selectedEnviroment != _environmentManager.current; + _restartRequired = selectedEnvironment != _environmentManager.current; } @override @@ -45,14 +45,14 @@ class _EnvironmentPickerWidgetState extends State { ..._environmentManager.environments.map( (environment) => Material( child: CheckboxListTile( - value: environment == selectedEnviroment, + value: environment == selectedEnvironment, key: ValueKey(environment), title: Text(environment.toString()), onChanged: (value) async { _environmentManager.setEnvironment(environment); setState(() { - selectedEnviroment = environment; + selectedEnvironment = environment; _restartRequired = environment != _environmentManager.current; }); }, diff --git a/src/app/lib/presentation/diagnostic/expanded_diagnostic_page.dart b/src/app/lib/presentation/diagnostic/expanded_diagnostic_page.dart index 049ec1c2..134e2f64 100644 --- a/src/app/lib/presentation/diagnostic/expanded_diagnostic_page.dart +++ b/src/app/lib/presentation/diagnostic/expanded_diagnostic_page.dart @@ -6,7 +6,7 @@ import 'package:app/presentation/diagnostic/mocking_diagnostic_widget.dart'; import 'package:app/presentation/diagnostic/navigation_diagnostic_widget.dart'; import 'package:flutter/material.dart'; -/// A page in the expanded diagnosticoverlay that holds other diagnostic widgets. +/// A page in the expanded diagnostic overlay that holds other diagnostic widgets. final class ExpandedDiagnosticPage extends StatefulWidget { const ExpandedDiagnosticPage({super.key}); diff --git a/src/app/lib/presentation/diagnostic/mocking_configuration_widget.dart b/src/app/lib/presentation/diagnostic/mocking_configuration_widget.dart index 037e816f..219bd9f0 100644 --- a/src/app/lib/presentation/diagnostic/mocking_configuration_widget.dart +++ b/src/app/lib/presentation/diagnostic/mocking_configuration_widget.dart @@ -2,7 +2,7 @@ import 'package:app/business/mocking/mocking_manager.dart'; import 'package:app/presentation/diagnostic/diagnostic_switch.dart'; import 'package:flutter/material.dart'; -/// Widget that handles logging configuration switching. +/// Widget that handles mocking configuration switching. final class MockingConfigurationWidget extends StatefulWidget { final MockingManager _mockingManager; diff --git a/src/app/lib/presentation/mvvm/mvvm_widget.dart b/src/app/lib/presentation/mvvm/mvvm_widget.dart index 4ff7bd91..8b2fe879 100644 --- a/src/app/lib/presentation/mvvm/mvvm_widget.dart +++ b/src/app/lib/presentation/mvvm/mvvm_widget.dart @@ -53,9 +53,9 @@ class _MvvmWidgetState @override void dispose() { - super.dispose(); _viewModel.removeListener(onPropertyChanged); _viewModel.dispose(); + super.dispose(); } @override diff --git a/src/app/lib/presentation/mvvm/view_model.dart b/src/app/lib/presentation/mvvm/view_model.dart index e4613833..68dd97d4 100644 --- a/src/app/lib/presentation/mvvm/view_model.dart +++ b/src/app/lib/presentation/mvvm/view_model.dart @@ -58,10 +58,11 @@ abstract class ViewModel extends ChangeNotifier { @override void dispose() { - super.dispose(); for (final subscription in _streamSubscriptions.values) { subscription.cancel(); } _streamSubscriptions.clear(); + + super.dispose(); } } diff --git a/src/cli/CHANGELOG.md b/src/cli/CHANGELOG.md index 4e6eee12..2691f3ad 100644 --- a/src/cli/CHANGELOG.md +++ b/src/cli/CHANGELOG.md @@ -5,14 +5,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) Prefix your items with `(Template)` if the change is about the template and not the resulting application. +## 0.26.2 +- Fix issue with dispose in VM. +- Fix errors in documentation. +- Fix issue with Bugsee and xcprivacy files. + ## 0.26.1 - Update flutter to 3.38.5 and update dependencies. -- iOS now uses UIScene life cycle, +- iOS now uses UIScene life cycle. ## 0.26.0 - Update flutter to 3.35.6 and update dependencies. -- Now compliant with [16 KB Google Play compatibility requirement](https://developer.android.com/guide/practices/page-sizes) -- Use Material3 navigation bar +- Now compliant with [16 KB Google Play compatibility requirement](https://developer.android.com/guide/practices/page-sizes). +- Use Material3 navigation bar. ## 0.25.4 - Fix CocoaPods cache and dependency issues in iOS build pipeline. @@ -56,17 +61,17 @@ Prefix your items with `(Template)` if the change is about the template and not - Moved Android distribution for Staging from App Center to Firebase App Distribution. ## 0.21.1 -- Added conventional commit validation stage `stage-build.yml` +- Added conventional commit validation stage `stage-build.yml`. ## 0.21.0 -- Add Bugsee SDK in Flutter template -- Update build stage in `steps-build-android.yml` and `steps-build-ios` providing Bugsee token +- Add Bugsee SDK in Flutter template. +- Update build stage in `steps-build-android.yml` and `steps-build-ios.yml` providing Bugsee token. ## 0.20.4 -- Updates to documentation +- Updates to documentation. ## 0.20.3 -- (CI/CD) Fixes an authentication issue with pub.dev +- (CI/CD) Fixes an authentication issue with pub.dev. ## 0.20.2 - (Template) Fixes an issue with the CLI in which the build fails during template generation because of a missing required file. @@ -74,7 +79,7 @@ Prefix your items with `(Template)` if the change is about the template and not ## 0.20.1 - Fix CI/CD artifact name for Android. - Fix CI/CD to install gcloud CLI Tool. -- Fix CI/CD build number +- Fix CI/CD build number. ## 0.20.0 - Configured MobSF security scan on Android and iOS for Staging and Production builds. @@ -123,7 +128,7 @@ Prefix your items with `(Template)` if the change is about the template and not - Added Alice as a tool to see logs in app. - Fix diagnostic overlay dismiss behavior so it's not permanent. - Added test for the UpdateRequiredService and fixed bug where remote config was not updating correctly. -- Added functionnal tests examples. +- Added functional tests examples. - Fixed minor bug where the current path was not being updated properly. - Added localization. - Added test for the killswitch.