From 5aae6cfefba5fd0bb29cea0de4da09c66c9c514f Mon Sep 17 00:00:00 2001 From: Tatiana Sugina Date: Fri, 12 Apr 2024 18:04:36 +0300 Subject: [PATCH 01/15] (feat): updated pubspec . --- pubspec.lock | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ pubspec.yaml | 1 + 2 files changed, 49 insertions(+) diff --git a/pubspec.lock b/pubspec.lock index 615f12ad..6ba5ec01 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -781,6 +781,54 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.1" + permission_handler: + dependency: "direct main" + description: + name: permission_handler + sha256: "18bf33f7fefbd812f37e72091a15575e72d5318854877e0e4035a24ac1113ecb" + url: "https://pub.dev" + source: hosted + version: "11.3.1" + permission_handler_android: + dependency: transitive + description: + name: permission_handler_android + sha256: "1acac6bae58144b442f11e66621c062aead9c99841093c38f5bcdcc24c1c3474" + url: "https://pub.dev" + source: hosted + version: "12.0.5" + permission_handler_apple: + dependency: transitive + description: + name: permission_handler_apple + sha256: e9ad66020b89ff1b63908f247c2c6f931c6e62699b756ef8b3c4569350cd8662 + url: "https://pub.dev" + source: hosted + version: "9.4.4" + permission_handler_html: + dependency: transitive + description: + name: permission_handler_html + sha256: "54bf176b90f6eddd4ece307e2c06cf977fb3973719c35a93b85cc7093eb6070d" + url: "https://pub.dev" + source: hosted + version: "0.1.1" + permission_handler_platform_interface: + dependency: transitive + description: + name: permission_handler_platform_interface + sha256: "48d4fcf201a1dad93ee869ab0d4101d084f49136ec82a8a06ed9cfeacab9fd20" + url: "https://pub.dev" + source: hosted + version: "4.2.1" + permission_handler_windows: + dependency: transitive + description: + name: permission_handler_windows + sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" + url: "https://pub.dev" + source: hosted + version: "0.2.1" petitparser: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index b3498026..98d011f9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -27,6 +27,7 @@ dependencies: nested: 1.0.0 path: 1.9.0 path_provider: 2.1.2 + permission_handler: 11.3.1 provider: 6.1.1 retrofit: 4.0.3 rxdart: 0.27.7 From af4af693fad61cdaa834399b4cb8e0c0b5c70073 Mon Sep 17 00:00:00 2001 From: Tatiana Sugina Date: Fri, 12 Apr 2024 18:05:06 +0300 Subject: [PATCH 02/15] (feat): updated app settings. --- android/app/src/main/AndroidManifest.xml | 3 +++ ios/Podfile | 10 ++++++++++ ios/Runner.xcodeproj/project.pbxproj | 19 +++++++++++++++++++ ios/Runner/Info.plist | 4 ++++ 4 files changed, 36 insertions(+) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 7da35af9..a9805b5b 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -8,6 +8,9 @@ FlutterApplication and put your custom class here. --> + + + diff --git a/ios/Podfile b/ios/Podfile index 16fac1a6..4eb5a171 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -40,5 +40,15 @@ end post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_ios_build_settings(target) + # YOUR CUSTOM TARGET CODE HERE. + target.build_configurations.each do |config| + config.build_settings['ENABLE_BITCODE'] = 'NO' + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [ + '$(inherited)', + ## dart: PermissionGroup.notification + 'PERMISSION_NOTIFICATIONS=1', + 'PERMISSION_LOCATION=1', + ] + end end end diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index cfb8c0b4..436ff833 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -195,6 +195,7 @@ 9C081569228C6AC20006FEB3 /* ShellScript */, B66FF691DE180E7D19E1A137 /* [CP] Embed Pods Frameworks */, 8A5D96D62B94EB81002D56E0 /* [firebase_crashlytics] Crashlytics Upload Symbols */, + BF513D92CD81C03FF509F09E /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -401,6 +402,24 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; + BF513D92CD81C03FF509F09E /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/permission_handler_apple/permission_handler_apple_privacy.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/permission_handler_apple_privacy.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index c9c7eaf2..d05009cb 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -36,6 +36,10 @@ LSRequiresIPhoneOS + NSLocationAlwaysUsageDescription + This way we can identify the places of interest closest to you + NSLocationWhenInUseUsageDescription + This way we can identify the places of interest closest to you UILaunchStoryboardName LaunchScreen UIMainStoryboardFile From 49c03a01117256f644ddef5146885e91402b9786 Mon Sep 17 00:00:00 2001 From: Tatiana Sugina Date: Fri, 12 Apr 2024 18:05:29 +0300 Subject: [PATCH 03/15] (feat): localizations --- lib/l10n/app_en.arb | 16 +++++- lib/l10n/app_localizations.g.dart | 83 +++++++++++++++++++++++++--- lib/l10n/app_localizations_en.g.dart | 30 ++++++++++ lib/l10n/app_localizations_ru.g.dart | 34 +++++++++++- lib/l10n/app_ru.arb | 22 ++++++-- 5 files changed, 169 insertions(+), 16 deletions(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 9b27a5ce..13f1992d 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -114,5 +114,19 @@ "---------": "---------", "description": "Example of feature" }, - "featureExampleFailedLoadIpMessage": "Failed to load IP address" + "featureExampleFailedLoadIpMessage": "Failed to load IP address", + "@segmentPermissionExample": { + "---------": "---------", + "description": "Permission Example" + }, + "permissionExampleLocation": "Location", + "permissionExampleNotification": "Notification", + "permissionExampleOpenSettingsButton": "Open Settings", + "permissionExampleCloseButton": "Close", + "permissionExampleRequestPermissionsTitle": "Request permissions", + "permissionExampleLocationPositiveText": "Access to geolocation is allowed", + "permissionExampleLocationNegativeText": "Access to geolocation is denied", + "permissionExampleNotificationPositiveText": "Push notifications are allowed", + "permissionExampleNotificationNegativeText": "Push notifications are denied", + "permissionExampleForeverText": " forever" } \ No newline at end of file diff --git a/lib/l10n/app_localizations.g.dart b/lib/l10n/app_localizations.g.dart index 8331ccb0..082b1259 100644 --- a/lib/l10n/app_localizations.g.dart +++ b/lib/l10n/app_localizations.g.dart @@ -88,7 +88,10 @@ abstract class AppLocalizations { ]; /// A list of this localizations delegate's supported locales. - static const List supportedLocales = [Locale('en'), Locale('ru')]; + static const List supportedLocales = [ + Locale('en'), + Locale('ru') + ]; /// No description provided for @positiveResponse. /// @@ -437,6 +440,66 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'Failed to load IP address'** String get featureExampleFailedLoadIpMessage; + + /// No description provided for @permissionExampleLocation. + /// + /// In en, this message translates to: + /// **'Location'** + String get permissionExampleLocation; + + /// No description provided for @permissionExampleNotification. + /// + /// In en, this message translates to: + /// **'Notification'** + String get permissionExampleNotification; + + /// No description provided for @permissionExampleOpenSettingsButton. + /// + /// In en, this message translates to: + /// **'Open Settings'** + String get permissionExampleOpenSettingsButton; + + /// No description provided for @permissionExampleCloseButton. + /// + /// In en, this message translates to: + /// **'Close'** + String get permissionExampleCloseButton; + + /// No description provided for @permissionExampleRequestPermissionsTitle. + /// + /// In en, this message translates to: + /// **'Request permissions'** + String get permissionExampleRequestPermissionsTitle; + + /// No description provided for @permissionExampleLocationPositiveText. + /// + /// In en, this message translates to: + /// **'Access to geolocation is allowed'** + String get permissionExampleLocationPositiveText; + + /// No description provided for @permissionExampleLocationNegativeText. + /// + /// In en, this message translates to: + /// **'Access to geolocation is denied'** + String get permissionExampleLocationNegativeText; + + /// No description provided for @permissionExampleNotificationPositiveText. + /// + /// In en, this message translates to: + /// **'Push notifications are allowed'** + String get permissionExampleNotificationPositiveText; + + /// No description provided for @permissionExampleNotificationNegativeText. + /// + /// In en, this message translates to: + /// **'Push notifications are denied'** + String get permissionExampleNotificationNegativeText; + + /// No description provided for @permissionExampleForeverText. + /// + /// In en, this message translates to: + /// **' forever'** + String get permissionExampleForeverText; } class _AppLocalizationsDelegate extends LocalizationsDelegate { @@ -455,16 +518,18 @@ class _AppLocalizationsDelegate extends LocalizationsDelegate } AppLocalizations lookupAppLocalizations(Locale locale) { + + // Lookup logic when only language code is specified. switch (locale.languageCode) { - case 'en': - return AppLocalizationsEn(); - case 'ru': - return AppLocalizationsRu(); + case 'en': return AppLocalizationsEn(); + case 'ru': return AppLocalizationsRu(); } - throw FlutterError('AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely ' - 'an issue with the localizations generation tool. Please file an issue ' - 'on GitHub with a reproducible sample app and the gen-l10n configuration ' - 'that was used.'); + throw FlutterError( + 'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely ' + 'an issue with the localizations generation tool. Please file an issue ' + 'on GitHub with a reproducible sample app and the gen-l10n configuration ' + 'that was used.' + ); } diff --git a/lib/l10n/app_localizations_en.g.dart b/lib/l10n/app_localizations_en.g.dart index 920d11f2..6184cc9c 100644 --- a/lib/l10n/app_localizations_en.g.dart +++ b/lib/l10n/app_localizations_en.g.dart @@ -202,4 +202,34 @@ class AppLocalizationsEn extends AppLocalizations { @override String get featureExampleFailedLoadIpMessage => 'Failed to load IP address'; + + @override + String get permissionExampleLocation => 'Location'; + + @override + String get permissionExampleNotification => 'Notification'; + + @override + String get permissionExampleOpenSettingsButton => 'Open Settings'; + + @override + String get permissionExampleCloseButton => 'Close'; + + @override + String get permissionExampleRequestPermissionsTitle => 'Request permissions'; + + @override + String get permissionExampleLocationPositiveText => 'Access to geolocation is allowed'; + + @override + String get permissionExampleLocationNegativeText => 'Access to geolocation is denied'; + + @override + String get permissionExampleNotificationPositiveText => 'Push notifications are allowed'; + + @override + String get permissionExampleNotificationNegativeText => 'Push notifications are denied'; + + @override + String get permissionExampleForeverText => ' forever'; } diff --git a/lib/l10n/app_localizations_ru.g.dart b/lib/l10n/app_localizations_ru.g.dart index 5d8a762f..20e86982 100644 --- a/lib/l10n/app_localizations_ru.g.dart +++ b/lib/l10n/app_localizations_ru.g.dart @@ -72,7 +72,7 @@ class AppLocalizationsRu extends AppLocalizations { String get debugScreenProxyInfo => 'Активирует передачу через прокси сервер.'; @override - String get debugScreenProxyEditTextLabel => 'Введите адресс прокси сервера'; + String get debugScreenProxyEditTextLabel => 'Введите адрес прокси сервера'; @override String get debugScreenProxyConnectButton => 'Подключить'; @@ -201,5 +201,35 @@ class AppLocalizationsRu extends AppLocalizations { String get uiKitScreenColorCardSkeletonTertiaryName => 'Skeleton Tertiary'; @override - String get featureExampleFailedLoadIpMessage => 'Не удалось загрузить IP-адрес'; + String get featureExampleFailedLoadIpMessage => 'Failed to load IP address'; + + @override + String get permissionExampleLocation => 'Location'; + + @override + String get permissionExampleNotification => 'Notification'; + + @override + String get permissionExampleOpenSettingsButton => 'Open Settings'; + + @override + String get permissionExampleCloseButton => 'Close'; + + @override + String get permissionExampleRequestPermissionsTitle => 'Request permissions'; + + @override + String get permissionExampleLocationPositiveText => 'Access to geolocation is allowed'; + + @override + String get permissionExampleLocationNegativeText => 'Access to geolocation is denied'; + + @override + String get permissionExampleNotificationPositiveText => 'Push notifications are allowed'; + + @override + String get permissionExampleNotificationNegativeText => 'Push notifications are denied'; + + @override + String get permissionExampleForeverText => ' forever'; } diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb index a877941c..af951363 100644 --- a/lib/l10n/app_ru.arb +++ b/lib/l10n/app_ru.arb @@ -43,7 +43,7 @@ }, "inboxCount": "{count, plural, zero{У вас нет новых сообщений} one{У вас 1 новое ообщение} other{У вас {count} новых сообщений}}", "@inboxCount": { - "description": "Количетво сообщений", + "description": "Количество сообщений", "placeholders": { "count": {} } @@ -64,7 +64,7 @@ "debugScreenServerConnectButton": "Переключить сервер", "debugScreenProxySubtitle": "Прокси", "debugScreenProxyInfo": "Активирует передачу через прокси сервер.", - "debugScreenProxyEditTextLabel": "Введите адресс прокси сервера", + "debugScreenProxyEditTextLabel": "Введите адрес прокси сервера", "debugScreenProxyConnectButton": "Подключить", "debugScreenThemeSubtitle": "Тема приложения", "debugScreenThemeLight": "Светлая тема", @@ -113,7 +113,21 @@ "uiKitScreenColorCardSkeletonTertiaryName": "Skeleton Tertiary", "@segmentFeatureExample": { "---------": "---------", - "description": "Пример фичи" + "description": "Feature example" }, - "featureExampleFailedLoadIpMessage": "Не удалось загрузить IP-адрес" + "featureExampleFailedLoadIpMessage": "Failed to load IP address", + "@segmentPermissionExample": { + "---------": "---------", + "description": "Permission Example" + }, + "permissionExampleLocation": "Location", + "permissionExampleNotification": "Notification", + "permissionExampleOpenSettingsButton": "Open Settings", + "permissionExampleCloseButton": "Close", + "permissionExampleRequestPermissionsTitle": "Request permissions", + "permissionExampleLocationPositiveText": "Access to geolocation is allowed", + "permissionExampleLocationNegativeText": "Access to geolocation is denied", + "permissionExampleNotificationPositiveText": "Push notifications are allowed", + "permissionExampleNotificationNegativeText": "Push notifications are denied", + "permissionExampleForeverText": " forever" } \ No newline at end of file From 5a0f5ad6e159cfdf319689ff0b54fe271657aedc Mon Sep 17 00:00:00 2001 From: Tatiana Sugina Date: Fri, 12 Apr 2024 18:05:53 +0300 Subject: [PATCH 04/15] (feat): add PermissionHandlerRepository --- lib/features/app/di/app_scope.dart | 16 +++++++-- .../permission_handler_repository.dart | 35 +++++++++++++++++++ .../entities/failure/permission_failure.dart | 30 ++++++++++++++++ .../i_permission_handler_repository.dart | 13 +++++++ 4 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 lib/features/shared/data/repositories/permission_handler_repository.dart create mode 100644 lib/features/shared/domain/entities/failure/permission_failure.dart create mode 100644 lib/features/shared/domain/repositories/i_permission_handler_repository.dart diff --git a/lib/features/app/di/app_scope.dart b/lib/features/app/di/app_scope.dart index 9357e689..da9f5519 100644 --- a/lib/features/app/di/app_scope.dart +++ b/lib/features/app/di/app_scope.dart @@ -3,6 +3,8 @@ import 'package:dio/dio.dart'; import 'package:flutter_template/common/utils/logger/i_log_writer.dart'; import 'package:flutter_template/config/app_config.dart'; import 'package:flutter_template/config/environment/environment.dart'; +import 'package:flutter_template/features/shared/data/repositories/permission_handler_repository.dart'; +import 'package:flutter_template/features/shared/domain/repositories/i_permission_handler_repository.dart'; import 'package:shared_preferences/shared_preferences.dart'; /// {@template app_scope.class} @@ -23,15 +25,22 @@ final class AppScope implements IAppScope { @override final ILogWriter logger; + late final IPermissionHandlerRepository _permissionHandlerRepository; + + @override + IPermissionHandlerRepository get permissionHandlerRepository => _permissionHandlerRepository; + /// {@macro app_scope.class} - const AppScope({ + AppScope({ required this.env, required this.appConfig, required this.sharedPreferences, required this.dio, required this.analyticsService, required this.logger, - }); + }) { + _permissionHandlerRepository = PermissionHandlerRepository(); + } } /// {@macro app_scope.class} @@ -53,4 +62,7 @@ abstract interface class IAppScope { /// Analytics sending service. AnalyticService get analyticsService; + + /// Permission handler repository. + IPermissionHandlerRepository get permissionHandlerRepository; } diff --git a/lib/features/shared/data/repositories/permission_handler_repository.dart b/lib/features/shared/data/repositories/permission_handler_repository.dart new file mode 100644 index 00000000..6869c145 --- /dev/null +++ b/lib/features/shared/data/repositories/permission_handler_repository.dart @@ -0,0 +1,35 @@ +import 'package:flutter_template/core/architecture/domain/entity/result.dart'; +import 'package:flutter_template/features/shared/domain/entities/failure/permission_failure.dart'; +import 'package:flutter_template/features/shared/domain/repositories/i_permission_handler_repository.dart'; +import 'package:permission_handler/permission_handler.dart'; + +/// Implementation of [PermissionHandlerRepository] for obtaining permissions from the user. +class PermissionHandlerRepository implements IPermissionHandlerRepository { + /// Create an instance of [PermissionHandlerRepository]. + PermissionHandlerRepository(); + + @override + Future checkPermission(Permission permission) async { + final status = await permission.status; + + if (status.isGranted) { + return const Result.ok(null); + } + + if (status.isDenied) { + final status = await permission.request(); + + if (status.isGranted) { + return const Result.ok(null); + } else { + return Result.failed(PermissionDenied(original: null, trace: null)); + } + } + + if (status.isPermanentlyDenied) { + return Result.failed(PermissionDeniedForever(original: null, trace: null)); + } + + return Result.failed(PermissionException(original: null, trace: null)); + } +} diff --git a/lib/features/shared/domain/entities/failure/permission_failure.dart b/lib/features/shared/domain/entities/failure/permission_failure.dart new file mode 100644 index 00000000..b0b2c36d --- /dev/null +++ b/lib/features/shared/domain/entities/failure/permission_failure.dart @@ -0,0 +1,30 @@ +import 'package:flutter_template/core/architecture/domain/entity/failure.dart'; + +/// Statuses of the user permission request error. +sealed class PermissionFailure extends Failure { + PermissionFailure({required super.original, required super.trace}); +} + +/// Access denied. +final class PermissionDenied extends PermissionFailure { + /// Create an instance of [PermissionDenied]. + PermissionDenied({required super.original, required super.trace}); +} + +/// Access denied forever. +final class PermissionDeniedForever extends PermissionFailure { + /// Create an instance of [PermissionDeniedForever]. + PermissionDeniedForever({required super.original, required super.trace}); +} + +/// Service unavailable. +final class ServiceDisabled extends PermissionFailure { + /// Create an instance of [ServiceDisabled]. + ServiceDisabled({required super.original, required super.trace}); +} + +/// Other errors when requesting user permissions. +final class PermissionException extends PermissionFailure { + /// Create an instance of [PermissionException]. + PermissionException({required super.original, required super.trace}); +} diff --git a/lib/features/shared/domain/repositories/i_permission_handler_repository.dart b/lib/features/shared/domain/repositories/i_permission_handler_repository.dart new file mode 100644 index 00000000..6ec04502 --- /dev/null +++ b/lib/features/shared/domain/repositories/i_permission_handler_repository.dart @@ -0,0 +1,13 @@ +// ignore_for_file: one_member_abstracts +import 'package:flutter_template/core/architecture/domain/entity/result.dart'; +import 'package:flutter_template/features/shared/domain/entities/failure/permission_failure.dart'; +import 'package:permission_handler/permission_handler.dart'; + +/// Typedef for the result of a request for user permissions. +typedef PermissionResult = Result; + +/// Interface of the repository for obtaining permissions from the user. +abstract class IPermissionHandlerRepository { + /// Check the permission for the use of [permission]. + Future checkPermission(Permission permission); +} From 0e3d0093300757ca438462d973c960a2161fea47 Mon Sep 17 00:00:00 2001 From: Tatiana Sugina Date: Fri, 12 Apr 2024 18:06:07 +0300 Subject: [PATCH 05/15] (feat): add example --- .../presentation/ui_kit/ui_kit_model.dart | 13 ++- .../presentation/ui_kit/ui_kit_screen.dart | 27 ++++++ .../debug/presentation/ui_kit/ui_kit_wm.dart | 90 ++++++++++++++++++- 3 files changed, 128 insertions(+), 2 deletions(-) diff --git a/lib/features/debug/presentation/ui_kit/ui_kit_model.dart b/lib/features/debug/presentation/ui_kit/ui_kit_model.dart index c37d6f45..0819cf10 100644 --- a/lib/features/debug/presentation/ui_kit/ui_kit_model.dart +++ b/lib/features/debug/presentation/ui_kit/ui_kit_model.dart @@ -1,10 +1,21 @@ import 'package:flutter_template/core/architecture/presentation/base_model.dart'; import 'package:flutter_template/features/debug/presentation/ui_kit/ui_kit_screen.dart'; +import 'package:flutter_template/features/shared/domain/repositories/i_permission_handler_repository.dart'; +import 'package:permission_handler/permission_handler.dart'; /// {@template ui_kit_model.class} /// Model for [UiKitScreen]. /// {@endtemplate} final class UiKitModel extends BaseModel { + final IPermissionHandlerRepository _permissionHandlerRepository; + /// {@macro ui_kit_model.class} - UiKitModel({required super.logWriter}); + UiKitModel({ + required super.logWriter, + required IPermissionHandlerRepository permissionHandlerRepository, + }) : _permissionHandlerRepository = permissionHandlerRepository; + + /// + Future checkPermission(Permission permission) => + _permissionHandlerRepository.checkPermission(permission); } diff --git a/lib/features/debug/presentation/ui_kit/ui_kit_screen.dart b/lib/features/debug/presentation/ui_kit/ui_kit_screen.dart index 9c616cf5..69990a94 100644 --- a/lib/features/debug/presentation/ui_kit/ui_kit_screen.dart +++ b/lib/features/debug/presentation/ui_kit/ui_kit_screen.dart @@ -4,6 +4,7 @@ import 'package:flutter_template/features/debug/presentation/ui_kit/ui_kit_wm.da import 'package:flutter_template/l10n/app_localizations_x.dart'; import 'package:flutter_template/uikit/app_sizes.dart'; import 'package:flutter_template/uikit/colors/app_color_scheme.dart'; +import 'package:permission_handler/permission_handler.dart'; /// {@template ui_kit_screen.class} /// UI-kit screen. @@ -36,6 +37,32 @@ class UiKitScreen extends ElementaryWidget { body: ListView( padding: const EdgeInsets.all(AppSizes.double16), children: [ + Row( + children: [ + Expanded( + child: ElevatedButton( + onPressed: () => wm.onPermissionLocationButtonPressed(Permission.location), + style: ElevatedButton.styleFrom( + foregroundColor: wm.colorScheme.onDanger, + backgroundColor: wm.colorScheme.dangerSecondary, + ), + child: Text(wm.l10n.permissionExampleLocation), + ), + ), + const SizedBox(width: AppSizes.double8), + Expanded( + child: ElevatedButton( + onPressed: () => wm.onPermissionNotificationButtonPressed(Permission.notification), + style: ElevatedButton.styleFrom( + foregroundColor: wm.colorScheme.onDanger, + backgroundColor: wm.colorScheme.dangerSecondary, + ), + child: Text(wm.l10n.permissionExampleNotification), + ), + ), + ], + ), + const SizedBox(height: AppSizes.double16), TextField( decoration: InputDecoration( labelText: wm.l10n.uiKitScreenTextFieldLabel, diff --git a/lib/features/debug/presentation/ui_kit/ui_kit_wm.dart b/lib/features/debug/presentation/ui_kit/ui_kit_wm.dart index 3acf0ccc..937afabe 100644 --- a/lib/features/debug/presentation/ui_kit/ui_kit_wm.dart +++ b/lib/features/debug/presentation/ui_kit/ui_kit_wm.dart @@ -2,10 +2,13 @@ import 'package:elementary/elementary.dart'; import 'package:flutter/material.dart'; import 'package:flutter_template/common/mixin/localization_mixin.dart'; import 'package:flutter_template/common/mixin/theme_wm_mixin.dart'; +import 'package:flutter_template/core/architecture/domain/entity/result.dart'; import 'package:flutter_template/features/app/di/app_scope.dart'; import 'package:flutter_template/features/debug/presentation/ui_kit/ui_kit_model.dart'; import 'package:flutter_template/features/debug/presentation/ui_kit/ui_kit_screen.dart'; +import 'package:flutter_template/features/shared/domain/entities/failure/permission_failure.dart'; import 'package:flutter_template/features/theme_mode/presentation/theme_mode_provider.dart'; +import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; /// Factory for [UiKitWM]. @@ -13,7 +16,10 @@ UiKitWM uiKitScreenWMFactory(BuildContext context) { final appScope = context.read(); final scaffoldMessenger = ScaffoldMessenger.of(context); - final model = UiKitModel(logWriter: appScope.logger); + final model = UiKitModel( + logWriter: appScope.logger, + permissionHandlerRepository: appScope.permissionHandlerRepository, + ); return UiKitWM(model, scaffoldMessenger: scaffoldMessenger); } @@ -40,6 +46,12 @@ abstract interface class IUiKitWM with ILocalizationMixin, ThemeIModelMixin impl /// Callback of pressing the positive snack button. void onPositiveSnackButtonPressed(); + + /// Callback of pressing the Permission Location button. + void onPermissionLocationButtonPressed(Permission permission); + + /// Callback of pressing the Permission Notification button. + void onPermissionNotificationButtonPressed(Permission permission); } /// {@template ui_kit_widget_model.class} @@ -102,4 +114,80 @@ class UiKitWM extends WidgetModel with LocalizationMixi ), ); } + + @override + Future onPermissionLocationButtonPressed(Permission permission) async { + await _checkPermission(permission); + } + + @override + Future onPermissionNotificationButtonPressed(Permission permission) async { + await _checkPermission(permission); + } + + Future _checkPermission(Permission permission) async { + final isLocation = permission == Permission.location; + final textLocationPositive = l10n.permissionExampleLocationPositiveText; + final textLocationNegative = l10n.permissionExampleLocationNegativeText; + final textNotificationPositive = l10n.permissionExampleNotificationPositiveText; + final textNotificationNegative = l10n.permissionExampleNotificationNegativeText; + + final result = await model.checkPermission(permission); + switch (result) { + case ResultOk(): + final _ = _scaffoldMessenger.showSnackBar( + SnackBar( + content: Text( + isLocation ? textLocationPositive : textNotificationPositive, + style: TextStyle(color: colorScheme.onPositive), + ), + backgroundColor: colorScheme.positive, + ), + ); + case ResultFailed(:final failure): + final isDeniedForever = failure is PermissionDeniedForever; + + if (isDeniedForever) { + _showDialogFromRequestPermission(); + } + + final _ = _scaffoldMessenger.showSnackBar( + SnackBar( + content: Text( + isLocation + ? '$textLocationNegative${isDeniedForever ? l10n.permissionExampleForeverText : ''}' + : '$textNotificationNegative${isDeniedForever ? l10n.permissionExampleForeverText : ''}', + style: TextStyle(color: colorScheme.onDanger), + ), + backgroundColor: colorScheme.danger, + ), + ); + } + } + + void _showDialogFromRequestPermission() { + showDialog( + context: context, + barrierDismissible: false, + builder: (context) { + return AlertDialog( + actions: [ + OutlinedButton( + onPressed: () async { + await openAppSettings(); + }, + child: Text(l10n.permissionExampleOpenSettingsButton), + ), + OutlinedButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text(l10n.permissionExampleCloseButton), + ), + ], + title: Text(l10n.permissionExampleRequestPermissionsTitle), + ); + }, + ); + } } From 2677dedf69782c019f698776e299490c863a6e1c Mon Sep 17 00:00:00 2001 From: Tatiana Sugina Date: Sat, 13 Apr 2024 16:51:40 +0300 Subject: [PATCH 06/15] (feat): dart format --- lib/l10n/app_localizations.g.dart | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/lib/l10n/app_localizations.g.dart b/lib/l10n/app_localizations.g.dart index 082b1259..b84929e9 100644 --- a/lib/l10n/app_localizations.g.dart +++ b/lib/l10n/app_localizations.g.dart @@ -88,10 +88,7 @@ abstract class AppLocalizations { ]; /// A list of this localizations delegate's supported locales. - static const List supportedLocales = [ - Locale('en'), - Locale('ru') - ]; + static const List supportedLocales = [Locale('en'), Locale('ru')]; /// No description provided for @positiveResponse. /// @@ -518,18 +515,16 @@ class _AppLocalizationsDelegate extends LocalizationsDelegate } AppLocalizations lookupAppLocalizations(Locale locale) { - - // Lookup logic when only language code is specified. switch (locale.languageCode) { - case 'en': return AppLocalizationsEn(); - case 'ru': return AppLocalizationsRu(); + case 'en': + return AppLocalizationsEn(); + case 'ru': + return AppLocalizationsRu(); } - throw FlutterError( - 'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely ' - 'an issue with the localizations generation tool. Please file an issue ' - 'on GitHub with a reproducible sample app and the gen-l10n configuration ' - 'that was used.' - ); + throw FlutterError('AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely ' + 'an issue with the localizations generation tool. Please file an issue ' + 'on GitHub with a reproducible sample app and the gen-l10n configuration ' + 'that was used.'); } From 7095ed957745a264c074e3c946bf9e5c9f3fce18 Mon Sep 17 00:00:00 2001 From: DmitrDomrachev Date: Thu, 25 Apr 2024 12:58:38 +0300 Subject: [PATCH 07/15] fix: fix permissionHandlerRepository init, checkPermission docs --- lib/features/app/di/app_scope.dart | 10 +++------- lib/features/app/di/app_scope_register.dart | 4 ++++ .../debug/presentation/ui_kit/ui_kit_model.dart | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/features/app/di/app_scope.dart b/lib/features/app/di/app_scope.dart index da9f5519..f3f7d176 100644 --- a/lib/features/app/di/app_scope.dart +++ b/lib/features/app/di/app_scope.dart @@ -3,7 +3,6 @@ import 'package:dio/dio.dart'; import 'package:flutter_template/common/utils/logger/i_log_writer.dart'; import 'package:flutter_template/config/app_config.dart'; import 'package:flutter_template/config/environment/environment.dart'; -import 'package:flutter_template/features/shared/data/repositories/permission_handler_repository.dart'; import 'package:flutter_template/features/shared/domain/repositories/i_permission_handler_repository.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -25,10 +24,8 @@ final class AppScope implements IAppScope { @override final ILogWriter logger; - late final IPermissionHandlerRepository _permissionHandlerRepository; - @override - IPermissionHandlerRepository get permissionHandlerRepository => _permissionHandlerRepository; + final IPermissionHandlerRepository permissionHandlerRepository; /// {@macro app_scope.class} AppScope({ @@ -38,9 +35,8 @@ final class AppScope implements IAppScope { required this.dio, required this.analyticsService, required this.logger, - }) { - _permissionHandlerRepository = PermissionHandlerRepository(); - } + required this.permissionHandlerRepository, + }); } /// {@macro app_scope.class} diff --git a/lib/features/app/di/app_scope_register.dart b/lib/features/app/di/app_scope_register.dart index 5e5ed329..15937cce 100644 --- a/lib/features/app/di/app_scope_register.dart +++ b/lib/features/app/di/app_scope_register.dart @@ -11,6 +11,7 @@ import 'package:flutter_template/config/environment/environment.dart'; import 'package:flutter_template/config/url.dart'; import 'package:flutter_template/features/app/di/app_scope.dart'; import 'package:flutter_template/features/debug/data/converters/url_converter.dart'; +import 'package:flutter_template/features/shared/data/repositories/permission_handler_repository.dart'; import 'package:flutter_template/persistence/storage/config_storage/config_storage_impl.dart'; import 'package:logger/logger.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -47,6 +48,8 @@ final class AppScopeRegister { }); final logger = LogWriter(surfLogger); + final permissionHandlerRepository = PermissionHandlerRepository(); + return AppScope( env: env, appConfig: appConfig, @@ -54,6 +57,7 @@ final class AppScopeRegister { dio: dio, analyticsService: analyticsService, logger: logger, + permissionHandlerRepository: permissionHandlerRepository, ); } diff --git a/lib/features/debug/presentation/ui_kit/ui_kit_model.dart b/lib/features/debug/presentation/ui_kit/ui_kit_model.dart index 0819cf10..762e60ea 100644 --- a/lib/features/debug/presentation/ui_kit/ui_kit_model.dart +++ b/lib/features/debug/presentation/ui_kit/ui_kit_model.dart @@ -15,7 +15,7 @@ final class UiKitModel extends BaseModel { required IPermissionHandlerRepository permissionHandlerRepository, }) : _permissionHandlerRepository = permissionHandlerRepository; - /// + /// Checks the status of a specific permission. Future checkPermission(Permission permission) => _permissionHandlerRepository.checkPermission(permission); } From 81f1c71aa5fc9678add28e3024e3aef2a682786b Mon Sep 17 00:00:00 2001 From: DmitrDomrachev Date: Sun, 5 May 2024 20:03:59 +0300 Subject: [PATCH 08/15] doc: setup is described in the documentation --- docs/permission_handler.md | 111 +++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 docs/permission_handler.md diff --git a/docs/permission_handler.md b/docs/permission_handler.md new file mode 100644 index 00000000..3666e1be --- /dev/null +++ b/docs/permission_handler.md @@ -0,0 +1,111 @@ + +# Permission Handler + +The guide describes how to use work with permissions in Flutter. + +# permission_handler + +[**permission_handler**](https://pub.dev/packages/permission_handler) is a permissions plugin for +Flutter. This plugin provides a cross-platform (iOS, Android, Web, Windows) API to request and check +permissions. + +## Setup + +1) Add permission_handler to your project using the instructions from [pub.dev](https://pub.dev/packages/permission_handler) +2) Create 'permissions' feature, using the masson. +3) In the 'permissions/domain/entities/failure' directory create the file 'permission_failure.dart': + +```dart +/// Statuses of the user permission request error. +sealed class PermissionFailure extends Failure { + PermissionFailure({required super.original, required super.trace});} + +/// Access denied. +final class PermissionDenied extends PermissionFailure { + /// Create an instance of [PermissionDenied]. + PermissionDenied({required super.original, required super.trace});} + +/// Access denied forever. +final class PermissionDeniedForever extends PermissionFailure { + /// Create an instance of [PermissionDeniedForever]. + PermissionDeniedForever({required super.original, required super.trace});} + +/// Service unavailable. +final class ServiceDisabled extends PermissionFailure { + /// Create an instance of [ServiceDisabled]. + ServiceDisabled({required super.original, required super.trace});} + +/// Other errors when requesting user permissions. +final class PermissionException extends PermissionFailure { + /// Create an instance of [PermissionException]. + PermissionException({required super.original, required super.trace});} +``` + +4) In the `permissions/domain/repositorie` directory create the file `i_permission_handler_repository.dart`: + +```dart +/// Typedef for the result of a request for user permissions. +typedef PermissionResult = Result; + +/// Interface of the repository for obtaining permissions from the user. +abstract class IPermissionHandlerRepository { + /// Check the permission for the use of [permission]. + Future checkPermission(Permission permission); +} +``` + +5) In the `permissions/data/repositories` directory create the + file `permission_handler_repository.dart`: + +```dart + /// Implementation of [PermissionHandlerRepository] for obtaining permissions from the user.class PermissionHandlerRepository implements IPermissionHandlerRepository { + /// Create an instance of [PermissionHandlerRepository]. PermissionHandlerRepository(); + @override Future checkPermission(Permission permission) async { final status = await permission.status; + if (status.isGranted) { return const Result.ok(null); } + if (status.isDenied) { final status = await permission.request(); + if (status.isGranted) { return const Result.ok(null); } else { return Result.failed(PermissionDenied(original: null, trace: null)); } } + if (status.isPermanentlyDenied) { return Result.failed(PermissionDeniedForever(original: null, trace: null)); } + return Result.failed(PermissionException(original: null, trace: null)); }} +``` + +6) Open the 'lib/features/app/di/app_scope' file. + Add the getter 'PermissionHandlerRepository' to the 'IAppScope' class: + +```dart + /// Permission handler repository. + IPermissionHandlerRepository get permissionHandlerRepository; +``` +In the 'AppScope' class, add the 'PermissionHandlerRepository' variable: + +```dart +... +@override +final IPermissionHandlerRepository permissionHandlerRepository; +... +AppScope({ +... +required this.permissionHandlerRepository, +... +}); +``` + +7) Open the 'lib/features/app/di/app_scope_register.dart' file. + In the 'AppScopeRegister' class, create the 'PermissionHandlerRepository' instance: + +```dart + final permissionHandlerRepository = PermissionHandlerRepository(); +``` +and pass it to the 'AppScope' constructor. + +```dart + return AppScope( + ... + permissionHandlerRepository: permissionHandlerRepository, + ... + ); +``` + +8) Now you can get the permissions repository from the context. +```dart + final permissionRepo = context.read().permissionHandlerRepository; +``` From 86a578ce3696fab1a51b1919999392a89c8a6c6a Mon Sep 17 00:00:00 2001 From: DmitrDomrachev Date: Mon, 6 May 2024 17:29:42 +0300 Subject: [PATCH 09/15] doc: the process of configuring the plugin is described --- docs/permission_handler.md | 101 +++++++++++++++++++++++++++---------- 1 file changed, 73 insertions(+), 28 deletions(-) diff --git a/docs/permission_handler.md b/docs/permission_handler.md index 3666e1be..2f581e69 100644 --- a/docs/permission_handler.md +++ b/docs/permission_handler.md @@ -10,11 +10,45 @@ Flutter. This plugin provides a cross-platform (iOS, Android, Web, Windows) API permissions. ## Setup +Add permission_handler to your pubspec.yaml file. -1) Add permission_handler to your project using the instructions from [pub.dev](https://pub.dev/packages/permission_handler) -2) Create 'permissions' feature, using the masson. -3) In the 'permissions/domain/entities/failure' directory create the file 'permission_failure.dart': +### Android: +In the AndroidManifest.xml file, add the permissions you need. +For example, to request the camera permission, add the following line: +```xml + +``` +[AndroidManifest example](https://github.com/Baseflow/flutter-permission-handler/blob/main/permission_handler/example/android/app/src/main/AndroidManifest.xml) + +### IOS: +In the Info.plist file, add the permissions you need. +For example, to request the camera permission, add the following line: +```xml +NSCameraUsageDescription +camera +``` +[Info.plist example](https://github.com/Baseflow/flutter-permission-handler/blob/main/permission_handler/example/ios/Runner/Info.plist) +In the Podfile file, you must describe the permissions you need: +```ruby +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + # YOUR CUSTOM TARGET CODE HERE. + target.build_configurations.each do |config| + config.build_settings['ENABLE_BITCODE'] = 'NO' + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [ + '$(inherited)', + ## dart: PermissionGroup.camera + 'PERMISSION_CAMERA=1', + ] + end + end +end +``` +## Usage +Create 'permissions' feature, using the masson. +In the 'permissions/domain/entities/failure' directory create the file 'permission_failure.dart': ```dart /// Statuses of the user permission request error. sealed class PermissionFailure extends Failure { @@ -41,8 +75,7 @@ final class PermissionException extends PermissionFailure { PermissionException({required super.original, required super.trace});} ``` -4) In the `permissions/domain/repositorie` directory create the file `i_permission_handler_repository.dart`: - +In the `permissions/domain/repositories` directory create the file `i_permission_handler_repository.dart`: ```dart /// Typedef for the result of a request for user permissions. typedef PermissionResult = Result; @@ -54,29 +87,42 @@ abstract class IPermissionHandlerRepository { } ``` -5) In the `permissions/data/repositories` directory create the - file `permission_handler_repository.dart`: - +In the `permissions/data/repositories` directory create the file `permission_handler_repository.dart`: ```dart - /// Implementation of [PermissionHandlerRepository] for obtaining permissions from the user.class PermissionHandlerRepository implements IPermissionHandlerRepository { - /// Create an instance of [PermissionHandlerRepository]. PermissionHandlerRepository(); - @override Future checkPermission(Permission permission) async { final status = await permission.status; - if (status.isGranted) { return const Result.ok(null); } - if (status.isDenied) { final status = await permission.request(); - if (status.isGranted) { return const Result.ok(null); } else { return Result.failed(PermissionDenied(original: null, trace: null)); } } - if (status.isPermanentlyDenied) { return Result.failed(PermissionDeniedForever(original: null, trace: null)); } - return Result.failed(PermissionException(original: null, trace: null)); }} + /// Implementation of [PermissionHandlerRepository] for obtaining permissions from the user. +class PermissionHandlerRepository implements IPermissionHandlerRepository { + /// Create an instance of [PermissionHandlerRepository]. + PermissionHandlerRepository(); + + @override Future checkPermission(Permission permission) async { + final status = await permission.status; + if (status.isGranted) { + return const Result.ok(null); + } + if (status.isDenied) { + final status = await permission.request(); + if (status.isGranted) { + return const Result.ok(null); + } else { + return Result.failed(PermissionDenied(original: null, trace: null)); + } + } + if (status.isPermanentlyDenied) { + return Result.failed(PermissionDeniedForever(original: null, trace: null)); + } + return Result.failed(PermissionException(original: null, trace: null)); + } +} ``` -6) Open the 'lib/features/app/di/app_scope' file. - Add the getter 'PermissionHandlerRepository' to the 'IAppScope' class: - +Open the 'lib/features/app/di/app_scope' file. +Add the getter 'PermissionHandlerRepository' to the 'IAppScope' class: ```dart /// Permission handler repository. IPermissionHandlerRepository get permissionHandlerRepository; ``` -In the 'AppScope' class, add the 'PermissionHandlerRepository' variable: +In the 'AppScope' class, add the 'PermissionHandlerRepository' variable: ```dart ... @override @@ -84,28 +130,27 @@ final IPermissionHandlerRepository permissionHandlerRepository; ... AppScope({ ... -required this.permissionHandlerRepository, + required this.permissionHandlerRepository, ... }); ``` -7) Open the 'lib/features/app/di/app_scope_register.dart' file. - In the 'AppScopeRegister' class, create the 'PermissionHandlerRepository' instance: - +Open the 'lib/features/app/di/app_scope_register.dart' file. +In the 'AppScopeRegister' class, create the 'PermissionHandlerRepository' instance: ```dart final permissionHandlerRepository = PermissionHandlerRepository(); ``` -and pass it to the 'AppScope' constructor. +and pass it to the 'AppScope' constructor: ```dart - return AppScope( +return AppScope( ... permissionHandlerRepository: permissionHandlerRepository, ... - ); +); ``` -8) Now you can get the permissions repository from the context. +Now you can get the permissions repository from the context. ```dart final permissionRepo = context.read().permissionHandlerRepository; ``` From 72c573bb260c1cf569db3abbaf1d2e63a91a29e2 Mon Sep 17 00:00:00 2001 From: DmitrDomrachev Date: Mon, 6 May 2024 17:46:30 +0300 Subject: [PATCH 10/15] fix: implementation of the permission_handler has been removed --- android/app/src/main/AndroidManifest.xml | 3 - ios/Podfile | 10 --- ios/Runner/Info.plist | 4 - lib/features/app/di/app_scope.dart | 8 -- lib/features/app/di/app_scope_register.dart | 4 - .../presentation/ui_kit/ui_kit_model.dart | 13 +-- .../presentation/ui_kit/ui_kit_screen.dart | 27 ------ .../debug/presentation/ui_kit/ui_kit_wm.dart | 86 ------------------- lib/features/shared/data/converters/.gitkeep | 0 .../shared/data/repositories/.gitkeep | 0 .../permission_handler_repository.dart | 35 -------- lib/features/shared/di/.gitkeep | 0 lib/features/shared/domain/entities/.gitkeep | 0 .../entities/failure/permission_failure.dart | 30 ------- .../shared/domain/repositories/.gitkeep | 0 .../i_permission_handler_repository.dart | 13 --- .../shared/presentation/screens/.gitkeep | 0 .../shared/presentation/widgets/.gitkeep | 0 lib/l10n/app_en.arb | 18 +--- lib/l10n/app_localizations.g.dart | 83 +++--------------- lib/l10n/app_localizations_en.g.dart | 30 ------- lib/l10n/app_localizations_ru.g.dart | 30 ------- lib/l10n/app_ru.arb | 18 +--- 23 files changed, 19 insertions(+), 393 deletions(-) delete mode 100644 lib/features/shared/data/converters/.gitkeep delete mode 100644 lib/features/shared/data/repositories/.gitkeep delete mode 100644 lib/features/shared/data/repositories/permission_handler_repository.dart delete mode 100644 lib/features/shared/di/.gitkeep delete mode 100644 lib/features/shared/domain/entities/.gitkeep delete mode 100644 lib/features/shared/domain/entities/failure/permission_failure.dart delete mode 100644 lib/features/shared/domain/repositories/.gitkeep delete mode 100644 lib/features/shared/domain/repositories/i_permission_handler_repository.dart delete mode 100644 lib/features/shared/presentation/screens/.gitkeep delete mode 100644 lib/features/shared/presentation/widgets/.gitkeep diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index a9805b5b..73fa08c7 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -7,9 +7,6 @@ additional functionality it is fine to subclass or reimplement FlutterApplication and put your custom class here. --> - - - LSRequiresIPhoneOS - NSLocationAlwaysUsageDescription - This way we can identify the places of interest closest to you - NSLocationWhenInUseUsageDescription - This way we can identify the places of interest closest to you UILaunchStoryboardName LaunchScreen UIMainStoryboardFile diff --git a/lib/features/app/di/app_scope.dart b/lib/features/app/di/app_scope.dart index f3f7d176..f55f2415 100644 --- a/lib/features/app/di/app_scope.dart +++ b/lib/features/app/di/app_scope.dart @@ -3,7 +3,6 @@ import 'package:dio/dio.dart'; import 'package:flutter_template/common/utils/logger/i_log_writer.dart'; import 'package:flutter_template/config/app_config.dart'; import 'package:flutter_template/config/environment/environment.dart'; -import 'package:flutter_template/features/shared/domain/repositories/i_permission_handler_repository.dart'; import 'package:shared_preferences/shared_preferences.dart'; /// {@template app_scope.class} @@ -24,9 +23,6 @@ final class AppScope implements IAppScope { @override final ILogWriter logger; - @override - final IPermissionHandlerRepository permissionHandlerRepository; - /// {@macro app_scope.class} AppScope({ required this.env, @@ -35,7 +31,6 @@ final class AppScope implements IAppScope { required this.dio, required this.analyticsService, required this.logger, - required this.permissionHandlerRepository, }); } @@ -58,7 +53,4 @@ abstract interface class IAppScope { /// Analytics sending service. AnalyticService get analyticsService; - - /// Permission handler repository. - IPermissionHandlerRepository get permissionHandlerRepository; } diff --git a/lib/features/app/di/app_scope_register.dart b/lib/features/app/di/app_scope_register.dart index 15937cce..5e5ed329 100644 --- a/lib/features/app/di/app_scope_register.dart +++ b/lib/features/app/di/app_scope_register.dart @@ -11,7 +11,6 @@ import 'package:flutter_template/config/environment/environment.dart'; import 'package:flutter_template/config/url.dart'; import 'package:flutter_template/features/app/di/app_scope.dart'; import 'package:flutter_template/features/debug/data/converters/url_converter.dart'; -import 'package:flutter_template/features/shared/data/repositories/permission_handler_repository.dart'; import 'package:flutter_template/persistence/storage/config_storage/config_storage_impl.dart'; import 'package:logger/logger.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -48,8 +47,6 @@ final class AppScopeRegister { }); final logger = LogWriter(surfLogger); - final permissionHandlerRepository = PermissionHandlerRepository(); - return AppScope( env: env, appConfig: appConfig, @@ -57,7 +54,6 @@ final class AppScopeRegister { dio: dio, analyticsService: analyticsService, logger: logger, - permissionHandlerRepository: permissionHandlerRepository, ); } diff --git a/lib/features/debug/presentation/ui_kit/ui_kit_model.dart b/lib/features/debug/presentation/ui_kit/ui_kit_model.dart index 762e60ea..c37d6f45 100644 --- a/lib/features/debug/presentation/ui_kit/ui_kit_model.dart +++ b/lib/features/debug/presentation/ui_kit/ui_kit_model.dart @@ -1,21 +1,10 @@ import 'package:flutter_template/core/architecture/presentation/base_model.dart'; import 'package:flutter_template/features/debug/presentation/ui_kit/ui_kit_screen.dart'; -import 'package:flutter_template/features/shared/domain/repositories/i_permission_handler_repository.dart'; -import 'package:permission_handler/permission_handler.dart'; /// {@template ui_kit_model.class} /// Model for [UiKitScreen]. /// {@endtemplate} final class UiKitModel extends BaseModel { - final IPermissionHandlerRepository _permissionHandlerRepository; - /// {@macro ui_kit_model.class} - UiKitModel({ - required super.logWriter, - required IPermissionHandlerRepository permissionHandlerRepository, - }) : _permissionHandlerRepository = permissionHandlerRepository; - - /// Checks the status of a specific permission. - Future checkPermission(Permission permission) => - _permissionHandlerRepository.checkPermission(permission); + UiKitModel({required super.logWriter}); } diff --git a/lib/features/debug/presentation/ui_kit/ui_kit_screen.dart b/lib/features/debug/presentation/ui_kit/ui_kit_screen.dart index 69990a94..9c616cf5 100644 --- a/lib/features/debug/presentation/ui_kit/ui_kit_screen.dart +++ b/lib/features/debug/presentation/ui_kit/ui_kit_screen.dart @@ -4,7 +4,6 @@ import 'package:flutter_template/features/debug/presentation/ui_kit/ui_kit_wm.da import 'package:flutter_template/l10n/app_localizations_x.dart'; import 'package:flutter_template/uikit/app_sizes.dart'; import 'package:flutter_template/uikit/colors/app_color_scheme.dart'; -import 'package:permission_handler/permission_handler.dart'; /// {@template ui_kit_screen.class} /// UI-kit screen. @@ -37,32 +36,6 @@ class UiKitScreen extends ElementaryWidget { body: ListView( padding: const EdgeInsets.all(AppSizes.double16), children: [ - Row( - children: [ - Expanded( - child: ElevatedButton( - onPressed: () => wm.onPermissionLocationButtonPressed(Permission.location), - style: ElevatedButton.styleFrom( - foregroundColor: wm.colorScheme.onDanger, - backgroundColor: wm.colorScheme.dangerSecondary, - ), - child: Text(wm.l10n.permissionExampleLocation), - ), - ), - const SizedBox(width: AppSizes.double8), - Expanded( - child: ElevatedButton( - onPressed: () => wm.onPermissionNotificationButtonPressed(Permission.notification), - style: ElevatedButton.styleFrom( - foregroundColor: wm.colorScheme.onDanger, - backgroundColor: wm.colorScheme.dangerSecondary, - ), - child: Text(wm.l10n.permissionExampleNotification), - ), - ), - ], - ), - const SizedBox(height: AppSizes.double16), TextField( decoration: InputDecoration( labelText: wm.l10n.uiKitScreenTextFieldLabel, diff --git a/lib/features/debug/presentation/ui_kit/ui_kit_wm.dart b/lib/features/debug/presentation/ui_kit/ui_kit_wm.dart index 937afabe..71d9f042 100644 --- a/lib/features/debug/presentation/ui_kit/ui_kit_wm.dart +++ b/lib/features/debug/presentation/ui_kit/ui_kit_wm.dart @@ -2,13 +2,10 @@ import 'package:elementary/elementary.dart'; import 'package:flutter/material.dart'; import 'package:flutter_template/common/mixin/localization_mixin.dart'; import 'package:flutter_template/common/mixin/theme_wm_mixin.dart'; -import 'package:flutter_template/core/architecture/domain/entity/result.dart'; import 'package:flutter_template/features/app/di/app_scope.dart'; import 'package:flutter_template/features/debug/presentation/ui_kit/ui_kit_model.dart'; import 'package:flutter_template/features/debug/presentation/ui_kit/ui_kit_screen.dart'; -import 'package:flutter_template/features/shared/domain/entities/failure/permission_failure.dart'; import 'package:flutter_template/features/theme_mode/presentation/theme_mode_provider.dart'; -import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; /// Factory for [UiKitWM]. @@ -18,7 +15,6 @@ UiKitWM uiKitScreenWMFactory(BuildContext context) { final model = UiKitModel( logWriter: appScope.logger, - permissionHandlerRepository: appScope.permissionHandlerRepository, ); return UiKitWM(model, scaffoldMessenger: scaffoldMessenger); @@ -46,12 +42,6 @@ abstract interface class IUiKitWM with ILocalizationMixin, ThemeIModelMixin impl /// Callback of pressing the positive snack button. void onPositiveSnackButtonPressed(); - - /// Callback of pressing the Permission Location button. - void onPermissionLocationButtonPressed(Permission permission); - - /// Callback of pressing the Permission Notification button. - void onPermissionNotificationButtonPressed(Permission permission); } /// {@template ui_kit_widget_model.class} @@ -114,80 +104,4 @@ class UiKitWM extends WidgetModel with LocalizationMixi ), ); } - - @override - Future onPermissionLocationButtonPressed(Permission permission) async { - await _checkPermission(permission); - } - - @override - Future onPermissionNotificationButtonPressed(Permission permission) async { - await _checkPermission(permission); - } - - Future _checkPermission(Permission permission) async { - final isLocation = permission == Permission.location; - final textLocationPositive = l10n.permissionExampleLocationPositiveText; - final textLocationNegative = l10n.permissionExampleLocationNegativeText; - final textNotificationPositive = l10n.permissionExampleNotificationPositiveText; - final textNotificationNegative = l10n.permissionExampleNotificationNegativeText; - - final result = await model.checkPermission(permission); - switch (result) { - case ResultOk(): - final _ = _scaffoldMessenger.showSnackBar( - SnackBar( - content: Text( - isLocation ? textLocationPositive : textNotificationPositive, - style: TextStyle(color: colorScheme.onPositive), - ), - backgroundColor: colorScheme.positive, - ), - ); - case ResultFailed(:final failure): - final isDeniedForever = failure is PermissionDeniedForever; - - if (isDeniedForever) { - _showDialogFromRequestPermission(); - } - - final _ = _scaffoldMessenger.showSnackBar( - SnackBar( - content: Text( - isLocation - ? '$textLocationNegative${isDeniedForever ? l10n.permissionExampleForeverText : ''}' - : '$textNotificationNegative${isDeniedForever ? l10n.permissionExampleForeverText : ''}', - style: TextStyle(color: colorScheme.onDanger), - ), - backgroundColor: colorScheme.danger, - ), - ); - } - } - - void _showDialogFromRequestPermission() { - showDialog( - context: context, - barrierDismissible: false, - builder: (context) { - return AlertDialog( - actions: [ - OutlinedButton( - onPressed: () async { - await openAppSettings(); - }, - child: Text(l10n.permissionExampleOpenSettingsButton), - ), - OutlinedButton( - onPressed: () { - Navigator.of(context).pop(); - }, - child: Text(l10n.permissionExampleCloseButton), - ), - ], - title: Text(l10n.permissionExampleRequestPermissionsTitle), - ); - }, - ); - } } diff --git a/lib/features/shared/data/converters/.gitkeep b/lib/features/shared/data/converters/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/lib/features/shared/data/repositories/.gitkeep b/lib/features/shared/data/repositories/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/lib/features/shared/data/repositories/permission_handler_repository.dart b/lib/features/shared/data/repositories/permission_handler_repository.dart deleted file mode 100644 index 6869c145..00000000 --- a/lib/features/shared/data/repositories/permission_handler_repository.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:flutter_template/core/architecture/domain/entity/result.dart'; -import 'package:flutter_template/features/shared/domain/entities/failure/permission_failure.dart'; -import 'package:flutter_template/features/shared/domain/repositories/i_permission_handler_repository.dart'; -import 'package:permission_handler/permission_handler.dart'; - -/// Implementation of [PermissionHandlerRepository] for obtaining permissions from the user. -class PermissionHandlerRepository implements IPermissionHandlerRepository { - /// Create an instance of [PermissionHandlerRepository]. - PermissionHandlerRepository(); - - @override - Future checkPermission(Permission permission) async { - final status = await permission.status; - - if (status.isGranted) { - return const Result.ok(null); - } - - if (status.isDenied) { - final status = await permission.request(); - - if (status.isGranted) { - return const Result.ok(null); - } else { - return Result.failed(PermissionDenied(original: null, trace: null)); - } - } - - if (status.isPermanentlyDenied) { - return Result.failed(PermissionDeniedForever(original: null, trace: null)); - } - - return Result.failed(PermissionException(original: null, trace: null)); - } -} diff --git a/lib/features/shared/di/.gitkeep b/lib/features/shared/di/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/lib/features/shared/domain/entities/.gitkeep b/lib/features/shared/domain/entities/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/lib/features/shared/domain/entities/failure/permission_failure.dart b/lib/features/shared/domain/entities/failure/permission_failure.dart deleted file mode 100644 index b0b2c36d..00000000 --- a/lib/features/shared/domain/entities/failure/permission_failure.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter_template/core/architecture/domain/entity/failure.dart'; - -/// Statuses of the user permission request error. -sealed class PermissionFailure extends Failure { - PermissionFailure({required super.original, required super.trace}); -} - -/// Access denied. -final class PermissionDenied extends PermissionFailure { - /// Create an instance of [PermissionDenied]. - PermissionDenied({required super.original, required super.trace}); -} - -/// Access denied forever. -final class PermissionDeniedForever extends PermissionFailure { - /// Create an instance of [PermissionDeniedForever]. - PermissionDeniedForever({required super.original, required super.trace}); -} - -/// Service unavailable. -final class ServiceDisabled extends PermissionFailure { - /// Create an instance of [ServiceDisabled]. - ServiceDisabled({required super.original, required super.trace}); -} - -/// Other errors when requesting user permissions. -final class PermissionException extends PermissionFailure { - /// Create an instance of [PermissionException]. - PermissionException({required super.original, required super.trace}); -} diff --git a/lib/features/shared/domain/repositories/.gitkeep b/lib/features/shared/domain/repositories/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/lib/features/shared/domain/repositories/i_permission_handler_repository.dart b/lib/features/shared/domain/repositories/i_permission_handler_repository.dart deleted file mode 100644 index 6ec04502..00000000 --- a/lib/features/shared/domain/repositories/i_permission_handler_repository.dart +++ /dev/null @@ -1,13 +0,0 @@ -// ignore_for_file: one_member_abstracts -import 'package:flutter_template/core/architecture/domain/entity/result.dart'; -import 'package:flutter_template/features/shared/domain/entities/failure/permission_failure.dart'; -import 'package:permission_handler/permission_handler.dart'; - -/// Typedef for the result of a request for user permissions. -typedef PermissionResult = Result; - -/// Interface of the repository for obtaining permissions from the user. -abstract class IPermissionHandlerRepository { - /// Check the permission for the use of [permission]. - Future checkPermission(Permission permission); -} diff --git a/lib/features/shared/presentation/screens/.gitkeep b/lib/features/shared/presentation/screens/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/lib/features/shared/presentation/widgets/.gitkeep b/lib/features/shared/presentation/widgets/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 13f1992d..eab0566f 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -114,19 +114,5 @@ "---------": "---------", "description": "Example of feature" }, - "featureExampleFailedLoadIpMessage": "Failed to load IP address", - "@segmentPermissionExample": { - "---------": "---------", - "description": "Permission Example" - }, - "permissionExampleLocation": "Location", - "permissionExampleNotification": "Notification", - "permissionExampleOpenSettingsButton": "Open Settings", - "permissionExampleCloseButton": "Close", - "permissionExampleRequestPermissionsTitle": "Request permissions", - "permissionExampleLocationPositiveText": "Access to geolocation is allowed", - "permissionExampleLocationNegativeText": "Access to geolocation is denied", - "permissionExampleNotificationPositiveText": "Push notifications are allowed", - "permissionExampleNotificationNegativeText": "Push notifications are denied", - "permissionExampleForeverText": " forever" -} \ No newline at end of file + "featureExampleFailedLoadIpMessage": "Failed to load IP address" +} diff --git a/lib/l10n/app_localizations.g.dart b/lib/l10n/app_localizations.g.dart index b84929e9..b81b1f80 100644 --- a/lib/l10n/app_localizations.g.dart +++ b/lib/l10n/app_localizations.g.dart @@ -88,7 +88,10 @@ abstract class AppLocalizations { ]; /// A list of this localizations delegate's supported locales. - static const List supportedLocales = [Locale('en'), Locale('ru')]; + static const List supportedLocales = [ + Locale('en'), + Locale('ru') + ]; /// No description provided for @positiveResponse. /// @@ -437,66 +440,6 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'Failed to load IP address'** String get featureExampleFailedLoadIpMessage; - - /// No description provided for @permissionExampleLocation. - /// - /// In en, this message translates to: - /// **'Location'** - String get permissionExampleLocation; - - /// No description provided for @permissionExampleNotification. - /// - /// In en, this message translates to: - /// **'Notification'** - String get permissionExampleNotification; - - /// No description provided for @permissionExampleOpenSettingsButton. - /// - /// In en, this message translates to: - /// **'Open Settings'** - String get permissionExampleOpenSettingsButton; - - /// No description provided for @permissionExampleCloseButton. - /// - /// In en, this message translates to: - /// **'Close'** - String get permissionExampleCloseButton; - - /// No description provided for @permissionExampleRequestPermissionsTitle. - /// - /// In en, this message translates to: - /// **'Request permissions'** - String get permissionExampleRequestPermissionsTitle; - - /// No description provided for @permissionExampleLocationPositiveText. - /// - /// In en, this message translates to: - /// **'Access to geolocation is allowed'** - String get permissionExampleLocationPositiveText; - - /// No description provided for @permissionExampleLocationNegativeText. - /// - /// In en, this message translates to: - /// **'Access to geolocation is denied'** - String get permissionExampleLocationNegativeText; - - /// No description provided for @permissionExampleNotificationPositiveText. - /// - /// In en, this message translates to: - /// **'Push notifications are allowed'** - String get permissionExampleNotificationPositiveText; - - /// No description provided for @permissionExampleNotificationNegativeText. - /// - /// In en, this message translates to: - /// **'Push notifications are denied'** - String get permissionExampleNotificationNegativeText; - - /// No description provided for @permissionExampleForeverText. - /// - /// In en, this message translates to: - /// **' forever'** - String get permissionExampleForeverText; } class _AppLocalizationsDelegate extends LocalizationsDelegate { @@ -515,16 +458,18 @@ class _AppLocalizationsDelegate extends LocalizationsDelegate } AppLocalizations lookupAppLocalizations(Locale locale) { + + // Lookup logic when only language code is specified. switch (locale.languageCode) { - case 'en': - return AppLocalizationsEn(); - case 'ru': - return AppLocalizationsRu(); + case 'en': return AppLocalizationsEn(); + case 'ru': return AppLocalizationsRu(); } - throw FlutterError('AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely ' - 'an issue with the localizations generation tool. Please file an issue ' - 'on GitHub with a reproducible sample app and the gen-l10n configuration ' - 'that was used.'); + throw FlutterError( + 'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely ' + 'an issue with the localizations generation tool. Please file an issue ' + 'on GitHub with a reproducible sample app and the gen-l10n configuration ' + 'that was used.' + ); } diff --git a/lib/l10n/app_localizations_en.g.dart b/lib/l10n/app_localizations_en.g.dart index 6184cc9c..920d11f2 100644 --- a/lib/l10n/app_localizations_en.g.dart +++ b/lib/l10n/app_localizations_en.g.dart @@ -202,34 +202,4 @@ class AppLocalizationsEn extends AppLocalizations { @override String get featureExampleFailedLoadIpMessage => 'Failed to load IP address'; - - @override - String get permissionExampleLocation => 'Location'; - - @override - String get permissionExampleNotification => 'Notification'; - - @override - String get permissionExampleOpenSettingsButton => 'Open Settings'; - - @override - String get permissionExampleCloseButton => 'Close'; - - @override - String get permissionExampleRequestPermissionsTitle => 'Request permissions'; - - @override - String get permissionExampleLocationPositiveText => 'Access to geolocation is allowed'; - - @override - String get permissionExampleLocationNegativeText => 'Access to geolocation is denied'; - - @override - String get permissionExampleNotificationPositiveText => 'Push notifications are allowed'; - - @override - String get permissionExampleNotificationNegativeText => 'Push notifications are denied'; - - @override - String get permissionExampleForeverText => ' forever'; } diff --git a/lib/l10n/app_localizations_ru.g.dart b/lib/l10n/app_localizations_ru.g.dart index 20e86982..aaba1583 100644 --- a/lib/l10n/app_localizations_ru.g.dart +++ b/lib/l10n/app_localizations_ru.g.dart @@ -202,34 +202,4 @@ class AppLocalizationsRu extends AppLocalizations { @override String get featureExampleFailedLoadIpMessage => 'Failed to load IP address'; - - @override - String get permissionExampleLocation => 'Location'; - - @override - String get permissionExampleNotification => 'Notification'; - - @override - String get permissionExampleOpenSettingsButton => 'Open Settings'; - - @override - String get permissionExampleCloseButton => 'Close'; - - @override - String get permissionExampleRequestPermissionsTitle => 'Request permissions'; - - @override - String get permissionExampleLocationPositiveText => 'Access to geolocation is allowed'; - - @override - String get permissionExampleLocationNegativeText => 'Access to geolocation is denied'; - - @override - String get permissionExampleNotificationPositiveText => 'Push notifications are allowed'; - - @override - String get permissionExampleNotificationNegativeText => 'Push notifications are denied'; - - @override - String get permissionExampleForeverText => ' forever'; } diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb index af951363..606fbeaa 100644 --- a/lib/l10n/app_ru.arb +++ b/lib/l10n/app_ru.arb @@ -115,19 +115,5 @@ "---------": "---------", "description": "Feature example" }, - "featureExampleFailedLoadIpMessage": "Failed to load IP address", - "@segmentPermissionExample": { - "---------": "---------", - "description": "Permission Example" - }, - "permissionExampleLocation": "Location", - "permissionExampleNotification": "Notification", - "permissionExampleOpenSettingsButton": "Open Settings", - "permissionExampleCloseButton": "Close", - "permissionExampleRequestPermissionsTitle": "Request permissions", - "permissionExampleLocationPositiveText": "Access to geolocation is allowed", - "permissionExampleLocationNegativeText": "Access to geolocation is denied", - "permissionExampleNotificationPositiveText": "Push notifications are allowed", - "permissionExampleNotificationNegativeText": "Push notifications are denied", - "permissionExampleForeverText": " forever" -} \ No newline at end of file + "featureExampleFailedLoadIpMessage": "Failed to load IP address" +} From 2678bb700cdb905fec8210207598fda62f53c06b Mon Sep 17 00:00:00 2001 From: DmitrDomrachev Date: Mon, 6 May 2024 17:50:52 +0300 Subject: [PATCH 11/15] style: style changes --- lib/features/app/di/app_scope.dart | 2 +- lib/features/debug/presentation/ui_kit/ui_kit_wm.dart | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/features/app/di/app_scope.dart b/lib/features/app/di/app_scope.dart index f55f2415..9357e689 100644 --- a/lib/features/app/di/app_scope.dart +++ b/lib/features/app/di/app_scope.dart @@ -24,7 +24,7 @@ final class AppScope implements IAppScope { final ILogWriter logger; /// {@macro app_scope.class} - AppScope({ + const AppScope({ required this.env, required this.appConfig, required this.sharedPreferences, diff --git a/lib/features/debug/presentation/ui_kit/ui_kit_wm.dart b/lib/features/debug/presentation/ui_kit/ui_kit_wm.dart index 71d9f042..3acf0ccc 100644 --- a/lib/features/debug/presentation/ui_kit/ui_kit_wm.dart +++ b/lib/features/debug/presentation/ui_kit/ui_kit_wm.dart @@ -13,9 +13,7 @@ UiKitWM uiKitScreenWMFactory(BuildContext context) { final appScope = context.read(); final scaffoldMessenger = ScaffoldMessenger.of(context); - final model = UiKitModel( - logWriter: appScope.logger, - ); + final model = UiKitModel(logWriter: appScope.logger); return UiKitWM(model, scaffoldMessenger: scaffoldMessenger); } From 11b20fee69071417d9e3abf251055a083cb0f123 Mon Sep 17 00:00:00 2001 From: DmitrDomrachev Date: Mon, 6 May 2024 17:58:22 +0300 Subject: [PATCH 12/15] style: dart format --- lib/l10n/app_localizations.g.dart | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/lib/l10n/app_localizations.g.dart b/lib/l10n/app_localizations.g.dart index b81b1f80..8331ccb0 100644 --- a/lib/l10n/app_localizations.g.dart +++ b/lib/l10n/app_localizations.g.dart @@ -88,10 +88,7 @@ abstract class AppLocalizations { ]; /// A list of this localizations delegate's supported locales. - static const List supportedLocales = [ - Locale('en'), - Locale('ru') - ]; + static const List supportedLocales = [Locale('en'), Locale('ru')]; /// No description provided for @positiveResponse. /// @@ -458,18 +455,16 @@ class _AppLocalizationsDelegate extends LocalizationsDelegate } AppLocalizations lookupAppLocalizations(Locale locale) { - - // Lookup logic when only language code is specified. switch (locale.languageCode) { - case 'en': return AppLocalizationsEn(); - case 'ru': return AppLocalizationsRu(); + case 'en': + return AppLocalizationsEn(); + case 'ru': + return AppLocalizationsRu(); } - throw FlutterError( - 'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely ' - 'an issue with the localizations generation tool. Please file an issue ' - 'on GitHub with a reproducible sample app and the gen-l10n configuration ' - 'that was used.' - ); + throw FlutterError('AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely ' + 'an issue with the localizations generation tool. Please file an issue ' + 'on GitHub with a reproducible sample app and the gen-l10n configuration ' + 'that was used.'); } From b510604b1d632ffdda48bac59cb495c150aa4036 Mon Sep 17 00:00:00 2001 From: DmitrDomrachev Date: Tue, 7 May 2024 14:27:58 +0300 Subject: [PATCH 13/15] fix: internet permission --- android/app/src/main/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 73fa08c7..7da35af9 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -7,7 +7,7 @@ additional functionality it is fine to subclass or reimplement FlutterApplication and put your custom class here. --> - + From a52086d2e6234f7d6d64b24d2d6f05a3ce815712 Mon Sep 17 00:00:00 2001 From: DmitrDomrachev Date: Mon, 13 May 2024 17:28:23 +0300 Subject: [PATCH 14/15] fix: permission_handler dependency --- pubspec.lock | 48 ------------------------------------------------ pubspec.yaml | 1 - 2 files changed, 49 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 6ba5ec01..615f12ad 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -781,54 +781,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.1" - permission_handler: - dependency: "direct main" - description: - name: permission_handler - sha256: "18bf33f7fefbd812f37e72091a15575e72d5318854877e0e4035a24ac1113ecb" - url: "https://pub.dev" - source: hosted - version: "11.3.1" - permission_handler_android: - dependency: transitive - description: - name: permission_handler_android - sha256: "1acac6bae58144b442f11e66621c062aead9c99841093c38f5bcdcc24c1c3474" - url: "https://pub.dev" - source: hosted - version: "12.0.5" - permission_handler_apple: - dependency: transitive - description: - name: permission_handler_apple - sha256: e9ad66020b89ff1b63908f247c2c6f931c6e62699b756ef8b3c4569350cd8662 - url: "https://pub.dev" - source: hosted - version: "9.4.4" - permission_handler_html: - dependency: transitive - description: - name: permission_handler_html - sha256: "54bf176b90f6eddd4ece307e2c06cf977fb3973719c35a93b85cc7093eb6070d" - url: "https://pub.dev" - source: hosted - version: "0.1.1" - permission_handler_platform_interface: - dependency: transitive - description: - name: permission_handler_platform_interface - sha256: "48d4fcf201a1dad93ee869ab0d4101d084f49136ec82a8a06ed9cfeacab9fd20" - url: "https://pub.dev" - source: hosted - version: "4.2.1" - permission_handler_windows: - dependency: transitive - description: - name: permission_handler_windows - sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" - url: "https://pub.dev" - source: hosted - version: "0.2.1" petitparser: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 98d011f9..b3498026 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -27,7 +27,6 @@ dependencies: nested: 1.0.0 path: 1.9.0 path_provider: 2.1.2 - permission_handler: 11.3.1 provider: 6.1.1 retrofit: 4.0.3 rxdart: 0.27.7 From dc145b0605197d72052c6b0a84b66e9e91d3389c Mon Sep 17 00:00:00 2001 From: DmitrDomrachev Date: Mon, 13 May 2024 17:37:58 +0300 Subject: [PATCH 15/15] fix: pod install --- ios/Runner.xcodeproj/project.pbxproj | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 436ff833..cfb8c0b4 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -195,7 +195,6 @@ 9C081569228C6AC20006FEB3 /* ShellScript */, B66FF691DE180E7D19E1A137 /* [CP] Embed Pods Frameworks */, 8A5D96D62B94EB81002D56E0 /* [firebase_crashlytics] Crashlytics Upload Symbols */, - BF513D92CD81C03FF509F09E /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -402,24 +401,6 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - BF513D92CD81C03FF509F09E /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/permission_handler_apple/permission_handler_apple_privacy.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/permission_handler_apple_privacy.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */