diff --git a/assets/images/svg/zoom-in.svg b/assets/images/svg/zoom-in.svg
new file mode 100644
index 00000000..99d6c329
--- /dev/null
+++ b/assets/images/svg/zoom-in.svg
@@ -0,0 +1,5 @@
+
+
\ No newline at end of file
diff --git a/assets/images/svg/zoom.svg b/assets/images/svg/zoom.svg
new file mode 100644
index 00000000..20e1ad9a
--- /dev/null
+++ b/assets/images/svg/zoom.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/assets/images/svg/zoom_out.svg b/assets/images/svg/zoom_out.svg
new file mode 100644
index 00000000..b4fb96f7
--- /dev/null
+++ b/assets/images/svg/zoom_out.svg
@@ -0,0 +1,26 @@
+
+
+
+
\ No newline at end of file
diff --git a/lib/features/symptoms_checker/symptoms_checker_view_model.dart b/lib/features/symptoms_checker/symptoms_checker_view_model.dart
index d06b2538..43b23982 100644
--- a/lib/features/symptoms_checker/symptoms_checker_view_model.dart
+++ b/lib/features/symptoms_checker/symptoms_checker_view_model.dart
@@ -47,6 +47,12 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
final Set _selectedOrganIds = {};
bool _isBottomSheetExpanded = false;
+ // Zoom state
+ double _currentZoomScale = 1.0;
+ static const double _minZoomScale = 0.5;
+ static const double _maxZoomScale = 4.0;
+ static const double _zoomStep = 0.5;
+
// Tooltip state
String? _tooltipOrganId;
Timer? _tooltipTimer;
@@ -135,6 +141,8 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
String? get tooltipOrganId => _tooltipOrganId;
+ double get currentZoomScale => _currentZoomScale;
+
String get currentSessionAuthToken => symptomsUserDetailsResponseModel?.tokenDetails?.authToken ?? "";
String get currentSessionId => symptomsUserDetailsResponseModel?.sessionId ?? "";
@@ -231,6 +239,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
void toggleView() {
_currentView = _currentView == BodyView.front ? BodyView.back : BodyView.front;
+ _currentZoomScale = 1.0; // Reset zoom when switching views
notifyListeners();
}
@@ -261,6 +270,20 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
notifyListeners();
}
+ toggleZoomIn() {
+ if (_currentZoomScale < _maxZoomScale) {
+ _currentZoomScale = (_currentZoomScale + _zoomStep).clamp(_minZoomScale, _maxZoomScale);
+ notifyListeners();
+ }
+ }
+
+ toggleZoomOut(){
+ if (_currentZoomScale > _minZoomScale) {
+ _currentZoomScale = (_currentZoomScale - _zoomStep).clamp(_minZoomScale, _maxZoomScale);
+ notifyListeners();
+ }
+ }
+
void _showTooltip(String organId) {
_tooltipTimer?.cancel();
@@ -865,6 +888,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
_triageEvidenceList.clear();
_selectedTriageChoicesByItemId.clear();
_triageQuestionCount = 0; // Reset question count
+ _currentZoomScale = 1.0; // Reset zoom scale
bodySymptomResponse = null;
riskFactorsResponse = null;
suggestionsResponse = null;
diff --git a/lib/presentation/contact_us/find_us_page.dart b/lib/presentation/contact_us/find_us_page.dart
index e1dff5e7..4a68b2aa 100644
--- a/lib/presentation/contact_us/find_us_page.dart
+++ b/lib/presentation/contact_us/find_us_page.dart
@@ -80,7 +80,9 @@ class FindUsPage extends StatelessWidget {
contactUsVM.sortHMGLocations(true);
// }
},
- onFailure: () {},
+ onFailure: () {
+ locationUtils.onFailureDilouge();
+ },
);
} else {
contactUsVM.sortHMGLocations(false);
diff --git a/lib/presentation/symptoms_checker/organ_selector_screen.dart b/lib/presentation/symptoms_checker/organ_selector_screen.dart
index 253fccdc..ea85b3b5 100644
--- a/lib/presentation/symptoms_checker/organ_selector_screen.dart
+++ b/lib/presentation/symptoms_checker/organ_selector_screen.dart
@@ -80,6 +80,7 @@ class _OrganSelectorPageState extends State {
children: [
_buildBodyViewer(viewModel),
_buildViewToggleButtons(viewModel),
+ _buildViewZoomButtons(viewModel),
_buildBottomSheet(viewModel),
],
),
@@ -161,6 +162,7 @@ class _OrganSelectorPageState extends State {
isBodyHidden: viewModel.isBodyHidden,
tooltipOrganId: viewModel.tooltipOrganId,
isArabic: _appState.isArabic(),
+ zoomScale: viewModel.currentZoomScale,
);
},
),
@@ -212,6 +214,26 @@ class _OrganSelectorPageState extends State {
);
}
+ Widget _buildViewZoomButtons(SymptomsCheckerViewModel viewModel) {
+ return PositionedDirectional(
+ end: 16.w,
+ top: 36.h,
+ child: Column(
+ children: [
+ _buildToggleButton(
+ icon: "assets/images/svg/zoom-in.svg",
+ onTap: viewModel.toggleZoomIn,
+ ),
+ SizedBox(height: 16.h),
+ _buildToggleButton(
+ icon: "assets/images/svg/zoom_out.svg",
+ onTap: viewModel.toggleZoomOut,
+ ),
+ ],
+ ),
+ );
+ }
+
Widget _buildToggleButton({required String icon, required VoidCallback onTap}) {
return GestureDetector(
onTap: onTap,
diff --git a/lib/presentation/symptoms_checker/widgets/interactive_body_widget.dart b/lib/presentation/symptoms_checker/widgets/interactive_body_widget.dart
index 62c38f9a..ee2370d1 100644
--- a/lib/presentation/symptoms_checker/widgets/interactive_body_widget.dart
+++ b/lib/presentation/symptoms_checker/widgets/interactive_body_widget.dart
@@ -5,6 +5,7 @@ import 'package:flutter/services.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/organ_model.dart';
import 'package:hmg_patient_app_new/presentation/symptoms_checker/widgets/organ_dot_widget.dart';
import 'package:hmg_patient_app_new/presentation/symptoms_checker/widgets/organ_tooltip_widget.dart';
+import 'package:vector_math/vector_math_64.dart' show Vector3;
class InteractiveBodyWidget extends StatefulWidget {
final String bodyImageAsset;
@@ -14,6 +15,7 @@ class InteractiveBodyWidget extends StatefulWidget {
final Function(String organId) onOrganTap;
final String? tooltipOrganId;
final bool isArabic;
+ final double zoomScale;
const InteractiveBodyWidget({
super.key,
@@ -24,6 +26,7 @@ class InteractiveBodyWidget extends StatefulWidget {
this.isBodyHidden = false,
this.tooltipOrganId,
this.isArabic = false,
+ this.zoomScale = 1.0,
});
@override
@@ -48,6 +51,11 @@ class _InteractiveBodyWidgetState extends State {
// Reset zoom when switching views
_transformationController.value = Matrix4.identity();
}
+
+ // Update zoom when zoomScale changes
+ if (oldWidget.zoomScale != widget.zoomScale) {
+ _updateZoom(widget.zoomScale);
+ }
}
@override
@@ -69,6 +77,19 @@ class _InteractiveBodyWidgetState extends State {
}
}
+ void _updateZoom(double scale) {
+ // Get current translation
+ final currentTransform = _transformationController.value;
+ final currentTranslation = currentTransform.getTranslation();
+
+ // Create new transformation with updated scale while preserving translation
+ final newTransform = Matrix4.identity()
+ ..setTranslation(currentTranslation)
+ ..scaleByVector3(Vector3(scale, scale, 1.0));
+
+ _transformationController.value = newTransform;
+ }
+
@override
Widget build(BuildContext context) {
if (_imageAspectRatio == null) {