fix permission error notification

This commit is contained in:
Fabian Freund
2026-06-02 11:21:43 +02:00
parent 341edc6951
commit 2a481bb873
4 changed files with 24 additions and 17 deletions
@@ -21,7 +21,6 @@ import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:qr_code_scanner_plus/qr_code_scanner_plus.dart';
import 'package:weblibre/core/branding/proxy_brands.dart'; import 'package:weblibre/core/branding/proxy_brands.dart';
import 'package:weblibre/features/proxy/data/models/proxy_profile_seed.dart'; import 'package:weblibre/features/proxy/data/models/proxy_profile_seed.dart';
import 'package:weblibre/features/proxy/domain/services/proxy_input_consumer.dart'; import 'package:weblibre/features/proxy/domain/services/proxy_input_consumer.dart';
@@ -69,10 +68,7 @@ class AddProxyMethodSheet extends ConsumerWidget {
} }
Future<void> scanQr() async { Future<void> scanQr() async {
final result = await showDialog<Barcode>( final result = await showQrScannerDialog(context);
context: context,
builder: (_) => const QrScannerDialog(),
);
final code = result?.code?.trim(); final code = result?.code?.trim();
if (code == null || code.isEmpty) return; if (code == null || code.isEmpty) return;
if (!context.mounted) return; if (!context.mounted) return;
@@ -21,9 +21,26 @@ import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:qr_code_scanner_plus/qr_code_scanner_plus.dart'; import 'package:qr_code_scanner_plus/qr_code_scanner_plus.dart';
import 'package:weblibre/utils/ui_helper.dart' as ui_helper; import 'package:weblibre/utils/ui_helper.dart' as ui_helper;
Future<Barcode?> showQrScannerDialog(BuildContext context) async {
final cameraPermission = await Permission.camera.request();
if (!context.mounted) return null;
if (!cameraPermission.isGranted) {
ui_helper.showErrorMessage(context, 'No Camera Permission granted');
return null;
}
return showDialog<Barcode>(
context: context,
builder: (_) => const QrScannerDialog(),
);
}
class QrScannerDialog extends HookWidget { class QrScannerDialog extends HookWidget {
const QrScannerDialog({super.key}); const QrScannerDialog({super.key});
@@ -33,6 +50,7 @@ class QrScannerDialog extends HookWidget {
final qrController = useState<QRViewController?>(null); final qrController = useState<QRViewController?>(null);
final flashState = useState(false); final flashState = useState(false);
final permissionDeniedHandled = useRef(false);
useEffect(() { useEffect(() {
StreamSubscription<Barcode>? sub; StreamSubscription<Barcode>? sub;
@@ -83,11 +101,13 @@ class QrScannerDialog extends HookWidget {
qrController.value = controller; qrController.value = controller;
}, },
onPermissionSet: (controller, result) { onPermissionSet: (controller, result) {
if (!result) { if (!result && !permissionDeniedHandled.value) {
permissionDeniedHandled.value = true;
ui_helper.showErrorMessage( ui_helper.showErrorMessage(
context, context,
'No Camera Permission granted', 'No Camera Permission granted',
); );
Navigator.of(context).pop();
} }
}, },
), ),
@@ -24,7 +24,6 @@ import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart'; import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:qr_code_scanner_plus/qr_code_scanner_plus.dart';
import 'package:weblibre/core/logger.dart'; import 'package:weblibre/core/logger.dart';
import 'package:weblibre/core/providers/format.dart'; import 'package:weblibre/core/providers/format.dart';
import 'package:weblibre/features/qr_scanner/presentation/dialogs/qr_scanner_dialog.dart'; import 'package:weblibre/features/qr_scanner/presentation/dialogs/qr_scanner_dialog.dart';
@@ -146,10 +145,7 @@ class SyncSettingsScreen extends HookConsumerWidget {
), ),
trailing: const Icon(Icons.chevron_right), trailing: const Icon(Icons.chevron_right),
onTap: () async { onTap: () async {
final barcode = await showDialog<Barcode>( final barcode = await showQrScannerDialog(context);
context: context,
builder: (_) => const QrScannerDialog(),
);
final code = barcode?.code; final code = barcode?.code;
if (code == null || code.isEmpty) return; if (code == null || code.isEmpty) return;
@@ -32,12 +32,7 @@ class QrScannerButton extends HookConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
return IconButton( return IconButton(
onPressed: () async { onPressed: () async {
final result = await showDialog<Barcode>( final result = await showQrScannerDialog(context);
context: context,
builder: (context) {
return const QrScannerDialog();
},
);
onScanResult(result); onScanResult(result);
}, },