From 8e64839fc6f32c024820aca8ff6b4bca420cf520 Mon Sep 17 00:00:00 2001 From: qguillaume Date: Thu, 11 Jun 2026 20:24:57 +0200 Subject: [PATCH] fix: capture photo plus robuste --- lib/features/capture/capture_screen.dart | 59 ++++++++++++++++++++---- 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/lib/features/capture/capture_screen.dart b/lib/features/capture/capture_screen.dart index d13e3a37..ceb55c0a 100644 --- a/lib/features/capture/capture_screen.dart +++ b/lib/features/capture/capture_screen.dart @@ -43,6 +43,7 @@ class _CaptureScreenState extends State String? _selectedImagePath; bool _isLoading = false; + bool _isCapturing = false; // garde anti-double-capture pendant le traitement // Caméra live CameraController? _cameraController; @@ -585,7 +586,7 @@ class _CaptureScreenState extends State right: 0, child: Center( child: GestureDetector( - onTap: _takePictureManually, + onTap: _isCapturing ? null : _takePictureManually, child: Container( height: 80, width: 80, @@ -607,6 +608,35 @@ class _CaptureScreenState extends State ), ), ), + + // 6. Overlay bloquant pendant la capture/traitement : empêche de + // bouger l'UI ou de relancer une capture tant que la photo n'est pas + // chargée (absorbe tous les gestes + voile + indicateur). + if (_isCapturing) + Positioned.fill( + child: AbsorbPointer( + child: Container( + color: Colors.black.withValues(alpha: 0.45), + child: const Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + CircularProgressIndicator(color: Colors.white), + SizedBox(height: 16), + Text( + 'Photo en cours…', + style: TextStyle( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + ), + ), + ), ], ), ); @@ -721,14 +751,21 @@ class _CaptureScreenState extends State return; } - setState(() => _isLoading = true); - try { - try { - await _cameraController!.setZoomLevel(1.0); - } catch (_) {} + // Garde anti-double-capture : tout appui supplémentaire pendant le + // traitement est ignoré (évite les photos multiples / états incohérents). + if (_isCapturing) return; + setState(() { + _isCapturing = true; + _isLoading = true; + }); + try { + // On stoppe le flux d'analyse (obligatoire avant takePicture) puis on + // capture IMMÉDIATEMENT, sans étape intermédiaire. Le reset de zoom + // inutile (aucun zoom possible sur cet écran) a été retiré pour que la + // photo parte sans délai perceptible. _stopAlignmentDetection(); - _stopParallelismDetection(); // NOUVEAU + _stopParallelismDetection(); final XFile photo = await _cameraController!.takePicture(); @@ -747,6 +784,7 @@ class _CaptureScreenState extends State debugPrint('Downscale ignoré: $e'); } + if (!mounted) return; setState(() { _selectedImagePath = finalPath; _showLiveCamera = false; @@ -756,7 +794,12 @@ class _CaptureScreenState extends State } catch (e) { debugPrint('Erreur lors du clic photo: $e'); } finally { - setState(() => _isLoading = false); + if (mounted) { + setState(() { + _isLoading = false; + _isCapturing = false; + }); + } } }