diff --git a/assets/images/png/full_body_back_female.png b/assets/images/png/full_body_back_female.png new file mode 100644 index 0000000..9b3aa74 Binary files /dev/null and b/assets/images/png/full_body_back_female.png differ diff --git a/assets/images/png/full_body_back.png b/assets/images/png/full_body_back_male.png similarity index 100% rename from assets/images/png/full_body_back.png rename to assets/images/png/full_body_back_male.png diff --git a/assets/images/png/full_body_front_female.png b/assets/images/png/full_body_front_female.png new file mode 100644 index 0000000..c89608b Binary files /dev/null and b/assets/images/png/full_body_front_female.png differ diff --git a/assets/images/png/full_body_front.png b/assets/images/png/full_body_front_male.png similarity index 100% rename from assets/images/png/full_body_front.png rename to assets/images/png/full_body_front_male.png diff --git a/convert_json.dart b/convert_json.dart deleted file mode 100644 index af5c594..0000000 --- a/convert_json.dart +++ /dev/null @@ -1,73 +0,0 @@ -// import 'dart:convert'; -// import 'dart:io'; -// -// void main() async { -// final file = File('assets/json/body_symptoms_data.json'); -// final content = await file.readAsString(); -// -// print('File size: ${content.length} characters'); -// -// // Split into two parts -// final parts = content.split('export const SymptomsData = ['); -// if (parts.length != 2) { -// print('ERROR: Could not split file properly'); -// exit(1); -// } -// -// print('Split into ${parts.length} parts'); -// -// // Process BodySymptomsData -// var bodyPart = parts[0] -// .replaceAll('export const BodySymptomsData = ', '') -// .trim() -// .replaceAll(RegExp(r';$'), ''); -// -// print('Parsing body symptoms...'); -// Map bodySymptomsData; -// try { -// bodySymptomsData = json.decode(bodyPart); -// print('✅ Body symptoms parsed: ${bodySymptomsData.length} body parts'); -// } catch (e) { -// print('❌ Error parsing body symptoms: $e'); -// exit(1); -// } -// -// // Process SymptomsData -// print('Processing symptoms data...'); -// var symptomsPart = parts[1] -// .trim() -// .replaceAll(RegExp(r'\];$'), '') -// .replaceAllMapped(RegExp(r'\n(\s*)id:'), (m) => '\n${m.group(1)}"id":') -// .replaceAllMapped(RegExp(r'\n(\s*)type:'), (m) => '\n${m.group(1)}"type":') -// .replaceAllMapped(RegExp(r'\n(\s*)name:'), (m) => '\n${m.group(1)}"name":') -// .replaceAllMapped(RegExp(r'\n(\s*)common_name:'), (m) => '\n${m.group(1)}"common_name":'); -// -// print('Parsing symptoms...'); -// List symptomsData; -// try { -// symptomsData = json.decode('[$symptomsPart]'); -// print('✅ Symptoms parsed: ${symptomsData.length} symptoms'); -// } catch (e) { -// print('❌ Error parsing symptoms: $e'); -// print('First 1000 chars:'); -// print('[$symptomsPart]'.substring(0, 1000)); -// exit(1); -// } -// -// // Create final JSON -// print('Creating final JSON structure...'); -// final jsonStructure = { -// 'bodySymptoms': bodySymptomsData, -// 'symptoms': symptomsData, -// }; -// -// // Write to file -// print('Writing to file...'); -// final encoder = JsonEncoder.withIndent(' '); -// await file.writeAsString(encoder.convert(jsonStructure)); -// -// print('\n✅ SUCCESS! File converted to proper JSON'); -// print('✅ Body parts: ${bodySymptomsData.length}'); -// print('✅ Symptoms: ${symptomsData.length}'); -// } -// diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart index d9d7120..96c7cc0 100644 --- a/lib/core/app_assets.dart +++ b/lib/core/app_assets.dart @@ -351,8 +351,10 @@ class AppAssets { static const String maleIcon = '$pngBasePath/male_icon.png'; static const String femaleIcon = '$pngBasePath/female_icon.png'; - static const String fullBodyFront = '$pngBasePath/full_body_front.png'; - static const String fullBodyBack = '$pngBasePath/full_body_back.png'; + static const String fullBodyFrontMale = '$pngBasePath/full_body_front_male.png'; + static const String fullBodyBackMale = '$pngBasePath/full_body_back_male.png'; + static const String fullBodyFrontFemale = '$pngBasePath/full_body_front_female.png'; + static const String fullBodyBackFemale = '$pngBasePath/full_body_back_female.png'; static const String bmiFullBody = '$pngBasePath/bmi_image_1.png'; } diff --git a/lib/features/symptoms_checker/data/organ_mapping_data.dart b/lib/features/symptoms_checker/data/organ_mapping_data.dart index c338a94..b0c2ffe 100644 --- a/lib/features/symptoms_checker/data/organ_mapping_data.dart +++ b/lib/features/symptoms_checker/data/organ_mapping_data.dart @@ -1,9 +1,11 @@ +import 'dart:developer'; + import 'package:hmg_patient_app_new/core/enums.dart'; import 'package:hmg_patient_app_new/features/symptoms_checker/models/organ_model.dart'; class OrganData { // ==================== FRONT VIEW ==================== - static const List frontViewOrgans = [ + static const List frontViewOrgansForMale = [ // ========== HEAD & FACE ========== OrganModel( id: 'head', @@ -307,9 +309,313 @@ class OrganData { position: OrganPosition(x: 0.57, y: 0.91), ), ]; + static const List frontViewOrgansForFemale = [ + // ========== HEAD & FACE ========== + OrganModel( + id: 'head', + name: 'whole_head', + nameAr: 'الرأس_كامل', + description: 'Head', + descriptionAr: 'الرأس', + bodyView: BodyView.front, + position: OrganPosition(x: 0.54, y: 0.05), + ), + OrganModel( + id: 'left_eye', + name: 'eyes', + nameAr: 'العيون', + description: 'Left Eye', + descriptionAr: 'العين اليسرى', + bodyView: BodyView.front, + position: OrganPosition(x: 0.49, y: 0.095), + ), + OrganModel( + id: 'right_eye', + name: 'eyes', + nameAr: 'العيون', + description: 'Right Eye', + descriptionAr: 'العين اليمنى', + bodyView: BodyView.front, + position: OrganPosition(x: 0.6, y: 0.095), + ), + OrganModel( + id: 'nose_mouth', + name: 'oral_cavity', + nameAr: 'تجويف_الفم', + description: 'Nose/Mouth', + descriptionAr: 'الأنف/الفم', + bodyView: BodyView.front, + position: OrganPosition(x: 0.54, y: 0.12), + ), + + // ========== NECK ========== + OrganModel( + id: 'throat', + name: 'neck_or_throat', + nameAr: 'الرقبة_أو_الحلق', + description: 'Throat', + descriptionAr: 'الحلق', + bodyView: BodyView.front, + position: OrganPosition(x: 0.54, y: 0.17), + ), + + // ========== SHOULDERS ========== + OrganModel( + id: 'left_shoulder', + name: 'upper_arm', + nameAr: 'الذراع_العلوي', + description: 'Left Shoulder', + descriptionAr: 'الكتف الأيسر', + bodyView: BodyView.front, + position: OrganPosition(x: 0.29, y: 0.22), + ), + OrganModel( + id: 'right_shoulder', + name: 'upper_arm', + nameAr: 'الذراع_العلوي', + description: 'Right Shoulder', + descriptionAr: 'الكتف الأيمن', + bodyView: BodyView.front, + position: OrganPosition(x: 0.75, y: 0.22), + ), + + // ========== CHEST ========== + OrganModel( + id: 'left_chest', + name: 'chest', + nameAr: 'الصدر', + description: 'Left Chest', + descriptionAr: 'الصدر الأيسر', + bodyView: BodyView.front, + position: OrganPosition(x: 0.4, y: 0.22), + ), + OrganModel( + id: 'center_chest', + name: 'chest', + nameAr: 'الصدر', + description: 'Center Chest', + descriptionAr: 'وسط الصدر', + bodyView: BodyView.front, + position: OrganPosition(x: 0.52, y: 0.25), + ), + OrganModel( + id: 'right_chest', + name: 'chest', + nameAr: 'الصدر', + description: 'Right Chest', + descriptionAr: 'الصدر الأيمن', + bodyView: BodyView.front, + position: OrganPosition(x: 0.65, y: 0.22), + ), + + // ========== RIBS ========== + OrganModel( + id: 'left_ribs', + name: 'chest', + nameAr: 'الصدر', + description: 'Left Ribs', + descriptionAr: 'الأضلاع اليسرى', + bodyView: BodyView.front, + position: OrganPosition(x: 0.38, y: 0.35), + ), + OrganModel( + id: 'right_ribs', + name: 'chest', + nameAr: 'الصدر', + description: 'Right Ribs', + descriptionAr: 'الأضلاع اليمنى', + bodyView: BodyView.front, + position: OrganPosition(x: 0.64, y: 0.35), + ), + + // ========== ABDOMEN ========== + OrganModel( + id: 'upper_abdomen', + name: 'upper_abdomen', + nameAr: 'البطن_العلوي', + description: 'Upper Abdomen', + descriptionAr: 'أعلى البطن', + bodyView: BodyView.front, + position: OrganPosition(x: 0.51, y: 0.31), + ), + OrganModel( + id: 'navel', + name: 'mid_abdomen', + nameAr: 'البطن_الأوسط', + description: 'Navel', + descriptionAr: 'السرة', + bodyView: BodyView.front, + position: OrganPosition(x: 0.51, y: 0.38), + ), + OrganModel( + id: 'lower_abdomen', + name: 'lower_abdomen', + nameAr: 'البطن_السفلي', + description: 'Lower Abdomen', + descriptionAr: 'أسفل البطن', + bodyView: BodyView.front, + position: OrganPosition(x: 0.51, y: 0.44), + ), + + // ========== PELVIS ========== + OrganModel( + id: 'left_groin', + name: 'sexual_organs', + nameAr: 'الأعضاء_التناسلية', + description: 'Left Groin', + descriptionAr: 'الفخذ الأيسر', + bodyView: BodyView.front, + position: OrganPosition(x: 0.42, y: 0.49), + ), + OrganModel( + id: 'right_groin', + name: 'sexual_organs', + nameAr: 'الأعضاء_التناسلية', + description: 'Right Groin', + descriptionAr: 'الفخذ الأيمن', + bodyView: BodyView.front, + position: OrganPosition(x: 0.59, y: 0.49), + ), + + // ========== LEFT ARM ========== + + OrganModel( + id: 'left_elbow', + name: 'elbow', + nameAr: 'الكوع', + description: 'Left Elbow', + descriptionAr: 'الكوع الأيسر', + bodyView: BodyView.front, + position: OrganPosition(x: 0.24, y: 0.35), + ), + OrganModel( + id: 'left_forearm', + name: 'forearm', + nameAr: 'الساعد', + description: 'Left Forearm', + descriptionAr: 'الساعد الأيسر', + bodyView: BodyView.front, + position: OrganPosition(x: 0.24, y: 0.43), + ), + OrganModel( + id: 'left_wrist', + name: 'hand', + nameAr: 'اليد', + description: 'Left Wrist', + descriptionAr: 'المعصم الأيسر', + bodyView: BodyView.front, + position: OrganPosition(x: 0.17, y: 0.49), + ), + + // ========== RIGHT ARM ========== + + OrganModel( + id: 'right_elbow', + name: 'elbow', + nameAr: 'الكوع', + description: 'Right Elbow', + descriptionAr: 'الكوع الأيمن', + bodyView: BodyView.front, + position: OrganPosition(x: 0.76, y: 0.35), + ), + OrganModel( + id: 'right_forearm', + name: 'forearm', + nameAr: 'الساعد', + description: 'Right Forearm', + descriptionAr: 'الساعد الأيمن', + bodyView: BodyView.front, + position: OrganPosition(x: 0.76, y: 0.43), + ), + OrganModel( + id: 'right_wrist', + name: 'hand', + nameAr: 'اليد', + description: 'Right Wrist', + descriptionAr: 'المعصم الأيمن', + bodyView: BodyView.front, + position: OrganPosition(x: 0.83, y: 0.5), + ), + + // ========== LEFT LEG ========== + OrganModel( + id: 'left_thigh', + name: 'thigh', + nameAr: 'الفخذ', + description: 'Left Thigh', + descriptionAr: 'الفخذ الأيسر', + bodyView: BodyView.front, + position: OrganPosition(x: 0.4, y: 0.60), + ), + OrganModel( + id: 'left_knee', + name: 'knee', + nameAr: 'الركبة', + description: 'Left Knee', + descriptionAr: 'الركبة اليسرى', + bodyView: BodyView.front, + position: OrganPosition(x: 0.4, y: 0.72), + ), + OrganModel( + id: 'left_shin', + name: 'lower_leg', + nameAr: 'الساق_السفلي', + description: 'Left Shin', + descriptionAr: 'الساق اليسرى', + bodyView: BodyView.front, + position: OrganPosition(x: 0.41, y: 0.82), + ), + OrganModel( + id: 'left_ankle', + name: 'foot', + nameAr: 'القدم', + description: 'Left Ankle', + descriptionAr: 'الكاحل الأيسر', + bodyView: BodyView.front, + position: OrganPosition(x: 0.43, y: 0.91), + ), + + // ========== RIGHT LEG ========== + OrganModel( + id: 'right_thigh', + name: 'thigh', + nameAr: 'الفخذ', + description: 'Right Thigh', + descriptionAr: 'الفخذ الأيمن', + bodyView: BodyView.front, + position: OrganPosition(x: 0.65, y: 0.60), + ), + OrganModel( + id: 'right_knee', + name: 'knee', + nameAr: 'الركبة', + description: 'Right Knee', + descriptionAr: 'الركبة اليمنى', + bodyView: BodyView.front, + position: OrganPosition(x: 0.6, y: 0.72), + ), + OrganModel( + id: 'right_shin', + name: 'lower_leg', + nameAr: 'الساق_السفلي', + description: 'Right Shin', + descriptionAr: 'الساق اليمنى', + bodyView: BodyView.front, + position: OrganPosition(x: 0.59, y: 0.82), + ), + OrganModel( + id: 'right_ankle', + name: 'foot', + nameAr: 'القدم', + description: 'Right Ankle', + descriptionAr: 'الكاحل الأيمن', + bodyView: BodyView.front, + position: OrganPosition(x: 0.57, y: 0.91), + ), + ]; // ==================== BACK VIEW ==================== - static const List backViewOrgans = [ + static const List backViewOrgansForMale = [ // ========== HEAD & NECK ========== OrganModel( id: 'back_of_head', @@ -504,19 +810,232 @@ class OrganData { position: OrganPosition(x: 0.57, y: 0.79), ), ]; + static const List backViewOrgansForFemale = [ + // ========== HEAD & NECK ========== + OrganModel( + id: 'back_of_head', + name: 'whole_head', + nameAr: 'الرأس_كامل', + description: 'Back of Head', + descriptionAr: 'مؤخرة الرأس', + bodyView: BodyView.back, + position: OrganPosition(x: 0.48, y: 0.055), + ), + OrganModel( + id: 'neck_back', + name: 'nape_of_neck', + nameAr: 'مؤخرة_الرقبة', + description: 'Neck', + descriptionAr: 'الرقبة', + bodyView: BodyView.back, + position: OrganPosition(x: 0.50, y: 0.14), + ), + + // ========== SHOULDERS ========== + OrganModel( + id: 'left_shoulder_back', + name: 'upper_arm', + nameAr: 'الذراع_العلوي', + description: 'Left Shoulder', + descriptionAr: 'الكتف الأيسر', + bodyView: BodyView.back, + position: OrganPosition(x: 0.3, y: 0.2), + ), + OrganModel( + id: 'right_shoulder_back', + name: 'upper_arm', + nameAr: 'الذراع_العلوي', + description: 'Right Shoulder', + descriptionAr: 'الكتف الأيمن', + bodyView: BodyView.back, + position: OrganPosition(x: 0.69, y: 0.2), + ), + + // ========== UPPER BACK ========== + OrganModel( + id: 'upper_spine', + name: 'back', + nameAr: 'الظهر', + description: 'Upper Spine', + descriptionAr: 'العمود الفقري العلوي', + bodyView: BodyView.back, + position: OrganPosition(x: 0.50, y: 0.23), + ), + OrganModel( + id: 'left_upper_back', + name: 'back', + nameAr: 'الظهر', + description: 'Left Upper Back', + descriptionAr: 'أعلى الظهر الأيسر', + bodyView: BodyView.back, + position: OrganPosition(x: 0.38, y: 0.28), + ), + OrganModel( + id: 'right_upper_back', + name: 'back', + nameAr: 'الظهر', + description: 'Right Upper Back', + descriptionAr: 'أعلى الظهر الأيمن', + bodyView: BodyView.back, + position: OrganPosition(x: 0.62, y: 0.28), + ), + + // ========== MID BACK ========== + OrganModel( + id: 'mid_spine', + name: 'back', + nameAr: 'الظهر', + description: 'Mid Spine', + descriptionAr: 'العمود الفقري الأوسط', + bodyView: BodyView.back, + position: OrganPosition(x: 0.50, y: 0.35), + ), + OrganModel( + id: 'left_mid_back', + name: 'back', + nameAr: 'الظهر', + description: 'Left Mid Back', + descriptionAr: 'وسط الظهر الأيسر', + bodyView: BodyView.back, + position: OrganPosition(x: 0.38, y: 0.35), + ), + OrganModel( + id: 'right_mid_back', + name: 'back', + nameAr: 'الظهر', + description: 'Right Mid Back', + descriptionAr: 'وسط الظهر الأيمن', + bodyView: BodyView.back, + position: OrganPosition(x: 0.62, y: 0.35), + ), + + // ========== LOWER BACK ========== + OrganModel( + id: 'lower_spine', + name: 'lower_back', + nameAr: 'أسفل_الظهر', + description: 'Lower Back', + descriptionAr: 'أسفل الظهر', + bodyView: BodyView.back, + position: OrganPosition(x: 0.50, y: 0.43), + ), + OrganModel( + id: 'left_lower_back', + name: 'lower_back', + nameAr: 'أسفل_الظهر', + description: 'Left Lower Back', + descriptionAr: 'أسفل الظهر الأيسر', + bodyView: BodyView.back, + position: OrganPosition(x: 0.36, y: 0.43), + ), + OrganModel( + id: 'right_lower_back', + name: 'lower_back', + nameAr: 'أسفل_الظهر', + description: 'Right Lower Back', + descriptionAr: 'أسفل الظهر الأيمن', + bodyView: BodyView.back, + position: OrganPosition(x: 0.65, y: 0.43), + ), + + // ========== GLUTES ========== + OrganModel( + id: 'sacrum', + name: 'lower_back', + nameAr: 'أسفل_الظهر', + description: 'Sacrum', + descriptionAr: 'العجز', + bodyView: BodyView.back, + position: OrganPosition(x: 0.50, y: 0.5), + ), + OrganModel( + id: 'left_glute', + name: 'buttocks', + nameAr: 'الأرداف', + description: 'Left Glute', + descriptionAr: 'الأرداف اليسرى', + bodyView: BodyView.back, + position: OrganPosition(x: 0.36, y: 0.52), + ), + OrganModel( + id: 'right_glute', + name: 'buttocks', + nameAr: 'الأرداف', + description: 'Right Glute', + descriptionAr: 'الأرداف اليمنى', + bodyView: BodyView.back, + position: OrganPosition(x: 0.61, y: 0.52), + ), + + // ========== LEGS ========== + OrganModel( + id: 'left_hamstring', + name: 'thigh', + nameAr: 'الفخذ', + description: 'Left Hamstring', + descriptionAr: 'عضلة الفخذ الخلفية اليسرى', + bodyView: BodyView.back, + position: OrganPosition(x: 0.41, y: 0.62), + ), + OrganModel( + id: 'right_hamstring', + name: 'thigh', + nameAr: 'الفخذ', + description: 'Right Hamstring', + descriptionAr: 'عضلة الفخذ الخلفية اليمنى', + bodyView: BodyView.back, + position: OrganPosition(x: 0.62, y: 0.62), + ), + OrganModel( + id: 'left_calf', + name: 'lower_leg', + nameAr: 'الساق_السفلي', + description: 'Left Calf', + descriptionAr: 'ربلة الساق اليسرى', + bodyView: BodyView.back, + position: OrganPosition(x: 0.43, y: 0.79), + ), + OrganModel( + id: 'right_calf', + name: 'lower_leg', + nameAr: 'الساق_السفلي', + description: 'Right Calf', + descriptionAr: 'ربلة الساق اليمنى', + bodyView: BodyView.back, + position: OrganPosition(x: 0.57, y: 0.79), + ), + ]; // Helper methods - static List getOrgansForView(BodyView view) { - return view == BodyView.front ? frontViewOrgans : backViewOrgans; + // Accept genderKey (e.g., 'male' / 'female' or Arabic 'ذكر' / 'أنثى') to return gender-specific organ sets + static List getOrgansForView(BodyView view, {String? genderKey}) { + final bool isFemale = genderKey != null && (genderKey.toLowerCase() == 'female' || genderKey == 'أنثى' || genderKey == '2'); + + + if (view == BodyView.front) { + return isFemale ? frontViewOrgansForFemale : frontViewOrgansForMale; + } else { + return isFemale ? backViewOrgansForFemale : backViewOrgansForMale; + } } - static List getAllOrgans() { - return [...frontViewOrgans, ...backViewOrgans]; + /// Return all organs (front + back) for the selected gender. + /// If genderKey is null, default to male to preserve previous behavior. + static List getAllOrgans({String? genderKey}) { + final bool isFemale = genderKey != null && (genderKey.toLowerCase() == 'female' || genderKey == 'أنثى' || genderKey == '2'); + + if (isFemale) { + return [...frontViewOrgansForFemale, ...backViewOrgansForFemale]; + } + + // default: male + return [...frontViewOrgansForMale, ...backViewOrgansForMale]; } - static OrganModel? getOrganById(String id) { + /// Find organ by id within the organs of the selected gender (or male if not specified) + static OrganModel? getOrganById(String id, {String? genderKey}) { try { - return getAllOrgans().firstWhere((organ) => organ.id == id); + return getAllOrgans(genderKey: genderKey).firstWhere((organ) => organ.id == id); } catch (e) { return null; } diff --git a/lib/features/symptoms_checker/symptoms_checker_view_model.dart b/lib/features/symptoms_checker/symptoms_checker_view_model.dart index 668b302..6670670 100644 --- a/lib/features/symptoms_checker/symptoms_checker_view_model.dart +++ b/lib/features/symptoms_checker/symptoms_checker_view_model.dart @@ -175,14 +175,11 @@ class SymptomsCheckerViewModel extends ChangeNotifier { } /// Get organs for current view - List get currentOrgans => OrganData.getOrgansForView(_currentView); + List get currentOrgans => OrganData.getOrgansForView(_currentView, genderKey: _selectedGender); - /// Get all selected organs from both views + /// Get all selected organs from both views (for the selected gender) List get selectedOrgans { - final allOrgans = [ - ...OrganData.frontViewOrgans, - ...OrganData.backViewOrgans, - ]; + final allOrgans = OrganData.getAllOrgans(genderKey: _selectedGender); return allOrgans.where((organ) => _selectedOrganIds.contains(organ.id)).toList(); } diff --git a/lib/presentation/symptoms_checker/organ_selector_screen.dart b/lib/presentation/symptoms_checker/organ_selector_screen.dart index 9a4a1d9..253fccd 100644 --- a/lib/presentation/symptoms_checker/organ_selector_screen.dart +++ b/lib/presentation/symptoms_checker/organ_selector_screen.dart @@ -142,15 +142,27 @@ class _OrganSelectorPageState extends State { transitionBuilder: (child, animation) => _build3DFlipTransition(child, animation), switchInCurve: Curves.easeInOut, switchOutCurve: Curves.easeInOut, - child: InteractiveBodyWidget( + child: Builder( key: ValueKey(viewModel.currentView), - bodyImageAsset: viewModel.currentView == BodyView.front ? AppAssets.fullBodyFront : AppAssets.fullBodyBack, - organs: viewModel.currentOrgans, - selectedOrganIds: viewModel.selectedOrganIds, - onOrganTap: viewModel.toggleOrganSelection, - isBodyHidden: viewModel.isBodyHidden, - tooltipOrganId: viewModel.tooltipOrganId, - isArabic: _appState.isArabic(), + builder: (context) { + // Detect female gender from viewModel; allow Arabic value as fallback + final bool isFemale = + (viewModel.selectedGender != null && (viewModel.selectedGender!.toLowerCase() == 'female' || viewModel.selectedGender == 'أنثى')); + + final String bodyAsset = viewModel.currentView == BodyView.front + ? (isFemale ? AppAssets.fullBodyFrontFemale : AppAssets.fullBodyFrontMale) + : (isFemale ? AppAssets.fullBodyBackFemale : AppAssets.fullBodyBackMale); + + return InteractiveBodyWidget( + bodyImageAsset: bodyAsset, + organs: viewModel.currentOrgans, + selectedOrganIds: viewModel.selectedOrganIds, + onOrganTap: viewModel.toggleOrganSelection, + isBodyHidden: viewModel.isBodyHidden, + tooltipOrganId: viewModel.tooltipOrganId, + isArabic: _appState.isArabic(), + ); + }, ), ), ), diff --git a/lib/presentation/symptoms_checker/user_info_selection/pages/height_selection_page.dart b/lib/presentation/symptoms_checker/user_info_selection/pages/height_selection_page.dart index f9f2d00..ce8087d 100644 --- a/lib/presentation/symptoms_checker/user_info_selection/pages/height_selection_page.dart +++ b/lib/presentation/symptoms_checker/user_info_selection/pages/height_selection_page.dart @@ -1,9 +1,6 @@ -import 'dart:developer'; - import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_export.dart'; -import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/symptoms_checker/symptoms_checker_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; @@ -154,6 +151,7 @@ class HeightSelectionPage extends StatelessWidget { ), Expanded( child: HeightScale( + key: ValueKey(viewModel.isHeightCm), enableHaptic: true, enableSound: true, minValue: minValue, @@ -161,7 +159,6 @@ class HeightSelectionPage extends StatelessWidget { initialHeight: (viewModel.selectedHeight ?? 100).toDouble(), isCm: viewModel.isHeightCm, onHeightChanged: (newHeight) { - log("height: $newHeight"); viewModel.setHeight(newHeight, viewModel.isHeightCm); }, ), diff --git a/lib/presentation/symptoms_checker/user_info_selection/widgets/height_scale.dart b/lib/presentation/symptoms_checker/user_info_selection/widgets/height_scale.dart index 29baf64..e09380e 100644 --- a/lib/presentation/symptoms_checker/user_info_selection/widgets/height_scale.dart +++ b/lib/presentation/symptoms_checker/user_info_selection/widgets/height_scale.dart @@ -43,10 +43,17 @@ class _HeightScaleState extends State { // Get increment based on unit (CM = 1.0, FT = 0.1) double get _increment => widget.isCm ? 1.0 : 0.1; + late final int _childCount; + @override void initState() { super.initState(); + // prepare child count and initial index using normal order (min at index 0) + _childCount = ((widget.maxValue - widget.minValue) / _increment).round() + 1; + // initialIndex should point to position of initialHeight in normal list int initialIndex = ((widget.initialHeight - widget.minValue) / _increment).round(); + if (initialIndex < 0) initialIndex = 0; + if (initialIndex >= _childCount) initialIndex = _childCount - 1; _scrollController = FixedExtentScrollController(initialItem: initialIndex); } @@ -95,19 +102,21 @@ class _HeightScaleState extends State { perspective: 0.001, physics: const BouncingScrollPhysics(), onSelectedItemChanged: (index) { + // Map index (0..n-1) to value normal: value = min + index*increment final selectedValue = widget.minValue + (index * _increment); widget.onHeightChanged?.call(selectedValue); _scheduleFeedback(); }, childDelegate: ListWheelChildBuilderDelegate( - childCount: ((widget.maxValue - widget.minValue) / _increment).round() + 1, + childCount: _childCount, builder: (context, index) { + // Displayed height value for this index (normal order) final height = widget.minValue + (index * _increment); // For CM: main mark every 10, mid mark every 5 // For FT: main mark every 1.0 (10 ticks), mid mark every 0.5 (5 ticks) - final isMainMark = widget.isCm ? height % 10 == 0 : (height * 10).round() % 10 == 0; - final isMidMark = widget.isCm ? height % 5 == 0 : (height * 10).round() % 5 == 0; + final isMainMark = widget.isCm ? height.round() % 10 == 0 : ((height * 10).round() % 10 == 0); + final isMidMark = widget.isCm ? height.round() % 5 == 0 : ((height * 10).round() % 5 == 0); return SizedBox( width: 100.w, diff --git a/lib/splashPage.dart b/lib/splashPage.dart index 49680a2..dc7a7c9 100644 --- a/lib/splashPage.dart +++ b/lib/splashPage.dart @@ -47,6 +47,7 @@ class _SplashScreenState extends State { PushNotificationHandler().init(context); // Asyncronously }, ); + // TODO: This next line should be tested. This stops the app at this step, sometimes await authVm.getServicePrivilege(); Timer(Duration(seconds: 2, milliseconds: 500), () async { bool isAppOpenedFromCall = getIt.get().getBool(key: CacheConst.isAppOpenedFromCall) ?? false;