Files
krow-worker-app/lib/core/permissions.dart

63 lines
2.3 KiB
Dart

import 'package:flutter/foundation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:permission_handler/permission_handler.dart';
/// The three things the app asks for, in the order it asks.
enum AppPermission { location, notifications, camera }
extension AppPermissionX on AppPermission {
Permission get _platform => switch (this) {
// While-in-use only: clock-in needs to know you are at the venue, and
// nothing here justifies background tracking.
AppPermission.location => Permission.locationWhenInUse,
AppPermission.notifications => Permission.notification,
AppPermission.camera => Permission.camera,
};
}
/// Thin wrapper over `permission_handler`.
///
/// Exists so the rest of the app never imports the plugin directly, and so the
/// platforms it has no implementation for — web, desktop — degrade to "granted"
/// instead of throwing. On the web the browser prompts at the point of use
/// anyway, so asking up front is neither possible nor needed.
class PermissionService {
const PermissionService();
bool get _supported =>
!kIsWeb &&
(defaultTargetPlatform == TargetPlatform.android ||
defaultTargetPlatform == TargetPlatform.iOS);
/// Shows the platform dialog. Returns whether the permission ended up
/// granted — which is not the same as whether the user tapped Allow, since
/// it may already have been permanently denied.
Future<bool> request(AppPermission permission) async {
if (!_supported) return true;
final status = await permission._platform.request();
return status.isGranted || status.isLimited;
}
Future<bool> isGranted(AppPermission permission) async {
if (!_supported) return true;
final status = await permission._platform.status;
return status.isGranted || status.isLimited;
}
/// True once the OS will no longer show a dialog, so the only way back is
/// the system settings page.
Future<bool> isPermanentlyDenied(AppPermission permission) async {
if (!_supported) return false;
return permission._platform.status.then((s) => s.isPermanentlyDenied);
}
Future<void> openSettings() async {
if (!_supported) return;
await openAppSettings();
}
}
final permissionServiceProvider = Provider<PermissionService>(
(ref) => const PermissionService(),
);