From 4f7fa4ba93d26a9d1ae24622003625914438fdca Mon Sep 17 00:00:00 2001 From: "mr.mojtaba" Date: Tue, 16 Dec 2025 14:38:06 +0330 Subject: [PATCH] feat: enhance CreateInspectionBottomSheetLogic with image listener setup and improve camera controller functionality for better user experience --- .../create_inspection_bottom_sheet_logic.dart | 11 +++++- .../step2_page.dart | 2 +- .../image_picker/image_picker_controller.dart | 36 +++++++++++++------ .../image_picker/image_picker_widget.dart | 31 ++++++++++++++++ 4 files changed, 68 insertions(+), 12 deletions(-) diff --git a/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart b/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart index 05a9215..c81cd05 100644 --- a/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart +++ b/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart @@ -209,6 +209,10 @@ class CreateInspectionBottomSheetLogic extends GetxController void onReady() { super.onReady(); activeStepperIndex.listen((value) { + iLog("==========>$value"); + if (value == 1) { + setUpPultryImagesListener(); + } pageController.animateToPage( value, duration: Duration(milliseconds: 300), @@ -956,7 +960,12 @@ class CreateInspectionBottomSheetLogic extends GetxController void setUpPultryImagesListener() { pultryImagesController.addListener(() { - pultryImages.assignAll(pultryImagesController.capturedImages); + if (pultryImagesController.capturedImages.isNotEmpty) { + WidgetsBinding.instance.addPostFrameCallback((_) { + pultryImages.assignAll(pultryImagesController.capturedImages); + }); + + } }); } } diff --git a/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step2_page.dart b/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step2_page.dart index e0309c6..b7cea3f 100644 --- a/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step2_page.dart +++ b/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step2_page.dart @@ -74,7 +74,7 @@ Widget generalConditionOfTheHall(CreateInspectionBottomSheetLogic controller) { children: [ ObxValue((data) { return Row( - children: data.value + children: data .map( (entry) => Stack( children: [ diff --git a/packages/core/lib/presentation/widget/image_picker/image_picker_controller.dart b/packages/core/lib/presentation/widget/image_picker/image_picker_controller.dart index 59923c3..09ee4e7 100644 --- a/packages/core/lib/presentation/widget/image_picker/image_picker_controller.dart +++ b/packages/core/lib/presentation/widget/image_picker/image_picker_controller.dart @@ -8,41 +8,57 @@ class RImagePickerController extends ChangeNotifier { CameraController? cameraController; bool isLoading = false; + bool isCameraReady = false; + bool frontCamera = true; + bool isCameraLoading = false; + bool hasTwoCameras = false; List capturedImages = []; Future getAvailableCameras() async { _cameras = await availableCameras(); + if (_cameras.length > 1) { + hasTwoCameras = true; + } } Future openCamera() async { try { - isLoading = true; + isCameraLoading = true; await disposeCameraController(); await getAvailableCameras(); if (_cameras.isNotEmpty) { - cameraController = CameraController( - _cameras[0], - ResolutionPreset.high, - enableAudio: false, - ); + if (hasTwoCameras && frontCamera) { + cameraController = CameraController( + _cameras[0], + ResolutionPreset.high, + enableAudio: false, + ); + } + if (hasTwoCameras && !frontCamera) { + cameraController = CameraController( + _cameras[1], + ResolutionPreset.high, + enableAudio: false, + ); + } await cameraController?.initialize(); isCameraReady = true; - isLoading = false; + isCameraLoading = false; notifyListeners(); } else { isCameraReady = false; - isLoading = false; + isCameraLoading = false; notifyListeners(); } } catch (e) { isCameraReady = false; - isLoading = false; + isCameraLoading = false; notifyListeners(); eLog(e); } @@ -59,7 +75,7 @@ class RImagePickerController extends ChangeNotifier { notifyListeners(); final image = await cameraController!.takePicture(); - capturedImages.add(image); + capturedImages.insert(0, image); isLoading = false; } catch (e) { diff --git a/packages/core/lib/presentation/widget/image_picker/image_picker_widget.dart b/packages/core/lib/presentation/widget/image_picker/image_picker_widget.dart index 0ff785c..254dbe5 100644 --- a/packages/core/lib/presentation/widget/image_picker/image_picker_widget.dart +++ b/packages/core/lib/presentation/widget/image_picker/image_picker_widget.dart @@ -92,6 +92,37 @@ class _RImagePickerState extends State { ), ], + Positioned( + bottom: 40, + left: 10, + + child: Center( + child: FloatingActionButton( + onPressed: widget.controller.isCameraLoading + ? null + : () async { + widget.controller.frontCamera = + !widget.controller.frontCamera; + + await widget.controller.openCamera(); + }, + backgroundColor: Colors.white, + child: widget.controller.isCameraLoading + ? const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + valueColor: AlwaysStoppedAnimation( + Colors.black, + ), + ), + ) + : const Icon(Icons.cameraswitch, color: Colors.black), + ), + ), + ), + if (widget.controller.capturedImages.isNotEmpty) ...[ Positioned( bottom: 120,