Skip to content

Commit

Permalink
feat (Permissions) not request permission if it is already requested
Browse files Browse the repository at this point in the history
build update version
  • Loading branch information
BreX900 authored and Elhan98 committed Jul 19, 2022
1 parent 563484b commit 72be992
Show file tree
Hide file tree
Showing 16 changed files with 132 additions and 50 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## 0.2.3 (2022-07-19)
- feat (Permissions) not request permission if it is already requested
- build update packages version

## 0.2.0

- feat: Upgrade flutter to 3.0.x and dart to 2.17.x
2 changes: 1 addition & 1 deletion kuama_core/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: kuama_core
description: A starting point for Dart libraries or applications.
publish_to: 'none'
version: 0.2.3
version: 0.2.4

environment:
sdk: '>=2.17.0 <3.0.0'
Expand Down
6 changes: 4 additions & 2 deletions kuama_permissions/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ dependencies:
git:
url: https://github.com/Kuama-IT/kuama_dart.git
path: kuama_permissions
ref: 0.2.3
ref: 0.2.4
kuama_position:
git:
url: https://github.com/Kuama-IT/kuama_dart.git
path: kuama_position
ref: 0.2.3
ref: 0.2.4

shared_preferences: ^2.0.15
geolocator: ^9.0.0
Expand All @@ -31,6 +31,8 @@ dependencies:
dependency_overrides:
kuama_core:
path: ../../kuama_core
kuama_permissions:
path: ..
kuama_position:
path: ../../kuama_position

Expand Down
3 changes: 2 additions & 1 deletion kuama_permissions/lib/src/blocs/_permissions_event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ class _CheckPermissionsEvent extends _PermissionsBlocEvent with _$_CheckPermissi
@DataClass(comparable: false)
class _RequestPermissionsEvent extends _PermissionsBlocEvent with _$_RequestPermissionsEvent {
final Set<Permission> permissions;
final bool tryAgain;

_RequestPermissionsEvent(this.permissions);
_RequestPermissionsEvent(this.permissions, {required this.tryAgain});

@override
R map<R>({
Expand Down
6 changes: 6 additions & 0 deletions kuama_permissions/lib/src/blocs/_permissions_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,13 @@ abstract class PermissionsBlocState with _$PermissionsBlocState {
Map<Permission, PermissionStatus>? permissionsStatus,
Map<Service, bool>? servicesStatus,
required Set<Permission> payload,
required bool isRequested,
}) {
return RequestedPermissionsState(
isRefreshing: false,
permissionsStatus: permissionsStatus ?? this.permissionsStatus,
servicesStatus: servicesStatus ?? this.servicesStatus,
isRequested: isRequested,
payload: payload,
);
}
Expand Down Expand Up @@ -328,11 +330,15 @@ class RequestingPermissionsState extends PermissionsBlocState with _$RequestingP
class RequestedPermissionsState extends PermissionsBlocState with _$RequestedPermissionsState {
final Set<Permission> payload;

/// Whether the permission has been requested.
final bool isRequested;

const RequestedPermissionsState({
required bool isRefreshing,
required Map<Permission, PermissionStatus> permissionsStatus,
required Map<Service, bool> servicesStatus,
required this.payload,
required this.isRequested,
}) : super(
isRefreshing: isRefreshing,
permissionsStatus: permissionsStatus,
Expand Down
34 changes: 27 additions & 7 deletions kuama_permissions/lib/src/blocs/permissions_bloc.b.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ class PermissionsBloc extends Bloc<_PermissionsBlocEvent, PermissionsBlocState>
///
/// While processing the actions, [RequestingPermissionsState] is emitted.
/// Once the action is completed, permissions and services status are update to [permissions] and [RequestedPermissionsState] is emitted.
void request(Set<Permission> permissions) => add(_RequestPermissionsEvent(permissions));
void request(Set<Permission> permissions, {bool tryAgain = true}) =>
add(_RequestPermissionsEvent(permissions, tryAgain: tryAgain));

/// Asks permissions.
///
Expand Down Expand Up @@ -93,7 +94,7 @@ class PermissionsBloc extends Bloc<_PermissionsBlocEvent, PermissionsBlocState>
return event.map<Future<void>>(check: (event) {
return _onCheck(emit, event.permissions);
}, request: (event) {
return _onRequest(emit, event.permissions);
return _onRequest(emit, event.permissions, tryAgain: event.tryAgain);
}, ask: (event) {
return _onAsk(emit, event.permissions, tryAgain: event.tryAgain);
}, confirmAsk: (event) {
Expand Down Expand Up @@ -129,19 +130,38 @@ class PermissionsBloc extends Bloc<_PermissionsBlocEvent, PermissionsBlocState>
));
}

Future<void> _onRequest(Emitter<PermissionsBlocState> emit, Set<Permission> permissions) async {
Future<void> _onRequest(
Emitter<PermissionsBlocState> emit,
Set<Permission> permissions, {
bool tryAgain = true,
}) async {
if (permissions.isEmpty || !state.checkCanRequest(permissions)) return;

emit(state.toRequesting(
payload: permissions,
));

final status = await _service.requestPermissions(permissions.toList());
final checkStatus = await _service.checkStatus(permissions.toList(), tryAgain: tryAgain);

_listenServices(checkStatus.services.keys);

if (!checkStatus.canResolve || checkStatus.areAllGrantedAndEnabled) {
emit(state.toRequested(
permissionsStatus: {...state.permissionsStatus, ...checkStatus.permissions},
servicesStatus: {...state.servicesStatus, ...checkStatus.services},
payload: permissions,
isRequested: false,
));
return;
}

final requestStatus = await _service.requestPermissions(permissions.toList());

emit(state.toRequested(
permissionsStatus: {...state.permissionsStatus, ...requestStatus.permissions},
servicesStatus: {...state.servicesStatus, ...requestStatus.services},
payload: permissions,
permissionsStatus: {...state.permissionsStatus, ...status.permissions},
servicesStatus: {...state.servicesStatus, ...status.services},
isRequested: true,
));
}

Expand All @@ -163,7 +183,7 @@ class PermissionsBloc extends Bloc<_PermissionsBlocEvent, PermissionsBlocState>
final permissionsStatus = {...state.permissionsStatus, ...result.permissions};
final servicesStatus = {...state.servicesStatus, ...result.services};

if (!result.canAsk || result.areAllGrantedAndEnabled) {
if (!result.canResolve || result.areAllGrantedAndEnabled) {
emit(state.toAsked(
permissionsStatus: permissionsStatus,
servicesStatus: servicesStatus,
Expand Down
12 changes: 9 additions & 3 deletions kuama_permissions/lib/src/blocs/permissions_bloc.b.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ part 'permissions_status_entity.b.g.dart';

@DataClass(changeable: false)
class PermissionsStatusEntity with _$PermissionsStatusEntity {
/// Whether the permissions can been asked
final bool canAsk;
/// Whether the permissions can been asked or requested
final bool canResolve;

/// Whether all permissions are granted and services are enabled
final bool areAllGrantedAndEnabled;
Expand All @@ -17,7 +17,7 @@ class PermissionsStatusEntity with _$PermissionsStatusEntity {
final Map<Service, bool> services;

const PermissionsStatusEntity({
required this.canAsk,
required this.canResolve,
required this.areAllGrantedAndEnabled,
required this.permissions,
required this.services,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import 'package:shared_preferences/shared_preferences.dart';
/// Allows you to read and save user preferences regarding app permissions
///
/// Allows to persist a pair [Permission] - [bool],
/// [bool] represents whether the [Permission] has already been asked.
/// [bool] represents whether the [Permission] has already been asked or requested.
///
/// ```dart
/// final repo = StoragePermissionsRepository();
Expand All @@ -18,16 +18,16 @@ import 'package:shared_preferences/shared_preferences.dart';
class PermissionsPreferencesRepository {
SharedPreferences get _preferences => GetIt.I();

/// Returns which permissions have already been asked
Map<Permission, bool> checkAsked(List<Permission> permissions) {
/// Returns which permissions have already been asked or requested
Map<Permission, bool> checkResolved(List<Permission> permissions) {
return {
for (final permission in permissions)
permission: _preferences.getBool('$permission') ?? false,
};
}

/// Update the permissions preferences if they can't be requested
Future<void> markAsked(List<Permission> permissions) async {
/// Update the permissions preferences if they can't be asked or requested
Future<void> markResolved(List<Permission> permissions) async {
await Future.wait(permissions.map((permission) async {
await _preferences.setBool('$permission', true);
}));
Expand Down
13 changes: 6 additions & 7 deletions kuama_permissions/lib/src/services/permissions_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,14 @@ class PermissionsService {
List<Permission> permissions, {
bool tryAgain = false,
}) async {
final preferencesPermissions = _preferences.checkAsked(permissions);
final canAsk = preferencesPermissions.any((_, isAsked) => !isAsked);

final preferencesPermissions = _preferences.checkResolved(permissions);
final hasResolvedPermission = preferencesPermissions.any((_, isResolved) => isResolved);
final checkedPermissions = await _handler.checkPermissions(permissions);

final checkedServices = await _checkServices(permissions);

return PermissionsStatusEntity(
canAsk: canAsk || tryAgain,
canResolve: !hasResolvedPermission || tryAgain,
areAllGrantedAndEnabled: _checkAllGrantedAndEnabled(checkedPermissions, checkedServices),
permissions: checkedPermissions,
services: checkedServices,
Expand All @@ -64,19 +63,19 @@ class PermissionsService {

/// Mark [permissions] as "not requestable"
Future<void> markAskedPermissions(List<Permission> permissions) async {
await _preferences.markAsked(permissions);
await _preferences.markResolved(permissions);
}

/// Requests [permissions] and mark them as "not requestable"
Future<PermissionsStatusEntity> requestPermissions(List<Permission> permissions) async {
await _preferences.markAsked(permissions);
await _preferences.markResolved(permissions);

final requestedPermissions = await _handler.requestPermissions(permissions);

final checkedServices = await _checkServices(permissions);

return PermissionsStatusEntity(
canAsk: false,
canResolve: false,
areAllGrantedAndEnabled: _checkAllGrantedAndEnabled(requestedPermissions, checkedServices),
permissions: requestedPermissions,
services: checkedServices,
Expand Down
4 changes: 2 additions & 2 deletions kuama_permissions/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ dependencies:
git:
url: https://github.com/Kuama-IT/kuama_dart.git
path: kuama_core
ref: 0.2.3
ref: 0.2.4

permission_handler_platform_interface: ^3.7.0
permission_handler: ^10.0.0
Expand All @@ -42,7 +42,7 @@ dev_dependencies:
# To generate .g files:
# flutter packages pub run build_runner build --delete-conflicting-outputs
# flutter packages pub run build_runner watch --delete-conflicting-outputs
build_runner: ^2.1.11
build_runner: ^2.2.0
mek_data_class_generator: ^0.1.3

dependency_overrides:
Expand Down
Loading

0 comments on commit 72be992

Please sign in to comment.