From 7fed1c58f3716468f92dc5115093c5a0eb6696ba Mon Sep 17 00:00:00 2001 From: mosazaid Date: Mon, 21 Jun 2021 09:21:21 +0300 Subject: [PATCH 001/289] working to open video stream from service --- android/app/src/main/AndroidManifest.xml | 3 + .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 73 ++++++++++++++--- .../Service/VideoStreamContainerService.kt | 30 +++++++ .../hmgDr/ui/fragment/VideoCallFragment.kt | 33 ++++++-- lib/core/service/VideoCallService.dart | 80 ++++++++++++------- .../viewModel/authentication_view_model.dart | 2 +- .../patient_profile_screen.dart | 11 +-- 7 files changed, 178 insertions(+), 54 deletions(-) create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamContainerService.kt diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index bf0d3766..0ac76ea8 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -40,6 +40,9 @@ + + + 60dp 54dp - 52dp + 48dp 24dp @@ -33,9 +33,15 @@ 4dp - 8sp + 8dp 16dp 24dp + 36dp + 60dp + 80dp + 40dp + + diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml index e13b5b14..dae5749f 100644 --- a/android/app/src/main/res/values/styles.xml +++ b/android/app/src/main/res/values/styles.xml @@ -1,10 +1,12 @@ + + @@ -25,12 +27,17 @@ true - true + true + true + false @null match_parent match_parent + + @android:style/Animation.Dialog + From a7c5e1afde3633edbf5af998d74ee67d7a2efede Mon Sep 17 00:00:00 2001 From: mosazaid Date: Sun, 27 Jun 2021 17:50:08 +0300 Subject: [PATCH 021/289] finish solve keybaord issue --- .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 83 ++++++++++--------- lib/core/service/VideoCallService.dart | 13 ++- .../viewModel/authentication_view_model.dart | 2 +- .../live_care/live_care_patient_screen.dart | 30 +++---- .../patient_profile_screen.dart | 11 ++- 5 files changed, 69 insertions(+), 70 deletions(-) diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt index f14dd823..f8b3f3ae 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -16,6 +16,7 @@ import com.hmg.hmgDr.Model.GetSessionStatusModel import com.hmg.hmgDr.Model.SessionStatusModel import com.hmg.hmgDr.Service.VideoStreamContainerService import com.hmg.hmgDr.ui.VideoCallResponseListener +import com.hmg.hmgDr.ui.fragment.VideoCallFragment import io.flutter.embedding.android.FlutterFragmentActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodCall @@ -32,6 +33,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, private var call: MethodCall? = null private val LAUNCH_VIDEO: Int = 1 + private var dialogFragment: VideoCallFragment? = null private var serviceIntent: Intent? = null private var videoStreamService: VideoStreamContainerService? = null private var bound = false @@ -105,7 +107,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, putExtras(arguments) startService(this) } - bindService() +// bindService() } /* override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { @@ -135,9 +137,8 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, }*/ override fun onCallFinished(resultCode: Int, intent: Intent?) { - // TODO uncomment it - /*if (resultCode == Activity.RESULT_OK) { + if (resultCode == Activity.RESULT_OK) { val result: SessionStatusModel? = intent?.getParcelableExtra("sessionStatusNotRespond") val callResponse: HashMap = HashMap() @@ -162,10 +163,10 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, Log.e("onVideoCallFinished", "${e.message}.") } } - */ - stopService(serviceIntent) - unbindService() - videoStreamService!!.serviceRunning = false + +// stopService(serviceIntent) +// unbindService() +// videoStreamService!!.serviceRunning = false } override fun minimizeVideoEvent(isMinimize: Boolean) { @@ -189,40 +190,40 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, // unbindService() // } - private fun bindService() { - serviceIntent?.run { - if (videoStreamService != null && !videoStreamService!!.serviceRunning){ - startService(this) - } - bindService(this, serviceConnection, Context.BIND_AUTO_CREATE) - videoStreamService?.serviceRunning = true - } - } - - private fun unbindService() { - if (bound) { - videoStreamService!!.videoCallResponseListener = null // unregister - videoStreamService!!.mActivity = null - unbindService(serviceConnection) - bound = false - } - } - - private val serviceConnection: ServiceConnection = object : ServiceConnection { - override fun onServiceConnected(name: ComponentName?, service: IBinder?) { - val binder: VideoStreamContainerService.VideoStreamBinder = - service as VideoStreamContainerService.VideoStreamBinder - videoStreamService = binder.service - bound = true - videoStreamService!!.videoCallResponseListener = this@MainActivity // register - videoStreamService!!.mActivity = this@MainActivity // register - } - - override fun onServiceDisconnected(name: ComponentName?) { - bound = false - } - - } +// private fun bindService() { +// serviceIntent?.run { +// if (videoStreamService != null && !videoStreamService!!.serviceRunning){ +// startService(this) +// } +// bindService(this, serviceConnection, Context.BIND_AUTO_CREATE) +// videoStreamService?.serviceRunning = true +// } +// } +// +// private fun unbindService() { +// if (bound) { +// videoStreamService!!.videoCallResponseListener = null // unregister +// videoStreamService!!.mActivity = null +// unbindService(serviceConnection) +// bound = false +// } +// } +// +// private val serviceConnection: ServiceConnection = object : ServiceConnection { +// override fun onServiceConnected(name: ComponentName?, service: IBinder?) { +// val binder: VideoStreamContainerService.VideoStreamBinder = +// service as VideoStreamContainerService.VideoStreamBinder +// videoStreamService = binder.service +// bound = true +// videoStreamService!!.videoCallResponseListener = this@MainActivity // register +// videoStreamService!!.mActivity = this@MainActivity // register +// } +// +// override fun onServiceDisconnected(name: ComponentName?) { +// bound = false +// } +// +// } // code to hide soft keyboard fun hideSoftKeyBoard(editBox: EditText?) { diff --git a/lib/core/service/VideoCallService.dart b/lib/core/service/VideoCallService.dart index 82ace4b4..58caf079 100644 --- a/lib/core/service/VideoCallService.dart +++ b/lib/core/service/VideoCallService.dart @@ -29,13 +29,12 @@ class VideoCallService extends BaseService { DoctorProfileModel doctorProfile = await getDoctorProfile(isGetProfile: true); await VideoChannel.openVideoCallScreen( - kToken: - "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==", - // startCallRes.openTokenID, - kSessionId: - "1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg", - //startCallRes.openSessionID, - kApiKey: '47247954',//'46209962' + kToken: startCallRes.openTokenID, + // "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==", + kSessionId: startCallRes.openSessionID, + // "1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg", + + kApiKey:'46209962', //'47247954', vcId: patient.vcId, patientName: patient.fullName ?? (patient.firstName != null diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index a161c861..cae415da 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -255,7 +255,7 @@ class AuthenticationViewModel extends BaseViewModel { /// add  token to shared preferences in case of send activation code is success setDataAfterSendActivationSuccess(SendActivationCodeForDoctorAppResponseModel sendActivationCodeForDoctorAppResponseModel) { print("VerificationCode : " + sendActivationCodeForDoctorAppResponseModel.verificationCode); - DrAppToastMsg.showSuccesToast("VerificationCode : " + sendActivationCodeForDoctorAppResponseModel.verificationCode); + // DrAppToastMsg.showSuccesToast("_VerificationCode_ : " + sendActivationCodeForDoctorAppResponseModel.verificationCode); sharedPref.setString(VIDA_AUTH_TOKEN_ID, sendActivationCodeForDoctorAppResponseModel.vidaAuthTokenID); sharedPref.setString(VIDA_REFRESH_TOKEN_ID, diff --git a/lib/screens/live_care/live_care_patient_screen.dart b/lib/screens/live_care/live_care_patient_screen.dart index 100679cc..911687c9 100644 --- a/lib/screens/live_care/live_care_patient_screen.dart +++ b/lib/screens/live_care/live_care_patient_screen.dart @@ -173,21 +173,21 @@ class _LiveCarePatientScreenState extends State { child: AppLoaderWidget( containerColor: Colors.transparent, )), - AppButton( - fontWeight: FontWeight.w700, - color:Colors.green[600], - title: TranslationBase.of(context).initiateCall, - disabled: model.state == ViewState.BusyLocal, - onPressed: () async { - AppPermissionsUtils.requestVideoCallPermission(context: context,onTapGrant: (){ - locator().openVideo(model.startCallRes, PatiantInformtion( - vcId: 454353, - fullName: "test mosa" - ), callConnected, callDisconnected); - }); - - }, - ), + // AppButton( + // fontWeight: FontWeight.w700, + // color:Colors.green[600], + // title: TranslationBase.of(context).initiateCall, + // disabled: model.state == ViewState.BusyLocal, + // onPressed: () async { + // AppPermissionsUtils.requestVideoCallPermission(context: context,onTapGrant: (){ + // locator().openVideo(model.startCallRes, PatiantInformtion( + // vcId: 454353, + // fullName: "test mosa" + // ), callConnected, callDisconnected); + // }); + // + // }, + // ), ], ), ), diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index 19dd6b98..4dc49b15 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -306,12 +306,11 @@ class _PatientProfileScreenState extends State with Single // builder: (BuildContext context) => // EndCallScreen(patient:patient))); - // TODO MOSA REMOVE THIS - AppPermissionsUtils.requestVideoCallPermission(context: context,onTapGrant: (){ - locator().openVideo(model.startCallRes, patient, callConnected, callDisconnected); - }); + // AppPermissionsUtils.requestVideoCallPermission(context: context,onTapGrant: (){ + // locator().openVideo(model.startCallRes, patient, callConnected, callDisconnected); + // }); - /* if(isCallFinished) { + if(isCallFinished) { Navigator.push(context, MaterialPageRoute( builder: (BuildContext context) => EndCallScreen(patient:patient))); } else { @@ -333,7 +332,7 @@ class _PatientProfileScreenState extends State with Single locator().openVideo(model.startCallRes, patient, callConnected, callDisconnected); }); } - }*/ + } }, ), From 783c74108b81221ae6ed64642603fe64c8408892 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Mon, 28 Jun 2021 10:52:28 +0300 Subject: [PATCH 022/289] video isRecord change --- android/app/src/main/res/layout/activity_video_call.xml | 2 +- .../profile/profile_screen/patient_profile_screen.dart | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/android/app/src/main/res/layout/activity_video_call.xml b/android/app/src/main/res/layout/activity_video_call.xml index 8dc33094..03c55729 100644 --- a/android/app/src/main/res/layout/activity_video_call.xml +++ b/android/app/src/main/res/layout/activity_video_call.xml @@ -121,8 +121,8 @@ android:id="@+id/record_icon" android:layout_width="@dimen/local_back_icon_size" android:layout_height="@dimen/local_back_icon_size" - android:layout_gravity="center" android:scaleType="centerCrop" + android:layout_margin="5dp" android:src="@drawable/ic_record" /> diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index d8410da1..a1da7882 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -309,7 +309,7 @@ class _PatientProfileScreenState extends State with Single // .openVideo( // model.startCallRes, // patient, - // false, callConnected, // model.startCallRes.isRecording + // model.startCallRes != null ? model.startCallRes.isRecording : true, callConnected, // callDisconnected); // }); if (isCallFinished) { @@ -349,7 +349,7 @@ class _PatientProfileScreenState extends State with Single .openVideo( model.startCallRes, patient, - /*model.startCallRes != null ? model.startCallRes.isRecording : */ true + model.startCallRes != null ? model.startCallRes.isRecording : true , callConnected, callDisconnected); }); From 1e35b70b010d716930053baf45c973f811cb2a7a Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Mon, 28 Jun 2021 12:13:40 +0300 Subject: [PATCH 023/289] medical report fix --- .../PatientMedicalReportViewModel.dart | 19 +- lib/core/viewModel/base_view_model.dart | 14 +- lib/locator.dart | 2 +- .../AddVerifyMedicalReport.dart | 215 ++++++++++-------- .../medical_report/MedicalReportPage.dart | 57 +++-- 5 files changed, 168 insertions(+), 139 deletions(-) diff --git a/lib/core/viewModel/PatientMedicalReportViewModel.dart b/lib/core/viewModel/PatientMedicalReportViewModel.dart index 7866fa69..ac5ecdeb 100644 --- a/lib/core/viewModel/PatientMedicalReportViewModel.dart +++ b/lib/core/viewModel/PatientMedicalReportViewModel.dart @@ -24,19 +24,8 @@ class PatientMedicalReportViewModel extends BaseViewModel { setState(ViewState.Idle); } - bool hasOnHold() { - bool hasHold = false; - medicalReportList.forEach((element) { - if (element.status == 1) { - hasHold = true; - } - }); - - return hasHold; - } - Future getMedicalReportTemplate() async { - setState(ViewState.BusyLocal); + setState(ViewState.Busy); await _service.getMedicalReportTemplate(); if (_service.hasError) { error = _service.error; @@ -62,7 +51,7 @@ class PatientMedicalReportViewModel extends BaseViewModel { error = _service.error; setState(ViewState.ErrorLocal); } else - getMedicalReportList(patient); + await getMedicalReportList(patient); setState(ViewState.Idle); } @@ -73,7 +62,7 @@ class PatientMedicalReportViewModel extends BaseViewModel { error = _service.error; setState(ViewState.ErrorLocal); } else - getMedicalReportList(patient); + await getMedicalReportList(patient); setState(ViewState.Idle); } @@ -84,7 +73,7 @@ class PatientMedicalReportViewModel extends BaseViewModel { error = _service.error; setState(ViewState.ErrorLocal); } else - getMedicalReportList(patient); + await getMedicalReportList(patient); setState(ViewState.Idle); } } diff --git a/lib/core/viewModel/base_view_model.dart b/lib/core/viewModel/base_view_model.dart index 9d7032aa..794706a6 100644 --- a/lib/core/viewModel/base_view_model.dart +++ b/lib/core/viewModel/base_view_model.dart @@ -19,12 +19,12 @@ class BaseViewModel extends ChangeNotifier { void setState(ViewState viewState) { _state = viewState; + notifyListeners(); } Future getDoctorProfile({bool isGetProfile = false}) async { - if(isGetProfile) - { + if (isGetProfile) { Map profile = await sharedPref.getObj(DOCTOR_PROFILE); if (profile != null) { doctorProfile = DoctorProfileModel.fromJson(profile); @@ -46,10 +46,10 @@ class BaseViewModel extends ChangeNotifier { return doctorProfile; } } - - setDoctorProfile(DoctorProfileModel doctorProfile)async { - await sharedPref.setObj(DOCTOR_PROFILE, doctorProfile); - this.doctorProfile = doctorProfile; - notifyListeners(); + + setDoctorProfile(DoctorProfileModel doctorProfile) async { + await sharedPref.setObj(DOCTOR_PROFILE, doctorProfile); + this.doctorProfile = doctorProfile; + notifyListeners(); } } diff --git a/lib/locator.dart b/lib/locator.dart index e2c578df..d74fad8b 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -124,6 +124,6 @@ void setupLocator() { locator.registerFactory(() => PatientSearchViewModel()); locator.registerFactory(() => HospitalViewModel()); locator.registerFactory(() => LiveCarePatientViewModel()); - locator.registerLazySingleton(() => PatientMedicalReportViewModel()); + locator.registerFactory(() => PatientMedicalReportViewModel()); locator.registerFactory(() => ScanQrViewModel()); } diff --git a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart index 304b39ac..4a6be6c8 100644 --- a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart +++ b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart @@ -1,13 +1,10 @@ import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/PatientMedicalReportViewModel.dart'; -import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/patient/MedicalReport/MeidcalReportModel.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; -import 'package:doctor_app_flutter/screens/patients/profile/medical_report/MedicalReportPage.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_loader_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; @@ -15,9 +12,27 @@ import 'package:doctor_app_flutter/widgets/shared/text_fields/html_rich_editor.d import 'package:flutter/material.dart'; import 'package:html_editor_enhanced/html_editor.dart'; import 'package:permission_handler/permission_handler.dart'; -import 'package:provider/provider.dart'; class AddVerifyMedicalReport extends StatefulWidget { + final PatiantInformtion patient; + final String patientType; + final String arrivalType; + final MedicalReportModel medicalReport; + final PatientMedicalReportViewModel model; + final MedicalReportStatus status; + final String medicalNote; + + const AddVerifyMedicalReport( + {Key key, + this.patient, + this.patientType, + this.arrivalType, + this.medicalReport, + this.model, + this.status, + this.medicalNote}) + : super(key: key); + @override _AddVerifyMedicalReportState createState() => _AddVerifyMedicalReportState(); } @@ -25,121 +40,121 @@ class AddVerifyMedicalReport extends StatefulWidget { class _AddVerifyMedicalReportState extends State { @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); - final routeArgs = ModalRoute.of(context).settings.arguments as Map; - PatientMedicalReportViewModel patientMedicalReportViewModel = routeArgs['model']; - PatiantInformtion patient = routeArgs['patient']; - MedicalReportStatus status = routeArgs['status'] as MedicalReportStatus; - MedicalReportModel medicalReport = routeArgs.containsKey("medicalReport") ? routeArgs['medicalReport'] : null; + String txtOfMedicalReport; return BaseView( - onModelReady: (_) => patientMedicalReportViewModel.getMedicalReportTemplate(), + onModelReady: (model) async {}, builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, - appBarTitle: status == MedicalReportStatus.ADD + appBarTitle: widget.status == MedicalReportStatus.ADD ? TranslationBase.of(context).medicalReportAdd : TranslationBase.of(context).medicalReportVerify, backgroundColor: Theme.of(context).scaffoldBackgroundColor, - body: model.state == ViewState.BusyLocal - ? AppLoaderWidget() - : Column( - children: [ - Expanded( - child: Container( - margin: EdgeInsets.all(16), - child: Column( - children: [ - Expanded( - child: SingleChildScrollView( - child: Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // if (model.medicalReportTemplate.length > 0) - HtmlRichEditor( - initialText: (medicalReport != null - ? medicalReport.reportDataHtml - : model.medicalReportTemplate[0].templateText.length > 0 - ? model.medicalReportTemplate[0].templateText - : ""), - hint: "Write the medical report ", - height: MediaQuery.of(context).size.height * 0.75, - ), - ], + body: Column( + children: [ + Expanded( + child: Container( + margin: EdgeInsets.all(16), + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (model.medicalReportTemplate.length > 0) + HtmlRichEditor( + initialText: (widget.medicalReport != null + ? widget.medicalNote + : widget.model.medicalReportTemplate[0].templateText.length > 0 + ? widget.model.medicalReportTemplate[0].templateText + : ""), + hint: "Write the medical report ", + height: MediaQuery.of(context).size.height * 0.75, ), - ), - ), + ], ), - ], + ), ), ), - ), - Container( - padding: EdgeInsets.all(16.0), - color: Colors.white, - child: Row( - children: [ - Expanded( - child: AppButton( - title: status == MedicalReportStatus.ADD - ? TranslationBase.of(context).save - : TranslationBase.of(context).save, - color: Color(0xffEAEAEA), - fontColor: Colors.black, - // disabled: progressNoteController.text.isEmpty, - fontWeight: FontWeight.w700, - onPressed: () async { - String txtOfMedicalReport = await HtmlEditor.getText(); + ], + ), + ), + ), + Container( + padding: EdgeInsets.all(16.0), + color: Colors.white, + child: Row( + children: [ + Expanded( + child: AppButton( + title: widget.status == MedicalReportStatus.ADD + ? TranslationBase.of(context).save + : TranslationBase.of(context).save, + color: Color(0xffEAEAEA), + fontColor: Colors.black, + // disabled: progressNoteController.text.isEmpty, + fontWeight: FontWeight.w700, + onPressed: () async { + txtOfMedicalReport = await HtmlEditor.getText(); - if (txtOfMedicalReport.isNotEmpty) { - GifLoaderDialogUtils.showMyDialog(context); - medicalReport != null - ? model.updateMedicalReport( - patient, - txtOfMedicalReport, - medicalReport != null ? medicalReport.lineItemNo : null, - medicalReport != null ? medicalReport.invoiceNo : null) - : model.addMedicalReport(patient, txtOfMedicalReport); - //model.getMedicalReportList(patient); + if (txtOfMedicalReport.isNotEmpty) { + GifLoaderDialogUtils.showMyDialog(context); + widget.medicalReport != null + ? widget.model.updateMedicalReport( + widget.patient, + txtOfMedicalReport, + widget.medicalReport != null ? widget.medicalReport.lineItemNo : null, + widget.medicalReport != null ? widget.medicalReport.invoiceNo : null) + : widget.model.addMedicalReport(widget.patient, txtOfMedicalReport); + //model.getMedicalReportList(patient); - Navigator.pop(context); + Navigator.pop(context); - GifLoaderDialogUtils.hideDialog(context); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } - } - }, - ), - ), - SizedBox( - width: 8, - ), - if (medicalReport != null) - Expanded( - child: AppButton( - title: status == MedicalReportStatus.ADD - ? TranslationBase.of(context).add - : TranslationBase.of(context).verify, - color: Color(0xff359846), - fontWeight: FontWeight.w700, - onPressed: () async { - GifLoaderDialogUtils.showMyDialog(context); - await model.verifyMedicalReport(patient, medicalReport); - GifLoaderDialogUtils.hideDialog(context); - Navigator.pop(context); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } - }, - ), - ), - ], + GifLoaderDialogUtils.hideDialog(context); + if (widget.model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(widget.model.error); + } + } else { + DrAppToastMsg.showErrorToast("Please enter medical note"); + } + }, ), ), + SizedBox( + width: 8, + ), + if (widget.medicalReport != null) + Expanded( + child: AppButton( + title: widget.status == MedicalReportStatus.ADD + ? TranslationBase.of(context).add + : TranslationBase.of(context).verify, + color: Color(0xff359846), + fontWeight: FontWeight.w700, + onPressed: () async { + txtOfMedicalReport = await HtmlEditor.getText(); + if (txtOfMedicalReport.isNotEmpty) { + GifLoaderDialogUtils.showMyDialog(context); + await widget.model.verifyMedicalReport(widget.patient, widget.medicalReport); + GifLoaderDialogUtils.hideDialog(context); + Navigator.pop(context); + if (widget.model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(widget.model.error); + } + } else { + DrAppToastMsg.showErrorToast("Please enter medical note"); + } + }, + ), + ), ], ), + ), + ], + ), )); } diff --git a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart index 10cb4be6..22645520 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart @@ -40,6 +40,7 @@ class _MedicalReportPageState extends State { return BaseView( onModelReady: (model) async { await model.getMedicalReportList(patient); + await model.getMedicalReportTemplate(); }, builder: (_, model, w) => AppScaffold( baseViewModel: model, @@ -79,13 +80,25 @@ class _MedicalReportPageState extends State { // Helpers.showErrorToast("Please Verified the on hold report to be able to add new one"); // } else - Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_INSERT, arguments: { - 'patient': patient, - 'patientType': patientType, - 'arrivalType': arrivalType, - 'type': MedicalReportStatus.ADD, - 'model': model, - }); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => AddVerifyMedicalReport( + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + model: model, + status: MedicalReportStatus.ADD, + )), + ); + + // Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_INSERT, arguments: { + // 'patient': patient, + // 'patientType': patientType, + // 'arrivalType': arrivalType, + // 'type': MedicalReportStatus.ADD, + // 'model': model, + // }); }, label: TranslationBase.of(context).createNewMedicalReport, ), @@ -95,13 +108,25 @@ class _MedicalReportPageState extends State { (index) => InkWell( onTap: () { if (model.medicalReportList[index].status == 1) { - Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_INSERT, arguments: { - 'patient': patient, - 'patientType': patientType, - 'arrivalType': arrivalType, - 'medicalReport': model.medicalReportList[index], - 'model': model, - }); + // Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_INSERT, arguments: { + // 'patient': patient, + // 'patientType': patientType, + // 'arrivalType': arrivalType, + // 'medicalReport': model.medicalReportList[index], + // 'model': model, + // }); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => AddVerifyMedicalReport( + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + medicalReport: model.medicalReportList[index], + model: model, + medicalNote: model.medicalReportList[index].reportDataHtml, + )), + ); } else { Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_DETAIL, arguments: { 'patient': patient, @@ -138,8 +163,8 @@ class _MedicalReportPageState extends State { ), AppText( projectViewModel.isArabic - ? model.medicalReportList[index].doctorNameN - : model.medicalReportList[index].doctorName, + ? model.medicalReportList[index].doctorNameN ?? "" + : model.medicalReportList[index].doctorName ?? "", fontSize: 1.9 * SizeConfig.textMultiplier, fontWeight: FontWeight.w700, color: Color(0xFF2E303A), From d839fd3545754b844b6fbbe9db801069c256521d Mon Sep 17 00:00:00 2001 From: mosazaid Date: Mon, 28 Jun 2021 12:19:02 +0300 Subject: [PATCH 024/289] outpatirnt referral changes --- .../viewModel/patient-referral-viewmodel.dart | 3 + .../referral/referred-patient-screen.dart | 13 +- .../referred_patient_detail_in-paint.dart | 195 ++++++++++-------- pubspec.lock | 14 +- 4 files changed, 128 insertions(+), 97 deletions(-) diff --git a/lib/core/viewModel/patient-referral-viewmodel.dart b/lib/core/viewModel/patient-referral-viewmodel.dart index 0351db77..08b3feb2 100644 --- a/lib/core/viewModel/patient-referral-viewmodel.dart +++ b/lib/core/viewModel/patient-referral-viewmodel.dart @@ -322,6 +322,7 @@ class PatientReferralViewModel extends BaseViewModel { patient.doctorId = referredPatient.doctorID; patient.doctorName = referredPatient.doctorName; patient.patientId = referredPatient.patientID; + patient.patientMRN = referredPatient.patientID; patient.firstName = referredPatient.firstName; patient.middleName = referredPatient.middleName; patient.lastName = referredPatient.lastName; @@ -339,6 +340,8 @@ class PatientReferralViewModel extends BaseViewModel { patient.nationalityFlagURL = referredPatient.nationalityFlagURL; patient.age = referredPatient.age; patient.clinicDescription = referredPatient.clinicDescription; + patient.appointmentNo = referredPatient.appointmentNo; + return patient; } diff --git a/lib/screens/patients/profile/referral/referred-patient-screen.dart b/lib/screens/patients/profile/referral/referred-patient-screen.dart index c95a28d8..8dce7d60 100644 --- a/lib/screens/patients/profile/referral/referred-patient-screen.dart +++ b/lib/screens/patients/profile/referral/referred-patient-screen.dart @@ -12,8 +12,13 @@ import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -class ReferredPatientScreen extends StatelessWidget { +class ReferredPatientScreen extends StatefulWidget { + @override + _ReferredPatientScreenState createState() => _ReferredPatientScreenState(); +} + +class _ReferredPatientScreenState extends State { PatientType patientType = PatientType.IN_PATIENT; @override @@ -30,7 +35,9 @@ class ReferredPatientScreen extends StatelessWidget { margin: EdgeInsets.only(top: 70), child: PatientTypeRadioWidget( (patientType) async { - this.patientType = patientType; + setState(() { + this.patientType = patientType; + }); GifLoaderDialogUtils.showMyDialog(context); if (patientType == PatientType.IN_PATIENT) { await model.getMyReferredPatient(isFirstTime: false); @@ -75,7 +82,7 @@ class ReferredPatientScreen extends StatelessWidget { context, FadePage( page: ReferredPatientDetailScreen( - model.getReferredPatientItem(index)), + model.getReferredPatientItem(index), this.patientType), ), ); }, diff --git a/lib/screens/patients/profile/referral/referred_patient_detail_in-paint.dart b/lib/screens/patients/profile/referral/referred_patient_detail_in-paint.dart index b3f11c51..f6d3b8d7 100644 --- a/lib/screens/patients/profile/referral/referred_patient_detail_in-paint.dart +++ b/lib/screens/patients/profile/referral/referred_patient_detail_in-paint.dart @@ -1,4 +1,5 @@ import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/enum/PatientType.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-referral-viewmodel.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; @@ -18,8 +19,9 @@ import '../../../../routes.dart'; class ReferredPatientDetailScreen extends StatelessWidget { final MyReferredPatientModel referredPatient; + final PatientType patientType; - ReferredPatientDetailScreen(this.referredPatient); + ReferredPatientDetailScreen(this.referredPatient, this.patientType); @override Widget build(BuildContext context) { @@ -74,7 +76,8 @@ class ReferredPatientDetailScreen extends StatelessWidget { .pushNamed(PATIENTS_PROFILE, arguments: { "patient": patient, "patientType": "1", - "isInpatient": true, + "isInpatient": + patientType == PatientType.IN_PATIENT, "arrivalType": "1", "from": AppDateUtils.convertDateToFormat( DateTime.now(), 'yyyy-MM-dd'), @@ -93,14 +96,15 @@ class ReferredPatientDetailScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ InkWell( - onTap: (){ + onTap: () { PatiantInformtion patient = - model.getPatientFromReferral(referredPatient); + model.getPatientFromReferral(referredPatient); Navigator.of(context) .pushNamed(PATIENTS_PROFILE, arguments: { "patient": patient, "patientType": "1", - "isInpatient": true, + "isInpatient": + patientType == PatientType.IN_PATIENT, "arrivalType": "1", "from": AppDateUtils.convertDateToFormat( DateTime.now(), 'yyyy-MM-dd'), @@ -236,36 +240,37 @@ class ReferredPatientDetailScreen extends StatelessWidget { ), ], ), - if(referredPatient - .frequencyDescription != null) - Row( - mainAxisAlignment: - MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context) - .frequency + - ": ", - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - fontSize: 1.7 * - SizeConfig.textMultiplier, - color: Color(0XFF575757), - ), - Expanded( - child: AppText( - referredPatient - .frequencyDescription, + if (referredPatient + .frequencyDescription != + null) + Row( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context) + .frequency + + ": ", fontFamily: 'Poppins', - fontWeight: FontWeight.w700, - fontSize: 14, - color: Color(0XFF2E303A), + fontWeight: FontWeight.w600, + fontSize: 1.7 * + SizeConfig.textMultiplier, + color: Color(0XFF575757), ), - ), - ], - ), + Expanded( + child: AppText( + referredPatient + .frequencyDescription, + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 14, + color: Color(0XFF2E303A), + ), + ), + ], + ), ], ), ), @@ -303,56 +308,65 @@ class ReferredPatientDetailScreen extends StatelessWidget { ) ], ), - if(referredPatient.priorityDescription != null) - Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).priority + - ": ", - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - fontSize: 1.7 * SizeConfig.textMultiplier, - color: Color(0XFF575757), - ), - AppText( - referredPatient.priorityDescription, - fontFamily: 'Poppins', - fontWeight: FontWeight.w700, - fontSize: 14, - color: Color(0XFF2E303A), - ), - ], - ), - if(referredPatient.mAXResponseTime != null) - Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context) - .maxResponseTime + - ": ", - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - fontSize: 1.7 * SizeConfig.textMultiplier, - color: Color(0XFF575757), - ), - Expanded( - child: AppText( - referredPatient.mAXResponseTime != null?AppDateUtils.convertDateFromServerFormat( - referredPatient.mAXResponseTime, - "dd MMM,yyyy"):'', + if (referredPatient.priorityDescription != null) + Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).priority + + ": ", fontFamily: 'Poppins', - fontWeight: FontWeight.w700, + fontWeight: FontWeight.w600, fontSize: - 1.8 * SizeConfig.textMultiplier, + 1.7 * SizeConfig.textMultiplier, + color: Color(0XFF575757), + ), + AppText( + referredPatient.priorityDescription, + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 14, color: Color(0XFF2E303A), ), - ), - ], - ), + ], + ), + if (referredPatient.mAXResponseTime != null) + Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context) + .maxResponseTime + + ": ", + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + fontSize: + 1.7 * SizeConfig.textMultiplier, + color: Color(0XFF575757), + ), + Expanded( + child: AppText( + referredPatient.mAXResponseTime != + null + ? AppDateUtils + .convertDateFromServerFormat( + referredPatient + .mAXResponseTime, + "dd MMM,yyyy") + : '', + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: + 1.8 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + ), + ], + ), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -518,11 +532,15 @@ class ReferredPatientDetailScreen extends StatelessWidget { color: Color(0XFF2E303A), ), AppText( - referredPatient - .referredDoctorRemarks == null ?'':referredPatient - .referredDoctorRemarks.isNotEmpty - ? referredPatient.referredDoctorRemarks - : TranslationBase.of(context).notRepliedYet, + referredPatient.referredDoctorRemarks == + null + ? '' + : referredPatient.referredDoctorRemarks + .isNotEmpty + ? referredPatient + .referredDoctorRemarks + : TranslationBase.of(context) + .notRepliedYet, fontFamily: 'Poppins', fontWeight: FontWeight.w600, fontSize: 1.6 * SizeConfig.textMultiplier, @@ -538,6 +556,7 @@ class ReferredPatientDetailScreen extends StatelessWidget { ), ), ), + if (patientType == PatientType.IN_PATIENT) Container( margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), child: AppButton( @@ -548,9 +567,11 @@ class ReferredPatientDetailScreen extends StatelessWidget { fontSize: 1.8, hPadding: 8, vPadding: 12, - disabled: referredPatient.referredDoctorRemarks == null? true: referredPatient.referredDoctorRemarks.isNotEmpty - ? false - : true, + disabled: referredPatient.referredDoctorRemarks == null + ? true + : referredPatient.referredDoctorRemarks.isNotEmpty + ? false + : true, onPressed: () async { await model.verifyReferralDoctorRemarks(referredPatient); if (model.state == ViewState.ErrorLocal) { diff --git a/pubspec.lock b/pubspec.lock index 18379111..a408ffd5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,14 +7,14 @@ packages: name: _fe_analyzer_shared url: "https://pub.dartlang.org" source: hosted - version: "14.0.0" + version: "12.0.0" analyzer: dependency: transitive description: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "0.41.2" + version: "0.40.6" archive: dependency: transitive description: @@ -119,7 +119,7 @@ packages: name: build_web_compilers url: "https://pub.dartlang.org" source: hosted - version: "2.15.3" + version: "2.12.2" built_collection: dependency: transitive description: @@ -280,7 +280,7 @@ packages: name: dart_style url: "https://pub.dartlang.org" source: hosted - version: "1.3.12" + version: "1.3.10" date_time_picker: dependency: "direct main" description: @@ -629,7 +629,7 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.4" + version: "1.3.0-nullsafety.3" mime: dependency: transitive description: @@ -921,7 +921,7 @@ packages: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.2" + version: "1.10.0-nullsafety.1" sticky_headers: dependency: "direct main" description: @@ -1119,5 +1119,5 @@ packages: source: hosted version: "2.2.1" sdks: - dart: ">=2.11.0-162.0 <=2.11.0-213.1.beta" + dart: ">=2.10.0 <2.11.0" flutter: ">=1.22.0 <2.0.0" From 1af52dc5b7567480d6872b45937233425ecacfff Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 28 Jun 2021 13:02:36 +0300 Subject: [PATCH 025/289] fix referral patient --- .../referral/MyReferralPatientModel.dart | 81 +- .../patient/MyReferralPatientService.dart | 8 +- .../patient-doctor-referral-service.dart | 15 +- .../viewModel/patient-referral-viewmodel.dart | 8 +- .../referral/AddReplayOnReferralPatient.dart | 58 -- .../referral/my-referral-detail-screen.dart | 757 ++++++++---------- .../my-referral-inpatient-screen.dart | 25 +- .../referral_patient_detail_in-paint.dart | 4 +- .../referral/referred-patient-screen.dart | 1 + .../profile_medical_info_widget_search.dart | 650 ++++----------- 10 files changed, 603 insertions(+), 1004 deletions(-) diff --git a/lib/core/model/referral/MyReferralPatientModel.dart b/lib/core/model/referral/MyReferralPatientModel.dart index ce8a6447..09b3769e 100644 --- a/lib/core/model/referral/MyReferralPatientModel.dart +++ b/lib/core/model/referral/MyReferralPatientModel.dart @@ -57,11 +57,33 @@ class MyReferralPatientModel { bool isDoctorLate; bool isDoctorResponse; String nationalityFlagURL; + + + + + + + + + + + + + + String nursingStationName; String priorityDescription; String referringClinicDescription; String referringDoctorName; int referalStatus; + String sourceSetupID; + int sourceProjectId; + String targetSetupID; + int targetProjectId; + int targetClinicID; + int targetDoctorID; + int sourceAppointmentNo; + int targetAppointmentNo; MyReferralPatientModel( {this.rowID, @@ -104,27 +126,27 @@ class MyReferralPatientModel { this.referralResponseOn, this.priority, this.frequency, - this.mAXResponseTime, - this.episodeID, - this.appointmentNo, - this.appointmentDate, - this.appointmentType, - this.patientMRN, - this.createdOn, - this.clinicID, - this.nationalityID, - this.age, - this.doctorImageURL, - this.frequencyDescription, - this.genderDescription, - this.isDoctorLate, - this.isDoctorResponse, - this.nationalityFlagURL, - this.nursingStationName, - this.priorityDescription, - this.referringClinicDescription, - this.referringDoctorName, - this.referalStatus}); + this.mAXResponseTime, + this.episodeID, + this.appointmentNo, + this.appointmentDate, + this.appointmentType, + this.patientMRN, + this.createdOn, + this.clinicID, + this.nationalityID, + this.age, + this.doctorImageURL, + this.frequencyDescription, + this.genderDescription, + this.isDoctorLate, + this.isDoctorResponse, + this.nationalityFlagURL, + this.nursingStationName, + this.priorityDescription, + this.referringClinicDescription, + this.referringDoctorName, + this.referalStatus, this.sourceSetupID, this.sourceAppointmentNo, this.sourceProjectId, this.targetProjectId, this.targetAppointmentNo, this.targetClinicID, this.targetSetupID, this.targetDoctorID}); MyReferralPatientModel.fromJson(Map json) { rowID = json['RowID']; @@ -201,7 +223,14 @@ class MyReferralPatientModel { priorityDescription = json['PriorityDescription']; referringClinicDescription = json['ReferringClinicDescription']; referringDoctorName = json['ReferringDoctorName']; - } + sourceSetupID = json['SourceSetupID']; + sourceProjectId = json['SourceProjectId']; + targetSetupID = json['TargetSetupID']; + targetProjectId = json['TargetProjectId']; + targetClinicID = json['TargetClinicID']; + targetDoctorID = json['TargetDoctorID']; + sourceAppointmentNo = json['SourceAppointmentNo']; + targetAppointmentNo = json['TargetAppointmentNo']; } Map toJson() { final Map data = new Map(); @@ -266,6 +295,14 @@ class MyReferralPatientModel { data['PriorityDescription'] = this.priorityDescription; data['ReferringClinicDescription'] = this.referringClinicDescription; data['ReferringDoctorName'] = this.referringDoctorName; + data['SourceSetupID'] = this.sourceSetupID; + data['SourceProjectId'] = this.sourceProjectId; + data['TargetSetupID'] = this.targetSetupID; + data['TargetProjectId'] = this.targetProjectId; + data['TargetClinicID'] = this.targetClinicID; + data['TargetDoctorID'] = this.targetDoctorID; + data['SourceAppointmentNo'] = this.sourceAppointmentNo; + data['TargetAppointmentNo'] = this.targetAppointmentNo; return data; } diff --git a/lib/core/service/patient/MyReferralPatientService.dart b/lib/core/service/patient/MyReferralPatientService.dart index 87fcdd23..35729def 100644 --- a/lib/core/service/patient/MyReferralPatientService.dart +++ b/lib/core/service/patient/MyReferralPatientService.dart @@ -100,20 +100,22 @@ class MyReferralInPatientService extends BaseService { ); } - Future replayReferred(String referredDoctorRemarks, MyReferralPatientModel referral, int referalStatus) async { + Future replayReferred(String referredDoctorRemarks, MyReferralPatientModel referral, int referralStatus) async { hasError = false; await getDoctorProfile(); AddReferredRemarksRequestModel _requestAddReferredDoctorRemarks = AddReferredRemarksRequestModel( editedBy: doctorProfile.doctorID, projectID: doctorProfile.projectID, referredDoctorRemarks: referredDoctorRemarks, - referalStatus: referalStatus); + referalStatus: referralStatus); _requestAddReferredDoctorRemarks.projectID = referral.projectID; + + //TODO Check this in case out patient _requestAddReferredDoctorRemarks.admissionNo = int.parse(referral.admissionNo); _requestAddReferredDoctorRemarks.lineItemNo = referral.lineItemNo; _requestAddReferredDoctorRemarks.referredDoctorRemarks = referredDoctorRemarks; _requestAddReferredDoctorRemarks.editedBy = doctorProfile.doctorID; - _requestAddReferredDoctorRemarks.referalStatus = referalStatus; + _requestAddReferredDoctorRemarks.referalStatus = referralStatus; // _requestAddReferredDoctorRemarks.patientID = referral.patientID; // _requestAddReferredDoctorRemarks.referringDoctor = referral.referringDoctor; diff --git a/lib/core/service/patient/patient-doctor-referral-service.dart b/lib/core/service/patient/patient-doctor-referral-service.dart index 81529590..cded130e 100644 --- a/lib/core/service/patient/patient-doctor-referral-service.dart +++ b/lib/core/service/patient/patient-doctor-referral-service.dart @@ -1,4 +1,5 @@ import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/core/model/referral/MyReferralPatientModel.dart'; import 'package:doctor_app_flutter/lookups/hospital_lookup.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/patient/get_clinic_by_project_id_request.dart'; @@ -242,18 +243,18 @@ class PatientReferralService extends LookupService { } Future responseReferral( - PendingReferral pendingReferral, bool isAccepted) async { + MyReferralPatientModel referralPatient, bool isAccepted) async { hasError = false; DoctorProfileModel doctorProfile = await getDoctorProfile(); Map body = Map(); - body['PatientMRN'] = pendingReferral.patientID; - body['AppointmentNo'] = pendingReferral.targetAppointmentNo; - body['SetupID'] = pendingReferral.targetSetupID; - body['ProjectID'] = pendingReferral.targetProjectId; + body['PatientMRN'] = referralPatient.patientID; + body['AppointmentNo'] = referralPatient.targetAppointmentNo; + body['SetupID'] = referralPatient.targetSetupID; + body['ProjectID'] = referralPatient.targetProjectId; body['IsAccepted'] = isAccepted; - body['PatientName'] = pendingReferral.patientName; - body['ReferralResponse'] = pendingReferral.remarksFromSource; + body['PatientName'] = referralPatient.patientName; + body['ReferralResponse'] = referralPatient.referringDoctorRemarks; body['DoctorName'] = doctorProfile.doctorName; await baseAppClient.post( diff --git a/lib/core/viewModel/patient-referral-viewmodel.dart b/lib/core/viewModel/patient-referral-viewmodel.dart index 0351db77..6c1c0115 100644 --- a/lib/core/viewModel/patient-referral-viewmodel.dart +++ b/lib/core/viewModel/patient-referral-viewmodel.dart @@ -203,9 +203,9 @@ class PatientReferralViewModel extends BaseViewModel { getMyReferralPatientService(); } - Future responseReferral(PendingReferral pendingReferral, bool isAccepted) async { + Future responseReferral(MyReferralPatientModel referralPatient, bool isAccepted) async { setState(ViewState.Busy); - await _referralPatientService.responseReferral(pendingReferral, isAccepted); + await _referralPatientService.responseReferral(referralPatient, isAccepted); if (_referralPatientService.hasError) { error = _referralPatientService.error; setState(ViewState.ErrorLocal); @@ -392,9 +392,9 @@ class PatientReferralViewModel extends BaseViewModel { return patient; } - Future replayReferred(String referredDoctorRemarks, MyReferralPatientModel referral, int referalStatus) async { + Future replayReferred(String referredDoctorRemarks, MyReferralPatientModel referral, int referralStatus) async { setState(ViewState.Busy); - await _myReferralService.replayReferred(referredDoctorRemarks, referral, referalStatus); + await _myReferralService.replayReferred(referredDoctorRemarks, referral, referralStatus); if (_myReferralService.hasError) { error = _myReferralService.error; setState(ViewState.ErrorLocal); diff --git a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart index 56ff85c4..e4b8700c 100644 --- a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart +++ b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart @@ -149,14 +149,6 @@ class _AddReplayOnReferralPatientState extends State DrAppToastMsg.showSuccesToast("Has been rejected"); Navigator.of(context).pop(); Navigator.of(context).pop(); - - // Navigator.push( - // context, - // FadePage( - // page: ReplySummeryOnReferralPatient( - // widget.myReferralInPatientModel, replayOnReferralController.text.trim()), - // ), - // ); } } else { Helpers.showErrorToast("You can't add empty reply"); @@ -190,14 +182,6 @@ class _AddReplayOnReferralPatientState extends State DrAppToastMsg.showSuccesToast("Your Reply Added Successfully"); Navigator.of(context).pop(); Navigator.of(context).pop(); - - // Navigator.push( - // context, - // FadePage( - // page: ReplySummeryOnReferralPatient( - // widget.myReferralInPatientModel, replayOnReferralController.text.trim()), - // ), - // ); } } else { Helpers.showErrorToast("You can't add empty reply"); @@ -214,48 +198,6 @@ class _AddReplayOnReferralPatientState extends State ], ), ), - // Container( - // margin: EdgeInsets.all(5), - // child: AppButton( - // title: 'Submit Reply', - // color: Color(0xff359846), - // fontWeight: FontWeight.w700, - // onPressed: () async { - // setState(() { - // isSubmitted = true; - // }); - // if (replayOnReferralController.text.isNotEmpty) { - // GifLoaderDialogUtils.showMyDialog(context); - // await widget.patientReferralViewModel.replay( - // replayOnReferralController.text.trim(), - // widget.myReferralInPatientModel); - // if (widget.patientReferralViewModel.state == - // ViewState.ErrorLocal) { - // Helpers.showErrorToast( - // widget.patientReferralViewModel.error); - // } else { - // GifLoaderDialogUtils.hideDialog(context); - // DrAppToastMsg.showSuccesToast( - // "Your Reply Added Successfully"); - // Navigator.of(context).pop(); - // Navigator.of(context).pop(); - // - // Navigator.push( - // context, - // FadePage( - // page: ReplySummeryOnReferralPatient( - // widget.myReferralInPatientModel, - // replayOnReferralController.text.trim()), - // ), - // ); - // } - // } else { - // Helpers.showErrorToast("You can't add empty reply"); - // setState(() { - // isSubmitted = false; - // }); - // } - // })), ], ), ), diff --git a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart index 447a3739..ffcd871a 100644 --- a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart @@ -1,8 +1,8 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/model/referral/MyReferralPatientModel.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-referral-viewmodel.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; -import 'package:doctor_app_flutter/models/patient/my_referral/PendingReferral.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; @@ -13,476 +13,411 @@ import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; // ignore: must_be_immutable class MyReferralDetailScreen extends StatelessWidget { - PendingReferral pendingReferral; + final MyReferralPatientModel referralPatient; + + const MyReferralDetailScreen({Key key, this.referralPatient}) + : super(key: key); @override Widget build(BuildContext context) { - final routeArgs = ModalRoute.of(context).settings.arguments as Map; - pendingReferral = routeArgs['referral']; + // final routeArgs = ModalRoute.of(context).settings.arguments as Map; + // pendingReferral = routeArgs['referral']; return BaseView( - onModelReady: (model) => model.getPatientDetails( - AppDateUtils.convertStringToDateFormat( - DateTime.now() /*.subtract(Duration(days: 350))*/ .toString(), - "yyyy-MM-dd"), - AppDateUtils.convertStringToDateFormat( - DateTime.now().toString(), "yyyy-MM-dd"), - pendingReferral.patientID, - pendingReferral.sourceAppointmentNo), + onModelReady: (model) => model.getDoctorProfile(), builder: (_, model, w) => AppScaffold( - baseViewModel: model, - appBarTitle: TranslationBase.of(context).referPatient, - isShowAppBar: false, - body: model.patientArrivalList != null && - model.patientArrivalList.length > 0 - ? Column( - children: [ - Container( - padding: - EdgeInsets.only(left: 0, right: 5, bottom: 5, top: 5), - decoration: BoxDecoration( - color: Colors.white, - ), - child: Container( - padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), - margin: EdgeInsets.only(top: 50), - child: Column( + baseViewModel: model, + appBarTitle: TranslationBase.of(context).referPatient, + isShowAppBar: false, + body: Column( + children: [ + Container( + padding: EdgeInsets.only(left: 0, right: 5, bottom: 5, top: 5), + decoration: BoxDecoration( + color: Colors.white, + ), + child: Container( + padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), + margin: EdgeInsets.only(top: 50), + child: Column( + children: [ + Container( + padding: EdgeInsets.only(left: 12.0), + child: Row(children: [ + IconButton( + icon: Icon(Icons.arrow_back_ios), + color: Colors.black, //Colors.black, + onPressed: () => Navigator.pop(context), + ), + Expanded( + child: AppText( + (Helpers.capitalize(referralPatient.firstName + " "+ + referralPatient.lastName)), + fontSize: SizeConfig.textMultiplier * 2.5, + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + ), + ), + referralPatient.gender == 1 + ? Icon( + DoctorApp.male_2, + color: Colors.blue, + ) + : Icon( + DoctorApp.female_1, + color: Colors.pink, + ), + ]), + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container( + Padding( padding: EdgeInsets.only(left: 12.0), - child: Row(children: [ - IconButton( - icon: Icon(Icons.arrow_back_ios), - color: Colors.black, //Colors.black, - onPressed: () => Navigator.pop(context), - ), - Expanded( - child: AppText( - (Helpers.capitalize(model - .patientArrivalList[0] - .patientDetails - .fullName)), - fontSize: SizeConfig.textMultiplier * 2.5, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - ), + child: Container( + width: 60, + height: 60, + child: Image.asset( + referralPatient.gender == 1 + ? 'assets/images/male_avatar.png' + : 'assets/images/female_avatar.png', + fit: BoxFit.cover, ), - model.patientArrivalList[0].patientDetails - .gender == - 1 - ? Icon( - DoctorApp.male_2, - color: Colors.blue, - ) - : Icon( - DoctorApp.female_1, - color: Colors.pink, - ), - ]), + ), ), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only(left: 12.0), - child: Container( - width: 60, - height: 60, - child: Image.asset( - pendingReferral.patientDetails.gender == 1 - ? 'assets/images/male_avatar.png' - : 'assets/images/female_avatar.png', - fit: BoxFit.cover, - ), + SizedBox( + width: 10, + ), + Expanded( + child: Column( + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + AppText( + referralPatient.referralStatus != null + ? model.getReferralStatusNameByCode( + referralPatient.referralStatus, + context) + : "", + fontFamily: 'Poppins', + fontSize: 1.9 * SizeConfig.textMultiplier, + fontWeight: FontWeight.w700, + color: referralPatient.referralStatus == 1 + ? Color(0xffc4aa54) + : referralPatient.referralStatus == + 46 || + referralPatient + .referralStatus == + 2 + ? Colors.green[700] + : Colors.red[700], + ), + AppText( + AppDateUtils.getDayMonthYearDateFormatted( + referralPatient.referralDate), + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + fontSize: + 2.0 * SizeConfig.textMultiplier, + color: Color(0XFF28353E), + ) + ], ), - ), - SizedBox( - width: 10, - ), - Expanded( - child: Column( + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, children: [ Row( mainAxisAlignment: - MainAxisAlignment.spaceBetween, + MainAxisAlignment.start, children: [ AppText( - pendingReferral.referralStatus != null - ? pendingReferral.referralStatus - : "", - fontFamily: 'Poppins', - fontSize: - 1.9 * SizeConfig.textMultiplier, - fontWeight: FontWeight.w700, - color: pendingReferral - .referralStatus != - null - ? pendingReferral - .referralStatus == - 'Pending' - ? Color(0xffc4aa54) - : pendingReferral - .referralStatus == - 'Accepted' - ? Colors.green[700] - : Colors.red[700] - : Colors.grey[500], - ), - AppText( - pendingReferral.referredOn - .split(" ")[0], + TranslationBase.of(context) + .fileNumber, fontFamily: 'Poppins', fontWeight: FontWeight.w600, fontSize: - 2.0 * SizeConfig.textMultiplier, - color: Color(0XFF28353E), - ) - ], - ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context) - .fileNumber, - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - fontSize: 1.7 * - SizeConfig.textMultiplier, - color: Color(0XFF575757), - ), - AppText( - "${pendingReferral.patientID}", - fontFamily: 'Poppins', - fontWeight: FontWeight.w700, - fontSize: 1.8 * - SizeConfig.textMultiplier, - color: Color(0XFF2E303A), - ), - ], + 1.7 * SizeConfig.textMultiplier, + color: Color(0XFF575757), ), AppText( - pendingReferral.referredOn - .split(" ")[1], + "${referralPatient.patientID}", fontFamily: 'Poppins', - fontWeight: FontWeight.w600, + fontWeight: FontWeight.w700, fontSize: 1.8 * SizeConfig.textMultiplier, - color: Color(0XFF575757), - ) + color: Color(0XFF2E303A), + ), ], ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - crossAxisAlignment: - CrossAxisAlignment.center, - children: [ - Expanded( - child: Column( + AppText( + AppDateUtils.getTimeHHMMA(referralPatient.referralDate), + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + fontSize: + 1.8 * SizeConfig.textMultiplier, + color: Color(0XFF575757), + ) + ], + ), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Column( + children: [ + + //todo Elham* return this + // Row( + // mainAxisAlignment: + // MainAxisAlignment.start, + // children: [ + // AppText( + // TranslationBase.of(context) + // .referredFrom, + // fontFamily: 'Poppins', + // fontWeight: FontWeight.w600, + // fontSize: 1.7 * + // SizeConfig.textMultiplier, + // color: Color(0XFF575757), + // ), + // AppText( + // referralPatient.projectID == model.doctorProfile.projectID + // ? TranslationBase.of( + // context) + // .sameBranch + // : TranslationBase.of( + // context) + // .otherBranch, + // fontFamily: 'Poppins', + // fontWeight: FontWeight.w700, + // fontSize: 1.8 * + // SizeConfig + // .textMultiplier, + // color: Color(0XFF2E303A), + // ), + // ], + // ), + Row( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context) - .referredFrom, - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - fontSize: 1.7 * - SizeConfig - .textMultiplier, - color: Color(0XFF575757), - ), - AppText( - pendingReferral - .isReferralDoctorSameBranch - ? TranslationBase.of( - context) - .sameBranch - : TranslationBase.of( - context) - .otherBranch, - fontFamily: 'Poppins', - fontWeight: FontWeight.w700, - fontSize: 1.8 * - SizeConfig - .textMultiplier, - color: Color(0XFF2E303A), - ), - ], + AppText( + TranslationBase.of(context) + .remarks + + " : ", + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + fontSize: 1.7 * + SizeConfig.textMultiplier, + color: Color(0XFF575757), ), - Row( - mainAxisAlignment: - MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context) - .remarks + - " : ", - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - fontSize: 1.7 * - SizeConfig - .textMultiplier, - color: Color(0XFF575757), - ), - Expanded( - child: AppText( - pendingReferral - .remarksFromSource, - fontFamily: 'Poppins', - fontWeight: - FontWeight.w700, - fontSize: 1.8 * - SizeConfig - .textMultiplier, - color: Color(0XFF2E303A), - ), - ), - ], + Expanded( + child: AppText( + referralPatient.referringDoctorRemarks?? + '', + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 1.8 * + SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), ), ], ), - ), - Row( - children: [ - AppText( - pendingReferral.patientDetails - .nationalityName != - null - ? pendingReferral - .patientDetails - .nationalityName - : "", - fontWeight: FontWeight.bold, - color: Color(0xFF2E303A), - fontSize: 1.4 * - SizeConfig.textMultiplier, - ), - pendingReferral - .nationalityFlagUrl != - null - ? ClipRRect( - borderRadius: - BorderRadius.circular( - 20.0), - child: Image.network( - pendingReferral - .nationalityFlagUrl, - height: 25, - width: 30, - errorBuilder: - (BuildContext context, - Object exception, - StackTrace - stackTrace) { - return Text('No Image'); - }, - )) - : SizedBox() - ], - ) - ], + ], + ), ), Row( - crossAxisAlignment: - CrossAxisAlignment.start, children: [ - Container( - margin: EdgeInsets.only( - left: 10, right: 0), - child: Image.asset( - 'assets/images/patient/ic_ref_arrow_up.png', - height: 50, - width: 30, - ), + AppText( + referralPatient.nationalityName != + null + ? referralPatient.nationalityName + : "", + fontWeight: FontWeight.bold, + color: Color(0xFF2E303A), + fontSize: + 1.4 * SizeConfig.textMultiplier, ), - Container( - margin: EdgeInsets.only( - left: 0, - top: 25, - right: 0, - bottom: 0), - padding: EdgeInsets.only( - left: 4.0, right: 4.0), - child: Container( - width: 40, - height: 40, - child: CircleAvatar( - radius: 25.0, - backgroundImage: NetworkImage( - pendingReferral - .doctorImageUrl), - backgroundColor: - Colors.transparent, - ), - ), + referralPatient.nationalityFlagURL != + null + ? ClipRRect( + borderRadius: + BorderRadius.circular(20.0), + child: Image.network( + referralPatient + .nationalityFlagURL, + height: 25, + width: 30, + errorBuilder: (BuildContext + context, + Object exception, + StackTrace stackTrace) { + return Text('No Image'); + }, + )) + : SizedBox() + ], + ) + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: + EdgeInsets.only(left: 10, right: 0), + child: Image.asset( + 'assets/images/patient/ic_ref_arrow_up.png', + height: 50, + width: 30, + ), + ), + Container( + margin: EdgeInsets.only( + left: 0, + top: 25, + right: 0, + bottom: 0), + padding: EdgeInsets.only( + left: 4.0, right: 4.0), + child: Container( + width: 40, + height: 40, + child: CircleAvatar( + radius: 25.0, + backgroundImage: NetworkImage( + referralPatient.doctorImageURL), + backgroundColor: Colors.transparent, ), - Expanded( - flex: 4, - child: Container( - margin: EdgeInsets.only( - left: 10, - top: 25, - right: 10, - bottom: 0), - child: Column( - children: [ - AppText( - pendingReferral - .referredByDoctorInfo, - fontFamily: 'Poppins', - fontWeight: FontWeight.w700, - fontSize: 1.7 * - SizeConfig.textMultiplier, - color: Color(0XFF2E303A), - ), - ], + ), + ), + Expanded( + flex: 4, + child: Container( + margin: EdgeInsets.only( + left: 10, + top: 25, + right: 10, + bottom: 0), + child: Column( + children: [ + AppText( + referralPatient.doctorName, + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 1.7 * + SizeConfig.textMultiplier, + color: Color(0XFF2E303A), ), - ), + ], ), - ], + ), ), ], ), - ), - ], + ], + ), ), ], ), - ), - ), - Expanded( - child: SingleChildScrollView( - child: Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 16, - ), - Padding( - padding: - const EdgeInsets.symmetric(horizontal: 16), - child: SizedBox( - child: ProfileMedicalInfoWidgetSearch( - patient: model.patientArrivalList[0], - patientType: "7", - from: null, - to: null, - ), - ), - ), - ], - ), - ), - ), + ], ), - Container( - margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), - child: Row( + ), + ), + Expanded( + child: SingleChildScrollView( + child: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - child: AppButton( - title: TranslationBase.of(context).accept, - color: Color(0xFF4BA821), - fontColor: Colors.white, - fontSize: 1.6, - hPadding: 8, - vPadding: 12, - onPressed: () async { - await model.responseReferral( - pendingReferral, true); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } else { - DrAppToastMsg.showSuccesToast( - TranslationBase.of(context) - .referralSuccessMsgAccept); - Navigator.pop(context); - Navigator.pop(context); - } - }, - ), - ), SizedBox( - width: 8, + height: 16, ), - Expanded( - child: AppButton( - title: TranslationBase.of(context).reject, - color: Color(0xFFB9382C), - fontColor: Colors.white, - fontSize: 1.6, - hPadding: 8, - vPadding: 12, - onPressed: () async { - await model.responseReferral( - pendingReferral, true); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } else { - DrAppToastMsg.showSuccesToast( - TranslationBase.of(context) - .referralSuccessMsgReject); - Navigator.pop(context); - Navigator.pop(context); - } - }, + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: SizedBox( + child: ProfileMedicalInfoWidgetSearch( + patient: model + .getPatientFromReferralO(referralPatient), + patientType: "7", + isInpatient: false, + from: null, + to: null, + ), ), ), ], ), ), - ], - ) - : Column( - children: [ - Container( - padding: EdgeInsets.only(left: 12.0), - child: Row(children: [ - IconButton( - icon: Icon(Icons.arrow_back_ios), - color: Colors.black, //Colors.black, - onPressed: () => Navigator.pop(context), - ), - Expanded( - child: AppText( - "", - fontSize: SizeConfig.textMultiplier * 2.5, - fontWeight: FontWeight.bold, - - fontFamily: 'Poppins', - ), + ), + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), + child: Row( + children: [ + Expanded( + child: AppButton( + title: TranslationBase.of(context).accept, + color: Color(0xFF4BA821), + fontColor: Colors.white, + fontSize: 1.6, + hPadding: 8, + vPadding: 12, + onPressed: () async { + await model.responseReferral(referralPatient, true); + if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); + } else { + DrAppToastMsg.showSuccesToast( + TranslationBase.of(context) + .referralSuccessMsgAccept); + Navigator.pop(context); + Navigator.pop(context); + } + }, ), - ]), - ), - Container( - child: Center( - child: AppText( - TranslationBase.of(context).patientNoDetailErrMsg, - color: HexColor("#B8382B"), - fontWeight: FontWeight.bold, - fontSize: 16, + ), + SizedBox( + width: 8, + ), + Expanded( + child: AppButton( + title: TranslationBase.of(context).reject, + color: Color(0xFFB9382C), + fontColor: Colors.white, + fontSize: 1.6, + hPadding: 8, + vPadding: 12, + onPressed: () async { + await model.responseReferral(referralPatient, false); + if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); + } else { + DrAppToastMsg.showSuccesToast( + TranslationBase.of(context) + .referralSuccessMsgReject); + Navigator.pop(context); + Navigator.pop(context); + } + }, ), ), - ), - ], + ], + ), ), - ), + ], + )), ); } } diff --git a/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart b/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart index 3ebd7896..48299bf2 100644 --- a/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart @@ -1,6 +1,7 @@ import 'package:doctor_app_flutter/core/enum/PatientType.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-referral-viewmodel.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/referral/my-referral-detail-screen.dart'; import 'package:doctor_app_flutter/screens/patients/profile/referral/referral_patient_detail_in-paint.dart'; import 'package:doctor_app_flutter/screens/patients/profile/referral/referred-patient-screen.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; @@ -13,6 +14,8 @@ import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'my-referral-patient-screen.dart'; + class MyReferralInPatientScreen extends StatelessWidget { PatientType patientType = PatientType.IN_PATIENT; @@ -70,12 +73,22 @@ class MyReferralInPatientScreen extends StatelessWidget { model.myReferralPatients.length, (index) => InkWell( onTap: () { - Navigator.push( - context, - FadePage( - page: ReferralPatientDetailScreen(model.myReferralPatients[index], model), - ), - ); + if(patientType == PatientType.OUT_PATIENT) { + Navigator.push( + context, + FadePage( + page: MyReferralDetailScreen(referralPatient: model.myReferralPatients[index]), + ), + ); + } else{ + Navigator.push( + context, + FadePage( + page: ReferralPatientDetailScreen(model.myReferralPatients[index], model), + ), + ); + } + }, child: PatientReferralItemWidget( referralStatus: model.getReferralStatusNameByCode( diff --git a/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart b/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart index 66e01364..50bd0a9e 100644 --- a/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart +++ b/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart @@ -433,7 +433,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { ], ), ), - if (referredPatient.referredDoctorRemarks.isNotEmpty) + if (referredPatient.referredDoctorRemarks!= null && referredPatient.referredDoctorRemarks.isNotEmpty) Container( width: double.infinity, margin: EdgeInsets.symmetric(horizontal: 16, vertical: 0), @@ -492,7 +492,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { widget: AddReplayOnReferralPatient( patientReferralViewModel: patientReferralViewModel, myReferralInPatientModel: referredPatient, - isEdited: referredPatient.referredDoctorRemarks.isNotEmpty, + isEdited: referredPatient.referredDoctorRemarks!=null && referredPatient.referredDoctorRemarks.isNotEmpty, ), ), ); diff --git a/lib/screens/patients/profile/referral/referred-patient-screen.dart b/lib/screens/patients/profile/referral/referred-patient-screen.dart index c95a28d8..3aa43855 100644 --- a/lib/screens/patients/profile/referral/referred-patient-screen.dart +++ b/lib/screens/patients/profile/referral/referred-patient-screen.dart @@ -79,6 +79,7 @@ class ReferredPatientScreen extends StatelessWidget { ), ); }, + /// TODO Elham* check why we call fun to access attribute child: PatientReferralItemWidget( referralStatus: model .getReferredPatientItem(index) diff --git a/lib/widgets/patients/profile/profile_medical_info_widget_search.dart b/lib/widgets/patients/profile/profile_medical_info_widget_search.dart index ac33eb82..573ada32 100644 --- a/lib/widgets/patients/profile/profile_medical_info_widget_search.dart +++ b/lib/widgets/patients/profile/profile_medical_info_widget_search.dart @@ -46,500 +46,168 @@ class ProfileMedicalInfoWidgetSearch extends StatelessWidget { height: MediaQuery.of(context).size.height * 1.0, width: double.infinity, child: Scaffold( - appBar: AppBar( - backgroundColor: Colors.white, - toolbarHeight: 55, - elevation: 0, - bottom: TabBar( - controller: _tabController, - indicator: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(10), // Creates border - color: Color(0xffD02126), - ), - //isScrollable: true, - - //indicatorWeight: 4.0, - indicatorColor: Colors.red[500], - - // labelPadding: - // EdgeInsets.symmetric(horizontal: 13.0, vertical: 2.0), - unselectedLabelColor: Color(0xff5A6168), - labelColor: Colors.white, - tabs: [ - Container( - width: MediaQuery.of(context).size.width * 0.35, - height: MediaQuery.of(context).size.height * 0.06, - child: Center( - child: Text('Inpatient Info'), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.35, - height: MediaQuery.of(context).size.height * 0.06, - child: Center( - child: Text('OutPatient Info'), - ), - ), - ]), - ), - body: Padding( - padding: const EdgeInsets.symmetric(vertical: 15.0), - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [ - GridView.count( - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - crossAxisSpacing: 10, - mainAxisSpacing: 10, - childAspectRatio: 1 / 1.0, - crossAxisCount: 3, - children: [ - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - from: from, - to: to, - nameLine1: TranslationBase.of(context).vital, - nameLine2: TranslationBase.of(context).signs, - route: VITAL_SIGN_DETAILS, - isInPatient: true, - icon: 'patient/vital_signs.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: LAB_RESULT, - isInPatient: true, - nameLine1: TranslationBase.of(context).lab, - nameLine2: TranslationBase.of(context).result, - icon: 'patient/lab_results.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - isInPatient: isInpatient, - route: RADIOLOGY_PATIENT, - nameLine1: TranslationBase.of(context).radiology, - nameLine2: TranslationBase.of(context).result, - icon: 'patient/health_summary.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: ORDER_PRESCRIPTION_NEW, - nameLine1: TranslationBase.of(context).patient, - nameLine2: TranslationBase.of(context).prescription, - icon: 'patient/order_prescription.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: PROGRESS_NOTE, - isDischargedPatient: isDischargedPatient, - nameLine1: TranslationBase.of(context).progress, - nameLine2: TranslationBase.of(context).note, - icon: 'patient/Progress_notes.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: ORDER_NOTE, - isDischargedPatient: isDischargedPatient, - nameLine1: "Order", //"Text", - nameLine2: - "Sheet", //TranslationBase.of(context).orders, - icon: 'patient/Progress_notes.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: ORDER_PROCEDURE, - nameLine1: TranslationBase.of(context).orders, - nameLine2: TranslationBase.of(context).procedures, - icon: 'patient/Order_Procedures.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: HEALTH_SUMMARY, - nameLine1: "Health", - //TranslationBase.of(context).medicalReport, - nameLine2: "Summary", - //TranslationBase.of(context).summaryReport, - icon: 'patient/health_summary.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - isDisable: true, - route: HEALTH_SUMMARY, - nameLine1: "Medical", //Health - //TranslationBase.of(context).medicalReport, - nameLine2: "Report", //Report - //TranslationBase.of(context).summaryReport, - icon: 'patient/health_summary.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: REFER_IN_PATIENT_TO_DOCTOR, - isInPatient: true, - nameLine1: TranslationBase.of(context).referral, - nameLine2: TranslationBase.of(context).patient, - icon: 'patient/refer_patient.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: PATIENT_INSURANCE_APPROVALS_NEW, - nameLine1: TranslationBase.of(context).insurance, - nameLine2: TranslationBase.of(context).approvals, - icon: 'patient/vital_signs.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - isDisable: true, - route: null, - nameLine1: "Discharge", - nameLine2: "Summery", - icon: 'patient/patient_sick_leave.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: ADD_SICKLEAVE, - nameLine1: TranslationBase.of(context).patientSick, - nameLine2: TranslationBase.of(context).leave, - icon: 'patient/patient_sick_leave.png'), - ], - ), - GridView.count( - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - crossAxisSpacing: 10, - mainAxisSpacing: 10, - childAspectRatio: 1 / 1.0, - crossAxisCount: 3, - children: [ - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - from: from, - to: to, - nameLine1: TranslationBase.of(context).vital, - nameLine2: TranslationBase.of(context).signs, - route: VITAL_SIGN_DETAILS, - icon: 'patient/vital_signs.png'), - // if (selectedPatientType != 7) - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: HEALTH_SUMMARY, - nameLine1: - "Health", //TranslationBase.of(context).medicalReport, - nameLine2: - "Summary", //TranslationBase.of(context).summaryReport, - icon: 'patient/health_summary.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: LAB_RESULT, - nameLine1: TranslationBase.of(context).lab, - nameLine2: TranslationBase.of(context).result, - icon: 'patient/lab_results.png'), - // if (int.parse(patientType) == 7 || int.parse(patientType) == 6) - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - isInPatient: isInpatient, - route: RADIOLOGY_PATIENT, - nameLine1: TranslationBase.of(context).radiology, - nameLine2: TranslationBase.of(context).service, - icon: 'patient/health_summary.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: PATIENT_ECG, - nameLine1: TranslationBase.of(context).patient, - nameLine2: "ECG", - icon: 'patient/patient_sick_leave.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: ORDER_PRESCRIPTION_NEW, - nameLine1: TranslationBase.of(context).orders, - nameLine2: TranslationBase.of(context).prescription, - icon: 'patient/order_prescription.png'), - // if (int.parse(patientType) == 7 || int.parse(patientType) == 6) - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: ORDER_PROCEDURE, - nameLine1: TranslationBase.of(context).orders, - nameLine2: TranslationBase.of(context).procedures, - icon: 'patient/Order_Procedures.png'), - //if (int.parse(patientType) == 7 || int.parse(patientType) == 6) - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: PATIENT_INSURANCE_APPROVALS_NEW, - nameLine1: TranslationBase.of(context).insurance, - nameLine2: TranslationBase.of(context).service, - icon: 'patient/vital_signs.png'), - // if (int.parse(patientType) == 7 || int.parse(patientType) == 6) - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: ADD_SICKLEAVE, - nameLine1: TranslationBase.of(context).patientSick, - nameLine2: TranslationBase.of(context).leave, - icon: 'patient/patient_sick_leave.png'), - if (patient.appointmentNo != null && - patient.appointmentNo != 0) - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: PATIENT_UCAF_REQUEST, - isDisable: - patient.patientStatusType != 43 ? true : false, - nameLine1: TranslationBase.of(context).patient, - nameLine2: TranslationBase.of(context).ucaf, - icon: 'patient/ucaf.png'), - if (patient.appointmentNo != null && - patient.appointmentNo != 0) - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: REFER_PATIENT_TO_DOCTOR, - isDisable: - patient.patientStatusType != 43 ? true : false, - nameLine1: TranslationBase.of(context).referral, - nameLine2: TranslationBase.of(context).patient, - icon: 'patient/refer_patient.png'), - if (patient.appointmentNo != null && - patient.appointmentNo != 0) - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: PATIENT_ADMISSION_REQUEST, - isDisable: - patient.patientStatusType != 43 ? true : false, - nameLine1: TranslationBase.of(context).admission, - nameLine2: TranslationBase.of(context).request, - icon: 'patient/admission_req.png'), - if (isInpatient) - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: PROGRESS_NOTE, - nameLine1: TranslationBase.of(context).progress, - nameLine2: TranslationBase.of(context).note, - icon: 'patient/Progress_notes.png'), - if (isInpatient) - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: ORDER_NOTE, - nameLine1: "Order", //"Text", - nameLine2: "Sheet", - icon: 'patient/Progress_notes.png'), - ], - ), - ], - ), + body: GridView.count( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + crossAxisSpacing: 8, + mainAxisSpacing: 10, + childAspectRatio: 1 / 1.0, + crossAxisCount: 3, + children: [ + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + from: from, + to: to, + nameLine1: TranslationBase.of(context).vital, + nameLine2: TranslationBase.of(context).signs, + route: VITAL_SIGN_DETAILS, + icon: 'patient/vital_signs.png'), + // if (selectedPatientType != 7) + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: HEALTH_SUMMARY, + nameLine1: + "Health", //TranslationBase.of(context).medicalReport, + nameLine2: + "Summary", //TranslationBase.of(context).summaryReport, + icon: 'patient/health_summary.png'), + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: LAB_RESULT, + nameLine1: TranslationBase.of(context).lab, + nameLine2: TranslationBase.of(context).result, + icon: 'patient/lab_results.png'), + // if (int.parse(patientType) == 7 || int.parse(patientType) == 6) + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + isInPatient: isInpatient, + route: RADIOLOGY_PATIENT, + nameLine1: TranslationBase.of(context).radiology, + nameLine2: TranslationBase.of(context).service, + icon: 'patient/health_summary.png'), + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: PATIENT_ECG, + nameLine1: TranslationBase.of(context).patient, + nameLine2: "ECG", + icon: 'patient/patient_sick_leave.png'), + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: ORDER_PRESCRIPTION_NEW, + nameLine1: TranslationBase.of(context).orders, + nameLine2: TranslationBase.of(context).prescription, + icon: 'patient/order_prescription.png'), + // if (int.parse(patientType) == 7 || int.parse(patientType) == 6) + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: ORDER_PROCEDURE, + nameLine1: TranslationBase.of(context).orders, + nameLine2: TranslationBase.of(context).procedures, + icon: 'patient/Order_Procedures.png'), + //if (int.parse(patientType) == 7 || int.parse(patientType) == 6) + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: PATIENT_INSURANCE_APPROVALS_NEW, + nameLine1: TranslationBase.of(context).insurance, + nameLine2: TranslationBase.of(context).service, + icon: 'patient/vital_signs.png'), + // if (int.parse(patientType) == 7 || int.parse(patientType) == 6) + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: ADD_SICKLEAVE, + nameLine1: TranslationBase.of(context).patientSick, + nameLine2: TranslationBase.of(context).leave, + icon: 'patient/patient_sick_leave.png'), + if (patient.appointmentNo != null && + patient.appointmentNo != 0) + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: PATIENT_UCAF_REQUEST, + isDisable: + patient.patientStatusType != 43 ? true : false, + nameLine1: TranslationBase.of(context).patient, + nameLine2: TranslationBase.of(context).ucaf, + icon: 'patient/ucaf.png'), + if (patient.appointmentNo != null && + patient.appointmentNo != 0) + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: REFER_PATIENT_TO_DOCTOR, + isDisable: + patient.patientStatusType != 43 ? true : false, + nameLine1: TranslationBase.of(context).referral, + nameLine2: TranslationBase.of(context).patient, + icon: 'patient/refer_patient.png'), + if (patient.appointmentNo != null && + patient.appointmentNo != 0) + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: PATIENT_ADMISSION_REQUEST, + isDisable: + patient.patientStatusType != 43 ? true : false, + nameLine1: TranslationBase.of(context).admission, + nameLine2: TranslationBase.of(context).request, + icon: 'patient/admission_req.png'), + if (isInpatient) + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: PROGRESS_NOTE, + nameLine1: TranslationBase.of(context).progress, + nameLine2: TranslationBase.of(context).note, + icon: 'patient/Progress_notes.png'), + if (isInpatient) + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: ORDER_NOTE, + nameLine1: "Order", //"Text", + nameLine2: "Sheet", + icon: 'patient/Progress_notes.png'), + ], ), ), ), - - // GridView.count( - // shrinkWrap: true, - // physics: NeverScrollableScrollPhysics(), - // crossAxisSpacing: 10, - // mainAxisSpacing: 10, - // childAspectRatio: 1 / 1.0, - // crossAxisCount: 3, - // children: [ - // PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // from: from, - // to: to, - // nameLine1: TranslationBase.of(context).vital, - // nameLine2: TranslationBase.of(context).signs, - // route: VITAL_SIGN_DETAILS, - // icon: 'patient/vital_signs.png'), - // PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // route: MEDICAL_FILE, - // nameLine1: - // "Health", //TranslationBase.of(context).medicalReport, - // nameLine2: - // "Summary", //TranslationBase.of(context).summaryReport, - // icon: 'patient/health_summary.png'), - // PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // route: LAB_RESULT, - // nameLine1: TranslationBase.of(context).lab, - // nameLine2: TranslationBase.of(context).result, - // icon: 'patient/lab_results.png'), - // PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // isInPatient: isInpatient, - // route: RADIOLOGY_PATIENT, - // nameLine1: TranslationBase.of(context).radiology, - // nameLine2: TranslationBase.of(context).service, - // icon: 'patient/health_summary.png'), - // PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // route: PATIENT_ECG, - // nameLine1: TranslationBase.of(context).patient, - // nameLine2: "ECG", - // icon: 'patient/patient_sick_leave.png'), - // (int.parse(patientType) == 7 || - // int.parse(patientType) == 6) - // ? PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // route: ORDER_PRESCRIPTION_NEW, - // nameLine1: TranslationBase.of(context).orders, - // nameLine2: - // TranslationBase.of(context).prescription, - // icon: 'patient/order_prescription.png') - // : PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // route: ORDER_PRESCRIPTION_NEW, - // nameLine1: TranslationBase.of(context).orders, - // nameLine2: - // TranslationBase.of(context).prescription, - // icon: 'patient/order_prescription.png'), - // PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // route: ORDER_PROCEDURE, - // nameLine1: TranslationBase.of(context).orders, - // nameLine2: TranslationBase.of(context).procedures, - // icon: 'patient/Order_Procedures.png'), - // PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // route: PATIENT_INSURANCE_APPROVALS_NEW, - // nameLine1: TranslationBase.of(context).insurance, - // nameLine2: TranslationBase.of(context).service, - // icon: 'patient/vital_signs.png'), - // PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // route: SHOW_SICKLEAVE, - // nameLine1: TranslationBase.of(context).patientSick, - // nameLine2: TranslationBase.of(context).leave, - // icon: 'patient/patient_sick_leave.png'), - // if (patient.admissionNo != null && - // patient.admissionNo != "0") - // PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // route: PROGRESS_NOTE, - // nameLine1: TranslationBase.of(context).progress, - // nameLine2: TranslationBase.of(context).note, - // icon: 'patient/Progress_notes.png'), - // if (patient.admissionNo != null && - // patient.admissionNo != "0") - // PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // route: ORDER_NOTE, - // nameLine1: "Order", //"Text", - // nameLine2: "Sheet", - // icon: 'patient/Progress_notes.png'), - // if (patient.appointmentNo != null && - // patient.appointmentNo != 0) - // PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // route: REFER_PATIENT_TO_DOCTOR, - // // isDisable: patient.patientStatusType != 43 ? true : false, - // nameLine1: TranslationBase.of(context).referral, - // nameLine2: TranslationBase.of(context).patient, - // icon: 'patient/refer_patient.png'), - // ], - // ), ), ); } From 33f032b6c40aea1f95bd7992ea87fdf4d602e860 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 28 Jun 2021 13:05:47 +0300 Subject: [PATCH 026/289] return from part on header --- .../referral/my-referral-detail-screen.dart | 61 +++++++++---------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart index ffcd871a..b20b29bb 100644 --- a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart @@ -174,37 +174,36 @@ class MyReferralDetailScreen extends StatelessWidget { child: Column( children: [ - //todo Elham* return this - // Row( - // mainAxisAlignment: - // MainAxisAlignment.start, - // children: [ - // AppText( - // TranslationBase.of(context) - // .referredFrom, - // fontFamily: 'Poppins', - // fontWeight: FontWeight.w600, - // fontSize: 1.7 * - // SizeConfig.textMultiplier, - // color: Color(0XFF575757), - // ), - // AppText( - // referralPatient.projectID == model.doctorProfile.projectID - // ? TranslationBase.of( - // context) - // .sameBranch - // : TranslationBase.of( - // context) - // .otherBranch, - // fontFamily: 'Poppins', - // fontWeight: FontWeight.w700, - // fontSize: 1.8 * - // SizeConfig - // .textMultiplier, - // color: Color(0XFF2E303A), - // ), - // ], - // ), + Row( + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context) + .referredFrom, + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + fontSize: 1.7 * + SizeConfig.textMultiplier, + color: Color(0XFF575757), + ), + AppText( + referralPatient.targetProjectId ==referralPatient.sourceProjectId + ? TranslationBase.of( + context) + .sameBranch + : TranslationBase.of( + context) + .otherBranch, + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 1.8 * + SizeConfig + .textMultiplier, + color: Color(0XFF2E303A), + ), + ], + ), Row( mainAxisAlignment: MainAxisAlignment.start, From 74294bfaf54e14add86e3fdcad91ea4312bc7026 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 28 Jun 2021 13:23:09 +0300 Subject: [PATCH 027/289] finish fix referral --- .../referral/MyReferralPatientModel.dart | 23 ++-- .../patient-doctor-referral-service.dart | 2 +- .../referral/my-referral-detail-screen.dart | 105 +++++++++--------- .../my-referral-inpatient-screen.dart | 11 +- 4 files changed, 71 insertions(+), 70 deletions(-) diff --git a/lib/core/model/referral/MyReferralPatientModel.dart b/lib/core/model/referral/MyReferralPatientModel.dart index 09b3769e..4f00f455 100644 --- a/lib/core/model/referral/MyReferralPatientModel.dart +++ b/lib/core/model/referral/MyReferralPatientModel.dart @@ -57,20 +57,6 @@ class MyReferralPatientModel { bool isDoctorLate; bool isDoctorResponse; String nationalityFlagURL; - - - - - - - - - - - - - - String nursingStationName; String priorityDescription; String referringClinicDescription; @@ -84,6 +70,7 @@ class MyReferralPatientModel { int targetDoctorID; int sourceAppointmentNo; int targetAppointmentNo; + String remarksFromSource; MyReferralPatientModel( {this.rowID, @@ -146,7 +133,7 @@ class MyReferralPatientModel { this.priorityDescription, this.referringClinicDescription, this.referringDoctorName, - this.referalStatus, this.sourceSetupID, this.sourceAppointmentNo, this.sourceProjectId, this.targetProjectId, this.targetAppointmentNo, this.targetClinicID, this.targetSetupID, this.targetDoctorID}); + this.referalStatus, this.sourceSetupID, this.sourceAppointmentNo, this.sourceProjectId, this.targetProjectId, this.targetAppointmentNo, this.targetClinicID, this.targetSetupID, this.targetDoctorID, this.remarksFromSource}); MyReferralPatientModel.fromJson(Map json) { rowID = json['RowID']; @@ -230,7 +217,10 @@ class MyReferralPatientModel { targetClinicID = json['TargetClinicID']; targetDoctorID = json['TargetDoctorID']; sourceAppointmentNo = json['SourceAppointmentNo']; - targetAppointmentNo = json['TargetAppointmentNo']; } + targetAppointmentNo = json['TargetAppointmentNo']; + remarksFromSource = json['RemarksFromSource']; + + } Map toJson() { final Map data = new Map(); @@ -303,6 +293,7 @@ class MyReferralPatientModel { data['TargetDoctorID'] = this.targetDoctorID; data['SourceAppointmentNo'] = this.sourceAppointmentNo; data['TargetAppointmentNo'] = this.targetAppointmentNo; + data['RemarksFromSource'] = this.remarksFromSource; return data; } diff --git a/lib/core/service/patient/patient-doctor-referral-service.dart b/lib/core/service/patient/patient-doctor-referral-service.dart index cded130e..5b659631 100644 --- a/lib/core/service/patient/patient-doctor-referral-service.dart +++ b/lib/core/service/patient/patient-doctor-referral-service.dart @@ -254,7 +254,7 @@ class PatientReferralService extends LookupService { body['ProjectID'] = referralPatient.targetProjectId; body['IsAccepted'] = isAccepted; body['PatientName'] = referralPatient.patientName; - body['ReferralResponse'] = referralPatient.referringDoctorRemarks; + body['ReferralResponse'] = referralPatient.remarksFromSource; body['DoctorName'] = doctorProfile.doctorName; await baseAppClient.post( diff --git a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart index b20b29bb..e5cc40da 100644 --- a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart @@ -361,60 +361,63 @@ class MyReferralDetailScreen extends StatelessWidget { ), ), ), - Container( - margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), - child: Row( - children: [ - Expanded( - child: AppButton( - title: TranslationBase.of(context).accept, - color: Color(0xFF4BA821), - fontColor: Colors.white, - fontSize: 1.6, - hPadding: 8, - vPadding: 12, - onPressed: () async { - await model.responseReferral(referralPatient, true); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } else { - DrAppToastMsg.showSuccesToast( - TranslationBase.of(context) - .referralSuccessMsgAccept); - Navigator.pop(context); - Navigator.pop(context); - } - }, + if (referralPatient.referralStatus != 46) + Container( + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), + child: Row( + children: [ + Expanded( + child: AppButton( + title: TranslationBase.of(context).accept, + color: Color(0xFF4BA821), + fontColor: Colors.white, + fontSize: 1.6, + hPadding: 8, + vPadding: 12, + disabled: model.state == ViewState.Busy, + onPressed: () async { + await model.responseReferral(referralPatient, true); + if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); + } else { + DrAppToastMsg.showSuccesToast( + TranslationBase.of(context) + .referralSuccessMsgAccept); + Navigator.pop(context); + Navigator.pop(context); + } + }, + ), ), - ), - SizedBox( - width: 8, - ), - Expanded( - child: AppButton( - title: TranslationBase.of(context).reject, - color: Color(0xFFB9382C), - fontColor: Colors.white, - fontSize: 1.6, - hPadding: 8, - vPadding: 12, - onPressed: () async { - await model.responseReferral(referralPatient, false); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } else { - DrAppToastMsg.showSuccesToast( - TranslationBase.of(context) - .referralSuccessMsgReject); - Navigator.pop(context); - Navigator.pop(context); - } - }, + SizedBox( + width: 8, ), - ), - ], + Expanded( + child: AppButton( + title: TranslationBase.of(context).reject, + color: Color(0xFFB9382C), + fontColor: Colors.white, + fontSize: 1.6, + hPadding: 8, + vPadding: 12, + disabled: model.state == ViewState.Busy, + onPressed: () async { + await model.responseReferral(referralPatient, false); + if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); + } else { + DrAppToastMsg.showSuccesToast( + TranslationBase.of(context) + .referralSuccessMsgReject); + Navigator.pop(context); + Navigator.pop(context); + } + }, + ), + ), + ], + ), ), - ), ], )), ); diff --git a/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart b/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart index 48299bf2..cb6c1e5f 100644 --- a/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart @@ -16,7 +16,12 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'my-referral-patient-screen.dart'; -class MyReferralInPatientScreen extends StatelessWidget { +class MyReferralInPatientScreen extends StatefulWidget { + @override + _MyReferralInPatientScreenState createState() => _MyReferralInPatientScreenState(); +} + +class _MyReferralInPatientScreenState extends State { PatientType patientType = PatientType.IN_PATIENT; @override @@ -33,7 +38,9 @@ class MyReferralInPatientScreen extends StatelessWidget { margin: EdgeInsets.only(top: 70), child: PatientTypeRadioWidget( (patientType) async { - this.patientType = patientType; + setState(() { + this.patientType = patientType; + }); GifLoaderDialogUtils.showMyDialog(context); if (patientType == PatientType.IN_PATIENT) { await model.getMyReferralPatientService(localBusy: true); From 0c730e827080e2e4ff4906d3b05bfe04c1a6d89f Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 28 Jun 2021 14:16:49 +0300 Subject: [PATCH 028/289] change the status condition --- .../patients/profile/referral/my-referral-detail-screen.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart index e5cc40da..fdbf9859 100644 --- a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart @@ -361,7 +361,7 @@ class MyReferralDetailScreen extends StatelessWidget { ), ), ), - if (referralPatient.referralStatus != 46) + if (referralPatient.referralStatus == 1) Container( margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), child: Row( From 93c7797ed4ec8287dca890c431ba5c751d79c04f Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 28 Jun 2021 14:22:03 +0300 Subject: [PATCH 029/289] recall the service --- .../patients/profile/referral/my-referral-detail-screen.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart index fdbf9859..4cc5effd 100644 --- a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart @@ -383,6 +383,7 @@ class MyReferralDetailScreen extends StatelessWidget { DrAppToastMsg.showSuccesToast( TranslationBase.of(context) .referralSuccessMsgAccept); + model.getMyReferralOutPatientService(); Navigator.pop(context); Navigator.pop(context); } @@ -409,6 +410,7 @@ class MyReferralDetailScreen extends StatelessWidget { DrAppToastMsg.showSuccesToast( TranslationBase.of(context) .referralSuccessMsgReject); + model.getMyReferralOutPatientService(); Navigator.pop(context); Navigator.pop(context); } From 0006a4de57b40929cd67ac3cbf82be443c2f3215 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 28 Jun 2021 14:23:49 +0300 Subject: [PATCH 030/289] remove comment --- .../patients/profile/referral/referred-patient-screen.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/screens/patients/profile/referral/referred-patient-screen.dart b/lib/screens/patients/profile/referral/referred-patient-screen.dart index dec6108f..8dce7d60 100644 --- a/lib/screens/patients/profile/referral/referred-patient-screen.dart +++ b/lib/screens/patients/profile/referral/referred-patient-screen.dart @@ -86,7 +86,6 @@ class _ReferredPatientScreenState extends State { ), ); }, - /// TODO Elham* check why we call fun to access attribute child: PatientReferralItemWidget( referralStatus: model .getReferredPatientItem(index) From e8f9c958b12f94213bb32c11f449e15b6bab18fe Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Mon, 28 Jun 2021 17:15:47 +0300 Subject: [PATCH 031/289] Fix medical report issues --- lib/config/config.dart | 4 ++-- .../viewModel/PatientMedicalReportViewModel.dart | 12 ++++++++---- lib/core/viewModel/project_view_model.dart | 4 ++-- .../medical_report/AddVerifyMedicalReport.dart | 4 ++-- .../medical_report/MedicalReportPage.dart | 16 +--------------- 5 files changed, 15 insertions(+), 25 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 2d8e4ea2..d6836827 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -5,8 +5,8 @@ const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; const BASE_URL_LIVE_CARE = 'https://livecare.hmg.com/'; -// const BASE_URL = 'https://hmgwebservices.com/'; -const BASE_URL = 'https://uat.hmgwebservices.com/'; +const BASE_URL = 'https://hmgwebservices.com/'; +// const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = "Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient"; diff --git a/lib/core/viewModel/PatientMedicalReportViewModel.dart b/lib/core/viewModel/PatientMedicalReportViewModel.dart index ac5ecdeb..e7d343b4 100644 --- a/lib/core/viewModel/PatientMedicalReportViewModel.dart +++ b/lib/core/viewModel/PatientMedicalReportViewModel.dart @@ -60,10 +60,12 @@ class PatientMedicalReportViewModel extends BaseViewModel { await _service.addMedicalReport(patient, htmlText); if (_service.hasError) { error = _service.error; + await getMedicalReportList(patient); setState(ViewState.ErrorLocal); } else - await getMedicalReportList(patient); - setState(ViewState.Idle); + { await getMedicalReportList(patient); + setState(ViewState.Idle); + } } Future updateMedicalReport(PatiantInformtion patient, String htmlText, int limitNumber, String invoiceNumber) async { @@ -71,9 +73,11 @@ class PatientMedicalReportViewModel extends BaseViewModel { await _service.updateMedicalReport(patient, htmlText, limitNumber, invoiceNumber); if (_service.hasError) { error = _service.error; + await getMedicalReportList(patient); setState(ViewState.ErrorLocal); } else - await getMedicalReportList(patient); - setState(ViewState.Idle); + { + await getMedicalReportList(patient); + setState(ViewState.Idle);} } } diff --git a/lib/core/viewModel/project_view_model.dart b/lib/core/viewModel/project_view_model.dart index f464df0e..e7b7a80f 100644 --- a/lib/core/viewModel/project_view_model.dart +++ b/lib/core/viewModel/project_view_model.dart @@ -107,8 +107,8 @@ class ProjectViewModel with ChangeNotifier { return Future.value(localRes); } catch (error) { - print(error); - throw error; + //print(error); + //throw error; } } diff --git a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart index 4a6be6c8..b3714edd 100644 --- a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart +++ b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart @@ -103,12 +103,12 @@ class _AddVerifyMedicalReportState extends State { if (txtOfMedicalReport.isNotEmpty) { GifLoaderDialogUtils.showMyDialog(context); widget.medicalReport != null - ? widget.model.updateMedicalReport( + ?await widget.model.updateMedicalReport( widget.patient, txtOfMedicalReport, widget.medicalReport != null ? widget.medicalReport.lineItemNo : null, widget.medicalReport != null ? widget.medicalReport.invoiceNo : null) - : widget.model.addMedicalReport(widget.patient, txtOfMedicalReport); + : await widget.model.addMedicalReport(widget.patient, txtOfMedicalReport); //model.getMedicalReportList(patient); Navigator.pop(context); diff --git a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart index 22645520..a5c367de 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart @@ -92,29 +92,15 @@ class _MedicalReportPageState extends State { )), ); - // Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_INSERT, arguments: { - // 'patient': patient, - // 'patientType': patientType, - // 'arrivalType': arrivalType, - // 'type': MedicalReportStatus.ADD, - // 'model': model, - // }); }, label: TranslationBase.of(context).createNewMedicalReport, ), - if (model.state != ViewState.ErrorLocal) + // if (model.state != ViewState.ErrorLocal)ß ...List.generate( model.medicalReportList.length, (index) => InkWell( onTap: () { if (model.medicalReportList[index].status == 1) { - // Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_INSERT, arguments: { - // 'patient': patient, - // 'patientType': patientType, - // 'arrivalType': arrivalType, - // 'medicalReport': model.medicalReportList[index], - // 'model': model, - // }); Navigator.push( context, MaterialPageRoute( From 158bea519e58e56021c6735559d6adfa6bbc52da Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Mon, 28 Jun 2021 17:20:29 +0300 Subject: [PATCH 032/289] medical report fix --- .../medical_report/PatientMedicalReportService.dart | 2 +- .../profile/medical_report/AddVerifyMedicalReport.dart | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart b/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart index 01a09592..2b0a1c38 100644 --- a/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart +++ b/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart @@ -17,7 +17,7 @@ class PatientMedicalReportService extends BaseService { body['ProjectID'] = doctorProfile.projectID; await baseAppClient.postPatient(PATIENT_MEDICAL_REPORT_GET_LIST, onSuccess: (dynamic response, int statusCode) { - medicalReportList.clear(); + medicalReportList = []; if (response['DAPP_ListMedicalReportList'] != null) { response['DAPP_ListMedicalReportList'].forEach((v) { medicalReportList.add(MedicalReportModel.fromJson(v)); diff --git a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart index 4a6be6c8..b31bb9bb 100644 --- a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart +++ b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart @@ -43,7 +43,9 @@ class _AddVerifyMedicalReportState extends State { String txtOfMedicalReport; return BaseView( - onModelReady: (model) async {}, + onModelReady: (model) async { + model.getMedicalReportTemplate(); + }, builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, From 405a363e2854af505af6a5ba6e60ef3c3455465c Mon Sep 17 00:00:00 2001 From: mosazaid Date: Mon, 28 Jun 2021 17:32:50 +0300 Subject: [PATCH 033/289] referral change --- .../viewModel/patient-referral-viewmodel.dart | 8 +-- .../patient-referral-item-widget.dart | 49 +++++++++++++------ 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/lib/core/viewModel/patient-referral-viewmodel.dart b/lib/core/viewModel/patient-referral-viewmodel.dart index 2e3a6605..4240e848 100644 --- a/lib/core/viewModel/patient-referral-viewmodel.dart +++ b/lib/core/viewModel/patient-referral-viewmodel.dart @@ -303,13 +303,13 @@ class PatientReferralViewModel extends BaseViewModel { String getReferralStatusNameByCode(int statusCode, BuildContext context) { switch (statusCode) { case 1: - return TranslationBase.of(context).pending /*referralStatusHold*/; + return TranslationBase.of(context).referralStatusHold /*pending*/; case 2: - return TranslationBase.of(context).accepted /*referralStatusActive*/; + return TranslationBase.of(context).referralStatusActive /* accepted*/; case 4: - return TranslationBase.of(context).rejected /*referralStatusCancelled*/; + return TranslationBase.of(context).referralStatusCancelled /*rejected*/; case 46: - return TranslationBase.of(context).accepted /*referralStatusCompleted*/; + return TranslationBase.of(context).referralStatusCompleted /*accepted*/; case 63: return TranslationBase.of(context).rejected /*referralStatusNotSeen*/; default: diff --git a/lib/widgets/patients/patient-referral-item-widget.dart b/lib/widgets/patients/patient-referral-item-widget.dart index a898e39c..6d573cc4 100644 --- a/lib/widgets/patients/patient-referral-item-widget.dart +++ b/lib/widgets/patients/patient-referral-item-widget.dart @@ -44,7 +44,9 @@ class PatientReferralItemWidget extends StatelessWidget { this.doctorAvatar, this.referralDoctorName, this.clinicDescription, - this.infoIcon,this.isReferralClinic=false,this.referralClinic}); + this.infoIcon, + this.isReferralClinic = false, + this.referralClinic}); @override Widget build(BuildContext context) { @@ -58,9 +60,13 @@ class PatientReferralItemWidget extends StatelessWidget { child: CardWithBgWidget( bgColor: referralStatusCode == 1 ? Color(0xffc4aa54) - : referralStatusCode == 46 || referralStatusCode == 2 + : referralStatusCode == 2 ? Colors.green[700] - : Colors.red[700], + : referralStatusCode == 46 + ? Colors.green[900] + : referralStatusCode == 4 + ? Colors.red[700] + : Colors.red[900], hasBorder: false, widget: Container( // padding: EdgeInsets.only(left: 20, right: 0, bottom: 0), @@ -78,9 +84,13 @@ class PatientReferralItemWidget extends StatelessWidget { fontWeight: FontWeight.w700, color: referralStatusCode == 1 ? Color(0xffc4aa54) - : referralStatusCode == 46 || referralStatusCode == 2 + : referralStatusCode == 2 ? Colors.green[700] - : Colors.red[700], + : referralStatusCode == 46 + ? Colors.green[900] + : referralStatusCode == 4 + ? Colors.red[700] + : Colors.red[900], ), AppText( referredDate, @@ -158,7 +168,10 @@ class PatientReferralItemWidget extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( - isSameBranch ? TranslationBase.of(context).referredFrom :TranslationBase.of(context).refClinic, + isSameBranch + ? TranslationBase.of(context) + .referredFrom + : TranslationBase.of(context).refClinic, fontFamily: 'Poppins', fontWeight: FontWeight.w600, fontSize: 1.7 * SizeConfig.textMultiplier, @@ -166,7 +179,13 @@ class PatientReferralItemWidget extends StatelessWidget { ), Expanded( child: AppText( - !isReferralClinic? isSameBranch ? TranslationBase.of(context).sameBranch : TranslationBase.of(context).otherBranch: " "+referralClinic, + !isReferralClinic + ? isSameBranch + ? TranslationBase.of(context) + .sameBranch + : TranslationBase.of(context) + .otherBranch + : " " + referralClinic, fontFamily: 'Poppins', fontWeight: FontWeight.w700, fontSize: 1.8 * SizeConfig.textMultiplier, @@ -217,7 +236,7 @@ class PatientReferralItemWidget extends StatelessWidget { ), Expanded( child: AppText( - remark??"", + remark ?? "", fontFamily: 'Poppins', fontWeight: FontWeight.w700, fontSize: 1.8 * SizeConfig.textMultiplier, @@ -261,13 +280,13 @@ class PatientReferralItemWidget extends StatelessWidget { }, )) : Container( - child: Image.asset( - patientGender == 1 - ? 'assets/images/male_avatar.png' - : 'assets/images/female_avatar.png', - fit: BoxFit.cover, - ), - ), + child: Image.asset( + patientGender == 1 + ? 'assets/images/male_avatar.png' + : 'assets/images/female_avatar.png', + fit: BoxFit.cover, + ), + ), ), ), Expanded( From 4c8f79c87e92c1302e80f6d8575f6ba67422c45f Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Mon, 28 Jun 2021 17:58:50 +0300 Subject: [PATCH 034/289] Fix medical report issues --- .../medical_report/PatientMedicalReportService.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart b/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart index 01a09592..dfb9c3ae 100644 --- a/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart +++ b/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart @@ -15,9 +15,8 @@ class PatientMedicalReportService extends BaseService { body['AdmissionNo'] = patient.admissionNo; body['SetupID'] = doctorProfile.setupID; body['ProjectID'] = doctorProfile.projectID; - + medicalReportList = []; await baseAppClient.postPatient(PATIENT_MEDICAL_REPORT_GET_LIST, onSuccess: (dynamic response, int statusCode) { - medicalReportList.clear(); if (response['DAPP_ListMedicalReportList'] != null) { response['DAPP_ListMedicalReportList'].forEach((v) { medicalReportList.add(MedicalReportModel.fromJson(v)); From eb40cc819d15a3632b6c15c16aebbcca5311ef83 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Wed, 30 Jun 2021 10:51:42 +0300 Subject: [PATCH 035/289] fix video call --- lib/models/livecare/start_call_res.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/models/livecare/start_call_res.dart b/lib/models/livecare/start_call_res.dart index e3c1a54f..44921d5f 100644 --- a/lib/models/livecare/start_call_res.dart +++ b/lib/models/livecare/start_call_res.dart @@ -24,7 +24,7 @@ class StartCallRes { isAuthenticated = json['IsAuthenticated']; messageStatus = json['MessageStatus']; appointmentNo = json['AppointmentNo']; - isRecording = json['isRecording']; + isRecording = json['IsRecordedSession'] ?? false; } Map toJson() { @@ -35,7 +35,7 @@ class StartCallRes { data['IsAuthenticated'] = this.isAuthenticated; data['MessageStatus'] = this.messageStatus; data['AppointmentNo'] = this.appointmentNo; - data['isRecording'] = this.isRecording; + data['IsRecordedSession'] = this.isRecording ?? false; return data; } } From 7cc25f6101640c87bf685f17d3f98fde12e88c2e Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 30 Jun 2021 14:41:51 +0300 Subject: [PATCH 036/289] make floating video screen --- android/app/src/main/AndroidManifest.xml | 11 +- .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 261 ++-- .../VideoStreamFloatingWidgetService.kt | 1057 +++++++++++++++++ .../hmgDr/ui/fragment/VideoCallFragment.kt | 5 +- .../kotlin/com/hmg/hmgDr/util/viewsUtil.kt | 17 + lib/config/config.dart | 4 +- lib/core/service/VideoCallService.dart | 13 +- lib/screens/home/home_screen.dart | 43 +- .../patient_profile_screen.dart | 27 +- 9 files changed, 1262 insertions(+), 176 deletions(-) create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 0ac76ea8..7c18e957 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -12,6 +12,9 @@ + + + @@ -41,7 +44,13 @@ - + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 7c18e957..2bd477be 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -10,7 +10,7 @@ FlutterApplication and put your custom class here. --> - + diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt index 670facf1..e20eef1e 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -14,9 +14,8 @@ import android.util.Log import android.widget.Toast import androidx.annotation.NonNull import com.google.gson.GsonBuilder -import com.hmg.hmgDr.Model.GetSessionStatusModel -import com.hmg.hmgDr.Model.SessionStatusModel -import com.hmg.hmgDr.Service.VideoStreamContainerService +import com.hmg.hmgDr.model.GetSessionStatusModel +import com.hmg.hmgDr.model.SessionStatusModel import com.hmg.hmgDr.Service.VideoStreamFloatingWidgetService import com.hmg.hmgDr.ui.VideoCallResponseListener import io.flutter.embedding.android.FlutterFragmentActivity @@ -115,6 +114,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, serviceIntent = Intent(this@MainActivity, VideoStreamFloatingWidgetService::class.java) serviceIntent?.run { putExtras(arguments) + action = VideoStreamFloatingWidgetService.ACTION_START_CALL } checkFloatingWidgetPermission() } @@ -145,6 +145,13 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, bindService() } + override fun onDestroy() { + super.onDestroy() + if (bound) { + unbindService() + } + } + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { /*if (requestCode == LAUNCH_VIDEO) { if (resultCode == Activity.RESULT_OK) { @@ -230,7 +237,13 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, } else { super.onBackPressed() } + } + override fun onPause() { + if (videoStreamService != null && videoStreamService?.serviceRunning == true && videoStreamService?.isFullScreen!!) { + videoStreamService!!.onMinimizedClicked() + } + super.onPause() } // override fun onStart() { @@ -279,5 +292,4 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, } } - } diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/Service/SessionStatusAPI.java b/android/app/src/main/kotlin/com/hmg/hmgDr/Service/SessionStatusAPI.java index e507650e..7c458b25 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/Service/SessionStatusAPI.java +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/Service/SessionStatusAPI.java @@ -1,8 +1,8 @@ package com.hmg.hmgDr.Service; -import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel; -import com.hmg.hmgDr.Model.GetSessionStatusModel; -import com.hmg.hmgDr.Model.SessionStatusModel; +import com.hmg.hmgDr.model.ChangeCallStatusRequestModel; +import com.hmg.hmgDr.model.GetSessionStatusModel; +import com.hmg.hmgDr.model.SessionStatusModel; import retrofit2.Call; diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt index 1ff2a2c2..f79f23a4 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt @@ -1,10 +1,10 @@ package com.hmg.hmgDr.Service import android.annotation.SuppressLint -import android.app.Activity -import android.app.Service +import android.app.* import android.content.Context import android.content.Intent +import android.graphics.BitmapFactory import android.graphics.PixelFormat import android.graphics.Point import android.opengl.GLSurfaceView @@ -13,20 +13,25 @@ import android.util.Log import android.view.* import android.widget.* import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationManagerCompat import androidx.core.content.ContextCompat import androidx.core.view.GestureDetectorCompat -import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel -import com.hmg.hmgDr.Model.GetSessionStatusModel -import com.hmg.hmgDr.Model.SessionStatusModel import com.hmg.hmgDr.R +import com.hmg.hmgDr.model.ChangeCallStatusRequestModel +import com.hmg.hmgDr.model.GetSessionStatusModel +import com.hmg.hmgDr.model.NotificationVideoModel +import com.hmg.hmgDr.model.SessionStatusModel import com.hmg.hmgDr.ui.VideoCallContract import com.hmg.hmgDr.ui.VideoCallPresenterImpl import com.hmg.hmgDr.ui.VideoCallResponseListener import com.hmg.hmgDr.util.DynamicVideoRenderer +import com.hmg.hmgDr.util.NotificationUtil import com.hmg.hmgDr.util.ViewsUtil import com.opentok.android.* import kotlin.math.ceil + class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, PublisherKit.PublisherListener, SubscriberKit.VideoListener, VideoCallContract.VideoCallView { @@ -39,6 +44,14 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, private const val RC_SETTINGS_SCREEN_PERM = 123 private const val RC_VIDEO_APP_PERM = 124 + const val CHANNEL_DEFAULT_IMPORTANCE = "Video_stream_channel" + const val CHANNEL_DEFAULT_NAME = "Video cAll" + const val ONGOING_NOTIFICATION_ID = 1 + + + const val ACTION_START_CALL = "com.hmg.hmgDr.Service.action.startCall" + const val ACTION_MINIMIZE_CALL = "com.hmg.hmgDr.Service.action.minimizeCall" + const val ACTION_END_CALL = "com.hmg.hmgDr.Service.action.endCall" } private lateinit var windowManagerParams: WindowManager.LayoutParams @@ -111,35 +124,52 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, private val serviceBinder: IBinder = VideoStreamBinder() + // Notification variables + private lateinit var mNotificationManagerCompat: NotificationManagerCompat + override fun onBind(intent: Intent?): IBinder { return serviceBinder } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { - if (intent != null && intent.extras != null) { - arguments = intent.extras - - arguments?.run { - apiKey = getString("apiKey") - sessionId = getString("sessionId") - token = getString("token") - appLang = getString("appLang") - baseUrl = getString("baseUrl") - sessionStatusModel = getParcelable("sessionStatusModel") - if (sessionStatusModel != null) - isRecording = sessionStatusModel!!.isRecording - } + if (intent != null) { + + val action = intent.action - //init WindowManager - mWindowManager = getSystemService(WINDOW_SERVICE) as WindowManager + if (action == ACTION_START_CALL) { + if (intent.extras != null) { + arguments = intent.extras + arguments?.run { + apiKey = getString("apiKey") + sessionId = getString("sessionId") + token = getString("token") + appLang = getString("appLang") + baseUrl = getString("baseUrl") + sessionStatusModel = getParcelable("sessionStatusModel") + if (sessionStatusModel != null) + isRecording = sessionStatusModel!!.isRecording + } - getWindowManagerDefaultDisplay() + //init WindowManager + mWindowManager = getSystemService(WINDOW_SERVICE) as WindowManager - //Init LayoutInflater - val inflater = getSystemService(LAYOUT_INFLATER_SERVICE) as LayoutInflater + getWindowManagerDefaultDisplay() + + //Init LayoutInflater + val inflater = getSystemService(LAYOUT_INFLATER_SERVICE) as LayoutInflater + + addFloatingWidgetView(inflater) + handleDragDialog() + + addForegroundService() + } + } else if (action == ACTION_END_CALL) { + closeVideoCall() + } else if (action == ACTION_MINIMIZE_CALL) { + if (!isFullScreen) + onMinimizedClicked() + } - addFloatingWidgetView(inflater) - handleDragDialog() } // Toast.makeText(this, "Service started by user.", Toast.LENGTH_LONG).show() return START_STICKY @@ -308,7 +338,10 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, videoCallPresenter.callClintConnected(sessionStatusModel) } } - mConnectedHandler!!.postDelayed(mConnectedRunnable!!, (10 * 1000).toLong()) // TODO MOSA return from 10 to 55 + mConnectedHandler!!.postDelayed( + mConnectedRunnable!!, + (55 * 1000).toLong() + ) } private fun handleVideoViewHeight() { @@ -726,6 +759,7 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, private fun disconnectSession() { if (mSession == null) { videoCallResponseListener?.onCallFinished(Activity.RESULT_CANCELED) + stopForeground(true) stopSelf() return } @@ -753,6 +787,7 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, sessionStatusModel!!.vcid ) ) + stopForeground(true) stopSelf() } @@ -865,6 +900,7 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, disconnectSession() videoCallResponseListener?.onCallFinished(Activity.RESULT_OK, returnIntent) stopSelf() + stopForeground(true) } } @@ -889,6 +925,158 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, ).toInt() } + private fun addForegroundService() { + mNotificationManagerCompat = NotificationManagerCompat.from(applicationContext) + val areNotificationsEnabled = mNotificationManagerCompat.areNotificationsEnabled() + if (!areNotificationsEnabled) { + Toast.makeText( + this, + "You need to enable notifications for this app", + Toast.LENGTH_SHORT + ).show() + // Links to this app's notification settings + openNotificationSettingsForApp() + return + } + generateBigTextStyleNotification() + } + + private fun generateBigTextStyleNotification() { + val notificationData: NotificationVideoModel = + NotificationVideoModel( + sessionStatusModel!!.patientName, + "Tap to return to call", + CHANNEL_DEFAULT_IMPORTANCE, + CHANNEL_DEFAULT_NAME, + "Video call stream background", + mSummaryText = "timer" + ) + // 1. Create/Retrieve Notification Channel for O and beyond devices (26+). + val notificationChannelId: String = + NotificationUtil.createNotificationChannel(this, notificationData) + + // 2. Build the BIG_TEXT_STYLE. + val bigTextStyle = + NotificationCompat.BigTextStyle() // Overrides ContentText in the big form of the template. + .bigText(notificationData.mBigText) // Overrides ContentTitle in the big form of the template. + .setBigContentTitle(notificationData.mBigContentTitle) // Summary line after the detail section in the big form of the template. + // Note: To improve readability, don't overload the user with info. If Summary Text + // doesn't add critical information, you should skip it. + .setSummaryText(notificationData.mSummaryText) + + // 3. Set up main Intent for notification. + val pendingIntent: PendingIntent = + Intent(this, VideoStreamFloatingWidgetService::class.java) + .let { notificationIntent -> + notificationIntent.action = ACTION_MINIMIZE_CALL + PendingIntent.getService(this, 0, notificationIntent, 0) + } + + // 4. Create additional Actions (Intents) for the Notification. + // Dismiss Action. + val endCallPendingIntent: PendingIntent = + Intent(this, VideoStreamFloatingWidgetService::class.java).apply { + action = ACTION_END_CALL + } + .let { notificationIntent -> + PendingIntent.getService(this, 0, notificationIntent, 0) + } +// val endCallAction = NotificationCompat.Action.Builder( +// R.drawable.ic_end_call, +// "End Call", +// endCallPendingIntent +// ) +// .build() + + // 5. Build and issue the notification. + // Notification Channel Id is ignored for Android pre O (26). + + + // 5. Build and issue the notification. + // Notification Channel Id is ignored for Android pre O (26). + val notificationCompatBuilder = notificationChannelId?.let { + NotificationCompat.Builder( + applicationContext, it + ) + } + + // notification's layout + val mRemoteViews = RemoteViews(packageName, R.layout.notifi_video_view) + mRemoteViews.setImageViewResource(R.id.iv_icon, R.mipmap.ic_launcher) + // notification's title + mRemoteViews.setTextViewText(R.id.notify_title, notificationData.mContentTitle) + // notification's content + mRemoteViews.setTextViewText(R.id.notify_content, notificationData.mContentText) + mRemoteViews.setOnClickPendingIntent(R.id.btn_end, endCallPendingIntent) + + val notification: Notification = notificationCompatBuilder + // BIG_TEXT_STYLE sets title and content for API 16 (4.1 and after). + .setStyle(bigTextStyle) + // Title for API <16 (4.0 and below) devices. + .setContentTitle(notificationData.mBigContentTitle) + // Content for API <24 (7.0 and below) devices. + .setContentText(notificationData.mContentText) + .setSmallIcon(R.mipmap.ic_launcher) + .setLargeIcon( + BitmapFactory.decodeResource( + resources, + R.mipmap.ic_launcher + ) + ) + .setCustomContentView(mRemoteViews) + .setCustomBigContentView(mRemoteViews) + .setContentIntent(pendingIntent) + .setDefaults(NotificationCompat.DEFAULT_ALL) + // Set primary color (important for Wear 2.0 Notifications). + .setColor(ContextCompat.getColor(applicationContext, R.color.colorPrimary)) + .setCategory(Notification.CATEGORY_SERVICE) + .setPriority(notificationData.mPriority) + .setVisibility(notificationData.mChannelLockscreenVisibility) +// .addAction(endCallAction) + .build() + + mNotificationManagerCompat.notify(ONGOING_NOTIFICATION_ID, notification) + + startForeground(ONGOING_NOTIFICATION_ID, notification) + /*val notification: Notification = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + Notification.Builder(this, CHANNEL_DEFAULT_IMPORTANCE) + .setContentTitle("") + .setContentText("") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentIntent(pendingIntent) + .setOngoing(true) + .build() + } else { + Notification.Builder(this) + .setContentTitle("") + .setContentText("") + .setSmallIcon(R.mipmap.ic_launcher) + .setOngoing(true) + .setContentIntent(pendingIntent) + .build() + } + // Notification ID cannot be 0. + */ + } + + /** + * IMPORTANT NOTE: You should not do this action unless the user takes an action to see your + * Notifications like this sample demonstrates. Spamming users to re-enable your notifications + * is a bad idea. + */ + private fun openNotificationSettingsForApp() { + // Links to this app's notification settings. + val intent = Intent() + intent.action = "android.settings.APP_NOTIFICATION_SETTINGS" + intent.putExtra("app_package", packageName) + intent.putExtra("app_uid", applicationInfo.uid) + + // for Android 8 and above + intent.putExtra("android.provider.extra.APP_PACKAGE", packageName) + startActivity(intent) + } + + /** * OnTouch actions */ @@ -1001,7 +1189,11 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, mParams.x = (szWindow.x - current_x_cord * current_x_cord - videoCallContainer.width).toInt() - mWindowManager?.updateViewLayout(floatingWidgetView, mParams) + try { + mWindowManager?.updateViewLayout(floatingWidgetView, mParams) + } catch (e: Exception) { + Log.e("windowManagerUpdate", "${e.localizedMessage}.") + } val x = szWindow.x - current_x_cord object : CountDownTimer(500, 5) { //get params of Floating Widget view @@ -1014,13 +1206,21 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, mParams.x = (szWindow.x - current_x_cord * current_x_cord * step - videoCallContainer.width).toInt() - mWindowManager?.updateViewLayout(floatingWidgetView, mParams) + try { + mWindowManager?.updateViewLayout(floatingWidgetView, mParams) + } catch (e: Exception) { + Log.e("windowManagerUpdate", "${e.localizedMessage}.") + } } override fun onFinish() { mParams.x = -(szWindow.x - videoCallContainer.width) - mWindowManager?.updateViewLayout(floatingWidgetView, mParams) + try { + mWindowManager?.updateViewLayout(floatingWidgetView, mParams) + } catch (e: Exception) { + Log.e("windowManagerUpdate", "${e.localizedMessage}.") + } } }.start() } @@ -1042,7 +1242,12 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, mParams.x = (szWindow.x + current_x_cord * current_x_cord * step - videoCallContainer.width).toInt() - mWindowManager?.updateViewLayout(floatingWidgetView, mParams) + try { + mWindowManager?.updateViewLayout(floatingWidgetView, mParams) + } catch (e: Exception) { + Log.e("windowManagerUpdate", "${e.localizedMessage}.") + } + } override fun onFinish() { diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/Model/ChangeCallStatusRequestModel.java b/android/app/src/main/kotlin/com/hmg/hmgDr/model/ChangeCallStatusRequestModel.java similarity index 99% rename from android/app/src/main/kotlin/com/hmg/hmgDr/Model/ChangeCallStatusRequestModel.java rename to android/app/src/main/kotlin/com/hmg/hmgDr/model/ChangeCallStatusRequestModel.java index 5fcdb611..c7993d5f 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/Model/ChangeCallStatusRequestModel.java +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/model/ChangeCallStatusRequestModel.java @@ -1,4 +1,4 @@ -package com.hmg.hmgDr.Model; +package com.hmg.hmgDr.model; import android.os.Parcel; diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/Model/GetSessionStatusModel.java b/android/app/src/main/kotlin/com/hmg/hmgDr/model/GetSessionStatusModel.java similarity index 99% rename from android/app/src/main/kotlin/com/hmg/hmgDr/Model/GetSessionStatusModel.java rename to android/app/src/main/kotlin/com/hmg/hmgDr/model/GetSessionStatusModel.java index 9e2e1cf4..32b3a96c 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/Model/GetSessionStatusModel.java +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/model/GetSessionStatusModel.java @@ -1,4 +1,4 @@ -package com.hmg.hmgDr.Model; +package com.hmg.hmgDr.model; import android.os.Parcel; import android.os.Parcelable; diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/model/NotificationDataModel.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/model/NotificationDataModel.kt new file mode 100644 index 00000000..bc025132 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/model/NotificationDataModel.kt @@ -0,0 +1,16 @@ +package com.hmg.hmgDr.model + +/** Represents standard data needed for a Notification. */ +open class NotificationDataModel( + // Standard notification values: + var mContentTitle: String, + var mContentText: String, + var mPriority: Int , + // Notification channel values (O and above): + var mChannelId: String, + var mChannelName: CharSequence, + var mChannelDescription: String, + var mChannelImportance: Int , + var mChannelEnableVibrate: Boolean , + var mChannelLockscreenVisibility: Int +) \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/model/NotificationVideoModel.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/model/NotificationVideoModel.kt new file mode 100644 index 00000000..78c15a91 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/model/NotificationVideoModel.kt @@ -0,0 +1,35 @@ +package com.hmg.hmgDr.model + +import android.app.NotificationManager +import android.os.Build +import androidx.annotation.RequiresApi +import androidx.core.app.NotificationCompat + +class NotificationVideoModel constructor( + mContentTitle: String, + mContentText: String, + mChannelId: String, + mChannelName: CharSequence, + mChannelDescription: String, + mPriority: Int = NotificationCompat.PRIORITY_DEFAULT, + mChannelImportance: Int = NotificationManager.IMPORTANCE_DEFAULT, + mChannelEnableVibrate: Boolean = false, + mChannelLockscreenVisibility: Int = NotificationCompat.VISIBILITY_PUBLIC, + // Unique data for this Notification.Style: + var mBigContentTitle: String = mContentTitle, + val mBigText: String = mContentText, + val mSummaryText: String + +) : NotificationDataModel( + mContentTitle, + mContentText, + mPriority, + mChannelId, + mChannelName, + mChannelDescription, + mChannelImportance, + mChannelEnableVibrate, + mChannelLockscreenVisibility +) { + +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/Model/SessionStatusModel.java b/android/app/src/main/kotlin/com/hmg/hmgDr/model/SessionStatusModel.java similarity index 98% rename from android/app/src/main/kotlin/com/hmg/hmgDr/Model/SessionStatusModel.java rename to android/app/src/main/kotlin/com/hmg/hmgDr/model/SessionStatusModel.java index 51b0b1ee..fe309922 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/Model/SessionStatusModel.java +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/model/SessionStatusModel.java @@ -1,4 +1,4 @@ -package com.hmg.hmgDr.Model; +package com.hmg.hmgDr.model; import android.os.Parcel; import android.os.Parcelable; diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallContract.java b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallContract.java index 2b099551..8b615e69 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallContract.java +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallContract.java @@ -1,8 +1,8 @@ package com.hmg.hmgDr.ui; -import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel; -import com.hmg.hmgDr.Model.GetSessionStatusModel; -import com.hmg.hmgDr.Model.SessionStatusModel; +import com.hmg.hmgDr.model.ChangeCallStatusRequestModel; +import com.hmg.hmgDr.model.GetSessionStatusModel; +import com.hmg.hmgDr.model.SessionStatusModel; public interface VideoCallContract { diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallPresenterImpl.java b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallPresenterImpl.java index ea2128ba..63cf8c27 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallPresenterImpl.java +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallPresenterImpl.java @@ -1,8 +1,8 @@ package com.hmg.hmgDr.ui; -import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel; -import com.hmg.hmgDr.Model.GetSessionStatusModel; -import com.hmg.hmgDr.Model.SessionStatusModel; +import com.hmg.hmgDr.model.ChangeCallStatusRequestModel; +import com.hmg.hmgDr.model.GetSessionStatusModel; +import com.hmg.hmgDr.model.SessionStatusModel; import com.hmg.hmgDr.Service.AppRetrofit; import com.hmg.hmgDr.Service.SessionStatusAPI; diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt index 061356ac..b020ed29 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -11,7 +11,6 @@ import android.graphics.Point import android.graphics.drawable.ColorDrawable import android.opengl.GLSurfaceView import android.os.* -import android.util.DisplayMetrics import android.util.Log import android.view.* import android.widget.* @@ -21,9 +20,9 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.content.ContextCompat import androidx.core.view.GestureDetectorCompat import androidx.fragment.app.DialogFragment -import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel -import com.hmg.hmgDr.Model.GetSessionStatusModel -import com.hmg.hmgDr.Model.SessionStatusModel +import com.hmg.hmgDr.model.ChangeCallStatusRequestModel +import com.hmg.hmgDr.model.GetSessionStatusModel +import com.hmg.hmgDr.model.SessionStatusModel import com.hmg.hmgDr.R import com.hmg.hmgDr.ui.VideoCallContract.VideoCallPresenter import com.hmg.hmgDr.ui.VideoCallContract.VideoCallView diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/util/NotificationUtil.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/util/NotificationUtil.kt new file mode 100644 index 00000000..13d6bd19 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/util/NotificationUtil.kt @@ -0,0 +1,42 @@ +package com.hmg.hmgDr.util + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.content.Context +import android.graphics.Color +import android.os.Build +import com.hmg.hmgDr.model.NotificationDataModel + +object NotificationUtil { + + fun createNotificationChannel(context: Context, notificationDataModel: NotificationDataModel): String{ + // The id of the channel. + val channelId: String = notificationDataModel.mChannelId + + // NotificationChannels are required for Notifications on O (API 26) and above. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + // The user-visible name of the channel. + val channelName: CharSequence = notificationDataModel.mChannelName + // The user-visible description of the channel. + val channelDescription: String = notificationDataModel.mChannelDescription + val channelImportance: Int = notificationDataModel.mChannelImportance + val channelEnableVibrate: Boolean = notificationDataModel.mChannelEnableVibrate + val channelLockscreenVisibility: Int = notificationDataModel.mChannelLockscreenVisibility + + // Initializes NotificationChannel. + val notificationChannel = NotificationChannel(channelId, channelName, channelImportance) + notificationChannel.description = channelDescription + notificationChannel.enableVibration(channelEnableVibrate) + notificationChannel.lightColor = Color.BLUE + notificationChannel.lockscreenVisibility = channelLockscreenVisibility + + // Adds NotificationChannel to system. Attempting to create an existing notification + // channel with its original values performs no operation, so it's safe to perform the + // below sequence. + val notificationManager = + context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + notificationManager.createNotificationChannel(notificationChannel) + } + return channelId + } +} \ No newline at end of file diff --git a/android/app/src/main/res/drawable/ic_arrow_bottom.xml b/android/app/src/main/res/drawable/ic_arrow_bottom.xml new file mode 100644 index 00000000..1aeaa998 --- /dev/null +++ b/android/app/src/main/res/drawable/ic_arrow_bottom.xml @@ -0,0 +1,5 @@ + + + diff --git a/android/app/src/main/res/drawable/ic_arrow_top.xml b/android/app/src/main/res/drawable/ic_arrow_top.xml new file mode 100644 index 00000000..1d112693 --- /dev/null +++ b/android/app/src/main/res/drawable/ic_arrow_top.xml @@ -0,0 +1,5 @@ + + + diff --git a/android/app/src/main/res/drawable/ic_end_call.xml b/android/app/src/main/res/drawable/ic_end_call.xml new file mode 100644 index 00000000..724ce9db --- /dev/null +++ b/android/app/src/main/res/drawable/ic_end_call.xml @@ -0,0 +1,5 @@ + + + diff --git a/android/app/src/main/res/layout/notifi_video_view.xml b/android/app/src/main/res/layout/notifi_video_view.xml new file mode 100644 index 00000000..3afd925b --- /dev/null +++ b/android/app/src/main/res/layout/notifi_video_view.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From ef8db07875399feadf63c5231bbe174bc4244078 Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Tue, 6 Jul 2021 09:56:37 +0300 Subject: [PATCH 042/289] add patient to doctor list in live care --- lib/config/config.dart | 2 + ..._patient_to_doctor_list_request_model.dart | 27 +++++++ .../patient/LiveCarePatientServices.dart | 75 ++++++++++++------- .../viewModel/LiveCarePatientViewModel.dart | 44 +++++++---- .../live_care/live_care_patient_screen.dart | 7 +- .../patient_profile_screen.dart | 43 ++++++----- 6 files changed, 130 insertions(+), 68 deletions(-) create mode 100644 lib/core/model/live_care/add_patient_to_doctor_list_request_model.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index a0f1464e..38dc201e 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -232,6 +232,8 @@ const INSERT_MEDICAL_REPORT = "Services/Patients.svc/REST/DAPP_InsertMedicalRepo const UPDATE_MEDICAL_REPORT = "Services/Patients.svc/REST/DAPP_UpdateMedicalReport"; const GET_SICK_LEAVE_DOCTOR_APP = "Services/DoctorApplication.svc/REST/GetAllSickLeaves"; +const ADD_PATIENT_TO_DOCTOR = "LiveCareApi/DoctorApp/AssignPatientToDoctor"; +const REMOVE_PATIENT_FROM_DOCTOR = "LiveCareApi/DoctorApp/BackPatientToQueue"; var selectedPatientType = 1; diff --git a/lib/core/model/live_care/add_patient_to_doctor_list_request_model.dart b/lib/core/model/live_care/add_patient_to_doctor_list_request_model.dart new file mode 100644 index 00000000..1d63e885 --- /dev/null +++ b/lib/core/model/live_care/add_patient_to_doctor_list_request_model.dart @@ -0,0 +1,27 @@ +class AddPatientToDoctorListRequestModel { + int vCID; + String tokenID; + String generalid; + int doctorId; + bool isOutKsa; + + AddPatientToDoctorListRequestModel({this.vCID, this.tokenID, this.generalid, this.doctorId, this.isOutKsa}); + + AddPatientToDoctorListRequestModel.fromJson(Map json) { + vCID = json['VC_ID']; + tokenID = json['TokenID']; + generalid = json['generalid']; + doctorId = json['DoctorId']; + isOutKsa = json['IsOutKsa']; + } + + Map toJson() { + final Map data = new Map(); + data['VC_ID'] = this.vCID; + data['TokenID'] = this.tokenID; + data['generalid'] = this.generalid; + data['DoctorId'] = this.doctorId; + data['IsOutKsa'] = this.isOutKsa; + return data; + } +} diff --git a/lib/core/service/patient/LiveCarePatientServices.dart b/lib/core/service/patient/LiveCarePatientServices.dart index fff803d8..10af0ea2 100644 --- a/lib/core/service/patient/LiveCarePatientServices.dart +++ b/lib/core/service/patient/LiveCarePatientServices.dart @@ -1,7 +1,7 @@ - import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/model/live_care/AlternativeServicesList.dart'; import 'package:doctor_app_flutter/core/model/live_care/PendingPatientERForDoctorAppRequestModel.dart'; +import 'package:doctor_app_flutter/core/model/live_care/add_patient_to_doctor_list_request_model.dart'; import 'package:doctor_app_flutter/core/model/live_care/live_care_login_reguest_model.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.dart'; import 'package:doctor_app_flutter/models/livecare/end_call_req.dart'; @@ -35,14 +35,12 @@ class LiveCarePatientServices extends BaseService { StartCallRes get startCallRes => _startCallRes; Future getPendingPatientERForDoctorApp( - PendingPatientERForDoctorAppRequestModel - pendingPatientERForDoctorAppRequestModel) async { + PendingPatientERForDoctorAppRequestModel pendingPatientERForDoctorAppRequestModel) async { hasError = false; await baseAppClient.post( GET_PENDING_PATIENT_ER_FOR_DOCTOR_APP, onSuccess: (dynamic response, int statusCode) { - - List localPatientList= []; + List localPatientList = []; response['List_PendingPatientList'].forEach((v) { localPatientList.add(PatiantInformtion.fromJson(v)); @@ -50,22 +48,19 @@ class LiveCarePatientServices extends BaseService { /// add new items. localPatientList.forEach((element) { - if ((_patientList.singleWhere((it) => it.patientId == element.patientId, - orElse: () => null)) == null) { + if ((_patientList.singleWhere((it) => it.patientId == element.patientId, orElse: () => null)) == null) { _patientList.add(element); } }); /// remove items. - List removedPatientList= []; + List removedPatientList = []; _patientList.forEach((element) { - if ((localPatientList.singleWhere((it) => it.patientId == element.patientId, - orElse: () => null)) == null) { + if ((localPatientList.singleWhere((it) => it.patientId == element.patientId, orElse: () => null)) == null) { removedPatientList.add(element); } }); - removedPatientList.forEach((element) { _patientList.remove(element); }); @@ -105,11 +100,7 @@ class LiveCarePatientServices extends BaseService { }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; - }, body: { - "VC_ID": vcID, - "AltServiceList": altServiceList, - "generalid":GENERAL_ID - }, isLiveCare: _isLive); + }, body: {"VC_ID": vcID, "AltServiceList": altServiceList, "generalid": GENERAL_ID}, isLiveCare: _isLive); } Future transferToAdmin(int vcID, String notes) async { @@ -128,20 +119,17 @@ class LiveCarePatientServices extends BaseService { Future sendSMSInstruction(int vcID) async { hasError = false; - await baseAppClient.post(SEND_SMS_INSTRUCTIONS, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(SEND_SMS_INSTRUCTIONS, onSuccess: (dynamic response, int statusCode) { transferToAdminResponse = response; }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; - }, body: { - "VC_ID": vcID, "generalid": GENERAL_ID - }, isLiveCare: _isLive); + }, body: {"VC_ID": vcID, "generalid": GENERAL_ID}, isLiveCare: _isLive); } Future isLogin({LiveCareUserLoginRequestModel isLoginRequestModel, int loginStatus}) async { hasError = false; - await getDoctorProfile( ); + await getDoctorProfile(); isLoginRequestModel.doctorId = super.doctorProfile.doctorID; await baseAppClient.post(LIVE_CARE_IS_LOGIN, onSuccess: (response, statusCode) async { isLoginResponse = response; @@ -155,17 +143,48 @@ class LiveCarePatientServices extends BaseService { hasError = false; alternativeServicesList.clear(); - await baseAppClient.post(GET_ALTERNATIVE_SERVICE, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(GET_ALTERNATIVE_SERVICE, onSuccess: (dynamic response, int statusCode) { response['AlternativeServicesList'].forEach((v) { alternativeServicesList.add(AlternativeService.fromJson(v)); }); }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; - }, body: { - "VC_ID": vcID, - "generalid": GENERAL_ID - }, isLiveCare: _isLive); + }, body: {"VC_ID": vcID, "generalid": GENERAL_ID}, isLiveCare: _isLive); + } + + Future addPatientToDoctorList({int vcID}) async { + hasError = false; + await getDoctorProfile(); + AddPatientToDoctorListRequestModel addPatientToDoctorListRequestModel = AddPatientToDoctorListRequestModel(); + + addPatientToDoctorListRequestModel.doctorId = super.doctorProfile.doctorID; + addPatientToDoctorListRequestModel.vCID = vcID; + addPatientToDoctorListRequestModel.isOutKsa = false; + addPatientToDoctorListRequestModel.generalid = GENERAL_ID; + + await baseAppClient.post(ADD_PATIENT_TO_DOCTOR, onSuccess: (response, statusCode) async { + isLoginResponse = response; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: addPatientToDoctorListRequestModel.toJson(), isLiveCare: _isLive); + } + + Future removePatientFromDoctorList({int vcID}) async { + hasError = false; + AddPatientToDoctorListRequestModel addPatientToDoctorListRequestModel = AddPatientToDoctorListRequestModel(); + await getDoctorProfile(); + addPatientToDoctorListRequestModel.doctorId = super.doctorProfile.doctorID; + addPatientToDoctorListRequestModel.vCID = vcID; + addPatientToDoctorListRequestModel.isOutKsa = false; + addPatientToDoctorListRequestModel.generalid = GENERAL_ID; + + await baseAppClient.post(REMOVE_PATIENT_FROM_DOCTOR, onSuccess: (response, statusCode) async { + isLoginResponse = response; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: addPatientToDoctorListRequestModel.toJson(), isLiveCare: _isLive); } } diff --git a/lib/core/viewModel/LiveCarePatientViewModel.dart b/lib/core/viewModel/LiveCarePatientViewModel.dart index 03cb0a7b..53feedd1 100644 --- a/lib/core/viewModel/LiveCarePatientViewModel.dart +++ b/lib/core/viewModel/LiveCarePatientViewModel.dart @@ -20,8 +20,7 @@ class LiveCarePatientViewModel extends BaseViewModel { StartCallRes get startCallRes => _liveCarePatientServices.startCallRes; - List get alternativeServicesList => - _liveCarePatientServices.alternativeServicesList; + List get alternativeServicesList => _liveCarePatientServices.alternativeServicesList; DashboardService _dashboardService = locator(); @@ -106,8 +105,7 @@ class LiveCarePatientViewModel extends BaseViewModel { selectedServices = getSelectedAlternativeServices(); } - await _liveCarePatientServices.endCallWithCharge( - vcID, selectedServices); + await _liveCarePatientServices.endCallWithCharge(vcID, selectedServices); if (_liveCarePatientServices.hasError) { error = _liveCarePatientServices.error; setState(ViewState.ErrorLocal); @@ -209,8 +207,7 @@ class LiveCarePatientViewModel extends BaseViewModel { AlternativeService(serviceID: 2, serviceName: "LABORATORY"), ); alternativeServicesList.add( - AlternativeService( - serviceID: 3, serviceName: "RADIOLOGY(ULTRASOUND) For pregnant only"), + AlternativeService(serviceID: 3, serviceName: "RADIOLOGY(ULTRASOUND) For pregnant only"), ); alternativeServicesList.add( AlternativeService(serviceID: 4, serviceName: "VACCINATIONS"), @@ -231,25 +228,46 @@ class LiveCarePatientViewModel extends BaseViewModel { AlternativeService(serviceID: 9, serviceName: "FAMILY MEDICIN DR"), ); alternativeServicesList.add( - AlternativeService( - serviceID: 10, serviceName: "FOLYS CATHETER INSERTION"), + AlternativeService(serviceID: 10, serviceName: "FOLYS CATHETER INSERTION"), ); alternativeServicesList.add( AlternativeService(serviceID: 11, serviceName: "GASTRIC TUBE CHANGE"), ); } - updateInCallPatient({PatiantInformtion patient, appointmentNo}){ - - _liveCarePatientServices.patientList.forEach((e) { - if(e.patientId == patient.patientId) { - e.episodeNo = 0 ; + updateInCallPatient({PatiantInformtion patient, appointmentNo}) { + _liveCarePatientServices.patientList.forEach((e) { + if (e.patientId == patient.patientId) { + e.episodeNo = 0; e.appointmentNo = appointmentNo; return; } }); setState(ViewState.Idle); + } + + Future addPatientToDoctorList(int vcID) async { + await getDoctorProfile(isGetProfile: true); + setState(ViewState.BusyLocal); + await _liveCarePatientServices.addPatientToDoctorList(vcID: vcID); + if (_liveCarePatientServices.hasError) { + error = _liveCarePatientServices.error; + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Idle); + } + } + Future removePatientFromDoctorList(int vcID) async { + await getDoctorProfile(isGetProfile: true); + setState(ViewState.BusyLocal); + await _liveCarePatientServices.removePatientFromDoctorList(vcID: vcID); + if (_liveCarePatientServices.hasError) { + error = _liveCarePatientServices.error; + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Idle); + } } } diff --git a/lib/screens/live_care/live_care_patient_screen.dart b/lib/screens/live_care/live_care_patient_screen.dart index 12c8caff..f0f5e232 100644 --- a/lib/screens/live_care/live_care_patient_screen.dart +++ b/lib/screens/live_care/live_care_patient_screen.dart @@ -194,10 +194,7 @@ class _LiveCarePatientScreenState extends State { ); } - callConnected(){ + callConnected() {} - } - - callDisconnected(){ - } + callDisconnected() {} } diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index a1da7882..1cbc67d8 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -32,6 +32,7 @@ class PatientProfileScreen extends StatefulWidget { class _PatientProfileScreenState extends State with SingleTickerProviderStateMixin { PatiantInformtion patient; + LiveCarePatientViewModel _liveCareViewModel = LiveCarePatientViewModel(); bool isFromSearch = false; bool isFromLiveCare = false; @@ -63,6 +64,9 @@ class _PatientProfileScreenState extends State with Single void dispose() { _tabController.dispose(); super.dispose(); + if (isFromLiveCare) { + _liveCareViewModel.removePatientFromDoctorList(patient.vcId); + } } @override @@ -123,6 +127,9 @@ class _PatientProfileScreenState extends State with Single Widget build(BuildContext context) { final screenSize = MediaQuery.of(context).size; return BaseView( + onModelReady: (model) async { + if (isFromLiveCare && patient.patientStatus == 1) await model.addPatientToDoctorList(patient.vcId); + }, builder: (_, model, w) => AppScaffold( baseViewModel: model, appBarTitle: TranslationBase.of(context).patientProfile, @@ -316,43 +323,35 @@ class _PatientProfileScreenState extends State with Single Navigator.push( context, MaterialPageRoute( - builder: (BuildContext context) => - EndCallScreen(patient: patient))); + builder: (BuildContext context) => EndCallScreen(patient: patient))); } else { GifLoaderDialogUtils.showMyDialog(context); - await model.startCall( - isReCall: false, vCID: patient.vcId); + await model.startCall(isReCall: false, vCID: patient.vcId); if (model.state == ViewState.ErrorLocal) { GifLoaderDialogUtils.hideDialog(context); Helpers.showErrorToast(model.error); } else { await model.getDoctorProfile(); - patient.appointmentNo = int.parse(model - .startCallRes.appointmentNo - .toString()); + patient.appointmentNo = int.parse(model.startCallRes.appointmentNo.toString()); patient.episodeNo = 0; model.updateInCallPatient( patient: patient, - appointmentNo: int.parse(model - .startCallRes.appointmentNo - .toString())); + appointmentNo: int.parse(model.startCallRes.appointmentNo.toString())); setState(() { isCallStarted = true; }); GifLoaderDialogUtils.hideDialog(context); - AppPermissionsUtils - .requestVideoCallPermission( - context: context, - onTapGrant: () { - locator() - .openVideo( - model.startCallRes, - patient, - model.startCallRes != null ? model.startCallRes.isRecording : true - , callConnected, - callDisconnected); - }); + AppPermissionsUtils.requestVideoCallPermission( + context: context, + onTapGrant: () { + locator().openVideo( + model.startCallRes, + patient, + model.startCallRes != null ? model.startCallRes.isRecording : true, + callConnected, + callDisconnected); + }); } } }, From d0f1f9e17fcd11febef179ae59470dcbee43536c Mon Sep 17 00:00:00 2001 From: mosazaid Date: Tue, 6 Jul 2021 17:07:28 +0300 Subject: [PATCH 043/289] notification with timer and bug fixes --- .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 12 +- .../VideoStreamFloatingWidgetService.kt | 108 +++++++++++------- .../hmg/hmgDr/model/NotificationVideoModel.kt | 2 +- .../src/main/res/layout/notifi_video_view.xml | 9 +- 4 files changed, 80 insertions(+), 51 deletions(-) diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt index e20eef1e..a2c0f742 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -111,12 +111,14 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, // start service // serviceIntent = Intent(this@MainActivity, VideoStreamContainerService::class.java) - serviceIntent = Intent(this@MainActivity, VideoStreamFloatingWidgetService::class.java) - serviceIntent?.run { - putExtras(arguments) - action = VideoStreamFloatingWidgetService.ACTION_START_CALL + if (videoStreamService == null || videoStreamService?.serviceRunning == false){ + serviceIntent = Intent(this@MainActivity, VideoStreamFloatingWidgetService::class.java) + serviceIntent?.run { + putExtras(arguments) + action = VideoStreamFloatingWidgetService.ACTION_START_CALL + } + checkFloatingWidgetPermission() } - checkFloatingWidgetPermission() } private fun checkFloatingWidgetPermission() { diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt index f79f23a4..96f0ce1f 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt @@ -18,10 +18,7 @@ import androidx.core.app.NotificationManagerCompat import androidx.core.content.ContextCompat import androidx.core.view.GestureDetectorCompat import com.hmg.hmgDr.R -import com.hmg.hmgDr.model.ChangeCallStatusRequestModel -import com.hmg.hmgDr.model.GetSessionStatusModel -import com.hmg.hmgDr.model.NotificationVideoModel -import com.hmg.hmgDr.model.SessionStatusModel +import com.hmg.hmgDr.model.* import com.hmg.hmgDr.ui.VideoCallContract import com.hmg.hmgDr.ui.VideoCallPresenterImpl import com.hmg.hmgDr.ui.VideoCallResponseListener @@ -115,6 +112,9 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, private var isSpeckerClicked = false private var isMicClicked = false private var elapsedTime: Long = 0 + private var formattedCallTime: String = "00:00" + private lateinit var notificationData: NotificationVideoModel + private var resume = false var isFullScreen: Boolean = true private var isCircle: Boolean = false @@ -125,7 +125,8 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, private val serviceBinder: IBinder = VideoStreamBinder() // Notification variables - private lateinit var mNotificationManagerCompat: NotificationManagerCompat + private var mNotificationManagerCompat: NotificationManagerCompat? = null + private lateinit var notificationCompatBuilder: NotificationCompat.Builder override fun onBind(intent: Intent?): IBinder { return serviceBinder @@ -180,14 +181,21 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, get() = this@VideoStreamFloatingWidgetService } - override fun onDestroy() { mWindowManager?.removeView(floatingWidgetView) // disconnectSession() - cmTimer.stop() super.onDestroy() } + private fun stopService() { + // because problem that timer still continue longer a bit than service so notification called again + mNotificationManagerCompat = null + cmTimer.stop() + stopForeground(true) + stopSelf() + + } + /* Add Floating Widget View to Window Manager */ private fun addFloatingWidgetView(inflater: LayoutInflater) { //Inflate the removing view layout we created @@ -225,7 +233,7 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, mWindowManager?.addView(floatingWidgetView, windowManagerParams) } - @SuppressLint("ClickableViewAccessibility") + @SuppressLint("ClickableViewAccessibility", "RestrictedApi") private fun init(view: View) { initUI(view) @@ -279,9 +287,22 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, elapsedTime += 1000 } val format = "%1$02d:%2$02d" // two digits + formattedCallTime = String.format(format, minutes, seconds) + arg0?.text = formattedCallTime - arg0?.text = String.format(format, minutes, seconds) - Log.d(TAG, "onChronometerTick: $minutes : $seconds") + try { + notificationCompatBuilder.contentView.setChronometer(R.id.notify_timer, cmTimer.base, null, true) + }catch (e : Exception){} + + // for change notification timer + if (mNotificationManagerCompat != null) { + val bigTextStyle = setNotificationBigStyle() + notificationCompatBuilder.setStyle(bigTextStyle) + mNotificationManagerCompat?.notify( + ONGOING_NOTIFICATION_ID, + notificationCompatBuilder.build() + ) + } } videoCallPresenter = VideoCallPresenterImpl(this, baseUrl) @@ -536,6 +557,9 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, } fun onMinimizedClicked() { + if (isCircle){ + onMiniCircleClicked() + } if (isFullScreen) { windowManagerParams.width = 400 windowManagerParams.height = 600 @@ -759,8 +783,7 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, private fun disconnectSession() { if (mSession == null) { videoCallResponseListener?.onCallFinished(Activity.RESULT_CANCELED) - stopForeground(true) - stopSelf() + stopService() return } @@ -787,8 +810,7 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, sessionStatusModel!!.vcid ) ) - stopForeground(true) - stopSelf() + stopService() } private fun subscribeToStream(stream: Stream) { @@ -899,8 +921,7 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, returnIntent.putExtra("sessionStatusNotRespond", sessionStatusModel) disconnectSession() videoCallResponseListener?.onCallFinished(Activity.RESULT_OK, returnIntent) - stopSelf() - stopForeground(true) + stopService() } } @@ -927,7 +948,7 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, private fun addForegroundService() { mNotificationManagerCompat = NotificationManagerCompat.from(applicationContext) - val areNotificationsEnabled = mNotificationManagerCompat.areNotificationsEnabled() + val areNotificationsEnabled = mNotificationManagerCompat!!.areNotificationsEnabled() if (!areNotificationsEnabled) { Toast.makeText( this, @@ -941,28 +962,33 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, generateBigTextStyleNotification() } + private fun setNotificationBigStyle(): NotificationCompat.BigTextStyle { + notificationData.mSummaryText = formattedCallTime + + return NotificationCompat.BigTextStyle() // Overrides ContentText in the big form of the template. + .bigText(notificationData.mBigText) // Overrides ContentTitle in the big form of the template. + .setBigContentTitle(notificationData.mBigContentTitle) // Summary line after the detail section in the big form of the template. + // Note: To improve readability, don't overload the user with info. If Summary Text + // doesn't add critical information, you should skip it. + .setSummaryText(notificationData.mSummaryText) + } + private fun generateBigTextStyleNotification() { - val notificationData: NotificationVideoModel = + notificationData = NotificationVideoModel( sessionStatusModel!!.patientName, "Tap to return to call", CHANNEL_DEFAULT_IMPORTANCE, CHANNEL_DEFAULT_NAME, "Video call stream background", - mSummaryText = "timer" + mSummaryText = formattedCallTime ) // 1. Create/Retrieve Notification Channel for O and beyond devices (26+). val notificationChannelId: String = NotificationUtil.createNotificationChannel(this, notificationData) // 2. Build the BIG_TEXT_STYLE. - val bigTextStyle = - NotificationCompat.BigTextStyle() // Overrides ContentText in the big form of the template. - .bigText(notificationData.mBigText) // Overrides ContentTitle in the big form of the template. - .setBigContentTitle(notificationData.mBigContentTitle) // Summary line after the detail section in the big form of the template. - // Note: To improve readability, don't overload the user with info. If Summary Text - // doesn't add critical information, you should skip it. - .setSummaryText(notificationData.mSummaryText) + val bigTextStyle = setNotificationBigStyle() // 3. Set up main Intent for notification. val pendingIntent: PendingIntent = @@ -981,20 +1007,16 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, .let { notificationIntent -> PendingIntent.getService(this, 0, notificationIntent, 0) } -// val endCallAction = NotificationCompat.Action.Builder( -// R.drawable.ic_end_call, -// "End Call", -// endCallPendingIntent -// ) -// .build() - - // 5. Build and issue the notification. - // Notification Channel Id is ignored for Android pre O (26). - + val endCallAction = NotificationCompat.Action.Builder( + R.drawable.ic_end_call, + "End Call", + endCallPendingIntent + ) + .build() // 5. Build and issue the notification. // Notification Channel Id is ignored for Android pre O (26). - val notificationCompatBuilder = notificationChannelId?.let { + notificationCompatBuilder = notificationChannelId.let { NotificationCompat.Builder( applicationContext, it ) @@ -1008,8 +1030,9 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, // notification's content mRemoteViews.setTextViewText(R.id.notify_content, notificationData.mContentText) mRemoteViews.setOnClickPendingIntent(R.id.btn_end, endCallPendingIntent) + mRemoteViews.setChronometer(R.id.notify_timer, SystemClock.elapsedRealtime(), null, false) - val notification: Notification = notificationCompatBuilder + notificationCompatBuilder // BIG_TEXT_STYLE sets title and content for API 16 (4.1 and after). .setStyle(bigTextStyle) // Title for API <16 (4.0 and below) devices. @@ -1033,10 +1056,14 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, .setPriority(notificationData.mPriority) .setVisibility(notificationData.mChannelLockscreenVisibility) // .addAction(endCallAction) - .build() + .setUsesChronometer(true) + .setWhen(elapsedTime) + .setOnlyAlertOnce(true) // This will ensure that updates to an existing notification won't sound/vibrate https://stackoverflow.com/a/52349466/6246772 - mNotificationManagerCompat.notify(ONGOING_NOTIFICATION_ID, notification) + val notification = notificationCompatBuilder + .build() + mNotificationManagerCompat!!.notify(ONGOING_NOTIFICATION_ID, notification) startForeground(ONGOING_NOTIFICATION_ID, notification) /*val notification: Notification = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { Notification.Builder(this, CHANNEL_DEFAULT_IMPORTANCE) @@ -1076,7 +1103,6 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, startActivity(intent) } - /** * OnTouch actions */ diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/model/NotificationVideoModel.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/model/NotificationVideoModel.kt index 78c15a91..6b6d9217 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/model/NotificationVideoModel.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/model/NotificationVideoModel.kt @@ -18,7 +18,7 @@ class NotificationVideoModel constructor( // Unique data for this Notification.Style: var mBigContentTitle: String = mContentTitle, val mBigText: String = mContentText, - val mSummaryText: String + var mSummaryText: String ) : NotificationDataModel( mContentTitle, diff --git a/android/app/src/main/res/layout/notifi_video_view.xml b/android/app/src/main/res/layout/notifi_video_view.xml index 3afd925b..cdc87a4b 100644 --- a/android/app/src/main/res/layout/notifi_video_view.xml +++ b/android/app/src/main/res/layout/notifi_video_view.xml @@ -32,17 +32,18 @@ android:textColor="@color/white" android:textSize="@dimen/text_size_small" /> - + android:format="MM:SS" + tools:text="25:45" /> Date: Wed, 7 Jul 2021 16:59:33 +0300 Subject: [PATCH 044/289] notification with timer and bug fixes --- .../VideoStreamFloatingWidgetService.kt | 16 +++- .../hmg/hmgDr/model/NotificationVideoModel.kt | 4 +- .../com/hmg/hmgDr/util/NotificationUtil.kt | 4 +- .../src/main/res/layout/notifi_video_view.xml | 24 +---- .../res/layout/notifi_video_view_expand.xml | 93 +++++++++++++++++++ 5 files changed, 114 insertions(+), 27 deletions(-) create mode 100644 android/app/src/main/res/layout/notifi_video_view_expand.xml diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt index 96f0ce1f..02413827 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt @@ -292,7 +292,8 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, try { notificationCompatBuilder.contentView.setChronometer(R.id.notify_timer, cmTimer.base, null, true) - }catch (e : Exception){} + notificationCompatBuilder.bigContentView.setChronometer(R.id.notify_timer, cmTimer.base, null, true) + } catch (e : Exception){} // for change notification timer if (mNotificationManagerCompat != null) { @@ -1029,8 +1030,12 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, mRemoteViews.setTextViewText(R.id.notify_title, notificationData.mContentTitle) // notification's content mRemoteViews.setTextViewText(R.id.notify_content, notificationData.mContentText) - mRemoteViews.setOnClickPendingIntent(R.id.btn_end, endCallPendingIntent) - mRemoteViews.setChronometer(R.id.notify_timer, SystemClock.elapsedRealtime(), null, false) + val mRemoteViewsExpand = RemoteViews(packageName, R.layout.notifi_video_view_expand) + mRemoteViewsExpand.setImageViewResource(R.id.iv_icon, R.mipmap.ic_launcher) + mRemoteViewsExpand.setTextViewText(R.id.notify_title, notificationData.mContentTitle) + mRemoteViewsExpand.setTextViewText(R.id.notify_content, notificationData.mContentText) + mRemoteViewsExpand.setOnClickPendingIntent(R.id.btn_end, endCallPendingIntent) + mRemoteViewsExpand.setChronometer(R.id.notify_timer, SystemClock.elapsedRealtime(), null, false) notificationCompatBuilder // BIG_TEXT_STYLE sets title and content for API 16 (4.1 and after). @@ -1047,9 +1052,9 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, ) ) .setCustomContentView(mRemoteViews) - .setCustomBigContentView(mRemoteViews) + .setCustomBigContentView(mRemoteViewsExpand) .setContentIntent(pendingIntent) - .setDefaults(NotificationCompat.DEFAULT_ALL) +// .setDefaults(NotificationCompat.DEFAULT_ALL) // Set primary color (important for Wear 2.0 Notifications). .setColor(ContextCompat.getColor(applicationContext, R.color.colorPrimary)) .setCategory(Notification.CATEGORY_SERVICE) @@ -1059,6 +1064,7 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, .setUsesChronometer(true) .setWhen(elapsedTime) .setOnlyAlertOnce(true) // This will ensure that updates to an existing notification won't sound/vibrate https://stackoverflow.com/a/52349466/6246772 + .setSound(null) val notification = notificationCompatBuilder .build() diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/model/NotificationVideoModel.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/model/NotificationVideoModel.kt index 6b6d9217..9a0835f3 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/model/NotificationVideoModel.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/model/NotificationVideoModel.kt @@ -12,8 +12,8 @@ class NotificationVideoModel constructor( mChannelName: CharSequence, mChannelDescription: String, mPriority: Int = NotificationCompat.PRIORITY_DEFAULT, - mChannelImportance: Int = NotificationManager.IMPORTANCE_DEFAULT, - mChannelEnableVibrate: Boolean = false, + mChannelImportance: Int = NotificationManager.IMPORTANCE_LOW, + mChannelEnableVibrate: Boolean = true, mChannelLockscreenVisibility: Int = NotificationCompat.VISIBILITY_PUBLIC, // Unique data for this Notification.Style: var mBigContentTitle: String = mContentTitle, diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/util/NotificationUtil.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/util/NotificationUtil.kt index 13d6bd19..1c55e1b2 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/util/NotificationUtil.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/util/NotificationUtil.kt @@ -26,9 +26,11 @@ object NotificationUtil { // Initializes NotificationChannel. val notificationChannel = NotificationChannel(channelId, channelName, channelImportance) notificationChannel.description = channelDescription - notificationChannel.enableVibration(channelEnableVibrate) notificationChannel.lightColor = Color.BLUE notificationChannel.lockscreenVisibility = channelLockscreenVisibility + // no vibration + notificationChannel.vibrationPattern = longArrayOf(0) + notificationChannel.enableVibration(channelEnableVibrate) // Adds NotificationChannel to system. Attempting to create an existing notification // channel with its original values performs no operation, so it's safe to perform the diff --git a/android/app/src/main/res/layout/notifi_video_view.xml b/android/app/src/main/res/layout/notifi_video_view.xml index cdc87a4b..a2a81be1 100644 --- a/android/app/src/main/res/layout/notifi_video_view.xml +++ b/android/app/src/main/res/layout/notifi_video_view.xml @@ -3,7 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="wrap_content" + android:layout_height="88dp" android:background="@android:color/holo_blue_dark" android:orientation="vertical" android:padding="@dimen/padding_space_medium"> @@ -48,20 +48,19 @@ + android:src="@drawable/ic_arrow_bottom" /> - @@ -73,20 +72,7 @@ android:paddingStart="@dimen/padding_space_small" android:paddingEnd="@dimen/padding_space_small" android:textColor="@color/white" - android:textSize="@dimen/text_size_medium" + android:textSize="@dimen/text_size_small" android:text="Tap to return to call" /> - - \ No newline at end of file diff --git a/android/app/src/main/res/layout/notifi_video_view_expand.xml b/android/app/src/main/res/layout/notifi_video_view_expand.xml new file mode 100644 index 00000000..c06aa9ac --- /dev/null +++ b/android/app/src/main/res/layout/notifi_video_view_expand.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 638ae40035b90b0c9d85e6ceb408e3ae4c66213b Mon Sep 17 00:00:00 2001 From: Elham Rababh Date: Thu, 8 Jul 2021 13:06:32 +0300 Subject: [PATCH 045/289] first step for fix first step from fixes soap --- lib/config/config.dart | 4 +- lib/models/SOAP/my_selected_allergy.dart | 6 ++- lib/models/SOAP/my_selected_examination.dart | 11 ++++- lib/models/SOAP/my_selected_history.dart | 5 ++- .../assessment/update_assessment_page.dart | 2 +- .../objective/update_objective_page.dart | 22 +++------- .../soap_update/plan/update_plan_page.dart | 6 ++- .../allergies/update_allergies_widget.dart | 11 +++-- .../history/update_history_widget.dart | 17 +++++-- .../subjective/update_subjective_page.dart | 44 ++++++++++--------- .../soap_update/update_soap_index.dart | 2 - 11 files changed, 74 insertions(+), 56 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 6b209e4e..1f51c81c 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -5,8 +5,8 @@ const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; const BASE_URL_LIVE_CARE = 'https://livecare.hmg.com/'; -const BASE_URL = 'https://hmgwebservices.com/'; -// const BASE_URL = 'https://uat.hmgwebservices.com/'; +// const BASE_URL = 'https://hmgwebservices.com/'; +const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = "Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient"; diff --git a/lib/models/SOAP/my_selected_allergy.dart b/lib/models/SOAP/my_selected_allergy.dart index c4e52af7..66234db3 100644 --- a/lib/models/SOAP/my_selected_allergy.dart +++ b/lib/models/SOAP/my_selected_allergy.dart @@ -6,6 +6,7 @@ class MySelectedAllergy { String remark; bool isChecked; bool isExpanded; + bool isLocal; int createdBy; MySelectedAllergy( @@ -13,7 +14,8 @@ class MySelectedAllergy { this.selectedAllergy, this.remark, this.isChecked, - this.isExpanded = true, + this.isExpanded = true, + this.isLocal = true, this.createdBy}); MySelectedAllergy.fromJson(Map json) { @@ -26,6 +28,7 @@ class MySelectedAllergy { remark = json['remark']; isChecked = json['isChecked']; isExpanded = json['isExpanded']; + isLocal = json['isLocal']; createdBy = json['createdBy']; } @@ -41,6 +44,7 @@ class MySelectedAllergy { data['isChecked'] = this.isChecked; data['isExpanded'] = this.isExpanded; data['createdBy'] = this.createdBy; + data['isLocal'] = this.isLocal; return data; } } diff --git a/lib/models/SOAP/my_selected_examination.dart b/lib/models/SOAP/my_selected_examination.dart index 393af944..c791b7cb 100644 --- a/lib/models/SOAP/my_selected_examination.dart +++ b/lib/models/SOAP/my_selected_examination.dart @@ -8,6 +8,8 @@ class MySelectedExamination { bool notExamined; bool isNew; int createdBy; + String createdOn; + String editedOn; MySelectedExamination( {this.selectedExamination, @@ -16,7 +18,9 @@ class MySelectedExamination { this.isAbnormal = false, this.notExamined = true, this.isNew = true, - this.createdBy}); + this.createdBy, this.createdOn, + + this.editedOn,}); MySelectedExamination.fromJson(Map json) { selectedExamination = json['selectedExamination'] != null @@ -28,6 +32,8 @@ class MySelectedExamination { notExamined = json['notExamined']; isNew = json['isNew']; createdBy = json['createdBy']; + createdOn = json['createdOn']; + editedOn = json['editedOn']; } Map toJson() { @@ -42,6 +48,9 @@ class MySelectedExamination { data['notExamined'] = this.notExamined; data['isNew'] = this.isNew; data['createdBy'] = this.createdBy; + data['createdOn'] = this.createdOn; + data['editedOn'] = this.editedOn; + return data; } } diff --git a/lib/models/SOAP/my_selected_history.dart b/lib/models/SOAP/my_selected_history.dart index 11e366c2..91f66910 100644 --- a/lib/models/SOAP/my_selected_history.dart +++ b/lib/models/SOAP/my_selected_history.dart @@ -4,9 +4,10 @@ class MySelectedHistory { MasterKeyModel selectedHistory; String remark; bool isChecked; + bool isLocal; MySelectedHistory( - { this.selectedHistory, this.remark, this.isChecked}); + { this.selectedHistory, this.remark, this.isChecked, this.isLocal = true}); MySelectedHistory.fromJson(Map json) { @@ -15,6 +16,7 @@ class MySelectedHistory { : null; remark = json['remark']; remark = json['isChecked']; + isLocal = json['isLocal']; } Map toJson() { @@ -25,6 +27,7 @@ class MySelectedHistory { } data['remark'] = this.remark; data['isChecked'] = this.remark; + data['isLocal'] = this.isLocal; return data; } } diff --git a/lib/screens/patients/profile/soap_update/assessment/update_assessment_page.dart b/lib/screens/patients/profile/soap_update/assessment/update_assessment_page.dart index fab69c44..a2177eb7 100644 --- a/lib/screens/patients/profile/soap_update/assessment/update_assessment_page.dart +++ b/lib/screens/patients/profile/soap_update/assessment/update_assessment_page.dart @@ -55,7 +55,7 @@ class _UpdateAssessmentPageState extends State { episodeID: widget.patientInfo.episodeNo.toString(), editedBy: '', doctorID: '', - appointmentNo: int.parse(widget.patientInfo.appointmentNo)); + appointmentNo: int.parse(widget.patientInfo.appointmentNo.toString())); await model.getPatientAssessment(getAssessmentReqModel); if (model.patientAssessmentList.isNotEmpty) { if (model.listOfDiagnosisCondition.length == 0) { diff --git a/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart b/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart index 4d36f49f..12004934 100644 --- a/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart +++ b/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart @@ -83,9 +83,11 @@ class _UpdateObjectivePageState extends State { remark: element.remarks, isNormal: element.isNormal, createdBy: element.createdBy, + createdOn:element.createdOn , + editedOn: element.editedOn, notExamined: element.notExamined, isNew: element.isNew, - isAbnormal: element.isAbnormal); + isAbnormal: element.isAbnormal,); widget.mySelectedExamination.add(tempEam); }); } @@ -213,7 +215,8 @@ class _UpdateObjectivePageState extends State { appointmentNo: widget.patientInfo.appointmentNo, remarks: exam.remark ?? '', createdBy: exam.createdBy ?? doctorProfile.doctorID, - createdOn: DateTime.now().toIso8601String(), + createdOn: exam.createdOn?? + DateTime.now().toIso8601String(), editedBy: doctorProfile.doctorID, editedOn: DateTime.now().toIso8601String(), examId: exam.selectedExamination.id, @@ -276,21 +279,6 @@ class _UpdateObjectivePageState extends State { removeExamination: (masterKey) => removeExamination(masterKey)), ), ); - /*showModalBottomSheet( - backgroundColor: Colors.white, - isScrollControlled: true, - context: context, - builder: (context) { - return AddExaminationDailog( - mySelectedExamination: widget.mySelectedExamination, - addSelectedExamination: () { - setState(() { - Navigator.of(context).pop(); - }); - }, - removeExamination: (masterKey) => removeExamination(masterKey), - ); - });*/ } } diff --git a/lib/screens/patients/profile/soap_update/plan/update_plan_page.dart b/lib/screens/patients/profile/soap_update/plan/update_plan_page.dart index 1960ef72..d9d61835 100644 --- a/lib/screens/patients/profile/soap_update/plan/update_plan_page.dart +++ b/lib/screens/patients/profile/soap_update/plan/update_plan_page.dart @@ -74,7 +74,7 @@ class _UpdatePlanPageState extends State { return BaseView( onModelReady: (model) async { GetGetProgressNoteReqModel getGetProgressNoteReqModel = GetGetProgressNoteReqModel( - appointmentNo: int.parse(widget.patientInfo.appointmentNo), + appointmentNo: int.parse(widget.patientInfo.appointmentNo.toString()), patientMRN: widget.patientInfo.patientMRN, episodeID: widget.patientInfo.episodeNo.toString(), editedBy: '', @@ -88,6 +88,8 @@ class _UpdatePlanPageState extends State { widget.patientProgressNote.createdOn = model.patientProgressNoteList[0].createdOn; widget.patientProgressNote.editedOn = model.patientProgressNoteList[0].editedOn; widget.patientProgressNote.editedByName = model.patientProgressNoteList[0].editedByName; + widget.patientProgressNote.appointmentNo = model.patientProgressNoteList[0].appointmentNo; + setState(() { isAddProgress = false; }); @@ -158,7 +160,7 @@ class _UpdatePlanPageState extends State { fontSize: 12, ), AppText( - widget.patientProgressNote.appointmentNo ?? '', + widget.patientProgressNote.appointmentNo.toString() ?? '', fontWeight: FontWeight.w600, ), ], diff --git a/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart b/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart index 6f7439e6..1083ed48 100644 --- a/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart +++ b/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart @@ -153,13 +153,15 @@ class _UpdateAllergiesWidgetState extends State { ).toList(); if (allergy.length > 0) { + if(allergy.first.isLocal) { + setState(() { + widget.myAllergiesList.remove(allergy.first); + }); + } setState(() { allergy[0].isChecked = false; }); } - - - print(allergy); } openAllergiesList(BuildContext context, Function changeParentState) { @@ -180,7 +182,8 @@ class _UpdateAllergiesWidgetState extends State { }); if (isAllDataFilled) { mySelectedAllergy.forEach((element) { - if (!widget.myAllergiesList.contains(element.selectedAllergySeverity.id)) { + if ((widget.myAllergiesList.singleWhere((it) => it.selectedAllergy.id == element.selectedAllergy.id, + orElse: () => null)) == null) { widget.myAllergiesList.add(element); } }); diff --git a/lib/screens/patients/profile/soap_update/subjective/history/update_history_widget.dart b/lib/screens/patients/profile/soap_update/subjective/history/update_history_widget.dart index f114702d..3b431a69 100644 --- a/lib/screens/patients/profile/soap_update/subjective/history/update_history_widget.dart +++ b/lib/screens/patients/profile/soap_update/subjective/history/update_history_widget.dart @@ -123,10 +123,19 @@ class _UpdateHistoryWidgetState extends State ).toList(); - if (history.length > 0) - setState(() { - history[0].isChecked = false; - }); + if (history.length > 0) { + if(history.first.isLocal) { + setState(() { + widget.myHistoryList.remove(history.first); + }); + } else { + setState(() { + history[0].isChecked = false; + }); + } + + } + } openHistoryList(BuildContext context) { diff --git a/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart b/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart index 1b6cd274..12db7266 100644 --- a/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart +++ b/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart @@ -30,16 +30,12 @@ import 'history/update_history_widget.dart'; class UpdateSubjectivePage extends StatefulWidget { final Function changePageViewIndex; final Function changeLoadingState; - final List myAllergiesList; - final List myHistoryList; final PatiantInformtion patientInfo; final int currentIndex; UpdateSubjectivePage( {Key key, this.changePageViewIndex, - this.myAllergiesList, - this.myHistoryList, this.patientInfo, this.changeLoadingState, this.currentIndex}); @@ -59,6 +55,8 @@ class _UpdateSubjectivePageState extends State { String medicationControllerError = ''; String illnessControllerError = ''; final formKey = GlobalKey(); + List myAllergiesList=List(); + List myHistoryList=List(); getHistory(SOAPViewModel model) async { widget.changeLoadingState(true); @@ -93,9 +91,9 @@ class _UpdateSubjectivePageState extends State { ); if (history != null) { MySelectedHistory mySelectedHistory = - MySelectedHistory(selectedHistory: history, isChecked: element.isChecked, remark: element.remarks); + MySelectedHistory(selectedHistory: history, isChecked: element.isChecked, remark: element.remarks,isLocal: false); - widget.myHistoryList.add(mySelectedHistory); + myHistoryList.add(mySelectedHistory); } } if (element.historyType == MasterKeysService.HistoryMedical.getMasterKeyService()) { @@ -105,9 +103,9 @@ class _UpdateSubjectivePageState extends State { ); if (history != null) { MySelectedHistory mySelectedHistory = - MySelectedHistory(selectedHistory: history, isChecked: element.isChecked, remark: element.remarks); + MySelectedHistory(selectedHistory: history, isChecked: element.isChecked, remark: element.remarks,isLocal: false); - widget.myHistoryList.add(mySelectedHistory); + myHistoryList.add(mySelectedHistory); } } if (element.historyType == MasterKeysService.HistorySports.getMasterKeyService()) { @@ -117,9 +115,9 @@ class _UpdateSubjectivePageState extends State { ); if (history != null) { MySelectedHistory mySelectedHistory = - MySelectedHistory(selectedHistory: history, isChecked: element.isChecked, remark: element.remarks); + MySelectedHistory(selectedHistory: history, isChecked: element.isChecked, remark: element.remarks,isLocal: false); - widget.myHistoryList.add(mySelectedHistory); + myHistoryList.add(mySelectedHistory); } } if (element.historyType == MasterKeysService.HistorySurgical.getMasterKeyService()) { @@ -129,9 +127,9 @@ class _UpdateSubjectivePageState extends State { ); if (history != null) { MySelectedHistory mySelectedHistory = - MySelectedHistory(selectedHistory: history, isChecked: element.isChecked, remark: element.remarks); + MySelectedHistory(selectedHistory: history, isChecked: element.isChecked, remark: element.remarks,isLocal: false); - widget.myHistoryList.add(mySelectedHistory); + myHistoryList.add(mySelectedHistory); } } }); @@ -169,8 +167,9 @@ class _UpdateSubjectivePageState extends State { isChecked: element.isChecked, createdBy: element.createdBy, remark: element.remarks, + isLocal : false, selectedAllergySeverity: selectedAllergySeverity); - if (selectedAllergy != null && selectedAllergySeverity != null) widget.myAllergiesList.add(mySelectedAllergy); + if (selectedAllergy != null && selectedAllergySeverity != null) myAllergiesList.add(mySelectedAllergy); }); } } @@ -179,8 +178,8 @@ class _UpdateSubjectivePageState extends State { Widget build(BuildContext context) { return BaseView( onModelReady: (model) async { - widget.myAllergiesList.clear(); - widget.myHistoryList.clear(); + myAllergiesList.clear(); + myHistoryList.clear(); GetChiefComplaintReqModel getChiefComplaintReqModel = GetChiefComplaintReqModel( patientMRN: widget.patientInfo.patientMRN, @@ -246,7 +245,7 @@ class _UpdateSubjectivePageState extends State { }); }, child: Column( - children: [UpdateHistoryWidget(myHistoryList: widget.myHistoryList)], + children: [UpdateHistoryWidget(myHistoryList: myHistoryList)], ), isExpanded: isHistoryExpand, ), @@ -264,7 +263,7 @@ class _UpdateSubjectivePageState extends State { child: Column( children: [ UpdateAllergiesWidget( - myAllergiesList: widget.myAllergiesList, + myAllergiesList: myAllergiesList, ), SizedBox( height: 30, @@ -304,10 +303,10 @@ class _UpdateSubjectivePageState extends State { title: TranslationBase.of(context).next, fontWeight: FontWeight.w600, color: Colors.red[700], - loading: model.state == ViewState.BusyLocal, + // loading: model.state == ViewState.BusyLocal, onPressed: () async { addSubjectiveInfo( - model: model, myAllergiesList: widget.myAllergiesList, myHistoryList: widget.myHistoryList); + model: model, myAllergiesList: myAllergiesList, myHistoryList: myHistoryList); }, ), ), @@ -325,6 +324,7 @@ class _UpdateSubjectivePageState extends State { addSubjectiveInfo( {SOAPViewModel model, List myAllergiesList, List myHistoryList}) async { + widget.changeLoadingState(true); formKey.currentState.save(); formKey.currentState.validate(); @@ -370,6 +370,8 @@ class _UpdateSubjectivePageState extends State { medicationControllerError = TranslationBase.of(context).emptyMessage; } }); + + widget.changeLoadingState(false); Helpers.showErrorToast(TranslationBase.of(context).chiefComplaintErrorMsg); } } @@ -380,7 +382,7 @@ class _UpdateSubjectivePageState extends State { Map profile = await sharedPref.getObj(DOCTOR_PROFILE); DoctorProfileModel doctorProfile = DoctorProfileModel.fromJson(profile); - widget.myAllergiesList.forEach((allergy) { + myAllergiesList.forEach((allergy) { if (postAllergyRequestModel.listHisProgNotePatientAllergyDiseaseVM == null) postAllergyRequestModel.listHisProgNotePatientAllergyDiseaseVM = []; postAllergyRequestModel.listHisProgNotePatientAllergyDiseaseVM.add(ListHisProgNotePatientAllergyDiseaseVM( @@ -419,7 +421,7 @@ class _UpdateSubjectivePageState extends State { postHistories({List myHistoryList, SOAPViewModel model}) async { PostHistoriesRequestModel postHistoriesRequestModel = new PostHistoriesRequestModel(doctorID: ''); - widget.myHistoryList.forEach((history) { + myHistoryList.forEach((history) { if (postHistoriesRequestModel.listMedicalHistoryVM == null) postHistoriesRequestModel.listMedicalHistoryVM = []; postHistoriesRequestModel.listMedicalHistoryVM.add(ListMedicalHistoryVM( patientMRN: widget.patientInfo.patientMRN, diff --git a/lib/screens/patients/profile/soap_update/update_soap_index.dart b/lib/screens/patients/profile/soap_update/update_soap_index.dart index 60597b11..fd4e8791 100644 --- a/lib/screens/patients/profile/soap_update/update_soap_index.dart +++ b/lib/screens/patients/profile/soap_update/update_soap_index.dart @@ -105,8 +105,6 @@ class _UpdateSoapIndexState extends State UpdateSubjectivePage( changePageViewIndex: changePageViewIndex, currentIndex: _currentIndex, - myAllergiesList: myAllergiesList, - myHistoryList: myHistoryList, patientInfo: patient, changeLoadingState: changeLoadingState), UpdateObjectivePage( From 993a266d4ffab748f3c89105922e4de7ffbfc789 Mon Sep 17 00:00:00 2001 From: Elham Rababh Date: Thu, 8 Jul 2021 14:17:20 +0300 Subject: [PATCH 046/289] fix first step from fixes soap --- .../allergies/update_allergies_widget.dart | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart b/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart index 1083ed48..cb7d7d00 100644 --- a/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart +++ b/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart @@ -37,7 +37,7 @@ class _UpdateAllergiesWidgetState extends State { SOAPOpenItems(label: "${TranslationBase.of(context).addAllergies}",onTap: () { - openAllergiesList(context, changeAllState); + openAllergiesList(context, changeAllState, removeAllergy); },), SizedBox( height: 20, @@ -164,7 +164,7 @@ class _UpdateAllergiesWidgetState extends State { } } - openAllergiesList(BuildContext context, Function changeParentState) { + openAllergiesList(BuildContext context, Function changeParentState, removeAllergy) { showModalBottomSheet( backgroundColor: Colors.white, isScrollControlled: true, @@ -173,6 +173,7 @@ class _UpdateAllergiesWidgetState extends State { builder: (context) { return AddAllergies( myAllergiesList: widget.myAllergiesList, + addAllergiesFun: (List mySelectedAllergy) { bool isAllDataFilled = true; mySelectedAllergy.forEach((element) { @@ -187,6 +188,20 @@ class _UpdateAllergiesWidgetState extends State { widget.myAllergiesList.add(element); } }); + + /// remove items. + List removedList= []; + widget.myAllergiesList.forEach((element) { + if ((mySelectedAllergy.singleWhere((it) => it.selectedAllergy.id == element.selectedAllergy.id, + orElse: () => null)) == null) { + removedList.add(element); + }}); + + removedList.forEach((element) { + removeAllergy(element); + }); + + changeParentState(); Navigator.of(context).pop(); } else { From c69f122713f05ab93645e5a5ea133e0d3791f37f Mon Sep 17 00:00:00 2001 From: Elham Rababh Date: Thu, 8 Jul 2021 16:31:35 +0300 Subject: [PATCH 047/289] prevent passing data and first step from refactor examinations --- lib/models/SOAP/my_selected_examination.dart | 31 +-- .../assessment/update_assessment_page.dart | 18 +- .../objective/add_examination_page.dart | 133 ++++++------ .../objective/add_examination_widget.dart | 191 ++++++++++-------- .../objective/examination_item_card.dart | 20 +- .../examinations_list_search_widget.dart | 16 +- .../objective/update_objective_page.dart | 173 +++++++++------- .../soap_update/plan/update_plan_page.dart | 49 ++--- .../subjective/update_subjective_page.dart | 1 - .../soap_update/update_soap_index.dart | 7 - 10 files changed, 337 insertions(+), 302 deletions(-) diff --git a/lib/models/SOAP/my_selected_examination.dart b/lib/models/SOAP/my_selected_examination.dart index c791b7cb..6a3ecf99 100644 --- a/lib/models/SOAP/my_selected_examination.dart +++ b/lib/models/SOAP/my_selected_examination.dart @@ -1,26 +1,29 @@ import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; class MySelectedExamination { - MasterKeyModel selectedExamination; + MasterKeyModel selectedExamination; String remark; bool isNormal; bool isAbnormal; bool notExamined; bool isNew; + bool isLocal; int createdBy; - String createdOn; - String editedOn; + String createdOn; + String editedOn; - MySelectedExamination( - {this.selectedExamination, - this.remark, - this.isNormal = false, - this.isAbnormal = false, - this.notExamined = true, - this.isNew = true, - this.createdBy, this.createdOn, - - this.editedOn,}); + MySelectedExamination({ + this.selectedExamination, + this.remark, + this.isNormal = false, + this.isAbnormal = false, + this.notExamined = true, + this.isNew = true, + this.isLocal = true, + this.createdBy, + this.createdOn, + this.editedOn, + }); MySelectedExamination.fromJson(Map json) { selectedExamination = json['selectedExamination'] != null @@ -34,6 +37,7 @@ class MySelectedExamination { createdBy = json['createdBy']; createdOn = json['createdOn']; editedOn = json['editedOn']; + isLocal = json['isLocal']; } Map toJson() { @@ -50,6 +54,7 @@ class MySelectedExamination { data['createdBy'] = this.createdBy; data['createdOn'] = this.createdOn; data['editedOn'] = this.editedOn; + data['isLocal'] = this.isLocal; return data; } diff --git a/lib/screens/patients/profile/soap_update/assessment/update_assessment_page.dart b/lib/screens/patients/profile/soap_update/assessment/update_assessment_page.dart index a2177eb7..1ab96170 100644 --- a/lib/screens/patients/profile/soap_update/assessment/update_assessment_page.dart +++ b/lib/screens/patients/profile/soap_update/assessment/update_assessment_page.dart @@ -26,14 +26,12 @@ import 'add_assessment_details.dart'; // ignore: must_be_immutable class UpdateAssessmentPage extends StatefulWidget { final Function changePageViewIndex; - List mySelectedAssessmentList; final PatiantInformtion patientInfo; final Function changeLoadingState; final int currentIndex; UpdateAssessmentPage( {Key key, this.changePageViewIndex, - this.mySelectedAssessmentList, this.patientInfo, this.changeLoadingState, this.currentIndex}); @@ -43,13 +41,14 @@ class UpdateAssessmentPage extends StatefulWidget { class _UpdateAssessmentPageState extends State { bool isAssessmentExpand = false; + List mySelectedAssessmentList = List(); @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) async { - widget.mySelectedAssessmentList.clear(); + mySelectedAssessmentList.clear(); GetAssessmentReqModel getAssessmentReqModel = GetAssessmentReqModel( patientMRN: widget.patientInfo.patientMRN, episodeID: widget.patientInfo.episodeNo.toString(), @@ -96,7 +95,7 @@ class _UpdateAssessmentPageState extends State { createdOn: element.createdOn, icdCode10ID: element.icdCode10ID); - widget.mySelectedAssessmentList.add(temMySelectedAssessment); + mySelectedAssessmentList.add(temMySelectedAssessment); } }); } @@ -147,7 +146,7 @@ class _UpdateAssessmentPageState extends State { height: 20, ), Column( - children: widget.mySelectedAssessmentList + children: mySelectedAssessmentList .map((assessment) { return Container( margin: EdgeInsets.only( @@ -501,14 +500,15 @@ class _UpdateAssessmentPageState extends State { color: Colors.red[700], disabled: model.state == ViewState.BusyLocal, onPressed: () async { - if (widget.mySelectedAssessmentList.isEmpty) { + if (mySelectedAssessmentList.isEmpty) { Helpers.showErrorToast( TranslationBase .of(context) .assessmentErrorMsg); } else { - widget.changePageViewIndex(3); widget.changeLoadingState(true); + widget.changePageViewIndex(3); + } }, ), @@ -542,11 +542,11 @@ class _UpdateAssessmentPageState extends State { mySelectedAssessment: assessment, patientInfo: widget.patientInfo, isUpdate: isUpdate, - mySelectedAssessmentList: widget.mySelectedAssessmentList, + mySelectedAssessmentList: mySelectedAssessmentList, addSelectedAssessment: (MySelectedAssessment mySelectedAssessment, bool isUpdate) async { setState(() { - widget.mySelectedAssessmentList.add(mySelectedAssessment); + mySelectedAssessmentList.add(mySelectedAssessment); }); }); }); diff --git a/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart b/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart index d98e17be..659de693 100644 --- a/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart +++ b/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart @@ -31,79 +31,80 @@ class _AddExaminationPageState extends State { @override Widget build(BuildContext context) { return BaseView( - onModelReady: (model) async { - if (model.physicalExaminationList.length == 0) { - await model.getMasterLookup(MasterKeysService.PhysicalExamination); - } - }, - builder: (_, model, w) => AppScaffold( - baseViewModel: model, - isShowAppBar: false, - backgroundColor: Color.fromRGBO(248, 248, 248, 1), - body: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - padding: - EdgeInsets.only(left: 16, top: 70, right: 16, bottom: 16), - color: Colors.white, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, + onModelReady: (model) async { + if (model.physicalExaminationList.length == 0) { + await model.getMasterLookup(MasterKeysService.PhysicalExamination); + } + }, + builder: (_, model, w) => AppScaffold( + baseViewModel: model, + isShowAppBar: false, + backgroundColor: Color.fromRGBO(248, 248, 248, 1), + body: Column( + mainAxisAlignment: MainAxisAlignment.start, children: [ - Expanded( - child: AppText( - "${TranslationBase.of(context).addExamination}", - fontSize: SizeConfig.textMultiplier * 3.3, - color: Colors.black, - fontWeight: FontWeight.w700, + Container( + padding: EdgeInsets.only( + left: 16, top: 70, right: 16, bottom: 16), + color: Colors.white, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: AppText( + "${TranslationBase.of(context).addExamination}", + fontSize: SizeConfig.textMultiplier * 3.3, + color: Colors.black, + fontWeight: FontWeight.w700, + ), + ), + InkWell( + onTap: () { + Navigator.of(context).pop(); + }, + child: Icon( + Icons.clear, + size: 40, + ), + ) + ], ), ), - InkWell( - onTap: () { - Navigator.of(context).pop(); - }, - child: Icon( - Icons.clear, - size: 40, - ), - ) - ], - ), - ), - Expanded( - child: SingleChildScrollView( - child: Column( - children: [ - Container( - margin: EdgeInsets.all(16.0), - padding: EdgeInsets.all(0.0), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - color: Colors.white, - borderRadius: BorderRadius.circular(12), - border: Border.fromBorderSide(BorderSide( - color: Colors.grey.shade400, - width: 0.4, - )), - ), + Expanded( + child: SingleChildScrollView( child: Column( children: [ - ExaminationsListSearchWidget( - masterList: model.physicalExaminationList, - isServiceSelected: (master) => - isServiceSelected(master), - removeHistory: (history) { - setState(() { - widget.removeExamination(history); - }); - }, - addHistory: (selectedExamination) { - setState(() { - widget.mySelectedExamination - .add(selectedExamination); + Container( + margin: EdgeInsets.all(16.0), + padding: EdgeInsets.all(0.0), + decoration: BoxDecoration( + shape: BoxShape.rectangle, + color: Colors.white, + borderRadius: BorderRadius.circular(12), + border: Border.fromBorderSide(BorderSide( + color: Colors.grey.shade400, + width: 0.4, + )), + ), + child: Column( + children: [ + ExaminationsListSearchWidget( + mySelectedExamination: + widget.mySelectedExamination, + masterList: model.physicalExaminationList, + isServiceSelected: (master) => + isServiceSelected(master), + removeExamination: (history) { + setState(() { + widget.removeExamination(history); }); }, + addExamination: (selectedExamination) { + widget.mySelectedExamination + .add(selectedExamination); + // setState(() {}); + }, ), ], ), diff --git a/lib/screens/patients/profile/soap_update/objective/add_examination_widget.dart b/lib/screens/patients/profile/soap_update/objective/add_examination_widget.dart index e990be79..5b5bfcb1 100644 --- a/lib/screens/patients/profile/soap_update/objective/add_examination_widget.dart +++ b/lib/screens/patients/profile/soap_update/objective/add_examination_widget.dart @@ -14,19 +14,21 @@ import 'package:provider/provider.dart'; // ignore: must_be_immutable class AddExaminationWidget extends StatefulWidget { MasterKeyModel item; - final Function(MasterKeyModel) removeHistory; - final Function(MySelectedExamination) addHistory; + final Function(MasterKeyModel) removeExamination; + final Function(MySelectedExamination) addExamination; final bool Function(MasterKeyModel) isServiceSelected; bool isExpand; final Function expandClick; + final List mySelectedExamination; AddExaminationWidget({ this.item, - this.removeHistory, - this.addHistory, + this.removeExamination, + this.addExamination, this.isServiceSelected, this.isExpand, this.expandClick, + this.mySelectedExamination, }); @override @@ -40,7 +42,17 @@ class _AddExaminationWidgetState extends State { @override void initState() { - examination.selectedExamination = widget.item; + if (getSelectedExam(widget.item) != null) { + examination = getSelectedExam(widget.item); + status = examination.isNormal + ? 1 + : examination.isAbnormal + ? 2 + : 3; + remarksController.text = examination.remark; + } else { + examination.selectedExamination = widget.item; + } super.initState(); } @@ -70,14 +82,15 @@ class _AddExaminationWidgetState extends State { onChanged: (newValue) { setState(() { if (widget.isServiceSelected(widget.item)) { - widget.removeHistory(widget.item); + if (!examination.isLocal) + widget.removeExamination(widget.item); widget.expandClick(); } else { examination.isNormal = status == 1; examination.isAbnormal = status == 2; examination.notExamined = status == 3; examination.remark = remarksController.text; - widget.addHistory(examination); + widget.addExamination(examination); widget.expandClick(); } }); @@ -113,18 +126,18 @@ class _AddExaminationWidgetState extends State { Row( children: [ Expanded( - child: Row( - children: [ - InkWell( - onTap: () { - setState(() { - status = 1; - }); - examination.isNormal = true; - examination.isAbnormal = false; - examination.notExamined = false; - }, - child: Container( + child: InkWell( + onTap: () { + setState(() { + status = 1; + }); + examination.isNormal = true; + examination.isAbnormal = false; + examination.notExamined = false; + }, + child: Row( + children: [ + Container( padding: EdgeInsets.all(2.0), margin: EdgeInsets.symmetric(horizontal: 6), width: 20, @@ -143,28 +156,28 @@ class _AddExaminationWidgetState extends State { ), ), ), - ), - AppText( - TranslationBase.of(context).normal, - fontWeight: FontWeight.normal, - fontFamily: 'Poppins', - fontSize: SizeConfig.textMultiplier * 1.6, - ), - ], + AppText( + TranslationBase.of(context).normal, + fontWeight: FontWeight.normal, + fontFamily: 'Poppins', + fontSize: SizeConfig.textMultiplier * 1.6, + ), + ], + ), )), Expanded( - child: Row( - children: [ - InkWell( - onTap: () { - setState(() { - status = 2; - }); - examination.isNormal = false; - examination.isAbnormal = true; - examination.notExamined = false; - }, - child: Container( + child: InkWell( + onTap: () { + setState(() { + status = 2; + }); + examination.isNormal = false; + examination.isAbnormal = true; + examination.notExamined = false; + }, + child: Row( + children: [ + Container( padding: EdgeInsets.all(2.0), margin: EdgeInsets.symmetric(horizontal: 6), width: 20, @@ -183,57 +196,58 @@ class _AddExaminationWidgetState extends State { ), ), ), - ), - AppText( - TranslationBase.of(context).abnormal, - fontWeight: FontWeight.normal, - fontFamily: 'Poppins', - fontSize: SizeConfig.textMultiplier * 1.6, - ), - ], + AppText( + TranslationBase.of(context).abnormal, + fontWeight: FontWeight.normal, + fontFamily: 'Poppins', + fontSize: SizeConfig.textMultiplier * 1.6, + ), + ], + ), )), - Expanded( + if (!examination.isLocal) + Expanded( + child: InkWell( + onTap: () { + setState(() { + status = 3; + }); + examination.isNormal = false; + examination.isAbnormal = false; + examination.notExamined = true; + }, child: Row( - children: [ - InkWell( - onTap: () { - setState(() { - status = 3; - }); - examination.isNormal = false; - examination.isAbnormal = false; - examination.notExamined = true; - }, - child: Container( - padding: EdgeInsets.all(2.0), - margin: EdgeInsets.symmetric(horizontal: 6), - width: 20, - height: 20, - decoration: BoxDecoration( - color: Colors.white, - shape: BoxShape.circle, - border: Border.all(color: Colors.grey, width: 1), - ), - child: Container( + children: [ + Container( + padding: EdgeInsets.all(2.0), + margin: EdgeInsets.symmetric(horizontal: 6), + width: 20, + height: 20, decoration: BoxDecoration( - color: status == 3 - ? HexColor("#D02127") - : Colors.white, + color: Colors.white, shape: BoxShape.circle, + border: Border.all(color: Colors.grey, width: 1), + ), + child: Container( + decoration: BoxDecoration( + color: status == 3 + ? HexColor("#D02127") + : Colors.white, + shape: BoxShape.circle, + ), ), ), - ), - ), - Expanded( - child: AppText( - TranslationBase.of(context).notExamined, - fontWeight: FontWeight.normal, - fontFamily: 'Poppins', - fontSize: SizeConfig.textMultiplier * 1.6, - ), + Expanded( + child: AppText( + TranslationBase.of(context).notExamined, + fontWeight: FontWeight.normal, + fontFamily: 'Poppins', + fontSize: SizeConfig.textMultiplier * 1.6, + ), + ), + ], ), - ], - )), + )), ], ), Container( @@ -256,4 +270,15 @@ class _AddExaminationWidgetState extends State { ), ); } + + MySelectedExamination getSelectedExam(MasterKeyModel masterKey) { + Iterable exam = widget.mySelectedExamination.where( + (element) => + masterKey.id == element.selectedExamination.id && + masterKey.typeId == element.selectedExamination.typeId); + if (exam.length > 0) { + return exam.first; + } + return null; + } } diff --git a/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart b/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart index d40faea5..5116ac6b 100644 --- a/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart +++ b/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart @@ -40,25 +40,6 @@ class ExaminationItemCard extends StatelessWidget { fontSize: SizeConfig.textMultiplier * 1.8, ), )), - Row( - children: [ - AppText( - TranslationBase.of(context).remove, - fontWeight: FontWeight.w600, - fontFamily: 'Poppins', - color: Colors.red.shade800, - fontSize: SizeConfig.textMultiplier * 1.8, - ), - InkWell( - onTap: removeExamination, - child: Icon( - Icons.clear, - size: 20, - color: Colors.red.shade800, - ), - ) - ], - ), ], ), AppText( @@ -79,6 +60,7 @@ class ExaminationItemCard extends StatelessWidget { SizedBox( height: 4, ), + if(examination.remark.isEmpty) AppText( examination.remark, fontWeight: FontWeight.normal, diff --git a/lib/screens/patients/profile/soap_update/objective/examinations_list_search_widget.dart b/lib/screens/patients/profile/soap_update/objective/examinations_list_search_widget.dart index 36b65d4c..ef6ec056 100644 --- a/lib/screens/patients/profile/soap_update/objective/examinations_list_search_widget.dart +++ b/lib/screens/patients/profile/soap_update/objective/examinations_list_search_widget.dart @@ -8,16 +8,17 @@ import 'package:flutter/material.dart'; import 'add_examination_widget.dart'; class ExaminationsListSearchWidget extends StatefulWidget { - final Function(MasterKeyModel) removeHistory; - final Function(MySelectedExamination) addHistory; + final Function(MasterKeyModel) removeExamination; + final Function(MySelectedExamination) addExamination; final bool Function(MasterKeyModel) isServiceSelected; final List masterList; + final List mySelectedExamination; ExaminationsListSearchWidget( - {this.removeHistory, - this.addHistory, + {this.removeExamination, + this.addExamination, this.isServiceSelected, - this.masterList}); + this.masterList, this.mySelectedExamination}); @override _ExaminationsListSearchWidgetState createState() => @@ -61,8 +62,9 @@ class _ExaminationsListSearchWidgetState ...items.mapIndexed((index, item) { return AddExaminationWidget( item: item, - addHistory: widget.addHistory, - removeHistory: widget.removeHistory, + addExamination: widget.addExamination, + removeExamination: widget.removeExamination, + mySelectedExamination: widget.mySelectedExamination, isServiceSelected: widget.isServiceSelected, isExpand: index == expandedIndex, expandClick: () { diff --git a/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart b/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart index 12004934..bd6cd39d 100644 --- a/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart +++ b/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart @@ -28,13 +28,11 @@ class UpdateObjectivePage extends StatefulWidget { final Function changePageViewIndex; final Function changeLoadingState; final int currentIndex; - final List mySelectedExamination; final PatiantInformtion patientInfo; UpdateObjectivePage( {Key key, this.changePageViewIndex, - this.mySelectedExamination, this.patientInfo, this.changeLoadingState, this.currentIndex}); @@ -45,8 +43,10 @@ class UpdateObjectivePage extends StatefulWidget { class _UpdateObjectivePageState extends State { bool isSysExaminationExpand = false; + List mySelectedExamination = List(); - BoxDecoration containerBorderDecoration(Color containerColor, Color borderColor) { + BoxDecoration containerBorderDecoration( + Color containerColor, Color borderColor) { return BoxDecoration( color: containerColor, shape: BoxShape.rectangle, @@ -62,11 +62,13 @@ class _UpdateObjectivePageState extends State { Widget build(BuildContext context) { return BaseView( onModelReady: (model) async { - widget.mySelectedExamination.clear(); - GetPhysicalExamReqModel getPhysicalExamReqModel = GetPhysicalExamReqModel( - patientMRN: widget.patientInfo.patientMRN, - episodeID: widget.patientInfo.episodeNo.toString(), - appointmentNo: int.parse(widget.patientInfo.appointmentNo.toString())); + mySelectedExamination.clear(); + GetPhysicalExamReqModel getPhysicalExamReqModel = + GetPhysicalExamReqModel( + patientMRN: widget.patientInfo.patientMRN, + episodeID: widget.patientInfo.episodeNo.toString(), + appointmentNo: + int.parse(widget.patientInfo.appointmentNo.toString())); await model.getPatientPhysicalExam(getPhysicalExamReqModel); if (model.patientPhysicalExamList.isNotEmpty) { @@ -79,16 +81,18 @@ class _UpdateObjectivePageState extends State { id: element.examId, ); MySelectedExamination tempEam = MySelectedExamination( - selectedExamination: examMaster, - remark: element.remarks, - isNormal: element.isNormal, - createdBy: element.createdBy, - createdOn:element.createdOn , + selectedExamination: examMaster, + remark: element.remarks, + isNormal: element.isNormal, + createdBy: element.createdBy, + createdOn: element.createdOn, editedOn: element.editedOn, - notExamined: element.notExamined, - isNew: element.isNew, - isAbnormal: element.isAbnormal,); - widget.mySelectedExamination.add(tempEam); + notExamined: element.notExamined, + isNew: element.isNew, + isLocal: false, + isAbnormal: element.isAbnormal, + ); + mySelectedExamination.add(tempEam); }); } @@ -104,9 +108,12 @@ class _UpdateObjectivePageState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ - SOAPStepHeader(currentIndex: widget.currentIndex, changePageViewIndex: widget.changePageViewIndex), + SOAPStepHeader( + currentIndex: widget.currentIndex, + changePageViewIndex: widget.changePageViewIndex), ExpandableSOAPWidget( - headerTitle: TranslationBase.of(context).physicalSystemExamination, + headerTitle: + TranslationBase.of(context).physicalSystemExamination, onTap: () { setState(() { isSysExaminationExpand = !isSysExaminationExpand; @@ -115,15 +122,17 @@ class _UpdateObjectivePageState extends State { child: Column( children: [ SOAPOpenItems( - label: "${TranslationBase.of(context).addExamination}", + label: + "${TranslationBase.of(context).addExamination}", onTap: () { openExaminationList(context); }, ), Column( - children: widget.mySelectedExamination.map((examination) { + children: mySelectedExamination.map((examination) { return ExaminationItemCard(examination, () { - removeExamination(examination.selectedExamination); + removeExamination( + examination.selectedExamination); }); }).toList(), ) @@ -200,41 +209,45 @@ class _UpdateObjectivePageState extends State { } submitUpdateObjectivePage(SOAPViewModel model) async { - if (widget.mySelectedExamination.isNotEmpty) { + if (mySelectedExamination.isNotEmpty) { + widget.changeLoadingState(true); Map profile = await sharedPref.getObj(DOCTOR_PROFILE); DoctorProfileModel doctorProfile = DoctorProfileModel.fromJson(profile); - PostPhysicalExamRequestModel postPhysicalExamRequestModel = new PostPhysicalExamRequestModel(); - widget.mySelectedExamination.forEach((exam) { - if (postPhysicalExamRequestModel.listHisProgNotePhysicalExaminationVM == null) - postPhysicalExamRequestModel.listHisProgNotePhysicalExaminationVM = []; + PostPhysicalExamRequestModel postPhysicalExamRequestModel = + new PostPhysicalExamRequestModel(); + mySelectedExamination.forEach((exam) { + if (postPhysicalExamRequestModel.listHisProgNotePhysicalExaminationVM == + null) + postPhysicalExamRequestModel.listHisProgNotePhysicalExaminationVM = + []; - postPhysicalExamRequestModel.listHisProgNotePhysicalExaminationVM.add(ListHisProgNotePhysicalExaminationVM( - patientMRN: widget.patientInfo.patientMRN, - episodeId: widget.patientInfo.episodeNo, - appointmentNo: widget.patientInfo.appointmentNo, - remarks: exam.remark ?? '', - createdBy: exam.createdBy ?? doctorProfile.doctorID, - createdOn: exam.createdOn?? - DateTime.now().toIso8601String(), - editedBy: doctorProfile.doctorID, - editedOn: DateTime.now().toIso8601String(), - examId: exam.selectedExamination.id, - examType: exam.selectedExamination.typeId, - isAbnormal: exam.isAbnormal, - isNormal: exam.isNormal, - notExamined: exam.notExamined, - examinationType: exam.isNormal - ? 1 - : exam.isAbnormal - ? 2 - : 3, - examinationTypeName: exam.isNormal - ? "Normal" - : exam.isAbnormal - ? 'AbNormal' - : "Not Examined", - isNew: exam.isNew)); + postPhysicalExamRequestModel.listHisProgNotePhysicalExaminationVM + .add(ListHisProgNotePhysicalExaminationVM( + patientMRN: widget.patientInfo.patientMRN, + episodeId: widget.patientInfo.episodeNo, + appointmentNo: widget.patientInfo.appointmentNo, + remarks: exam.remark ?? '', + createdBy: exam.createdBy ?? doctorProfile.doctorID, + createdOn: exam.createdOn ?? DateTime.now().toIso8601String(), + editedBy: doctorProfile.doctorID, + editedOn: DateTime.now().toIso8601String(), + examId: exam.selectedExamination.id, + examType: exam.selectedExamination.typeId, + isAbnormal: exam.isAbnormal, + isNormal: exam.isNormal, + notExamined: exam.notExamined, + examinationType: exam.isNormal + ? 1 + : exam.isAbnormal + ? 2 + : 3, + examinationTypeName: exam.isNormal + ? "Normal" + : exam.isAbnormal + ? 'AbNormal' + : "Not Examined", + isNew: exam.isNew)); }); if (model.patientPhysicalExamList.isEmpty) { @@ -244,11 +257,14 @@ class _UpdateObjectivePageState extends State { } if (model.state == ViewState.ErrorLocal) { + widget.changeLoadingState(false); Helpers.showErrorToast(model.error); } else { - widget.changeLoadingState(true); + widget.changeLoadingState(false); + // TODO Elham* return this + // widget.changeLoadingState(true); - widget.changePageViewIndex(2); + //widget.changePageViewIndex(2); } } else { Helpers.showErrorToast(TranslationBase.of(context).examinationErrorMsg); @@ -256,12 +272,14 @@ class _UpdateObjectivePageState extends State { } removeExamination(MasterKeyModel masterKey) { - Iterable history = widget.mySelectedExamination.where((element) => - masterKey.id == element.selectedExamination.id && masterKey.typeId == element.selectedExamination.typeId); + Iterable history = mySelectedExamination.where( + (element) => + masterKey.id == element.selectedExamination.id && + masterKey.typeId == element.selectedExamination.typeId); if (history.length > 0) setState(() { - widget.mySelectedExamination.remove(history.first); + mySelectedExamination.remove(history.first); }); } @@ -270,7 +288,7 @@ class _UpdateObjectivePageState extends State { context, FadePage( page: AddExaminationPage( - mySelectedExamination: widget.mySelectedExamination, + mySelectedExamination: mySelectedExamination, addSelectedExamination: () { setState(() { Navigator.of(context).pop(); @@ -287,7 +305,11 @@ class AddExaminationDailog extends StatefulWidget { final Function addSelectedExamination; final Function(MasterKeyModel) removeExamination; - const AddExaminationDailog({Key key, this.mySelectedExamination, this.addSelectedExamination, this.removeExamination}) + const AddExaminationDailog( + {Key key, + this.mySelectedExamination, + this.addSelectedExamination, + this.removeExamination}) : super(key: key); @override @@ -302,7 +324,8 @@ class _AddExaminationDailogState extends State { child: BaseView( onModelReady: (model) async { if (model.physicalExaminationList.length == 0) { - await model.getMasterLookup(MasterKeysService.PhysicalExamination); + await model + .getMasterLookup(MasterKeysService.PhysicalExamination); } }, builder: (_, model, w) => AppScaffold( @@ -312,19 +335,21 @@ class _AddExaminationDailogState extends State { child: Container( child: FractionallySizedBox( widthFactor: 0.9, - child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - SizedBox( - height: 16, - ), - AppText( - TranslationBase.of(context).physicalSystemExamination, - fontWeight: FontWeight.bold, - fontSize: 16, - ), - SizedBox( - height: 16, - ), - ]), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 16, + ), + AppText( + TranslationBase.of(context).physicalSystemExamination, + fontWeight: FontWeight.bold, + fontSize: 16, + ), + SizedBox( + height: 16, + ), + ]), ))), )), ); diff --git a/lib/screens/patients/profile/soap_update/plan/update_plan_page.dart b/lib/screens/patients/profile/soap_update/plan/update_plan_page.dart index d9d61835..114b73d2 100644 --- a/lib/screens/patients/profile/soap_update/plan/update_plan_page.dart +++ b/lib/screens/patients/profile/soap_update/plan/update_plan_page.dart @@ -27,14 +27,12 @@ class UpdatePlanPage extends StatefulWidget { final Function changeLoadingState; final int currentIndex; - GetPatientProgressNoteResModel patientProgressNote; UpdatePlanPage( {Key key, this.changePageViewIndex, this.patientInfo, this.changeLoadingState, - this.patientProgressNote, this.currentIndex}); @override @@ -44,6 +42,7 @@ class UpdatePlanPage extends StatefulWidget { class _UpdatePlanPageState extends State { bool isAddProgress = true; bool isProgressExpanded = true; + GetPatientProgressNoteResModel patientProgressNote =GetPatientProgressNoteResModel(); TextEditingController progressNoteController = TextEditingController(text: null); @@ -62,7 +61,7 @@ class _UpdatePlanPageState extends State { @override void initState() { super.initState(); - if (widget.patientProgressNote.planNote != null) { + if (patientProgressNote.planNote != null) { setState(() { isAddProgress = false; }); @@ -83,12 +82,12 @@ class _UpdatePlanPageState extends State { if (model.patientProgressNoteList.isNotEmpty) { progressNoteController.text = Helpers.parseHtmlString(model.patientProgressNoteList[0].planNote); - widget.patientProgressNote.planNote = progressNoteController.text; - widget.patientProgressNote.createdByName = model.patientProgressNoteList[0].createdByName; - widget.patientProgressNote.createdOn = model.patientProgressNoteList[0].createdOn; - widget.patientProgressNote.editedOn = model.patientProgressNoteList[0].editedOn; - widget.patientProgressNote.editedByName = model.patientProgressNoteList[0].editedByName; - widget.patientProgressNote.appointmentNo = model.patientProgressNoteList[0].appointmentNo; + patientProgressNote.planNote = progressNoteController.text; + patientProgressNote.createdByName = model.patientProgressNoteList[0].createdByName; + patientProgressNote.createdOn = model.patientProgressNoteList[0].createdOn; + patientProgressNote.editedOn = model.patientProgressNoteList[0].editedOn; + patientProgressNote.editedByName = model.patientProgressNoteList[0].editedByName; + patientProgressNote.appointmentNo = model.patientProgressNoteList[0].appointmentNo; setState(() { isAddProgress = false; @@ -133,14 +132,14 @@ class _UpdatePlanPageState extends State { maxLines: 4, inputType: TextInputType.multiline, onChanged: (value) { - widget.patientProgressNote.planNote = value; + patientProgressNote.planNote = value; }, ), ), SizedBox( height: 9, ), - if (widget.patientProgressNote.planNote != null && !isAddProgress) + if (patientProgressNote.planNote != null && !isAddProgress) Container( margin: EdgeInsets.only( left: 5, @@ -160,15 +159,15 @@ class _UpdatePlanPageState extends State { fontSize: 12, ), AppText( - widget.patientProgressNote.appointmentNo.toString() ?? '', + patientProgressNote.appointmentNo.toString() ?? '', fontWeight: FontWeight.w600, ), ], ), AppText( - widget.patientProgressNote.createdOn != null + patientProgressNote.createdOn != null ? AppDateUtils.getDayMonthYearDateFormatted( - DateTime.parse(widget.patientProgressNote.createdOn)) + DateTime.parse(patientProgressNote.createdOn)) : AppDateUtils.getDayMonthYearDateFormatted(DateTime.now()), fontWeight: FontWeight.w600, fontSize: 14, @@ -185,14 +184,14 @@ class _UpdatePlanPageState extends State { 'Condition: ', fontSize: 12, ), - AppText(widget.patientProgressNote.mName ?? '', + AppText(patientProgressNote.mName ?? '', fontWeight: FontWeight.w600), ], ), AppText( - widget.patientProgressNote.createdOn != null + patientProgressNote.createdOn != null ? AppDateUtils.getHour( - DateTime.parse(widget.patientProgressNote.createdOn)) + DateTime.parse(patientProgressNote.createdOn)) : AppDateUtils.getHour(DateTime.now()), fontWeight: FontWeight.w600, fontSize: 14, @@ -287,11 +286,11 @@ class _UpdatePlanPageState extends State { Map profile = await sharedPref.getObj(DOCTOR_PROFILE); DoctorProfileModel doctorProfile = DoctorProfileModel.fromJson(profile); setState(() { - widget.patientProgressNote.createdByName = - widget.patientProgressNote.createdByName ?? doctorProfile.doctorName; - widget.patientProgressNote.editedByName = doctorProfile.doctorName; - widget.patientProgressNote.createdOn = DateTime.now().toString(); - widget.patientProgressNote.planNote = progressNoteController.text; + patientProgressNote.createdByName = + patientProgressNote.createdByName ?? doctorProfile.doctorName; + patientProgressNote.editedByName = doctorProfile.doctorName; + patientProgressNote.createdOn = DateTime.now().toString(); + patientProgressNote.planNote = progressNoteController.text; isAddProgress = !isAddProgress; }); submitPlan(model); @@ -320,11 +319,12 @@ class _UpdatePlanPageState extends State { submitPlan(SOAPViewModel model) async { if (progressNoteController.text.isNotEmpty) { + widget.changeLoadingState(true); PostProgressNoteRequestModel postProgressNoteRequestModel = new PostProgressNoteRequestModel( patientMRN: widget.patientInfo.patientMRN, episodeId: widget.patientInfo.episodeNo, appointmentNo: widget.patientInfo.appointmentNo, - planNote: widget.patientProgressNote.planNote, + planNote: patientProgressNote.planNote, doctorID: '', editedBy: ''); @@ -339,10 +339,13 @@ class _UpdatePlanPageState extends State { } if (model.state == ViewState.ErrorLocal) { + Helpers.showErrorToast(model.error); } else { widget.changePageViewIndex(4, isChangeState: false); } + + widget.changeLoadingState(false); } else { Helpers.showErrorToast(TranslationBase.of(context).progressNoteErrorMsg); } diff --git a/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart b/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart index 12db7266..ade555ba 100644 --- a/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart +++ b/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart @@ -338,7 +338,6 @@ class _UpdateSubjectivePageState extends State { if (model.state == ViewState.ErrorLocal) { Helpers.showErrorToast(model.error); } - if (myHistoryList.length != 0) { await postHistories(model: model, myHistoryList: myHistoryList); if (model.state == ViewState.ErrorLocal) { diff --git a/lib/screens/patients/profile/soap_update/update_soap_index.dart b/lib/screens/patients/profile/soap_update/update_soap_index.dart index fd4e8791..883e19f0 100644 --- a/lib/screens/patients/profile/soap_update/update_soap_index.dart +++ b/lib/screens/patients/profile/soap_update/update_soap_index.dart @@ -31,11 +31,7 @@ class _UpdateSoapIndexState extends State int _currentIndex = 0; List myAllergiesList = List(); List myHistoryList = List(); - List mySelectedExamination = List(); - List mySelectedAssessment = List(); - GetPatientProgressNoteResModel patientProgressNote = - GetPatientProgressNoteResModel(); changePageViewIndex(pageIndex,{isChangeState = true}) { if (pageIndex != _currentIndex && isChangeState) @@ -110,20 +106,17 @@ class _UpdateSoapIndexState extends State UpdateObjectivePage( changePageViewIndex: changePageViewIndex, currentIndex: _currentIndex, - mySelectedExamination: mySelectedExamination, patientInfo: patient, changeLoadingState: changeLoadingState), UpdateAssessmentPage( changePageViewIndex: changePageViewIndex, currentIndex: _currentIndex, - mySelectedAssessmentList: mySelectedAssessment, patientInfo: patient, changeLoadingState: changeLoadingState), UpdatePlanPage( changePageViewIndex: changePageViewIndex, currentIndex: _currentIndex, patientInfo: patient, - patientProgressNote: patientProgressNote, changeLoadingState: changeLoadingState) ], ), From adab2d47d38efda8a881ce8d4923c827aa832158 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 8 Jul 2021 16:46:22 +0300 Subject: [PATCH 048/289] video stream bug disconnect fixes --- .../VideoStreamFloatingWidgetService.kt | 81 +++++++++++++++---- .../hmgDr/ui/fragment/VideoCallFragment.kt | 3 + lib/core/service/VideoCallService.dart | 4 +- 3 files changed, 70 insertions(+), 18 deletions(-) diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt index 02413827..f76104dc 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt @@ -182,8 +182,13 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, } override fun onDestroy() { - mWindowManager?.removeView(floatingWidgetView) -// disconnectSession() + try { + mWindowManager?.removeView(floatingWidgetView) + + } catch (e: Exception) { + Log.e("onDestroyService", "${e.localizedMessage}.") + } + // disconnectSession() super.onDestroy() } @@ -193,7 +198,12 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, cmTimer.stop() stopForeground(true) stopSelf() - + videoCallResponseListener?.minimizeVideoEvent(false) + try { + mWindowManager?.removeView(floatingWidgetView) + } catch (e: Exception) { + Log.e("stopService", "${e.localizedMessage}.") + } } /* Add Floating Widget View to Window Manager */ @@ -291,9 +301,20 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, arg0?.text = formattedCallTime try { - notificationCompatBuilder.contentView.setChronometer(R.id.notify_timer, cmTimer.base, null, true) - notificationCompatBuilder.bigContentView.setChronometer(R.id.notify_timer, cmTimer.base, null, true) - } catch (e : Exception){} + notificationCompatBuilder.contentView.setChronometer( + R.id.notify_timer, + cmTimer.base, + null, + true + ) + notificationCompatBuilder.bigContentView.setChronometer( + R.id.notify_timer, + cmTimer.base, + null, + true + ) + } catch (e: Exception) { + } // for change notification timer if (mNotificationManagerCompat != null) { @@ -321,6 +342,17 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, mSession = Session.Builder(this, apiKey, sessionId).build() mSession!!.setSessionListener(this) mSession!!.connect(token) + + mSession!!.setReconnectionListener(object : Session.ReconnectionListener { + override fun onReconnecting(session: Session?) { + + } + + override fun onReconnected(session: Session?) { + session?.connect(token) + session?.onResume() + } + }) } catch (e: Exception) { e.printStackTrace() } @@ -558,20 +590,26 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, } fun onMinimizedClicked() { - if (isCircle){ + if (isCircle) { onMiniCircleClicked() } if (isFullScreen) { windowManagerParams.width = 400 windowManagerParams.height = 600 - mWindowManager?.updateViewLayout(floatingWidgetView, windowManagerParams) + try { + mWindowManager?.updateViewLayout(floatingWidgetView, windowManagerParams) + } catch (e: Exception) { + } recordContainer.visibility = View.GONE } else { windowManagerParams.width = WindowManager.LayoutParams.MATCH_PARENT windowManagerParams.height = WindowManager.LayoutParams.MATCH_PARENT - mWindowManager?.updateViewLayout(floatingWidgetView, windowManagerParams) + try { + mWindowManager?.updateViewLayout(floatingWidgetView, windowManagerParams) + } catch (e: Exception) { + } if (isRecording) { recordContainer.visibility = View.VISIBLE @@ -637,12 +675,18 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, windowManagerParams.width = 400 windowManagerParams.height = 600 - mWindowManager?.updateViewLayout(floatingWidgetView, windowManagerParams) + try { + mWindowManager?.updateViewLayout(floatingWidgetView, windowManagerParams) + } catch (e: Exception) { + } } else { windowManagerParams.width = 300 windowManagerParams.height = 300 - mWindowManager?.updateViewLayout(floatingWidgetView, windowManagerParams) + try { + mWindowManager?.updateViewLayout(floatingWidgetView, windowManagerParams) + } catch (e: Exception) { + } } isCircle = !isCircle @@ -728,10 +772,10 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, override fun onDisconnected(session: Session) { Log.d(TAG, "onDisconnected: disconnected from session " + session.sessionId) - mSession = null - cmTimer.stop() - disconnectSession() - videoCallResponseListener?.minimizeVideoEvent(false) +// mSession = null +// cmTimer.stop() +// disconnectSession() +// videoCallResponseListener?.minimizeVideoEvent(false) } override fun onError(session: Session, opentokError: OpentokError) { @@ -1035,7 +1079,12 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, mRemoteViewsExpand.setTextViewText(R.id.notify_title, notificationData.mContentTitle) mRemoteViewsExpand.setTextViewText(R.id.notify_content, notificationData.mContentText) mRemoteViewsExpand.setOnClickPendingIntent(R.id.btn_end, endCallPendingIntent) - mRemoteViewsExpand.setChronometer(R.id.notify_timer, SystemClock.elapsedRealtime(), null, false) + mRemoteViewsExpand.setChronometer( + R.id.notify_timer, + SystemClock.elapsedRealtime(), + null, + false + ) notificationCompatBuilder // BIG_TEXT_STYLE sets title and content for API 16 (4.1 and after). diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt index b020ed29..4d649aac 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -199,6 +199,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } } + fun setCallListener(videoCallResponseListener: VideoCallResponseListener) { this.videoCallResponseListener = videoCallResponseListener } @@ -354,6 +355,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session checkClientConnected() handleVideoViewHeight(true) + + if (appLang == "ar") { progressBarLayout!!.layoutDirection = View.LAYOUT_DIRECTION_RTL } diff --git a/lib/core/service/VideoCallService.dart b/lib/core/service/VideoCallService.dart index f9693f69..73c31f91 100644 --- a/lib/core/service/VideoCallService.dart +++ b/lib/core/service/VideoCallService.dart @@ -33,8 +33,8 @@ class VideoCallService extends BaseService { // kToken: startCallRes.openTokenID, // kSessionId: startCallRes.openSessionID, // kApiKey:'46209962', - kToken: "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==", - kSessionId: "1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg", + kToken: "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGUyZjgxMjFlYTFkNzU5NjcxNDY2ZTM2ZjM3YTVhNTI2NGY0NTI2NzpzZXNzaW9uX2lkPTJfTVg0ME56STBOemsxTkg1LU1UWXlOVGN5TmpnMk5qZzNOMzQ1YUhCcGRtcDFXbVpDTDFkNE1qbDRkWFY2TTA4cmIySi1mZyZjcmVhdGVfdGltZT0xNjI1NzI2ODg5Jm5vbmNlPTAuNjc2Nzc4OTQxNjA1MTMxNSZyb2xlPXB1Ymxpc2hlciZleHBpcmVfdGltZT0xNjI4MzE4ODg4JmluaXRpYWxfbGF5b3V0X2NsYXNzX2xpc3Q9", + kSessionId: "2_MX40NzI0Nzk1NH5-MTYyNTcyNjg2Njg3N345aHBpdmp1WmZCL1d4Mjl4dXV6M08rb2J-fg", kApiKey:'47247954', vcId: patient.vcId, isRecording: isRecording, From ac6a6e78552cf3d53e3a1a75f231942478f35a46 Mon Sep 17 00:00:00 2001 From: Elham Rababh Date: Thu, 8 Jul 2021 17:31:46 +0300 Subject: [PATCH 049/289] keep show header in bottom sheet while it loading --- .../assessment/add_assessment_details.dart | 7 +- .../objective/add_examination_page.dart | 36 +-- .../objective/add_examination_widget.dart | 2 +- .../objective/examination_item_card.dart | 2 +- .../examinations_list_search_widget.dart | 6 +- .../objective/update_objective_page.dart | 7 +- .../bottom_sheet_title.dart | 5 +- .../subjective/allergies/add_allergies.dart | 174 +++++------ .../history/add_history_dialog.dart | 288 +++++++++--------- .../subjective/medication/add_medication.dart | 11 +- 10 files changed, 263 insertions(+), 275 deletions(-) diff --git a/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart b/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart index a30842f8..8b9cf7b8 100644 --- a/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart +++ b/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart @@ -32,6 +32,7 @@ class AddAssessmentDetails extends StatefulWidget { addSelectedAssessment; final PatiantInformtion patientInfo; final bool isUpdate; + AddAssessmentDetails( {Key key, this.mySelectedAssessment, @@ -129,14 +130,14 @@ class _AddAssessmentDetailsState extends State { }, builder: (_, model, w) => AppScaffold( baseViewModel: model, - isShowAppBar: false, + isShowAppBar: true, + appBar: BottomSheetTitle( + title: TranslationBase.of(context).addAssessmentDetails), backgroundColor: Theme.of(context).scaffoldBackgroundColor, body: SingleChildScrollView( child: Center( child: Column( children: [ - BottomSheetTitle( - title: TranslationBase.of(context).addAssessmentDetails), FractionallySizedBox( widthFactor: 0.9, child: Container( diff --git a/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart b/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart index 659de693..87af6ec2 100644 --- a/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart +++ b/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart @@ -4,6 +4,7 @@ import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; import 'package:doctor_app_flutter/models/SOAP/my_selected_examination.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/bottom_sheet_title.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; @@ -38,39 +39,14 @@ class _AddExaminationPageState extends State { }, builder: (_, model, w) => AppScaffold( baseViewModel: model, - isShowAppBar: false, + isShowAppBar: true, + appBar: BottomSheetTitle( + title: "${TranslationBase.of(context).addExamination}", + ), backgroundColor: Color.fromRGBO(248, 248, 248, 1), body: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ - Container( - padding: EdgeInsets.only( - left: 16, top: 70, right: 16, bottom: 16), - color: Colors.white, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Expanded( - child: AppText( - "${TranslationBase.of(context).addExamination}", - fontSize: SizeConfig.textMultiplier * 3.3, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - ), - InkWell( - onTap: () { - Navigator.of(context).pop(); - }, - child: Icon( - Icons.clear, - size: 40, - ), - ) - ], - ), - ), Expanded( child: SingleChildScrollView( child: Column( @@ -100,7 +76,7 @@ class _AddExaminationPageState extends State { widget.removeExamination(history); }); }, - addExamination: (selectedExamination) { + addHistory: (selectedExamination) { widget.mySelectedExamination .add(selectedExamination); // setState(() {}); diff --git a/lib/screens/patients/profile/soap_update/objective/add_examination_widget.dart b/lib/screens/patients/profile/soap_update/objective/add_examination_widget.dart index 5b5bfcb1..f0dc25cf 100644 --- a/lib/screens/patients/profile/soap_update/objective/add_examination_widget.dart +++ b/lib/screens/patients/profile/soap_update/objective/add_examination_widget.dart @@ -82,7 +82,7 @@ class _AddExaminationWidgetState extends State { onChanged: (newValue) { setState(() { if (widget.isServiceSelected(widget.item)) { - if (!examination.isLocal) + if (examination.isLocal) widget.removeExamination(widget.item); widget.expandClick(); } else { diff --git a/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart b/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart index 5116ac6b..84a4c740 100644 --- a/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart +++ b/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart @@ -60,7 +60,7 @@ class ExaminationItemCard extends StatelessWidget { SizedBox( height: 4, ), - if(examination.remark.isEmpty) + if(examination.remark.isNotEmpty) AppText( examination.remark, fontWeight: FontWeight.normal, diff --git a/lib/screens/patients/profile/soap_update/objective/examinations_list_search_widget.dart b/lib/screens/patients/profile/soap_update/objective/examinations_list_search_widget.dart index ef6ec056..c67102ee 100644 --- a/lib/screens/patients/profile/soap_update/objective/examinations_list_search_widget.dart +++ b/lib/screens/patients/profile/soap_update/objective/examinations_list_search_widget.dart @@ -9,14 +9,14 @@ import 'add_examination_widget.dart'; class ExaminationsListSearchWidget extends StatefulWidget { final Function(MasterKeyModel) removeExamination; - final Function(MySelectedExamination) addExamination; + final Function(MySelectedExamination) addHistory; final bool Function(MasterKeyModel) isServiceSelected; final List masterList; final List mySelectedExamination; ExaminationsListSearchWidget( {this.removeExamination, - this.addExamination, + this.addHistory, this.isServiceSelected, this.masterList, this.mySelectedExamination}); @@ -62,7 +62,7 @@ class _ExaminationsListSearchWidgetState ...items.mapIndexed((index, item) { return AddExaminationWidget( item: item, - addExamination: widget.addExamination, + addExamination: widget.addHistory, removeExamination: widget.removeExamination, mySelectedExamination: widget.mySelectedExamination, isServiceSelected: widget.isServiceSelected, diff --git a/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart b/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart index bd6cd39d..dbd3b080 100644 --- a/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart +++ b/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart @@ -260,11 +260,8 @@ class _UpdateObjectivePageState extends State { widget.changeLoadingState(false); Helpers.showErrorToast(model.error); } else { - widget.changeLoadingState(false); - // TODO Elham* return this - // widget.changeLoadingState(true); - - //widget.changePageViewIndex(2); + widget.changeLoadingState(true); + widget.changePageViewIndex(2); } } else { Helpers.showErrorToast(TranslationBase.of(context).examinationErrorMsg); diff --git a/lib/screens/patients/profile/soap_update/shared_soap_widgets/bottom_sheet_title.dart b/lib/screens/patients/profile/soap_update/shared_soap_widgets/bottom_sheet_title.dart index 8f5ecf93..d8110844 100644 --- a/lib/screens/patients/profile/soap_update/shared_soap_widgets/bottom_sheet_title.dart +++ b/lib/screens/patients/profile/soap_update/shared_soap_widgets/bottom_sheet_title.dart @@ -1,7 +1,7 @@ import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:flutter/material.dart'; -class BottomSheetTitle extends StatelessWidget { +class BottomSheetTitle extends StatelessWidget with PreferredSizeWidget { const BottomSheetTitle({ Key key, this.title, }) : super(key: key); @@ -57,4 +57,7 @@ class BottomSheetTitle extends StatelessWidget { ), ); } + + @override + Size get preferredSize => Size(double.maxFinite,115); } diff --git a/lib/screens/patients/profile/soap_update/subjective/allergies/add_allergies.dart b/lib/screens/patients/profile/soap_update/subjective/allergies/add_allergies.dart index fc7329e5..083c8743 100644 --- a/lib/screens/patients/profile/soap_update/subjective/allergies/add_allergies.dart +++ b/lib/screens/patients/profile/soap_update/subjective/allergies/add_allergies.dart @@ -1,5 +1,6 @@ import 'package:autocomplete_textfield/autocomplete_textfield.dart'; import 'package:doctor_app_flutter/core/enum/master_lookup_key.dart'; +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; import 'package:doctor_app_flutter/models/SOAP/my_selected_allergy.dart'; @@ -83,95 +84,100 @@ class _AddAllergiesState extends State { } }, builder: (_, model, w) => AppScaffold( - baseViewModel: model, - isShowAppBar: false, - body: Center( - child: Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - BottomSheetTitle( - title: TranslationBase.of(context).addAllergies, + baseViewModel: model, + isShowAppBar: true, + appBar: BottomSheetTitle( + title: TranslationBase.of(context).addAllergies, + ), + body: Center( + child: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 10, + ), + SizedBox( + height: 16, + ), + Expanded( + child: Center( + child: FractionallySizedBox( + widthFactor: 0.9, + child: Center( + child: NetworkBaseView( + baseViewModel: model, + child: MasterKeyCheckboxSearchAllergiesWidget( + model: model, + masterList: model.allergiesList, + removeAllergy: (master) { + setState(() { + removeAllergyFromLocalList(master); + }); + }, + addAllergy: + (MySelectedAllergy mySelectedAllergy) { + addAllergyLocally(mySelectedAllergy); + }, + addSelectedAllergy: () => widget + .addAllergiesFun(myAllergiesListLocal), + isServiceSelected: (master) => + isServiceSelected(master), + getServiceSelectedAllergy: (master) => + getSelectedAllergy(master), + ), + ), + ), + ), ), + ), + SizedBox( + height: MediaQuery.of(context).size.height * 0.11, + ), + ]), + ), + ), + bottomSheet: model.state == ViewState.Busy + ? Container( + height: 0, + ) + : Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(0.0), + ), + border: Border.all(color: HexColor('#707070'), width: 0), + ), + height: MediaQuery.of(context).size.height * 0.1, + width: double.infinity, + child: Column( + children: [ SizedBox( height: 10, ), - SizedBox( - height: 16, - ), - Expanded( - child: Center( - child: FractionallySizedBox( - widthFactor: 0.9, - child: Center( - child: NetworkBaseView( - baseViewModel: model, - child: MasterKeyCheckboxSearchAllergiesWidget( - model: model, - masterList: model.allergiesList, - removeAllergy: (master) { - setState(() { - removeAllergyFromLocalList(master); - }); - }, - addAllergy: - (MySelectedAllergy mySelectedAllergy) { - addAllergyLocally(mySelectedAllergy); - }, - addSelectedAllergy: () => widget - .addAllergiesFun(myAllergiesListLocal), - isServiceSelected: (master) => - isServiceSelected(master), - getServiceSelectedAllergy: (master) => - getSelectedAllergy(master), - ), - ), + Container( + child: FractionallySizedBox( + widthFactor: .80, + child: Center( + child: AppButton( + title: TranslationBase.of(context).addAllergies, + padding: 10, + color: Color(0xFF359846), + onPressed: () { + widget.addAllergiesFun(myAllergiesListLocal); + }, ), ), ), ), SizedBox( - height: MediaQuery.of(context).size.height * 0.11, + height: 5, ), - ]), - ), - ),bottomSheet: Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all( - Radius.circular(0.0), - ), - border: Border.all(color: HexColor('#707070'), width: 0), - ), - height: MediaQuery.of(context).size.height * 0.1, - width: double.infinity, - child: Column( - children: [ - SizedBox( - height: 10, - ), - Container( - child: FractionallySizedBox( - widthFactor: .80, - child: Center( - child: AppButton( - title: - TranslationBase.of(context).addAllergies, - padding: 10, - color: Color(0xFF359846), - onPressed: () { - widget.addAllergiesFun(myAllergiesListLocal); - }, - ), + ], ), ), - ), - SizedBox( - height: 5, - ), - ], - ), - ),), + ), ), ); } @@ -207,17 +213,15 @@ class _AddAllergiesState extends State { addAllergyLocally(MySelectedAllergy mySelectedAllergy) { if (mySelectedAllergy.selectedAllergy == null) { - Helpers.showErrorToast(TranslationBase - .of(context) - .requiredMsg); + Helpers.showErrorToast(TranslationBase.of(context).requiredMsg); } else { setState(() { List allergy = - // ignore: missing_return - myAllergiesListLocal - .where((element) => - mySelectedAllergy.selectedAllergy.id == - element.selectedAllergy.id) + // ignore: missing_return + myAllergiesListLocal + .where((element) => + mySelectedAllergy.selectedAllergy.id == + element.selectedAllergy.id) .toList(); if (allergy.isEmpty) { diff --git a/lib/screens/patients/profile/soap_update/subjective/history/add_history_dialog.dart b/lib/screens/patients/profile/soap_update/subjective/history/add_history_dialog.dart index 1da8db17..bd2f8502 100644 --- a/lib/screens/patients/profile/soap_update/subjective/history/add_history_dialog.dart +++ b/lib/screens/patients/profile/soap_update/subjective/history/add_history_dialog.dart @@ -1,4 +1,5 @@ import 'package:doctor_app_flutter/core/enum/master_lookup_key.dart'; +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; import 'package:doctor_app_flutter/models/SOAP/my_selected_history.dart'; @@ -19,10 +20,15 @@ class AddHistoryDialog extends StatefulWidget { final PageController controller; final List myHistoryList; final Function addSelectedHistories; - final Function (MasterKeyModel) removeHistory; + final Function(MasterKeyModel) removeHistory; const AddHistoryDialog( - {Key key, this.changePageViewIndex, this.controller, this.myHistoryList, this.addSelectedHistories, this.removeHistory}) + {Key key, + this.changePageViewIndex, + this.controller, + this.myHistoryList, + this.addSelectedHistories, + this.removeHistory}) : super(key: key); @override @@ -51,96 +57,96 @@ class _AddHistoryDialogState extends State { }, builder: (_, model, w) => AppScaffold( baseViewModel: model, - isShowAppBar: false, + isShowAppBar: true, + appBar: BottomSheetTitle( + title: TranslationBase.of(context).addHistory), body: Center( child: Container( child: Column( - children: [ - BottomSheetTitle(title:TranslationBase.of(context).addHistory), - SizedBox( - height: 10, - ), - PriorityBar(onTap: (activePriority) async { - widget.changePageViewIndex(activePriority); - }), - SizedBox( - height: 20, - ), - Expanded( - child: FractionallySizedBox( - widthFactor: 0.9, - child: PageView( - physics: NeverScrollableScrollPhysics(), - controller: widget.controller, - onPageChanged: (index) { - setState(() { - }); - }, - scrollDirection: Axis.horizontal, - children: [ - NetworkBaseView( - baseViewModel: model, - child: MasterKeyCheckboxSearchWidget( - model: model, - masterList: model.historyFamilyList, - removeHistory: (history){ - setState(() { - widget.removeHistory(history); - }); - }, - addHistory: (history){ - setState(() { - createAndAddHistory( - history); - }); - }, - addSelectedHistories: (){ - widget.addSelectedHistories(); - }, - isServiceSelected: (master) =>isServiceSelected(master), - ), - ), - NetworkBaseView( - baseViewModel: model, - child: MasterKeyCheckboxSearchWidget( - model: model, - masterList: model.mergeHistorySurgicalWithHistorySportList, - removeHistory: (history){ - setState(() { - widget.removeHistory(history); - }); - }, - addHistory: (history){ - setState(() { - createAndAddHistory( - history); - }); - }, - addSelectedHistories: (){ - widget.addSelectedHistories(); - }, - isServiceSelected: (master) =>isServiceSelected(master), - ), - ), - NetworkBaseView( - baseViewModel: model, - child: MasterKeyCheckboxSearchWidget( - model: model, - masterList: model.historyMedicalList, - removeHistory: (history){ - setState(() { - widget.removeHistory(history); - }); - }, - addHistory: (history){ - setState(() { - createAndAddHistory( - history); - }); - }, - addSelectedHistories: (){ - widget.addSelectedHistories(); - }, + children: [ + SizedBox( + height: 10, + ), + PriorityBar(onTap: (activePriority) async { + widget.changePageViewIndex(activePriority); + }), + SizedBox( + height: 20, + ), + Expanded( + child: FractionallySizedBox( + widthFactor: 0.9, + child: PageView( + physics: NeverScrollableScrollPhysics(), + controller: widget.controller, + onPageChanged: (index) { + setState(() {}); + }, + scrollDirection: Axis.horizontal, + children: [ + NetworkBaseView( + baseViewModel: model, + child: MasterKeyCheckboxSearchWidget( + model: model, + masterList: model.historyFamilyList, + removeHistory: (history) { + setState(() { + widget.removeHistory(history); + }); + }, + addHistory: (history) { + setState(() { + createAndAddHistory(history); + }); + }, + addSelectedHistories: () { + widget.addSelectedHistories(); + }, + isServiceSelected: (master) => + isServiceSelected(master), + ), + ), + NetworkBaseView( + baseViewModel: model, + child: MasterKeyCheckboxSearchWidget( + model: model, + masterList: model + .mergeHistorySurgicalWithHistorySportList, + removeHistory: (history) { + setState(() { + widget.removeHistory(history); + }); + }, + addHistory: (history) { + setState(() { + createAndAddHistory(history); + }); + }, + addSelectedHistories: () { + widget.addSelectedHistories(); + }, + isServiceSelected: (master) => + isServiceSelected(master), + ), + ), + NetworkBaseView( + baseViewModel: model, + child: MasterKeyCheckboxSearchWidget( + model: model, + masterList: model.historyMedicalList, + removeHistory: (history) { + setState(() { + widget.removeHistory(history); + }); + }, + addHistory: (history) { + setState(() { + createAndAddHistory(history); + }); + }, + addSelectedHistories: () { + widget.addSelectedHistories(); + }, isServiceSelected: (master) => isServiceSelected(master), ), @@ -149,59 +155,63 @@ class _AddHistoryDialogState extends State { ), ), ), - SizedBox(height:MediaQuery.of(context).size.height * 0.11 ,) + SizedBox( + height: MediaQuery.of(context).size.height * 0.11, + ) ], - ) - ), + )), ), - bottomSheet: Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all( - Radius.circular(0.0), - ), - border: Border.all(color: HexColor('#707070'), width: 0), - ), - height: MediaQuery.of(context).size.height * 0.1, - width: double.infinity, - child: Column( - children: [ - SizedBox( - height: 10, - ), - Container( - child: FractionallySizedBox( - widthFactor: .80, - child: Center( - child: AppButton( - title: - TranslationBase.of(context).addSelectedHistories, - padding: 10, - color: Color(0xFF359846), - onPressed: () { - widget.addSelectedHistories(); - }, - ), + bottomSheet: model.state == ViewState.Busy + ? Container( + height: 0, + ) + : Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(0.0), ), + border: Border.all(color: HexColor('#707070'), width: 0), + ), + height: MediaQuery.of(context).size.height * 0.1, + width: double.infinity, + child: Column( + children: [ + SizedBox( + height: 10, + ), + Container( + child: FractionallySizedBox( + widthFactor: .80, + child: Center( + child: AppButton( + title: TranslationBase.of(context) + .addSelectedHistories, + padding: 10, + color: Color(0xFF359846), + onPressed: () { + widget.addSelectedHistories(); + }, + ), + ), + ), + ), + SizedBox( + height: 5, + ), + ], ), ), - SizedBox( - height: 5, - ), - ], - ), - ), ), )); } createAndAddHistory(MasterKeyModel history) { - List myhistory = widget.myHistoryList.where((element) => - history.id == - element.selectedHistory.id && - history.typeId == - element.selectedHistory.typeId - ).toList(); + List myhistory = widget.myHistoryList + .where((element) => + history.id == element.selectedHistory.id && + history.typeId == element.selectedHistory.typeId) + .toList(); if (myhistory.isEmpty) { setState(() { @@ -217,18 +227,14 @@ class _AddHistoryDialogState extends State { } isServiceSelected(MasterKeyModel masterKey) { - Iterable history = - widget - .myHistoryList - .where((element) => - masterKey.id == element.selectedHistory.id && - masterKey.typeId == element.selectedHistory.typeId && - element.isChecked); + Iterable history = widget.myHistoryList.where( + (element) => + masterKey.id == element.selectedHistory.id && + masterKey.typeId == element.selectedHistory.typeId && + element.isChecked); if (history.length > 0) { return true; } return false; } - } - diff --git a/lib/screens/patients/profile/soap_update/subjective/medication/add_medication.dart b/lib/screens/patients/profile/soap_update/subjective/medication/add_medication.dart index 69475926..d7f8f6ed 100644 --- a/lib/screens/patients/profile/soap_update/subjective/medication/add_medication.dart +++ b/lib/screens/patients/profile/soap_update/subjective/medication/add_medication.dart @@ -1,6 +1,7 @@ // ignore: must_be_immutable import 'package:autocomplete_textfield/autocomplete_textfield.dart'; import 'package:doctor_app_flutter/core/enum/master_lookup_key.dart'; +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/search_drug/get_medication_response_model.dart'; import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; @@ -74,15 +75,15 @@ class _AddMedicationState extends State { }, builder: (_, model, w) => AppScaffold( baseViewModel: model, - isShowAppBar: false, + isShowAppBar: true, + appBar: BottomSheetTitle( + title: TranslationBase.of(context).addMedication, + ), body: Center( child: Container( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - BottomSheetTitle( - title: TranslationBase.of(context).addMedication, - ), SizedBox( height: 10, ), @@ -381,7 +382,7 @@ class _AddMedicationState extends State { ]), ), ), - bottomSheet: Container( + bottomSheet:model.state == ViewState.Busy?Container(height: 0,): Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.all( From c7c6314a8de087993c15d03518bc5a72ad9fc9f8 Mon Sep 17 00:00:00 2001 From: Elham Rababh Date: Sun, 11 Jul 2021 11:35:54 +0300 Subject: [PATCH 050/289] finish create episode fixes --- lib/config/localized_values.dart | 1 + .../assessment/add_assessment_details.dart | 13 +- .../assessment/update_assessment_page.dart | 3 +- .../soap_update/plan/update_plan_page.dart | 165 ++++++++++++------ .../shared_soap_widgets/steps_widget.dart | 32 ++-- lib/util/translations_delegate_base.dart | 1 + 6 files changed, 138 insertions(+), 77 deletions(-) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 089ff3b5..0a094b9b 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -703,4 +703,5 @@ const Map> localizedValues = { "addPrescription": {"en": "Add prescription", "ar": "إضافة الوصفات"}, "edit": {"en": "Edit", "ar": "تعديل"}, "summeryReply": {"en": "Summary Reply", "ar": "موجز الرد"}, + "finish": {"en": "Finish", "ar": "انهاء"}, }; diff --git a/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart b/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart index 8b9cf7b8..6f51fa40 100644 --- a/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart +++ b/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart @@ -18,6 +18,7 @@ import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/dialogs/master_key_dailog.dart'; +import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/auto_complete_text_field.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/text_fields_utils.dart'; @@ -254,6 +255,8 @@ class _AddAssessmentDetailsState extends State { MasterKeyDailog dialog = MasterKeyDailog( list: model.listOfDiagnosisCondition, okText: TranslationBase.of(context).ok, + selectedValue: widget.mySelectedAssessment.selectedDiagnosisCondition, + okFunction: (MasterKeyModel selectedValue) { setState(() { @@ -306,6 +309,7 @@ class _AddAssessmentDetailsState extends State { MasterKeyDailog dialog = MasterKeyDailog( list: model.listOfDiagnosisType, okText: TranslationBase.of(context).ok, + selectedValue: widget.mySelectedAssessment.selectedDiagnosisType, okFunction: (MasterKeyModel selectedValue) { setState(() { @@ -435,6 +439,7 @@ class _AddAssessmentDetailsState extends State { {SOAPViewModel model, MySelectedAssessment mySelectedAssessment, bool isUpdate = false}) async { + GifLoaderDialogUtils.showMyDialog(context); if (isUpdate) { PatchAssessmentReqModel patchAssessmentReqModel = PatchAssessmentReqModel( patientMRN: widget.patientInfo.patientMRN, @@ -465,8 +470,9 @@ class _AddAssessmentDetailsState extends State { await model.postAssessment(postAssessmentRequestModel); } - + GifLoaderDialogUtils.hideDialog(context); if (model.state == ViewState.ErrorLocal) { + Helpers.showErrorToast(model.error); } else { Map profile = await sharedPref.getObj(DOCTOR_PROFILE); @@ -474,10 +480,7 @@ class _AddAssessmentDetailsState extends State { DoctorProfileModel doctorProfile = DoctorProfileModel.fromJson(profile); mySelectedAssessment.icdCode10ID = mySelectedAssessment.selectedICD.code; mySelectedAssessment.doctorName = doctorProfile.doctorName; - - if (!isUpdate) { - widget.addSelectedAssessment(mySelectedAssessment, isUpdate); - } + widget.addSelectedAssessment(mySelectedAssessment, isUpdate); Navigator.of(context).pop(); } } diff --git a/lib/screens/patients/profile/soap_update/assessment/update_assessment_page.dart b/lib/screens/patients/profile/soap_update/assessment/update_assessment_page.dart index 1ab96170..f8da93f5 100644 --- a/lib/screens/patients/profile/soap_update/assessment/update_assessment_page.dart +++ b/lib/screens/patients/profile/soap_update/assessment/update_assessment_page.dart @@ -347,7 +347,7 @@ class _UpdateAssessmentPageState extends State { height: 6, ), AppText( - (assessment.remark != null || + (assessment.remark != null && assessment.remark != '') ? TranslationBase.of( @@ -546,6 +546,7 @@ class _UpdateAssessmentPageState extends State { addSelectedAssessment: (MySelectedAssessment mySelectedAssessment, bool isUpdate) async { setState(() { + if(!isUpdate) mySelectedAssessmentList.add(mySelectedAssessment); }); }); diff --git a/lib/screens/patients/profile/soap_update/plan/update_plan_page.dart b/lib/screens/patients/profile/soap_update/plan/update_plan_page.dart index 114b73d2..47165896 100644 --- a/lib/screens/patients/profile/soap_update/plan/update_plan_page.dart +++ b/lib/screens/patients/profile/soap_update/plan/update_plan_page.dart @@ -42,11 +42,14 @@ class UpdatePlanPage extends StatefulWidget { class _UpdatePlanPageState extends State { bool isAddProgress = true; bool isProgressExpanded = true; - GetPatientProgressNoteResModel patientProgressNote =GetPatientProgressNoteResModel(); + GetPatientProgressNoteResModel patientProgressNote = + GetPatientProgressNoteResModel(); - TextEditingController progressNoteController = TextEditingController(text: null); + TextEditingController progressNoteController = + TextEditingController(text: null); - BoxDecoration containerBorderDecoration(Color containerColor, Color borderColor) { + BoxDecoration containerBorderDecoration( + Color containerColor, Color borderColor) { return BoxDecoration( color: containerColor, shape: BoxShape.rectangle, @@ -72,22 +75,30 @@ class _UpdatePlanPageState extends State { Widget build(BuildContext context) { return BaseView( onModelReady: (model) async { - GetGetProgressNoteReqModel getGetProgressNoteReqModel = GetGetProgressNoteReqModel( - appointmentNo: int.parse(widget.patientInfo.appointmentNo.toString()), - patientMRN: widget.patientInfo.patientMRN, - episodeID: widget.patientInfo.episodeNo.toString(), - editedBy: '', - doctorID: ''); + GetGetProgressNoteReqModel getGetProgressNoteReqModel = + GetGetProgressNoteReqModel( + appointmentNo: + int.parse(widget.patientInfo.appointmentNo.toString()), + patientMRN: widget.patientInfo.patientMRN, + episodeID: widget.patientInfo.episodeNo.toString(), + editedBy: '', + doctorID: ''); await model.getPatientProgressNote(getGetProgressNoteReqModel); if (model.patientProgressNoteList.isNotEmpty) { - progressNoteController.text = Helpers.parseHtmlString(model.patientProgressNoteList[0].planNote); + progressNoteController.text = Helpers.parseHtmlString( + model.patientProgressNoteList[0].planNote); patientProgressNote.planNote = progressNoteController.text; - patientProgressNote.createdByName = model.patientProgressNoteList[0].createdByName; - patientProgressNote.createdOn = model.patientProgressNoteList[0].createdOn; - patientProgressNote.editedOn = model.patientProgressNoteList[0].editedOn; - patientProgressNote.editedByName = model.patientProgressNoteList[0].editedByName; - patientProgressNote.appointmentNo = model.patientProgressNoteList[0].appointmentNo; + patientProgressNote.createdByName = + model.patientProgressNoteList[0].createdByName; + patientProgressNote.createdOn = + model.patientProgressNoteList[0].createdOn; + patientProgressNote.editedOn = + model.patientProgressNoteList[0].editedOn; + patientProgressNote.editedByName = + model.patientProgressNoteList[0].editedByName; + patientProgressNote.appointmentNo = + model.patientProgressNoteList[0].appointmentNo; setState(() { isAddProgress = false; @@ -105,7 +116,9 @@ class _UpdatePlanPageState extends State { widthFactor: 0.90, child: Column( children: [ - SOAPStepHeader(currentIndex: widget.currentIndex, changePageViewIndex: widget.changePageViewIndex), + SOAPStepHeader( + currentIndex: widget.currentIndex, + changePageViewIndex: widget.changePageViewIndex), SizedBox( height: 10, ), @@ -124,33 +137,41 @@ class _UpdatePlanPageState extends State { children: [ if (isAddProgress) Container( - margin: EdgeInsets.only(left: 10, right: 10, top: 15), + margin: EdgeInsets.only( + left: 10, right: 10, top: 15), child: AppTextFieldCustom( - hintText: TranslationBase.of(context).progressNote, + hintText: TranslationBase.of(context) + .progressNote, controller: progressNoteController, minLines: 2, maxLines: 4, inputType: TextInputType.multiline, onChanged: (value) { - patientProgressNote.planNote = value; + setState(() { + patientProgressNote.planNote = value; + }); }, ), ), SizedBox( height: 9, ), - if (patientProgressNote.planNote != null && !isAddProgress) + if (patientProgressNote.planNote != null && + !isAddProgress) Container( margin: EdgeInsets.only( left: 5, right: 5, ), child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, children: [ Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + crossAxisAlignment: + CrossAxisAlignment.start, children: [ Row( children: [ @@ -159,24 +180,39 @@ class _UpdatePlanPageState extends State { fontSize: 12, ), AppText( - patientProgressNote.appointmentNo.toString() ?? '', + patientProgressNote + .appointmentNo != + null + ? patientProgressNote + .appointmentNo + .toString() + : '', fontWeight: FontWeight.w600, + fontSize: 14, ), ], ), AppText( - patientProgressNote.createdOn != null - ? AppDateUtils.getDayMonthYearDateFormatted( - DateTime.parse(patientProgressNote.createdOn)) - : AppDateUtils.getDayMonthYearDateFormatted(DateTime.now()), + patientProgressNote.createdOn != + null + ? AppDateUtils + .getDayMonthYearDateFormatted( + DateTime.parse( + patientProgressNote + .createdOn)) + : AppDateUtils + .getDayMonthYearDateFormatted( + DateTime.now()), fontWeight: FontWeight.w600, fontSize: 14, ) ], ), Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + crossAxisAlignment: + CrossAxisAlignment.start, children: [ Row( children: [ @@ -184,15 +220,21 @@ class _UpdatePlanPageState extends State { 'Condition: ', fontSize: 12, ), - AppText(patientProgressNote.mName ?? '', + AppText( + patientProgressNote.mName ?? + '', fontWeight: FontWeight.w600), ], ), AppText( - patientProgressNote.createdOn != null + patientProgressNote.createdOn != + null ? AppDateUtils.getHour( - DateTime.parse(patientProgressNote.createdOn)) - : AppDateUtils.getHour(DateTime.now()), + DateTime.parse( + patientProgressNote + .createdOn)) + : AppDateUtils.getHour( + DateTime.now()), fontWeight: FontWeight.w600, fontSize: 14, ) @@ -202,7 +244,8 @@ class _UpdatePlanPageState extends State { height: 8, ), Row( - mainAxisAlignment: MainAxisAlignment.start, + mainAxisAlignment: + MainAxisAlignment.start, children: [ Expanded( child: AppText( @@ -214,7 +257,6 @@ class _UpdatePlanPageState extends State { onTap: () { setState(() { isAddProgress = true; - widget.changePageViewIndex(3, isChangeState: false); }); }, child: Icon( @@ -275,30 +317,38 @@ class _UpdatePlanPageState extends State { ), Expanded( child: AppButton( - title: TranslationBase.of(context).next, + title: isAddProgress + ? TranslationBase.of(context).next + : TranslationBase.of(context).finish, fontWeight: FontWeight.w600, color: Colors.red[700], - loading: model.state == ViewState.BusyLocal, disabled: progressNoteController.text.isEmpty, onPressed: () async { if (progressNoteController.text.isNotEmpty) { if (isAddProgress) { - Map profile = await sharedPref.getObj(DOCTOR_PROFILE); - DoctorProfileModel doctorProfile = DoctorProfileModel.fromJson(profile); + Map profile = + await sharedPref.getObj(DOCTOR_PROFILE); + DoctorProfileModel doctorProfile = + DoctorProfileModel.fromJson(profile); setState(() { patientProgressNote.createdByName = - patientProgressNote.createdByName ?? doctorProfile.doctorName; - patientProgressNote.editedByName = doctorProfile.doctorName; - patientProgressNote.createdOn = DateTime.now().toString(); - patientProgressNote.planNote = progressNoteController.text; - isAddProgress = !isAddProgress; + patientProgressNote.createdByName ?? + doctorProfile.doctorName; + patientProgressNote.editedByName = + doctorProfile.doctorName; + patientProgressNote.createdOn = + DateTime.now().toString(); + patientProgressNote.planNote = + progressNoteController.text; }); submitPlan(model); } else { Navigator.of(context).pop(); } } else { - Helpers.showErrorToast(TranslationBase.of(context).progressNoteErrorMsg); + Helpers.showErrorToast( + TranslationBase.of(context) + .progressNoteErrorMsg); } }, ), @@ -320,31 +370,32 @@ class _UpdatePlanPageState extends State { submitPlan(SOAPViewModel model) async { if (progressNoteController.text.isNotEmpty) { widget.changeLoadingState(true); - PostProgressNoteRequestModel postProgressNoteRequestModel = new PostProgressNoteRequestModel( - patientMRN: widget.patientInfo.patientMRN, - episodeId: widget.patientInfo.episodeNo, - appointmentNo: widget.patientInfo.appointmentNo, - planNote: patientProgressNote.planNote, - doctorID: '', - editedBy: ''); + PostProgressNoteRequestModel postProgressNoteRequestModel = + new PostProgressNoteRequestModel( + patientMRN: widget.patientInfo.patientMRN, + episodeId: widget.patientInfo.episodeNo, + appointmentNo: widget.patientInfo.appointmentNo, + planNote: patientProgressNote.planNote, + doctorID: '', + editedBy: ''); if (model.patientProgressNoteList.isEmpty) { await model.postProgressNote(postProgressNoteRequestModel); } else { Map profile = await sharedPref.getObj(DOCTOR_PROFILE); - DoctorProfileModel doctorProfile = DoctorProfileModel.fromJson(profile); postProgressNoteRequestModel.editedBy = doctorProfile.doctorID; await model.patchProgressNote(postProgressNoteRequestModel); } if (model.state == ViewState.ErrorLocal) { - Helpers.showErrorToast(model.error); } else { - widget.changePageViewIndex(4, isChangeState: false); - } + setState(() { + isAddProgress = !isAddProgress; + }); + } widget.changeLoadingState(false); } else { Helpers.showErrorToast(TranslationBase.of(context).progressNoteErrorMsg); diff --git a/lib/screens/patients/profile/soap_update/shared_soap_widgets/steps_widget.dart b/lib/screens/patients/profile/soap_update/shared_soap_widgets/steps_widget.dart index c5c2e8ca..e79c24a7 100644 --- a/lib/screens/patients/profile/soap_update/shared_soap_widgets/steps_widget.dart +++ b/lib/screens/patients/profile/soap_update/shared_soap_widgets/steps_widget.dart @@ -247,6 +247,8 @@ class StepsWidget extends StatelessWidget { "Plan", fontWeight: FontWeight.bold, fontSize: 12, + textAlign: TextAlign.end, + marginLeft: 25, ), StatusLabel( selectedStepId: index, @@ -530,20 +532,22 @@ class StatusLabel extends StatelessWidget { ), border: Border.all(color: HexColor('#707070'), width: 0.30), ), - child: AppText( - stepId == selectedStepId - ? "inProgress" - : stepId < selectedStepId - ? "Completed" - : " Locked ", - fontWeight: FontWeight.bold, - textAlign: TextAlign.center, - fontSize: 10, - color: stepId == selectedStepId - ? Color(0xFFCC9B14) - : stepId < selectedStepId - ? Color(0xFF359846) - : Color(0xFF969696), + child: Center( + child: AppText( + stepId == selectedStepId + ? "inProgress" + : stepId < selectedStepId + ? "Completed" + : "Locked", + fontWeight: FontWeight.bold, + textAlign: TextAlign.center, + fontSize: 10, + color: stepId == selectedStepId + ? Color(0xFFCC9B14) + : stepId < selectedStepId + ? Color(0xFF359846) + : Color(0xFF969696), + ), ), ); } diff --git a/lib/util/translations_delegate_base.dart b/lib/util/translations_delegate_base.dart index 165a9bb5..e30a006a 100644 --- a/lib/util/translations_delegate_base.dart +++ b/lib/util/translations_delegate_base.dart @@ -562,6 +562,7 @@ class TranslationBase { localizedValues['no-priscription-listed'][locale.languageCode]; String get next => localizedValues['next'][locale.languageCode]; + String get finish => localizedValues['finish'][locale.languageCode]; String get previous => localizedValues['previous'][locale.languageCode]; From 3ee0acbf6e932e4568a46a75d12c880d7546613c Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Sun, 11 Jul 2021 16:56:36 +0300 Subject: [PATCH 051/289] Add Analytics Service --- .../com/hmg/hmgDr/ui/VideoCallContract.java | 1 + .../hmg/hmgDr/ui/VideoCallPresenterImpl.java | 1 - .../hmgDr/ui/fragment/VideoCallFragment.kt | 34 ++++++++++++++++--- android/google-services.json | 16 ++++----- lib/core/service/AnalyticsService.dart | 22 ++++++++++++ lib/core/service/VideoCallService.dart | 4 +-- lib/locator.dart | 2 ++ lib/main.dart | 8 ++++- pubspec.lock | 28 +++++++++++++++ pubspec.yaml | 1 + 10 files changed, 100 insertions(+), 17 deletions(-) create mode 100644 lib/core/service/AnalyticsService.dart diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallContract.java b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallContract.java index 2b099551..c26f8df4 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallContract.java +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallContract.java @@ -13,6 +13,7 @@ public interface VideoCallContract { void onCallChangeCallStatusSuccessful(SessionStatusModel sessionStatusModel); void onFailure(); + } interface VideoCallPresenter { diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallPresenterImpl.java b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallPresenterImpl.java index ea2128ba..4613c231 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallPresenterImpl.java +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallPresenterImpl.java @@ -59,7 +59,6 @@ public class VideoCallPresenterImpl implements VideoCallContract.VideoCallPresen public void onResponse(@NotNull Call call, @NotNull Response response) { if (!response.isSuccessful()) view.onFailure(); - } @Override diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt index abe6225e..cba99ab9 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -416,6 +416,20 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session mSession = Session.Builder(context, apiKey, sessionId).build() mSession!!.setSessionListener(this) mSession!!.connect(token) + + mSession!!.setReconnectionListener(object :Session.ReconnectionListener{ + override fun onReconnecting(p0: Session?) { + + } + + override fun onReconnected(session: Session?) { + session?.connect(token) + } + + + }) + + } catch (e: Exception) { e.printStackTrace() } @@ -453,10 +467,10 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onDisconnected(session: Session) { Log.d(TAG, "onDisconnected: disconnected from session " + session.sessionId) - mSession = null - cmTimer.stop() - disconnectSession() - videoCallResponseListener?.minimizeVideoEvent(false) +// mSession = null +// cmTimer.stop() +// disconnectSession() +// videoCallResponseListener?.minimizeVideoEvent(false) } override fun onError(session: Session, opentokError: OpentokError) { @@ -503,7 +517,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session mSubscriber!!.destroy() mSubscriber = null } - disconnectSession() + //disconnectSession() } override fun onStreamCreated(publisherKit: PublisherKit?, stream: Stream) { @@ -628,6 +642,16 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session sessionStatusModel!!.vcid ) ) +// if(isDismiss) +// dialog?.dismiss() +// else + onCallChangeCallStatusSuccessful() + } + + fun onCallChangeCallStatusSuccessful(){ + val returnIntent = Intent() + returnIntent.putExtra("CallEnd", sessionStatusModel) + videoCallResponseListener?.onCallFinished(Activity.RESULT_CANCELED, returnIntent) dialog?.dismiss() } diff --git a/android/google-services.json b/android/google-services.json index db548786..34a225b2 100644 --- a/android/google-services.json +++ b/android/google-services.json @@ -1,33 +1,33 @@ { "project_info": { - "project_number": "157373154094", - "project_id": "hmg-doctor-app-1553688619744", - "storage_bucket": "hmg-doctor-app-1553688619744.appspot.com" + "project_number": "1095694324958", + "project_id": "mobapp-bb272", + "storage_bucket": "mobapp-bb272.appspot.com" }, "client": [ { "client_info": { - "mobilesdk_app_id": "1:157373154094:android:daeea3a4e1f4462a1bf0bf", + "mobilesdk_app_id": "1:1095694324958:android:70a42e30fcc98ea33fde4f", "android_client_info": { "package_name": "com.hmg.hmgDr" } }, "oauth_client": [ { - "client_id": "157373154094-egrhbfr861l7k722g3v2gd4a0opi3r1u.apps.googleusercontent.com", + "client_id": "1095694324958-5psabq8tpbti0uqo8bt46atjtbas9uhr.apps.googleusercontent.com", "client_type": 3 } ], "api_key": [ { - "current_key": "AIzaSyDX8RPwu00MyrpqC-T2zXtrUQvTQGRv1mM" + "current_key": "AIzaSyCuPtf1hTikWXrp5OQIVfqO-TJWubI-Vd8" } ], "services": { "appinvite_service": { "other_platform_oauth_client": [ { - "client_id": "157373154094-egrhbfr861l7k722g3v2gd4a0opi3r1u.apps.googleusercontent.com", + "client_id": "1095694324958-5psabq8tpbti0uqo8bt46atjtbas9uhr.apps.googleusercontent.com", "client_type": 3 } ] @@ -36,4 +36,4 @@ } ], "configuration_version": "1" -} \ No newline at end of file +} diff --git a/lib/core/service/AnalyticsService.dart b/lib/core/service/AnalyticsService.dart new file mode 100644 index 00000000..660267d5 --- /dev/null +++ b/lib/core/service/AnalyticsService.dart @@ -0,0 +1,22 @@ +import 'package:firebase_analytics/firebase_analytics.dart'; +import 'package:firebase_analytics/observer.dart'; + +class AnalyticsService { + final FirebaseAnalytics _analytics = FirebaseAnalytics(); + + FirebaseAnalyticsObserver getAnalyticsObserver() => + FirebaseAnalyticsObserver(analytics: _analytics); + + Future logEvent( + {String eventCategory, + String eventLabel, + String eventAction, + String eventValue}) async { + await _analytics.logEvent(name: 'event', parameters: { + "eventCategory": eventCategory, + "eventLabel": eventLabel, + "eventAction": eventAction, + "eventValue": eventValue + }); + } +} diff --git a/lib/core/service/VideoCallService.dart b/lib/core/service/VideoCallService.dart index dcc31b71..50a507e6 100644 --- a/lib/core/service/VideoCallService.dart +++ b/lib/core/service/VideoCallService.dart @@ -32,8 +32,8 @@ class VideoCallService extends BaseService { kToken: startCallRes.openTokenID, kSessionId: startCallRes.openSessionID, kApiKey:'46209962', - // kToken: "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==", - // kSessionId: "1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg", + // kToken: "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGUyZjgxMjFlYTFkNzU5NjcxNDY2ZTM2ZjM3YTVhNTI2NGY0NTI2NzpzZXNzaW9uX2lkPTJfTVg0ME56STBOemsxTkg1LU1UWXlOVGN5TmpnMk5qZzNOMzQ1YUhCcGRtcDFXbVpDTDFkNE1qbDRkWFY2TTA4cmIySi1mZyZjcmVhdGVfdGltZT0xNjI1NzI2ODg5Jm5vbmNlPTAuNjc2Nzc4OTQxNjA1MTMxNSZyb2xlPXB1Ymxpc2hlciZleHBpcmVfdGltZT0xNjI4MzE4ODg4JmluaXRpYWxfbGF5b3V0X2NsYXNzX2xpc3Q9", + // kSessionId: "2_MX40NzI0Nzk1NH5-MTYyNTcyNjg2Njg3N345aHBpdmp1WmZCL1d4Mjl4dXV6M08rb2J-fg", // kApiKey:'47247954', vcId: patient.vcId, isRecording: isRecording, diff --git a/lib/locator.dart b/lib/locator.dart index d74fad8b..aa259758 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -10,6 +10,7 @@ import 'package:doctor_app_flutter/core/viewModel/scan_qr_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/sick_leave_view_model.dart'; import 'package:get_it/get_it.dart'; +import 'core/service/AnalyticsService.dart'; import 'core/service/NavigationService.dart'; import 'core/service/VideoCallService.dart'; import 'core/service/home/dasboard_service.dart'; @@ -98,6 +99,7 @@ void setupLocator() { locator.registerLazySingleton(() => ScanQrService()); locator.registerLazySingleton(() => SpecialClinicsService()); locator.registerLazySingleton(() => VideoCallService()); + locator.registerLazySingleton(() => AnalyticsService()); /// View Model locator.registerFactory(() => DoctorReplayViewModel()); diff --git a/lib/main.dart b/lib/main.dart index c29429b0..bf319a84 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,6 +2,8 @@ import 'package:doctor_app_flutter/core/provider/robot_provider.dart'; import 'package:doctor_app_flutter/core/viewModel/livecare_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:firebase_analytics/firebase_analytics.dart'; +import 'package:firebase_analytics/observer.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; @@ -11,6 +13,7 @@ import 'package:provider/provider.dart'; import './config/size_config.dart'; import './routes.dart'; import 'config/config.dart'; +import 'core/service/AnalyticsService.dart'; import 'core/service/NavigationService.dart'; import 'core/viewModel/authentication_view_model.dart'; import 'locator.dart'; @@ -67,7 +70,10 @@ class MyApp extends StatelessWidget { dividerColor: Colors.grey[350], backgroundColor: Color.fromRGBO(255, 255, 255, 1), ), - navigatorKey: locator().navigatorKey, + navigatorKey: locator().navigatorKey, + navigatorObservers:[ + locator().getAnalyticsObserver(), + ], initialRoute: INIT_ROUTE, routes: routes, debugShowCheckedModeBanner: false, diff --git a/pubspec.lock b/pubspec.lock index a408ffd5..c90d86d9 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -351,6 +351,34 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "5.2.1" + firebase: + dependency: transitive + description: + name: firebase + url: "https://pub.dartlang.org" + source: hosted + version: "7.3.3" + firebase_analytics: + dependency: "direct main" + description: + name: firebase_analytics + url: "https://pub.dartlang.org" + source: hosted + version: "6.3.0" + firebase_analytics_platform_interface: + dependency: transitive + description: + name: firebase_analytics_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + firebase_analytics_web: + dependency: transitive + description: + name: firebase_analytics_web + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.1" firebase_core: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 1429bc3e..8582b9cb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -71,6 +71,7 @@ dependencies: # Firebase firebase_messaging: ^7.0.3 + firebase_analytics: 6.3.0 #GIF image flutter_gifimage: ^1.0.1 From 9b40638f863645a989fd06607ff3f958ef4e8eb1 Mon Sep 17 00:00:00 2001 From: Elham Rababh Date: Sun, 11 Jul 2021 17:07:17 +0300 Subject: [PATCH 052/289] fix get allergies issues --- lib/models/SOAP/my_selected_allergy.dart | 8 +- .../subjective/allergies/add_allergies.dart | 15 +- .../subjective/allergies/allergies_item.dart | 195 ++++++++ ..._key_checkbox_search_allergies_widget.dart | 148 ++++++ .../allergies/update_allergies_widget.dart | 6 +- ..._key_checkbox_search_allergies_widget.dart | 421 ------------------ .../user-guid/custom_validation_error.dart | 6 +- 7 files changed, 364 insertions(+), 435 deletions(-) create mode 100644 lib/screens/patients/profile/soap_update/subjective/allergies/allergies_item.dart create mode 100644 lib/screens/patients/profile/soap_update/subjective/allergies/master_key_checkbox_search_allergies_widget.dart delete mode 100644 lib/widgets/shared/master_key_checkbox_search_allergies_widget.dart diff --git a/lib/models/SOAP/my_selected_allergy.dart b/lib/models/SOAP/my_selected_allergy.dart index 66234db3..90031230 100644 --- a/lib/models/SOAP/my_selected_allergy.dart +++ b/lib/models/SOAP/my_selected_allergy.dart @@ -8,6 +8,7 @@ class MySelectedAllergy { bool isExpanded; bool isLocal; int createdBy; + bool hasValidationError; MySelectedAllergy( {this.selectedAllergySeverity, @@ -15,8 +16,9 @@ class MySelectedAllergy { this.remark, this.isChecked, this.isExpanded = true, - this.isLocal = true, - this.createdBy}); + this.isLocal = true, + this.createdBy, + this.hasValidationError = false}); MySelectedAllergy.fromJson(Map json) { selectedAllergySeverity = json['selectedAllergySeverity'] != null @@ -30,6 +32,7 @@ class MySelectedAllergy { isExpanded = json['isExpanded']; isLocal = json['isLocal']; createdBy = json['createdBy']; + hasValidationError = json['hasValidationError']; } Map toJson() { @@ -45,6 +48,7 @@ class MySelectedAllergy { data['isExpanded'] = this.isExpanded; data['createdBy'] = this.createdBy; data['isLocal'] = this.isLocal; + data['hasValidationError'] = this.hasValidationError; return data; } } diff --git a/lib/screens/patients/profile/soap_update/subjective/allergies/add_allergies.dart b/lib/screens/patients/profile/soap_update/subjective/allergies/add_allergies.dart index 083c8743..4cf20318 100644 --- a/lib/screens/patients/profile/soap_update/subjective/allergies/add_allergies.dart +++ b/lib/screens/patients/profile/soap_update/subjective/allergies/add_allergies.dart @@ -9,12 +9,12 @@ import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/master_key_checkbox_search_allergies_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; import 'package:flutter/material.dart'; import 'package:hexcolor/hexcolor.dart'; import '../../shared_soap_widgets/bottom_sheet_title.dart'; +import 'master_key_checkbox_search_allergies_widget.dart'; class AddAllergies extends StatefulWidget { final Function addAllergiesFun; @@ -119,8 +119,13 @@ class _AddAllergiesState extends State { (MySelectedAllergy mySelectedAllergy) { addAllergyLocally(mySelectedAllergy); }, - addSelectedAllergy: () => widget - .addAllergiesFun(myAllergiesListLocal), + addSelectedAllergy: () { + + setState(() { + widget + .addAllergiesFun(myAllergiesListLocal); + }); + }, isServiceSelected: (master) => isServiceSelected(master), getServiceSelectedAllergy: (master) => @@ -165,7 +170,9 @@ class _AddAllergiesState extends State { padding: 10, color: Color(0xFF359846), onPressed: () { - widget.addAllergiesFun(myAllergiesListLocal); + setState(() { + widget.addAllergiesFun(myAllergiesListLocal); + }); }, ), ), diff --git a/lib/screens/patients/profile/soap_update/subjective/allergies/allergies_item.dart b/lib/screens/patients/profile/soap_update/subjective/allergies/allergies_item.dart new file mode 100644 index 00000000..8a402a7b --- /dev/null +++ b/lib/screens/patients/profile/soap_update/subjective/allergies/allergies_item.dart @@ -0,0 +1,195 @@ +import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; +import 'package:doctor_app_flutter/models/SOAP/my_selected_allergy.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/dialogs/master_key_dailog.dart'; +import 'package:doctor_app_flutter/widgets/shared/expandable-widget-header-body.dart'; +import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; +import 'package:eva_icons_flutter/eva_icons_flutter.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class AddAllergiesItem extends StatefulWidget { + // TODO Elham* see what fun we can move here without effects + final SOAPViewModel model; + final Function(MasterKeyModel) removeAllergy; + final Function(MySelectedAllergy mySelectedAllergy) addAllergy; + final bool Function(MasterKeyModel) isServiceSelected; + final MySelectedAllergy Function(MasterKeyModel) getServiceSelectedAllergy; + + final MasterKeyModel item; + + const AddAllergiesItem( + {Key key, + this.model, + this.removeAllergy, + this.addAllergy, + this.isServiceSelected, + this.getServiceSelectedAllergy, + this.item}) + : super(key: key); + + @override + _AddAllergiesItemState createState() => _AddAllergiesItemState(); +} + +class _AddAllergiesItemState extends State { + MasterKeyModel _selectedAllergySeverity; + bool isSubmitted = false; + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + + bool isSelected = widget.isServiceSelected(widget.item); + MySelectedAllergy mySelectedAllergy; + if (isSelected) { + mySelectedAllergy = widget.getServiceSelectedAllergy(widget.item); + } + TextEditingController remarkController = TextEditingController( + text: isSelected ? mySelectedAllergy.remark : null); + TextEditingController severityController = TextEditingController( + text: isSelected + ? mySelectedAllergy.selectedAllergySeverity != null + ? projectViewModel.isArabic + ? mySelectedAllergy.selectedAllergySeverity.nameAr + : mySelectedAllergy.selectedAllergySeverity.nameEn + : null + : null); + return HeaderBodyExpandableNotifier( + headerWidget: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Checkbox( + value: widget.isServiceSelected(widget.item), + activeColor: Colors.red[800], + onChanged: (bool newValue) { + onTapItem(); + }), + InkWell( + onTap:onTapItem, + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 10, vertical: 0), + child: Container( + child: AppText( + projectViewModel.isArabic + ? widget.item.nameAr != "" + ? widget.item.nameAr + : widget.item.nameEn + : widget.item.nameEn, + color: Color(0xFF575757), + fontSize: 16, + fontWeight: FontWeight.w600, + ), + width: MediaQuery.of(context).size.width * 0.55, + ), + ), + ), + ], + ), + InkWell( + onTap: () { + if (mySelectedAllergy != null) { + setState(() { + mySelectedAllergy.isExpanded = + mySelectedAllergy.isExpanded ? false : true; + }); + } + }, + child: Icon((mySelectedAllergy != null + ? mySelectedAllergy.isExpanded + : false) + ? EvaIcons.arrowIosUpwardOutline + : EvaIcons.arrowIosDownwardOutline)) + ], + ), + bodyWidget: Center( + child: FractionallySizedBox( + widthFactor: 0.9, + child: Center( + child: Column( + children: [ + AppTextFieldCustom( + onClick: widget.model.allergySeverityList != null + ? () { + MasterKeyDailog dialog = MasterKeyDailog( + list: widget.model.allergySeverityList, + selectedValue: + mySelectedAllergy.selectedAllergySeverity, + okText: TranslationBase.of(context).ok, + okFunction: (selectedValue) { + setState(() { + mySelectedAllergy.selectedAllergySeverity = + selectedValue; + }); + }, + ); + showDialog( + barrierDismissible: false, + context: context, + builder: (BuildContext context) { + return dialog; + }, + ); + } + : null, + isTextFieldHasSuffix: true, + hintText: TranslationBase.of(context).selectSeverity, + enabled: false, + maxLines: 2, + minLines: 2, + validationError: mySelectedAllergy != null && + mySelectedAllergy.selectedAllergySeverity == null && + mySelectedAllergy.hasValidationError + ? TranslationBase.of(context).emptyMessage + : null, + controller: severityController, + ), + SizedBox( + height: 10, + ), + AppTextFieldCustom( + hintText: TranslationBase.of(context).remarks, + controller: remarkController, + maxLines: 25, + minLines: 3, + hasBorder: true, + inputType: TextInputType.multiline, + + ), + SizedBox( + height: 10, + ), + ], + ), + ), + ), + ), + isExpand: + mySelectedAllergy != null ? mySelectedAllergy.isExpanded : false, + ); + } + + onTapItem(){ + setState(() { + if (widget.isServiceSelected(widget.item)) { + widget.removeAllergy(widget.item); + } else { + MySelectedAllergy mySelectedAllergy = + new MySelectedAllergy( + selectedAllergy: widget.item, + selectedAllergySeverity: _selectedAllergySeverity, + remark: null, + isChecked: true, + isExpanded: true); + widget.addAllergy(mySelectedAllergy); + } + }); + } +} diff --git a/lib/screens/patients/profile/soap_update/subjective/allergies/master_key_checkbox_search_allergies_widget.dart b/lib/screens/patients/profile/soap_update/subjective/allergies/master_key_checkbox_search_allergies_widget.dart new file mode 100644 index 00000000..8644c9a9 --- /dev/null +++ b/lib/screens/patients/profile/soap_update/subjective/allergies/master_key_checkbox_search_allergies_widget.dart @@ -0,0 +1,148 @@ +import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; +import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; +import 'package:doctor_app_flutter/models/SOAP/my_selected_allergy.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/shared/divider_with_spaces_around.dart'; +import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'allergies_item.dart'; + + +class MasterKeyCheckboxSearchAllergiesWidget extends StatefulWidget { + final SOAPViewModel model; + final Function() addSelectedAllergy; + final Function(MasterKeyModel) removeAllergy; + final Function(MySelectedAllergy mySelectedAllergy) addAllergy; + final bool Function(MasterKeyModel) isServiceSelected; + final MySelectedAllergy Function(MasterKeyModel) getServiceSelectedAllergy; + + final List masterList; + final String buttonName; + final String hintSearchText; + + MasterKeyCheckboxSearchAllergiesWidget( + {Key key, + this.model, + this.addSelectedAllergy, + this.removeAllergy, + this.masterList, + this.addAllergy, + this.isServiceSelected, + this.buttonName, + this.hintSearchText, + this.getServiceSelectedAllergy}) + : super(key: key); + + @override + _MasterKeyCheckboxSearchAllergiesWidgetState createState() => + _MasterKeyCheckboxSearchAllergiesWidgetState(); +} + +class _MasterKeyCheckboxSearchAllergiesWidgetState + extends State { + List items = List(); + + + @override + void initState() { + items.addAll(widget.masterList); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Container( + child: Column( + children: [ + Expanded( + child: Container( + height: MediaQuery.of(context).size.height * 0.70, + child: Center( + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.white), + child: Column( + children: [ + AppTextFieldCustom( + // height: + // MediaQuery.of(context).size.height * 0.070, + hintText: + TranslationBase.of(context).selectAllergy, + isTextFieldHasSuffix: true, + hasBorder: false, + // controller: filteredSearchController, + onChanged: (value) { + filterSearchResults(value); + }, + suffixIcon: IconButton( + icon: Icon( + Icons.search, + color: Colors.black, + )), + ), + DividerWithSpacesAround(), + SizedBox( + height: 10, + ), + Expanded( + child: FractionallySizedBox( + widthFactor: 0.9, + child: Container( + height: + MediaQuery.of(context).size.height * 0.60, + child: ListView.builder( + itemCount: items.length, + itemBuilder: (context, index) { + + return AddAllergiesItem( + item:items[index], + model: widget.model, + removeAllergy: widget.removeAllergy, + addAllergy:widget.addAllergy, + isServiceSelected: widget.isServiceSelected, + getServiceSelectedAllergy: widget.getServiceSelectedAllergy, + ); + }, + ), + ), + ), + ), + ], + ))), + ), + ), + SizedBox( + height: 10, + ), + ], + ), + ); + } + + void filterSearchResults(String query) { + List dummySearchList = List(); + dummySearchList.addAll(widget.masterList); + if (query.isNotEmpty) { + List dummyListData = List(); + dummySearchList.forEach((items) { + if (items.nameAr.toLowerCase().contains(query.toLowerCase()) || + items.nameEn.toLowerCase().contains(query.toLowerCase())) { + dummyListData.add(items); + } + }); + setState(() { + items.clear(); + items.addAll(dummyListData); + }); + return; + } else { + setState(() { + items.clear(); + items.addAll(widget.masterList); + }); + } + } +} diff --git a/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart b/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart index cb7d7d00..4be953a7 100644 --- a/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart +++ b/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart @@ -34,8 +34,6 @@ class _UpdateAllergiesWidgetState extends State { return Column( children: [ - - SOAPOpenItems(label: "${TranslationBase.of(context).addAllergies}",onTap: () { openAllergiesList(context, changeAllState, removeAllergy); },), @@ -173,11 +171,11 @@ class _UpdateAllergiesWidgetState extends State { builder: (context) { return AddAllergies( myAllergiesList: widget.myAllergiesList, - addAllergiesFun: (List mySelectedAllergy) { bool isAllDataFilled = true; mySelectedAllergy.forEach((element) { if (element.selectedAllergySeverity == null) { + element.hasValidationError = true; isAllDataFilled = false; } }); @@ -200,8 +198,6 @@ class _UpdateAllergiesWidgetState extends State { removedList.forEach((element) { removeAllergy(element); }); - - changeParentState(); Navigator.of(context).pop(); } else { diff --git a/lib/widgets/shared/master_key_checkbox_search_allergies_widget.dart b/lib/widgets/shared/master_key_checkbox_search_allergies_widget.dart deleted file mode 100644 index 7a1fc3f5..00000000 --- a/lib/widgets/shared/master_key_checkbox_search_allergies_widget.dart +++ /dev/null @@ -1,421 +0,0 @@ -import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; -import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; -import 'package:doctor_app_flutter/models/SOAP/my_selected_allergy.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/shared/text_fields/new_text_Field.dart'; -import 'package:doctor_app_flutter/widgets/shared/user-guid/custom_validation_error.dart'; -import 'package:eva_icons_flutter/eva_icons_flutter.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - -import 'app_texts_widget.dart'; -import 'dialogs/master_key_dailog.dart'; -import 'divider_with_spaces_around.dart'; -import 'expandable-widget-header-body.dart'; -import 'text_fields/app-textfield-custom.dart'; - -class MasterKeyCheckboxSearchAllergiesWidget extends StatefulWidget { - final SOAPViewModel model; - final Function() addSelectedAllergy; - final Function(MasterKeyModel) removeAllergy; - final Function(MySelectedAllergy mySelectedAllergy) addAllergy; - final bool Function(MasterKeyModel) isServiceSelected; - final MySelectedAllergy Function(MasterKeyModel) getServiceSelectedAllergy; - - final List masterList; - final String buttonName; - final String hintSearchText; - - MasterKeyCheckboxSearchAllergiesWidget( - {Key key, - this.model, - this.addSelectedAllergy, - this.removeAllergy, - this.masterList, - this.addAllergy, - this.isServiceSelected, - this.buttonName, - this.hintSearchText, - this.getServiceSelectedAllergy}) - : super(key: key); - - @override - _MasterKeyCheckboxSearchAllergiesWidgetState createState() => - _MasterKeyCheckboxSearchAllergiesWidgetState(); -} - -class _MasterKeyCheckboxSearchAllergiesWidgetState - extends State { - List items = List(); - MasterKeyModel _selectedAllergySeverity; - bool isSubmitted = false; - - @override - void initState() { - items.addAll(widget.masterList); - super.initState(); - } - - @override - Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); - return Container( - child: Column( - children: [ - Expanded( - child: Container( - height: MediaQuery.of(context).size.height * 0.70, - child: Center( - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Column( - children: [ - AppTextFieldCustom( - // height: - // MediaQuery.of(context).size.height * 0.070, - hintText: - TranslationBase.of(context).selectAllergy, - isTextFieldHasSuffix: true, - hasBorder: false, - // controller: filteredSearchController, - onChanged: (value) { - filterSearchResults(value); - }, - suffixIcon: IconButton( - icon: Icon( - Icons.search, - color: Colors.black, - )), - ), - DividerWithSpacesAround(), - SizedBox( - height: 10, - ), - Expanded( - child: FractionallySizedBox( - widthFactor: 0.9, - child: Container( - height: - MediaQuery.of(context).size.height * 0.60, - child: ListView.builder( - itemCount: items.length, - itemBuilder: (context, index) { - bool isSelected = widget - .isServiceSelected(items[index]); - MySelectedAllergy mySelectedAllergy; - if (isSelected) { - mySelectedAllergy = - widget.getServiceSelectedAllergy( - items[index]); - } - TextEditingController remarkController = - TextEditingController( - text: isSelected - ? mySelectedAllergy.remark - : null); - TextEditingController severityController = - TextEditingController( - text: isSelected - ? mySelectedAllergy - .selectedAllergySeverity != - null - ? projectViewModel - .isArabic - ? mySelectedAllergy - .selectedAllergySeverity - .nameAr - : mySelectedAllergy - .selectedAllergySeverity - .nameEn - : null - : null); - return HeaderBodyExpandableNotifier( - headerWidget: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - Checkbox( - value: widget - .isServiceSelected( - items[index]), - activeColor: - Colors.red[800], - onChanged: (bool newValue) { - setState(() { - if (widget - .isServiceSelected( - items[index])) { - widget.removeAllergy( - items[index]); - } else { - MySelectedAllergy - mySelectedAllergy = - new MySelectedAllergy( - selectedAllergy: - items[ - index], - selectedAllergySeverity: - _selectedAllergySeverity, - remark: null, - isChecked: - true, - isExpanded: - true); - widget.addAllergy( - mySelectedAllergy); - } - }); - }), - InkWell( - onTap: () { - setState(() { - if (widget - .isServiceSelected( - items[index])) { - widget.removeAllergy( - items[index]); - } else { - - MySelectedAllergy mySelectedAllergy = - new MySelectedAllergy( - selectedAllergy: - items[ - index], - selectedAllergySeverity: - _selectedAllergySeverity, - remark: null, - isChecked: true, - isExpanded: - true); - widget.addAllergy( - mySelectedAllergy); - } - }); - }, - child: Padding( - padding: const EdgeInsets - .symmetric( - horizontal: 10, - vertical: 0), - child: Container( - child: AppText( - projectViewModel - .isArabic - ? items[index] - .nameAr != - "" - ? items[index] - .nameAr - : items[index] - .nameEn - : items[index] - .nameEn, - color: - Color(0xFF575757), - fontSize: 16, - fontWeight: - FontWeight.w600, - ), - width: - MediaQuery.of(context) - .size - .width * - 0.55, - ), - ), - ), - ], - ), - InkWell( - onTap: () { - if (mySelectedAllergy != - null) { - setState(() { - mySelectedAllergy - .isExpanded = - mySelectedAllergy - .isExpanded - ? false - : true; - }); - } - }, - child: Icon((mySelectedAllergy != - null - ? mySelectedAllergy - .isExpanded - : false) - ? EvaIcons - .arrowIosUpwardOutline - : EvaIcons - .arrowIosDownwardOutline)) - ], - ), - bodyWidget: Center( - child: FractionallySizedBox( - widthFactor: 0.9, - child: Center( - child: Column( - children: [ - AppTextFieldCustom( - onClick: widget.model - .allergySeverityList != - null - ? () { - MasterKeyDailog - dialog = - MasterKeyDailog( - list: widget.model - .allergySeverityList, - okText: - TranslationBase.of( - context) - .ok, - okFunction: - (selectedValue) { - setState(() { - mySelectedAllergy - .selectedAllergySeverity = - selectedValue; - }); - }, - ); - showDialog( - barrierDismissible: - false, - context: context, - builder: - (BuildContext - context) { - return dialog; - }, - ); - } - : null, - isTextFieldHasSuffix: true, - hintText: - TranslationBase.of( - context) - .selectSeverity, - enabled: false, - maxLines: 2, - minLines: 2, - controller: - severityController, - ), - SizedBox( - height: 5, - ), - if (isSubmitted && - mySelectedAllergy != - null && - mySelectedAllergy - .selectedAllergySeverity == - null) - Row( - children: [ - CustomValidationError(), - ], - mainAxisAlignment: - MainAxisAlignment - .start, - ), - SizedBox( - height: 10, - ), - Container( - margin: EdgeInsets.only( - left: 0, - right: 0, - top: 15), - child: NewTextFields( - hintText: - TranslationBase.of( - context) - .remarks, - fontSize: 13.5, - // hintColor: Colors.black, - fontWeight: - FontWeight.w600, - maxLines: 25, - minLines: 3, - initialValue: isSelected - ? mySelectedAllergy - .remark - : '', - // controller: remarkControlle - - onChanged: (value) { - if (isSelected) { - mySelectedAllergy - .remark = value; - } - }, - validator: (value) { - if (value == null) - return TranslationBase - .of(context) - .emptyMessage; - else - return null; - }), - ), - SizedBox( - height: 10, - ), - ], - ), - ), - ), - ), - isExpand: mySelectedAllergy != null - ? mySelectedAllergy.isExpanded - : false, - ); - }, - ), - ), - ), - ), - ], - ))), - ), - ), - SizedBox( - height: 10, - ), - ], - ), - ); - } - - void filterSearchResults(String query) { - List dummySearchList = List(); - dummySearchList.addAll(widget.masterList); - if (query.isNotEmpty) { - List dummyListData = List(); - dummySearchList.forEach((items) { - if (items.nameAr.toLowerCase().contains(query.toLowerCase()) || - items.nameEn.toLowerCase().contains(query.toLowerCase())) { - dummyListData.add(items); - } - }); - setState(() { - items.clear(); - items.addAll(dummyListData); - }); - return; - } else { - setState(() { - items.clear(); - items.addAll(widget.masterList); - }); - } - } -} diff --git a/lib/widgets/shared/user-guid/custom_validation_error.dart b/lib/widgets/shared/user-guid/custom_validation_error.dart index a05d52a2..fd1f2125 100644 --- a/lib/widgets/shared/user-guid/custom_validation_error.dart +++ b/lib/widgets/shared/user-guid/custom_validation_error.dart @@ -13,9 +13,9 @@ class CustomValidationError extends StatelessWidget { @override Widget build(BuildContext context) { if(error == null ) - error = TranslationBase - .of(context) - .emptyMessage; + error = TranslationBase + .of(context) + .emptyMessage; return Column( children: [ SizedBox( From f52917f2191c4260e1bd1bd82cd3fe9dc63b94da Mon Sep 17 00:00:00 2001 From: Elham Rababh Date: Sun, 11 Jul 2021 17:10:32 +0300 Subject: [PATCH 053/289] fix get allergies issues --- .../profile/soap_update/subjective/allergies/allergies_item.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/screens/patients/profile/soap_update/subjective/allergies/allergies_item.dart b/lib/screens/patients/profile/soap_update/subjective/allergies/allergies_item.dart index 8a402a7b..b9eef0f5 100644 --- a/lib/screens/patients/profile/soap_update/subjective/allergies/allergies_item.dart +++ b/lib/screens/patients/profile/soap_update/subjective/allergies/allergies_item.dart @@ -13,7 +13,6 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class AddAllergiesItem extends StatefulWidget { - // TODO Elham* see what fun we can move here without effects final SOAPViewModel model; final Function(MasterKeyModel) removeAllergy; final Function(MySelectedAllergy mySelectedAllergy) addAllergy; From 469169023a42e419d52f61187cbd4e89849c2169 Mon Sep 17 00:00:00 2001 From: Elham Rababh Date: Mon, 12 Jul 2021 09:33:51 +0300 Subject: [PATCH 054/289] fix get allergies issues --- .../profile/soap_update/subjective/update_subjective_page.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart b/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart index ade555ba..89859a35 100644 --- a/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart +++ b/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart @@ -405,6 +405,9 @@ class _UpdateSubjectivePageState extends State { await model.patchAllergy(postAllergyRequestModel); } + if (model.state == ViewState.ErrorLocal) { + Helpers.showErrorToast(model.error); + } GeneralGetReqForSOAP generalGetReqForSOAP = GeneralGetReqForSOAP( patientMRN: widget.patientInfo.patientMRN, episodeId: widget.patientInfo.episodeNo, From 8a4dcf23343558454716f5c3e8d8789310a764fa Mon Sep 17 00:00:00 2001 From: mosazaid Date: Mon, 12 Jul 2021 16:13:52 +0300 Subject: [PATCH 055/289] try fixing error that was originally registered here. Are you missing a call to unregisterReceiver()? --- android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt | 2 +- .../com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt index a2c0f742..3c879350 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -269,7 +269,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, private fun unbindService() { if (bound) { - videoStreamService!!.videoCallResponseListener = null // unregister + videoStreamService?.videoCallResponseListener = null // unregister // videoStreamService!!.mActivity = null unbindService(serviceConnection) bound = false diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt index 3c4a5dc1..cdd9ebc0 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt @@ -833,6 +833,7 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, } if (mSubscriber != null) { + mSubscriber!!.subscribeToAudio = false // mosa added for error that was originally registered here. Are you missing a call to unregisterReceiver()? mSubscriberViewContainer.removeView(mSubscriber!!.view) mSession!!.unsubscribe(mSubscriber) mSubscriber!!.destroy() From c3ed212e6a178759a2a2010247df8addc817d284 Mon Sep 17 00:00:00 2001 From: Elham Rababh Date: Mon, 12 Jul 2021 17:09:04 +0300 Subject: [PATCH 056/289] remove base View --- .../profile/soap_update/update_soap_index.dart | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/screens/patients/profile/soap_update/update_soap_index.dart b/lib/screens/patients/profile/soap_update/update_soap_index.dart index 883e19f0..e9d6d16d 100644 --- a/lib/screens/patients/profile/soap_update/update_soap_index.dart +++ b/lib/screens/patients/profile/soap_update/update_soap_index.dart @@ -61,12 +61,11 @@ class _UpdateSoapIndexState extends State Widget build(BuildContext context) { final routeArgs = ModalRoute.of(context).settings.arguments as Map; PatiantInformtion patient = routeArgs['patient']; - return BaseView( - builder: (_, model, w) => AppScaffold( - isLoading: _isLoading, - isShowAppBar: false, - body: SingleChildScrollView( - child: SingleChildScrollView( + return AppScaffold( + isLoading: _isLoading, + isShowAppBar: false, + body: SingleChildScrollView( + child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -128,6 +127,6 @@ class _UpdateSoapIndexState extends State ), ), ), - )); + ); } } From 5a61a3eabae57a798e189bc2573e9deceb1322b8 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Tue, 13 Jul 2021 09:19:47 +0300 Subject: [PATCH 057/289] Add missing page tob google analytics --- android/app/build.gradle | 2 +- android/app/google-services.json | 14 +++++++------- android/build.gradle | 2 +- android/google-services.json | 2 +- lib/screens/doctor/doctor_reply_screen.dart | 2 +- lib/screens/home/home_screen.dart | 6 +++++- lib/screens/live_care/end_call_screen.dart | 3 ++- lib/screens/medical-file/health_summary_page.dart | 3 ++- lib/screens/medicine/medicine_search_screen.dart | 2 +- .../insurance_approval_screen_patient.dart | 4 ++-- .../patients/out_patient/out_patient_screen.dart | 2 +- .../patient_search/patient_search_screen.dart | 1 + .../profile/lab_result/labs_home_page.dart | 1 + .../profile/medical_report/MedicalReportPage.dart | 7 +++++-- .../profile/note/progress_note_screen.dart | 4 ++-- .../profile_screen/patient_profile_screen.dart | 2 +- .../profile/radiology/radiology_home_page.dart | 2 +- lib/screens/prescription/prescriptions_page.dart | 2 +- .../procedures/add-favourite-procedure.dart | 4 ++-- lib/screens/procedures/procedure_screen.dart | 2 +- .../reschedule-leaves/reschedule_leave.dart | 3 ++- .../profile/prescription_out_patinets_widget.dart | 1 + lib/widgets/shared/app_drawer_widget.dart | 1 + lib/widgets/transitions/fade_page.dart | 1 + lib/widgets/transitions/slide_up_page.dart | 1 + 25 files changed, 45 insertions(+), 29 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 2e124398..e19addc9 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -108,6 +108,6 @@ dependencies { implementation 'com.squareup.okhttp3:okhttp:4.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.6.2' implementation 'com.squareup.okhttp3:logging-interceptor:4.9.1' - + implementation 'com.google.firebase:firebase-analytics:17.4.1' } apply plugin: 'com.google.gms.google-services' \ No newline at end of file diff --git a/android/app/google-services.json b/android/app/google-services.json index db548786..3afb6dca 100644 --- a/android/app/google-services.json +++ b/android/app/google-services.json @@ -1,33 +1,33 @@ { "project_info": { - "project_number": "157373154094", - "project_id": "hmg-doctor-app-1553688619744", - "storage_bucket": "hmg-doctor-app-1553688619744.appspot.com" + "project_number": "1095694324958", + "project_id": "mobapp-bb272", + "storage_bucket": "mobapp-bb272.appspot.com" }, "client": [ { "client_info": { - "mobilesdk_app_id": "1:157373154094:android:daeea3a4e1f4462a1bf0bf", + "mobilesdk_app_id": "1:1095694324958:android:70a42e30fcc98ea33fde4f", "android_client_info": { "package_name": "com.hmg.hmgDr" } }, "oauth_client": [ { - "client_id": "157373154094-egrhbfr861l7k722g3v2gd4a0opi3r1u.apps.googleusercontent.com", + "client_id": "1095694324958-5psabq8tpbti0uqo8bt46atjtbas9uhr.apps.googleusercontent.com", "client_type": 3 } ], "api_key": [ { - "current_key": "AIzaSyDX8RPwu00MyrpqC-T2zXtrUQvTQGRv1mM" + "current_key": "AIzaSyCuPtf1hTikWXrp5OQIVfqO-TJWubI-Vd8" } ], "services": { "appinvite_service": { "other_platform_oauth_client": [ { - "client_id": "157373154094-egrhbfr861l7k722g3v2gd4a0opi3r1u.apps.googleusercontent.com", + "client_id": "1095694324958-5psabq8tpbti0uqo8bt46atjtbas9uhr.apps.googleusercontent.com", "client_type": 3 } ] diff --git a/android/build.gradle b/android/build.gradle index badc1b18..bf0f679d 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -8,7 +8,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:3.5.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'com.google.gms:google-services:4.3.2' + classpath 'com.google.gms:google-services:4.3.3' } } diff --git a/android/google-services.json b/android/google-services.json index 34a225b2..3afb6dca 100644 --- a/android/google-services.json +++ b/android/google-services.json @@ -36,4 +36,4 @@ } ], "configuration_version": "1" -} +} \ No newline at end of file diff --git a/lib/screens/doctor/doctor_reply_screen.dart b/lib/screens/doctor/doctor_reply_screen.dart index f522561f..b318f6a4 100644 --- a/lib/screens/doctor/doctor_reply_screen.dart +++ b/lib/screens/doctor/doctor_reply_screen.dart @@ -56,7 +56,7 @@ class DoctorReplyScreen extends StatelessWidget { DoctorReplayChat( reply: reply, previousModel: model, - ))); + ), settings: RouteSettings(name: 'DoctorReplayChat'),)); }, child: DoctorReplyWidget(reply: reply), ); diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 568ad60f..3efd0243 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -405,7 +405,8 @@ class _HomeScreenState extends State { from: date, to: date, doctorID: - authenticationViewModel.doctorProfile.doctorID)), + authenticationViewModel.doctorProfile.doctorID),), + settings: RouteSettings(name: 'OutPatientsScreen'), )); }, )); @@ -422,6 +423,7 @@ class _HomeScreenState extends State { context, MaterialPageRoute( builder: (context) => PatientReferralScreen(), + settings: RouteSettings(name: 'PatientReferralScreen'), ), ); }, @@ -439,6 +441,7 @@ class _HomeScreenState extends State { context, MaterialPageRoute( builder: (context) => PatientSearchScreen(), + settings: RouteSettings(name: 'PatientSearchScreen'), )); }, )); @@ -455,6 +458,7 @@ class _HomeScreenState extends State { context, MaterialPageRoute( builder: (context) => MedicineSearchScreen(), + settings: RouteSettings(name: 'MedicineSearchScreen'), )); }, )); diff --git a/lib/screens/live_care/end_call_screen.dart b/lib/screens/live_care/end_call_screen.dart index 0e65182b..62b97f2d 100644 --- a/lib/screens/live_care/end_call_screen.dart +++ b/lib/screens/live_care/end_call_screen.dart @@ -184,7 +184,8 @@ class _EndCallScreenState extends State { context, MaterialPageRoute( builder: (BuildContext context) => - LivaCareTransferToAdmin(patient: patient))); + LivaCareTransferToAdmin(patient: patient), + settings: RouteSettings(name: 'LivaCareTransferToAdmin'),),); }, isInPatient: isInpatient, isDartIcon: true, diff --git a/lib/screens/medical-file/health_summary_page.dart b/lib/screens/medical-file/health_summary_page.dart index 6b4b066c..45b95de0 100644 --- a/lib/screens/medical-file/health_summary_page.dart +++ b/lib/screens/medical-file/health_summary_page.dart @@ -149,7 +149,8 @@ class _HealthSummaryPageState extends State { episode: model.medicalFileList[0].entityList[0].timelines[index].timeLineEvents[0].consulations.isNotEmpty ? model.medicalFileList[0].entityList[0].timelines[index].timeLineEvents[0].consulations[0].episodeID.toString() : "", - vistDate: model.medicalFileList[0].entityList[0].timelines[index].date.toString())), + vistDate: model.medicalFileList[0].entityList[0].timelines[index].date.toString()), + settings: RouteSettings(name: 'MedicalFileDetails'),), ); }, child: DoctorCard( diff --git a/lib/screens/medicine/medicine_search_screen.dart b/lib/screens/medicine/medicine_search_screen.dart index eeea51c5..c0289605 100644 --- a/lib/screens/medicine/medicine_search_screen.dart +++ b/lib/screens/medicine/medicine_search_screen.dart @@ -226,7 +226,7 @@ class _MedicineSearchState extends State { ["ItemID"], url: model.pharmacyItemsList[index] ["ImageSRCUrl"]), - ), + settings: RouteSettings(name: 'PharmaciesListScreen'),), ); }, ); diff --git a/lib/screens/patients/insurance_approval_screen_patient.dart b/lib/screens/patients/insurance_approval_screen_patient.dart index b9d3f57e..0cc5d5c3 100644 --- a/lib/screens/patients/insurance_approval_screen_patient.dart +++ b/lib/screens/patients/insurance_approval_screen_patient.dart @@ -96,7 +96,7 @@ class _InsuranceApprovalScreenNewState extends State patient: patient, indexInsurance: index, patientType: patientType, - )), + ),settings: RouteSettings(name: 'InsuranceApprovalsDetails'),), ); }, child: DoctorCardInsurance( @@ -183,7 +183,7 @@ class _InsuranceApprovalScreenNewState extends State patient: patient, indexInsurance: index, patientType: patientType, - )), + ),settings: RouteSettings(name: 'InsuranceApprovalsDetails'),), ); }, child: DoctorCardInsurance( diff --git a/lib/screens/patients/out_patient/out_patient_screen.dart b/lib/screens/patients/out_patient/out_patient_screen.dart index 0037634d..fa96a191 100644 --- a/lib/screens/patients/out_patient/out_patient_screen.dart +++ b/lib/screens/patients/out_patient/out_patient_screen.dart @@ -223,7 +223,7 @@ class _OutPatientsScreenState extends State { builder: (BuildContext context) => FilterDatePage( outPatientFilterType: outPatientFilterType, patientSearchViewModel: model, - ))); + ),settings: RouteSettings(name: 'FilterOutPatentDateScreen'),)); }, ), onChanged: (String str) { diff --git a/lib/screens/patients/patient_search/patient_search_screen.dart b/lib/screens/patients/patient_search/patient_search_screen.dart index 2275cc09..2479910f 100644 --- a/lib/screens/patients/patient_search/patient_search_screen.dart +++ b/lib/screens/patients/patient_search/patient_search_screen.dart @@ -208,6 +208,7 @@ class _PatientSearchScreenState extends State { searchKey: patientFileInfoController.text, isInpatient: false, ), + settings: RouteSettings(name: 'PatientsSearchResultScreen'), ), ); } diff --git a/lib/screens/patients/profile/lab_result/labs_home_page.dart b/lib/screens/patients/profile/lab_result/labs_home_page.dart index 7da55967..dfc1a1e8 100644 --- a/lib/screens/patients/profile/lab_result/labs_home_page.dart +++ b/lib/screens/patients/profile/lab_result/labs_home_page.dart @@ -121,6 +121,7 @@ class _LabsHomePageState extends State { model: model, procedureType: ProcedureType.LAB_RESULT, ), + settings: RouteSettings(name: 'AddProcedureTabPage'), ), ); }, diff --git a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart index a5c367de..4ebfdbf6 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart @@ -89,7 +89,9 @@ class _MedicalReportPageState extends State { arrivalType: arrivalType, model: model, status: MedicalReportStatus.ADD, - )), + ), + settings: RouteSettings(name: 'AddVerifyMedicalReport'), + ), ); }, @@ -111,7 +113,8 @@ class _MedicalReportPageState extends State { medicalReport: model.medicalReportList[index], model: model, medicalNote: model.medicalReportList[index].reportDataHtml, - )), + ), + settings: RouteSettings(name: 'AddVerifyMedicalReport')), ); } else { Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_DETAIL, arguments: { diff --git a/lib/screens/patients/profile/note/progress_note_screen.dart b/lib/screens/patients/profile/note/progress_note_screen.dart index 723ee75f..6b6e7c24 100644 --- a/lib/screens/patients/profile/note/progress_note_screen.dart +++ b/lib/screens/patients/profile/note/progress_note_screen.dart @@ -114,7 +114,7 @@ class _ProgressNoteState extends State { patient: patient, visitType: widget.visitType, isUpdate: false, - )), + ),settings: RouteSettings(name: 'UpdateNoteOrder'),), ); }, label: widget.visitType == 3 @@ -236,7 +236,7 @@ class _ProgressNoteState extends State { visitType: widget .visitType, isUpdate: true, - )), + ),settings: RouteSettings(name: 'UpdateNoteOrder'),), ); }, child: Container( diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index 1cbc67d8..412cf986 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -323,7 +323,7 @@ class _PatientProfileScreenState extends State with Single Navigator.push( context, MaterialPageRoute( - builder: (BuildContext context) => EndCallScreen(patient: patient))); + builder: (BuildContext context) => EndCallScreen(patient: patient),settings: RouteSettings(name: 'EndCallScreen'),),); } else { GifLoaderDialogUtils.showMyDialog(context); await model.startCall(isReCall: false, vCID: patient.vcId); diff --git a/lib/screens/patients/profile/radiology/radiology_home_page.dart b/lib/screens/patients/profile/radiology/radiology_home_page.dart index 3d8d527c..46b5ad28 100644 --- a/lib/screens/patients/profile/radiology/radiology_home_page.dart +++ b/lib/screens/patients/profile/radiology/radiology_home_page.dart @@ -117,7 +117,7 @@ class _RadiologyHomePageState extends State { patient: patient, model: model, procedureType: ProcedureType.RADIOLOGY, - ), + ), settings: RouteSettings(name: 'AddProcedureTabPage') ), ); }, diff --git a/lib/screens/prescription/prescriptions_page.dart b/lib/screens/prescription/prescriptions_page.dart index 1a99299b..4c9d986e 100644 --- a/lib/screens/prescription/prescriptions_page.dart +++ b/lib/screens/prescription/prescriptions_page.dart @@ -104,7 +104,7 @@ class PrescriptionsPage extends StatelessWidget { prescriptionModel: model, procedureType: ProcedureType.PRESCRIPTION, - )), + ),settings: RouteSettings(name: 'AddProcedureTabPage')), ); }, label: TranslationBase.of(context) diff --git a/lib/screens/procedures/add-favourite-procedure.dart b/lib/screens/procedures/add-favourite-procedure.dart index 978fc2c5..236ec5e2 100644 --- a/lib/screens/procedures/add-favourite-procedure.dart +++ b/lib/screens/procedures/add-favourite-procedure.dart @@ -108,7 +108,7 @@ class _AddFavouriteProcedureState extends State { patient: widget.patient, model: widget.prescriptionModel, groupProcedures: groupProcedures, - ), + ), settings: RouteSettings(name: 'PrescriptionCheckOutScreen') ), ); } else { @@ -128,7 +128,7 @@ class _AddFavouriteProcedureState extends State { patient: widget.patient, addButtonTitle: widget.procedureType.getAddButtonTitle(context), toolbarTitle: widget.procedureType.getToolbarLabel(context), - ), + ), settings: RouteSettings(name: 'ProcedureCheckOutScreen') ), ); } diff --git a/lib/screens/procedures/procedure_screen.dart b/lib/screens/procedures/procedure_screen.dart index 79371459..3ca6d25d 100644 --- a/lib/screens/procedures/procedure_screen.dart +++ b/lib/screens/procedures/procedure_screen.dart @@ -110,7 +110,7 @@ class ProcedureScreen extends StatelessWidget { patient: patient, model: model, procedureType: ProcedureType.PROCEDURE, - ), + ), settings: RouteSettings(name: 'AddProcedureTabPage') ), ); }, diff --git a/lib/screens/reschedule-leaves/reschedule_leave.dart b/lib/screens/reschedule-leaves/reschedule_leave.dart index dc3d0adf..98e9f9ec 100644 --- a/lib/screens/reschedule-leaves/reschedule_leave.dart +++ b/lib/screens/reschedule-leaves/reschedule_leave.dart @@ -982,6 +982,7 @@ class _RescheduleLeaveScreen extends State { context, MaterialPageRoute( builder: (context) => AddRescheduleLeavScreen(), + settings: RouteSettings(name: 'AddRescheduleLeaveScreen') // MyReferredPatient(), ), ); @@ -1045,7 +1046,7 @@ class _RescheduleLeaveScreen extends State { context, MaterialPageRoute( builder: (context) => AddRescheduleLeavScreen(), - // MyReferredPatient(), + settings: RouteSettings(name: 'AddRescheduleLeaveScreen') ), ); } diff --git a/lib/widgets/patients/profile/prescription_out_patinets_widget.dart b/lib/widgets/patients/profile/prescription_out_patinets_widget.dart index bd40c3ca..50afbdcf 100644 --- a/lib/widgets/patients/profile/prescription_out_patinets_widget.dart +++ b/lib/widgets/patients/profile/prescription_out_patinets_widget.dart @@ -71,6 +71,7 @@ class PrescriptionOutPatientWidget extends StatelessWidget { prescriptionResModel: patientPrescriptionsList[index], ), + settings: RouteSettings(name: 'OutPatientPrescriptionDetailsScreen') ), ); }, diff --git a/lib/widgets/shared/app_drawer_widget.dart b/lib/widgets/shared/app_drawer_widget.dart index b13a4f10..49f7d4e8 100644 --- a/lib/widgets/shared/app_drawer_widget.dart +++ b/lib/widgets/shared/app_drawer_widget.dart @@ -118,6 +118,7 @@ class _AppDrawerState extends State { context, MaterialPageRoute( builder: (context) => AddRescheduleLeavScreen(), + settings: RouteSettings(name: 'AddRescheduleLeaveScreen') // MyReferredPatient(), )); }, diff --git a/lib/widgets/transitions/fade_page.dart b/lib/widgets/transitions/fade_page.dart index 97a37ce1..7cd3826c 100644 --- a/lib/widgets/transitions/fade_page.dart +++ b/lib/widgets/transitions/fade_page.dart @@ -7,6 +7,7 @@ class FadePage extends PageRouteBuilder { FadePage({this.page}) : super( opaque: false, + settings: RouteSettings(name: page.runtimeType.toString()), fullscreenDialog: true, barrierDismissible: true, barrierColor: Colors.black.withOpacity(0.8), diff --git a/lib/widgets/transitions/slide_up_page.dart b/lib/widgets/transitions/slide_up_page.dart index 2c138b9e..f534e2a3 100644 --- a/lib/widgets/transitions/slide_up_page.dart +++ b/lib/widgets/transitions/slide_up_page.dart @@ -24,6 +24,7 @@ class SlideUpPageRoute extends PageRouteBuilder { opaque: opaque, barrierColor: Color.fromRGBO(0, 0, 0, 0.5), barrierDismissible: true, + settings: RouteSettings(name: widget.runtimeType.toString()), transitionDuration: Duration(milliseconds: 800), transitionsBuilder: ((BuildContext context, Animation animation, From eabe16a1d37442c395fc94a226833135a4f11594 Mon Sep 17 00:00:00 2001 From: Elham Rababh Date: Tue, 13 Jul 2021 09:21:53 +0300 Subject: [PATCH 058/289] change text field --- lib/widgets/shared/text_fields/app-textfield-custom.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/widgets/shared/text_fields/app-textfield-custom.dart b/lib/widgets/shared/text_fields/app-textfield-custom.dart index fc7df189..009446ff 100644 --- a/lib/widgets/shared/text_fields/app-textfield-custom.dart +++ b/lib/widgets/shared/text_fields/app-textfield-custom.dart @@ -104,7 +104,7 @@ class _AppTextFieldCustomState extends State { widget.height != 0 && widget.maxLines == 1 ? widget.height - 22 : null, - child: TextField( + child: TextFormField( textAlign: projectViewModel.isArabic ? TextAlign.right : TextAlign.left, @@ -129,7 +129,7 @@ class _AppTextFieldCustomState extends State { ? widget.inputFormatters : [], onChanged: (value) { - setState(() {}); + // setState(() {}); if (widget.onChanged != null) { widget.onChanged(value); } From 3b6fcb424084655e0d44f66ce250ad39c12889fa Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Tue, 13 Jul 2021 10:54:12 +0300 Subject: [PATCH 059/289] fix app text field custom --- .../subjective/update_subjective_page.dart | 1 + .../text_fields/app-textfield-custom.dart | 36 +++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart b/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart index 89859a35..47b7e6df 100644 --- a/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart +++ b/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart @@ -324,6 +324,7 @@ class _UpdateSubjectivePageState extends State { addSubjectiveInfo( {SOAPViewModel model, List myAllergiesList, List myHistoryList}) async { + FocusScope.of(context).unfocus(); widget.changeLoadingState(true); formKey.currentState.save(); formKey.currentState.validate(); diff --git a/lib/widgets/shared/text_fields/app-textfield-custom.dart b/lib/widgets/shared/text_fields/app-textfield-custom.dart index fc7df189..05f139a2 100644 --- a/lib/widgets/shared/text_fields/app-textfield-custom.dart +++ b/lib/widgets/shared/text_fields/app-textfield-custom.dart @@ -27,6 +27,7 @@ class AppTextFieldCustom extends StatefulWidget { final String validationError; final bool isPrscription; final bool isSecure; + final bool focus; AppTextFieldCustom({ this.height = 0, @@ -47,6 +48,7 @@ class AppTextFieldCustom extends StatefulWidget { this.validationError, this.isPrscription = false, this.isSecure = false, + this.focus = false, }); @override @@ -54,6 +56,32 @@ class AppTextFieldCustom extends StatefulWidget { } class _AppTextFieldCustomState extends State { + final FocusNode _focusNode = FocusNode(); + bool focus = false; + bool view = false; + + @override + void initState() { + super.initState(); + _focusNode.addListener(() { + setState(() { + focus = _focusNode.hasFocus; + }); + }); + } + + @override + void didUpdateWidget(AppTextFieldCustom oldWidget) { + if (widget.focus) _focusNode.requestFocus(); + super.didUpdateWidget(oldWidget); + } + + @override + void dispose() { + _focusNode.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); @@ -104,10 +132,11 @@ class _AppTextFieldCustomState extends State { widget.height != 0 && widget.maxLines == 1 ? widget.height - 22 : null, - child: TextField( + child: TextFormField( textAlign: projectViewModel.isArabic ? TextAlign.right : TextAlign.left, + focusNode: _focusNode, decoration: TextFieldsUtils .textFieldSelectorDecoration( widget.hintText, null, true), @@ -129,7 +158,7 @@ class _AppTextFieldCustomState extends State { ? widget.inputFormatters : [], onChanged: (value) { - setState(() {}); + // setState(() {}); if (widget.onChanged != null) { widget.onChanged(value); } @@ -162,9 +191,10 @@ class _AppTextFieldCustomState extends State { ), ), ), - if (widget.validationError != null) + if (widget.validationError != null && widget.validationError.isNotEmpty) TextFieldsError(error: widget.validationError), ], ); } + } From 87c906ae2bf5cab5af0c107df9a156087e6956ee Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Tue, 13 Jul 2021 10:57:11 +0300 Subject: [PATCH 060/289] Add check if has focus --- .../profile/soap_update/subjective/update_subjective_page.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart b/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart index 47b7e6df..7a48a786 100644 --- a/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart +++ b/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart @@ -324,6 +324,7 @@ class _UpdateSubjectivePageState extends State { addSubjectiveInfo( {SOAPViewModel model, List myAllergiesList, List myHistoryList}) async { + if(FocusScope.of(context).hasFocus) FocusScope.of(context).unfocus(); widget.changeLoadingState(true); formKey.currentState.save(); From b015cb06f7262bbcc4a6876e07995673db77d9fa Mon Sep 17 00:00:00 2001 From: Elham Rababh Date: Tue, 13 Jul 2021 11:16:08 +0300 Subject: [PATCH 061/289] add fixes on episode --- .../assessment/add_assessment_details.dart | 2 +- .../soap_update/plan/update_plan_page.dart | 104 ++++++++++++------ .../subjective/allergies/allergies_item.dart | 3 + .../subjective/medication/add_medication.dart | 4 + 4 files changed, 81 insertions(+), 32 deletions(-) diff --git a/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart b/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart index 6f51fa40..e14eb6f2 100644 --- a/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart +++ b/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart @@ -372,7 +372,7 @@ class _AddAssessmentDetailsState extends State { ), ), ), - bottomSheet: Container( + bottomSheet: model.state == ViewState.Busy?Container(height: 0,):Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.all( diff --git a/lib/screens/patients/profile/soap_update/plan/update_plan_page.dart b/lib/screens/patients/profile/soap_update/plan/update_plan_page.dart index 47165896..4622bc94 100644 --- a/lib/screens/patients/profile/soap_update/plan/update_plan_page.dart +++ b/lib/screens/patients/profile/soap_update/plan/update_plan_page.dart @@ -71,6 +71,38 @@ class _UpdatePlanPageState extends State { } } + + getPatientProgressNote(model, {bool isAddProgress = false}) async { + GetGetProgressNoteReqModel getGetProgressNoteReqModel = + GetGetProgressNoteReqModel( + appointmentNo: + int.parse(widget.patientInfo.appointmentNo.toString()), + patientMRN: widget.patientInfo.patientMRN, + episodeID: widget.patientInfo.episodeNo.toString(), + editedBy: '', + doctorID: ''); + await model.getPatientProgressNote(getGetProgressNoteReqModel); + + if (model.patientProgressNoteList.isNotEmpty) { + progressNoteController.text = Helpers.parseHtmlString( + model.patientProgressNoteList[0].planNote); + patientProgressNote.planNote = progressNoteController.text; + patientProgressNote.createdByName = + model.patientProgressNoteList[0].createdByName; + patientProgressNote.createdOn = + model.patientProgressNoteList[0].createdOn; + patientProgressNote.editedOn = + model.patientProgressNoteList[0].editedOn; + patientProgressNote.editedByName = + model.patientProgressNoteList[0].editedByName; + patientProgressNote.appointmentNo = + model.patientProgressNoteList[0].appointmentNo; + setState(() { + isAddProgress = isAddProgress; + }); + } + } + @override Widget build(BuildContext context) { return BaseView( @@ -210,22 +242,22 @@ class _UpdatePlanPageState extends State { ), Row( mainAxisAlignment: - MainAxisAlignment.spaceBetween, + MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - children: [ - AppText( - 'Condition: ', - fontSize: 12, - ), - AppText( - patientProgressNote.mName ?? - '', - fontWeight: FontWeight.w600), - ], - ), + // Row( + // children: [ + // AppText( + // 'Condition: ', + // fontSize: 12, + // ), + // AppText( + // patientProgressNote.mName ?? + // '', + // fontWeight: FontWeight.w600), + // ], + // ), AppText( patientProgressNote.createdOn != null @@ -326,21 +358,6 @@ class _UpdatePlanPageState extends State { onPressed: () async { if (progressNoteController.text.isNotEmpty) { if (isAddProgress) { - Map profile = - await sharedPref.getObj(DOCTOR_PROFILE); - DoctorProfileModel doctorProfile = - DoctorProfileModel.fromJson(profile); - setState(() { - patientProgressNote.createdByName = - patientProgressNote.createdByName ?? - doctorProfile.doctorName; - patientProgressNote.editedByName = - doctorProfile.doctorName; - patientProgressNote.createdOn = - DateTime.now().toString(); - patientProgressNote.planNote = - progressNoteController.text; - }); submitPlan(model); } else { Navigator.of(context).pop(); @@ -391,10 +408,35 @@ class _UpdatePlanPageState extends State { if (model.state == ViewState.ErrorLocal) { Helpers.showErrorToast(model.error); } else { - setState(() { - isAddProgress = !isAddProgress; - }); + GetGetProgressNoteReqModel getGetProgressNoteReqModel = + GetGetProgressNoteReqModel( + appointmentNo: + int.parse(widget.patientInfo.appointmentNo.toString()), + patientMRN: widget.patientInfo.patientMRN, + episodeID: widget.patientInfo.episodeNo.toString(), + editedBy: '', + doctorID: ''); + await model.getPatientProgressNote(getGetProgressNoteReqModel); + if (model.patientProgressNoteList.isNotEmpty) { + progressNoteController.text = Helpers.parseHtmlString( + model.patientProgressNoteList[0].planNote); + patientProgressNote.planNote = progressNoteController.text; + patientProgressNote.createdByName = + model.patientProgressNoteList[0].createdByName; + patientProgressNote.createdOn = + model.patientProgressNoteList[0].createdOn; + patientProgressNote.editedOn = + model.patientProgressNoteList[0].editedOn; + patientProgressNote.editedByName = + model.patientProgressNoteList[0].editedByName; + patientProgressNote.appointmentNo = + model.patientProgressNoteList[0].appointmentNo; + + setState(() { + isAddProgress = false; + }); + } } widget.changeLoadingState(false); } else { diff --git a/lib/screens/patients/profile/soap_update/subjective/allergies/allergies_item.dart b/lib/screens/patients/profile/soap_update/subjective/allergies/allergies_item.dart index b9eef0f5..55e36342 100644 --- a/lib/screens/patients/profile/soap_update/subjective/allergies/allergies_item.dart +++ b/lib/screens/patients/profile/soap_update/subjective/allergies/allergies_item.dart @@ -159,6 +159,9 @@ class _AddAllergiesItemState extends State { maxLines: 25, minLines: 3, hasBorder: true, + onChanged: (value){ + mySelectedAllergy.remark = value; + }, inputType: TextInputType.multiline, ), diff --git a/lib/screens/patients/profile/soap_update/subjective/medication/add_medication.dart b/lib/screens/patients/profile/soap_update/subjective/medication/add_medication.dart index d7f8f6ed..11e4fa72 100644 --- a/lib/screens/patients/profile/soap_update/subjective/medication/add_medication.dart +++ b/lib/screens/patients/profile/soap_update/subjective/medication/add_medication.dart @@ -188,6 +188,7 @@ class _AddMedicationState extends State { list: model.medicationDoseTimeList, okText: TranslationBase.of(context).ok, + selectedValue: _selectedMedicationDose, okFunction: (selectedValue) { setState(() { _selectedMedicationDose = @@ -236,6 +237,7 @@ class _AddMedicationState extends State { list: model.medicationStrengthList, okText: TranslationBase.of(context).ok, + selectedValue: _selectedMedicationStrength, okFunction: (selectedValue) { setState(() { _selectedMedicationStrength = @@ -284,6 +286,7 @@ class _AddMedicationState extends State { MasterKeyDailog dialog = MasterKeyDailog( list: model.medicationRouteList, + selectedValue: _selectedMedicationRoute, okText: TranslationBase.of(context).ok, okFunction: (selectedValue) { @@ -333,6 +336,7 @@ class _AddMedicationState extends State { list: model.medicationFrequencyList, okText: TranslationBase.of(context).ok, + selectedValue: _selectedMedicationFrequency, okFunction: (selectedValue) { setState(() { _selectedMedicationFrequency = From d0d68741598f2355873d3930d29713dd3ac24b90 Mon Sep 17 00:00:00 2001 From: Elham Rababh Date: Wed, 14 Jul 2021 11:02:51 +0300 Subject: [PATCH 062/289] create mapper for the selected items --- lib/config/localized_values.dart | 1 + lib/models/SOAP/my_selected_allergy.dart | 54 -- lib/models/SOAP/my_selected_assement.dart | 65 -- lib/models/SOAP/my_selected_examination.dart | 61 -- lib/models/SOAP/my_selected_history.dart | 33 - .../selected_items/my_selected_allergy.dart | 23 + .../selected_items/my_selected_assement.dart | 24 + .../my_selected_examination.dart | 27 + .../selected_items/my_selected_history.dart | 11 + .../assessment/add_assessment_details.dart | 2 +- .../assessment/update_assessment_page.dart | 755 +++++++++--------- .../objective/add_examination_page.dart | 2 +- .../objective/add_examination_widget.dart | 2 +- .../objective/examination_item_card.dart | 2 +- .../examinations_list_search_widget.dart | 2 +- .../objective/update_objective_page.dart | 8 +- .../profile/soap_update/soap_utils.dart | 88 ++ .../subjective/allergies/add_allergies.dart | 2 +- .../subjective/allergies/allergies_item.dart | 14 +- ..._key_checkbox_search_allergies_widget.dart | 2 +- .../allergies/update_allergies_widget.dart | 2 +- .../history/add_history_dialog.dart | 9 +- .../history/update_history_widget.dart | 2 +- .../medication/update_medication_widget.dart | 2 +- .../subjective/update_subjective_page.dart | 203 +++-- .../soap_update/update_soap_index.dart | 7 +- lib/util/translations_delegate_base.dart | 1 + 27 files changed, 713 insertions(+), 691 deletions(-) delete mode 100644 lib/models/SOAP/my_selected_allergy.dart delete mode 100644 lib/models/SOAP/my_selected_assement.dart delete mode 100644 lib/models/SOAP/my_selected_examination.dart delete mode 100644 lib/models/SOAP/my_selected_history.dart create mode 100644 lib/models/SOAP/selected_items/my_selected_allergy.dart create mode 100644 lib/models/SOAP/selected_items/my_selected_assement.dart create mode 100644 lib/models/SOAP/selected_items/my_selected_examination.dart create mode 100644 lib/models/SOAP/selected_items/my_selected_history.dart create mode 100644 lib/screens/patients/profile/soap_update/soap_utils.dart diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 0a094b9b..ebc43a87 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -704,4 +704,5 @@ const Map> localizedValues = { "edit": {"en": "Edit", "ar": "تعديل"}, "summeryReply": {"en": "Summary Reply", "ar": "موجز الرد"}, "finish": {"en": "Finish", "ar": "انهاء"}, + "severityValidationError": {"en": "Please add allergy severity", "ar": "الرجاء إضافة شدة الحساسية"}, }; diff --git a/lib/models/SOAP/my_selected_allergy.dart b/lib/models/SOAP/my_selected_allergy.dart deleted file mode 100644 index 90031230..00000000 --- a/lib/models/SOAP/my_selected_allergy.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; - -class MySelectedAllergy { - MasterKeyModel selectedAllergySeverity; - MasterKeyModel selectedAllergy; - String remark; - bool isChecked; - bool isExpanded; - bool isLocal; - int createdBy; - bool hasValidationError; - - MySelectedAllergy( - {this.selectedAllergySeverity, - this.selectedAllergy, - this.remark, - this.isChecked, - this.isExpanded = true, - this.isLocal = true, - this.createdBy, - this.hasValidationError = false}); - - MySelectedAllergy.fromJson(Map json) { - selectedAllergySeverity = json['selectedAllergySeverity'] != null - ? new MasterKeyModel.fromJson(json['selectedAllergySeverity']) - : null; - selectedAllergy = json['selectedAllergy'] != null - ? new MasterKeyModel.fromJson(json['selectedAllergy']) - : null; - remark = json['remark']; - isChecked = json['isChecked']; - isExpanded = json['isExpanded']; - isLocal = json['isLocal']; - createdBy = json['createdBy']; - hasValidationError = json['hasValidationError']; - } - - Map toJson() { - final Map data = new Map(); - if (this.selectedAllergySeverity != null) { - data['selectedAllergySeverity'] = this.selectedAllergySeverity.toJson(); - } - if (this.selectedAllergy != null) { - data['selectedAllergy'] = this.selectedAllergy.toJson(); - } - data['remark'] = this.remark; - data['isChecked'] = this.isChecked; - data['isExpanded'] = this.isExpanded; - data['createdBy'] = this.createdBy; - data['isLocal'] = this.isLocal; - data['hasValidationError'] = this.hasValidationError; - return data; - } -} diff --git a/lib/models/SOAP/my_selected_assement.dart b/lib/models/SOAP/my_selected_assement.dart deleted file mode 100644 index 4d4afc2d..00000000 --- a/lib/models/SOAP/my_selected_assement.dart +++ /dev/null @@ -1,65 +0,0 @@ -import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; - -class MySelectedAssessment { - MasterKeyModel selectedICD; - MasterKeyModel selectedDiagnosisCondition; - MasterKeyModel selectedDiagnosisType; - String remark; - int appointmentId; - int createdBy; - String createdOn; - int doctorID; - String doctorName; - String icdCode10ID; - - MySelectedAssessment( - {this.selectedICD, - this.selectedDiagnosisCondition, - this.selectedDiagnosisType, - this.remark, this.appointmentId, this.createdBy, - this.createdOn, - this.doctorID, - this.doctorName, - this.icdCode10ID}); - - MySelectedAssessment.fromJson(Map json) { - selectedICD = json['selectedICD'] != null - ? new MasterKeyModel.fromJson(json['selectedICD']) - : null; - selectedDiagnosisCondition = json['selectedDiagnosisCondition'] != null - ? new MasterKeyModel.fromJson(json['selectedDiagnosisCondition']) - : null; - selectedDiagnosisType = json['selectedDiagnosisType'] != null - ? new MasterKeyModel.fromJson(json['selectedDiagnosisType']) - : null; - remark = json['remark']; - appointmentId = json['appointmentId']; - createdBy = json['createdBy']; - createdOn = json['createdOn']; - doctorID = json['doctorID']; - doctorName = json['doctorName']; - icdCode10ID = json['icdCode10ID']; - } - - Map toJson() { - final Map data = new Map(); - - if (this.selectedICD != null) { - data['selectedICD'] = this.selectedICD.toJson(); - } - if (this.selectedDiagnosisCondition != null) { - data['selectedICD'] = this.selectedDiagnosisCondition.toJson(); - } - if (this.selectedDiagnosisType != null) { - data['selectedICD'] = this.selectedDiagnosisType.toJson(); - } - data['remark'] = this.remark; - data['appointmentId'] = this.appointmentId; - data['createdBy'] = this.createdBy; - data['createdOn'] = this.createdOn; - data['doctorID'] = this.doctorID; - data['doctorName'] = this.doctorName; - data['icdCode10ID'] = this.icdCode10ID; - return data; - } -} diff --git a/lib/models/SOAP/my_selected_examination.dart b/lib/models/SOAP/my_selected_examination.dart deleted file mode 100644 index 6a3ecf99..00000000 --- a/lib/models/SOAP/my_selected_examination.dart +++ /dev/null @@ -1,61 +0,0 @@ -import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; - -class MySelectedExamination { - MasterKeyModel selectedExamination; - String remark; - bool isNormal; - bool isAbnormal; - bool notExamined; - bool isNew; - bool isLocal; - int createdBy; - String createdOn; - String editedOn; - - MySelectedExamination({ - this.selectedExamination, - this.remark, - this.isNormal = false, - this.isAbnormal = false, - this.notExamined = true, - this.isNew = true, - this.isLocal = true, - this.createdBy, - this.createdOn, - this.editedOn, - }); - - MySelectedExamination.fromJson(Map json) { - selectedExamination = json['selectedExamination'] != null - ? new MasterKeyModel.fromJson(json['selectedExamination']) - : null; - remark = json['remark']; - isNormal = json['isNormal']; - isAbnormal = json['isAbnormal']; - notExamined = json['notExamined']; - isNew = json['isNew']; - createdBy = json['createdBy']; - createdOn = json['createdOn']; - editedOn = json['editedOn']; - isLocal = json['isLocal']; - } - - Map toJson() { - final Map data = new Map(); - - if (this.selectedExamination != null) { - data['selectedExamination'] = this.selectedExamination.toJson(); - } - data['remark'] = this.remark; - data['isNormal'] = this.isNormal; - data['isAbnormal'] = this.isAbnormal; - data['notExamined'] = this.notExamined; - data['isNew'] = this.isNew; - data['createdBy'] = this.createdBy; - data['createdOn'] = this.createdOn; - data['editedOn'] = this.editedOn; - data['isLocal'] = this.isLocal; - - return data; - } -} diff --git a/lib/models/SOAP/my_selected_history.dart b/lib/models/SOAP/my_selected_history.dart deleted file mode 100644 index 91f66910..00000000 --- a/lib/models/SOAP/my_selected_history.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; - -class MySelectedHistory { - MasterKeyModel selectedHistory; - String remark; - bool isChecked; - bool isLocal; - - MySelectedHistory( - { this.selectedHistory, this.remark, this.isChecked, this.isLocal = true}); - - MySelectedHistory.fromJson(Map json) { - - selectedHistory = json['selectedHistory'] != null - ? new MasterKeyModel.fromJson(json['selectedHistory']) - : null; - remark = json['remark']; - remark = json['isChecked']; - isLocal = json['isLocal']; - } - - Map toJson() { - final Map data = new Map(); - - if (this.selectedHistory != null) { - data['selectedHistory'] = this.selectedHistory.toJson(); - } - data['remark'] = this.remark; - data['isChecked'] = this.remark; - data['isLocal'] = this.isLocal; - return data; - } -} diff --git a/lib/models/SOAP/selected_items/my_selected_allergy.dart b/lib/models/SOAP/selected_items/my_selected_allergy.dart new file mode 100644 index 00000000..512a4f64 --- /dev/null +++ b/lib/models/SOAP/selected_items/my_selected_allergy.dart @@ -0,0 +1,23 @@ +import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; + +class MySelectedAllergy { + MasterKeyModel selectedAllergySeverity; + MasterKeyModel selectedAllergy; + String remark; + bool isChecked; + bool isExpanded; + bool isLocal; + int createdBy; + bool hasValidationError; + + MySelectedAllergy( + {this.selectedAllergySeverity, + this.selectedAllergy, + this.remark, + this.isChecked, + this.isExpanded = true, + this.isLocal = true, + this.createdBy, + this.hasValidationError = false}); + +} diff --git a/lib/models/SOAP/selected_items/my_selected_assement.dart b/lib/models/SOAP/selected_items/my_selected_assement.dart new file mode 100644 index 00000000..01572e6d --- /dev/null +++ b/lib/models/SOAP/selected_items/my_selected_assement.dart @@ -0,0 +1,24 @@ +import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; + +class MySelectedAssessment { + MasterKeyModel selectedICD; + MasterKeyModel selectedDiagnosisCondition; + MasterKeyModel selectedDiagnosisType; + String remark; + int appointmentId; + int createdBy; + String createdOn; + int doctorID; + String doctorName; + String icdCode10ID; + + MySelectedAssessment( + {this.selectedICD, + this.selectedDiagnosisCondition, + this.selectedDiagnosisType, + this.remark, this.appointmentId, this.createdBy, + this.createdOn, + this.doctorID, + this.doctorName, + this.icdCode10ID}); +} diff --git a/lib/models/SOAP/selected_items/my_selected_examination.dart b/lib/models/SOAP/selected_items/my_selected_examination.dart new file mode 100644 index 00000000..75f67ae2 --- /dev/null +++ b/lib/models/SOAP/selected_items/my_selected_examination.dart @@ -0,0 +1,27 @@ +import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; + +class MySelectedExamination { + MasterKeyModel selectedExamination; + String remark; + bool isNormal; + bool isAbnormal; + bool notExamined; + bool isNew; + bool isLocal; + int createdBy; + String createdOn; + String editedOn; + + MySelectedExamination({ + this.selectedExamination, + this.remark, + this.isNormal = false, + this.isAbnormal = false, + this.notExamined = true, + this.isNew = true, + this.isLocal = true, + this.createdBy, + this.createdOn, + this.editedOn, + }); +} diff --git a/lib/models/SOAP/selected_items/my_selected_history.dart b/lib/models/SOAP/selected_items/my_selected_history.dart new file mode 100644 index 00000000..3769c418 --- /dev/null +++ b/lib/models/SOAP/selected_items/my_selected_history.dart @@ -0,0 +1,11 @@ +import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; + +class MySelectedHistory { + MasterKeyModel selectedHistory; + String remark; + bool isChecked; + bool isLocal; + + MySelectedHistory( + {this.selectedHistory, this.remark, this.isChecked, this.isLocal = true}); +} diff --git a/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart b/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart index e14eb6f2..cc8be61f 100644 --- a/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart +++ b/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart @@ -6,8 +6,8 @@ import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/PatchAssessmentReqModel.dart'; import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; -import 'package:doctor_app_flutter/models/SOAP/my_selected_assement.dart'; import 'package:doctor_app_flutter/models/SOAP/post_assessment_request_model.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_assement.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; diff --git a/lib/screens/patients/profile/soap_update/assessment/update_assessment_page.dart b/lib/screens/patients/profile/soap_update/assessment/update_assessment_page.dart index f8da93f5..95d3cda5 100644 --- a/lib/screens/patients/profile/soap_update/assessment/update_assessment_page.dart +++ b/lib/screens/patients/profile/soap_update/assessment/update_assessment_page.dart @@ -5,9 +5,10 @@ import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/models/SOAP/GetAssessmentReqModel.dart'; import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; -import 'package:doctor_app_flutter/models/SOAP/my_selected_assement.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_assement.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/soap_update/soap_utils.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; @@ -28,12 +29,14 @@ class UpdateAssessmentPage extends StatefulWidget { final Function changePageViewIndex; final PatiantInformtion patientInfo; final Function changeLoadingState; - final int currentIndex; + final int currentIndex; + UpdateAssessmentPage( {Key key, this.changePageViewIndex, this.patientInfo, - this.changeLoadingState, this.currentIndex}); + this.changeLoadingState, + this.currentIndex}); @override _UpdateAssessmentPageState createState() => _UpdateAssessmentPageState(); @@ -42,6 +45,7 @@ class UpdateAssessmentPage extends StatefulWidget { class _UpdateAssessmentPageState extends State { bool isAssessmentExpand = false; List mySelectedAssessmentList = List(); + @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); @@ -54,7 +58,8 @@ class _UpdateAssessmentPageState extends State { episodeID: widget.patientInfo.episodeNo.toString(), editedBy: '', doctorID: '', - appointmentNo: int.parse(widget.patientInfo.appointmentNo.toString())); + appointmentNo: + int.parse(widget.patientInfo.appointmentNo.toString())); await model.getPatientAssessment(getAssessmentReqModel); if (model.patientAssessmentList.isNotEmpty) { if (model.listOfDiagnosisCondition.length == 0) { @@ -83,11 +88,11 @@ class _UpdateAssessmentPageState extends State { diagnosisType != null && diagnosisCondition != null) { MySelectedAssessment temMySelectedAssessment = - MySelectedAssessment( - appointmentId: element.appointmentNo, + SoapUtils.generateMySelectedAssessment( + appointmentNo: element.appointmentNo, remark: element.remarks, - selectedDiagnosisType: diagnosisType, - selectedDiagnosisCondition: diagnosisCondition, + diagnosisType: diagnosisType, + diagnosisCondition: diagnosisCondition, selectedICD: selectedICD, doctorID: element.doctorID, doctorName: element.doctorName, @@ -103,207 +108,173 @@ class _UpdateAssessmentPageState extends State { widget.changeLoadingState(false); }, builder: (_, model, w) => AppScaffold( - isShowAppBar: false, - backgroundColor: Theme - .of(context) - .scaffoldBackgroundColor, - body: SingleChildScrollView( - physics: ScrollPhysics(), - child: Container( - - color: Theme - .of(context) - .scaffoldBackgroundColor, - child: Center( - child: FractionallySizedBox( - widthFactor: 0.9, - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - SOAPStepHeader(currentIndex: widget.currentIndex, changePageViewIndex:widget.changePageViewIndex), - - ExpandableSOAPWidget( - headerTitle: TranslationBase.of(context).assessment - , - onTap: () { - setState(() { - isAssessmentExpand = !isAssessmentExpand; - }); - }, - child: Column(children: [ - SizedBox( - height: 20, - ), - Column( - children: [ - - SOAPOpenItems(label: "${TranslationBase.of(context).addAssessment}",onTap: () { - openAssessmentDialog(context, - isUpdate: false, model: model); - },), - - SizedBox( - height: 20, - ), - Column( - children: mySelectedAssessmentList - .map((assessment) { - return Container( - margin: EdgeInsets.only( - left: 5, right: 5, top: 15), - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - RichText( - text: new TextSpan( - style: new TextStyle( - fontSize: 12, - color: Color(0xFF2E303A), - fontFamily: 'Poppins', - fontWeight: FontWeight.w600), - children: [ - new TextSpan( - text: "ICD : ".toUpperCase(), - ), - new TextSpan( - text: assessment - .selectedICD.code - .trim() - .toUpperCase() ?? - "", - ), - ], - ), - ), - Container( - width: MediaQuery.of(context) - .size - .width * - 0.50, - child: RichText( + isShowAppBar: false, + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + body: SingleChildScrollView( + physics: ScrollPhysics(), + child: Container( + color: Theme.of(context).scaffoldBackgroundColor, + child: Center( + child: FractionallySizedBox( + widthFactor: 0.9, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SOAPStepHeader( + currentIndex: widget.currentIndex, + changePageViewIndex: widget.changePageViewIndex), + ExpandableSOAPWidget( + headerTitle: TranslationBase.of(context).assessment, + onTap: () { + setState(() { + isAssessmentExpand = !isAssessmentExpand; + }); + }, + child: Column(children: [ + SizedBox( + height: 20, + ), + Column( + children: [ + SOAPOpenItems( + label: + "${TranslationBase.of(context).addAssessment}", + onTap: () { + openAssessmentDialog(context, + isUpdate: false, model: model); + }, + ), + SizedBox( + height: 20, + ), + Column( + children: + mySelectedAssessmentList.map((assessment) { + return Container( + margin: EdgeInsets.only( + left: 5, right: 5, top: 15), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + RichText( text: new TextSpan( style: new TextStyle( - fontSize: 16, + fontSize: 12, color: Color(0xFF2E303A), fontFamily: 'Poppins', fontWeight: FontWeight.w600), children: [ + new TextSpan( + text: + "ICD : ".toUpperCase(), + ), new TextSpan( text: assessment - .selectedICD.description - .toString(), + .selectedICD.code + .trim() + .toUpperCase() ?? + "", ), ], ), ), - ), - RichText( - text: new TextSpan( - style: new TextStyle( - fontSize: 12, - color: Color(0xFF2E303A), - fontFamily: 'Poppins', - fontWeight: FontWeight.w600), - children: [ - new TextSpan( - text: TranslationBase.of( - context) - .appointmentNo, + Container( + width: MediaQuery.of(context) + .size + .width * + 0.50, + child: RichText( + text: new TextSpan( style: new TextStyle( - color: Color(0xFF575757), - ), - ), - new TextSpan( - text: assessment - .appointmentId.toString() - - ?? - "", - style: new TextStyle( - fontSize: 14, - color: Color(0xFF2B353E), - ), + fontSize: 16, + color: Color(0xFF2E303A), + fontFamily: 'Poppins', + fontWeight: + FontWeight.w600), + children: [ + new TextSpan( + text: assessment + .selectedICD + .description + .toString(), + ), + ], ), - ], + ), ), - ), - RichText( - text: new TextSpan( - style: new TextStyle( - fontSize: 12, - color: Color(0xFF2E303A), - fontFamily: 'Poppins', - fontWeight: FontWeight.w600), - children: [ - new TextSpan( - text: TranslationBase.of( - context) - .condition + - " : ", - style: new TextStyle( - color: Color(0xFF575757), + RichText( + text: new TextSpan( + style: new TextStyle( + fontSize: 12, + color: Color(0xFF2E303A), + fontFamily: 'Poppins', + fontWeight: + FontWeight.w600), + children: [ + new TextSpan( + text: TranslationBase.of( + context) + .appointmentNo, + style: new TextStyle( + color: Color(0xFF575757), + ), ), - ), - new TextSpan( - text: projectViewModel - .isArabic - ? assessment - .selectedDiagnosisCondition - .nameAr - : assessment - .selectedDiagnosisCondition - .nameEn, - style: new TextStyle( - fontSize: 14, - color: Color(0xFF2B353E), + new TextSpan( + text: assessment + .appointmentId + .toString() ?? + "", + style: new TextStyle( + fontSize: 14, + color: Color(0xFF2B353E), + ), ), - ), - ], + ], + ), ), - ), - RichText( - text: new TextSpan( - style: new TextStyle( - fontSize: 12, - color: Color(0xFF2E303A), - fontFamily: 'Poppins', - fontWeight: FontWeight.w600), - children: [ - new TextSpan( - text: TranslationBase.of( - context) - .dType + - ' : ', - style: new TextStyle( - color: Color(0xFF575757), + RichText( + text: new TextSpan( + style: new TextStyle( + fontSize: 12, + color: Color(0xFF2E303A), + fontFamily: 'Poppins', + fontWeight: + FontWeight.w600), + children: [ + new TextSpan( + text: TranslationBase.of( + context) + .condition + + " : ", + style: new TextStyle( + color: Color(0xFF575757), + ), ), - ), - new TextSpan( - text: projectViewModel - .isArabic - ? assessment - .selectedDiagnosisType - .nameAr - : assessment - .selectedDiagnosisType - .nameEn, - style: new TextStyle( - fontSize: 14, - color: Color(0xFF2B353E), + new TextSpan( + text: projectViewModel + .isArabic + ? assessment + .selectedDiagnosisCondition + .nameAr + : assessment + .selectedDiagnosisCondition + .nameEn, + style: new TextStyle( + fontSize: 14, + color: Color(0xFF2B353E), + ), ), - ), - ], + ], + ), ), - ), - if (assessment.doctorName != null) RichText( text: new TextSpan( style: new TextStyle( @@ -316,16 +287,21 @@ class _UpdateAssessmentPageState extends State { new TextSpan( text: TranslationBase.of( context) - .doc + + .dType + ' : ', style: new TextStyle( color: Color(0xFF575757), ), ), new TextSpan( - text: - assessment.doctorName ?? - '', + text: projectViewModel + .isArabic + ? assessment + .selectedDiagnosisType + .nameAr + : assessment + .selectedDiagnosisType + .nameEn, style: new TextStyle( fontSize: 14, color: Color(0xFF2B353E), @@ -334,204 +310,236 @@ class _UpdateAssessmentPageState extends State { ], ), ), - SizedBox( - height: 6, - ), - - Row( - mainAxisAlignment: - MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 6, - ), - AppText( - (assessment.remark != null && - assessment.remark != - '') - ? TranslationBase.of( - context) - .remarks + - " : " - : '', - - fontSize: 12, - color: Color(0xFF2E303A), - fontFamily: 'Poppins', - fontWeight: - FontWeight.w600 - ), - Container( - width: MediaQuery.of(context) - .size - .width * - 0.38, - child: AppText( - assessment.remark ?? "", - fontSize: 11, - color: Color(0xFF2B353E), - fontWeight: FontWeight.w700, + if (assessment.doctorName != null) + RichText( + text: new TextSpan( + style: new TextStyle( + fontSize: 12, + color: Color(0xFF2E303A), + fontFamily: 'Poppins', + fontWeight: + FontWeight.w600), + children: [ + new TextSpan( + text: TranslationBase.of( + context) + .doc + + ' : ', + style: new TextStyle( + color: + Color(0xFF575757), + ), + ), + new TextSpan( + text: assessment + .doctorName ?? + '', + style: new TextStyle( + fontSize: 14, + color: + Color(0xFF2B353E), + ), + ), + ], ), ), - ], - ), - ], - ), - Column( - crossAxisAlignment: - CrossAxisAlignment.end, - children: [ - Row( - children: [ - Column( - children: [ - AppText( - assessment.createdOn != null - ? AppDateUtils - .getDayMonthYearDateFormatted( - DateTime.parse( - assessment - .createdOn)) - : AppDateUtils - .getDayMonthYearDateFormatted( - DateTime.now()), - fontWeight: FontWeight - .w600, - fontSize: 14, - ), AppText( - assessment.createdOn != null - ? AppDateUtils.getHour( - DateTime.parse( - assessment - .createdOn)) - : AppDateUtils.getHour( - DateTime.now()), - fontWeight: FontWeight - .w600, - fontSize: 14, + SizedBox( + height: 6, + ), + Row( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + SizedBox( + height: 6, + ), + AppText( + (assessment.remark != + null && + assessment.remark != + '') + ? TranslationBase.of( + context) + .remarks + + " : " + : '', + fontSize: 12, + color: Color(0xFF2E303A), + fontFamily: 'Poppins', + fontWeight: + FontWeight.w600), + Container( + width: MediaQuery.of(context) + .size + .width * + 0.38, + child: AppText( + assessment.remark ?? "", + fontSize: 11, + color: Color(0xFF2B353E), + fontWeight: FontWeight.w700, ), - ], + ), + ], + ), + ], + ), + Column( + crossAxisAlignment: + CrossAxisAlignment.end, + children: [ + Row( + children: [ + Column( + children: [ + AppText( + assessment.createdOn != + null + ? AppDateUtils + .getDayMonthYearDateFormatted( + DateTime.parse( + assessment + .createdOn)) + : AppDateUtils + .getDayMonthYearDateFormatted( + DateTime + .now()), + fontWeight: + FontWeight.w600, + fontSize: 14, + ), + AppText( + assessment.createdOn != + null + ? AppDateUtils.getHour( + DateTime.parse( + assessment + .createdOn)) + : AppDateUtils + .getHour(DateTime + .now()), + fontWeight: + FontWeight.w600, + fontSize: 14, + ), + ], + ), + ], + ), + SizedBox( + height: MediaQuery.of(context) + .size + .height * + 0.05, + ), + InkWell( + onTap: () { + openAssessmentDialog(context, + isUpdate: true, + assessment: assessment, + model: model); + }, + child: Icon( + DoctorApp.edit, + size: 18, ), - ], - ), - SizedBox( - height: MediaQuery.of(context) - .size - .height * - 0.05, - ), - InkWell( - onTap: () { - openAssessmentDialog(context, - isUpdate: true, - assessment: assessment, - model: model); - }, - child: Icon( - DoctorApp.edit, size: 18,), - ) - ], - ), - ], - ), - ); - }).toList(), - ) - ], - ) - ]), - isExpanded: isAssessmentExpand, - ), - SizedBox( - height: 130, - ), - ], + ) + ], + ), + ], + ), + ); + }).toList(), + ) + ], + ) + ]), + isExpanded: isAssessmentExpand, + ), + SizedBox( + height: 130, + ), + ], + ), ), ), ), ), - ), - bottomSheet:Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all( - Radius.circular(0.0), - ), - border: Border.all( - color: HexColor('#707070'), - width: 0), - ), - height: 80, - width: double.infinity, - child: Column( - children: [ - SizedBox( - height: 10, + bottomSheet: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(0.0), ), - Container(child: - FractionallySizedBox( - widthFactor: .80, - child: Center( - child: Row( - children: [ - Expanded( - child: AppButton( - title: TranslationBase - .of(context) - .previous, - color: Colors.grey[300], - fontColor: Colors.black, - fontWeight: FontWeight.w600, - disabled: model.state == ViewState.BusyLocal, - onPressed: () async { - widget.changePageViewIndex(1); - }, - ) - , - ), - SizedBox(width: 5,), - Expanded( - child: AppButton( - title: TranslationBase - .of(context) - .next, - fontWeight: FontWeight.w600, - color: Colors.red[700], - disabled: model.state == ViewState.BusyLocal, - onPressed: () async { - if (mySelectedAssessmentList.isEmpty) { - Helpers.showErrorToast( - TranslationBase - .of(context) - .assessmentErrorMsg); - } else { - widget.changeLoadingState(true); - widget.changePageViewIndex(3); - - } - }, - ), + border: Border.all(color: HexColor('#707070'), width: 0), + ), + height: 80, + width: double.infinity, + child: Column( + children: [ + SizedBox( + height: 10, + ), + Container( + child: FractionallySizedBox( + widthFactor: .80, + child: Center( + child: Row( + children: [ + Expanded( + child: AppButton( + title: TranslationBase.of(context).previous, + color: Colors.grey[300], + fontColor: Colors.black, + fontWeight: FontWeight.w600, + disabled: model.state == ViewState.BusyLocal, + onPressed: () async { + widget.changePageViewIndex(1); + }, + ), + ), + SizedBox( + width: 5, + ), + Expanded( + child: AppButton( + title: TranslationBase.of(context).next, + fontWeight: FontWeight.w600, + color: Colors.red[700], + disabled: model.state == ViewState.BusyLocal, + onPressed: () async { + if (mySelectedAssessmentList.isEmpty) { + Helpers.showErrorToast( + TranslationBase.of(context) + .assessmentErrorMsg); + } else { + widget.changeLoadingState(true); + widget.changePageViewIndex(3); + } + }, + ), + ), + ], ), - ], + ), ), ), - ),), - SizedBox( - height: 5, - ), - ], - ),) - - ), + SizedBox( + height: 5, + ), + ], + ), + )), ); } openAssessmentDialog(BuildContext context, {MySelectedAssessment assessment, bool isUpdate, SOAPViewModel model}) { if (assessment == null) { - assessment = MySelectedAssessment( - remark: '', appointmentId: widget.patientInfo.appointmentNo); + assessment = SoapUtils.generateMySelectedAssessment( + remark: '', appointmentNo: widget.patientInfo.appointmentNo); } showModalBottomSheet( backgroundColor: Colors.white, @@ -546,11 +554,10 @@ class _UpdateAssessmentPageState extends State { addSelectedAssessment: (MySelectedAssessment mySelectedAssessment, bool isUpdate) async { setState(() { - if(!isUpdate) - mySelectedAssessmentList.add(mySelectedAssessment); + if (!isUpdate) + mySelectedAssessmentList.add(mySelectedAssessment); }); }); }); } } - diff --git a/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart b/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart index 87af6ec2..37f67ffc 100644 --- a/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart +++ b/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart @@ -2,7 +2,7 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/master_lookup_key.dart'; import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; -import 'package:doctor_app_flutter/models/SOAP/my_selected_examination.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_examination.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/bottom_sheet_title.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; diff --git a/lib/screens/patients/profile/soap_update/objective/add_examination_widget.dart b/lib/screens/patients/profile/soap_update/objective/add_examination_widget.dart index f0dc25cf..ce2bced1 100644 --- a/lib/screens/patients/profile/soap_update/objective/add_examination_widget.dart +++ b/lib/screens/patients/profile/soap_update/objective/add_examination_widget.dart @@ -2,7 +2,7 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; -import 'package:doctor_app_flutter/models/SOAP/my_selected_examination.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_examination.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/expandable-widget-header-body.dart'; diff --git a/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart b/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart index 84a4c740..58dc7180 100644 --- a/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart +++ b/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart @@ -1,6 +1,6 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; -import 'package:doctor_app_flutter/models/SOAP/my_selected_examination.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_examination.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/material.dart'; diff --git a/lib/screens/patients/profile/soap_update/objective/examinations_list_search_widget.dart b/lib/screens/patients/profile/soap_update/objective/examinations_list_search_widget.dart index c67102ee..ed7554e1 100644 --- a/lib/screens/patients/profile/soap_update/objective/examinations_list_search_widget.dart +++ b/lib/screens/patients/profile/soap_update/objective/examinations_list_search_widget.dart @@ -1,5 +1,5 @@ import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; -import 'package:doctor_app_flutter/models/SOAP/my_selected_examination.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_examination.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/divider_with_spaces_around.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; diff --git a/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart b/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart index dbd3b080..ca2464b1 100644 --- a/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart +++ b/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart @@ -4,11 +4,12 @@ import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/GetPhysicalExamReqModel.dart'; import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; -import 'package:doctor_app_flutter/models/SOAP/my_selected_examination.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_examination.dart'; import 'package:doctor_app_flutter/models/SOAP/post_physical_exam_request_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/soap_update/soap_utils.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; @@ -80,8 +81,9 @@ class _UpdateObjectivePageState extends State { masterKeys: MasterKeysService.PhysicalExamination, id: element.examId, ); - MySelectedExamination tempEam = MySelectedExamination( - selectedExamination: examMaster, + MySelectedExamination tempEam = + SoapUtils.generateMySelectedExamination( + examination: examMaster, remark: element.remarks, isNormal: element.isNormal, createdBy: element.createdBy, diff --git a/lib/screens/patients/profile/soap_update/soap_utils.dart b/lib/screens/patients/profile/soap_update/soap_utils.dart new file mode 100644 index 00000000..34bf4236 --- /dev/null +++ b/lib/screens/patients/profile/soap_update/soap_utils.dart @@ -0,0 +1,88 @@ +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_allergy.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_assement.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_examination.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_history.dart'; + +class SoapUtils { + static MySelectedHistory generateMySelectedHistory( + {history, isChecked, remark, isLocal}) { + MySelectedHistory mySelectedHistory = MySelectedHistory( + selectedHistory: history, + isChecked: isChecked, + remark: remark, + isLocal: isLocal); + return mySelectedHistory; + } + + static MySelectedAllergy generateMySelectedAllergy( + {allergy, + allergySeverity, + isChecked, + remark, + isLocal, + int createdBy, + bool isExpanded}) { + MySelectedAllergy mySelectedAllergy = MySelectedAllergy( + selectedAllergy: allergy, + selectedAllergySeverity: allergySeverity, + isChecked: isChecked, + remark: remark, + isLocal: isLocal, + createdBy: createdBy, + isExpanded: isExpanded); + return mySelectedAllergy; + } + + static MySelectedExamination generateMySelectedExamination( + {examination, + allergySeverity, + isChecked, + remark, + isLocal, + isNormal, + createdBy, + createdOn, + editedOn, + notExamined, + isNew, + isAbnormal}) { + MySelectedExamination mySelectedExamination = MySelectedExamination( + selectedExamination: examination, + remark: remark, + isNormal: isNormal, + createdBy: createdBy, + createdOn: createdOn, + editedOn: editedOn, + notExamined: notExamined, + isNew: isNew, + isLocal: isLocal, + isAbnormal: isAbnormal, + ); + return mySelectedExamination; + } + + static MySelectedAssessment generateMySelectedAssessment( + {appointmentNo, + remark, + diagnosisType, + diagnosisCondition, + selectedICD, + doctorID, + doctorName, + createdBy, + createdOn, + icdCode10ID}) { + MySelectedAssessment mySelectedAssessment = MySelectedAssessment( + appointmentId: appointmentNo, + remark: remark, + selectedDiagnosisType: diagnosisType, + selectedDiagnosisCondition: diagnosisCondition, + selectedICD: selectedICD, + doctorID: doctorID, + doctorName: doctorName, + createdBy: createdBy, + createdOn: createdOn, + icdCode10ID: icdCode10ID); + return mySelectedAssessment; + } +} diff --git a/lib/screens/patients/profile/soap_update/subjective/allergies/add_allergies.dart b/lib/screens/patients/profile/soap_update/subjective/allergies/add_allergies.dart index 4cf20318..9f002d65 100644 --- a/lib/screens/patients/profile/soap_update/subjective/allergies/add_allergies.dart +++ b/lib/screens/patients/profile/soap_update/subjective/allergies/add_allergies.dart @@ -3,7 +3,7 @@ import 'package:doctor_app_flutter/core/enum/master_lookup_key.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; -import 'package:doctor_app_flutter/models/SOAP/my_selected_allergy.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_allergy.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; diff --git a/lib/screens/patients/profile/soap_update/subjective/allergies/allergies_item.dart b/lib/screens/patients/profile/soap_update/subjective/allergies/allergies_item.dart index 55e36342..08753bec 100644 --- a/lib/screens/patients/profile/soap_update/subjective/allergies/allergies_item.dart +++ b/lib/screens/patients/profile/soap_update/subjective/allergies/allergies_item.dart @@ -1,7 +1,7 @@ import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; -import 'package:doctor_app_flutter/models/SOAP/my_selected_allergy.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_allergy.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/dialogs/master_key_dailog.dart'; @@ -12,6 +12,8 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import '../../soap_utils.dart'; + class AddAllergiesItem extends StatefulWidget { final SOAPViewModel model; final Function(MasterKeyModel) removeAllergy; @@ -139,14 +141,14 @@ class _AddAllergiesItemState extends State { } : null, isTextFieldHasSuffix: true, - hintText: TranslationBase.of(context).selectSeverity, + hintText: TranslationBase.of(context).selectSeverity + "*", enabled: false, maxLines: 2, minLines: 2, validationError: mySelectedAllergy != null && mySelectedAllergy.selectedAllergySeverity == null && mySelectedAllergy.hasValidationError - ? TranslationBase.of(context).emptyMessage + ? TranslationBase.of(context).severityValidationError : null, controller: severityController, ), @@ -184,9 +186,9 @@ class _AddAllergiesItemState extends State { widget.removeAllergy(widget.item); } else { MySelectedAllergy mySelectedAllergy = - new MySelectedAllergy( - selectedAllergy: widget.item, - selectedAllergySeverity: _selectedAllergySeverity, + SoapUtils.generateMySelectedAllergy( + allergy: widget.item, + allergySeverity: _selectedAllergySeverity, remark: null, isChecked: true, isExpanded: true); diff --git a/lib/screens/patients/profile/soap_update/subjective/allergies/master_key_checkbox_search_allergies_widget.dart b/lib/screens/patients/profile/soap_update/subjective/allergies/master_key_checkbox_search_allergies_widget.dart index 8644c9a9..8da1799b 100644 --- a/lib/screens/patients/profile/soap_update/subjective/allergies/master_key_checkbox_search_allergies_widget.dart +++ b/lib/screens/patients/profile/soap_update/subjective/allergies/master_key_checkbox_search_allergies_widget.dart @@ -1,6 +1,6 @@ import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; -import 'package:doctor_app_flutter/models/SOAP/my_selected_allergy.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_allergy.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/divider_with_spaces_around.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; diff --git a/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart b/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart index 4be953a7..32c54f52 100644 --- a/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart +++ b/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart @@ -1,5 +1,5 @@ import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; -import 'package:doctor_app_flutter/models/SOAP/my_selected_allergy.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_allergy.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; diff --git a/lib/screens/patients/profile/soap_update/subjective/history/add_history_dialog.dart b/lib/screens/patients/profile/soap_update/subjective/history/add_history_dialog.dart index bd2f8502..566eeda4 100644 --- a/lib/screens/patients/profile/soap_update/subjective/history/add_history_dialog.dart +++ b/lib/screens/patients/profile/soap_update/subjective/history/add_history_dialog.dart @@ -2,8 +2,9 @@ import 'package:doctor_app_flutter/core/enum/master_lookup_key.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; -import 'package:doctor_app_flutter/models/SOAP/my_selected_history.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_history.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/soap_update/soap_utils.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; @@ -215,10 +216,10 @@ class _AddHistoryDialogState extends State { if (myhistory.isEmpty) { setState(() { - MySelectedHistory mySelectedHistory = MySelectedHistory( - remark: history.remarks ?? "", - selectedHistory: history, + MySelectedHistory mySelectedHistory = SoapUtils.generateMySelectedHistory(remark: history.remarks ?? "", + history: history, isChecked: true); + widget.myHistoryList.add(mySelectedHistory); }); } else { diff --git a/lib/screens/patients/profile/soap_update/subjective/history/update_history_widget.dart b/lib/screens/patients/profile/soap_update/subjective/history/update_history_widget.dart index 3b431a69..cede4e15 100644 --- a/lib/screens/patients/profile/soap_update/subjective/history/update_history_widget.dart +++ b/lib/screens/patients/profile/soap_update/subjective/history/update_history_widget.dart @@ -1,6 +1,6 @@ import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; -import 'package:doctor_app_flutter/models/SOAP/my_selected_history.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_history.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/material.dart'; diff --git a/lib/screens/patients/profile/soap_update/subjective/medication/update_medication_widget.dart b/lib/screens/patients/profile/soap_update/subjective/medication/update_medication_widget.dart index 7372e7ee..c6427511 100644 --- a/lib/screens/patients/profile/soap_update/subjective/medication/update_medication_widget.dart +++ b/lib/screens/patients/profile/soap_update/subjective/medication/update_medication_widget.dart @@ -1,4 +1,4 @@ -import 'package:doctor_app_flutter/models/SOAP/my_selected_allergy.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_allergy.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:flutter/material.dart'; diff --git a/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart b/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart index 7a48a786..5942a7cf 100644 --- a/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart +++ b/lib/screens/patients/profile/soap_update/subjective/update_subjective_page.dart @@ -6,14 +6,15 @@ import 'package:doctor_app_flutter/models/SOAP/ChiefComplaint/GetChiefComplaintR import 'package:doctor_app_flutter/models/SOAP/GeneralGetReqForSOAP.dart'; import 'package:doctor_app_flutter/models/SOAP/GetHistoryReqModel.dart'; import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; -import 'package:doctor_app_flutter/models/SOAP/my_selected_allergy.dart'; -import 'package:doctor_app_flutter/models/SOAP/my_selected_history.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_allergy.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_history.dart'; import 'package:doctor_app_flutter/models/SOAP/post_allergy_request_model.dart'; import 'package:doctor_app_flutter/models/SOAP/post_chief_complaint_request_model.dart'; import 'package:doctor_app_flutter/models/SOAP/post_histories_request_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/soap_update/soap_utils.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; @@ -55,8 +56,8 @@ class _UpdateSubjectivePageState extends State { String medicationControllerError = ''; String illnessControllerError = ''; final formKey = GlobalKey(); - List myAllergiesList=List(); - List myHistoryList=List(); + List myAllergiesList = List(); + List myHistoryList = List(); getHistory(SOAPViewModel model) async { widget.changeLoadingState(true); @@ -84,51 +85,67 @@ class _UpdateSubjectivePageState extends State { } model.patientHistoryList.forEach((element) { - if (element.historyType == MasterKeysService.HistoryFamily.getMasterKeyService()) { + if (element.historyType == + MasterKeysService.HistoryFamily.getMasterKeyService()) { MasterKeyModel history = model.getOneMasterKey( masterKeys: MasterKeysService.HistoryFamily, id: element.historyId, ); if (history != null) { MySelectedHistory mySelectedHistory = - MySelectedHistory(selectedHistory: history, isChecked: element.isChecked, remark: element.remarks,isLocal: false); - + SoapUtils.generateMySelectedHistory( + history: history, + isChecked: element.isChecked, + remark: element.remarks, + isLocal: false); myHistoryList.add(mySelectedHistory); } } - if (element.historyType == MasterKeysService.HistoryMedical.getMasterKeyService()) { + if (element.historyType == + MasterKeysService.HistoryMedical.getMasterKeyService()) { MasterKeyModel history = model.getOneMasterKey( masterKeys: MasterKeysService.HistoryMedical, id: element.historyId, ); if (history != null) { MySelectedHistory mySelectedHistory = - MySelectedHistory(selectedHistory: history, isChecked: element.isChecked, remark: element.remarks,isLocal: false); - + SoapUtils.generateMySelectedHistory( + history: history, + isChecked: element.isChecked, + remark: element.remarks, + isLocal: false); myHistoryList.add(mySelectedHistory); } } - if (element.historyType == MasterKeysService.HistorySports.getMasterKeyService()) { + if (element.historyType == + MasterKeysService.HistorySports.getMasterKeyService()) { MasterKeyModel history = model.getOneMasterKey( masterKeys: MasterKeysService.HistorySports, id: element.historyId, ); if (history != null) { MySelectedHistory mySelectedHistory = - MySelectedHistory(selectedHistory: history, isChecked: element.isChecked, remark: element.remarks,isLocal: false); - + SoapUtils.generateMySelectedHistory( + history: history, + isChecked: element.isChecked, + remark: element.remarks, + isLocal: false); myHistoryList.add(mySelectedHistory); } } - if (element.historyType == MasterKeysService.HistorySurgical.getMasterKeyService()) { + if (element.historyType == + MasterKeysService.HistorySurgical.getMasterKeyService()) { MasterKeyModel history = model.getOneMasterKey( masterKeys: MasterKeysService.HistorySurgical, id: element.historyId, ); if (history != null) { MySelectedHistory mySelectedHistory = - MySelectedHistory(selectedHistory: history, isChecked: element.isChecked, remark: element.remarks,isLocal: false); - + SoapUtils.generateMySelectedHistory( + history: history, + isChecked: element.isChecked, + remark: element.remarks, + isLocal: false); myHistoryList.add(mySelectedHistory); } } @@ -145,16 +162,23 @@ class _UpdateSubjectivePageState extends State { editedBy: ''); await model.getPatientAllergy(generalGetReqForSOAP); if (model.patientAllergiesList.isNotEmpty) { - if (model.allergiesList.isEmpty) await model.getMasterLookup(MasterKeysService.Allergies); - if (model.allergySeverityList.isEmpty) await model.getMasterLookup(MasterKeysService.AllergySeverity); + if (model.allergiesList.isEmpty) + await model.getMasterLookup(MasterKeysService.Allergies); + if (model.allergySeverityList.isEmpty) + await model.getMasterLookup(MasterKeysService.AllergySeverity); model.patientAllergiesList.forEach((element) { MasterKeyModel selectedAllergy = model.getOneMasterKey( - masterKeys: MasterKeysService.Allergies, id: element.allergyDiseaseId, typeId: element.allergyDiseaseType); + masterKeys: MasterKeysService.Allergies, + id: element.allergyDiseaseId, + typeId: element.allergyDiseaseType); MasterKeyModel selectedAllergySeverity; if (element.severity == 0) { selectedAllergySeverity = MasterKeyModel( - id: 0, typeId: MasterKeysService.AllergySeverity.getMasterKeyService(), nameAr: '', nameEn: ''); + id: 0, + typeId: MasterKeysService.AllergySeverity.getMasterKeyService(), + nameAr: '', + nameEn: ''); } else { selectedAllergySeverity = model.getOneMasterKey( masterKeys: MasterKeysService.AllergySeverity, @@ -162,14 +186,17 @@ class _UpdateSubjectivePageState extends State { ); } - MySelectedAllergy mySelectedAllergy = MySelectedAllergy( - selectedAllergy: selectedAllergy, - isChecked: element.isChecked, - createdBy: element.createdBy, - remark: element.remarks, - isLocal : false, - selectedAllergySeverity: selectedAllergySeverity); - if (selectedAllergy != null && selectedAllergySeverity != null) myAllergiesList.add(mySelectedAllergy); + MySelectedAllergy mySelectedAllergy = + SoapUtils.generateMySelectedAllergy( + allergy: selectedAllergy, + isChecked: element.isChecked, + createdBy: element.createdBy, + remark: element.remarks, + isLocal: false, + allergySeverity: selectedAllergySeverity); + + if (selectedAllergy != null && selectedAllergySeverity != null) + myAllergiesList.add(mySelectedAllergy); }); } } @@ -181,20 +208,25 @@ class _UpdateSubjectivePageState extends State { myAllergiesList.clear(); myHistoryList.clear(); - GetChiefComplaintReqModel getChiefComplaintReqModel = GetChiefComplaintReqModel( - patientMRN: widget.patientInfo.patientMRN, - appointmentNo: int.parse(widget.patientInfo.appointmentNo.toString()), - episodeId: widget.patientInfo.episodeNo, - episodeID: widget.patientInfo.episodeNo, - doctorID: ''); + GetChiefComplaintReqModel getChiefComplaintReqModel = + GetChiefComplaintReqModel( + patientMRN: widget.patientInfo.patientMRN, + appointmentNo: + int.parse(widget.patientInfo.appointmentNo.toString()), + episodeId: widget.patientInfo.episodeNo, + episodeID: widget.patientInfo.episodeNo, + doctorID: ''); await model.getPatientChiefComplaint(getChiefComplaintReqModel); if (model.patientChiefComplaintList.isNotEmpty) { isChiefExpand = true; - complaintsController.text = Helpers.parseHtmlString(model.patientChiefComplaintList[0].chiefComplaint); + complaintsController.text = Helpers.parseHtmlString( + model.patientChiefComplaintList[0].chiefComplaint); illnessController.text = model.patientChiefComplaintList[0].hopi; - medicationController.text = !(model.patientChiefComplaintList[0].currentMedication).isNotEmpty - ? model.patientChiefComplaintList[0].currentMedication + '\n \n' - : model.patientChiefComplaintList[0].currentMedication; + medicationController.text = + !(model.patientChiefComplaintList[0].currentMedication).isNotEmpty + ? model.patientChiefComplaintList[0].currentMedication + + '\n \n' + : model.patientChiefComplaintList[0].currentMedication; } await getHistory(model); @@ -214,7 +246,9 @@ class _UpdateSubjectivePageState extends State { mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ - SOAPStepHeader(currentIndex: widget.currentIndex, changePageViewIndex: widget.changePageViewIndex), + SOAPStepHeader( + currentIndex: widget.currentIndex, + changePageViewIndex: widget.changePageViewIndex), ExpandableSOAPWidget( headerTitle: TranslationBase.of(context).chiefComplaints, onTap: () { @@ -245,7 +279,9 @@ class _UpdateSubjectivePageState extends State { }); }, child: Column( - children: [UpdateHistoryWidget(myHistoryList: myHistoryList)], + children: [ + UpdateHistoryWidget(myHistoryList: myHistoryList) + ], ), isExpanded: isHistoryExpand, ), @@ -306,7 +342,9 @@ class _UpdateSubjectivePageState extends State { // loading: model.state == ViewState.BusyLocal, onPressed: () async { addSubjectiveInfo( - model: model, myAllergiesList: myAllergiesList, myHistoryList: myHistoryList); + model: model, + myAllergiesList: myAllergiesList, + myHistoryList: myHistoryList); }, ), ), @@ -323,9 +361,10 @@ class _UpdateSubjectivePageState extends State { } addSubjectiveInfo( - {SOAPViewModel model, List myAllergiesList, List myHistoryList}) async { - if(FocusScope.of(context).hasFocus) - FocusScope.of(context).unfocus(); + {SOAPViewModel model, + List myAllergiesList, + List myHistoryList}) async { + if (FocusScope.of(context).hasFocus) FocusScope.of(context).unfocus(); widget.changeLoadingState(true); formKey.currentState.save(); formKey.currentState.validate(); @@ -360,7 +399,8 @@ class _UpdateSubjectivePageState extends State { if (complaintsController.text.isEmpty) { complaintsControllerError = TranslationBase.of(context).emptyMessage; } else if (complaintsController.text.length < 25) { - complaintsControllerError = TranslationBase.of(context).chiefComplaintLength; + complaintsControllerError = + TranslationBase.of(context).chiefComplaintLength; } if (illnessController.text.isEmpty) { @@ -373,33 +413,38 @@ class _UpdateSubjectivePageState extends State { }); widget.changeLoadingState(false); - Helpers.showErrorToast(TranslationBase.of(context).chiefComplaintErrorMsg); + Helpers.showErrorToast( + TranslationBase.of(context).chiefComplaintErrorMsg); } } - postAllergy({List myAllergiesList, SOAPViewModel model}) async { - PostAllergyRequestModel postAllergyRequestModel = new PostAllergyRequestModel(); + postAllergy( + {List myAllergiesList, SOAPViewModel model}) async { + PostAllergyRequestModel postAllergyRequestModel = + new PostAllergyRequestModel(); Map profile = await sharedPref.getObj(DOCTOR_PROFILE); DoctorProfileModel doctorProfile = DoctorProfileModel.fromJson(profile); myAllergiesList.forEach((allergy) { - if (postAllergyRequestModel.listHisProgNotePatientAllergyDiseaseVM == null) + if (postAllergyRequestModel.listHisProgNotePatientAllergyDiseaseVM == + null) postAllergyRequestModel.listHisProgNotePatientAllergyDiseaseVM = []; - postAllergyRequestModel.listHisProgNotePatientAllergyDiseaseVM.add(ListHisProgNotePatientAllergyDiseaseVM( - allergyDiseaseId: allergy.selectedAllergy.id, - allergyDiseaseType: allergy.selectedAllergy.typeId, - patientMRN: widget.patientInfo.patientMRN, - episodeId: widget.patientInfo.episodeNo, - appointmentNo: widget.patientInfo.appointmentNo, - severity: allergy.selectedAllergySeverity.id, - remarks: allergy.remark, - createdBy: allergy.createdBy ?? doctorProfile.doctorID, - createdOn: DateTime.now().toIso8601String(), - editedBy: doctorProfile.doctorID, - editedOn: DateTime.now().toIso8601String(), - isChecked: allergy.isChecked, - isUpdatedByNurse: false)); + postAllergyRequestModel.listHisProgNotePatientAllergyDiseaseVM.add( + ListHisProgNotePatientAllergyDiseaseVM( + allergyDiseaseId: allergy.selectedAllergy.id, + allergyDiseaseType: allergy.selectedAllergy.typeId, + patientMRN: widget.patientInfo.patientMRN, + episodeId: widget.patientInfo.episodeNo, + appointmentNo: widget.patientInfo.appointmentNo, + severity: allergy.selectedAllergySeverity.id, + remarks: allergy.remark, + createdBy: allergy.createdBy ?? doctorProfile.doctorID, + createdOn: DateTime.now().toIso8601String(), + editedBy: doctorProfile.doctorID, + editedOn: DateTime.now().toIso8601String(), + isChecked: allergy.isChecked, + isUpdatedByNurse: false)); }); if (model.patientAllergiesList.isEmpty) { await model.postAllergy(postAllergyRequestModel); @@ -423,10 +468,13 @@ class _UpdateSubjectivePageState extends State { } } - postHistories({List myHistoryList, SOAPViewModel model}) async { - PostHistoriesRequestModel postHistoriesRequestModel = new PostHistoriesRequestModel(doctorID: ''); + postHistories( + {List myHistoryList, SOAPViewModel model}) async { + PostHistoriesRequestModel postHistoriesRequestModel = + new PostHistoriesRequestModel(doctorID: ''); myHistoryList.forEach((history) { - if (postHistoriesRequestModel.listMedicalHistoryVM == null) postHistoriesRequestModel.listMedicalHistoryVM = []; + if (postHistoriesRequestModel.listMedicalHistoryVM == null) + postHistoriesRequestModel.listMedicalHistoryVM = []; postHistoriesRequestModel.listMedicalHistoryVM.add(ListMedicalHistoryVM( patientMRN: widget.patientInfo.patientMRN, episodeId: widget.patientInfo.episodeNo, @@ -452,17 +500,18 @@ class _UpdateSubjectivePageState extends State { postChiefComplaint({SOAPViewModel model}) async { formKey.currentState.save(); if (formKey.currentState.validate()) { - PostChiefComplaintRequestModel postChiefComplaintRequestModel = new PostChiefComplaintRequestModel( - patientMRN: widget.patientInfo.patientMRN, - episodeID: widget.patientInfo.episodeNo, - appointmentNo: widget.patientInfo.appointmentNo, - chiefComplaint: complaintsController.text, - currentMedication: medicationController.text, - hopi: illnessController.text, - isLactation: false, - ispregnant: false, - doctorID: '', - numberOfWeeks: 0); + PostChiefComplaintRequestModel postChiefComplaintRequestModel = + new PostChiefComplaintRequestModel( + patientMRN: widget.patientInfo.patientMRN, + episodeID: widget.patientInfo.episodeNo, + appointmentNo: widget.patientInfo.appointmentNo, + chiefComplaint: complaintsController.text, + currentMedication: medicationController.text, + hopi: illnessController.text, + isLactation: false, + ispregnant: false, + doctorID: '', + numberOfWeeks: 0); if (model.patientChiefComplaintList.isEmpty) { postChiefComplaintRequestModel.editedBy = ''; await model.postChiefComplaint(postChiefComplaintRequestModel); diff --git a/lib/screens/patients/profile/soap_update/update_soap_index.dart b/lib/screens/patients/profile/soap_update/update_soap_index.dart index e9d6d16d..d2fefb31 100644 --- a/lib/screens/patients/profile/soap_update/update_soap_index.dart +++ b/lib/screens/patients/profile/soap_update/update_soap_index.dart @@ -1,9 +1,8 @@ import 'package:doctor_app_flutter/core/viewModel/doctor_replay_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/GetGetProgressNoteResModel.dart'; -import 'package:doctor_app_flutter/models/SOAP/my_selected_allergy.dart'; -import 'package:doctor_app_flutter/models/SOAP/my_selected_assement.dart'; -import 'package:doctor_app_flutter/models/SOAP/my_selected_examination.dart'; -import 'package:doctor_app_flutter/models/SOAP/my_selected_history.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_allergy.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_examination.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_history.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/patients/profile/soap_update/subjective/update_subjective_page.dart'; diff --git a/lib/util/translations_delegate_base.dart b/lib/util/translations_delegate_base.dart index e30a006a..d36512ae 100644 --- a/lib/util/translations_delegate_base.dart +++ b/lib/util/translations_delegate_base.dart @@ -1366,6 +1366,7 @@ class TranslationBase { String get addPrescription => localizedValues['addPrescription'][locale.languageCode]; String get edit => localizedValues['edit'][locale.languageCode]; String get summeryReply => localizedValues['summeryReply'][locale.languageCode]; + String get severityValidationError => localizedValues['severityValidationError'][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { From efd3d4942eb6ae962b3ea66eeb03e35877ee20eb Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Wed, 14 Jul 2021 12:15:51 +0300 Subject: [PATCH 063/289] change the google json files --- android/app/google-services.json | 57 +++++++++++++++++++++++++---- android/google-services.json | 57 +++++++++++++++++++++++++---- ios/GoogleService-Info .plist | 16 ++++---- ios/Runner/GoogleService-Info.plist | 16 ++++---- lib/config/config.dart | 4 +- 5 files changed, 118 insertions(+), 32 deletions(-) diff --git a/android/app/google-services.json b/android/app/google-services.json index 3afb6dca..e6560790 100644 --- a/android/app/google-services.json +++ b/android/app/google-services.json @@ -1,34 +1,77 @@ { "project_info": { - "project_number": "1095694324958", - "project_id": "mobapp-bb272", - "storage_bucket": "mobapp-bb272.appspot.com" + "project_number": "934365232760", + "project_id": "hmg-dr-app", + "storage_bucket": "hmg-dr-app.appspot.com" }, "client": [ { "client_info": { - "mobilesdk_app_id": "1:1095694324958:android:70a42e30fcc98ea33fde4f", + "mobilesdk_app_id": "1:934365232760:android:024b3569972f1c09f9778d", + "android_client_info": { + "package_name": "COM.HMG.HMGDR" + } + }, + "oauth_client": [ + { + "client_id": "934365232760-bobv1r1sn222le020jeni6u1bdbjdu1v.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCpYwrmuntOBdZv6GV6KEnLj8nQRvEnZ6I" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "934365232760-bobv1r1sn222le020jeni6u1bdbjdu1v.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "934365232760-57v2ld1qqulc4nt4o5pgjfbpc47fj3qf.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "COM.HMG.HMGDR" + } + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:934365232760:android:e0e185e68c0d7690f9778d", "android_client_info": { "package_name": "com.hmg.hmgDr" } }, "oauth_client": [ { - "client_id": "1095694324958-5psabq8tpbti0uqo8bt46atjtbas9uhr.apps.googleusercontent.com", + "client_id": "934365232760-bobv1r1sn222le020jeni6u1bdbjdu1v.apps.googleusercontent.com", "client_type": 3 } ], "api_key": [ { - "current_key": "AIzaSyCuPtf1hTikWXrp5OQIVfqO-TJWubI-Vd8" + "current_key": "AIzaSyCpYwrmuntOBdZv6GV6KEnLj8nQRvEnZ6I" } ], "services": { "appinvite_service": { "other_platform_oauth_client": [ { - "client_id": "1095694324958-5psabq8tpbti0uqo8bt46atjtbas9uhr.apps.googleusercontent.com", + "client_id": "934365232760-bobv1r1sn222le020jeni6u1bdbjdu1v.apps.googleusercontent.com", "client_type": 3 + }, + { + "client_id": "934365232760-57v2ld1qqulc4nt4o5pgjfbpc47fj3qf.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "COM.HMG.HMGDR" + } } ] } diff --git a/android/google-services.json b/android/google-services.json index 3afb6dca..e6560790 100644 --- a/android/google-services.json +++ b/android/google-services.json @@ -1,34 +1,77 @@ { "project_info": { - "project_number": "1095694324958", - "project_id": "mobapp-bb272", - "storage_bucket": "mobapp-bb272.appspot.com" + "project_number": "934365232760", + "project_id": "hmg-dr-app", + "storage_bucket": "hmg-dr-app.appspot.com" }, "client": [ { "client_info": { - "mobilesdk_app_id": "1:1095694324958:android:70a42e30fcc98ea33fde4f", + "mobilesdk_app_id": "1:934365232760:android:024b3569972f1c09f9778d", + "android_client_info": { + "package_name": "COM.HMG.HMGDR" + } + }, + "oauth_client": [ + { + "client_id": "934365232760-bobv1r1sn222le020jeni6u1bdbjdu1v.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCpYwrmuntOBdZv6GV6KEnLj8nQRvEnZ6I" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "934365232760-bobv1r1sn222le020jeni6u1bdbjdu1v.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "934365232760-57v2ld1qqulc4nt4o5pgjfbpc47fj3qf.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "COM.HMG.HMGDR" + } + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:934365232760:android:e0e185e68c0d7690f9778d", "android_client_info": { "package_name": "com.hmg.hmgDr" } }, "oauth_client": [ { - "client_id": "1095694324958-5psabq8tpbti0uqo8bt46atjtbas9uhr.apps.googleusercontent.com", + "client_id": "934365232760-bobv1r1sn222le020jeni6u1bdbjdu1v.apps.googleusercontent.com", "client_type": 3 } ], "api_key": [ { - "current_key": "AIzaSyCuPtf1hTikWXrp5OQIVfqO-TJWubI-Vd8" + "current_key": "AIzaSyCpYwrmuntOBdZv6GV6KEnLj8nQRvEnZ6I" } ], "services": { "appinvite_service": { "other_platform_oauth_client": [ { - "client_id": "1095694324958-5psabq8tpbti0uqo8bt46atjtbas9uhr.apps.googleusercontent.com", + "client_id": "934365232760-bobv1r1sn222le020jeni6u1bdbjdu1v.apps.googleusercontent.com", "client_type": 3 + }, + { + "client_id": "934365232760-57v2ld1qqulc4nt4o5pgjfbpc47fj3qf.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "COM.HMG.HMGDR" + } } ] } diff --git a/ios/GoogleService-Info .plist b/ios/GoogleService-Info .plist index 81c3af44..a29eac6d 100644 --- a/ios/GoogleService-Info .plist +++ b/ios/GoogleService-Info .plist @@ -3,21 +3,21 @@ CLIENT_ID - 1097451043303-ifgtu6ub88dlk5dmv5tm531a5s47gbre.apps.googleusercontent.com + 934365232760-en86g42ch3fgu7odnv5ka6kec8irg8d5.apps.googleusercontent.com REVERSED_CLIENT_ID - com.googleusercontent.apps.1097451043303-ifgtu6ub88dlk5dmv5tm531a5s47gbre + com.googleusercontent.apps.934365232760-en86g42ch3fgu7odnv5ka6kec8irg8d5 API_KEY - AIzaSyAKPayaNaI-2RN6S4PH5W9wYExmEgoBUvo + AIzaSyBtA8-oCZ5T4gkuTG7CucGr_d_7lakp4MM GCM_SENDER_ID - 1097451043303 + 934365232760 PLIST_VERSION 1 BUNDLE_ID - com.hmg.doctorApp + com.hmg.hmgDr PROJECT_ID - doctor-app-35ddc + hmg-dr-app STORAGE_BUCKET - doctor-app-35ddc.appspot.com + hmg-dr-app.appspot.com IS_ADS_ENABLED IS_ANALYTICS_ENABLED @@ -29,6 +29,6 @@ IS_SIGNIN_ENABLED GOOGLE_APP_ID - 1:1097451043303:ios:0e9b87e77dcf397d866542 + 1:934365232760:ios:61e01db91b41502bf9778d \ No newline at end of file diff --git a/ios/Runner/GoogleService-Info.plist b/ios/Runner/GoogleService-Info.plist index 81c3af44..a29eac6d 100644 --- a/ios/Runner/GoogleService-Info.plist +++ b/ios/Runner/GoogleService-Info.plist @@ -3,21 +3,21 @@ CLIENT_ID - 1097451043303-ifgtu6ub88dlk5dmv5tm531a5s47gbre.apps.googleusercontent.com + 934365232760-en86g42ch3fgu7odnv5ka6kec8irg8d5.apps.googleusercontent.com REVERSED_CLIENT_ID - com.googleusercontent.apps.1097451043303-ifgtu6ub88dlk5dmv5tm531a5s47gbre + com.googleusercontent.apps.934365232760-en86g42ch3fgu7odnv5ka6kec8irg8d5 API_KEY - AIzaSyAKPayaNaI-2RN6S4PH5W9wYExmEgoBUvo + AIzaSyBtA8-oCZ5T4gkuTG7CucGr_d_7lakp4MM GCM_SENDER_ID - 1097451043303 + 934365232760 PLIST_VERSION 1 BUNDLE_ID - com.hmg.doctorApp + com.hmg.hmgDr PROJECT_ID - doctor-app-35ddc + hmg-dr-app STORAGE_BUCKET - doctor-app-35ddc.appspot.com + hmg-dr-app.appspot.com IS_ADS_ENABLED IS_ANALYTICS_ENABLED @@ -29,6 +29,6 @@ IS_SIGNIN_ENABLED GOOGLE_APP_ID - 1:1097451043303:ios:0e9b87e77dcf397d866542 + 1:934365232760:ios:61e01db91b41502bf9778d \ No newline at end of file diff --git a/lib/config/config.dart b/lib/config/config.dart index 6c7cff87..d193bfac 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -5,8 +5,8 @@ const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; const BASE_URL_LIVE_CARE = 'https://livecare.hmg.com/'; -// const BASE_URL = 'https://hmgwebservices.com/'; -const BASE_URL = 'https://uat.hmgwebservices.com/'; +const BASE_URL = 'https://hmgwebservices.com/'; +// const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = "Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient"; From d301c2a3f40a1b4fcf25abbbd66374840462b1e0 Mon Sep 17 00:00:00 2001 From: Elham Rababh Date: Wed, 14 Jul 2021 12:17:01 +0300 Subject: [PATCH 064/289] add new and old part form examination --- lib/core/viewModel/SOAP_view_model.dart | 12 ++ .../objective/add_examination_page.dart | 8 +- .../objective/add_examination_widget.dart | 2 +- .../objective/examination_item_card.dart | 61 +++++++--- .../examinations_list_search_widget.dart | 6 +- .../objective/update_objective_page.dart | 112 ++++++++---------- 6 files changed, 119 insertions(+), 82 deletions(-) diff --git a/lib/core/viewModel/SOAP_view_model.dart b/lib/core/viewModel/SOAP_view_model.dart index 8b789cbc..eaa91131 100644 --- a/lib/core/viewModel/SOAP_view_model.dart +++ b/lib/core/viewModel/SOAP_view_model.dart @@ -26,6 +26,7 @@ import 'package:doctor_app_flutter/models/SOAP/post_chief_complaint_request_mode import 'package:doctor_app_flutter/models/SOAP/post_histories_request_model.dart'; import 'package:doctor_app_flutter/models/SOAP/post_physical_exam_request_model.dart'; import 'package:doctor_app_flutter/models/SOAP/post_progress_note_request_model.dart'; +import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_examination.dart'; import 'package:flutter/material.dart'; import '../../locator.dart'; @@ -466,4 +467,15 @@ class SOAPViewModel extends BaseViewModel { break; } } + + int getFirstIndexForOldExamination(List mySelectedExamination){ + Iterable examList = mySelectedExamination.where( + (element) => !element.isLocal); + + if (examList.length > 0) { + return mySelectedExamination.indexOf(examList.first); + } else + return -1; + + } } diff --git a/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart b/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart index 37f67ffc..935ac247 100644 --- a/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart +++ b/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart @@ -71,14 +71,14 @@ class _AddExaminationPageState extends State { masterList: model.physicalExaminationList, isServiceSelected: (master) => isServiceSelected(master), - removeExamination: (history) { + removeExamination: (exam) { setState(() { - widget.removeExamination(history); + widget.removeExamination(exam); }); }, - addHistory: (selectedExamination) { + addExamination: (selectedExamination) { widget.mySelectedExamination - .add(selectedExamination); + .insert(0,selectedExamination); // setState(() {}); }, ), diff --git a/lib/screens/patients/profile/soap_update/objective/add_examination_widget.dart b/lib/screens/patients/profile/soap_update/objective/add_examination_widget.dart index ce2bced1..2bb9b943 100644 --- a/lib/screens/patients/profile/soap_update/objective/add_examination_widget.dart +++ b/lib/screens/patients/profile/soap_update/objective/add_examination_widget.dart @@ -36,7 +36,7 @@ class AddExaminationWidget extends StatefulWidget { } class _AddExaminationWidgetState extends State { - int status = 3; + int status = 1; TextEditingController remarksController = TextEditingController(); MySelectedExamination examination = MySelectedExamination(); diff --git a/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart b/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart index 58dc7180..085089bd 100644 --- a/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart +++ b/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart @@ -4,6 +4,8 @@ import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_examin import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; class ExaminationItemCard extends StatelessWidget { @@ -42,21 +44,52 @@ class ExaminationItemCard extends StatelessWidget { )), ], ), - AppText( - !examination.isNormal - ? examination.isAbnormal - ? TranslationBase.of(context).abnormal - : TranslationBase.of(context).notExamined - : TranslationBase.of(context).normal, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - color: !examination.isNormal - ? examination.isAbnormal - ? Colors.red.shade800 - : Colors.grey.shade800 - : Colors.green.shade800, - fontSize: SizeConfig.textMultiplier * 1.8, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + AppText( + !examination.isNormal + ? examination.isAbnormal + ? TranslationBase.of(context).abnormal + : TranslationBase.of(context).notExamined + : TranslationBase.of(context).normal, + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + color: !examination.isNormal + ? examination.isAbnormal + ? Colors.red.shade800 + : Colors.grey.shade800 + : Colors.green.shade800, + fontSize: SizeConfig.textMultiplier * 1.8, + ), + if(!examination.notExamined) + InkWell( + child: Row( + children: [Container( + child: AppText( + examination.isLocal ?TranslationBase + .of(context) + .remove :TranslationBase + .of(context) + .notExamined, + fontSize: 15, + variant: "bodyText", + color: HexColor("#B8382C"),), + ), + Icon( + FontAwesomeIcons.times, + color: HexColor("#B8382C"), + size: 20, + ), + ], + ), + onTap: removeExamination, + ), + ], ), + + + SizedBox( height: 4, ), diff --git a/lib/screens/patients/profile/soap_update/objective/examinations_list_search_widget.dart b/lib/screens/patients/profile/soap_update/objective/examinations_list_search_widget.dart index ed7554e1..497bafa8 100644 --- a/lib/screens/patients/profile/soap_update/objective/examinations_list_search_widget.dart +++ b/lib/screens/patients/profile/soap_update/objective/examinations_list_search_widget.dart @@ -9,14 +9,14 @@ import 'add_examination_widget.dart'; class ExaminationsListSearchWidget extends StatefulWidget { final Function(MasterKeyModel) removeExamination; - final Function(MySelectedExamination) addHistory; + final Function(MySelectedExamination) addExamination; final bool Function(MasterKeyModel) isServiceSelected; final List masterList; final List mySelectedExamination; ExaminationsListSearchWidget( {this.removeExamination, - this.addHistory, + this.addExamination, this.isServiceSelected, this.masterList, this.mySelectedExamination}); @@ -62,7 +62,7 @@ class _ExaminationsListSearchWidgetState ...items.mapIndexed((index, item) { return AddExaminationWidget( item: item, - addExamination: widget.addHistory, + addExamination: widget.addExamination, removeExamination: widget.removeExamination, mySelectedExamination: widget.mySelectedExamination, isServiceSelected: widget.isServiceSelected, diff --git a/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart b/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart index ca2464b1..eb9a6002 100644 --- a/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart +++ b/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart @@ -97,7 +97,6 @@ class _UpdateObjectivePageState extends State { mySelectedExamination.add(tempEam); }); } - widget.changeLoadingState(false); }, builder: (_, model, w) => AppScaffold( @@ -130,8 +129,50 @@ class _UpdateObjectivePageState extends State { openExaminationList(context); }, ), + if (mySelectedExamination.isNotEmpty && + mySelectedExamination.first.isLocal) + Row( + children: [ + AppText( + "New", + fontWeight: FontWeight.w600, + fontFamily: 'Poppins', + color: Colors.blue, + ), + ], + ), Column( - children: mySelectedExamination.map((examination) { + children: mySelectedExamination + .sublist( + 0, + model.getFirstIndexForOldExamination( + mySelectedExamination)) + .map((examination) { + return ExaminationItemCard(examination, () { + removeExamination( + examination.selectedExamination); + }); + }).toList(), + ), + + if (mySelectedExamination.isNotEmpty && + model.getFirstIndexForOldExamination( + mySelectedExamination)>-1) + Row( + children: [ + AppText( + "old", + fontWeight: FontWeight.w600, + fontFamily: 'Poppins', + color: Colors.green, + ), + ], + ), + Column( + children: mySelectedExamination + .sublist(model.getFirstIndexForOldExamination( + mySelectedExamination)) + .map((examination) { return ExaminationItemCard(examination, () { removeExamination( examination.selectedExamination); @@ -276,10 +317,17 @@ class _UpdateObjectivePageState extends State { masterKey.id == element.selectedExamination.id && masterKey.typeId == element.selectedExamination.typeId); - if (history.length > 0) + if (history.length > 0) { setState(() { - mySelectedExamination.remove(history.first); + if (history.first.isLocal) { + mySelectedExamination.remove(history.first); + } else { + history.first.notExamined = true; + history.first.isNormal = false; + history.first.isAbnormal = false; + } }); + } } openExaminationList(BuildContext context) { @@ -298,59 +346,3 @@ class _UpdateObjectivePageState extends State { ); } } - -class AddExaminationDailog extends StatefulWidget { - final List mySelectedExamination; - final Function addSelectedExamination; - final Function(MasterKeyModel) removeExamination; - - const AddExaminationDailog( - {Key key, - this.mySelectedExamination, - this.addSelectedExamination, - this.removeExamination}) - : super(key: key); - - @override - _AddExaminationDailogState createState() => _AddExaminationDailogState(); -} - -class _AddExaminationDailogState extends State { - @override - Widget build(BuildContext context) { - return FractionallySizedBox( - heightFactor: 0.7, - child: BaseView( - onModelReady: (model) async { - if (model.physicalExaminationList.length == 0) { - await model - .getMasterLookup(MasterKeysService.PhysicalExamination); - } - }, - builder: (_, model, w) => AppScaffold( - baseViewModel: model, - isShowAppBar: false, - body: Center( - child: Container( - child: FractionallySizedBox( - widthFactor: 0.9, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 16, - ), - AppText( - TranslationBase.of(context).physicalSystemExamination, - fontWeight: FontWeight.bold, - fontSize: 16, - ), - SizedBox( - height: 16, - ), - ]), - ))), - )), - ); - } -} From 7e578823491aea719e89e25fdcf4e7e1fbcf5719 Mon Sep 17 00:00:00 2001 From: Elham Rababh Date: Wed, 14 Jul 2021 17:56:03 +0300 Subject: [PATCH 065/289] fix design issues on first step form create episode --- .../assessment/add_assessment_details.dart | 86 ++++------ .../objective/examination_item_card.dart | 48 ++---- .../shared_soap_widgets/SOAP_open_items.dart | 14 +- .../shared_soap_widgets/SOAP_step_header.dart | 11 +- .../bottom_sheet_dialog_button.dart | 49 ++++++ .../expandable_SOAP_widget.dart | 6 +- .../shared_soap_widgets/remove_button.dart | 38 +++++ .../profile/soap_update/soap_utils.dart | 6 +- .../subjective/allergies/add_allergies.dart | 47 +----- .../subjective/allergies/allergies_item.dart | 32 ++-- ..._key_checkbox_search_allergies_widget.dart | 6 +- .../allergies/update_allergies_widget.dart | 158 +++++++++--------- .../history/add_history_dialog.dart | 54 ++---- .../history/update_history_widget.dart | 83 ++++----- .../subjective/medication/add_medication.dart | 71 +++----- lib/widgets/shared/app_texts_widget.dart | 5 +- .../master_key_checkbox_search_widget.dart | 28 ++-- 17 files changed, 338 insertions(+), 404 deletions(-) create mode 100644 lib/screens/patients/profile/soap_update/shared_soap_widgets/bottom_sheet_dialog_button.dart create mode 100644 lib/screens/patients/profile/soap_update/shared_soap_widgets/remove_button.dart diff --git a/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart b/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart index cc8be61f..4549ae3d 100644 --- a/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart +++ b/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart @@ -11,6 +11,7 @@ import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_asseme import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/bottom_sheet_dialog_button.dart'; import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/bottom_sheet_title.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; @@ -372,63 +373,34 @@ class _AddAssessmentDetailsState extends State { ), ), ), - bottomSheet: model.state == ViewState.Busy?Container(height: 0,):Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all( - Radius.circular(0.0), - ), - border: Border.all(color: HexColor('#707070'), width: 0), - ), - height: MediaQuery.of(context).size.height * 0.1, - width: double.infinity, - child: Column( - children: [ - SizedBox( - height: 10, - ), - Container( - child: FractionallySizedBox( - widthFactor: .80, - child: Center( - child: AppButton( - fontWeight: FontWeight.w700, - color: Colors.green, - title: (widget.isUpdate - ? 'Update Assessment Details' - : 'Add Assessment Details'), - loading: model.state == ViewState.BusyLocal, - onPressed: () async { - setState(() { - isFormSubmitted = true; - }); - widget.mySelectedAssessment.remark = - remarkController.text; - widget.mySelectedAssessment.appointmentId = - int.parse(appointmentIdController.text); - if (widget.mySelectedAssessment - .selectedDiagnosisCondition != - null && - widget.mySelectedAssessment - .selectedDiagnosisType != - null && - widget.mySelectedAssessment.selectedICD != null) { - await submitAssessment( - isUpdate: widget.isUpdate, - model: model, - mySelectedAssessment: - widget.mySelectedAssessment); - } - }, - ), - ), - ), - ), - SizedBox( - height: 5, - ), - ], - ), + bottomSheet: model.state == ViewState.Busy?Container(height: 0,): + + BottomSheetDialogButton( + label: TranslationBase.of(context) + .addMedication + .toUpperCase(), + onTap: () async { + setState(() { + isFormSubmitted = true; + }); + widget.mySelectedAssessment.remark = + remarkController.text; + widget.mySelectedAssessment.appointmentId = + int.parse(appointmentIdController.text); + if (widget.mySelectedAssessment + .selectedDiagnosisCondition != + null && + widget.mySelectedAssessment + .selectedDiagnosisType != + null && + widget.mySelectedAssessment.selectedICD != null) { + await submitAssessment( + isUpdate: widget.isUpdate, + model: model, + mySelectedAssessment: + widget.mySelectedAssessment); + } + }, ), ), ), diff --git a/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart b/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart index 085089bd..c52f1d4a 100644 --- a/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart +++ b/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart @@ -1,6 +1,7 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_examination.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/remove_button.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/material.dart'; @@ -62,45 +63,26 @@ class ExaminationItemCard extends StatelessWidget { : Colors.green.shade800, fontSize: SizeConfig.textMultiplier * 1.8, ), - if(!examination.notExamined) - InkWell( - child: Row( - children: [Container( - child: AppText( - examination.isLocal ?TranslationBase - .of(context) - .remove :TranslationBase - .of(context) - .notExamined, - fontSize: 15, - variant: "bodyText", - color: HexColor("#B8382C"),), - ), - Icon( - FontAwesomeIcons.times, - color: HexColor("#B8382C"), - size: 20, - ), - ], + if (!examination.notExamined) + RemoveButton( + label: examination.isLocal + ? TranslationBase.of(context).remove + : TranslationBase.of(context).notExamined, + onTap: removeExamination, ), - onTap: removeExamination, - ), ], ), - - - SizedBox( height: 4, ), - if(examination.remark.isNotEmpty) - AppText( - examination.remark, - fontWeight: FontWeight.normal, - fontFamily: 'Poppins', - color: Color(0xFF575757), - fontSize: SizeConfig.textMultiplier * 1.8, - ), + if (examination.remark.isNotEmpty) + AppText( + examination.remark, + fontWeight: FontWeight.normal, + fontFamily: 'Poppins', + color: Color(0xFF575757), + fontSize: SizeConfig.textMultiplier * 1.8, + ), ], ), ); diff --git a/lib/screens/patients/profile/soap_update/shared_soap_widgets/SOAP_open_items.dart b/lib/screens/patients/profile/soap_update/shared_soap_widgets/SOAP_open_items.dart index 31a501ce..d0819b76 100644 --- a/lib/screens/patients/profile/soap_update/shared_soap_widgets/SOAP_open_items.dart +++ b/lib/screens/patients/profile/soap_update/shared_soap_widgets/SOAP_open_items.dart @@ -36,19 +36,23 @@ class SOAPOpenItems extends StatelessWidget { AppText( "$label", fontSize:15, - color: Colors.black, - fontWeight: FontWeight.w600, + fontWeight: FontWeight.w700, + color: Color(0xFF2E303A), + letterSpacing:-0.44 , ), AppText( "${TranslationBase.of(context).searchHere}", - fontSize:13, - color: Colors.grey.shade700, + fontSize:14, + fontWeight: FontWeight.w500, + color: Color(0xFF575757), + letterSpacing:-0.56 , ), ], )), Icon( Icons.add_box_rounded, - size: 25, + size: 28, + color: Color(0xFF2E303A), ) ], ), diff --git a/lib/screens/patients/profile/soap_update/shared_soap_widgets/SOAP_step_header.dart b/lib/screens/patients/profile/soap_update/shared_soap_widgets/SOAP_step_header.dart index 85614b6d..f345666f 100644 --- a/lib/screens/patients/profile/soap_update/shared_soap_widgets/SOAP_step_header.dart +++ b/lib/screens/patients/profile/soap_update/shared_soap_widgets/SOAP_step_header.dart @@ -21,12 +21,17 @@ class SOAPStepHeader extends StatelessWidget { SizedBox(height: 15,), AppText( TranslationBase.of(context).createNew, - fontSize: 14, - fontWeight: FontWeight.w500, + fontSize: 12, + fontWeight: FontWeight.w700, + letterSpacing:-0.72, + color: Color(0xFF2E303A), + ), AppText(TranslationBase.of(context).episode, - fontSize: 26, + fontSize: 24, fontWeight: FontWeight.bold, + letterSpacing:-1.44, + color: Color(0xFF2E303A), ), Container( color: Theme.of(context).scaffoldBackgroundColor, diff --git a/lib/screens/patients/profile/soap_update/shared_soap_widgets/bottom_sheet_dialog_button.dart b/lib/screens/patients/profile/soap_update/shared_soap_widgets/bottom_sheet_dialog_button.dart new file mode 100644 index 00000000..d6cab800 --- /dev/null +++ b/lib/screens/patients/profile/soap_update/shared_soap_widgets/bottom_sheet_dialog_button.dart @@ -0,0 +1,49 @@ +import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:hexcolor/hexcolor.dart'; + +class BottomSheetDialogButton extends StatelessWidget { + final Function onTap; + final String label; + + const BottomSheetDialogButton({Key key, this.onTap, this.label}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(0.0), + ), + border: Border.all(color: HexColor('#EFEFEF'), width: 1), + ), + height: MediaQuery.of(context).size.height * 0.1, + width: double.infinity, + child: Column( + children: [ + SizedBox( + height: 10, + ), + Container( + child: FractionallySizedBox( + widthFactor: .80, + child: Center( + child: AppButton( + title: label, + padding: 10, + color: Color(0xFF359846), + onPressed: onTap, + ), + ), + ), + ), + SizedBox( + height: 5, + ), + ], + ), + ); + } +} diff --git a/lib/screens/patients/profile/soap_update/shared_soap_widgets/expandable_SOAP_widget.dart b/lib/screens/patients/profile/soap_update/shared_soap_widgets/expandable_SOAP_widget.dart index d4666428..2dcce4ae 100644 --- a/lib/screens/patients/profile/soap_update/shared_soap_widgets/expandable_SOAP_widget.dart +++ b/lib/screens/patients/profile/soap_update/shared_soap_widgets/expandable_SOAP_widget.dart @@ -41,8 +41,10 @@ class ExpandableSOAPWidget extends StatelessWidget { children: [ AppText(headerTitle, variant: isExpanded ? "bodyText" : '', - fontSize: 15, - color: Colors.black), + fontSize: 16, + letterSpacing:-0.64, + fontWeight: FontWeight.w700, + color: Color(0xFF2E303A),), if(isRequired) Icon( FontAwesomeIcons.asterisk, diff --git a/lib/screens/patients/profile/soap_update/shared_soap_widgets/remove_button.dart b/lib/screens/patients/profile/soap_update/shared_soap_widgets/remove_button.dart new file mode 100644 index 00000000..bff3d4a8 --- /dev/null +++ b/lib/screens/patients/profile/soap_update/shared_soap_widgets/remove_button.dart @@ -0,0 +1,38 @@ + +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:hexcolor/hexcolor.dart'; + +class RemoveButton extends StatelessWidget { + final Function onTap; + final String label; + + const RemoveButton({Key key, this.onTap, this.label}) : super(key: key); + + @override + Widget build(BuildContext context) { + return InkWell( + child: Row( + children: [ + Container( + child: AppText( + label??TranslationBase.of(context).remove, + fontSize: 12, + fontWeight: FontWeight.w700, + color: HexColor("#D02127"), + letterSpacing:-0.48, + ), + ), + Icon( + FontAwesomeIcons.times, + color: HexColor("#D02127"), + size: 16, + ), + ], + ), + onTap: onTap, + ); + } +} diff --git a/lib/screens/patients/profile/soap_update/soap_utils.dart b/lib/screens/patients/profile/soap_update/soap_utils.dart index 34bf4236..455b5439 100644 --- a/lib/screens/patients/profile/soap_update/soap_utils.dart +++ b/lib/screens/patients/profile/soap_update/soap_utils.dart @@ -5,7 +5,7 @@ import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_histor class SoapUtils { static MySelectedHistory generateMySelectedHistory( - {history, isChecked, remark, isLocal}) { + {history, isChecked, remark, isLocal = true}) { MySelectedHistory mySelectedHistory = MySelectedHistory( selectedHistory: history, isChecked: isChecked, @@ -19,7 +19,7 @@ class SoapUtils { allergySeverity, isChecked, remark, - isLocal, + isLocal = true, int createdBy, bool isExpanded}) { MySelectedAllergy mySelectedAllergy = MySelectedAllergy( @@ -38,7 +38,7 @@ class SoapUtils { allergySeverity, isChecked, remark, - isLocal, + isLocal = true, isNormal, createdBy, createdOn, diff --git a/lib/screens/patients/profile/soap_update/subjective/allergies/add_allergies.dart b/lib/screens/patients/profile/soap_update/subjective/allergies/add_allergies.dart index 9f002d65..44eae2b8 100644 --- a/lib/screens/patients/profile/soap_update/subjective/allergies/add_allergies.dart +++ b/lib/screens/patients/profile/soap_update/subjective/allergies/add_allergies.dart @@ -5,6 +5,7 @@ import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_allergy.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/bottom_sheet_dialog_button.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; @@ -120,7 +121,6 @@ class _AddAllergiesState extends State { addAllergyLocally(mySelectedAllergy); }, addSelectedAllergy: () { - setState(() { widget .addAllergiesFun(myAllergiesListLocal); @@ -146,43 +146,13 @@ class _AddAllergiesState extends State { ? Container( height: 0, ) - : Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all( - Radius.circular(0.0), - ), - border: Border.all(color: HexColor('#707070'), width: 0), - ), - height: MediaQuery.of(context).size.height * 0.1, - width: double.infinity, - child: Column( - children: [ - SizedBox( - height: 10, - ), - Container( - child: FractionallySizedBox( - widthFactor: .80, - child: Center( - child: AppButton( - title: TranslationBase.of(context).addAllergies, - padding: 10, - color: Color(0xFF359846), - onPressed: () { - setState(() { - widget.addAllergiesFun(myAllergiesListLocal); - }); - }, - ), - ), - ), - ), - SizedBox( - height: 5, - ), - ], - ), + : BottomSheetDialogButton( + label: TranslationBase.of(context).addAllergies, + onTap: () { + setState(() { + widget.addAllergiesFun(myAllergiesListLocal); + }); + }, ), ), ), @@ -244,3 +214,4 @@ class _AddAllergiesState extends State { } } } + diff --git a/lib/screens/patients/profile/soap_update/subjective/allergies/allergies_item.dart b/lib/screens/patients/profile/soap_update/subjective/allergies/allergies_item.dart index 08753bec..00606f68 100644 --- a/lib/screens/patients/profile/soap_update/subjective/allergies/allergies_item.dart +++ b/lib/screens/patients/profile/soap_update/subjective/allergies/allergies_item.dart @@ -74,22 +74,19 @@ class _AddAllergiesItemState extends State { }), InkWell( onTap:onTapItem, - child: Padding( - padding: - const EdgeInsets.symmetric(horizontal: 10, vertical: 0), - child: Container( - child: AppText( - projectViewModel.isArabic - ? widget.item.nameAr != "" - ? widget.item.nameAr - : widget.item.nameEn - : widget.item.nameEn, - color: Color(0xFF575757), - fontSize: 16, - fontWeight: FontWeight.w600, - ), - width: MediaQuery.of(context).size.width * 0.55, + child: Container( + child: AppText( + projectViewModel.isArabic + ? widget.item.nameAr != "" + ? widget.item.nameAr + : widget.item.nameEn + : widget.item.nameEn, + color: Color(0xFF575757), + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.56, ), + width: MediaQuery.of(context).size.width * 0.55, ), ), ], @@ -106,8 +103,11 @@ class _AddAllergiesItemState extends State { child: Icon((mySelectedAllergy != null ? mySelectedAllergy.isExpanded : false) + ? EvaIcons.arrowIosUpwardOutline - : EvaIcons.arrowIosDownwardOutline)) + : EvaIcons.arrowIosDownwardOutline, + color: Color(0xFF575757) , + ),) ], ), bodyWidget: Center( diff --git a/lib/screens/patients/profile/soap_update/subjective/allergies/master_key_checkbox_search_allergies_widget.dart b/lib/screens/patients/profile/soap_update/subjective/allergies/master_key_checkbox_search_allergies_widget.dart index 8da1799b..3f6f694f 100644 --- a/lib/screens/patients/profile/soap_update/subjective/allergies/master_key_checkbox_search_allergies_widget.dart +++ b/lib/screens/patients/profile/soap_update/subjective/allergies/master_key_checkbox_search_allergies_widget.dart @@ -43,7 +43,7 @@ class MasterKeyCheckboxSearchAllergiesWidget extends StatefulWidget { class _MasterKeyCheckboxSearchAllergiesWidgetState extends State { List items = List(); - + TextEditingController filteredSearchController = TextEditingController(); @override void initState() { @@ -67,13 +67,11 @@ class _MasterKeyCheckboxSearchAllergiesWidgetState child: Column( children: [ AppTextFieldCustom( - // height: - // MediaQuery.of(context).size.height * 0.070, hintText: TranslationBase.of(context).selectAllergy, isTextFieldHasSuffix: true, hasBorder: false, - // controller: filteredSearchController, + controller: filteredSearchController, onChanged: (value) { filterSearchResults(value); }, diff --git a/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart b/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart index 32c54f52..1984e3f9 100644 --- a/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart +++ b/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart @@ -1,12 +1,11 @@ import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_allergy.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/remove_button.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/divider_with_spaces_around.dart'; import 'package:flutter/material.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; import '../../shared_soap_widgets/SOAP_open_items.dart'; @@ -14,7 +13,7 @@ import 'add_allergies.dart'; // ignore: must_be_immutable class UpdateAllergiesWidget extends StatefulWidget { - List myAllergiesList; + List myAllergiesList; UpdateAllergiesWidget({Key key, this.myAllergiesList}); @@ -27,28 +26,28 @@ class _UpdateAllergiesWidgetState extends State { Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); changeAllState() { - setState(() { - - }); + setState(() {}); } return Column( children: [ - SOAPOpenItems(label: "${TranslationBase.of(context).addAllergies}",onTap: () { - openAllergiesList(context, changeAllState, removeAllergy); - },), + SOAPOpenItems( + label: "${TranslationBase.of(context).addAllergies}", + onTap: () { + openAllergiesList(context, changeAllState, removeAllergy); + }, + ), SizedBox( height: 20, ), Container( - margin: - EdgeInsets.only(left: 15, right: 15, top: 15), + margin: EdgeInsets.only(left: 15, right: 15, top: 15), child: Column( children: widget.myAllergiesList.map((selectedAllergy) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -61,53 +60,41 @@ class _UpdateAllergiesWidgetState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( - projectViewModel.isArabic - ? selectedAllergy.selectedAllergy.nameAr - : selectedAllergy.selectedAllergy.nameEn - .toUpperCase(), - textDecoration: selectedAllergy.isChecked - ? null - : TextDecoration.lineThrough, - bold: true, - color: Color(0xFF2B353E)), + projectViewModel.isArabic + ? selectedAllergy.selectedAllergy.nameAr + : selectedAllergy.selectedAllergy.nameEn + .toUpperCase(), + textDecoration: selectedAllergy.isChecked + ? null + : TextDecoration.lineThrough, + bold: true, + color: Color(0xFF2B353E), + fontSize: 12, + fontWeight: FontWeight.w700, + letterSpacing: -0.48, + // fontHeight:0.18 , + ), AppText( - projectViewModel.isArabic - ? selectedAllergy.selectedAllergySeverity - .nameAr - : selectedAllergy.selectedAllergySeverity - .nameEn - .toUpperCase(), - textDecoration: selectedAllergy.isChecked - ? null - : TextDecoration.lineThrough, - color: Color(0xFFCC9B14)), + projectViewModel.isArabic + ? selectedAllergy + .selectedAllergySeverity.nameAr + : selectedAllergy + .selectedAllergySeverity.nameEn + .toUpperCase(), + textDecoration: selectedAllergy.isChecked + ? null + : TextDecoration.lineThrough, + color: Color(0xFFCC9B14), + fontSize: 10, + fontWeight: FontWeight.w700, + letterSpacing: -0.48, + ), ], ), - width: MediaQuery - .of(context) - .size - .width * 0.5, + width: MediaQuery.of(context).size.width * 0.5, ), - if (selectedAllergy.isChecked) - InkWell( - child: Row( - children: [Container( - child: AppText( - TranslationBase - .of(context) - .remove, - fontSize: 15, - variant: "bodyText", - color: HexColor("#B8382C"),), - ), - Icon( - FontAwesomeIcons.times, - color: HexColor("#B8382C"), - size: 20, - ), - ], - ), + RemoveButton( onTap: () => removeAllergy(selectedAllergy), ) ], @@ -120,8 +107,10 @@ class _UpdateAllergiesWidgetState extends State { width: MediaQuery.of(context).size.width * 0.55, child: AppText( selectedAllergy.remark ?? '', + color: Color(0xFF575757), fontSize: 10, - color: Colors.grey, + fontWeight: FontWeight.w700, + letterSpacing: -0.4, ), ), ], @@ -143,15 +132,17 @@ class _UpdateAllergiesWidgetState extends State { removeAllergy(MySelectedAllergy mySelectedAllergy) { List allergy = - // ignore: missing_return - widget.myAllergiesList.where((element) => - mySelectedAllergy.selectedAllergySeverity.id == - element.selectedAllergySeverity.id && - mySelectedAllergy.selectedAllergy.id == element.selectedAllergy.id - ).toList(); + // ignore: missing_return + widget.myAllergiesList + .where((element) => + mySelectedAllergy.selectedAllergySeverity.id == + element.selectedAllergySeverity.id && + mySelectedAllergy.selectedAllergy.id == + element.selectedAllergy.id) + .toList(); if (allergy.length > 0) { - if(allergy.first.isLocal) { + if (allergy.first.isLocal) { setState(() { widget.myAllergiesList.remove(allergy.first); }); @@ -162,7 +153,8 @@ class _UpdateAllergiesWidgetState extends State { } } - openAllergiesList(BuildContext context, Function changeParentState, removeAllergy) { + openAllergiesList( + BuildContext context, Function changeParentState, removeAllergy) { showModalBottomSheet( backgroundColor: Colors.white, isScrollControlled: true, @@ -170,7 +162,7 @@ class _UpdateAllergiesWidgetState extends State { context: context, builder: (context) { return AddAllergies( - myAllergiesList: widget.myAllergiesList, + myAllergiesList: widget.myAllergiesList, addAllergiesFun: (List mySelectedAllergy) { bool isAllDataFilled = true; mySelectedAllergy.forEach((element) { @@ -181,19 +173,28 @@ class _UpdateAllergiesWidgetState extends State { }); if (isAllDataFilled) { mySelectedAllergy.forEach((element) { - if ((widget.myAllergiesList.singleWhere((it) => it.selectedAllergy.id == element.selectedAllergy.id, - orElse: () => null)) == null) { + if ((widget.myAllergiesList.singleWhere( + (it) => + it.selectedAllergy.id == + element.selectedAllergy.id, + orElse: () => null)) == + null) { widget.myAllergiesList.add(element); } }); /// remove items. - List removedList= []; + List removedList = []; widget.myAllergiesList.forEach((element) { - if ((mySelectedAllergy.singleWhere((it) => it.selectedAllergy.id == element.selectedAllergy.id, - orElse: () => null)) == null) { + if ((mySelectedAllergy.singleWhere( + (it) => + it.selectedAllergy.id == + element.selectedAllergy.id, + orElse: () => null)) == + null) { removedList.add(element); - }}); + } + }); removedList.forEach((element) { removeAllergy(element); @@ -201,18 +202,11 @@ class _UpdateAllergiesWidgetState extends State { changeParentState(); Navigator.of(context).pop(); } else { - Helpers.showErrorToast(TranslationBase - .of(context) - .requiredMsg); + Helpers.showErrorToast( + TranslationBase.of(context).requiredMsg); } }); }); } - } - - - - - diff --git a/lib/screens/patients/profile/soap_update/subjective/history/add_history_dialog.dart b/lib/screens/patients/profile/soap_update/subjective/history/add_history_dialog.dart index 566eeda4..c089bd24 100644 --- a/lib/screens/patients/profile/soap_update/subjective/history/add_history_dialog.dart +++ b/lib/screens/patients/profile/soap_update/subjective/history/add_history_dialog.dart @@ -4,6 +4,7 @@ import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_history.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/bottom_sheet_dialog_button.dart'; import 'package:doctor_app_flutter/screens/patients/profile/soap_update/soap_utils.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; @@ -59,8 +60,8 @@ class _AddHistoryDialogState extends State { builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, - appBar: BottomSheetTitle( - title: TranslationBase.of(context).addHistory), + appBar: + BottomSheetTitle(title: TranslationBase.of(context).addHistory), body: Center( child: Container( child: Column( @@ -166,42 +167,11 @@ class _AddHistoryDialogState extends State { ? Container( height: 0, ) - : Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all( - Radius.circular(0.0), - ), - border: Border.all(color: HexColor('#707070'), width: 0), - ), - height: MediaQuery.of(context).size.height * 0.1, - width: double.infinity, - child: Column( - children: [ - SizedBox( - height: 10, - ), - Container( - child: FractionallySizedBox( - widthFactor: .80, - child: Center( - child: AppButton( - title: TranslationBase.of(context) - .addSelectedHistories, - padding: 10, - color: Color(0xFF359846), - onPressed: () { - widget.addSelectedHistories(); - }, - ), - ), - ), - ), - SizedBox( - height: 5, - ), - ], - ), + : BottomSheetDialogButton( + label: TranslationBase.of(context).addSelectedHistories, + onTap: () { + widget.addSelectedHistories(); + }, ), ), )); @@ -216,9 +186,11 @@ class _AddHistoryDialogState extends State { if (myhistory.isEmpty) { setState(() { - MySelectedHistory mySelectedHistory = SoapUtils.generateMySelectedHistory(remark: history.remarks ?? "", - history: history, - isChecked: true); + MySelectedHistory mySelectedHistory = + SoapUtils.generateMySelectedHistory( + remark: history.remarks ?? "", + history: history, + isChecked: true); widget.myHistoryList.add(mySelectedHistory); }); diff --git a/lib/screens/patients/profile/soap_update/subjective/history/update_history_widget.dart b/lib/screens/patients/profile/soap_update/subjective/history/update_history_widget.dart index cede4e15..2f17d332 100644 --- a/lib/screens/patients/profile/soap_update/subjective/history/update_history_widget.dart +++ b/lib/screens/patients/profile/soap_update/subjective/history/update_history_widget.dart @@ -1,6 +1,7 @@ import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_history.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/remove_button.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/material.dart'; @@ -40,17 +41,17 @@ class _UpdateHistoryWidgetState extends State ProjectViewModel projectViewModel = Provider.of(context); return Column( children: [ - - SOAPOpenItems(label: "${TranslationBase.of(context).addHistory}",onTap: () { - openHistoryList(context); - - },), + SOAPOpenItems( + label: "${TranslationBase.of(context).addHistory}", + onTap: () { + openHistoryList(context); + }, + ), SizedBox( height: 20, ), Container( - margin: - EdgeInsets.only(left: 15, right: 15, top: 15), + margin: EdgeInsets.only(left: 15, right: 15, top: 15), child: Column( children: widget.myHistoryList.map((myHistory) { return Column( @@ -60,42 +61,21 @@ class _UpdateHistoryWidgetState extends State children: [ Container( child: AppText( - projectViewModel.isArabic - ? myHistory.selectedHistory.nameAr - : myHistory.selectedHistory.nameEn, - fontSize: 15, - textDecoration: myHistory.isChecked - ? null - : TextDecoration.lineThrough, - color: Colors.black), - width: MediaQuery - .of(context) - .size - .width * 0.5, + projectViewModel.isArabic + ? myHistory.selectedHistory.nameAr + : myHistory.selectedHistory.nameEn, + textDecoration: myHistory.isChecked + ? null + : TextDecoration.lineThrough, + color: Color(0xFF2B353E), + fontSize: 12, + fontWeight: FontWeight.w700, + letterSpacing: -0.48, + ), + width: MediaQuery.of(context).size.width * 0.5, ), if (myHistory.isChecked) - InkWell( - child: Row( - children: [ - Container( - child: AppText( - TranslationBase - .of(context) - .remove, - fontSize: 15, - variant: "bodyText", - textDecoration: myHistory.isChecked - ? null - : TextDecoration.lineThrough, - color: HexColor("#B8382C"),), - ), - Icon( - FontAwesomeIcons.times, - color: HexColor("#B8382C"), - size: 17, - ), - ], - ), + RemoveButton( onTap: () => removeHistory(myHistory.selectedHistory), ) ], @@ -114,17 +94,15 @@ class _UpdateHistoryWidgetState extends State removeHistory(MasterKeyModel historyKey) { List history = - // ignore: missing_return - widget.myHistoryList.where((element) => - historyKey.id == - element.selectedHistory.id && - historyKey.typeId == - element.selectedHistory.typeId - ).toList(); - + // ignore: missing_return + widget.myHistoryList + .where((element) => + historyKey.id == element.selectedHistory.id && + historyKey.typeId == element.selectedHistory.typeId) + .toList(); if (history.length > 0) { - if(history.first.isLocal) { + if (history.first.isLocal) { setState(() { widget.myHistoryList.remove(history.first); }); @@ -133,9 +111,7 @@ class _UpdateHistoryWidgetState extends State history[0].isChecked = false; }); } - } - } openHistoryList(BuildContext context) { @@ -162,6 +138,3 @@ class _UpdateHistoryWidgetState extends State }); } } - - - diff --git a/lib/screens/patients/profile/soap_update/subjective/medication/add_medication.dart b/lib/screens/patients/profile/soap_update/subjective/medication/add_medication.dart index 11e4fa72..c80251f8 100644 --- a/lib/screens/patients/profile/soap_update/subjective/medication/add_medication.dart +++ b/lib/screens/patients/profile/soap_update/subjective/medication/add_medication.dart @@ -7,6 +7,7 @@ import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/bottom_sheet_dialog_button.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; @@ -386,55 +387,27 @@ class _AddMedicationState extends State { ]), ), ), - bottomSheet:model.state == ViewState.Busy?Container(height: 0,): Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all( - Radius.circular(10.0), - ), - border: Border.all(color: HexColor('#707070'), width: 0.30), - ), - height: MediaQuery.of(context).size.height * 0.1, - width: double.infinity, - child: Column( - children: [ - SizedBox( - height: 10, - ), - Container( - child: FractionallySizedBox( - widthFactor: .80, - child: Center( - child: AppButton( - title: TranslationBase.of(context) - .addMedication - .toUpperCase(), - color: Color(0xFF359846), - onPressed: () { - setState(() { - isFormSubmitted = true; - }); - if (_selectedMedication != null && - _selectedMedicationDose != null && - _selectedMedicationStrength != null && - _selectedMedicationRoute != null && - _selectedMedicationFrequency != null) { - widget.medicationController.text = widget - .medicationController.text + - '${_selectedMedication.description} (${TranslationBase.of(context).doseTime} ) ${doseController.text} (${TranslationBase.of(context).strength}) ${strengthController.text} (${TranslationBase.of(context).route}) ${routeController.text} (${TranslationBase.of(context).frequency}) ${frequencyController.text} \n \n'; - Navigator.of(context).pop(); - } - }, - ), - ), - ), - ), - SizedBox( - height: 5, - ), - ], - ), - ), + bottomSheet:model.state == ViewState.Busy?Container(height: 0,): + BottomSheetDialogButton( + label: TranslationBase.of(context) + .addMedication + .toUpperCase(), + onTap: () { + setState(() { + isFormSubmitted = true; + }); + if (_selectedMedication != null && + _selectedMedicationDose != null && + _selectedMedicationStrength != null && + _selectedMedicationRoute != null && + _selectedMedicationFrequency != null) { + widget.medicationController.text = widget + .medicationController.text + + '${_selectedMedication.description} (${TranslationBase.of(context).doseTime} ) ${doseController.text} (${TranslationBase.of(context).strength}) ${strengthController.text} (${TranslationBase.of(context).route}) ${routeController.text} (${TranslationBase.of(context).frequency}) ${frequencyController.text} \n \n'; + Navigator.of(context).pop(); + } + }, + ) ), ), ); diff --git a/lib/widgets/shared/app_texts_widget.dart b/lib/widgets/shared/app_texts_widget.dart index 48661a32..4bf89d4e 100644 --- a/lib/widgets/shared/app_texts_widget.dart +++ b/lib/widgets/shared/app_texts_widget.dart @@ -18,6 +18,7 @@ class AppText extends StatefulWidget { final double marginRight; final double marginBottom; final double marginLeft; + final double letterSpacing; final TextAlign textAlign; final bool bold; final bool regular; @@ -55,7 +56,7 @@ class AppText extends StatefulWidget { this.allowExpand = true, this.visibility = true, this.textOverflow, - this.textDecoration, + this.textDecoration, this.letterSpacing, }); @override @@ -132,7 +133,7 @@ class _AppTextState extends State { widget.color != null ? widget.color : Colors.black, fontSize: widget.fontSize ?? _getFontSize(), letterSpacing: - widget.variant == "overline" ? 1.5 : null, + widget.letterSpacing??(widget.variant == "overline" ? 1.5 : null), fontWeight: widget.fontWeight ?? _getFontWeight(), fontFamily: widget.fontFamily ?? 'Poppins', decoration: widget.textDecoration, diff --git a/lib/widgets/shared/master_key_checkbox_search_widget.dart b/lib/widgets/shared/master_key_checkbox_search_widget.dart index 3a0a1525..780f82ca 100644 --- a/lib/widgets/shared/master_key_checkbox_search_widget.dart +++ b/lib/widgets/shared/master_key_checkbox_search_widget.dart @@ -40,6 +40,8 @@ class MasterKeyCheckboxSearchWidget extends StatefulWidget { class _MasterKeyCheckboxSearchWidgetState extends State { List items = List(); + TextEditingController filteredSearchController = TextEditingController(); + @override void initState() { @@ -77,7 +79,7 @@ class _MasterKeyCheckboxSearchWidgetState hintText: TranslationBase.of(context).searchHistory, isTextFieldHasSuffix: true, hasBorder: false, - // controller: filteredSearchController, + controller: filteredSearchController, onChanged: (value) { filterSearchResults(value); }, @@ -123,19 +125,17 @@ class _MasterKeyCheckboxSearchWidgetState }); }), Expanded( - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 10, vertical: 0), - child: AppText( - projectViewModel.isArabic - ? historyInfo.nameAr != "" - ? historyInfo.nameAr - : historyInfo.nameEn - : historyInfo.nameEn, - color: Color(0xFF575757), - fontSize: 16, - fontWeight: FontWeight.w600, - ), + child: AppText( + projectViewModel.isArabic + ? historyInfo.nameAr != "" + ? historyInfo.nameAr + : historyInfo.nameEn + : historyInfo.nameEn, + + color: Color(0xFF575757), + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.56, ), ), ], From 3b1a493d7632b4855638bd9c886f689d28a29e9b Mon Sep 17 00:00:00 2001 From: Elham Rababh Date: Thu, 15 Jul 2021 12:53:16 +0300 Subject: [PATCH 066/289] fix design issues on create episode and prevent exam from keep it state --- .../assessment/add_assessment_details.dart | 6 +- .../assessment/update_assessment_page.dart | 69 +++++++++--------- .../objective/add_examination_page.dart | 64 +++++++---------- .../objective/examination_item_card.dart | 9 +-- .../objective/update_objective_page.dart | 71 ++++++++++++++----- .../shared_soap_widgets/remark_text.dart | 24 +++++++ .../shared_soap_widgets/steps_widget.dart | 2 +- .../subjective/allergies/add_allergies.dart | 26 ------- .../allergies/update_allergies_widget.dart | 13 +--- 9 files changed, 148 insertions(+), 136 deletions(-) create mode 100644 lib/screens/patients/profile/soap_update/shared_soap_widgets/remark_text.dart diff --git a/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart b/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart index 4549ae3d..691cc5b6 100644 --- a/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart +++ b/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart @@ -376,9 +376,9 @@ class _AddAssessmentDetailsState extends State { bottomSheet: model.state == ViewState.Busy?Container(height: 0,): BottomSheetDialogButton( - label: TranslationBase.of(context) - .addMedication - .toUpperCase(), + label: (widget.isUpdate + ? 'Update Assessment Details' + : 'Add Assessment Details'), onTap: () async { setState(() { isFormSubmitted = true; diff --git a/lib/screens/patients/profile/soap_update/assessment/update_assessment_page.dart b/lib/screens/patients/profile/soap_update/assessment/update_assessment_page.dart index 95d3cda5..8caf61fe 100644 --- a/lib/screens/patients/profile/soap_update/assessment/update_assessment_page.dart +++ b/lib/screens/patients/profile/soap_update/assessment/update_assessment_page.dart @@ -8,6 +8,7 @@ import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_assement.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/remark_text.dart'; import 'package:doctor_app_flutter/screens/patients/profile/soap_update/soap_utils.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; @@ -152,7 +153,7 @@ class _UpdateAssessmentPageState extends State { mySelectedAssessmentList.map((assessment) { return Container( margin: EdgeInsets.only( - left: 5, right: 5, top: 15), + left: 5, right: 5, top: 15, bottom: 15), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -166,11 +167,11 @@ class _UpdateAssessmentPageState extends State { RichText( text: new TextSpan( style: new TextStyle( - fontSize: 12, + fontSize: 10, color: Color(0xFF2E303A), fontFamily: 'Poppins', - fontWeight: - FontWeight.w600), + fontWeight: FontWeight.w600, + letterSpacing: -0.4), children: [ new TextSpan( text: @@ -194,11 +195,12 @@ class _UpdateAssessmentPageState extends State { child: RichText( text: new TextSpan( style: new TextStyle( - fontSize: 16, - color: Color(0xFF2E303A), - fontFamily: 'Poppins', - fontWeight: - FontWeight.w600), + fontSize: 16, + color: Color(0xFF2E303A), + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + letterSpacing: -0.64, + ), children: [ new TextSpan( text: assessment @@ -213,17 +215,19 @@ class _UpdateAssessmentPageState extends State { RichText( text: new TextSpan( style: new TextStyle( - fontSize: 12, - color: Color(0xFF2E303A), - fontFamily: 'Poppins', - fontWeight: - FontWeight.w600), + fontSize: 12, + color: Color(0xFF2E303A), + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + ), children: [ new TextSpan( text: TranslationBase.of( context) .appointmentNo, style: new TextStyle( + fontSize: 10, + letterSpacing: -0.4, color: Color(0xFF575757), ), ), @@ -234,6 +238,7 @@ class _UpdateAssessmentPageState extends State { "", style: new TextStyle( fontSize: 14, + letterSpacing: -0.48, color: Color(0xFF2B353E), ), ), @@ -255,6 +260,7 @@ class _UpdateAssessmentPageState extends State { .condition + " : ", style: new TextStyle( + letterSpacing: -0.4, color: Color(0xFF575757), ), ), @@ -268,7 +274,8 @@ class _UpdateAssessmentPageState extends State { .selectedDiagnosisCondition .nameEn, style: new TextStyle( - fontSize: 14, + fontSize: 12, + letterSpacing: -0.48, color: Color(0xFF2B353E), ), ), @@ -278,7 +285,7 @@ class _UpdateAssessmentPageState extends State { RichText( text: new TextSpan( style: new TextStyle( - fontSize: 12, + fontSize: 10, color: Color(0xFF2E303A), fontFamily: 'Poppins', fontWeight: @@ -290,6 +297,7 @@ class _UpdateAssessmentPageState extends State { .dType + ' : ', style: new TextStyle( + letterSpacing: -0.4, color: Color(0xFF575757), ), ), @@ -303,7 +311,8 @@ class _UpdateAssessmentPageState extends State { .selectedDiagnosisType .nameEn, style: new TextStyle( - fontSize: 14, + fontSize: 12, + letterSpacing: -0.48, color: Color(0xFF2B353E), ), ), @@ -323,9 +332,10 @@ class _UpdateAssessmentPageState extends State { new TextSpan( text: TranslationBase.of( context) - .doc + + .doctor + ' : ', style: new TextStyle( + fontSize: 10,letterSpacing: -0.4, color: Color(0xFF575757), ), @@ -335,7 +345,7 @@ class _UpdateAssessmentPageState extends State { .doctorName ?? '', style: new TextStyle( - fontSize: 14, + fontSize: 12,letterSpacing: -0.48, color: Color(0xFF2B353E), ), @@ -370,17 +380,9 @@ class _UpdateAssessmentPageState extends State { fontFamily: 'Poppins', fontWeight: FontWeight.w600), - Container( - width: MediaQuery.of(context) - .size - .width * - 0.38, - child: AppText( - assessment.remark ?? "", - fontSize: 11, - color: Color(0xFF2B353E), - fontWeight: FontWeight.w700, - ), + RemarkText( + remark: + assessment.remark ?? "", ), ], ), @@ -393,6 +395,8 @@ class _UpdateAssessmentPageState extends State { Row( children: [ Column( + crossAxisAlignment: + CrossAxisAlignment.end, children: [ AppText( assessment.createdOn != @@ -408,7 +412,7 @@ class _UpdateAssessmentPageState extends State { .now()), fontWeight: FontWeight.w600, - fontSize: 14, + fontSize: 12, ), AppText( assessment.createdOn != @@ -422,7 +426,8 @@ class _UpdateAssessmentPageState extends State { .now()), fontWeight: FontWeight.w600, - fontSize: 14, + color: Color(0xFF575757), + fontSize: 12, ), ], ), diff --git a/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart b/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart index 935ac247..07343bb7 100644 --- a/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart +++ b/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart @@ -1,9 +1,11 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/master_lookup_key.dart'; +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_examination.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/bottom_sheet_dialog_button.dart'; import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/bottom_sheet_title.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; @@ -16,7 +18,7 @@ import 'examinations_list_search_widget.dart'; class AddExaminationPage extends StatefulWidget { final List mySelectedExamination; - final Function addSelectedExamination; + final Function (List)addSelectedExamination; final Function(MasterKeyModel) removeExamination; AddExaminationPage( @@ -29,6 +31,14 @@ class AddExaminationPage extends StatefulWidget { } class _AddExaminationPageState extends State { + List mySelectedExaminationLocal; + + @override + initState() { + super.initState(); + mySelectedExaminationLocal = [...widget.mySelectedExamination]; + } + @override Widget build(BuildContext context) { return BaseView( @@ -77,8 +87,9 @@ class _AddExaminationPageState extends State { }); }, addExamination: (selectedExamination) { - widget.mySelectedExamination - .insert(0,selectedExamination); + + mySelectedExaminationLocal + .insert(0, selectedExamination); // setState(() {}); }, ), @@ -91,48 +102,21 @@ class _AddExaminationPageState extends State { ), ], ), - bottomSheet: Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all( - Radius.circular(0.0), - ), - border: Border.all(color: HexColor('#707070'), width: 0), - ), - height: MediaQuery.of(context).size.height * 0.1, - width: double.infinity, - child: Column( - children: [ - SizedBox( - height: 10, + bottomSheet: model.state == ViewState.Busy + ? Container( + height: 0, + ) + : BottomSheetDialogButton( + label: "${TranslationBase.of(context).addExamination}", + onTap: () { + widget.addSelectedExamination(mySelectedExaminationLocal); + }, ), - Container( - child: FractionallySizedBox( - widthFactor: .80, - child: Center( - child: AppButton( - title: - "${TranslationBase.of(context).addExamination}", - padding: 10, - color: Color(0xFF359846), - onPressed: () { - widget.addSelectedExamination(); - }, - ), - ), - ), - ), - SizedBox( - height: 5, - ), - ], - ), - ), )); } isServiceSelected(MasterKeyModel masterKey) { - Iterable exam = widget.mySelectedExamination.where( + Iterable exam = mySelectedExaminationLocal.where( (element) => masterKey.id == element.selectedExamination.id && masterKey.typeId == element.selectedExamination.typeId); diff --git a/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart b/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart index c52f1d4a..384aff90 100644 --- a/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart +++ b/lib/screens/patients/profile/soap_update/objective/examination_item_card.dart @@ -1,6 +1,7 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_examination.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/remark_text.dart'; import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/remove_button.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; @@ -76,13 +77,7 @@ class ExaminationItemCard extends StatelessWidget { height: 4, ), if (examination.remark.isNotEmpty) - AppText( - examination.remark, - fontWeight: FontWeight.normal, - fontFamily: 'Poppins', - color: Color(0xFF575757), - fontSize: SizeConfig.textMultiplier * 1.8, - ), + RemarkText(remark: examination.remark), ], ), ); diff --git a/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart b/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart index eb9a6002..317fa4af 100644 --- a/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart +++ b/lib/screens/patients/profile/soap_update/objective/update_objective_page.dart @@ -137,7 +137,7 @@ class _UpdateObjectivePageState extends State { "New", fontWeight: FontWeight.w600, fontFamily: 'Poppins', - color: Colors.blue, + color: Color(0xFFCC9B14), ), ], ), @@ -146,7 +146,11 @@ class _UpdateObjectivePageState extends State { .sublist( 0, model.getFirstIndexForOldExamination( - mySelectedExamination)) + mySelectedExamination) == + -1 + ? 0 + : model.getFirstIndexForOldExamination( + mySelectedExamination)) .map((examination) { return ExaminationItemCard(examination, () { removeExamination( @@ -154,24 +158,28 @@ class _UpdateObjectivePageState extends State { }); }).toList(), ), - if (mySelectedExamination.isNotEmpty && model.getFirstIndexForOldExamination( - mySelectedExamination)>-1) - Row( - children: [ - AppText( - "old", - fontWeight: FontWeight.w600, - fontFamily: 'Poppins', - color: Colors.green, - ), - ], - ), + mySelectedExamination) > + -1) + Row( + children: [ + AppText( + "Verified", + fontWeight: FontWeight.w600, + fontFamily: 'Poppins', + color: Colors.green, + ), + ], + ), Column( children: mySelectedExamination .sublist(model.getFirstIndexForOldExamination( - mySelectedExamination)) + mySelectedExamination) == + -1 + ? 0 + : model.getFirstIndexForOldExamination( + mySelectedExamination)) .map((examination) { return ExaminationItemCard(examination, () { removeExamination( @@ -336,9 +344,38 @@ class _UpdateObjectivePageState extends State { FadePage( page: AddExaminationPage( mySelectedExamination: mySelectedExamination, - addSelectedExamination: () { + addSelectedExamination: (List mySelectedExaminationLocal ) { setState(() { - Navigator.of(context).pop(); + { + mySelectedExaminationLocal.forEach((element) { + if ((mySelectedExamination.singleWhere( + (it) => + it.selectedExamination.id == + element.selectedExamination.id, + orElse: () => null)) == + null) { + mySelectedExamination.add(element); + } + }); + + /// remove items. + List removedList = []; + mySelectedExamination.forEach((element) { + if ((mySelectedExaminationLocal.singleWhere( + (it) => + it.selectedExamination.id == + element.selectedExamination.id, + orElse: () => null)) == + null) { + removedList.add(element); + } + }); + + removedList.forEach((element) { + removeExamination(element.selectedExamination); + }); + Navigator.of(context).pop(); + } }); }, removeExamination: (masterKey) => removeExamination(masterKey)), diff --git a/lib/screens/patients/profile/soap_update/shared_soap_widgets/remark_text.dart b/lib/screens/patients/profile/soap_update/shared_soap_widgets/remark_text.dart new file mode 100644 index 00000000..91ef6954 --- /dev/null +++ b/lib/screens/patients/profile/soap_update/shared_soap_widgets/remark_text.dart @@ -0,0 +1,24 @@ + +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:flutter/material.dart'; + +class RemarkText extends StatelessWidget { + final String remark; + const RemarkText({ + Key key, this.remark, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + width: MediaQuery.of(context).size.width * 0.55, + child: AppText( + remark ?? '', + color: Color(0xFF575757), + fontSize: 10, + fontWeight: FontWeight.w700, + letterSpacing: -0.4, + ), + ); + } +} \ No newline at end of file diff --git a/lib/screens/patients/profile/soap_update/shared_soap_widgets/steps_widget.dart b/lib/screens/patients/profile/soap_update/shared_soap_widgets/steps_widget.dart index e79c24a7..31524295 100644 --- a/lib/screens/patients/profile/soap_update/shared_soap_widgets/steps_widget.dart +++ b/lib/screens/patients/profile/soap_update/shared_soap_widgets/steps_widget.dart @@ -248,7 +248,7 @@ class StepsWidget extends StatelessWidget { fontWeight: FontWeight.bold, fontSize: 12, textAlign: TextAlign.end, - marginLeft: 25, + marginLeft: 30, ), StatusLabel( selectedStepId: index, diff --git a/lib/screens/patients/profile/soap_update/subjective/allergies/add_allergies.dart b/lib/screens/patients/profile/soap_update/subjective/allergies/add_allergies.dart index 44eae2b8..7f1abb64 100644 --- a/lib/screens/patients/profile/soap_update/subjective/allergies/add_allergies.dart +++ b/lib/screens/patients/profile/soap_update/subjective/allergies/add_allergies.dart @@ -45,32 +45,6 @@ class _AddAllergiesState extends State { GlobalKey key = new GlobalKey>(); bool isFormSubmitted = false; - InputDecoration textFieldSelectorDecoration( - String hintText, String selectedText, bool isDropDown, - {IconData icon}) { - return InputDecoration( - contentPadding: EdgeInsets.symmetric(vertical: 10, horizontal: 10), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: Colors.grey, width: 1.0), - borderRadius: BorderRadius.circular(8), - ), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Colors.grey, width: 1.0), - borderRadius: BorderRadius.circular(8), - ), - disabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Colors.grey, width: 1.0), - borderRadius: BorderRadius.circular(8), - ), - hintText: selectedText != null ? selectedText : hintText, - suffixIcon: isDropDown ? Icon(icon ?? Icons.arrow_drop_down) : null, - hintStyle: TextStyle( - fontSize: 10, - color: Theme.of(context).hintColor, - fontWeight: FontWeight.w700), - ); - } - @override Widget build(BuildContext context) { return FractionallySizedBox( diff --git a/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart b/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart index 1984e3f9..48136cb4 100644 --- a/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart +++ b/lib/screens/patients/profile/soap_update/subjective/allergies/update_allergies_widget.dart @@ -1,5 +1,6 @@ import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/selected_items/my_selected_allergy.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/remark_text.dart'; import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/remove_button.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; @@ -103,16 +104,7 @@ class _UpdateAllergiesWidgetState extends State { padding: const EdgeInsets.symmetric(vertical: 8), child: Row( children: [ - Container( - width: MediaQuery.of(context).size.width * 0.55, - child: AppText( - selectedAllergy.remark ?? '', - color: Color(0xFF575757), - fontSize: 10, - fontWeight: FontWeight.w700, - letterSpacing: -0.4, - ), - ), + RemarkText(remark: selectedAllergy.remark,), ], ), ), @@ -210,3 +202,4 @@ class _UpdateAllergiesWidgetState extends State { } } + From 64a7aca228abef744b468672f41f76d26c6bcdff Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Thu, 15 Jul 2021 16:38:33 +0300 Subject: [PATCH 067/289] adding google anlyatic to doctor app --- lib/config/config.dart | 4 +- lib/core/service/AnalyticsService.dart | 12 +- lib/main.dart | 5 +- .../medical-file/health_summary_page.dart | 153 ++--- .../insurance_approval_screen_patient.dart | 19 +- .../admission-request-first-screen.dart | 200 +++--- .../admission-request-third-screen.dart | 147 ++-- .../admission-request_second-screen.dart | 339 +++------ .../medical_report/MedicalReportPage.dart | 258 +++---- .../profile/note/progress_note_screen.dart | 647 +++++++----------- .../patient_profile_screen.dart | 11 +- .../radiology/radiology_details_page.dart | 28 +- .../referral/AddReplayOnReferralPatient.dart | 6 + .../referral/my-referral-detail-screen.dart | 145 ++-- .../referral/refer-patient-screen.dart | 229 +++---- .../referral_patient_detail_in-paint.dart | 12 +- .../vital_sign/vital_sign_details_screen.dart | 371 ++++------ .../prescription/add_prescription_form.dart | 6 + .../procedures/procedure_checkout_screen.dart | 55 +- lib/screens/qr_reader/QR_reader_screen.dart | 13 +- .../add-rescheduleleave.dart | 158 ++--- lib/screens/sick-leave/add-sickleave.dart | 9 +- ...ent-profile-header-new-design-app-bar.dart | 154 ++--- .../profile/profile_status_info_widget.dart | 51 -- pubspec.lock | 6 +- 25 files changed, 1152 insertions(+), 1886 deletions(-) delete mode 100644 lib/widgets/patients/profile/profile_status_info_widget.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index 6c7cff87..d193bfac 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -5,8 +5,8 @@ const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; const BASE_URL_LIVE_CARE = 'https://livecare.hmg.com/'; -// const BASE_URL = 'https://hmgwebservices.com/'; -const BASE_URL = 'https://uat.hmgwebservices.com/'; +const BASE_URL = 'https://hmgwebservices.com/'; +// const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = "Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient"; diff --git a/lib/core/service/AnalyticsService.dart b/lib/core/service/AnalyticsService.dart index 660267d5..0ad669ab 100644 --- a/lib/core/service/AnalyticsService.dart +++ b/lib/core/service/AnalyticsService.dart @@ -1,22 +1,16 @@ import 'package:firebase_analytics/firebase_analytics.dart'; import 'package:firebase_analytics/observer.dart'; +import 'package:flutter/cupertino.dart'; class AnalyticsService { final FirebaseAnalytics _analytics = FirebaseAnalytics(); - FirebaseAnalyticsObserver getAnalyticsObserver() => - FirebaseAnalyticsObserver(analytics: _analytics); + FirebaseAnalyticsObserver getAnalyticsObserver() => FirebaseAnalyticsObserver(analytics: _analytics); - Future logEvent( - {String eventCategory, - String eventLabel, - String eventAction, - String eventValue}) async { + Future logEvent({@required String eventCategory, @required String eventAction}) async { await _analytics.logEvent(name: 'event', parameters: { "eventCategory": eventCategory, - "eventLabel": eventLabel, "eventAction": eventAction, - "eventValue": eventValue }); } } diff --git a/lib/main.dart b/lib/main.dart index bf319a84..6bfd624a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -35,8 +35,7 @@ class MyApp extends StatelessWidget { SizeConfig().init(constraints, orientation); return MultiProvider( providers: [ - ChangeNotifierProvider( - create: (context) => AuthenticationViewModel()), + ChangeNotifierProvider(create: (context) => AuthenticationViewModel()), ChangeNotifierProvider( create: (context) => ProjectViewModel(), ), @@ -71,7 +70,7 @@ class MyApp extends StatelessWidget { backgroundColor: Color.fromRGBO(255, 255, 255, 1), ), navigatorKey: locator().navigatorKey, - navigatorObservers:[ + navigatorObservers: [ locator().getAnalyticsObserver(), ], initialRoute: INIT_ROUTE, diff --git a/lib/screens/medical-file/health_summary_page.dart b/lib/screens/medical-file/health_summary_page.dart index 6b4b066c..c6e4cd27 100644 --- a/lib/screens/medical-file/health_summary_page.dart +++ b/lib/screens/medical-file/health_summary_page.dart @@ -1,4 +1,6 @@ +import 'package:doctor_app_flutter/core/service/AnalyticsService.dart'; import 'package:doctor_app_flutter/core/viewModel/medical_file_view_model.dart'; +import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/medical-file/medical_file_details.dart'; @@ -27,9 +29,7 @@ class _HealthSummaryPageState extends State { bool isInpatient = routeArgs['isInpatient']; return BaseView( onModelReady: (model) => model.getMedicalFile(mrn: patient.patientId), - builder: - (BuildContext context, MedicalFileViewModel model, Widget child) => - AppScaffold( + builder: (BuildContext context, MedicalFileViewModel model, Widget child) => AppScaffold( appBar: PatientProfileAppBar( patient, isInpatient: isInpatient, @@ -43,8 +43,7 @@ class _HealthSummaryPageState extends State { child: Column( children: [ Padding( - padding: - EdgeInsets.symmetric(horizontal: 12.0, vertical: 8.0), + padding: EdgeInsets.symmetric(horizontal: 12.0, vertical: 8.0), child: Container( child: Padding( padding: const EdgeInsets.all(8.0), @@ -74,112 +73,67 @@ class _HealthSummaryPageState extends State { ), ), ), - (model.medicalFileList != null && - model.medicalFileList.length != 0) + (model.medicalFileList != null && model.medicalFileList.length != 0) ? ListView.builder( //physics: , physics: NeverScrollableScrollPhysics(), scrollDirection: Axis.vertical, shrinkWrap: true, - itemCount: model.medicalFileList[0].entityList[0] - .timelines.length, + itemCount: model.medicalFileList[0].entityList[0].timelines.length, itemBuilder: (BuildContext ctxt, int index) { return InkWell( - onTap: () { - if (model - .medicalFileList[0] - .entityList[0] - .timelines[index] - .timeLineEvents[0] - .consulations - .length != + onTap: () async { + if (model.medicalFileList[0].entityList[0].timelines[index].timeLineEvents[0] + .consulations.length != 0) - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => MedicalFileDetails( - age: patient.age is String - ? patient.age ?? "" - : "${patient.age}", - firstName: patient.firstName, - lastName: patient.lastName, - gender: patient.genderDescription, - encounterNumber: index, - pp: patient.patientId, - patient: patient, - doctorName: model - .medicalFileList[0] - .entityList[0] - .timelines[index] - .timeLineEvents[0] - .consulations - .isNotEmpty - ? model - .medicalFileList[0] - .entityList[0] - .timelines[index] - .doctorName - : "", - clinicName: model - .medicalFileList[0] - .entityList[0] - .timelines[index] - .timeLineEvents[0] - .consulations - .isNotEmpty - ? model - .medicalFileList[0] - .entityList[0] - .timelines[index] - .clinicName - : "", - doctorImage: model - .medicalFileList[0] - .entityList[0] - .timelines[index] - .timeLineEvents[0] - .consulations - .isNotEmpty - ? model - .medicalFileList[0] - .entityList[0] - .timelines[index] - .doctorImage - : "", - episode: model.medicalFileList[0].entityList[0].timelines[index].timeLineEvents[0].consulations.isNotEmpty - ? model.medicalFileList[0].entityList[0].timelines[index].timeLineEvents[0].consulations[0].episodeID.toString() - : "", - vistDate: model.medicalFileList[0].entityList[0].timelines[index].date.toString())), + await locator().logEvent( + eventCategory: "Health Summary Page", + eventAction: "Health Summary Details", ); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => MedicalFileDetails( + age: patient.age is String ? patient.age ?? "" : "${patient.age}", + firstName: patient.firstName, + lastName: patient.lastName, + gender: patient.genderDescription, + encounterNumber: index, + pp: patient.patientId, + patient: patient, + doctorName: model.medicalFileList[0].entityList[0].timelines[index] + .timeLineEvents[0].consulations.isNotEmpty + ? model.medicalFileList[0].entityList[0].timelines[index].doctorName + : "", + clinicName: model.medicalFileList[0].entityList[0].timelines[index] + .timeLineEvents[0].consulations.isNotEmpty + ? model.medicalFileList[0].entityList[0].timelines[index].clinicName + : "", + doctorImage: model.medicalFileList[0].entityList[0].timelines[index] + .timeLineEvents[0].consulations.isNotEmpty + ? model.medicalFileList[0].entityList[0].timelines[index].doctorImage + : "", + episode: model.medicalFileList[0].entityList[0].timelines[index] + .timeLineEvents[0].consulations.isNotEmpty + ? model.medicalFileList[0].entityList[0].timelines[index] + .timeLineEvents[0].consulations[0].episodeID + .toString() + : "", + vistDate: + model.medicalFileList[0].entityList[0].timelines[index].date.toString())), + ); }, child: DoctorCard( - doctorName: model - .medicalFileList[0] - .entityList[0] - .timelines[index] - .doctorName, - clinic: model.medicalFileList[0].entityList[0] - .timelines[index].clinicName, - branch: model.medicalFileList[0].entityList[0] - .timelines[index].projectName, - profileUrl: model - .medicalFileList[0] - .entityList[0] - .timelines[index] - .doctorImage, - appointmentDate: - AppDateUtils.getDateTimeFromServerFormat( - model.medicalFileList[0].entityList[0] - .timelines[index].date, + doctorName: model.medicalFileList[0].entityList[0].timelines[index].doctorName, + clinic: model.medicalFileList[0].entityList[0].timelines[index].clinicName, + branch: model.medicalFileList[0].entityList[0].timelines[index].projectName, + profileUrl: model.medicalFileList[0].entityList[0].timelines[index].doctorImage, + appointmentDate: AppDateUtils.getDateTimeFromServerFormat( + model.medicalFileList[0].entityList[0].timelines[index].date, ), isPrescriptions: true, - isShowEye: model - .medicalFileList[0] - .entityList[0] - .timelines[index] - .timeLineEvents[0] - .consulations - .length != + isShowEye: model.medicalFileList[0].entityList[0].timelines[index].timeLineEvents[0] + .consulations.length != 0 ? true : false), @@ -195,8 +149,7 @@ class _HealthSummaryPageState extends State { Image.asset('assets/images/no-data.png'), Padding( padding: const EdgeInsets.all(8.0), - child: AppText(TranslationBase.of(context) - .noMedicalFileFound), + child: AppText(TranslationBase.of(context).noMedicalFileFound), ) ], ), diff --git a/lib/screens/patients/insurance_approval_screen_patient.dart b/lib/screens/patients/insurance_approval_screen_patient.dart index b9d3f57e..3144ced9 100644 --- a/lib/screens/patients/insurance_approval_screen_patient.dart +++ b/lib/screens/patients/insurance_approval_screen_patient.dart @@ -1,6 +1,8 @@ import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/service/AnalyticsService.dart'; import 'package:doctor_app_flutter/core/viewModel/InsuranceViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/patients/insurance_approvals_details.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; @@ -175,15 +177,20 @@ class _InsuranceApprovalScreenNewState extends State model.insuranceApproval.length, (index) => Container( child: InkWell( - onTap: () { + onTap: () async { + await locator().logEvent( + eventCategory: "Insurance Approval Screen New", + eventAction: "Insurance Approval Details", + ); Navigator.push( context, MaterialPageRoute( - builder: (context) => InsuranceApprovalsDetails( - patient: patient, - indexInsurance: index, - patientType: patientType, - )), + builder: (context) => InsuranceApprovalsDetails( + patient: patient, + indexInsurance: index, + patientType: patientType, + ), + ), ); }, child: DoctorCardInsurance( diff --git a/lib/screens/patients/profile/admission-request/admission-request-first-screen.dart b/lib/screens/patients/profile/admission-request/admission-request-first-screen.dart index f0ccaece..9fa78cef 100644 --- a/lib/screens/patients/profile/admission-request/admission-request-first-screen.dart +++ b/lib/screens/patients/profile/admission-request/admission-request-first-screen.dart @@ -1,8 +1,10 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/admissionRequest/admission-request.dart'; +import 'package:doctor_app_flutter/core/service/AnalyticsService.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-admission-request-viewmodel.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; @@ -23,12 +25,10 @@ import '../../../../routes.dart'; class AdmissionRequestFirstScreen extends StatefulWidget { @override - _AdmissionRequestThirdScreenState createState() => - _AdmissionRequestThirdScreenState(); + _AdmissionRequestThirdScreenState createState() => _AdmissionRequestThirdScreenState(); } -class _AdmissionRequestThirdScreenState - extends State { +class _AdmissionRequestThirdScreenState extends State { final _dietTypeRemarksController = TextEditingController(); final _sickLeaveCommentsController = TextEditingController(); final _postMedicalHistoryController = TextEditingController(); @@ -61,8 +61,7 @@ class _AdmissionRequestThirdScreenState builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, - appBar: PatientProfileAppBar( - patient), + appBar: PatientProfileAppBar(patient), appBarTitle: TranslationBase.of(context).admissionRequest, body: GestureDetector( onTap: () { @@ -100,14 +99,12 @@ class _AdmissionRequestThirdScreenState ), ), Container( - margin: - EdgeInsets.symmetric(vertical: 0, horizontal: 16), + margin: EdgeInsets.symmetric(vertical: 0, horizontal: 16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( - TranslationBase.of(context) - .specialityAndDoctorDetail, + TranslationBase.of(context).specialityAndDoctorDetail, color: Color(0xFF2E303A), fontSize: SizeConfig.textMultiplier * 1.8, fontWeight: FontWeight.w700, @@ -121,14 +118,15 @@ class _AdmissionRequestThirdScreenState isTextFieldHasSuffix: true, validationError: clinicError, dropDownText: _selectedClinic != null - ? projectViewModel.isArabic? _selectedClinic['clinicNameArabic'] : _selectedClinic['clinicNameEnglish'] + ? projectViewModel.isArabic + ? _selectedClinic['clinicNameArabic'] + : _selectedClinic['clinicNameEnglish'] : null, enabled: false, - onClick: model.clinicList != null && - model.clinicList.length > 0 + onClick: model.clinicList != null && model.clinicList.length > 0 ? () { openListDialogField( - projectViewModel.isArabic? 'clinicNameArabic' : 'clinicNameEnglish', + projectViewModel.isArabic ? 'clinicNameArabic' : 'clinicNameEnglish', 'clinicID', model.clinicList, (selectedValue) { setState(() { @@ -137,28 +135,21 @@ class _AdmissionRequestThirdScreenState }); } : () async { - GifLoaderDialogUtils.showMyDialog( - context); - await model.getClinics().then((_) => - GifLoaderDialogUtils.hideDialog( - context)); - if (model.state == ViewState.Idle && - model.clinicList.length > 0) { + GifLoaderDialogUtils.showMyDialog(context); + await model.getClinics().then((_) => GifLoaderDialogUtils.hideDialog(context)); + if (model.state == ViewState.Idle && model.clinicList.length > 0) { openListDialogField( - projectViewModel.isArabic? 'clinicNameArabic' : 'clinicNameEnglish', + projectViewModel.isArabic ? 'clinicNameArabic' : 'clinicNameEnglish', 'clinicID', model.clinicList, (selectedValue) { setState(() { _selectedClinic = selectedValue; }); }); - } else if (model.state == - ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast( - model.error); + } else if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); } else { - DrAppToastMsg.showErrorToast( - "Empty List"); + DrAppToastMsg.showErrorToast("Empty List"); } }, ), @@ -169,17 +160,13 @@ class _AdmissionRequestThirdScreenState height: screenSize.height * 0.075, hintText: TranslationBase.of(context).doctor, isTextFieldHasSuffix: true, - dropDownText: _selectedDoctor != null - ? _selectedDoctor['DoctorName'] - : null, + dropDownText: _selectedDoctor != null ? _selectedDoctor['DoctorName'] : null, enabled: false, validationError: doctorError, onClick: _selectedClinic != null - ? model.doctorsList != null && - model.doctorsList.length > 0 + ? model.doctorsList != null && model.doctorsList.length > 0 ? () { - openListDialogField('DoctorName', - 'DoctorID', model.doctorsList, + openListDialogField('DoctorName', 'DoctorID', model.doctorsList, (selectedValue) { setState(() { _selectedDoctor = selectedValue; @@ -187,29 +174,21 @@ class _AdmissionRequestThirdScreenState }); } : () async { - GifLoaderDialogUtils.showMyDialog( - context); + GifLoaderDialogUtils.showMyDialog(context); await model - .getClinicDoctors( - _selectedClinic['clinicID']) - .then((_) => GifLoaderDialogUtils - .hideDialog(context)); - if (model.state == ViewState.Idle && - model.doctorsList.length > 0) { - openListDialogField('DoctorName', - 'DoctorID', model.doctorsList, + .getClinicDoctors(_selectedClinic['clinicID']) + .then((_) => GifLoaderDialogUtils.hideDialog(context)); + if (model.state == ViewState.Idle && model.doctorsList.length > 0) { + openListDialogField('DoctorName', 'DoctorID', model.doctorsList, (selectedValue) { setState(() { _selectedDoctor = selectedValue; }); }); - } else if (model.state == - ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast( - model.error); + } else if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); } else { - DrAppToastMsg.showErrorToast( - "Empty List"); + DrAppToastMsg.showErrorToast("Empty List"); } } : null, @@ -226,7 +205,7 @@ class _AdmissionRequestThirdScreenState SizedBox( height: 10, ), - if(patient.gender != 1) + if (patient.gender != 1) CheckboxListTile( title: AppText( TranslationBase.of(context).patientPregnant, @@ -262,8 +241,7 @@ class _AdmissionRequestThirdScreenState contentPadding: EdgeInsets.all(0), ), AppTextFieldCustom( - hintText: - TranslationBase.of(context).sickLeaveComments, + hintText: TranslationBase.of(context).sickLeaveComments, controller: _sickLeaveCommentsController, minLines: 2, maxLines: 4, @@ -278,43 +256,31 @@ class _AdmissionRequestThirdScreenState hintText: TranslationBase.of(context).dietType, isTextFieldHasSuffix: true, validationError: dietTypeError, - dropDownText: _selectedDietType != null - ? _selectedDietType['nameEn'] - : null, + dropDownText: _selectedDietType != null ? _selectedDietType['nameEn'] : null, enabled: false, - onClick: model.dietTypesList != null && - model.dietTypesList.length > 0 + onClick: model.dietTypesList != null && model.dietTypesList.length > 0 ? () { - openListDialogField( - 'nameEn', 'id', model.dietTypesList, - (selectedValue) { + openListDialogField('nameEn', 'id', model.dietTypesList, (selectedValue) { setState(() { _selectedDietType = selectedValue; }); }); } : () async { - GifLoaderDialogUtils.showMyDialog( - context); - await model.getDietTypes(patient.patientId).then((_) => - GifLoaderDialogUtils.hideDialog( - context)); - if (model.state == ViewState.Idle && - model.dietTypesList.length > 0) { - openListDialogField( - 'nameEn', 'id', model.dietTypesList, - (selectedValue) { + GifLoaderDialogUtils.showMyDialog(context); + await model + .getDietTypes(patient.patientId) + .then((_) => GifLoaderDialogUtils.hideDialog(context)); + if (model.state == ViewState.Idle && model.dietTypesList.length > 0) { + openListDialogField('nameEn', 'id', model.dietTypesList, (selectedValue) { setState(() { _selectedDietType = selectedValue; }); }); - } else if (model.state == - ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast( - model.error); + } else if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); } else { - DrAppToastMsg.showErrorToast( - "Empty List"); + DrAppToastMsg.showErrorToast("Empty List"); } }, ), @@ -322,8 +288,7 @@ class _AdmissionRequestThirdScreenState height: 10, ), AppTextFieldCustom( - hintText: - TranslationBase.of(context).dietTypeRemarks, + hintText: TranslationBase.of(context).dietTypeRemarks, controller: _dietTypeRemarksController, minLines: 4, maxLines: 6, @@ -363,82 +328,71 @@ class _AdmissionRequestThirdScreenState child: AppButton( title: TranslationBase.of(context).next, color: HexColor("#D02127"), - onPressed: () { + onPressed: () async { + await locator().logEvent( + eventCategory: "Admission Request First Screen", + eventAction: "Go To Admission Request Two", + ); model.admissionRequestData = AdmissionRequest(); if (_selectedClinic != null && _selectedDoctor != null && _sickLeaveCommentsController.text != "" && _postMedicalHistoryController.text != "" && _postSurgicalHistoryController.text != "") { - model.admissionRequestData.patientMRN = - patient.patientMRN; - model.admissionRequestData.appointmentNo = - patient.appointmentNo; + model.admissionRequestData.patientMRN = patient.patientMRN; + model.admissionRequestData.appointmentNo = patient.appointmentNo; model.admissionRequestData.episodeID = patient.episodeNo; model.admissionRequestData.admissionRequestNo = 0; - model.admissionRequestData.admitToClinic = - _selectedClinic['clinicID']; - model.admissionRequestData.mrpDoctorID = - _selectedDoctor['DoctorID']; + model.admissionRequestData.admitToClinic = _selectedClinic['clinicID']; + model.admissionRequestData.mrpDoctorID = _selectedDoctor['DoctorID']; model.admissionRequestData.isPregnant = _patientPregnant; - model.admissionRequestData.isSickLeaveRequired = - _isSickLeaveRequired; - model.admissionRequestData.sickLeaveComments = - _sickLeaveCommentsController.text; - model.admissionRequestData.isDietType = - _selectedDietType != null ? true : false; - model.admissionRequestData.dietType = - _selectedDietType != null - ? _selectedDietType['id'] - : 0; - model.admissionRequestData.dietRemarks = - _dietTypeRemarksController.text; - model.admissionRequestData.pastMedicalHistory = - _postMedicalHistoryController.text; - model.admissionRequestData.pastSurgicalHistory = - _postSurgicalHistoryController.text; - Navigator.of(context) - .pushNamed(PATIENT_ADMISSION_REQUEST_2, arguments: { + model.admissionRequestData.isSickLeaveRequired = _isSickLeaveRequired; + model.admissionRequestData.sickLeaveComments = _sickLeaveCommentsController.text; + model.admissionRequestData.isDietType = _selectedDietType != null ? true : false; + model.admissionRequestData.dietType = _selectedDietType != null ? _selectedDietType['id'] : 0; + model.admissionRequestData.dietRemarks = _dietTypeRemarksController.text; + model.admissionRequestData.pastMedicalHistory = _postMedicalHistoryController.text; + model.admissionRequestData.pastSurgicalHistory = _postSurgicalHistoryController.text; + Navigator.of(context).pushNamed(PATIENT_ADMISSION_REQUEST_2, arguments: { 'patient': patient, 'patientType': patientType, 'arrivalType': arrivalType, 'admission-data': model.admissionRequestData }); } else { - DrAppToastMsg.showErrorToast( - TranslationBase.of(context).pleaseFill); + DrAppToastMsg.showErrorToast(TranslationBase.of(context).pleaseFill); setState(() { - if(_selectedClinic == null){ + if (_selectedClinic == null) { clinicError = TranslationBase.of(context).fieldRequired; - }else { + } else { clinicError = null; } - if(_selectedDoctor == null){ + if (_selectedDoctor == null) { doctorError = TranslationBase.of(context).fieldRequired; - }else { + } else { doctorError = null; } - if(_sickLeaveCommentsController.text == ""){ + if (_sickLeaveCommentsController.text == "") { sickLeaveCommentError = TranslationBase.of(context).fieldRequired; - }else { + } else { sickLeaveCommentError = null; } - if(_selectedDietType == null){ + if (_selectedDietType == null) { dietTypeError = TranslationBase.of(context).fieldRequired; - }else { + } else { dietTypeError = null; } - if(_postMedicalHistoryController.text == ""){ + if (_postMedicalHistoryController.text == "") { medicalHistoryError = TranslationBase.of(context).fieldRequired; - }else { + } else { medicalHistoryError = null; } - if(_postSurgicalHistoryController.text == ""){ + if (_postSurgicalHistoryController.text == "") { surgicalHistoryError = TranslationBase.of(context).fieldRequired; - }else { + } else { surgicalHistoryError = null; } }); @@ -453,8 +407,8 @@ class _AdmissionRequestThirdScreenState ); } - void openListDialogField(String attributeName, String attributeValueId, - List list, Function(dynamic selectedValue) okFunction) { + void openListDialogField( + String attributeName, String attributeValueId, List list, Function(dynamic selectedValue) okFunction) { ListSelectDialog dialog = ListSelectDialog( list: list, attributeName: attributeName, diff --git a/lib/screens/patients/profile/admission-request/admission-request-third-screen.dart b/lib/screens/patients/profile/admission-request/admission-request-third-screen.dart index 563b4827..99097777 100644 --- a/lib/screens/patients/profile/admission-request/admission-request-third-screen.dart +++ b/lib/screens/patients/profile/admission-request/admission-request-third-screen.dart @@ -2,8 +2,10 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/master_lookup_key.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/admissionRequest/admission-request.dart'; +import 'package:doctor_app_flutter/core/service/AnalyticsService.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-admission-request-viewmodel.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; @@ -23,12 +25,10 @@ import '../../../../routes.dart'; class AdmissionRequestThirdScreen extends StatefulWidget { @override - _AdmissionRequestThirdScreenState createState() => - _AdmissionRequestThirdScreenState(); + _AdmissionRequestThirdScreenState createState() => _AdmissionRequestThirdScreenState(); } -class _AdmissionRequestThirdScreenState - extends State { +class _AdmissionRequestThirdScreenState extends State { dynamic _selectedDiagnosis; dynamic _selectedIcd; dynamic _selectedDiagnosisType; @@ -52,8 +52,7 @@ class _AdmissionRequestThirdScreenState builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, - appBar: PatientProfileAppBar( - patient), + appBar: PatientProfileAppBar(patient), appBarTitle: TranslationBase.of(context).admissionRequest, body: GestureDetector( onTap: () { @@ -106,18 +105,13 @@ class _AdmissionRequestThirdScreenState AppTextFieldCustom( height: screenSize.height * 0.075, hintText: TranslationBase.of(context).diagnosis, - dropDownText: _selectedDiagnosis != null - ? _selectedDiagnosis['nameEn'] - : null, + dropDownText: _selectedDiagnosis != null ? _selectedDiagnosis['nameEn'] : null, enabled: false, isTextFieldHasSuffix: true, validationError: diagnosisError, - onClick: model.diagnosisTypesList != null && - model.diagnosisTypesList.length > 0 + onClick: model.diagnosisTypesList != null && model.diagnosisTypesList.length > 0 ? () { - openListDialogField('nameEn', 'id', - model.diagnosisTypesList, - (selectedValue) { + openListDialogField('nameEn', 'id', model.diagnosisTypesList, (selectedValue) { setState(() { _selectedDiagnosis = selectedValue; }); @@ -125,24 +119,17 @@ class _AdmissionRequestThirdScreenState } : () async { GifLoaderDialogUtils.showMyDialog(context); - await model.getDiagnosis().then((_) => - GifLoaderDialogUtils.hideDialog( - context)); - if (model.state == ViewState.Idle && - model.diagnosisTypesList.length > 0) { - openListDialogField('nameEn', 'id', - model.diagnosisTypesList, - (selectedValue) { + await model.getDiagnosis().then((_) => GifLoaderDialogUtils.hideDialog(context)); + if (model.state == ViewState.Idle && model.diagnosisTypesList.length > 0) { + openListDialogField('nameEn', 'id', model.diagnosisTypesList, (selectedValue) { setState(() { _selectedDiagnosis = selectedValue; }); }); - } else if (model.state == - ViewState.ErrorLocal) { + } else if (model.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(model.error); } else { - DrAppToastMsg.showErrorToast( - "Empty List"); + DrAppToastMsg.showErrorToast("Empty List"); } }, ), @@ -152,18 +139,13 @@ class _AdmissionRequestThirdScreenState AppTextFieldCustom( height: screenSize.height * 0.075, hintText: TranslationBase.of(context).icd, - dropDownText: _selectedIcd != null - ? _selectedIcd['description'] - : null, + dropDownText: _selectedIcd != null ? _selectedIcd['description'] : null, enabled: false, isTextFieldHasSuffix: true, validationError: icdError, - onClick: model.icdCodes != null && - model.icdCodes.length > 0 + onClick: model.icdCodes != null && model.icdCodes.length > 0 ? () { - openListDialogField( - 'description', 'code', model.icdCodes, - (selectedValue) { + openListDialogField('description', 'code', model.icdCodes, (selectedValue) { setState(() { _selectedIcd = selectedValue; }); @@ -173,24 +155,17 @@ class _AdmissionRequestThirdScreenState GifLoaderDialogUtils.showMyDialog(context); await model .getICDCodes(patient.patientMRN) - .then((_) => - GifLoaderDialogUtils.hideDialog( - context)); - if (model.state == ViewState.Idle && - model.icdCodes.length > 0) { - openListDialogField( - 'description', 'code', model.icdCodes, - (selectedValue) { + .then((_) => GifLoaderDialogUtils.hideDialog(context)); + if (model.state == ViewState.Idle && model.icdCodes.length > 0) { + openListDialogField('description', 'code', model.icdCodes, (selectedValue) { setState(() { _selectedIcd = selectedValue; }); }); - } else if (model.state == - ViewState.ErrorLocal) { + } else if (model.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(model.error); } else { - DrAppToastMsg.showErrorToast( - "Empty List"); + DrAppToastMsg.showErrorToast("Empty List"); } }, ), @@ -200,19 +175,14 @@ class _AdmissionRequestThirdScreenState AppTextFieldCustom( height: screenSize.height * 0.075, hintText: TranslationBase.of(context).diagnoseType, - dropDownText: _selectedDiagnosisType != null - ? _selectedDiagnosisType['description'] - : null, + dropDownText: _selectedDiagnosisType != null ? _selectedDiagnosisType['description'] : null, enabled: false, isTextFieldHasSuffix: true, validationError: diagnosisTypeError, - onClick: model.listOfDiagnosisSelectionTypes != - null && - model.listOfDiagnosisSelectionTypes.length > - 0 + onClick: model.listOfDiagnosisSelectionTypes != null && + model.listOfDiagnosisSelectionTypes.length > 0 ? () { - openListDialogField('description', 'code', - model.listOfDiagnosisSelectionTypes, + openListDialogField('description', 'code', model.listOfDiagnosisSelectionTypes, (selectedValue) { setState(() { _selectedDiagnosisType = selectedValue; @@ -222,29 +192,20 @@ class _AdmissionRequestThirdScreenState : () async { GifLoaderDialogUtils.showMyDialog(context); await model - .getMasterLookup(MasterKeysService - .DiagnosisSelectionType) - .then((_) => - GifLoaderDialogUtils.hideDialog( - context)); + .getMasterLookup(MasterKeysService.DiagnosisSelectionType) + .then((_) => GifLoaderDialogUtils.hideDialog(context)); if (model.state == ViewState.Idle && - model.listOfDiagnosisSelectionTypes - .length > - 0) { - openListDialogField('description', 'code', - model.listOfDiagnosisSelectionTypes, + model.listOfDiagnosisSelectionTypes.length > 0) { + openListDialogField('description', 'code', model.listOfDiagnosisSelectionTypes, (selectedValue) { setState(() { - _selectedDiagnosisType = - selectedValue; + _selectedDiagnosisType = selectedValue; }); }); - } else if (model.state == - ViewState.ErrorLocal) { + } else if (model.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(model.error); } else { - DrAppToastMsg.showErrorToast( - "Empty List"); + DrAppToastMsg.showErrorToast("Empty List"); } }, ), @@ -279,58 +240,52 @@ class _AdmissionRequestThirdScreenState title: TranslationBase.of(context).submit, color: HexColor("#359846"), onPressed: () async { - if (_selectedDiagnosis != null && - _selectedIcd != null && - _selectedDiagnosisType != null) { + await locator().logEvent( + eventCategory: "Admission Request Third Screen", + eventAction: "Submit Admission Request", + ); + if (_selectedDiagnosis != null && _selectedIcd != null && _selectedDiagnosisType != null) { model.admissionRequestData = admissionRequest; dynamic admissionRequestDiagnoses = [ { - 'diagnosisDescription': - _selectedDiagnosis['nameEn'], + 'diagnosisDescription': _selectedDiagnosis['nameEn'], 'diagnosisType': _selectedDiagnosis['id'], 'icdCode': _selectedIcd['code'], - 'icdCodeDescription': - _selectedIcd['description'], + 'icdCodeDescription': _selectedIcd['description'], 'type': _selectedDiagnosisType['code'], 'remarks': "", 'isActive': true, } ]; - model.admissionRequestData - .admissionRequestDiagnoses = - admissionRequestDiagnoses; + model.admissionRequestData.admissionRequestDiagnoses = admissionRequestDiagnoses; await model.makeAdmissionRequest(); if (model.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(model.error); } else { - DrAppToastMsg.showSuccesToast( - TranslationBase.of(context) - .admissionRequestSuccessMsg); - Navigator.popUntil(context, - ModalRoute.withName(PATIENTS_PROFILE)); + DrAppToastMsg.showSuccesToast(TranslationBase.of(context).admissionRequestSuccessMsg); + Navigator.popUntil(context, ModalRoute.withName(PATIENTS_PROFILE)); } } else { - DrAppToastMsg.showErrorToast( - TranslationBase.of(context).pleaseFill); + DrAppToastMsg.showErrorToast(TranslationBase.of(context).pleaseFill); setState(() { - if(_selectedDiagnosis == null){ + if (_selectedDiagnosis == null) { diagnosisError = TranslationBase.of(context).fieldRequired; - }else { + } else { diagnosisError = null; } - if(_selectedIcd == null){ + if (_selectedIcd == null) { icdError = TranslationBase.of(context).fieldRequired; - }else { + } else { icdError = null; } - if(_selectedDiagnosisType == null){ + if (_selectedDiagnosisType == null) { diagnosisTypeError = TranslationBase.of(context).fieldRequired; - }else { + } else { diagnosisTypeError = null; } }); @@ -348,8 +303,8 @@ class _AdmissionRequestThirdScreenState ); } - void openListDialogField(String attributeName, String attributeValueId, - List list, Function(dynamic selectedValue) okFunction) { + void openListDialogField( + String attributeName, String attributeValueId, List list, Function(dynamic selectedValue) okFunction) { ListSelectDialog dialog = ListSelectDialog( list: list, attributeName: attributeName, diff --git a/lib/screens/patients/profile/admission-request/admission-request_second-screen.dart b/lib/screens/patients/profile/admission-request/admission-request_second-screen.dart index dc79b2be..0258d26f 100644 --- a/lib/screens/patients/profile/admission-request/admission-request_second-screen.dart +++ b/lib/screens/patients/profile/admission-request/admission-request_second-screen.dart @@ -3,8 +3,10 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/master_lookup_key.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/admissionRequest/admission-request.dart'; +import 'package:doctor_app_flutter/core/service/AnalyticsService.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-admission-request-viewmodel.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; @@ -26,12 +28,10 @@ import '../../../../routes.dart'; class AdmissionRequestSecondScreen extends StatefulWidget { @override - _AdmissionRequestSecondScreenState createState() => - _AdmissionRequestSecondScreenState(); + _AdmissionRequestSecondScreenState createState() => _AdmissionRequestSecondScreenState(); } -class _AdmissionRequestSecondScreenState - extends State { +class _AdmissionRequestSecondScreenState extends State { final _postPlansEstimatedCostController = TextEditingController(); final _estimatedCostController = TextEditingController(); final _expectedDaysController = TextEditingController(); @@ -74,8 +74,7 @@ class _AdmissionRequestSecondScreenState builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, - appBar: PatientProfileAppBar( - patient), + appBar: PatientProfileAppBar(patient), appBarTitle: TranslationBase.of(context).admissionRequest, body: GestureDetector( onTap: () { @@ -112,14 +111,12 @@ class _AdmissionRequestSecondScreenState ), ), Container( - margin: - EdgeInsets.symmetric(vertical: 0, horizontal: 16), + margin: EdgeInsets.symmetric(vertical: 0, horizontal: 16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( - TranslationBase.of(context) - .postPlansEstimatedCost, + TranslationBase.of(context).postPlansEstimatedCost, color: Color(0xFF2E303A), fontSize: SizeConfig.textMultiplier * 1.8, fontWeight: FontWeight.w700, @@ -129,15 +126,11 @@ class _AdmissionRequestSecondScreenState ), AppTextFieldCustom( height: screenSize.height * 0.075, - hintText: - TranslationBase.of(context).estimatedCost, + hintText: TranslationBase.of(context).estimatedCost, controller: _estimatedCostController, validationError: costError, inputType: TextInputType.number, - inputFormatters: [ - FilteringTextInputFormatter.allow( - RegExp(ONLY_NUMBERS)) - ], + inputFormatters: [FilteringTextInputFormatter.allow(RegExp(ONLY_NUMBERS))], ), SizedBox( height: 10, @@ -154,10 +147,8 @@ class _AdmissionRequestSecondScreenState height: 10, ), AppTextFieldCustom( - hintText: TranslationBase.of(context) - .otherDepartmentsInterventions, - controller: - _otherDepartmentsInterventionsController, + hintText: TranslationBase.of(context).otherDepartmentsInterventions, + controller: _otherDepartmentsInterventionsController, inputType: TextInputType.multiline, validationError: otherInterventionsError, minLines: 2, @@ -177,23 +168,18 @@ class _AdmissionRequestSecondScreenState ), AppTextFieldCustom( height: screenSize.height * 0.075, - hintText: - TranslationBase.of(context).expectedDays, + hintText: TranslationBase.of(context).expectedDays, controller: _expectedDaysController, validationError: expectedDaysError, inputType: TextInputType.number, - inputFormatters: [ - FilteringTextInputFormatter.allow( - RegExp(ONLY_NUMBERS)) - ], + inputFormatters: [FilteringTextInputFormatter.allow(RegExp(ONLY_NUMBERS))], ), SizedBox( height: 10, ), AppTextFieldCustom( height: screenSize.height * 0.075, - hintText: TranslationBase.of(context) - .expectedAdmissionDate, + hintText: TranslationBase.of(context).expectedAdmissionDate, dropDownText: _expectedAdmissionDate != null ? "${AppDateUtils.convertStringToDateFormat(_expectedAdmissionDate.toString(), "yyyy-MM-dd")}" : null, @@ -209,8 +195,7 @@ class _AdmissionRequestSecondScreenState if (_expectedAdmissionDate == null) { _expectedAdmissionDate = DateTime.now(); } - _selectDate(context, _expectedAdmissionDate, - (picked) { + _selectDate(context, _expectedAdmissionDate, (picked) { setState(() { _expectedAdmissionDate = picked; }); @@ -223,47 +208,32 @@ class _AdmissionRequestSecondScreenState AppTextFieldCustom( height: screenSize.height * 0.075, hintText: TranslationBase.of(context).floor, - dropDownText: _selectedFloor != null - ? _selectedFloor['description'] - : null, + dropDownText: _selectedFloor != null ? _selectedFloor['description'] : null, enabled: false, isTextFieldHasSuffix: true, validationError: floorError, - onClick: model.floorList != null && - model.floorList.length > 0 + onClick: model.floorList != null && model.floorList.length > 0 ? () { - openListDialogField( - 'description', - 'floorID', - model.floorList, (selectedValue) { + openListDialogField('description', 'floorID', model.floorList, (selectedValue) { setState(() { _selectedFloor = selectedValue; }); }); } : () async { - GifLoaderDialogUtils.showMyDialog( - context); - await model.getFloors().then((_) => - GifLoaderDialogUtils.hideDialog( - context)); - if (model.state == ViewState.Idle && - model.floorList.length > 0) { - openListDialogField( - 'description', - 'floorID', - model.floorList, (selectedValue) { + GifLoaderDialogUtils.showMyDialog(context); + await model.getFloors().then((_) => GifLoaderDialogUtils.hideDialog(context)); + if (model.state == ViewState.Idle && model.floorList.length > 0) { + openListDialogField('description', 'floorID', model.floorList, + (selectedValue) { setState(() { _selectedFloor = selectedValue; }); }); - } else if (model.state == - ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast( - model.error); + } else if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); } else { - DrAppToastMsg.showErrorToast( - "Empty List"); + DrAppToastMsg.showErrorToast("Empty List"); } }, ), @@ -273,46 +243,32 @@ class _AdmissionRequestSecondScreenState AppTextFieldCustom( height: screenSize.height * 0.075, hintText: TranslationBase.of(context).ward, - dropDownText: _selectedWard != null - ? _selectedWard['description'] - : null, + dropDownText: _selectedWard != null ? _selectedWard['description'] : null, enabled: false, isTextFieldHasSuffix: true, - onClick: model.wardList != null && - model.wardList.length > 0 + onClick: model.wardList != null && model.wardList.length > 0 ? () { - openListDialogField( - 'description', - 'nursingStationID', - model.wardList, (selectedValue) { + openListDialogField('description', 'nursingStationID', model.wardList, + (selectedValue) { setState(() { _selectedWard = selectedValue; }); }); } : () async { - GifLoaderDialogUtils.showMyDialog( - context); - await model.getWards().then((_) => - GifLoaderDialogUtils.hideDialog( - context)); - if (model.state == ViewState.Idle && - model.wardList.length > 0) { - openListDialogField( - 'description', - 'nursingStationID', - model.wardList, (selectedValue) { + GifLoaderDialogUtils.showMyDialog(context); + await model.getWards().then((_) => GifLoaderDialogUtils.hideDialog(context)); + if (model.state == ViewState.Idle && model.wardList.length > 0) { + openListDialogField('description', 'nursingStationID', model.wardList, + (selectedValue) { setState(() { _selectedWard = selectedValue; }); }); - } else if (model.state == - ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast( - model.error); + } else if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); } else { - DrAppToastMsg.showErrorToast( - "Empty List"); + DrAppToastMsg.showErrorToast("Empty List"); } }, ), @@ -321,54 +277,37 @@ class _AdmissionRequestSecondScreenState ), AppTextFieldCustom( height: screenSize.height * 0.075, - hintText: - TranslationBase.of(context).roomCategory, - dropDownText: _selectedRoomCategory != null - ? _selectedRoomCategory['description'] - : null, + hintText: TranslationBase.of(context).roomCategory, + dropDownText: + _selectedRoomCategory != null ? _selectedRoomCategory['description'] : null, enabled: false, isTextFieldHasSuffix: true, validationError: roomError, - onClick: model.roomCategoryList != null && - model.roomCategoryList.length > 0 + onClick: model.roomCategoryList != null && model.roomCategoryList.length > 0 ? () { - openListDialogField( - 'description', - 'categoryID', - model.roomCategoryList, + openListDialogField('description', 'categoryID', model.roomCategoryList, (selectedValue) { setState(() { - _selectedRoomCategory = - selectedValue; + _selectedRoomCategory = selectedValue; }); }); } : () async { - GifLoaderDialogUtils.showMyDialog( - context); - await model.getRoomCategories().then( - (_) => - GifLoaderDialogUtils.hideDialog( - context)); - if (model.state == ViewState.Idle && - model.roomCategoryList.length > 0) { - openListDialogField( - 'description', - 'categoryID', - model.roomCategoryList, + GifLoaderDialogUtils.showMyDialog(context); + await model + .getRoomCategories() + .then((_) => GifLoaderDialogUtils.hideDialog(context)); + if (model.state == ViewState.Idle && model.roomCategoryList.length > 0) { + openListDialogField('description', 'categoryID', model.roomCategoryList, (selectedValue) { setState(() { - _selectedRoomCategory = - selectedValue; + _selectedRoomCategory = selectedValue; }); }); - } else if (model.state == - ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast( - model.error); + } else if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); } else { - DrAppToastMsg.showErrorToast( - "Empty List"); + DrAppToastMsg.showErrorToast("Empty List"); } }, ), @@ -376,8 +315,7 @@ class _AdmissionRequestSecondScreenState height: 10, ), AppTextFieldCustom( - hintText: - TranslationBase.of(context).treatmentLine, + hintText: TranslationBase.of(context).treatmentLine, controller: _treatmentLineController, inputType: TextInputType.multiline, validationError: treatmentsError, @@ -388,8 +326,7 @@ class _AdmissionRequestSecondScreenState height: 10, ), AppTextFieldCustom( - hintText: - TranslationBase.of(context).complications, + hintText: TranslationBase.of(context).complications, controller: _complicationsController, inputType: TextInputType.multiline, validationError: complicationsError, @@ -400,8 +337,7 @@ class _AdmissionRequestSecondScreenState height: 10, ), AppTextFieldCustom( - hintText: - TranslationBase.of(context).otherProcedure, + hintText: TranslationBase.of(context).otherProcedure, controller: _otherProceduresController, inputType: TextInputType.multiline, validationError: proceduresError, @@ -413,53 +349,34 @@ class _AdmissionRequestSecondScreenState ), AppTextFieldCustom( height: screenSize.height * 0.075, - hintText: - TranslationBase.of(context).admissionType, - dropDownText: _selectedAdmissionType != null - ? _selectedAdmissionType['nameEn'] - : null, + hintText: TranslationBase.of(context).admissionType, + dropDownText: _selectedAdmissionType != null ? _selectedAdmissionType['nameEn'] : null, enabled: false, isTextFieldHasSuffix: true, validationError: admissionTypeError, - onClick: model.admissionTypeList != null && - model.admissionTypeList.length > 0 + onClick: model.admissionTypeList != null && model.admissionTypeList.length > 0 ? () { - openListDialogField('nameEn', 'id', - model.admissionTypeList, - (selectedValue) { + openListDialogField('nameEn', 'id', model.admissionTypeList, (selectedValue) { setState(() { - _selectedAdmissionType = - selectedValue; + _selectedAdmissionType = selectedValue; }); }); } : () async { - GifLoaderDialogUtils.showMyDialog( - context); + GifLoaderDialogUtils.showMyDialog(context); await model - .getMasterLookup(MasterKeysService - .AdmissionRequestType) - .then((_) => - GifLoaderDialogUtils.hideDialog( - context)); - if (model.state == ViewState.Idle && - model.admissionTypeList.length > - 0) { - openListDialogField('nameEn', 'id', - model.admissionTypeList, - (selectedValue) { + .getMasterLookup(MasterKeysService.AdmissionRequestType) + .then((_) => GifLoaderDialogUtils.hideDialog(context)); + if (model.state == ViewState.Idle && model.admissionTypeList.length > 0) { + openListDialogField('nameEn', 'id', model.admissionTypeList, (selectedValue) { setState(() { - _selectedAdmissionType = - selectedValue; + _selectedAdmissionType = selectedValue; }); }); - } else if (model.state == - ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast( - model.error); + } else if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); } else { - DrAppToastMsg.showErrorToast( - "Empty List"); + DrAppToastMsg.showErrorToast("Empty List"); } }, ), @@ -492,144 +409,115 @@ class _AdmissionRequestSecondScreenState title: TranslationBase.of(context).next, color: HexColor("#D02127"), onPressed: () async { + await locator().logEvent( + eventCategory: "Admission Request Second Screen", + eventAction: "Go To Admission Request Three", + ); if (_estimatedCostController.text != "" && _postPlansEstimatedCostController.text != "" && _expectedDaysController.text != "" && _expectedAdmissionDate != null && - _otherDepartmentsInterventionsController.text != - "" && + _otherDepartmentsInterventionsController.text != "" && _selectedFloor != null && - _selectedRoomCategory != - null /*_selectedWard is not required*/ && + _selectedRoomCategory != null /*_selectedWard is not required*/ && _treatmentLineController.text != "" && _complicationsController.text != "" && _otherProceduresController.text != "" && _selectedAdmissionType != null) { model.admissionRequestData = admissionRequest; - model.admissionRequestData.estimatedCost = - int.parse(_estimatedCostController.text); - model.admissionRequestData - .elementsForImprovement = + model.admissionRequestData.estimatedCost = int.parse(_estimatedCostController.text); + model.admissionRequestData.elementsForImprovement = _postPlansEstimatedCostController.text; - model.admissionRequestData.expectedDays = - int.parse(_expectedDaysController.text); - model.admissionRequestData.admissionDate = - _expectedAdmissionDate.toIso8601String(); - model.admissionRequestData - .otherDepartmentInterventions = + model.admissionRequestData.expectedDays = int.parse(_expectedDaysController.text); + model.admissionRequestData.admissionDate = _expectedAdmissionDate.toIso8601String(); + model.admissionRequestData.otherDepartmentInterventions = _otherDepartmentsInterventionsController.text; - model.admissionRequestData.admissionLocationID = - _selectedFloor['floorID']; + model.admissionRequestData.admissionLocationID = _selectedFloor['floorID']; model.admissionRequestData.wardID = - _selectedWard != null - ? _selectedWard['nursingStationID'] - : 0; - model.admissionRequestData.roomCategoryID = - _selectedRoomCategory['categoryID']; + _selectedWard != null ? _selectedWard['nursingStationID'] : 0; + model.admissionRequestData.roomCategoryID = _selectedRoomCategory['categoryID']; - model.admissionRequestData - .admissionRequestProcedures = []; + model.admissionRequestData.admissionRequestProcedures = []; - model.admissionRequestData.mainLineOfTreatment = - _treatmentLineController.text; - model.admissionRequestData.complications = - _complicationsController.text; - model.admissionRequestData.otherProcedures = - _otherProceduresController.text; - model.admissionRequestData.admissionType = - _selectedAdmissionType['id']; + model.admissionRequestData.mainLineOfTreatment = _treatmentLineController.text; + model.admissionRequestData.complications = _complicationsController.text; + model.admissionRequestData.otherProcedures = _otherProceduresController.text; + model.admissionRequestData.admissionType = _selectedAdmissionType['id']; - Navigator.of(context).pushNamed( - PATIENT_ADMISSION_REQUEST_3, - arguments: { - 'patient': patient, - 'patientType': patientType, - 'arrivalType': arrivalType, - 'admission-data': model.admissionRequestData - }); + Navigator.of(context).pushNamed(PATIENT_ADMISSION_REQUEST_3, arguments: { + 'patient': patient, + 'patientType': patientType, + 'arrivalType': arrivalType, + 'admission-data': model.admissionRequestData + }); } else { - DrAppToastMsg.showErrorToast( - TranslationBase.of(context).pleaseFill); + DrAppToastMsg.showErrorToast(TranslationBase.of(context).pleaseFill); setState(() { if (_estimatedCostController.text == "") { - costError = - TranslationBase.of(context).fieldRequired; + costError = TranslationBase.of(context).fieldRequired; } else { costError = null; } - if (_postPlansEstimatedCostController.text == - "") { - plansError = - TranslationBase.of(context).fieldRequired; + if (_postPlansEstimatedCostController.text == "") { + plansError = TranslationBase.of(context).fieldRequired; } else { plansError = null; } if (_expectedDaysController.text == "") { - expectedDaysError = - TranslationBase.of(context).fieldRequired; + expectedDaysError = TranslationBase.of(context).fieldRequired; } else { expectedDaysError = null; } if (_expectedAdmissionDate == null) { - expectedDatesError = - TranslationBase.of(context).fieldRequired; + expectedDatesError = TranslationBase.of(context).fieldRequired; } else { expectedDatesError = null; } - if (_otherDepartmentsInterventionsController - .text == - "") { - otherInterventionsError = - TranslationBase.of(context).fieldRequired; + if (_otherDepartmentsInterventionsController.text == "") { + otherInterventionsError = TranslationBase.of(context).fieldRequired; } else { otherInterventionsError = null; } if (_selectedFloor == null) { - floorError = - TranslationBase.of(context).fieldRequired; + floorError = TranslationBase.of(context).fieldRequired; } else { floorError = null; } if (_selectedRoomCategory == null) { - roomError = - TranslationBase.of(context).fieldRequired; + roomError = TranslationBase.of(context).fieldRequired; } else { roomError = null; } if (_treatmentLineController.text == "") { - treatmentsError = - TranslationBase.of(context).fieldRequired; + treatmentsError = TranslationBase.of(context).fieldRequired; } else { treatmentsError = null; } if (_complicationsController.text == "") { - complicationsError = - TranslationBase.of(context).fieldRequired; + complicationsError = TranslationBase.of(context).fieldRequired; } else { complicationsError = null; } if (_otherProceduresController.text == "") { - proceduresError = - TranslationBase.of(context).fieldRequired; + proceduresError = TranslationBase.of(context).fieldRequired; } else { proceduresError = null; } if (_selectedAdmissionType == null) { - admissionTypeError = - TranslationBase.of(context).fieldRequired; + admissionTypeError = TranslationBase.of(context).fieldRequired; } else { admissionTypeError = null; } @@ -647,8 +535,7 @@ class _AdmissionRequestSecondScreenState ); } - Future _selectDate(BuildContext context, DateTime dateTime, - Function(DateTime picked) updateDate) async { + Future _selectDate(BuildContext context, DateTime dateTime, Function(DateTime picked) updateDate) async { final DateTime picked = await showDatePicker( context: context, initialDate: dateTime, @@ -661,8 +548,8 @@ class _AdmissionRequestSecondScreenState } } - void openListDialogField(String attributeName, String attributeValueId, - List list, Function(dynamic selectedValue) okFunction) { + void openListDialogField( + String attributeName, String attributeValueId, List list, Function(dynamic selectedValue) okFunction) { ListSelectDialog dialog = ListSelectDialog( list: list, attributeName: attributeName, diff --git a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart index a5c367de..e4463bab 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart @@ -1,8 +1,10 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/service/AnalyticsService.dart'; import 'package:doctor_app_flutter/core/viewModel/PatientMedicalReportViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; +import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; @@ -75,11 +77,14 @@ class _MedicalReportPageState extends State { ), ), AddNewOrder( - onTap: () { + onTap: () async { // if (model.hasOnHold()) { // Helpers.showErrorToast("Please Verified the on hold report to be able to add new one"); // } else - + await locator().logEvent( + eventCategory: "Medical Report Page", + eventAction: "Add New Medical Report", + ); Navigator.push( context, MaterialPageRoute( @@ -91,147 +96,146 @@ class _MedicalReportPageState extends State { status: MedicalReportStatus.ADD, )), ); - }, label: TranslationBase.of(context).createNewMedicalReport, ), - // if (model.state != ViewState.ErrorLocal)ß - ...List.generate( - model.medicalReportList.length, - (index) => InkWell( - onTap: () { - if (model.medicalReportList[index].status == 1) { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => AddVerifyMedicalReport( - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - medicalReport: model.medicalReportList[index], - model: model, - medicalNote: model.medicalReportList[index].reportDataHtml, - )), - ); - } else { - Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_DETAIL, arguments: { - 'patient': patient, - 'patientType': patientType, - 'arrivalType': arrivalType, - 'type': MedicalReportStatus.ADD, - 'medicalReport': model.medicalReportList[index], - 'model': model, - }); - } - }, - child: Container( - margin: EdgeInsets.symmetric(horizontal: 8), - child: CardWithBgWidget( - hasBorder: false, - bgColor: model.medicalReportList[index].status == 1 ? Color(0xFFCC9B14) : Colors.green[700], - widget: Column( - children: [ - Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - model.medicalReportList[index].status == 1 - ? TranslationBase.of(context).onHold - : TranslationBase.of(context).verified, - color: model.medicalReportList[index].status == 1 - ? Color(0xFFCC9B14) - : Colors.green[700], - fontSize: 1.4 * SizeConfig.textMultiplier, - bold: true, - ), - AppText( - projectViewModel.isArabic - ? model.medicalReportList[index].doctorNameN ?? "" - : model.medicalReportList[index].doctorName ?? "", - fontSize: 1.9 * SizeConfig.textMultiplier, - fontWeight: FontWeight.w700, - color: Color(0xFF2E303A), - ), - ], + // if (model.state != ViewState.ErrorLocal)ß + ...List.generate( + model.medicalReportList.length, + (index) => InkWell( + onTap: () { + if (model.medicalReportList[index].status == 1) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => AddVerifyMedicalReport( + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + medicalReport: model.medicalReportList[index], + model: model, + medicalNote: model.medicalReportList[index].reportDataHtml, )), - Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - AppText( - '${AppDateUtils.convertDateFromServerFormat(model.medicalReportList[index].editedOn ?? model.medicalReportList[index].createdOn, "dd MMM yyyy")}', - color: Color(0xFF2E303A), - fontWeight: FontWeight.w600, - fontSize: 1.6 * SizeConfig.textMultiplier, - ), - AppText( - '${AppDateUtils.convertDateFromServerFormat(model.medicalReportList[index].editedOn ?? model.medicalReportList[index].createdOn, "hh:mm a")}', - color: Color(0xFF2E303A), - fontWeight: FontWeight.w600, - fontSize: 1.5 * SizeConfig.textMultiplier, - ), - ], - ), - ], - ), - Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Container( - margin: EdgeInsets.only(left: 0, top: 4, right: 8, bottom: 0), - child: LargeAvatar( - name: projectViewModel.isArabic - ? model.medicalReportList[index].doctorNameN - : model.medicalReportList[index].doctorName, - url: model.medicalReportList[index].doctorImageURL, + ); + } else { + Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_DETAIL, arguments: { + 'patient': patient, + 'patientType': patientType, + 'arrivalType': arrivalType, + 'type': MedicalReportStatus.ADD, + 'medicalReport': model.medicalReportList[index], + 'model': model, + }); + } + }, + child: Container( + margin: EdgeInsets.symmetric(horizontal: 8), + child: CardWithBgWidget( + hasBorder: false, + bgColor: model.medicalReportList[index].status == 1 ? Color(0xFFCC9B14) : Colors.green[700], + widget: Column( + children: [ + Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + model.medicalReportList[index].status == 1 + ? TranslationBase.of(context).onHold + : TranslationBase.of(context).verified, + color: model.medicalReportList[index].status == 1 + ? Color(0xFFCC9B14) + : Colors.green[700], + fontSize: 1.4 * SizeConfig.textMultiplier, + bold: true, ), - width: 50, - height: 50, - ), - Expanded( - child: Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - projectViewModel.isArabic - ? model.medicalReportList[index].projectNameN - : model.medicalReportList[index].projectName, - fontSize: 1.6 * SizeConfig.textMultiplier, - color: Color(0xFF2E303A), - ), - AppText( - projectViewModel.isArabic - ? model.medicalReportList[index].clinicNameN - : model.medicalReportList[index].clinicName, - fontSize: 1.6 * SizeConfig.textMultiplier, - color: Color(0xFF2E303A), - ), - ], - ), + AppText( + projectViewModel.isArabic + ? model.medicalReportList[index].doctorNameN ?? "" + : model.medicalReportList[index].doctorName ?? "", + fontSize: 1.9 * SizeConfig.textMultiplier, + fontWeight: FontWeight.w700, + color: Color(0xFF2E303A), ), + ], + )), + Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + AppText( + '${AppDateUtils.convertDateFromServerFormat(model.medicalReportList[index].editedOn ?? model.medicalReportList[index].createdOn, "dd MMM yyyy")}', + color: Color(0xFF2E303A), + fontWeight: FontWeight.w600, + fontSize: 1.6 * SizeConfig.textMultiplier, + ), + AppText( + '${AppDateUtils.convertDateFromServerFormat(model.medicalReportList[index].editedOn ?? model.medicalReportList[index].createdOn, "hh:mm a")}', + color: Color(0xFF2E303A), + fontWeight: FontWeight.w600, + fontSize: 1.5 * SizeConfig.textMultiplier, + ), + ], + ), + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + margin: EdgeInsets.only(left: 0, top: 4, right: 8, bottom: 0), + child: LargeAvatar( + name: projectViewModel.isArabic + ? model.medicalReportList[index].doctorNameN + : model.medicalReportList[index].doctorName, + url: model.medicalReportList[index].doctorImageURL, ), - Container( - height: 50, + width: 50, + height: 50, + ), + Expanded( + child: Container( child: Column( - mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Icon( - model.medicalReportList[index].status == 1 ? DoctorApp.edit_1 : EvaIcons.eye, + AppText( + projectViewModel.isArabic + ? model.medicalReportList[index].projectNameN + : model.medicalReportList[index].projectName, + fontSize: 1.6 * SizeConfig.textMultiplier, + color: Color(0xFF2E303A), + ), + AppText( + projectViewModel.isArabic + ? model.medicalReportList[index].clinicNameN + : model.medicalReportList[index].clinicName, + fontSize: 1.6 * SizeConfig.textMultiplier, + color: Color(0xFF2E303A), ), ], ), - ) - ], - ), - ], - ), + ), + ), + Container( + height: 50, + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Icon( + model.medicalReportList[index].status == 1 ? DoctorApp.edit_1 : EvaIcons.eye, + ), + ], + ), + ) + ], + ), + ], ), ), ), ), + ), SizedBox( height: 15, ) diff --git a/lib/screens/patients/profile/note/progress_note_screen.dart b/lib/screens/patients/profile/note/progress_note_screen.dart index 723ee75f..8b3f4500 100644 --- a/lib/screens/patients/profile/note/progress_note_screen.dart +++ b/lib/screens/patients/profile/note/progress_note_screen.dart @@ -1,9 +1,11 @@ import 'package:doctor_app_flutter/core/model/note/note_model.dart'; import 'package:doctor_app_flutter/core/model/note/update_note_model.dart'; +import 'package:doctor_app_flutter/core/service/AnalyticsService.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; +import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/models/patient/progress_note_request.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/patients/profile/note/update_note.dart'; @@ -43,8 +45,7 @@ class _ProgressNoteState extends State { AuthenticationViewModel authenticationViewModel; ProjectViewModel projectViewModel; - getProgressNoteList(BuildContext context, PatientViewModel model, - {bool isLocalBusy = false}) async { + getProgressNoteList(BuildContext context, PatientViewModel model, {bool isLocalBusy = false}) async { final routeArgs = ModalRoute.of(context).settings.arguments as Map; PatiantInformtion patient = routeArgs['patient']; String token = await sharedPref.getString(TOKEN); @@ -59,10 +60,7 @@ class _ProgressNoteState extends State { tokenID: token, patientTypeID: patient.patientType, languageID: 2); - model - .getPatientProgressNote(progressNoteRequest.toJson(), - isLocalBusy: isLocalBusy) - .then((c) { + model.getPatientProgressNote(progressNoteRequest.toJson(), isLocalBusy: isLocalBusy).then((c) { notesList = model.patientProgressNoteList; }); } @@ -71,170 +69,111 @@ class _ProgressNoteState extends State { Widget build(BuildContext context) { authenticationViewModel = Provider.of(context); projectViewModel = Provider.of(context); - final routeArgs = ModalRoute - .of(context) - .settings - .arguments as Map; + final routeArgs = ModalRoute.of(context).settings.arguments as Map; PatiantInformtion patient = routeArgs['patient']; String arrivalType = routeArgs['arrivalType']; - if (routeArgs.containsKey('isDischargedPatient')) - isDischargedPatient = routeArgs['isDischargedPatient']; + if (routeArgs.containsKey('isDischargedPatient')) isDischargedPatient = routeArgs['isDischargedPatient']; return BaseView( onModelReady: (model) => getProgressNoteList(context, model), - builder: (_, model, w) => - AppScaffold( - baseViewModel: model, - backgroundColor: Theme - .of(context) - .scaffoldBackgroundColor, - // appBarTitle: TranslationBase.of(context).progressNote, - appBar: PatientProfileAppBar( - patient, - isInpatient: true, - ), - body: model.patientProgressNoteList == null || - model.patientProgressNoteList.length == 0 - ? DrAppEmbeddedError( - error: TranslationBase - .of(context) - .errorNoProgressNote) - : Container( - color: Colors.grey[200], - child: Column( - children: [ - if (!isDischargedPatient) - AddNewOrder( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - UpdateNoteOrder( - patientModel: model, - patient: patient, - visitType: widget.visitType, - isUpdate: false, - )), - ); - }, - label: widget.visitType == 3 - ? TranslationBase - .of(context) - .addNewOrderSheet - : TranslationBase - .of(context) - .addProgressNote, - ), - Expanded( - child: Container( - child: ListView.builder( - itemCount: model.patientProgressNoteList.length, - itemBuilder: (BuildContext ctxt, int index) { - return FractionallySizedBox( - widthFactor: 0.95, - child: CardWithBgWidget( - hasBorder: false, - bgColor: model.patientProgressNoteList[index] - .status == - 1 && - authenticationViewModel.doctorProfile.doctorID != - model - .patientProgressNoteList[ - index] - .createdBy - ? Color(0xFFCC9B14) - : model.patientProgressNoteList[index] - .status == - 4 - ? Colors.red.shade700 - : model.patientProgressNoteList[index] - .status == - 2 - ? Colors.green[600] - : Color(0xFFCC9B14), - widget: Column( - children: [ - Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - if (model - .patientProgressNoteList[ - index] - .status == - 1 && - authenticationViewModel - .doctorProfile.doctorID != - model - .patientProgressNoteList[ - index] - .createdBy) - AppText( - TranslationBase - .of(context) - .notePending, - fontWeight: FontWeight.bold, - color: Color(0xFFCC9B14), - fontSize: 12, - ), - if (model - .patientProgressNoteList[ - index] - .status == - 4) + builder: (_, model, w) => AppScaffold( + baseViewModel: model, + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + // appBarTitle: TranslationBase.of(context).progressNote, + appBar: PatientProfileAppBar( + patient, + isInpatient: true, + ), + body: model.patientProgressNoteList == null || model.patientProgressNoteList.length == 0 + ? DrAppEmbeddedError(error: TranslationBase.of(context).errorNoProgressNote) + : Container( + color: Colors.grey[200], + child: Column( + children: [ + if (!isDischargedPatient) + AddNewOrder( + onTap: () async { + await locator().logEvent( + eventCategory: "Progress Note Screen", + eventAction: "Update Progress Note", + ); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => UpdateNoteOrder( + patientModel: model, + patient: patient, + visitType: widget.visitType, + isUpdate: false, + )), + ); + }, + label: widget.visitType == 3 + ? TranslationBase.of(context).addNewOrderSheet + : TranslationBase.of(context).addProgressNote, + ), + Expanded( + child: Container( + child: ListView.builder( + itemCount: model.patientProgressNoteList.length, + itemBuilder: (BuildContext ctxt, int index) { + return FractionallySizedBox( + widthFactor: 0.95, + child: CardWithBgWidget( + hasBorder: false, + bgColor: model.patientProgressNoteList[index].status == 1 && + authenticationViewModel.doctorProfile.doctorID != + model.patientProgressNoteList[index].createdBy + ? Color(0xFFCC9B14) + : model.patientProgressNoteList[index].status == 4 + ? Colors.red.shade700 + : model.patientProgressNoteList[index].status == 2 + ? Colors.green[600] + : Color(0xFFCC9B14), + widget: Column( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (model.patientProgressNoteList[index].status == 1 && + authenticationViewModel.doctorProfile.doctorID != + model.patientProgressNoteList[index].createdBy) AppText( - TranslationBase - .of(context) - .noteCanceled, + TranslationBase.of(context).notePending, + fontWeight: FontWeight.bold, + color: Color(0xFFCC9B14), + fontSize: 12, + ), + if (model.patientProgressNoteList[index].status == 4) + AppText( + TranslationBase.of(context).noteCanceled, fontWeight: FontWeight.bold, color: Colors.red.shade700, fontSize: 12, ), - if (model - .patientProgressNoteList[ - index] - .status == - 2) + if (model.patientProgressNoteList[index].status == 2) AppText( - TranslationBase - .of(context) - .noteVerified, + TranslationBase.of(context).noteVerified, fontWeight: FontWeight.bold, color: Colors.green[600], fontSize: 12, ), if (model.patientProgressNoteList[index].status != 2 && - model - .patientProgressNoteList[ - index] - .status != - 4 && - authenticationViewModel - .doctorProfile.doctorID == - model - .patientProgressNoteList[ - index] - .createdBy) + model.patientProgressNoteList[index].status != 4 && + authenticationViewModel.doctorProfile.doctorID == + model.patientProgressNoteList[index].createdBy) Row( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ InkWell( onTap: () { Navigator.push( context, MaterialPageRoute( - builder: (context) => - UpdateNoteOrder( - note: model - .patientProgressNoteList[ - index], - patientModel: - model, - patient: - patient, - visitType: widget - .visitType, + builder: (context) => UpdateNoteOrder( + note: model.patientProgressNoteList[index], + patientModel: model, + patient: patient, + visitType: widget.visitType, isUpdate: true, )), ); @@ -242,9 +181,7 @@ class _ProgressNoteState extends State { child: Container( decoration: BoxDecoration( color: Colors.grey[600], - borderRadius: - BorderRadius.circular( - 10), + borderRadius: BorderRadius.circular(10), ), // color:Colors.red[600], @@ -259,10 +196,7 @@ class _ProgressNoteState extends State { width: 2, ), AppText( - TranslationBase - .of( - context) - .update, + TranslationBase.of(context).update, fontSize: 10, color: Colors.white, ), @@ -280,61 +214,33 @@ class _ProgressNoteState extends State { context: context, actionName: "verify", confirmFun: () async { - GifLoaderDialogUtils - .showMyDialog( - context); - UpdateNoteReqModel - reqModel = - UpdateNoteReqModel( - admissionNo: int - .parse(patient - .admissionNo), - cancelledNote: - false, - lineItemNo: model - .patientProgressNoteList[ - index] - .lineItemNo, - createdBy: model - .patientProgressNoteList[ - index] - .createdBy, - notes: model - .patientProgressNoteList[ - index] - .notes, + GifLoaderDialogUtils.showMyDialog(context); + UpdateNoteReqModel reqModel = UpdateNoteReqModel( + admissionNo: int.parse(patient.admissionNo), + cancelledNote: false, + lineItemNo: model.patientProgressNoteList[index].lineItemNo, + createdBy: model.patientProgressNoteList[index].createdBy, + notes: model.patientProgressNoteList[index].notes, verifiedNote: true, - patientTypeID: - patient - .patientType, + patientTypeID: patient.patientType, patientOutSA: false, ); - await model - .updatePatientProgressNote( - reqModel); - await getProgressNoteList( - context, model, - isLocalBusy: - true); - GifLoaderDialogUtils - .hideDialog( - context); + await model.updatePatientProgressNote(reqModel); + await getProgressNoteList(context, model, isLocalBusy: true); + GifLoaderDialogUtils.hideDialog(context); }); }, child: Container( decoration: BoxDecoration( color: Colors.green[600], - borderRadius: - BorderRadius.circular( - 10), + borderRadius: BorderRadius.circular(10), ), // color:Colors.red[600], child: Row( children: [ Icon( - FontAwesomeIcons - .check, + FontAwesomeIcons.check, size: 12, color: Colors.white, ), @@ -342,10 +248,7 @@ class _ProgressNoteState extends State { width: 2, ), AppText( - TranslationBase - .of( - context) - .noteVerify, + TranslationBase.of(context).noteVerify, fontSize: 10, color: Colors.white, ), @@ -361,67 +264,37 @@ class _ProgressNoteState extends State { onTap: () async { showMyDialog( context: context, - actionName: - TranslationBase - .of( - context) - .cancel, + actionName: TranslationBase.of(context).cancel, confirmFun: () async { - GifLoaderDialogUtils - .showMyDialog( + GifLoaderDialogUtils.showMyDialog( context, ); - UpdateNoteReqModel - reqModel = - UpdateNoteReqModel( - admissionNo: int - .parse(patient - .admissionNo), + UpdateNoteReqModel reqModel = UpdateNoteReqModel( + admissionNo: int.parse(patient.admissionNo), cancelledNote: true, - lineItemNo: model - .patientProgressNoteList[ - index] - .lineItemNo, - createdBy: model - .patientProgressNoteList[ - index] - .createdBy, - notes: model - .patientProgressNoteList[ - index] - .notes, + lineItemNo: model.patientProgressNoteList[index].lineItemNo, + createdBy: model.patientProgressNoteList[index].createdBy, + notes: model.patientProgressNoteList[index].notes, verifiedNote: false, - patientTypeID: - patient - .patientType, + patientTypeID: patient.patientType, patientOutSA: false, ); - await model - .updatePatientProgressNote( - reqModel); - await getProgressNoteList( - context, model, - isLocalBusy: - true); - GifLoaderDialogUtils - .hideDialog( - context); + await model.updatePatientProgressNote(reqModel); + await getProgressNoteList(context, model, isLocalBusy: true); + GifLoaderDialogUtils.hideDialog(context); }); }, child: Container( decoration: BoxDecoration( color: Colors.red[600], - borderRadius: - BorderRadius.circular( - 10), + borderRadius: BorderRadius.circular(10), ), // color:Colors.red[600], child: Row( children: [ Icon( - FontAwesomeIcons - .trash, + FontAwesomeIcons.trash, size: 12, color: Colors.white, ), @@ -447,41 +320,25 @@ class _ProgressNoteState extends State { height: 10, ), Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - crossAxisAlignment: - CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - width: MediaQuery.of(context) - .size - .width * - 0.60, + width: MediaQuery.of(context).size.width * 0.60, child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( - crossAxisAlignment: - CrossAxisAlignment - .start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( - TranslationBase - .of( - context) - .createdBy, + TranslationBase.of(context).createdBy, fontSize: 10, ), Expanded( child: AppText( - model - .patientProgressNoteList[ - index] - .doctorName ?? - '', - fontWeight: - FontWeight.w600, + model.patientProgressNoteList[index].doctorName ?? '', + fontWeight: FontWeight.w600, fontSize: 12, ), ), @@ -493,85 +350,55 @@ class _ProgressNoteState extends State { Column( children: [ AppText( - model - .patientProgressNoteList[ - index] - .createdOn != - null + model.patientProgressNoteList[index].createdOn != null ? AppDateUtils.getDayMonthYearDateFormatted( - AppDateUtils - .getDateTimeFromServerFormat( - model - .patientProgressNoteList[ - index] - .createdOn), - isArabic: - projectViewModel - .isArabic) - : AppDateUtils - .getDayMonthYearDateFormatted( - DateTime.now(), - isArabic: - projectViewModel - .isArabic), + AppDateUtils.getDateTimeFromServerFormat( + model.patientProgressNoteList[index].createdOn), + isArabic: projectViewModel.isArabic) + : AppDateUtils.getDayMonthYearDateFormatted(DateTime.now(), + isArabic: projectViewModel.isArabic), fontWeight: FontWeight.w600, fontSize: 14, ), AppText( - model - .patientProgressNoteList[ - index] - .createdOn != - null - ? AppDateUtils.getHour(AppDateUtils - .getDateTimeFromServerFormat( - model - .patientProgressNoteList[ - index] - .createdOn)) - : AppDateUtils.getHour( - DateTime.now()), + model.patientProgressNoteList[index].createdOn != null + ? AppDateUtils.getHour(AppDateUtils.getDateTimeFromServerFormat( + model.patientProgressNoteList[index].createdOn)) + : AppDateUtils.getHour(DateTime.now()), fontWeight: FontWeight.w600, fontSize: 14, ), ], - crossAxisAlignment: - CrossAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.end, ) ], ), SizedBox( height: 8, ), - Row( - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - Expanded( - child: AppText( - model - .patientProgressNoteList[ - index] - .notes, - fontSize: 10, - ), - ), - ]) - ], - ), - SizedBox( - height: 20, - ), - ], + Row(mainAxisAlignment: MainAxisAlignment.start, children: [ + Expanded( + child: AppText( + model.patientProgressNoteList[index].notes, + fontSize: 10, + ), + ), + ]) + ], + ), + SizedBox( + height: 20, + ), + ], + ), ), - ), - ); - }), + ); + }), + ), ), - ), - ], + ], + ), ), - ), ), ); } @@ -580,100 +407,92 @@ class _ProgressNoteState extends State { showDialog( context: context, builder: (ctx) => Center( - child: Container( - width: MediaQuery - .of(context) - .size - .width * 0.8, - height: 200, - child: AppScaffold( - isShowAppBar: false, - body: Container( - color: Colors.white, - child: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - // SizedBox(height: 20,), - SizedBox( - height: 10, - ), - Row( + child: Container( + width: MediaQuery.of(context).size.width * 0.8, + height: 200, + child: AppScaffold( + isShowAppBar: false, + body: Container( + color: Colors.white, + child: Center( + child: Column( mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, children: [ - AppText( - TranslationBase - .of(context) - .noteConfirm, - fontWeight: FontWeight.w600, - color: Colors.black, - fontSize: 16, + // SizedBox(height: 20,), + SizedBox( + height: 10, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + AppText( + TranslationBase.of(context).noteConfirm, + fontWeight: FontWeight.w600, + color: Colors.black, + fontSize: 16, + ), + ], + ), + SizedBox( + height: 10, + ), + DividerWithSpacesAround(), + SizedBox( + height: 12, ), - ], - ), - SizedBox( - height: 10, - ), - DividerWithSpacesAround(), - SizedBox( - height: 12, - ), - Container( - padding: EdgeInsets.all(20), - color: Colors.white, - child: AppText( - projectViewModel.isArabic?"هل أنت متأكد أنك تريد تنفيذ $actionName هذا الأمر؟":'Are you sure you want $actionName this order?', - fontSize: 15, - textAlign: TextAlign.center, - ), - ), + Container( + padding: EdgeInsets.all(20), + color: Colors.white, + child: AppText( + projectViewModel.isArabic + ? "هل أنت متأكد أنك تريد تنفيذ $actionName هذا الأمر؟" + : 'Are you sure you want $actionName this order?', + fontSize: 15, + textAlign: TextAlign.center, + ), + ), - SizedBox( - height: 8, + SizedBox( + height: 8, + ), + DividerWithSpacesAround(), + FractionallySizedBox( + widthFactor: 0.75, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + FlatButton( + child: AppText( + TranslationBase.of(context).cancel, + fontWeight: FontWeight.w600, + color: Colors.black, + fontSize: 16, + ), //Text("Cancel"), + onPressed: () { + Navigator.of(context).pop(); + }), + FlatButton( + child: AppText( + TranslationBase.of(context).noteConfirm, + fontWeight: FontWeight.w600, + color: Colors.red.shade700, + fontSize: 16, + ), //Text("Confirm", ), + onPressed: () async { + await confirmFun(); + Navigator.of(context).pop(); + }) + ], + ), + ) + ], ), - DividerWithSpacesAround(), - FractionallySizedBox( - widthFactor: 0.75, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - FlatButton( - child: AppText( - TranslationBase - .of(context) - .cancel, - fontWeight: FontWeight.w600, - color: Colors.black, - fontSize: 16, - ), //Text("Cancel"), - onPressed: () { - Navigator.of(context).pop(); - }), - FlatButton( - child: AppText( - TranslationBase - .of(context) - .noteConfirm, - fontWeight: FontWeight.w600, - color: Colors.red.shade700, - fontSize: 16, - ), //Text("Confirm", ), - onPressed: () async { - await confirmFun(); - Navigator.of(context).pop(); - }) - ], - ), - ) - ], + ), ), ), ), - ), - ), - ) - ); + )); } } diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index 1cbc67d8..a225773c 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/service/AnalyticsService.dart'; import 'package:doctor_app_flutter/core/service/VideoCallService.dart'; import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; @@ -232,6 +233,10 @@ class _PatientProfileScreenState extends State with Single onPressed: () async { if ((isFromLiveCare && patient.appointmentNo != null) || patient.patientStatusType == 43) { + await locator().logEvent( + eventCategory: "Patient Profile", + eventAction: "Create Episode", + ); PostEpisodeReqModel postEpisodeReqModel = PostEpisodeReqModel( appointmentNo: int.parse(patient.appointmentNo.toString()), patientMRN: patient.patientMRN); @@ -264,7 +269,11 @@ class _PatientProfileScreenState extends State with Single color: Colors.white, height: 30, ), - onPressed: () { + onPressed: () async { + await locator().logEvent( + eventCategory: "Patient Profile ", + eventAction: "Update Episode", + ); if ((isFromLiveCare && patient.appointmentNo != null && patient.appointmentNo != 0) || diff --git a/lib/screens/patients/profile/radiology/radiology_details_page.dart b/lib/screens/patients/profile/radiology/radiology_details_page.dart index 48bef68a..93613275 100644 --- a/lib/screens/patients/profile/radiology/radiology_details_page.dart +++ b/lib/screens/patients/profile/radiology/radiology_details_page.dart @@ -1,4 +1,5 @@ import 'package:doctor_app_flutter/core/model/radiology/final_radiology.dart'; +import 'package:doctor_app_flutter/core/service/AnalyticsService.dart'; import 'package:doctor_app_flutter/core/viewModel/radiology_view_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; @@ -11,6 +12,8 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:url_launcher/url_launcher.dart'; +import '../../../../locator.dart'; + class RadiologyDetailsPage extends StatelessWidget { final FinalRadiology finalRadiology; final PatiantInformtion patient; @@ -19,12 +22,7 @@ class RadiologyDetailsPage extends StatelessWidget { final bool isInpatient; RadiologyDetailsPage( - {Key key, - this.finalRadiology, - this.patient, - this.patientType, - this.arrivalType, - this.isInpatient = false}); + {Key key, this.finalRadiology, this.patient, this.patientType, this.arrivalType, this.isInpatient = false}); @override Widget build(BuildContext context) { @@ -36,7 +34,7 @@ class RadiologyDetailsPage extends StatelessWidget { invoiceNo: finalRadiology.invoiceNo), builder: (_, model, widget) => AppScaffold( appBar: PatientProfileAppBar( - patient, + patient, appointmentDate: finalRadiology.orderDate, doctorName: finalRadiology.doctorName, clinic: finalRadiology.clinicDescription, @@ -44,7 +42,6 @@ class RadiologyDetailsPage extends StatelessWidget { profileUrl: finalRadiology.doctorImageURL, invoiceNO: finalRadiology.invoiceNo.toString(), isAppointmentHeader: true, - ), isShowAppBar: true, baseViewModel: model, @@ -68,9 +65,11 @@ class RadiologyDetailsPage extends StatelessWidget { ), Padding( padding: const EdgeInsets.all(8.0), - child: AppText(TranslationBase.of(context).generalResult,color: Color(0xff2E303A),), + child: AppText( + TranslationBase.of(context).generalResult, + color: Color(0xff2E303A), + ), ), - Padding( padding: const EdgeInsets.all(8.0), child: AppText( @@ -94,13 +93,16 @@ class RadiologyDetailsPage extends StatelessWidget { height: 80, width: double.maxFinite, child: Container( - margin: - EdgeInsets.only(left: 35, right: 35, top: 12, bottom: 12), + margin: EdgeInsets.only(left: 35, right: 35, top: 12, bottom: 12), child: SecondaryButton( color: Color(0xffD02127), disabled: finalRadiology.dIAPACSURL == "", textColor: Color(0xffFFFFFF), - onTap: () { + onTap: () async { + await locator().logEvent( + eventCategory: "RadiologyDetailsPage", + eventAction: "Open Radiology Image", + ); launch(model.radImageURL); }, label: TranslationBase.of(context).openRad, diff --git a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart index e4b8700c..251a91fa 100644 --- a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart +++ b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart @@ -3,8 +3,10 @@ import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/referral/MyReferralPatientModel.dart'; import 'package:doctor_app_flutter/core/model/referral/add_referred_remarks_request.dart'; import 'package:doctor_app_flutter/core/provider/robot_provider.dart'; +import 'package:doctor_app_flutter/core/service/AnalyticsService.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-referral-viewmodel.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; +import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/bottom_sheet_title.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; @@ -138,6 +140,10 @@ class _AddReplayOnReferralPatientState extends State Expanded( child: AppButton( onPressed: () async { + await locator().logEvent( + eventCategory: "Add Replay On Referral Patient", + eventAction: "Add Replay on Referral", + ); if (replayOnReferralController.text.isNotEmpty) { GifLoaderDialogUtils.showMyDialog(context); await widget.patientReferralViewModel.replayReferred( diff --git a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart index 4cc5effd..8bf89d87 100644 --- a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart @@ -18,8 +18,7 @@ import 'package:flutter/material.dart'; class MyReferralDetailScreen extends StatelessWidget { final MyReferralPatientModel referralPatient; - const MyReferralDetailScreen({Key key, this.referralPatient}) - : super(key: key); + const MyReferralDetailScreen({Key key, this.referralPatient}) : super(key: key); @override Widget build(BuildContext context) { @@ -54,8 +53,7 @@ class MyReferralDetailScreen extends StatelessWidget { ), Expanded( child: AppText( - (Helpers.capitalize(referralPatient.firstName + " "+ - referralPatient.lastName)), + (Helpers.capitalize(referralPatient.firstName + " " + referralPatient.lastName)), fontSize: SizeConfig.textMultiplier * 2.5, fontWeight: FontWeight.bold, fontFamily: 'Poppins', @@ -95,62 +93,48 @@ class MyReferralDetailScreen extends StatelessWidget { child: Column( children: [ Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ AppText( referralPatient.referralStatus != null - ? model.getReferralStatusNameByCode( - referralPatient.referralStatus, - context) + ? model.getReferralStatusNameByCode(referralPatient.referralStatus, context) : "", fontFamily: 'Poppins', fontSize: 1.9 * SizeConfig.textMultiplier, fontWeight: FontWeight.w700, color: referralPatient.referralStatus == 1 ? Color(0xffc4aa54) - : referralPatient.referralStatus == - 46 || - referralPatient - .referralStatus == - 2 + : referralPatient.referralStatus == 46 || referralPatient.referralStatus == 2 ? Colors.green[700] : Colors.red[700], ), AppText( - AppDateUtils.getDayMonthYearDateFormatted( - referralPatient.referralDate), + AppDateUtils.getDayMonthYearDateFormatted(referralPatient.referralDate), fontFamily: 'Poppins', fontWeight: FontWeight.w600, - fontSize: - 2.0 * SizeConfig.textMultiplier, + fontSize: 2.0 * SizeConfig.textMultiplier, color: Color(0XFF28353E), ) ], ), Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( - mainAxisAlignment: - MainAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, children: [ AppText( - TranslationBase.of(context) - .fileNumber, + TranslationBase.of(context).fileNumber, fontFamily: 'Poppins', fontWeight: FontWeight.w600, - fontSize: - 1.7 * SizeConfig.textMultiplier, + fontSize: 1.7 * SizeConfig.textMultiplier, color: Color(0XFF575757), ), AppText( "${referralPatient.patientID}", fontFamily: 'Poppins', fontWeight: FontWeight.w700, - fontSize: - 1.8 * SizeConfig.textMultiplier, + fontSize: 1.8 * SizeConfig.textMultiplier, color: Color(0XFF2E303A), ), ], @@ -159,75 +143,56 @@ class MyReferralDetailScreen extends StatelessWidget { AppDateUtils.getTimeHHMMA(referralPatient.referralDate), fontFamily: 'Poppins', fontWeight: FontWeight.w600, - fontSize: - 1.8 * SizeConfig.textMultiplier, + fontSize: 1.8 * SizeConfig.textMultiplier, color: Color(0XFF575757), ) ], ), Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( child: Column( children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, children: [ AppText( - TranslationBase.of(context) - .referredFrom, + TranslationBase.of(context).referredFrom, fontFamily: 'Poppins', fontWeight: FontWeight.w600, - fontSize: 1.7 * - SizeConfig.textMultiplier, + fontSize: 1.7 * SizeConfig.textMultiplier, color: Color(0XFF575757), ), AppText( - referralPatient.targetProjectId ==referralPatient.sourceProjectId - ? TranslationBase.of( - context) - .sameBranch - : TranslationBase.of( - context) - .otherBranch, + referralPatient.targetProjectId == referralPatient.sourceProjectId + ? TranslationBase.of(context).sameBranch + : TranslationBase.of(context).otherBranch, fontFamily: 'Poppins', fontWeight: FontWeight.w700, - fontSize: 1.8 * - SizeConfig - .textMultiplier, + fontSize: 1.8 * SizeConfig.textMultiplier, color: Color(0XFF2E303A), ), ], ), Row( - mainAxisAlignment: - MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( - TranslationBase.of(context) - .remarks + - " : ", + TranslationBase.of(context).remarks + " : ", fontFamily: 'Poppins', fontWeight: FontWeight.w600, - fontSize: 1.7 * - SizeConfig.textMultiplier, + fontSize: 1.7 * SizeConfig.textMultiplier, color: Color(0XFF575757), ), Expanded( child: AppText( - referralPatient.referringDoctorRemarks?? - '', + referralPatient.referringDoctorRemarks ?? '', fontFamily: 'Poppins', fontWeight: FontWeight.w700, - fontSize: 1.8 * - SizeConfig.textMultiplier, + fontSize: 1.8 * SizeConfig.textMultiplier, color: Color(0XFF2E303A), ), ), @@ -239,29 +204,22 @@ class MyReferralDetailScreen extends StatelessWidget { Row( children: [ AppText( - referralPatient.nationalityName != - null + referralPatient.nationalityName != null ? referralPatient.nationalityName : "", fontWeight: FontWeight.bold, color: Color(0xFF2E303A), - fontSize: - 1.4 * SizeConfig.textMultiplier, + fontSize: 1.4 * SizeConfig.textMultiplier, ), - referralPatient.nationalityFlagURL != - null + referralPatient.nationalityFlagURL != null ? ClipRRect( - borderRadius: - BorderRadius.circular(20.0), + borderRadius: BorderRadius.circular(20.0), child: Image.network( - referralPatient - .nationalityFlagURL, + referralPatient.nationalityFlagURL, height: 25, width: 30, - errorBuilder: (BuildContext - context, - Object exception, - StackTrace stackTrace) { + errorBuilder: + (BuildContext context, Object exception, StackTrace stackTrace) { return Text('No Image'); }, )) @@ -274,8 +232,7 @@ class MyReferralDetailScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - margin: - EdgeInsets.only(left: 10, right: 0), + margin: EdgeInsets.only(left: 10, right: 0), child: Image.asset( 'assets/images/patient/ic_ref_arrow_up.png', height: 50, @@ -283,20 +240,14 @@ class MyReferralDetailScreen extends StatelessWidget { ), ), Container( - margin: EdgeInsets.only( - left: 0, - top: 25, - right: 0, - bottom: 0), - padding: EdgeInsets.only( - left: 4.0, right: 4.0), + margin: EdgeInsets.only(left: 0, top: 25, right: 0, bottom: 0), + padding: EdgeInsets.only(left: 4.0, right: 4.0), child: Container( width: 40, height: 40, child: CircleAvatar( radius: 25.0, - backgroundImage: NetworkImage( - referralPatient.doctorImageURL), + backgroundImage: NetworkImage(referralPatient.doctorImageURL), backgroundColor: Colors.transparent, ), ), @@ -304,19 +255,14 @@ class MyReferralDetailScreen extends StatelessWidget { Expanded( flex: 4, child: Container( - margin: EdgeInsets.only( - left: 10, - top: 25, - right: 10, - bottom: 0), + margin: EdgeInsets.only(left: 10, top: 25, right: 10, bottom: 0), child: Column( children: [ AppText( referralPatient.doctorName, fontFamily: 'Poppins', fontWeight: FontWeight.w700, - fontSize: 1.7 * - SizeConfig.textMultiplier, + fontSize: 1.7 * SizeConfig.textMultiplier, color: Color(0XFF2E303A), ), ], @@ -347,8 +293,7 @@ class MyReferralDetailScreen extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 16), child: SizedBox( child: ProfileMedicalInfoWidgetSearch( - patient: model - .getPatientFromReferralO(referralPatient), + patient: model.getPatientFromReferralO(referralPatient), patientType: "7", isInpatient: false, from: null, @@ -380,9 +325,7 @@ class MyReferralDetailScreen extends StatelessWidget { if (model.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(model.error); } else { - DrAppToastMsg.showSuccesToast( - TranslationBase.of(context) - .referralSuccessMsgAccept); + DrAppToastMsg.showSuccesToast(TranslationBase.of(context).referralSuccessMsgAccept); model.getMyReferralOutPatientService(); Navigator.pop(context); Navigator.pop(context); @@ -407,9 +350,7 @@ class MyReferralDetailScreen extends StatelessWidget { if (model.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(model.error); } else { - DrAppToastMsg.showSuccesToast( - TranslationBase.of(context) - .referralSuccessMsgReject); + DrAppToastMsg.showSuccesToast(TranslationBase.of(context).referralSuccessMsgReject); model.getMyReferralOutPatientService(); Navigator.pop(context); Navigator.pop(context); diff --git a/lib/screens/patients/profile/referral/refer-patient-screen.dart b/lib/screens/patients/profile/referral/refer-patient-screen.dart index 407a6815..6010a422 100644 --- a/lib/screens/patients/profile/referral/refer-patient-screen.dart +++ b/lib/screens/patients/profile/referral/refer-patient-screen.dart @@ -1,6 +1,8 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/service/AnalyticsService.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-referral-viewmodel.dart'; +import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; @@ -21,8 +23,7 @@ import 'package:hexcolor/hexcolor.dart'; class PatientMakeReferralScreen extends StatefulWidget { // previous design page is: ReferPatientScreen @override - _PatientMakeReferralScreenState createState() => - _PatientMakeReferralScreenState(); + _PatientMakeReferralScreenState createState() => _PatientMakeReferralScreenState(); } class _PatientMakeReferralScreenState extends State { @@ -55,14 +56,8 @@ class _PatientMakeReferralScreenState extends State { String arrivalType = routeArgs['arrivalType']; referToList = List(); - dynamic sameBranch = { - "id": 1, - "name": TranslationBase.of(context).sameBranch - }; - dynamic otherBranch = { - "id": 2, - "name": TranslationBase.of(context).otherBranch - }; + dynamic sameBranch = {"id": 1, "name": TranslationBase.of(context).sameBranch}; + dynamic otherBranch = {"id": 2, "name": TranslationBase.of(context).otherBranch}; referToList.add(sameBranch); referToList.add(otherBranch); @@ -74,8 +69,7 @@ class _PatientMakeReferralScreenState extends State { baseViewModel: model, appBarTitle: TranslationBase.of(context).referPatient, isShowAppBar: true, - appBar: PatientProfileAppBar( - patient), + appBar: PatientProfileAppBar(patient), body: SingleChildScrollView( child: Container( child: Column( @@ -109,57 +103,25 @@ class _PatientMakeReferralScreenState extends State { model.patientReferral.length == 0 ? referralForm(model, screenSize) : PatientReferralItemWidget( - referralStatus: model - .patientReferral[ - model.patientReferral.length - 1] - .referralStatus, - patientName: model - .patientReferral[ - model.patientReferral.length - 1] - .patientName, - patientGender: model - .patientReferral[ - model.patientReferral.length - 1] - .patientDetails - .gender, - referredDate: model - .patientReferral[ - model.patientReferral.length - 1] - .referredOn - .split(" ")[0], - referredTime: model - .patientReferral[ - model.patientReferral.length - 1] - .referredOn - .split(" ")[1], - patientID: - "${model.patientReferral[model.patientReferral.length - 1].patientID}", - isSameBranch: model - .patientReferral[ - model.patientReferral.length - 1] - .isReferralDoctorSameBranch, + referralStatus: model.patientReferral[model.patientReferral.length - 1].referralStatus, + patientName: model.patientReferral[model.patientReferral.length - 1].patientName, + patientGender: + model.patientReferral[model.patientReferral.length - 1].patientDetails.gender, + referredDate: + model.patientReferral[model.patientReferral.length - 1].referredOn.split(" ")[0], + referredTime: + model.patientReferral[model.patientReferral.length - 1].referredOn.split(" ")[1], + patientID: "${model.patientReferral[model.patientReferral.length - 1].patientID}", + isSameBranch: + model.patientReferral[model.patientReferral.length - 1].isReferralDoctorSameBranch, isReferral: true, - remark: model - .patientReferral[ - model.patientReferral.length - 1] - .remarksFromSource, - nationality: model - .patientReferral[ - model.patientReferral.length - 1] - .patientDetails - .nationalityName, - nationalityFlag: model - .patientReferral[ - model.patientReferral.length - 1] - .nationalityFlagUrl, - doctorAvatar: model - .patientReferral[ - model.patientReferral.length - 1] - .doctorImageUrl, - referralDoctorName: model - .patientReferral[ - model.patientReferral.length - 1] - .referredByDoctorInfo, + remark: model.patientReferral[model.patientReferral.length - 1].remarksFromSource, + nationality: + model.patientReferral[model.patientReferral.length - 1].patientDetails.nationalityName, + nationalityFlag: model.patientReferral[model.patientReferral.length - 1].nationalityFlagUrl, + doctorAvatar: model.patientReferral[model.patientReferral.length - 1].doctorImageUrl, + referralDoctorName: + model.patientReferral[model.patientReferral.length - 1].referredByDoctorInfo, clinicDescription: null, ), ], @@ -171,29 +133,29 @@ class _PatientMakeReferralScreenState extends State { title: TranslationBase.of(context).refer, fontWeight: FontWeight.w700, color: HexColor("#359846"), - onPressed: () { - setState(() { + onPressed: () async { + setState(() async { + await locator().logEvent( + eventCategory: "Refer Patient", + eventAction: "Submit Refer", + ); if (_referTo == null) { - branchError = - TranslationBase.of(context).fieldRequired; + branchError = TranslationBase.of(context).fieldRequired; } else { branchError = null; } if (_selectedBranch == null) { - hospitalError = - TranslationBase.of(context).fieldRequired; + hospitalError = TranslationBase.of(context).fieldRequired; } else { hospitalError = null; } if (_selectedClinic == null) { - clinicError = - TranslationBase.of(context).fieldRequired; + clinicError = TranslationBase.of(context).fieldRequired; } else { clinicError = null; } if (_selectedDoctor == null) { - doctorError = - TranslationBase.of(context).fieldRequired; + doctorError = TranslationBase.of(context).fieldRequired; } else { doctorError = null; } @@ -204,16 +166,10 @@ class _PatientMakeReferralScreenState extends State { _selectedDoctor == null || _remarksController.text == null) return; model - .makeReferral( - patient, - appointmentDate.toIso8601String(), - _selectedBranch['facilityId'], - _selectedClinic['ClinicID'], - _selectedDoctor['DoctorID'], - _remarksController.text) + .makeReferral(patient, appointmentDate.toIso8601String(), _selectedBranch['facilityId'], + _selectedClinic['ClinicID'], _selectedDoctor['DoctorID'], _remarksController.text) .then((_) { - DrAppToastMsg.showSuccesToast( - TranslationBase.of(context).referralSuccessMsg); + DrAppToastMsg.showSuccesToast(TranslationBase.of(context).referralSuccessMsg); Navigator.pop(context); }); }, @@ -259,8 +215,7 @@ class _PatientMakeReferralScreenState extends State { GifLoaderDialogUtils.showMyDialog(context); await model .getClinics(_selectedBranch['facilityId']) - .then((_) => - GifLoaderDialogUtils.hideDialog(context)); + .then((_) => GifLoaderDialogUtils.hideDialog(context)); if (model.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(model.error); } @@ -287,47 +242,42 @@ class _PatientMakeReferralScreenState extends State { AppTextFieldCustom( height: screenSize.height * 0.075, hintText: TranslationBase.of(context).hospital, - dropDownText: _selectedBranch != null - ? _selectedBranch['facilityName'] - : null, + dropDownText: _selectedBranch != null ? _selectedBranch['facilityName'] : null, enabled: false, isTextFieldHasSuffix: true, validationError: hospitalError, - onClick: model.branchesList != null && - model.branchesList.length > 0 && - _referTo != null && - _referTo['id'] == 2 - ? () { - ListSelectDialog dialog = ListSelectDialog( - list: model.branchesList, - attributeName: 'facilityName', - attributeValueId: 'facilityId', - okText: TranslationBase.of(context).ok, - okFunction: (selectedValue) { - setState(() async { - _selectedBranch = selectedValue; - _selectedClinic = null; - _selectedDoctor = null; - GifLoaderDialogUtils.showMyDialog(context); - await model - .getClinics(_selectedBranch['facilityId']) - .then((_) => - GifLoaderDialogUtils.hideDialog(context)); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } - }); - }, - ); - showDialog( - barrierDismissible: false, - context: context, - builder: (BuildContext context) { - return dialog; - }, - ); - } - : null, + onClick: + model.branchesList != null && model.branchesList.length > 0 && _referTo != null && _referTo['id'] == 2 + ? () { + ListSelectDialog dialog = ListSelectDialog( + list: model.branchesList, + attributeName: 'facilityName', + attributeValueId: 'facilityId', + okText: TranslationBase.of(context).ok, + okFunction: (selectedValue) { + setState(() async { + _selectedBranch = selectedValue; + _selectedClinic = null; + _selectedDoctor = null; + GifLoaderDialogUtils.showMyDialog(context); + await model + .getClinics(_selectedBranch['facilityId']) + .then((_) => GifLoaderDialogUtils.hideDialog(context)); + if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); + } + }); + }, + ); + showDialog( + barrierDismissible: false, + context: context, + builder: (BuildContext context) { + return dialog; + }, + ); + } + : null, ), SizedBox( height: 10, @@ -335,15 +285,11 @@ class _PatientMakeReferralScreenState extends State { AppTextFieldCustom( height: screenSize.height * 0.075, hintText: TranslationBase.of(context).clinic, - dropDownText: _selectedClinic != null - ? _selectedClinic['ClinicDescription'] - : null, + dropDownText: _selectedClinic != null ? _selectedClinic['ClinicDescription'] : null, enabled: false, isTextFieldHasSuffix: true, validationError: clinicError, - onClick: _selectedBranch != null && - model.clinicsList != null && - model.clinicsList.length > 0 + onClick: _selectedBranch != null && model.clinicsList != null && model.clinicsList.length > 0 ? () { ListSelectDialog dialog = ListSelectDialog( list: model.clinicsList, @@ -358,12 +304,8 @@ class _PatientMakeReferralScreenState extends State { _selectedClinic = selectedValue; GifLoaderDialogUtils.showMyDialog(context); await model - .getClinicDoctors( - patient, - _selectedClinic['ClinicID'], - _selectedBranch['facilityId']) - .then((_) => - GifLoaderDialogUtils.hideDialog(context)); + .getClinicDoctors(patient, _selectedClinic['ClinicID'], _selectedBranch['facilityId']) + .then((_) => GifLoaderDialogUtils.hideDialog(context)); if (model.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(model.error); } @@ -386,14 +328,11 @@ class _PatientMakeReferralScreenState extends State { AppTextFieldCustom( height: screenSize.height * 0.075, hintText: TranslationBase.of(context).doctor, - dropDownText: - _selectedDoctor != null ? _selectedDoctor['Name'] : null, + dropDownText: _selectedDoctor != null ? _selectedDoctor['Name'] : null, enabled: false, isTextFieldHasSuffix: true, validationError: doctorError, - onClick: _selectedClinic != null && - model.doctorsList != null && - model.doctorsList.length > 0 + onClick: _selectedClinic != null && model.doctorsList != null && model.doctorsList.length > 0 ? () { ListSelectDialog dialog = ListSelectDialog( list: model.doctorsList, @@ -418,12 +357,9 @@ class _PatientMakeReferralScreenState extends State { } : () { if (_selectedClinic == null) { - DrAppToastMsg.showErrorToast( - "You need to select a clinic first"); - } else if (model.doctorsList == null || - model.doctorsList.length == 0) { - DrAppToastMsg.showErrorToast( - "There is no doctors for this clinic"); + DrAppToastMsg.showErrorToast("You need to select a clinic first"); + } else if (model.doctorsList == null || model.doctorsList.length == 0) { + DrAppToastMsg.showErrorToast("There is no doctors for this clinic"); } }, ), @@ -433,9 +369,8 @@ class _PatientMakeReferralScreenState extends State { AppTextFieldCustom( height: screenSize.height * 0.075, hintText: TranslationBase.of(context).date, - dropDownText: appointmentDate != null - ? "${AppDateUtils.convertDateToFormat(appointmentDate, "yyyy-MM-dd")}" - : null, + dropDownText: + appointmentDate != null ? "${AppDateUtils.convertDateToFormat(appointmentDate, "yyyy-MM-dd")}" : null, enabled: false, isTextFieldHasSuffix: true, suffixIcon: IconButton( diff --git a/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart b/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart index 50bd0a9e..d9b9aae9 100644 --- a/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart +++ b/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart @@ -1,7 +1,9 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/model/referral/MyReferralPatientModel.dart'; +import 'package:doctor_app_flutter/core/service/AnalyticsService.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-referral-viewmodel.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; +import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; @@ -433,7 +435,8 @@ class ReferralPatientDetailScreen extends StatelessWidget { ], ), ), - if (referredPatient.referredDoctorRemarks!= null && referredPatient.referredDoctorRemarks.isNotEmpty) + if (referredPatient.referredDoctorRemarks != null && + referredPatient.referredDoctorRemarks.isNotEmpty) Container( width: double.infinity, margin: EdgeInsets.symmetric(horizontal: 16, vertical: 0), @@ -486,13 +489,18 @@ class ReferralPatientDetailScreen extends StatelessWidget { hPadding: 8, vPadding: 12, onPressed: () async { + await locator().logEvent( + eventCategory: "Referral Patient Detail", + eventAction: "Replay To Patient", + ); Navigator.push( context, SlideUpPageRoute( widget: AddReplayOnReferralPatient( patientReferralViewModel: patientReferralViewModel, myReferralInPatientModel: referredPatient, - isEdited: referredPatient.referredDoctorRemarks!=null && referredPatient.referredDoctorRemarks.isNotEmpty, + isEdited: referredPatient.referredDoctorRemarks != null && + referredPatient.referredDoctorRemarks.isNotEmpty, ), ), ); diff --git a/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart b/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart index 23266095..09694ad6 100644 --- a/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart +++ b/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart @@ -1,5 +1,7 @@ import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/service/AnalyticsService.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-vital-sign-viewmodel.dart'; +import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/lookups/patient_lookup.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; @@ -18,8 +20,7 @@ class VitalSignDetailsScreen extends StatelessWidget { int projectID; bool isNotOneAppointment; - VitalSignDetailsScreen( - {this.appointmentNo, this.projectID, this.isNotOneAppointment = true}); + VitalSignDetailsScreen({this.appointmentNo, this.projectID, this.isNotOneAppointment = true}); @override Widget build(BuildContext context) { @@ -34,14 +35,12 @@ class VitalSignDetailsScreen extends StatelessWidget { String assetBasePath = "${imageBasePath}patient/vital_signs/"; return BaseView( - onModelReady: (model) => - model.getPatientVitalSignHistory(patient, from, to, isInpatient), + onModelReady: (model) => model.getPatientVitalSignHistory(patient, from, to, isInpatient), builder: (_, mode, widget) => AppScaffold( baseViewModel: mode, isShowAppBar: true, backgroundColor: Theme.of(context).scaffoldBackgroundColor, - appBar: PatientProfileAppBar( - patient), + appBar: PatientProfileAppBar(patient), appBarTitle: TranslationBase.of(context).vitalSign, body: mode.patientVitalSignsHistory.length > 0 ? Column( @@ -57,7 +56,7 @@ class VitalSignDetailsScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( - "${patient.firstName ?? patient?.patientDetails?.firstName?? patient.fullName?? ''}'s", + "${patient.firstName ?? patient?.patientDetails?.firstName ?? patient.fullName ?? ''}'s", fontSize: SizeConfig.textMultiplier * 1.6, fontWeight: FontWeight.w700, color: Color(0xFF2E303A), @@ -75,8 +74,7 @@ class VitalSignDetailsScreen extends StatelessWidget { height: MediaQuery.of(context).size.height * 0.23, width: double.infinity, padding: EdgeInsets.all(12.0), - margin: EdgeInsets.symmetric( - horizontal: 16.0, vertical: 8.0), + margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), decoration: BoxDecoration( shape: BoxShape.rectangle, color: Colors.white, @@ -100,17 +98,13 @@ class VitalSignDetailsScreen extends StatelessWidget { children: [ Expanded( child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, children: [ Image.asset( mode.getBMIStatus() != 1 ? '${assetBasePath}underweight_BMI.png' : '${assetBasePath}underweight_BMI-r.png', - height: MediaQuery.of(context) - .size - .height * - 0.10, + height: MediaQuery.of(context).size.height * 0.10, ), const SizedBox( height: 4, @@ -118,38 +112,28 @@ class VitalSignDetailsScreen extends StatelessWidget { AppText( "${TranslationBase.of(context).bmiUnderWeight}", fontFamily: 'Poppins', - fontSize: - SizeConfig.textMultiplier * 1.15, - color: mode.getBMIStatus() == 1 - ? Color(0XFFD02127) - : null, + fontSize: SizeConfig.textMultiplier * 1.15, + color: mode.getBMIStatus() == 1 ? Color(0XFFD02127) : null, fontWeight: FontWeight.w700, ), AppText( "(<18.5)", fontFamily: 'Poppins', - fontSize: - SizeConfig.textMultiplier * 1.15, - color: mode.getBMIStatus() == 1 - ? Color(0XFFD02127) - : null, + fontSize: SizeConfig.textMultiplier * 1.15, + color: mode.getBMIStatus() == 1 ? Color(0XFFD02127) : null, fontWeight: FontWeight.w700, ), ], )), Expanded( child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, children: [ Image.asset( mode.getBMIStatus() != 2 ? '${assetBasePath}health_BMI.png' : '${assetBasePath}health_BMI-r.png', - height: MediaQuery.of(context) - .size - .height * - 0.10, + height: MediaQuery.of(context).size.height * 0.10, ), const SizedBox( height: 4, @@ -158,40 +142,29 @@ class VitalSignDetailsScreen extends StatelessWidget { child: AppText( "${TranslationBase.of(context).normal}", fontFamily: 'Poppins', - fontSize: - SizeConfig.textMultiplier * - 1.15, + fontSize: SizeConfig.textMultiplier * 1.15, fontWeight: FontWeight.w700, - color: mode.getBMIStatus() == 2 - ? Color(0XFFD02127) - : null, + color: mode.getBMIStatus() == 2 ? Color(0XFFD02127) : null, ), ), AppText( "(18.5-24.9)", fontFamily: 'Poppins', - fontSize: - SizeConfig.textMultiplier * 1.15, + fontSize: SizeConfig.textMultiplier * 1.15, fontWeight: FontWeight.w700, - color: mode.getBMIStatus() == 2 - ? Color(0XFFD02127) - : null, + color: mode.getBMIStatus() == 2 ? Color(0XFFD02127) : null, ), ], )), Expanded( child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, children: [ Image.asset( mode.getBMIStatus() != 3 ? '${assetBasePath}ovrweight_BMI.png' : '${assetBasePath}ovrweight_BMI-r.png', - height: MediaQuery.of(context) - .size - .height * - 0.10, + height: MediaQuery.of(context).size.height * 0.10, ), const SizedBox( height: 4, @@ -199,38 +172,28 @@ class VitalSignDetailsScreen extends StatelessWidget { AppText( "${TranslationBase.of(context).bmiOverWeight}", fontFamily: 'Poppins', - fontSize: - SizeConfig.textMultiplier * 1.155, + fontSize: SizeConfig.textMultiplier * 1.155, fontWeight: FontWeight.w700, - color: mode.getBMIStatus() == 3 - ? Color(0XFFD02127) - : null, + color: mode.getBMIStatus() == 3 ? Color(0XFFD02127) : null, ), AppText( "(25-29.9)", fontFamily: 'Poppins', - fontSize: - SizeConfig.textMultiplier * 1.155, + fontSize: SizeConfig.textMultiplier * 1.155, fontWeight: FontWeight.w700, - color: mode.getBMIStatus() == 3 - ? Color(0XFFD02127) - : null, + color: mode.getBMIStatus() == 3 ? Color(0XFFD02127) : null, ), ], )), Expanded( child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, children: [ Image.asset( mode.getBMIStatus() != 4 ? '${assetBasePath}Obese_BMI.png' : '${assetBasePath}Obese_BMI-r.png', - height: MediaQuery.of(context) - .size - .height * - 0.10, + height: MediaQuery.of(context).size.height * 0.10, ), const SizedBox( height: 4, @@ -238,38 +201,28 @@ class VitalSignDetailsScreen extends StatelessWidget { AppText( "${TranslationBase.of(context).bmiObese}", fontFamily: 'Poppins', - fontSize: - SizeConfig.textMultiplier * 1.15, + fontSize: SizeConfig.textMultiplier * 1.15, fontWeight: FontWeight.w700, - color: mode.getBMIStatus() == 4 - ? Color(0XFFD02127) - : null, + color: mode.getBMIStatus() == 4 ? Color(0XFFD02127) : null, ), AppText( "(30-34.9)", fontFamily: 'Poppins', - fontSize: - SizeConfig.textMultiplier * 1.15, + fontSize: SizeConfig.textMultiplier * 1.15, fontWeight: FontWeight.w700, - color: mode.getBMIStatus() == 4 - ? Color(0XFFD02127) - : null, + color: mode.getBMIStatus() == 4 ? Color(0XFFD02127) : null, ), ], )), Expanded( child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, children: [ Image.asset( mode.getBMIStatus() != 5 ? '${assetBasePath}Obese_BMI.png' : '${assetBasePath}Obese_BMI-r.png', - height: MediaQuery.of(context) - .size - .height * - 0.10, + height: MediaQuery.of(context).size.height * 0.10, ), const SizedBox( height: 4, @@ -279,24 +232,17 @@ class VitalSignDetailsScreen extends StatelessWidget { child: AppText( "${TranslationBase.of(context).bmiObeseExtreme}", fontFamily: 'Poppins', - fontSize: - SizeConfig.textMultiplier * - 1.15, + fontSize: SizeConfig.textMultiplier * 1.15, fontWeight: FontWeight.w700, - color: mode.getBMIStatus() == 5 - ? Color(0XFFD02127) - : null, + color: mode.getBMIStatus() == 5 ? Color(0XFFD02127) : null, ), ), AppText( "(35<)", fontFamily: 'Poppins', - fontSize: - SizeConfig.textMultiplier * 1.15, + fontSize: SizeConfig.textMultiplier * 1.15, fontWeight: FontWeight.w700, - color: mode.getBMIStatus() == 5 - ? Color(0XFFD02127) - : null, + color: mode.getBMIStatus() == 5 ? Color(0XFFD02127) : null, ), ], )), @@ -308,11 +254,9 @@ class VitalSignDetailsScreen extends StatelessWidget { Expanded( child: SingleChildScrollView( child: Container( - margin: EdgeInsets.symmetric( - horizontal: 16.0, vertical: 16), + margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 16), child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ GridView.count( shrinkWrap: true, @@ -326,16 +270,10 @@ class VitalSignDetailsScreen extends StatelessWidget { ? Navigator.push( context, FadePage( - page: - VitalSignItemDetailsScreen( - pageKey: vitalSignDetails - .Height, - pageTitle: - TranslationBase.of( - context) - .height, - vitalList: mode - .patientVitalSignsHistory, + page: VitalSignItemDetailsScreen( + pageKey: vitalSignDetails.Height, + pageTitle: TranslationBase.of(context).height, + vitalList: mode.patientVitalSignsHistory, patient: patient, patientType: patientType, arrivalType: arrivalType, @@ -345,63 +283,51 @@ class VitalSignDetailsScreen extends StatelessWidget { : null, child: Container( child: VitalSignItem( - des: TranslationBase.of(context) - .height, - imagePath: - "${assetBasePath}height.png", + des: TranslationBase.of(context).height, + imagePath: "${assetBasePath}height.png", lastVal: mode.heightCm, - unit: TranslationBase.of(context) - .cm, + unit: TranslationBase.of(context).cm, ), ), ), - InkWell( - onTap: () => isNotOneAppointment - ? Navigator.push( - context, - FadePage( - page: - VitalSignItemDetailsScreen( - pageKey: vitalSignDetails - .Weight, - pageTitle: - TranslationBase.of( - context) - .weight, - vitalList: mode - .patientVitalSignsHistory, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - ), + if (isNotOneAppointment) + InkWell( + onTap: () async { + await locator().logEvent( + eventCategory: "Vital Sign Details Screen", + eventAction: "Vital Sign Details", + ); + + Navigator.push( + context, + FadePage( + page: VitalSignItemDetailsScreen( + pageKey: vitalSignDetails.Weight, + pageTitle: TranslationBase.of(context).weight, + vitalList: mode.patientVitalSignsHistory, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, ), - ) - : null, - child: VitalSignItem( - des: TranslationBase.of(context) - .weight, - imagePath: - "${assetBasePath}weight.png", - unit: - TranslationBase.of(context).kg, - lastVal: mode.weightKg, + ), + ); + }, + child: VitalSignItem( + des: TranslationBase.of(context).weight, + imagePath: "${assetBasePath}weight.png", + unit: TranslationBase.of(context).kg, + lastVal: mode.weightKg, + ), ), - ), InkWell( onTap: () => isNotOneAppointment ? Navigator.push( context, FadePage( - page: - VitalSignItemDetailsScreen( - pageKey: vitalSignDetails - .Temperature, - pageTitle: - TranslationBase.of( - context) - .temperature, - vitalList: mode - .patientVitalSignsHistory, + page: VitalSignItemDetailsScreen( + pageKey: vitalSignDetails.Temperature, + pageTitle: TranslationBase.of(context).temperature, + vitalList: mode.patientVitalSignsHistory, patient: patient, patientType: patientType, arrivalType: arrivalType, @@ -411,13 +337,10 @@ class VitalSignDetailsScreen extends StatelessWidget { : null, child: Container( child: VitalSignItem( - des: TranslationBase.of(context) - .temperature, - imagePath: - "${assetBasePath}temperature.png", + des: TranslationBase.of(context).temperature, + imagePath: "${assetBasePath}temperature.png", lastVal: mode.temperatureCelcius, - unit: TranslationBase.of(context) - .tempC, + unit: TranslationBase.of(context).tempC, ), ), ), @@ -426,16 +349,10 @@ class VitalSignDetailsScreen extends StatelessWidget { ? Navigator.push( context, FadePage( - page: - VitalSignItemDetailsScreen( - pageKey: vitalSignDetails - .heart, - pageTitle: - TranslationBase.of( - context) - .heart, - vitalList: mode - .patientVitalSignsHistory, + page: VitalSignItemDetailsScreen( + pageKey: vitalSignDetails.heart, + pageTitle: TranslationBase.of(context).heart, + vitalList: mode.patientVitalSignsHistory, patient: patient, patientType: patientType, arrivalType: arrivalType, @@ -444,13 +361,10 @@ class VitalSignDetailsScreen extends StatelessWidget { ) : null, child: VitalSignItem( - des: TranslationBase.of(context) - .heart, - imagePath: - "${assetBasePath}heart_rate.png", + des: TranslationBase.of(context).heart, + imagePath: "${assetBasePath}heart_rate.png", lastVal: mode.hartRat, - unit: - TranslationBase.of(context).bpm, + unit: TranslationBase.of(context).bpm, ), ), InkWell( @@ -458,16 +372,10 @@ class VitalSignDetailsScreen extends StatelessWidget { ? Navigator.push( context, FadePage( - page: - VitalSignItemDetailsScreen( - pageKey: vitalSignDetails - .Respiration, - pageTitle: - TranslationBase.of( - context) - .respirationRate, - vitalList: mode - .patientVitalSignsHistory, + page: VitalSignItemDetailsScreen( + pageKey: vitalSignDetails.Respiration, + pageTitle: TranslationBase.of(context).respirationRate, + vitalList: mode.patientVitalSignsHistory, patient: patient, patientType: patientType, arrivalType: arrivalType, @@ -476,14 +384,10 @@ class VitalSignDetailsScreen extends StatelessWidget { ) : null, child: VitalSignItem( - des: TranslationBase.of(context) - .respirationRate, - imagePath: - "${assetBasePath}respiration_rate.png", - lastVal: - mode.respirationBeatPerMinute, - unit: TranslationBase.of(context) - .respirationSigns, + des: TranslationBase.of(context).respirationRate, + imagePath: "${assetBasePath}respiration_rate.png", + lastVal: mode.respirationBeatPerMinute, + unit: TranslationBase.of(context).respirationSigns, ), ), InkWell( @@ -491,16 +395,10 @@ class VitalSignDetailsScreen extends StatelessWidget { ? Navigator.push( context, FadePage( - page: - VitalSignItemDetailsScreen( - pageKey: vitalSignDetails - .BloodPressure, - pageTitle: - TranslationBase.of( - context) - .bloodPressure, - vitalList: mode - .patientVitalSignsHistory, + page: VitalSignItemDetailsScreen( + pageKey: vitalSignDetails.BloodPressure, + pageTitle: TranslationBase.of(context).bloodPressure, + vitalList: mode.patientVitalSignsHistory, patient: patient, patientType: patientType, arrivalType: arrivalType, @@ -509,13 +407,10 @@ class VitalSignDetailsScreen extends StatelessWidget { ) : null, child: VitalSignItem( - des: TranslationBase.of(context) - .bloodPressure, - imagePath: - "${assetBasePath}blood_pressure.png", + des: TranslationBase.of(context).bloodPressure, + imagePath: "${assetBasePath}blood_pressure.png", lastVal: mode.bloodPressure, - unit: TranslationBase.of(context) - .sysDias, + unit: TranslationBase.of(context).sysDias, ), ), InkWell( @@ -523,16 +418,10 @@ class VitalSignDetailsScreen extends StatelessWidget { ? Navigator.push( context, FadePage( - page: - VitalSignItemDetailsScreen( - pageKey: vitalSignDetails - .Oxygenation, - pageTitle: - TranslationBase.of( - context) - .oxygenation, - vitalList: mode - .patientVitalSignsHistory, + page: VitalSignItemDetailsScreen( + pageKey: vitalSignDetails.Oxygenation, + pageTitle: TranslationBase.of(context).oxygenation, + vitalList: mode.patientVitalSignsHistory, patient: patient, patientType: patientType, arrivalType: arrivalType, @@ -541,10 +430,8 @@ class VitalSignDetailsScreen extends StatelessWidget { ) : null, child: VitalSignItem( - des: TranslationBase.of(context) - .oxygenation, - imagePath: - "${assetBasePath}oxg.png", + des: TranslationBase.of(context).oxygenation, + imagePath: "${assetBasePath}oxg.png", lastVal: "${mode.oxygenation}%", unit: "", ), @@ -554,16 +441,10 @@ class VitalSignDetailsScreen extends StatelessWidget { ? Navigator.push( context, FadePage( - page: - VitalSignItemDetailsScreen( - pageKey: vitalSignDetails - .PainScale, - pageTitle: - TranslationBase.of( - context) - .painScale, - vitalList: mode - .patientVitalSignsHistory, + page: VitalSignItemDetailsScreen( + pageKey: vitalSignDetails.PainScale, + pageTitle: TranslationBase.of(context).painScale, + vitalList: mode.patientVitalSignsHistory, patient: patient, patientType: patientType, arrivalType: arrivalType, @@ -572,10 +453,8 @@ class VitalSignDetailsScreen extends StatelessWidget { ) : null, child: VitalSignItem( - des: TranslationBase.of(context) - .painScale, - imagePath: - "${assetBasePath}painScale.png", + des: TranslationBase.of(context).painScale, + imagePath: "${assetBasePath}painScale.png", lastVal: mode.painScore, unit: TranslationBase.of(context).severe, ), @@ -588,19 +467,17 @@ class VitalSignDetailsScreen extends StatelessWidget { ), ), ], - ), - ), - ), - ], - ) + ), + ), + ), + ], + ) : Container( - color: Theme - .of(context) - .scaffoldBackgroundColor, - child: ErrorMessage(error: TranslationBase - .of(context) - .vitalSignEmptyMsg,)), + color: Theme.of(context).scaffoldBackgroundColor, + child: ErrorMessage( + error: TranslationBase.of(context).vitalSignEmptyMsg, + )), ), ); } -} \ No newline at end of file +} diff --git a/lib/screens/prescription/add_prescription_form.dart b/lib/screens/prescription/add_prescription_form.dart index 477e5359..6d1609be 100644 --- a/lib/screens/prescription/add_prescription_form.dart +++ b/lib/screens/prescription/add_prescription_form.dart @@ -6,10 +6,12 @@ import 'package:doctor_app_flutter/core/model/Prescriptions/post_prescrition_req import 'package:doctor_app_flutter/core/model/Prescriptions/prescription_model.dart'; import 'package:doctor_app_flutter/core/model/search_drug/get_medication_response_model.dart'; import 'package:doctor_app_flutter/core/provider/robot_provider.dart'; +import 'package:doctor_app_flutter/core/service/AnalyticsService.dart'; import 'package:doctor_app_flutter/core/viewModel/medicine_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; +import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/models/SOAP/GetAssessmentReqModel.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; @@ -638,6 +640,10 @@ class _PrescriptionFormWidgetState extends State { title: TranslationBase.of(context).addMedication, fontWeight: FontWeight.w600, onPressed: () async { + await locator().logEvent( + eventCategory: "Add Prescription Form", + eventAction: "Add Prescription", + ); if (route != null && duration != null && doseTime != null && diff --git a/lib/screens/procedures/procedure_checkout_screen.dart b/lib/screens/procedures/procedure_checkout_screen.dart index 4c054fc5..a2afdba6 100644 --- a/lib/screens/procedures/procedure_checkout_screen.dart +++ b/lib/screens/procedures/procedure_checkout_screen.dart @@ -1,7 +1,9 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_template_details_model.dart'; +import 'package:doctor_app_flutter/core/service/AnalyticsService.dart'; import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; +import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/procedures/add-procedure-page.dart'; @@ -21,11 +23,10 @@ class ProcedureCheckOutScreen extends StatefulWidget { final String toolbarTitle; ProcedureCheckOutScreen( - {this.items, this.model, this.patient,@required this.addButtonTitle,@required this.toolbarTitle}); + {this.items, this.model, this.patient, @required this.addButtonTitle, @required this.toolbarTitle}); @override - _ProcedureCheckOutScreenState createState() => - _ProcedureCheckOutScreenState(); + _ProcedureCheckOutScreenState createState() => _ProcedureCheckOutScreenState(); } class _ProcedureCheckOutScreenState extends State { @@ -36,8 +37,7 @@ class _ProcedureCheckOutScreenState extends State { @override Widget build(BuildContext context) { return BaseView( - builder: (BuildContext context, ProcedureViewModel model, Widget child) => - AppScaffold( + builder: (BuildContext context, ProcedureViewModel model, Widget child) => AppScaffold( backgroundColor: Color(0xffF8F8F8).withOpacity(0.9), isShowAppBar: false, body: SingleChildScrollView( @@ -82,10 +82,8 @@ class _ProcedureCheckOutScreenState extends State { widget.items.length, (index) => Container( margin: EdgeInsets.only(bottom: 15.0), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: - BorderRadius.all(Radius.circular(10.0))), + decoration: + BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(10.0))), child: ExpansionTile( initiallyExpanded: true, title: Row( @@ -98,9 +96,7 @@ class _ProcedureCheckOutScreenState extends State { SizedBox( width: 6.0, ), - Expanded( - child: AppText( - widget.items[index].procedureName)), + Expanded(child: AppText(widget.items[index].procedureName)), ], ), children: [ @@ -113,11 +109,9 @@ class _ProcedureCheckOutScreenState extends State { Row( children: [ Padding( - padding: const EdgeInsets.symmetric( - horizontal: 11), + padding: const EdgeInsets.symmetric(horizontal: 11), child: AppText( - TranslationBase.of(context) - .orderType, + TranslationBase.of(context).orderType, fontWeight: FontWeight.w700, color: Color(0xff2B353E), ), @@ -129,14 +123,11 @@ class _ProcedureCheckOutScreenState extends State { Radio( activeColor: Color(0xFFD02127), value: 0, - groupValue: - widget.items[index].selectedType, + groupValue: widget.items[index].selectedType, onChanged: (value) { - widget.items[index].selectedType = - 0; + widget.items[index].selectedType = 0; setState(() { - widget.items[index].type = - value.toString(); + widget.items[index].type = value.toString(); }); }, ), @@ -147,15 +138,12 @@ class _ProcedureCheckOutScreenState extends State { ), Radio( activeColor: Color(0xFFD02127), - groupValue: - widget.items[index].selectedType, + groupValue: widget.items[index].selectedType, value: 1, onChanged: (value) { - widget.items[index].selectedType = - 1; + widget.items[index].selectedType = 1; setState(() { - widget.items[index].type = - value.toString(); + widget.items[index].type = value.toString(); }); }, ), @@ -174,8 +162,7 @@ class _ProcedureCheckOutScreenState extends State { height: 2.0, ), Padding( - padding: EdgeInsets.symmetric( - horizontal: 12, vertical: 15.0), + padding: EdgeInsets.symmetric(horizontal: 12, vertical: 15.0), child: TextFields( hintText: TranslationBase.of(context).remarks, controller: remarksController, @@ -222,11 +209,13 @@ class _ProcedureCheckOutScreenState extends State { ), ); }); + await locator().logEvent( + eventCategory: "Procedure Checkout Screen", + eventAction: "Add New Procedure", + ); Navigator.pop(context); await model.preparePostProcedure( - entityList: entityList, - patient: widget.patient, - remarks: remarksController.text); + entityList: entityList, patient: widget.patient, remarks: remarksController.text); Navigator.pop(context); Navigator.pop(context); }, diff --git a/lib/screens/qr_reader/QR_reader_screen.dart b/lib/screens/qr_reader/QR_reader_screen.dart index c6d07bb9..c06a8722 100644 --- a/lib/screens/qr_reader/QR_reader_screen.dart +++ b/lib/screens/qr_reader/QR_reader_screen.dart @@ -2,8 +2,10 @@ import 'package:barcode_scan_fix/barcode_scan.dart'; import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/patient_muse/PatientSearchRequestModel.dart'; +import 'package:doctor_app_flutter/core/service/AnalyticsService.dart'; import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/scan_qr_view_model.dart'; +import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; @@ -61,7 +63,11 @@ class _QrReaderScreenState extends State { ), AppButton( title: TranslationBase.of(context).scanQr, - onPressed: () { + onPressed: () async { + await locator().logEvent( + eventCategory: "QrReaderScreen", + eventAction: "Scan QR", + ); _scanQrAndGetPatient(context, model); }, icon: Image.asset('assets/images/qr_code_white.png'), @@ -82,10 +88,7 @@ class _QrReaderScreenState extends State { int patientID = 0; if (listOfParams[1].length != 0) patientID = int.parse(listOfParams[1]); PatientSearchRequestModel patientSearchRequestModel = PatientSearchRequestModel( - patientID: patientID,clinicID: 0, - doctorID: 0, - projectID: int.parse(listOfParams[0]) - ); + patientID: patientID, clinicID: 0, doctorID: 0, projectID: int.parse(listOfParams[0])); await model.getInPatientList(patientSearchRequestModel, isMyInpatient: false).then((d) { if (model.state != ViewState.ErrorLocal) { diff --git a/lib/screens/reschedule-leaves/add-rescheduleleave.dart b/lib/screens/reschedule-leaves/add-rescheduleleave.dart index 2e0a284f..43d4ae68 100644 --- a/lib/screens/reschedule-leaves/add-rescheduleleave.dart +++ b/lib/screens/reschedule-leaves/add-rescheduleleave.dart @@ -1,6 +1,8 @@ +import 'package:doctor_app_flutter/core/service/AnalyticsService.dart'; import 'package:doctor_app_flutter/core/viewModel/leave_rechdule_response.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/sick_leave_view_model.dart'; +import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/reschedule-leaves/reschedule_leave.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; @@ -20,23 +22,29 @@ class AddRescheduleLeavScreen extends StatelessWidget { Widget build(BuildContext context) { projectsProvider = Provider.of(context); return BaseView( - onModelReady: (model) => - {model.getRescheduleLeave(), model.getCoveringDoctors()}, + onModelReady: (model) => {model.getRescheduleLeave(), model.getCoveringDoctors()}, builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, appBarTitle: TranslationBase.of(context).rescheduleLeaves, body: SingleChildScrollView( child: Column(children: [ - AddNewOrder( onTap: () { - openLeave( - context, - false, - ); - },label: TranslationBase.of(context).applyForReschedule,), + AddNewOrder( + onTap: () async { + await locator().logEvent( + eventCategory: "Add Reschedule" + "Leave Screen", + eventAction: "apply For Reschedule", + ); + openLeave( + context, + false, + ); + }, + label: TranslationBase.of(context).applyForReschedule, + ), Column( - children: model.getReschduleLeave - .map((GetRescheduleLeavesResponse item) { + children: model.getReschduleLeave.map((GetRescheduleLeavesResponse item) { return RoundedContainer( child: Column( children: [ @@ -62,71 +70,55 @@ class AddRescheduleLeavScreen extends StatelessWidget { child: Wrap( children: [ Column( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Container( - padding: EdgeInsets.all(3), - margin: - EdgeInsets.only(top: 10), - child: AppText( - item.statusDescription, - fontWeight: FontWeight.bold, - color: item.status == 10 - ? Colors.red[800] - : item.status == 2 - ? HexColor('#CC9B14') - : item.status == 9 - ? Colors.green - : Colors.red, - fontSize: 14, - ), - ), - Padding( - padding: - EdgeInsets.only(top: 10), - child: AppText( - AppDateUtils - .convertStringToDateFormat( - item.createdOn, - 'yyyy-MM-dd HH:mm'), - fontWeight: FontWeight.bold, - )) - ]), + Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ + Container( + padding: EdgeInsets.all(3), + margin: EdgeInsets.only(top: 10), + child: AppText( + item.statusDescription, + fontWeight: FontWeight.bold, + color: item.status == 10 + ? Colors.red[800] + : item.status == 2 + ? HexColor('#CC9B14') + : item.status == 9 + ? Colors.green + : Colors.red, + fontSize: 14, + ), + ), + Padding( + padding: EdgeInsets.only(top: 10), + child: AppText( + AppDateUtils.convertStringToDateFormat( + item.createdOn, 'yyyy-MM-dd HH:mm'), + fontWeight: FontWeight.bold, + )) + ]), SizedBox( height: 5, ), Container( child: AppText( item.requisitionType == 1 - ? TranslationBase.of(context) - .offTime + ? TranslationBase.of(context).offTime : item.requisitionType == 2 - ? TranslationBase.of(context) - .holiday + ? TranslationBase.of(context).holiday : item.requisitionType == 3 - ? TranslationBase.of( - context) - .changeOfSchedule - : TranslationBase.of( - context) - .newSchedule, + ? TranslationBase.of(context).changeOfSchedule + : TranslationBase.of(context).newSchedule, fontWeight: FontWeight.bold, )), SizedBox( height: 5, ), Row(children: [ - AppText(TranslationBase.of(context) - .startDate), + AppText(TranslationBase.of(context).startDate), AppText( AppDateUtils.convertStringToDateFormat( - item.dateTimeFrom, - 'yyyy-MM-dd HH:mm'), + item.dateTimeFrom, 'yyyy-MM-dd HH:mm'), fontWeight: FontWeight.bold, ) @@ -142,13 +134,10 @@ class AddRescheduleLeavScreen extends StatelessWidget { ), Row( children: [ - AppText(TranslationBase.of(context) - .endDate), + AppText(TranslationBase.of(context).endDate), AppText( - AppDateUtils - .convertStringToDateFormat( - item.dateTimeTo, - 'yyyy-MM-dd HH:mm'), + AppDateUtils.convertStringToDateFormat( + item.dateTimeTo, 'yyyy-MM-dd HH:mm'), fontWeight: FontWeight.bold, ) ], @@ -160,13 +149,10 @@ class AddRescheduleLeavScreen extends StatelessWidget { model.coveringDoctors.length > 0 ? Row(children: [ AppText( - TranslationBase.of(context) - .coveringDoctor, + TranslationBase.of(context).coveringDoctor, ), AppText( - getDoctor( - model.coveringDoctors, - item.coveringDoctorId), + getDoctor(model.coveringDoctors, item.coveringDoctorId), fontWeight: FontWeight.bold, ) ]) @@ -176,28 +162,18 @@ class AddRescheduleLeavScreen extends StatelessWidget { // .reasons, // fontWeight: FontWeight.bold, // ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: EdgeInsets.only( - bottom: 5), - child: AppText(getReasons( - model.allReasons, - item.reasonId))), - (item.status == 2) - ? IconButton( - icon: Image.asset( - 'assets/images/edit.png'), - // color: Colors.green, //Colors.black, - onPressed: () => { - openLeave(context, true, - extendedData: item) - }, - ) - : SizedBox(), - ]), + Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ + Padding( + padding: EdgeInsets.only(bottom: 5), + child: AppText(getReasons(model.allReasons, item.reasonId))), + (item.status == 2) + ? IconButton( + icon: Image.asset('assets/images/edit.png'), + // color: Colors.green, //Colors.black, + onPressed: () => {openLeave(context, true, extendedData: item)}, + ) + : SizedBox(), + ]), ], ), SizedBox( diff --git a/lib/screens/sick-leave/add-sickleave.dart b/lib/screens/sick-leave/add-sickleave.dart index 61c81957..d7dffd8d 100644 --- a/lib/screens/sick-leave/add-sickleave.dart +++ b/lib/screens/sick-leave/add-sickleave.dart @@ -1,8 +1,10 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/model/sick_leave/sick_leave_patient_model.dart'; +import 'package:doctor_app_flutter/core/service/AnalyticsService.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/sick_leave_view_model.dart'; +import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/models/sickleave/get_all_sickleave_response.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; @@ -64,7 +66,12 @@ class AddSickLeavScreen extends StatelessWidget { ], )), InkWell( - onTap: () { + onTap: () async { + await locator().logEvent( + eventCategory: "Add Sick Leave Screen" + "Leave Screen", + eventAction: "apply For Sick Leave", + ); openSickLeave( context, false, diff --git a/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart b/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart index f2a32e63..08cc26c5 100644 --- a/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart @@ -1,6 +1,8 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/service/AnalyticsService.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; +import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; @@ -11,8 +13,7 @@ import 'package:hexcolor/hexcolor.dart'; import 'package:intl/intl.dart'; import 'package:url_launcher/url_launcher.dart'; -class PatientProfileHeaderNewDesignAppBar extends StatelessWidget - with PreferredSizeWidget { +class PatientProfileHeaderNewDesignAppBar extends StatelessWidget with PreferredSizeWidget { final PatiantInformtion patient; final String patientType; final String arrivalType; @@ -23,8 +24,12 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget final Stream videoCallDurationStream; - PatientProfileHeaderNewDesignAppBar( - this.patient, this.patientType, this.arrivalType, {this.height = 0.0, this.isInpatient=false, this.isDischargedPatient=false, this.isFromLiveCare = false, this.videoCallDurationStream}); + PatientProfileHeaderNewDesignAppBar(this.patient, this.patientType, this.arrivalType, + {this.height = 0.0, + this.isInpatient = false, + this.isDischargedPatient = false, + this.isFromLiveCare = false, + this.videoCallDurationStream}); @override Widget build(BuildContext context) { @@ -43,7 +48,11 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget decoration: BoxDecoration( color: Colors.white, ), - height: height == 0 ? isInpatient? 215:200 : height, + height: height == 0 + ? isInpatient + ? 215 + : 200 + : height, child: Container( padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), margin: EdgeInsets.only(top: 50), @@ -60,10 +69,8 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget Expanded( child: AppText( patient.firstName != null - ? (Helpers.capitalize(patient.firstName) + - " " + - Helpers.capitalize(patient.lastName)) - : Helpers.capitalize(patient.fullName??patient.patientDetails.fullName), + ? (Helpers.capitalize(patient.firstName) + " " + Helpers.capitalize(patient.lastName)) + : Helpers.capitalize(patient.fullName ?? patient.patientDetails.fullName), fontSize: SizeConfig.textMultiplier * 1.8, fontWeight: FontWeight.bold, fontFamily: 'Poppins', @@ -81,7 +88,11 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget Container( margin: EdgeInsets.symmetric(horizontal: 4), child: InkWell( - onTap: () { + onTap: () async { + await locator().logEvent( + eventCategory: "Patient Profile Header", + eventAction: "Call Patient", + ); launch("tel://" + patient.mobileNumber); }, child: Icon( @@ -93,14 +104,16 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget StreamBuilder( stream: videoCallDurationStream, builder: (BuildContext context, AsyncSnapshot snapshot) { - if(snapshot.hasData && snapshot.data != null) + if (snapshot.hasData && snapshot.data != null) return InkWell( - onTap: (){ - }, + onTap: () {}, child: Container( decoration: BoxDecoration(color: Colors.red, borderRadius: BorderRadius.circular(20)), padding: EdgeInsets.symmetric(vertical: 2, horizontal: 10), - child: Text(snapshot.data, style: TextStyle(color: Colors.white),), + child: Text( + snapshot.data, + style: TextStyle(color: Colors.white), + ), ), ); else @@ -116,9 +129,7 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget width: 60, height: 60, child: Image.asset( - gender == 1 - ? 'assets/images/male_avatar.png' - : 'assets/images/female_avatar.png', + gender == 1 ? 'assets/images/male_avatar.png' : 'assets/images/female_avatar.png', fit: BoxFit.cover, ), ), @@ -130,8 +141,7 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SERVICES_PATIANT2[int.parse(patientType)] == - "patientArrivalList" + SERVICES_PATIANT2[int.parse(patientType)] == "patientArrivalList" ? Container( child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -151,19 +161,16 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget fontFamily: 'Poppins', fontSize: 12, ), - arrivalType == '1'|| patient.arrivedOn == null + arrivalType == '1' || patient.arrivedOn == null ? AppText( - patient.startTime != null - ? patient.startTime - : '', + patient.startTime != null ? patient.startTime : '', fontFamily: 'Poppins', fontWeight: FontWeight.w600, ) : AppText( patient.arrivedOn != null ? AppDateUtils.convertStringToDateFormat( - patient.arrivedOn, - 'MM-dd-yyyy HH:mm') + patient.arrivedOn, 'MM-dd-yyyy HH:mm') : '', fontFamily: 'Poppins', fontWeight: FontWeight.w600, @@ -171,15 +178,13 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget ], )) : SizedBox(), - if (SERVICES_PATIANT2[int.parse(patientType)] == - "List_MyOutPatient" && !isFromLiveCare) + if (SERVICES_PATIANT2[int.parse(patientType)] == "List_MyOutPatient" && !isFromLiveCare) Container( child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ AppText( - TranslationBase.of(context).appointmentDate + - " : ", + TranslationBase.of(context).appointmentDate + " : ", fontSize: 14, ), patient.startTime != null @@ -191,7 +196,7 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget color: HexColor("#20A169"), ), child: AppText( - patient.startTime??"", + patient.startTime ?? "", color: Colors.white, fontSize: 1.5 * SizeConfig.textMultiplier, textAlign: TextAlign.center, @@ -202,14 +207,13 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget SizedBox( width: 3.5, ), - Container( - child: AppText( - convertDateFormat2( - patient.appointmentDate ?? ''), - fontSize: 1.5 * SizeConfig.textMultiplier, - fontWeight: FontWeight.bold, - ), + Container( + child: AppText( + convertDateFormat2(patient.appointmentDate ?? ''), + fontSize: 1.5 * SizeConfig.textMultiplier, + fontWeight: FontWeight.bold, ), + ), SizedBox( height: 0.5, ) @@ -224,27 +228,21 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget children: [ RichText( text: TextSpan( - style: TextStyle( - fontSize: 1.6 * SizeConfig.textMultiplier, - color: Colors.black), + style: TextStyle(fontSize: 1.6 * SizeConfig.textMultiplier, color: Colors.black), children: [ new TextSpan( text: TranslationBase.of(context).fileNumber, - style: TextStyle( - fontSize: 12, fontFamily: 'Poppins')), + style: TextStyle(fontSize: 12, fontFamily: 'Poppins')), new TextSpan( text: patient.patientId.toString(), - style: TextStyle( - fontWeight: FontWeight.w700, - fontFamily: 'Poppins', - fontSize: 14)), + style: TextStyle(fontWeight: FontWeight.w700, fontFamily: 'Poppins', fontSize: 14)), ], ), ), Row( children: [ AppText( - patient.nationalityName ?? patient.nationality?? patient.nationalityId ?? '', + patient.nationalityName ?? patient.nationality ?? patient.nationalityId ?? '', fontWeight: FontWeight.bold, fontSize: 12, ), @@ -255,9 +253,7 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget patient.nationalityFlagURL, height: 25, width: 30, - errorBuilder: (BuildContext context, - Object exception, - StackTrace stackTrace) { + errorBuilder: (BuildContext context, Object exception, StackTrace stackTrace) { return Text('No Image'); }, )) @@ -275,19 +271,16 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget fontFamily: 'Poppins', ), children: [ - new TextSpan( - text: TranslationBase.of(context).age+ " : ", - style: TextStyle(fontSize: 14)), + new TextSpan(text: TranslationBase.of(context).age + " : ", style: TextStyle(fontSize: 14)), new TextSpan( text: - "${AppDateUtils.getAgeByBirthday(patient.patientDetails != null ? patient.patientDetails.dateofBirth??"" : patient.dateofBirth??"", context,isServerFormat: !isFromLiveCare)}", - style: TextStyle( - fontWeight: FontWeight.w700, fontSize: 14)), + "${AppDateUtils.getAgeByBirthday(patient.patientDetails != null ? patient.patientDetails.dateofBirth ?? "" : patient.dateofBirth ?? "", context, isServerFormat: !isFromLiveCare)}", + style: TextStyle(fontWeight: FontWeight.w700, fontSize: 14)), ], ), ), ), - if(isInpatient) + if (isInpatient) Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -295,27 +288,22 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget child: RichText( text: new TextSpan( style: new TextStyle( - fontSize: - 2.0 * SizeConfig.textMultiplier, + fontSize: 2.0 * SizeConfig.textMultiplier, color: Colors.black, fontFamily: 'Poppins', ), children: [ - new TextSpan( - text: patient.admissionDate == null - ? "" - : TranslationBase.of(context) - .admissionDate + - " : ", - style: TextStyle(fontSize: 14)), - new TextSpan( - text: patient.admissionDate == null - ? "" - : "${AppDateUtils.convertDateFromServerFormat(patient.admissionDate.toString(), 'yyyy-MM-dd')}", - style: TextStyle( - fontWeight: FontWeight.w700, - fontSize: 15)), - ]))), + new TextSpan( + text: patient.admissionDate == null + ? "" + : TranslationBase.of(context).admissionDate + " : ", + style: TextStyle(fontSize: 14)), + new TextSpan( + text: patient.admissionDate == null + ? "" + : "${AppDateUtils.convertDateFromServerFormat(patient.admissionDate.toString(), 'yyyy-MM-dd')}", + style: TextStyle(fontWeight: FontWeight.w700, fontSize: 15)), + ]))), if (patient.admissionDate != null) Row( children: [ @@ -323,11 +311,11 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget "${TranslationBase.of(context).numOfDays}: ", fontSize: 15, ), - if(isDischargedPatient && patient.dischargeDate!=null) - AppText( - "${AppDateUtils.getDateTimeFromServerFormat(patient.dischargeDate).difference(AppDateUtils.getDateTimeFromServerFormat(patient.admissionDate)).inDays + 1}", - fontSize: 15, - fontWeight: FontWeight.w700) + if (isDischargedPatient && patient.dischargeDate != null) + AppText( + "${AppDateUtils.getDateTimeFromServerFormat(patient.dischargeDate).difference(AppDateUtils.getDateTimeFromServerFormat(patient.admissionDate)).inDays + 1}", + fontSize: 15, + fontWeight: FontWeight.w700) else AppText( "${DateTime.now().difference(AppDateUtils.getDateTimeFromServerFormat(patient.admissionDate)).inDays + 1}", @@ -356,8 +344,7 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget final startIndex = str.indexOf(start); final endIndex = str.indexOf(end, startIndex + start.length); - var date = new DateTime.fromMillisecondsSinceEpoch( - int.parse(str.substring(startIndex + start.length, endIndex))); + var date = new DateTime.fromMillisecondsSinceEpoch(int.parse(str.substring(startIndex + start.length, endIndex))); newDate = date.year.toString() + "/" + date.month.toString().padLeft(2, '0') + @@ -365,13 +352,12 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget date.day.toString().padLeft(2, '0'); } - return newDate??''; + return newDate ?? ''; } isToday(date) { DateTime tempDate = new DateFormat("yyyy-MM-dd").parse(date); - return DateFormat("yyyy-MM-dd").format(tempDate) == - DateFormat("yyyy-MM-dd").format(DateTime.now()); + return DateFormat("yyyy-MM-dd").format(tempDate) == DateFormat("yyyy-MM-dd").format(DateTime.now()); } myBoxDecoration() { diff --git a/lib/widgets/patients/profile/profile_status_info_widget.dart b/lib/widgets/patients/profile/profile_status_info_widget.dart deleted file mode 100644 index d616c36f..00000000 --- a/lib/widgets/patients/profile/profile_status_info_widget.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; - -import '../../../config/size_config.dart'; -import '../../shared/app_texts_widget.dart'; -import '../../shared/rounded_container_widget.dart'; - - -/* - *@author: Elham Rababah - *@Date:13/4/2020 - *@param: - *@return: ProfileStatusInfoWidget - *@desc: Profile Status Info Widget - */ -class ProfileStatusInfoWidget extends StatelessWidget { - const ProfileStatusInfoWidget({ - Key key, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return RoundedContainer( - child: ListView( - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 14), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - 'Insurance approval', - fontSize: SizeConfig.textMultiplier * 3, - fontWeight: FontWeight.w700, - color: HexColor('#58434F'), - ), - AppText( - 'Approved', - color: HexColor('#707070'), - fontSize: SizeConfig.textMultiplier * 2.5, - ) - ], - ), - ), - ], - ), - width: SizeConfig.screenWidth * 0.70, - height: SizeConfig.screenHeight * 0.12, - ); - } -} diff --git a/pubspec.lock b/pubspec.lock index c90d86d9..491e4c5b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -657,7 +657,7 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.3" + version: "1.3.0-nullsafety.4" mime: dependency: transitive description: @@ -949,7 +949,7 @@ packages: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.1" + version: "1.10.0-nullsafety.2" sticky_headers: dependency: "direct main" description: @@ -1147,5 +1147,5 @@ packages: source: hosted version: "2.2.1" sdks: - dart: ">=2.10.0 <2.11.0" + dart: ">=2.10.0 <=2.11.0-213.1.beta" flutter: ">=1.22.0 <2.0.0" From d29d3e26669a9c9a5c47ce0e505486a876b2288b Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Thu, 15 Jul 2021 16:44:47 +0300 Subject: [PATCH 068/289] adding google anlyatic to doctor app --- .../medical-file/health_summary_page.dart | 109 ++-- .../insurance_approval_screen_patient.dart | 24 +- .../medical_report/MedicalReportPage.dart | 18 +- .../profile/note/progress_note_screen.dart | 489 ++++++------------ 4 files changed, 236 insertions(+), 404 deletions(-) diff --git a/lib/screens/medical-file/health_summary_page.dart b/lib/screens/medical-file/health_summary_page.dart index f83def0f..b1ee901b 100644 --- a/lib/screens/medical-file/health_summary_page.dart +++ b/lib/screens/medical-file/health_summary_page.dart @@ -29,9 +29,7 @@ class _HealthSummaryPageState extends State { bool isInpatient = routeArgs['isInpatient']; return BaseView( onModelReady: (model) => model.getMedicalFile(mrn: patient.patientId), - builder: - (BuildContext context, MedicalFileViewModel model, Widget child) => - AppScaffold( + builder: (BuildContext context, MedicalFileViewModel model, Widget child) => AppScaffold( appBar: PatientProfileAppBar( patient, isInpatient: isInpatient, @@ -45,8 +43,7 @@ class _HealthSummaryPageState extends State { child: Column( children: [ Padding( - padding: - EdgeInsets.symmetric(horizontal: 12.0, vertical: 8.0), + padding: EdgeInsets.symmetric(horizontal: 12.0, vertical: 8.0), child: Container( child: Padding( padding: const EdgeInsets.all(8.0), @@ -76,15 +73,13 @@ class _HealthSummaryPageState extends State { ), ), ), - (model.medicalFileList != null && - model.medicalFileList.length != 0) + (model.medicalFileList != null && model.medicalFileList.length != 0) ? ListView.builder( //physics: , physics: NeverScrollableScrollPhysics(), scrollDirection: Axis.vertical, shrinkWrap: true, - itemCount: model.medicalFileList[0].entityList[0] - .timelines.length, + itemCount: model.medicalFileList[0].entityList[0].timelines.length, itemBuilder: (BuildContext ctxt, int index) { return InkWell( onTap: () async { @@ -98,65 +93,48 @@ class _HealthSummaryPageState extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => MedicalFileDetails( - age: patient.age is String ? patient.age ?? "" : "${patient.age}", - firstName: patient.firstName, - lastName: patient.lastName, - gender: patient.genderDescription, - encounterNumber: index, - pp: patient.patientId, - patient: patient, - doctorName: model.medicalFileList[0].entityList[0].timelines[index] - .timeLineEvents[0].consulations.isNotEmpty - ? model.medicalFileList[0].entityList[0].timelines[index].doctorName - : "", - clinicName: model.medicalFileList[0].entityList[0].timelines[index] - .timeLineEvents[0].consulations.isNotEmpty - ? model.medicalFileList[0].entityList[0].timelines[index].clinicName - : "", - doctorImage: model.medicalFileList[0].entityList[0].timelines[index] - .timeLineEvents[0].consulations.isNotEmpty - ? model.medicalFileList[0].entityList[0].timelines[index].doctorImage - : "", - episode: model.medicalFileList[0].entityList[0].timelines[index] - .timeLineEvents[0].consulations.isNotEmpty - ? model.medicalFileList[0].entityList[0].timelines[index] - .timeLineEvents[0].consulations[0].episodeID - .toString() - : "", - vistDate: - model.medicalFileList[0].entityList[0].timelines[index].date.toString()), - settings: RouteSettings(name: 'MedicalFileDetails'),), - ); + builder: (context) => MedicalFileDetails( + age: patient.age is String ? patient.age ?? "" : "${patient.age}", + firstName: patient.firstName, + lastName: patient.lastName, + gender: patient.genderDescription, + encounterNumber: index, + pp: patient.patientId, + patient: patient, + doctorName: model.medicalFileList[0].entityList[0].timelines[index] + .timeLineEvents[0].consulations.isNotEmpty + ? model.medicalFileList[0].entityList[0].timelines[index].doctorName + : "", + clinicName: model.medicalFileList[0].entityList[0].timelines[index] + .timeLineEvents[0].consulations.isNotEmpty + ? model.medicalFileList[0].entityList[0].timelines[index].clinicName + : "", + doctorImage: model.medicalFileList[0].entityList[0].timelines[index] + .timeLineEvents[0].consulations.isNotEmpty + ? model.medicalFileList[0].entityList[0].timelines[index].doctorImage + : "", + episode: model.medicalFileList[0].entityList[0].timelines[index] + .timeLineEvents[0].consulations.isNotEmpty + ? model.medicalFileList[0].entityList[0].timelines[index].timeLineEvents[0] + .consulations[0].episodeID + .toString() + : "", + vistDate: model.medicalFileList[0].entityList[0].timelines[index].date.toString()), + settings: RouteSettings(name: 'MedicalFileDetails'), + ), + ); }, child: DoctorCard( - doctorName: model - .medicalFileList[0] - .entityList[0] - .timelines[index] - .doctorName, - clinic: model.medicalFileList[0].entityList[0] - .timelines[index].clinicName, - branch: model.medicalFileList[0].entityList[0] - .timelines[index].projectName, - profileUrl: model - .medicalFileList[0] - .entityList[0] - .timelines[index] - .doctorImage, - appointmentDate: - AppDateUtils.getDateTimeFromServerFormat( - model.medicalFileList[0].entityList[0] - .timelines[index].date, + doctorName: model.medicalFileList[0].entityList[0].timelines[index].doctorName, + clinic: model.medicalFileList[0].entityList[0].timelines[index].clinicName, + branch: model.medicalFileList[0].entityList[0].timelines[index].projectName, + profileUrl: model.medicalFileList[0].entityList[0].timelines[index].doctorImage, + appointmentDate: AppDateUtils.getDateTimeFromServerFormat( + model.medicalFileList[0].entityList[0].timelines[index].date, ), isPrescriptions: true, - isShowEye: model - .medicalFileList[0] - .entityList[0] - .timelines[index] - .timeLineEvents[0] - .consulations - .length != + isShowEye: model.medicalFileList[0].entityList[0].timelines[index].timeLineEvents[0] + .consulations.length != 0 ? true : false), @@ -172,8 +150,7 @@ class _HealthSummaryPageState extends State { Image.asset('assets/images/no-data.png'), Padding( padding: const EdgeInsets.all(8.0), - child: AppText(TranslationBase.of(context) - .noMedicalFileFound), + child: AppText(TranslationBase.of(context).noMedicalFileFound), ) ], ), diff --git a/lib/screens/patients/insurance_approval_screen_patient.dart b/lib/screens/patients/insurance_approval_screen_patient.dart index 9563ac0d..2c89425e 100644 --- a/lib/screens/patients/insurance_approval_screen_patient.dart +++ b/lib/screens/patients/insurance_approval_screen_patient.dart @@ -94,11 +94,13 @@ class _InsuranceApprovalScreenNewState extends State Navigator.push( context, MaterialPageRoute( - builder: (context) => InsuranceApprovalsDetails( - patient: patient, - indexInsurance: index, - patientType: patientType, - ),settings: RouteSettings(name: 'InsuranceApprovalsDetails'),), + builder: (context) => InsuranceApprovalsDetails( + patient: patient, + indexInsurance: index, + patientType: patientType, + ), + settings: RouteSettings(name: 'InsuranceApprovalsDetails'), + ), ); }, child: DoctorCardInsurance( @@ -185,11 +187,13 @@ class _InsuranceApprovalScreenNewState extends State Navigator.push( context, MaterialPageRoute( - builder: (context) => InsuranceApprovalsDetails( - patient: patient, - indexInsurance: index, - patientType: patientType, - ),settings: RouteSettings(name: 'InsuranceApprovalsDetails'),), + builder: (context) => InsuranceApprovalsDetails( + patient: patient, + indexInsurance: index, + patientType: patientType, + ), + settings: RouteSettings(name: 'InsuranceApprovalsDetails'), + ), ); }, child: DoctorCardInsurance( diff --git a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart index d96f25f2..a25d03b4 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart @@ -88,17 +88,16 @@ class _MedicalReportPageState extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => AddVerifyMedicalReport( - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - model: model, - status: MedicalReportStatus.ADD, - ), + builder: (context) => AddVerifyMedicalReport( + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + model: model, + status: MedicalReportStatus.ADD, + ), settings: RouteSettings(name: 'AddVerifyMedicalReport'), ), ); - }, label: TranslationBase.of(context).createNewMedicalReport, ), @@ -119,7 +118,8 @@ class _MedicalReportPageState extends State { model: model, medicalNote: model.medicalReportList[index].reportDataHtml, ), - settings: RouteSettings(name: 'AddVerifyMedicalReport')),); + settings: RouteSettings(name: 'AddVerifyMedicalReport')), + ); } else { Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_DETAIL, arguments: { 'patient': patient, diff --git a/lib/screens/patients/profile/note/progress_note_screen.dart b/lib/screens/patients/profile/note/progress_note_screen.dart index 0e553587..d4a6f3b1 100644 --- a/lib/screens/patients/profile/note/progress_note_screen.dart +++ b/lib/screens/patients/profile/note/progress_note_screen.dart @@ -45,8 +45,7 @@ class _ProgressNoteState extends State { AuthenticationViewModel authenticationViewModel; ProjectViewModel projectViewModel; - getProgressNoteList(BuildContext context, PatientViewModel model, - {bool isLocalBusy = false}) async { + getProgressNoteList(BuildContext context, PatientViewModel model, {bool isLocalBusy = false}) async { final routeArgs = ModalRoute.of(context).settings.arguments as Map; PatiantInformtion patient = routeArgs['patient']; String token = await sharedPref.getString(TOKEN); @@ -61,10 +60,7 @@ class _ProgressNoteState extends State { tokenID: token, patientTypeID: patient.patientType, languageID: 2); - model - .getPatientProgressNote(progressNoteRequest.toJson(), - isLocalBusy: isLocalBusy) - .then((c) { + model.getPatientProgressNote(progressNoteRequest.toJson(), isLocalBusy: isLocalBusy).then((c) { notesList = model.patientProgressNoteList; }); } @@ -73,14 +69,10 @@ class _ProgressNoteState extends State { Widget build(BuildContext context) { authenticationViewModel = Provider.of(context); projectViewModel = Provider.of(context); - final routeArgs = ModalRoute - .of(context) - .settings - .arguments as Map; + final routeArgs = ModalRoute.of(context).settings.arguments as Map; PatiantInformtion patient = routeArgs['patient']; String arrivalType = routeArgs['arrivalType']; - if (routeArgs.containsKey('isDischargedPatient')) - isDischargedPatient = routeArgs['isDischargedPatient']; + if (routeArgs.containsKey('isDischargedPatient')) isDischargedPatient = routeArgs['isDischargedPatient']; return BaseView( onModelReady: (model) => getProgressNoteList(context, model), builder: (_, model, w) => AppScaffold( @@ -107,12 +99,14 @@ class _ProgressNoteState extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => UpdateNoteOrder( - patientModel: model, - patient: patient, - visitType: widget.visitType, - isUpdate: false, - ),settings: RouteSettings(name: 'UpdateNoteOrder'),), + builder: (context) => UpdateNoteOrder( + patientModel: model, + patient: patient, + visitType: widget.visitType, + isUpdate: false, + ), + settings: RouteSettings(name: 'UpdateNoteOrder'), + ), ); }, label: widget.visitType == 3 @@ -153,58 +147,35 @@ class _ProgressNoteState extends State { ), if (model.patientProgressNoteList[index].status == 4) AppText( - TranslationBase - .of(context) - .noteCanceled, + TranslationBase.of(context).noteCanceled, fontWeight: FontWeight.bold, color: Colors.red.shade700, fontSize: 12, ), - if (model - .patientProgressNoteList[ - index] - .status == - 2) + if (model.patientProgressNoteList[index].status == 2) AppText( - TranslationBase - .of(context) - .noteVerified, + TranslationBase.of(context).noteVerified, fontWeight: FontWeight.bold, color: Colors.green[600], fontSize: 12, ), if (model.patientProgressNoteList[index].status != 2 && - model - .patientProgressNoteList[ - index] - .status != - 4 && - authenticationViewModel - .doctorProfile.doctorID == - model - .patientProgressNoteList[ - index] - .createdBy) + model.patientProgressNoteList[index].status != 4 && + authenticationViewModel.doctorProfile.doctorID == + model.patientProgressNoteList[index].createdBy) Row( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ InkWell( onTap: () { Navigator.push( context, MaterialPageRoute( - builder: (context) => - UpdateNoteOrder( - note: model - .patientProgressNoteList[ - index], - patientModel: - model, - patient: - patient, - visitType: widget - .visitType, + builder: (context) => UpdateNoteOrder( + note: model.patientProgressNoteList[index], + patientModel: model, + patient: patient, + visitType: widget.visitType, isUpdate: true, )), ); @@ -212,9 +183,7 @@ class _ProgressNoteState extends State { child: Container( decoration: BoxDecoration( color: Colors.grey[600], - borderRadius: - BorderRadius.circular( - 10), + borderRadius: BorderRadius.circular(10), ), // color:Colors.red[600], @@ -229,10 +198,7 @@ class _ProgressNoteState extends State { width: 2, ), AppText( - TranslationBase - .of( - context) - .update, + TranslationBase.of(context).update, fontSize: 10, color: Colors.white, ), @@ -250,61 +216,33 @@ class _ProgressNoteState extends State { context: context, actionName: "verify", confirmFun: () async { - GifLoaderDialogUtils - .showMyDialog( - context); - UpdateNoteReqModel - reqModel = - UpdateNoteReqModel( - admissionNo: int - .parse(patient - .admissionNo), - cancelledNote: - false, - lineItemNo: model - .patientProgressNoteList[ - index] - .lineItemNo, - createdBy: model - .patientProgressNoteList[ - index] - .createdBy, - notes: model - .patientProgressNoteList[ - index] - .notes, + GifLoaderDialogUtils.showMyDialog(context); + UpdateNoteReqModel reqModel = UpdateNoteReqModel( + admissionNo: int.parse(patient.admissionNo), + cancelledNote: false, + lineItemNo: model.patientProgressNoteList[index].lineItemNo, + createdBy: model.patientProgressNoteList[index].createdBy, + notes: model.patientProgressNoteList[index].notes, verifiedNote: true, - patientTypeID: - patient - .patientType, + patientTypeID: patient.patientType, patientOutSA: false, ); - await model - .updatePatientProgressNote( - reqModel); - await getProgressNoteList( - context, model, - isLocalBusy: - true); - GifLoaderDialogUtils - .hideDialog( - context); + await model.updatePatientProgressNote(reqModel); + await getProgressNoteList(context, model, isLocalBusy: true); + GifLoaderDialogUtils.hideDialog(context); }); }, child: Container( decoration: BoxDecoration( color: Colors.green[600], - borderRadius: - BorderRadius.circular( - 10), + borderRadius: BorderRadius.circular(10), ), // color:Colors.red[600], child: Row( children: [ Icon( - FontAwesomeIcons - .check, + FontAwesomeIcons.check, size: 12, color: Colors.white, ), @@ -312,10 +250,7 @@ class _ProgressNoteState extends State { width: 2, ), AppText( - TranslationBase - .of( - context) - .noteVerify, + TranslationBase.of(context).noteVerify, fontSize: 10, color: Colors.white, ), @@ -331,67 +266,37 @@ class _ProgressNoteState extends State { onTap: () async { showMyDialog( context: context, - actionName: - TranslationBase - .of( - context) - .cancel, + actionName: TranslationBase.of(context).cancel, confirmFun: () async { - GifLoaderDialogUtils - .showMyDialog( + GifLoaderDialogUtils.showMyDialog( context, ); - UpdateNoteReqModel - reqModel = - UpdateNoteReqModel( - admissionNo: int - .parse(patient - .admissionNo), + UpdateNoteReqModel reqModel = UpdateNoteReqModel( + admissionNo: int.parse(patient.admissionNo), cancelledNote: true, - lineItemNo: model - .patientProgressNoteList[ - index] - .lineItemNo, - createdBy: model - .patientProgressNoteList[ - index] - .createdBy, - notes: model - .patientProgressNoteList[ - index] - .notes, + lineItemNo: model.patientProgressNoteList[index].lineItemNo, + createdBy: model.patientProgressNoteList[index].createdBy, + notes: model.patientProgressNoteList[index].notes, verifiedNote: false, - patientTypeID: - patient - .patientType, + patientTypeID: patient.patientType, patientOutSA: false, ); - await model - .updatePatientProgressNote( - reqModel); - await getProgressNoteList( - context, model, - isLocalBusy: - true); - GifLoaderDialogUtils - .hideDialog( - context); + await model.updatePatientProgressNote(reqModel); + await getProgressNoteList(context, model, isLocalBusy: true); + GifLoaderDialogUtils.hideDialog(context); }); }, child: Container( decoration: BoxDecoration( color: Colors.red[600], - borderRadius: - BorderRadius.circular( - 10), + borderRadius: BorderRadius.circular(10), ), // color:Colors.red[600], child: Row( children: [ Icon( - FontAwesomeIcons - .trash, + FontAwesomeIcons.trash, size: 12, color: Colors.white, ), @@ -417,41 +322,25 @@ class _ProgressNoteState extends State { height: 10, ), Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - crossAxisAlignment: - CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - width: MediaQuery.of(context) - .size - .width * - 0.60, + width: MediaQuery.of(context).size.width * 0.60, child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( - crossAxisAlignment: - CrossAxisAlignment - .start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( - TranslationBase - .of( - context) - .createdBy, + TranslationBase.of(context).createdBy, fontSize: 10, ), Expanded( child: AppText( - model - .patientProgressNoteList[ - index] - .doctorName ?? - '', - fontWeight: - FontWeight.w600, + model.patientProgressNoteList[index].doctorName ?? '', + fontWeight: FontWeight.w600, fontSize: 12, ), ), @@ -463,85 +352,55 @@ class _ProgressNoteState extends State { Column( children: [ AppText( - model - .patientProgressNoteList[ - index] - .createdOn != - null + model.patientProgressNoteList[index].createdOn != null ? AppDateUtils.getDayMonthYearDateFormatted( - AppDateUtils - .getDateTimeFromServerFormat( - model - .patientProgressNoteList[ - index] - .createdOn), - isArabic: - projectViewModel - .isArabic) - : AppDateUtils - .getDayMonthYearDateFormatted( - DateTime.now(), - isArabic: - projectViewModel - .isArabic), + AppDateUtils.getDateTimeFromServerFormat( + model.patientProgressNoteList[index].createdOn), + isArabic: projectViewModel.isArabic) + : AppDateUtils.getDayMonthYearDateFormatted(DateTime.now(), + isArabic: projectViewModel.isArabic), fontWeight: FontWeight.w600, fontSize: 14, ), AppText( - model - .patientProgressNoteList[ - index] - .createdOn != - null - ? AppDateUtils.getHour(AppDateUtils - .getDateTimeFromServerFormat( - model - .patientProgressNoteList[ - index] - .createdOn)) - : AppDateUtils.getHour( - DateTime.now()), + model.patientProgressNoteList[index].createdOn != null + ? AppDateUtils.getHour(AppDateUtils.getDateTimeFromServerFormat( + model.patientProgressNoteList[index].createdOn)) + : AppDateUtils.getHour(DateTime.now()), fontWeight: FontWeight.w600, fontSize: 14, ), ], - crossAxisAlignment: - CrossAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.end, ) ], ), SizedBox( height: 8, ), - Row( - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - Expanded( - child: AppText( - model - .patientProgressNoteList[ - index] - .notes, - fontSize: 10, - ), - ), - ]) - ], - ), - SizedBox( - height: 20, - ), - ], + Row(mainAxisAlignment: MainAxisAlignment.start, children: [ + Expanded( + child: AppText( + model.patientProgressNoteList[index].notes, + fontSize: 10, + ), + ), + ]) + ], + ), + SizedBox( + height: 20, + ), + ], + ), ), - ), - ); - }), + ); + }), + ), ), - ), - ], + ], + ), ), - ), ), ); } @@ -550,100 +409,92 @@ class _ProgressNoteState extends State { showDialog( context: context, builder: (ctx) => Center( - child: Container( - width: MediaQuery - .of(context) - .size - .width * 0.8, - height: 200, - child: AppScaffold( - isShowAppBar: false, - body: Container( - color: Colors.white, - child: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - // SizedBox(height: 20,), - SizedBox( - height: 10, - ), - Row( + child: Container( + width: MediaQuery.of(context).size.width * 0.8, + height: 200, + child: AppScaffold( + isShowAppBar: false, + body: Container( + color: Colors.white, + child: Center( + child: Column( mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, children: [ - AppText( - TranslationBase - .of(context) - .noteConfirm, - fontWeight: FontWeight.w600, - color: Colors.black, - fontSize: 16, + // SizedBox(height: 20,), + SizedBox( + height: 10, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + AppText( + TranslationBase.of(context).noteConfirm, + fontWeight: FontWeight.w600, + color: Colors.black, + fontSize: 16, + ), + ], + ), + SizedBox( + height: 10, + ), + DividerWithSpacesAround(), + SizedBox( + height: 12, ), - ], - ), - SizedBox( - height: 10, - ), - DividerWithSpacesAround(), - SizedBox( - height: 12, - ), - Container( - padding: EdgeInsets.all(20), - color: Colors.white, - child: AppText( - projectViewModel.isArabic?"هل أنت متأكد أنك تريد تنفيذ $actionName هذا الأمر؟":'Are you sure you want $actionName this order?', - fontSize: 15, - textAlign: TextAlign.center, - ), - ), + Container( + padding: EdgeInsets.all(20), + color: Colors.white, + child: AppText( + projectViewModel.isArabic + ? "هل أنت متأكد أنك تريد تنفيذ $actionName هذا الأمر؟" + : 'Are you sure you want $actionName this order?', + fontSize: 15, + textAlign: TextAlign.center, + ), + ), - SizedBox( - height: 8, + SizedBox( + height: 8, + ), + DividerWithSpacesAround(), + FractionallySizedBox( + widthFactor: 0.75, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + FlatButton( + child: AppText( + TranslationBase.of(context).cancel, + fontWeight: FontWeight.w600, + color: Colors.black, + fontSize: 16, + ), //Text("Cancel"), + onPressed: () { + Navigator.of(context).pop(); + }), + FlatButton( + child: AppText( + TranslationBase.of(context).noteConfirm, + fontWeight: FontWeight.w600, + color: Colors.red.shade700, + fontSize: 16, + ), //Text("Confirm", ), + onPressed: () async { + await confirmFun(); + Navigator.of(context).pop(); + }) + ], + ), + ) + ], ), - DividerWithSpacesAround(), - FractionallySizedBox( - widthFactor: 0.75, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - FlatButton( - child: AppText( - TranslationBase - .of(context) - .cancel, - fontWeight: FontWeight.w600, - color: Colors.black, - fontSize: 16, - ), //Text("Cancel"), - onPressed: () { - Navigator.of(context).pop(); - }), - FlatButton( - child: AppText( - TranslationBase - .of(context) - .noteConfirm, - fontWeight: FontWeight.w600, - color: Colors.red.shade700, - fontSize: 16, - ), //Text("Confirm", ), - onPressed: () async { - await confirmFun(); - Navigator.of(context).pop(); - }) - ], - ), - ) - ], + ), ), ), ), - ), - ), - ) - ); + )); } } From 8a69becab313ac60770ebf2f487b7a00d79b603c Mon Sep 17 00:00:00 2001 From: Elham Rababh Date: Thu, 15 Jul 2021 17:20:03 +0300 Subject: [PATCH 069/289] fix header issues && exam issues --- lib/config/size_config.dart | 27 ++++++++++ .../objective/add_examination_page.dart | 4 +- .../objective/add_examination_widget.dart | 4 +- .../examinations_list_search_widget.dart | 2 +- .../shared_soap_widgets/steps_widget.dart | 52 ++++++++++--------- 5 files changed, 59 insertions(+), 30 deletions(-) diff --git a/lib/config/size_config.dart b/lib/config/size_config.dart index 6b996b3f..6ba584c6 100644 --- a/lib/config/size_config.dart +++ b/lib/config/size_config.dart @@ -59,5 +59,32 @@ class SizeConfig { print('widthMultiplier $widthMultiplier'); print('isPortrait $isPortrait'); print('isMobilePortrait $isMobilePortrait'); + + + } + + static getTextMultiplierBasedOnWidth({double width}) { + // TODO handel LandScape case + if (width != null) { + return width / 100; + } + return widthMultiplier; + } + + static getWidthMultiplier({double width}) { + // TODO handel LandScape case + if (width != null) { + return width / 100; + } + return widthMultiplier; + } + + static getHeightMultiplier({double height}) { + // TODO handel LandScape case + if (height != null) { + return height / 100; + } + return heightMultiplier; } + } diff --git a/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart b/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart index 07343bb7..f1966130 100644 --- a/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart +++ b/lib/screens/patients/profile/soap_update/objective/add_examination_page.dart @@ -81,9 +81,9 @@ class _AddExaminationPageState extends State { masterList: model.physicalExaminationList, isServiceSelected: (master) => isServiceSelected(master), - removeExamination: (exam) { + removeExamination: (selectedExamination) { setState(() { - widget.removeExamination(exam); + mySelectedExaminationLocal.remove(selectedExamination); }); }, addExamination: (selectedExamination) { diff --git a/lib/screens/patients/profile/soap_update/objective/add_examination_widget.dart b/lib/screens/patients/profile/soap_update/objective/add_examination_widget.dart index 2bb9b943..82d26dc9 100644 --- a/lib/screens/patients/profile/soap_update/objective/add_examination_widget.dart +++ b/lib/screens/patients/profile/soap_update/objective/add_examination_widget.dart @@ -14,7 +14,7 @@ import 'package:provider/provider.dart'; // ignore: must_be_immutable class AddExaminationWidget extends StatefulWidget { MasterKeyModel item; - final Function(MasterKeyModel) removeExamination; + final Function(MySelectedExamination) removeExamination; final Function(MySelectedExamination) addExamination; final bool Function(MasterKeyModel) isServiceSelected; bool isExpand; @@ -83,7 +83,7 @@ class _AddExaminationWidgetState extends State { setState(() { if (widget.isServiceSelected(widget.item)) { if (examination.isLocal) - widget.removeExamination(widget.item); + widget.removeExamination(examination); widget.expandClick(); } else { examination.isNormal = status == 1; diff --git a/lib/screens/patients/profile/soap_update/objective/examinations_list_search_widget.dart b/lib/screens/patients/profile/soap_update/objective/examinations_list_search_widget.dart index 497bafa8..bab2d647 100644 --- a/lib/screens/patients/profile/soap_update/objective/examinations_list_search_widget.dart +++ b/lib/screens/patients/profile/soap_update/objective/examinations_list_search_widget.dart @@ -8,7 +8,7 @@ import 'package:flutter/material.dart'; import 'add_examination_widget.dart'; class ExaminationsListSearchWidget extends StatefulWidget { - final Function(MasterKeyModel) removeExamination; + final Function(MySelectedExamination) removeExamination; final Function(MySelectedExamination) addExamination; final bool Function(MasterKeyModel) isServiceSelected; final List masterList; diff --git a/lib/screens/patients/profile/soap_update/shared_soap_widgets/steps_widget.dart b/lib/screens/patients/profile/soap_update/shared_soap_widgets/steps_widget.dart index 31524295..c998bceb 100644 --- a/lib/screens/patients/profile/soap_update/shared_soap_widgets/steps_widget.dart +++ b/lib/screens/patients/profile/soap_update/shared_soap_widgets/steps_widget.dart @@ -1,3 +1,4 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/cupertino.dart'; @@ -76,11 +77,7 @@ class StepsWidget extends StatelessWidget { Column( mainAxisAlignment: MainAxisAlignment.start, children: [ - AppText( - "Subjective", - fontWeight: FontWeight.bold, - fontSize: 12, - ), + StepWidget(stepLabel: "Subjective",), StatusLabel( selectedStepId: index, stepId: 0, @@ -132,11 +129,7 @@ class StepsWidget extends StatelessWidget { Column( mainAxisAlignment: MainAxisAlignment.start, children: [ - AppText( - "Objective", - fontWeight: FontWeight.bold, - fontSize: 12, - ), + StepWidget(stepLabel: "Objective",), StatusLabel( selectedStepId: index, stepId: 1, @@ -152,7 +145,7 @@ class StepsWidget extends StatelessWidget { left: MediaQuery .of(context) .size - .width * 0.50, + .width * 0.47, child: InkWell( onTap: () { if (index >= 3) changeCurrentTab(2); @@ -190,11 +183,7 @@ class StepsWidget extends StatelessWidget { Column( mainAxisAlignment: MainAxisAlignment.start, children: [ - AppText( - "Assessment", - fontWeight: FontWeight.bold, - fontSize: 12, - ), + StepWidget(stepLabel: "Assessment",), StatusLabel( selectedStepId: index, stepId: 2, @@ -243,13 +232,7 @@ class StepsWidget extends StatelessWidget { Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ - AppText( - "Plan", - fontWeight: FontWeight.bold, - fontSize: 12, - textAlign: TextAlign.end, - marginLeft: 30, - ), + StepWidget(stepLabel: "Plan",marginLeft: 30,), StatusLabel( selectedStepId: index, stepId: 3, @@ -506,6 +489,25 @@ class StepsWidget extends StatelessWidget { } } +class StepWidget extends StatelessWidget { + final String stepLabel; + final double marginLeft; + + const StepWidget({ + Key key, this.stepLabel, this.marginLeft = 0, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return AppText( + stepLabel, + fontWeight: FontWeight.bold, + marginLeft: marginLeft, + fontSize:SizeConfig.getTextMultiplierBasedOnWidth() * 3.5 //12, + ); + } +} + class StatusLabel extends StatelessWidget { const StatusLabel({ Key key, @@ -519,7 +521,7 @@ class StatusLabel extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - width: 65, + width: SizeConfig.getTextMultiplierBasedOnWidth() * 18.5, padding: EdgeInsets.symmetric(horizontal: 2, vertical: 3), decoration: BoxDecoration( color: stepId == selectedStepId @@ -541,7 +543,7 @@ class StatusLabel extends StatelessWidget { : "Locked", fontWeight: FontWeight.bold, textAlign: TextAlign.center, - fontSize: 10, + fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 3, color: stepId == selectedStepId ? Color(0xFFCC9B14) : stepId < selectedStepId From 88b04a8f5d870c8b73bafc1feb8f91e22aaec13b Mon Sep 17 00:00:00 2001 From: Elham Rababh Date: Sun, 25 Jul 2021 11:49:58 +0300 Subject: [PATCH 070/289] fix stepper labels and translate it. --- lib/config/localized_values.dart | 4 + .../shared_soap_widgets/SOAP_step_header.dart | 2 +- .../steper/Step_details_widget.dart | 22 ++++ .../steper/status_Label.dart | 52 +++++++++ .../{ => steper}/steps_widget.dart | 105 +++--------------- lib/util/translations_delegate_base.dart | 3 + 6 files changed, 95 insertions(+), 93 deletions(-) create mode 100644 lib/screens/patients/profile/soap_update/shared_soap_widgets/steper/Step_details_widget.dart create mode 100644 lib/screens/patients/profile/soap_update/shared_soap_widgets/steper/status_Label.dart rename lib/screens/patients/profile/soap_update/shared_soap_widgets/{ => steper}/steps_widget.dart (85%) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index ebc43a87..8766832a 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -705,4 +705,8 @@ const Map> localizedValues = { "summeryReply": {"en": "Summary Reply", "ar": "موجز الرد"}, "finish": {"en": "Finish", "ar": "انهاء"}, "severityValidationError": {"en": "Please add allergy severity", "ar": "الرجاء إضافة شدة الحساسية"}, + "inProgress": {"en": "inProgress", "ar": "تحت المعالجه"}, + "Completed": {"en": "Completed", "ar": "مكتمل"}, + "Locked": {"en": "Locked", "ar": "مقفل"}, + }; diff --git a/lib/screens/patients/profile/soap_update/shared_soap_widgets/SOAP_step_header.dart b/lib/screens/patients/profile/soap_update/shared_soap_widgets/SOAP_step_header.dart index f345666f..5052d48f 100644 --- a/lib/screens/patients/profile/soap_update/shared_soap_widgets/SOAP_step_header.dart +++ b/lib/screens/patients/profile/soap_update/shared_soap_widgets/SOAP_step_header.dart @@ -1,4 +1,4 @@ -import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/steps_widget.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/steper/steps_widget.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/material.dart'; diff --git a/lib/screens/patients/profile/soap_update/shared_soap_widgets/steper/Step_details_widget.dart b/lib/screens/patients/profile/soap_update/shared_soap_widgets/steper/Step_details_widget.dart new file mode 100644 index 00000000..fb1bdcc9 --- /dev/null +++ b/lib/screens/patients/profile/soap_update/shared_soap_widgets/steper/Step_details_widget.dart @@ -0,0 +1,22 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:flutter/material.dart'; + +class StepDetailsWidget extends StatelessWidget { + final String stepLabel; + final double marginLeft; + + const StepDetailsWidget({ + Key key, this.stepLabel, this.marginLeft = 0, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return AppText( + stepLabel, + fontWeight: FontWeight.bold, + marginLeft: marginLeft, + fontSize:SizeConfig.getTextMultiplierBasedOnWidth() * 3.5 //12, + ); + } +} \ No newline at end of file diff --git a/lib/screens/patients/profile/soap_update/shared_soap_widgets/steper/status_Label.dart b/lib/screens/patients/profile/soap_update/shared_soap_widgets/steper/status_Label.dart new file mode 100644 index 00000000..a6c5c22b --- /dev/null +++ b/lib/screens/patients/profile/soap_update/shared_soap_widgets/steper/status_Label.dart @@ -0,0 +1,52 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:hexcolor/hexcolor.dart'; + +class StatusLabel extends StatelessWidget { + const StatusLabel({ + Key key, + this.stepId, + this.selectedStepId, + }) : super(key: key); + + final int stepId; + final int selectedStepId; + + @override + Widget build(BuildContext context) { + return Container( + width: SizeConfig.getTextMultiplierBasedOnWidth() * 18.5, + padding: EdgeInsets.symmetric(horizontal: 2, vertical: 3), + decoration: BoxDecoration( + color: stepId == selectedStepId + ? Color(0xFFF1E9D3) + : stepId < selectedStepId + ? Color(0xFFD8E8DB) + : Color(0xFFCCCCCC), + borderRadius: BorderRadius.all( + Radius.circular(5.0), + ), + border: Border.all(color: HexColor('#707070'), width: 0.30), + ), + child: Center( + child: AppText( + stepId == selectedStepId + ? TranslationBase.of(context).inProgress + : stepId < selectedStepId + ? TranslationBase.of(context).completed + : TranslationBase.of(context).locked, + fontWeight: FontWeight.bold, + textAlign: TextAlign.center, + fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 3, + color: stepId == selectedStepId + ? Color(0xFFCC9B14) + : stepId < selectedStepId + ? Color(0xFF359846) + : Color(0xFF969696), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/screens/patients/profile/soap_update/shared_soap_widgets/steps_widget.dart b/lib/screens/patients/profile/soap_update/shared_soap_widgets/steper/steps_widget.dart similarity index 85% rename from lib/screens/patients/profile/soap_update/shared_soap_widgets/steps_widget.dart rename to lib/screens/patients/profile/soap_update/shared_soap_widgets/steper/steps_widget.dart index c998bceb..304a6765 100644 --- a/lib/screens/patients/profile/soap_update/shared_soap_widgets/steps_widget.dart +++ b/lib/screens/patients/profile/soap_update/shared_soap_widgets/steper/steps_widget.dart @@ -1,5 +1,6 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/steper/status_Label.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -7,6 +8,8 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; +import 'Step_details_widget.dart'; + class StepsWidget extends StatelessWidget { final int index; final Function changeCurrentTab; @@ -77,7 +80,7 @@ class StepsWidget extends StatelessWidget { Column( mainAxisAlignment: MainAxisAlignment.start, children: [ - StepWidget(stepLabel: "Subjective",), + StepDetailsWidget(stepLabel: "Subjective",), StatusLabel( selectedStepId: index, stepId: 0, @@ -129,7 +132,7 @@ class StepsWidget extends StatelessWidget { Column( mainAxisAlignment: MainAxisAlignment.start, children: [ - StepWidget(stepLabel: "Objective",), + StepDetailsWidget(stepLabel: "Objective",), StatusLabel( selectedStepId: index, stepId: 1, @@ -183,7 +186,7 @@ class StepsWidget extends StatelessWidget { Column( mainAxisAlignment: MainAxisAlignment.start, children: [ - StepWidget(stepLabel: "Assessment",), + StepDetailsWidget(stepLabel: "Assessment",), StatusLabel( selectedStepId: index, stepId: 2, @@ -232,7 +235,7 @@ class StepsWidget extends StatelessWidget { Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ - StepWidget(stepLabel: "Plan",marginLeft: 30,), + StepDetailsWidget(stepLabel: "Plan",marginLeft: 30,), StatusLabel( selectedStepId: index, stepId: 3, @@ -303,11 +306,7 @@ class StepsWidget extends StatelessWidget { SizedBox(height: 3), Column( children: [ - AppText( - "شخصي", - fontWeight: FontWeight.bold, - fontSize: 16, - ), + StepDetailsWidget(stepLabel: "شخصي",), StatusLabel( selectedStepId: index, stepId: 0, @@ -323,7 +322,7 @@ class StepsWidget extends StatelessWidget { right: MediaQuery .of(context) .size - .width * 0.28, + .width * 0.25, child: InkWell( onTap: () => index >= 2 ? changeCurrentTab(1) : null, child: Column( @@ -356,11 +355,7 @@ class StepsWidget extends StatelessWidget { SizedBox(height: 5), Column( children: [ - AppText( - "هدف", - fontWeight: FontWeight.bold, - fontSize: 14, - ), + StepDetailsWidget(stepLabel: "هدف",), StatusLabel( selectedStepId: index, stepId: 1, @@ -376,7 +371,7 @@ class StepsWidget extends StatelessWidget { right: MediaQuery .of(context) .size - .width * 0.52, + .width * 0.50, child: InkWell( onTap: () => index >= 3 ? changeCurrentTab(2) : null, child: Column( @@ -413,11 +408,7 @@ class StepsWidget extends StatelessWidget { padding: const EdgeInsets.only(right: 2), child: Column( children: [ - AppText( - "تقدير", - fontWeight: FontWeight.bold, - fontSize: 14, - ), + StepDetailsWidget(stepLabel: "تقدير",), StatusLabel( selectedStepId: index, stepId: 2, @@ -468,11 +459,7 @@ class StepsWidget extends StatelessWidget { margin: EdgeInsets.only(right: index == 3 ? 15 : 0), child: Column( children: [ - AppText( - "خطة", - fontWeight: FontWeight.bold, - fontSize: 14, - ), + StepDetailsWidget(stepLabel: "خطة",), StatusLabel( selectedStepId: index, stepId: 3, @@ -488,69 +475,3 @@ class StepsWidget extends StatelessWidget { ); } } - -class StepWidget extends StatelessWidget { - final String stepLabel; - final double marginLeft; - - const StepWidget({ - Key key, this.stepLabel, this.marginLeft = 0, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return AppText( - stepLabel, - fontWeight: FontWeight.bold, - marginLeft: marginLeft, - fontSize:SizeConfig.getTextMultiplierBasedOnWidth() * 3.5 //12, - ); - } -} - -class StatusLabel extends StatelessWidget { - const StatusLabel({ - Key key, - this.stepId, - this.selectedStepId, - }) : super(key: key); - - final int stepId; - final int selectedStepId; - - @override - Widget build(BuildContext context) { - return Container( - width: SizeConfig.getTextMultiplierBasedOnWidth() * 18.5, - padding: EdgeInsets.symmetric(horizontal: 2, vertical: 3), - decoration: BoxDecoration( - color: stepId == selectedStepId - ? Color(0xFFF1E9D3) - : stepId < selectedStepId - ? Color(0xFFD8E8DB) - : Color(0xFFCCCCCC), - borderRadius: BorderRadius.all( - Radius.circular(5.0), - ), - border: Border.all(color: HexColor('#707070'), width: 0.30), - ), - child: Center( - child: AppText( - stepId == selectedStepId - ? "inProgress" - : stepId < selectedStepId - ? "Completed" - : "Locked", - fontWeight: FontWeight.bold, - textAlign: TextAlign.center, - fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 3, - color: stepId == selectedStepId - ? Color(0xFFCC9B14) - : stepId < selectedStepId - ? Color(0xFF359846) - : Color(0xFF969696), - ), - ), - ); - } -} diff --git a/lib/util/translations_delegate_base.dart b/lib/util/translations_delegate_base.dart index d36512ae..2e8d10c9 100644 --- a/lib/util/translations_delegate_base.dart +++ b/lib/util/translations_delegate_base.dart @@ -1233,6 +1233,9 @@ class TranslationBase { localizedValues['typeHereToReply'][locale.languageCode]; String get searchHere => localizedValues['searchHere'][locale.languageCode]; String get remove => localizedValues['remove'][locale.languageCode]; + String get inProgress => localizedValues['inProgress'][locale.languageCode]; + String get completed => localizedValues['Completed'][locale.languageCode]; + String get locked => localizedValues['Locked'][locale.languageCode]; String get step => localizedValues['step'][locale.languageCode]; String get fieldRequired => From 529711d2ce124cd9f81128f99319562a79cdddad Mon Sep 17 00:00:00 2001 From: mosazaid Date: Sun, 25 Jul 2021 12:33:27 +0300 Subject: [PATCH 071/289] video stream crash working to fix --- android/app/build.gradle | 1 + android/app/src/debug/AndroidManifest.xml | 64 --- android/app/src/main/AndroidManifest.xml | 31 +- .../kotlin/com/hmg/hmgDr/AppApplication.kt | 12 + .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 88 ++- .../VideoStreamFloatingWidgetService.kt | 47 +- .../com/hmg/hmgDr/errorhandler/Action.kt | 7 + .../com/hmg/hmgDr/errorhandler/ActionEntry.kt | 34 ++ .../hmg/hmgDr/errorhandler/ErrorHandler.kt | 505 ++++++++++++++++++ .../hmgDr/errorhandler/ExceptionMatcher.kt | 9 + .../com/hmg/hmgDr/errorhandler/Matcher .kt | 5 + .../hmg/hmgDr/errorhandler/MatcherFactory.kt | 11 + .../errorhandler/UnknownErrorCodeException.kt | 3 + .../hmg/hmgDr/errorhandler/retrofit/Range.kt | 45 ++ .../retrofit/RetrofitMatcherFactory.kt | 48 ++ .../hmg/hmgDr/globalErrorHandler/FileUtil.kt | 37 ++ .../LoggingExceptionHandler.kt | 39 ++ .../globalErrorHandler/UCEDefaultActivity.kt | 6 + .../globalErrorHandler/UCEFileProvider.kt | 6 + .../hmgDr/globalErrorHandler/UCEHandler.kt | 280 ++++++++++ .../hmg/hmgDr/util/audio/CustomAudioDevice.kt | 467 ++++++++++++++++ .../res/layout/default_error_activity.xml | 81 +++ android/app/src/main/res/values/strings.xml | 3 +- .../app/src/main/res/xml/provider_paths.xml | 4 + lib/core/service/VideoCallService.dart | 29 +- .../viewModel/authentication_view_model.dart | 2 +- 26 files changed, 1760 insertions(+), 104 deletions(-) delete mode 100644 android/app/src/debug/AndroidManifest.xml create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/AppApplication.kt create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/Action.kt create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/ActionEntry.kt create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/ErrorHandler.kt create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/ExceptionMatcher.kt create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/Matcher .kt create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/MatcherFactory.kt create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/UnknownErrorCodeException.kt create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/retrofit/Range.kt create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/retrofit/RetrofitMatcherFactory.kt create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/globalErrorHandler/FileUtil.kt create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/globalErrorHandler/LoggingExceptionHandler.kt create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/globalErrorHandler/UCEDefaultActivity.kt create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/globalErrorHandler/UCEFileProvider.kt create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/globalErrorHandler/UCEHandler.kt create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/util/audio/CustomAudioDevice.kt create mode 100644 android/app/src/main/res/layout/default_error_activity.xml create mode 100644 android/app/src/main/res/xml/provider_paths.xml diff --git a/android/app/build.gradle b/android/app/build.gradle index 2e124398..c7b2631e 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -108,6 +108,7 @@ dependencies { implementation 'com.squareup.okhttp3:okhttp:4.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.6.2' implementation 'com.squareup.okhttp3:logging-interceptor:4.9.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.1.0' } apply plugin: 'com.google.gms.google-services' \ No newline at end of file diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml deleted file mode 100644 index 23a5488a..00000000 --- a/android/app/src/debug/AndroidManifest.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 2bd477be..82805ecc 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -15,20 +15,25 @@ - - + + + + - - - - @@ -59,6 +60,22 @@ + + + + + + + + \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/AppApplication.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/AppApplication.kt new file mode 100644 index 00000000..8b5994d7 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/AppApplication.kt @@ -0,0 +1,12 @@ +package com.hmg.hmgDr + +import com.hmg.hmgDr.globalErrorHandler.LoggingExceptionHandler +import io.flutter.app.FlutterApplication + +class AppApplication : FlutterApplication() { + + override fun onCreate() { + super.onCreate() + LoggingExceptionHandler(this, "ErrorFile") + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt index 3c879350..5120cb22 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -1,5 +1,6 @@ package com.hmg.hmgDr +import android.Manifest import android.app.Activity import android.content.ComponentName import android.content.Context @@ -17,16 +18,23 @@ import com.google.gson.GsonBuilder import com.hmg.hmgDr.model.GetSessionStatusModel import com.hmg.hmgDr.model.SessionStatusModel import com.hmg.hmgDr.Service.VideoStreamFloatingWidgetService +import com.hmg.hmgDr.globalErrorHandler.FileUtil +import com.hmg.hmgDr.globalErrorHandler.LoggingExceptionHandler import com.hmg.hmgDr.ui.VideoCallResponseListener +import com.hmg.hmgDr.ui.fragment.VideoCallFragment +import com.opentok.android.Session import io.flutter.embedding.android.FlutterFragmentActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel import io.flutter.plugins.GeneratedPluginRegistrant +import pub.devrel.easypermissions.AfterPermissionGranted +import pub.devrel.easypermissions.AppSettingsDialog +import pub.devrel.easypermissions.EasyPermissions class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, - VideoCallResponseListener { + VideoCallResponseListener, EasyPermissions.PermissionCallbacks { /* Permission request code to draw over other apps */ private val DRAW_OVER_OTHER_APP_PERMISSION_REQUEST_CODE = 1222 @@ -41,6 +49,10 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, private var videoStreamService: VideoStreamFloatingWidgetService? = null private var bound = false + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + } + override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { GeneratedPluginRegistrant.registerWith(flutterEngine) @@ -111,7 +123,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, // start service // serviceIntent = Intent(this@MainActivity, VideoStreamContainerService::class.java) - if (videoStreamService == null || videoStreamService?.serviceRunning == false){ + if (videoStreamService == null || videoStreamService?.serviceRunning == false) { serviceIntent = Intent(this@MainActivity, VideoStreamFloatingWidgetService::class.java) serviceIntent?.run { putExtras(arguments) @@ -122,6 +134,8 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, } private fun checkFloatingWidgetPermission() { + requestPermissions() + //Check if the application has draw over other apps permission or not? //This permission is by default available for API<23. But for API > 23 //you have to ask for the permission in runtime. @@ -177,16 +191,20 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, } } else*/ if (requestCode == DRAW_OVER_OTHER_APP_PERMISSION_REQUEST_CODE) { //Check if the permission is granted or not. - if (resultCode == RESULT_OK) - //If permission granted start floating widget service + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (Settings.canDrawOverlays(this)) { + startFloatingWidgetService() + } else { + //Permission is not available then display toast + Toast.makeText( + this, + "Draw over other app permission not available. App won\\'t work without permission. Please try again.", + Toast.LENGTH_SHORT + ).show() + } + } else { startFloatingWidgetService() - else - //Permission is not available then display toast - Toast.makeText( - this, - "Draw over other app permission not available. App won\\'t work without permission. Please try again.", - Toast.LENGTH_SHORT - ).show() + } } else { super.onActivityResult(requestCode, resultCode, data) } @@ -294,4 +312,52 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, } } + + @AfterPermissionGranted(RC_READ_WRITE) + private fun requestPermissions() { + val perms = arrayOf( + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.READ_EXTERNAL_STORAGE + ) + if (EasyPermissions.hasPermissions(this, *perms)) { + } else { + EasyPermissions.requestPermissions( + this, + getString(R.string.remaining_ar), + RC_READ_WRITE, + *perms + ) + } + } + + override fun onPermissionsGranted(requestCode: Int, perms: MutableList?) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: MutableList) { + if (EasyPermissions.somePermissionPermanentlyDenied(this@MainActivity, perms)) { + AppSettingsDialog.Builder(this) + .setTitle(getString(R.string.title_settings_dialog)) + .setRationale(getString(R.string.rationale_ask_again)) + .setPositiveButton(getString(R.string.setting)) + .setNegativeButton(getString(R.string.cancel)) + .setRequestCode(RC_SETTINGS_SCREEN_PERM) + .build() + .show() + } + } + + override fun onRequestPermissionsResult( + requestCode: Int, + permissions: Array, + grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + companion object{ + private const val RC_READ_WRITE = 1 + private const val RC_SETTINGS_SCREEN_PERM = 123 + } } diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt index cdd9ebc0..fcf86260 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt @@ -25,6 +25,7 @@ import com.hmg.hmgDr.ui.VideoCallResponseListener import com.hmg.hmgDr.util.DynamicVideoRenderer import com.hmg.hmgDr.util.NotificationUtil import com.hmg.hmgDr.util.ViewsUtil +import com.hmg.hmgDr.util.audio.CustomAudioDevice import com.opentok.android.* import kotlin.math.ceil @@ -45,6 +46,9 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, const val CHANNEL_DEFAULT_NAME = "Video cAll" const val ONGOING_NOTIFICATION_ID = 1 + private const val TEST_DURATION = 20 //test quality duration in seconds + private const val TIME_WINDOW = 3 //3 seconds + private const val TIME_VIDEO_TEST = 15 //time interval to check the video quality in seconds const val ACTION_START_CALL = "com.hmg.hmgDr.Service.action.startCall" const val ACTION_MINIMIZE_CALL = "com.hmg.hmgDr.Service.action.minimizeCall" @@ -115,6 +119,22 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, private var formattedCallTime: String = "00:00" private lateinit var notificationData: NotificationVideoModel + private val mVideoPLRatio = 0.0 + private val mVideoBw: Long = 0 + private val mAudioPLRatio = 0.0 + private val mAudioBw: Long = 0 + private val mPrevVideoPacketsLost: Long = 0 + private val mPrevVideoPacketsRcvd: Long = 0 + private val mPrevVideoTimestamp = 0.0 + private val mPrevVideoBytes: Long = 0 + private val mPrevAudioPacketsLost: Long = 0 + private val mPrevAudioPacketsRcvd: Long = 0 + private val mPrevAudioTimestamp = 0.0 + private val mPrevAudioBytes: Long = 0 + private val mStartTestTime: Long = 0 + + private val audioOnly = false + private var resume = false var isFullScreen: Boolean = true private var isCircle: Boolean = false @@ -184,6 +204,9 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, override fun onDestroy() { try { mWindowManager?.removeView(floatingWidgetView) + floatingWidgetView = null + mSession = null + mWindowManager = null } catch (e: Exception) { Log.e("onDestroyService", "${e.localizedMessage}.") @@ -339,6 +362,15 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, { miniCircleDoubleTap() }) ) try { + // Add a custom audio device before session initialization + + // Add a custom audio device before session initialization + val customAudioDevice = CustomAudioDevice( + this + ) + customAudioDevice.setRendererMute(true) + AudioDeviceManager.setAudioDevice(customAudioDevice) + mSession = Session.Builder(this, apiKey, sessionId).build() mSession!!.setSessionListener(this) mSession!!.connect(token) @@ -755,6 +787,7 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, // .renderer(ThumbnailCircleVideoRenderer(requireContext())) .build() mPublisher!!.setPublisherListener(this) + mPublisher!!.audioFallbackEnabled = false if (mPublisher!!.view is GLSurfaceView) { (mPublisher!!.view as GLSurfaceView).setZOrderOnTop(true) } @@ -833,7 +866,6 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, } if (mSubscriber != null) { - mSubscriber!!.subscribeToAudio = false // mosa added for error that was originally registered here. Are you missing a call to unregisterReceiver()? mSubscriberViewContainer.removeView(mSubscriber!!.view) mSession!!.unsubscribe(mSubscriber) mSubscriber!!.destroy() @@ -891,6 +923,9 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, */ override fun onVideoDataReceived(subscriberKit: SubscriberKit?) { + if (mSubscriber == null) { + return + } mSubscriber!!.setStyle( BaseVideoRenderer.STYLE_VIDEO_SCALE, BaseVideoRenderer.STYLE_VIDEO_FILL @@ -972,7 +1007,7 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, } } - fun onCallChangeCallStatusSuccessful(){ + fun onCallChangeCallStatusSuccessful() { val returnIntent = Intent() returnIntent.putExtra("CallEnd", sessionStatusModel) videoCallResponseListener?.onCallFinished(Activity.RESULT_CANCELED, returnIntent) @@ -1232,13 +1267,13 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, y_cord_Destination = y_init_margin + y_diff val barHeight: Int = getStatusBarHeight() if (y_cord_Destination < 0) { -// y_cord_Destination = 0 + y_cord_Destination = 0 // y_cord_Destination = // -(szWindow.y - (videoCallContainer.height /*+ barHeight*/)) - y_cord_Destination = -(szWindow.y / 2) +// y_cord_Destination = -(szWindow.y / 2) } else if (y_cord_Destination + (videoCallContainer.height + barHeight) > szWindow.y) { -// y_cord_Destination = szWindow.y - (videoCallContainer.height + barHeight) - y_cord_Destination = (szWindow.y / 2) + y_cord_Destination = szWindow.y - (videoCallContainer.height + barHeight) +// y_cord_Destination = (szWindow.y / 2) } layoutParams.y = y_cord_Destination diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/Action.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/Action.kt new file mode 100644 index 00000000..2b1f3dad --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/Action.kt @@ -0,0 +1,7 @@ +package com.hmg.hmgDr.errorhandler + +/** + * A functional interface representing an action that gets executed + * upon an error by an [ErrorHandler]. + */ +typealias Action = (Throwable, ErrorHandler) -> Unit diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/ActionEntry.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/ActionEntry.kt new file mode 100644 index 00000000..8fc636dd --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/ActionEntry.kt @@ -0,0 +1,34 @@ +package com.hmg.hmgDr.errorhandler + + +/** + * Container to ease passing around a tuple of two objects. This object provides a sensible + * implementation of equals(), returning true if equals() is true on each of the contained + * objects. + */ +class ActionEntry +/** + * Constructor for an ActionEntry. + * + * @param matcher the matcher object in the ActionEntry + * @param action the action object in the ActionEntry + */( + val matcher: Matcher, + val action: Action +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || javaClass != other.javaClass) return false + val that = other as ActionEntry + return if (matcher != that.matcher) false else action == that.action + } + + /** + * Compute a hash code using the hash codes of the underlying objects + * + * @return a hashcode of the ActionEntry + */ + override fun hashCode(): Int { + return matcher.hashCode() xor action.hashCode() + } +} diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/ErrorHandler.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/ErrorHandler.kt new file mode 100644 index 00000000..d504d0f4 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/ErrorHandler.kt @@ -0,0 +1,505 @@ +package com.hmg.hmgDr.errorhandler + +import java.util.HashMap +import kotlin.reflect.KClass + +/** + * https://github.com/mgray88/kotlin-error-handler + * An ErrorHandler is responsible for handling an error by executing one or more actions, + * instances of [Action], that are found to match the error. + */ + +class ErrorHandler private constructor() { + + private val errorCodeMap = mutableMapOf, MatcherFactory<*>>() + private val actions = mutableListOf() + private val otherwiseActions= mutableListOf() + private val alwaysActions = mutableListOf() + private var localContext: ThreadLocal = object : ThreadLocal() { + override fun initialValue(): Context { + return Context() + } + } + private var parentErrorHandler: ErrorHandler? = null + + /** + * Create a new ErrorHandler with the given one as parent. + * + * @param parentErrorHandler the parent @{link ErrorHandler} + */ + private constructor(parentErrorHandler: ErrorHandler) : this() { + this.parentErrorHandler = parentErrorHandler + } + + /** + * Register `action` to be executed by [.handle], + * if the thrown error matches the `matcher`. + * + * @param matcher a matcher to match the thrown error + * @param action the associated action + * @return the current `ErrorHandler` instance - to use in command chains + */ + fun on( + matcher: Matcher, + action: Action + ): ErrorHandler { + actions.add(ActionEntry(matcher, action)) + return this + } + + /** + * Kotlin <1.4 lambda compatibility for `[.on(Matcher, Action)]` + */ + fun on( + matcher: (Throwable) -> Boolean, + action: Action + ): ErrorHandler { + return on(object : Matcher { + override fun matches(throwable: Throwable): Boolean { + return matcher(throwable) + } + }, action) + } + + /** + * Register `action` to be executed by [.handle], + * if the thrown error is an instance of `exceptionClass`. + * + * @param exceptionClass the class of the error + * @param action the associated action + * @return the current `ErrorHandler` instance - to use in command chains + */ + fun on( + exceptionClass: KClass, + action: Action + ): ErrorHandler { + actions.add(ActionEntry(ExceptionMatcher(exceptionClass), action)) + return this + } + + /** + * Register `action` to be executed by [.handle], + * if the thrown error is bound (associated) to `errorCode`. + * + * + * See [.bindClass] and [.bind] + * on how to associate arbitrary error codes with actual Throwables via [Matcher]. + * + * @param the error code type + * @param errorCode the error code + * @param action the associated action + * @return the current `ErrorHandler` instance - to use in command chains + */ + fun on( + errorCode: T, + action: Action + ): ErrorHandler { + val matcherFactory: MatcherFactory = + getMatcherFactoryForErrorCode(errorCode) + ?: throw UnknownErrorCodeException(errorCode) + actions.add(ActionEntry(matcherFactory.build(errorCode), action)) + return this + } + + /** + * Register `action` to be executed in case no other *conditional* + * action gets executed. + * + * @param action the action + * @return the current `ErrorHandler` instance - to use in command chains + */ + fun otherwise(action: Action): ErrorHandler { + otherwiseActions.add(action) + return this + } + + /** + * Register `action` to be executed on all errors. + * + * @param action the action + * @return the current `ErrorHandler` instance - to use in command chains + */ + fun always(action: Action): ErrorHandler { + alwaysActions.add(action) + return this + } + + /** + * Skip all following actions registered via an `on` method + * @return the current `ErrorHandler` instance - to use in command chains + */ + fun skipFollowing(): ErrorHandler { + localContext.get().skipFollowing = true + return this + } + + /** + * Skip all actions registered via [.always] + * @return the current `ErrorHandler` instance - to use in command chains + */ + fun skipAlways(): ErrorHandler { + localContext.get().skipAlways = true + return this + } + + /** + * Skip the default matching actions if any + * @return the current `ErrorHandler` instance - to use in command chains + */ + fun skipDefaults(): ErrorHandler { + localContext.get().skipDefaults = true + return this + } + + private fun handle( + error: Throwable, + context: ThreadLocal + ) { + localContext = context + val ctx = localContext.get() + for (actionEntry in actions) { + if (ctx.skipFollowing) break + if (actionEntry.matcher.matches(error)) { + actionEntry.action(error, this) + ctx.handled = true + } + } + if (!ctx.handled && otherwiseActions.isNotEmpty()) { + for (action in otherwiseActions) { + action(error, this) + ctx.handled = true + } + } + if (!ctx.skipAlways) { + for (action in alwaysActions) { + action(error, this) + ctx.handled = true + } + } + if (!ctx.skipDefaults) { + parentErrorHandler?.handle(error, localContext) + } + } + + /** + * Run a custom code block and assign current ErrorHandler instance + * to handle a possible exception throw in 'catch'. + * + * @param closure functional interface containing Exception prone code + */ + fun runHandling(closure: () -> Unit) { + try { + closure() + } catch (throwable: Throwable) { + handle(throwable, localContext) + } + } + + /** + * Handle `error` by executing all matching actions. + * + * @param error the error as a [Throwable] + */ + fun handle(error: Throwable) { + this.handle(error, localContext) + } + + /** + * Bind an `errorCode` to a `Matcher`, using a `MatcherFactory`. + * + * + * + * For example, when we need to catch a network timeout it's better to just write "timeout" + * instead of a train-wreck expression. So we need to bind this "timeout" error code to an actual + * condition that will check the actual error when it occurs to see if its a network timeout or not. + * + * + *
+     * ```
+     * ErrorHandler
+     *     .defaultErrorHandler()
+     *     .bind("timeout") { errorCode ->
+     *         Matcher { throwable ->
+     *             return (throwable is SocketTimeoutException) && throwable.message.contains("Read timed out")
+     *         }
+     *     }
+     *
+     * // ...
+     *
+     * ErrorHandler
+     *     .create()
+     *     .on("timeout") { throwable, handler ->
+     *         showOfflineScreen()
+     *     }
+     * ```
+     * 
+ * + * + * @param the error code type + * @param errorCode the errorCode value, can use a primitive for clarity and let it be autoboxed + * @param matcherFactory a factory that given an error code, provides a matcher to match the error against it + * @return the current `ErrorHandler` instance - to use in command chains + */ + fun bind( + errorCode: T, + matcherFactory: MatcherFactory + ): ErrorHandler { + errorCodeMap[ErrorCodeIdentifier(errorCode)] = matcherFactory + return this + } + + /** + * Kotlin <1.4 lambda compatibility for `[.bind(T, MatcherFactory)]` + */ + fun bind( + errorCode: T, + matcherFactory: (T) -> (Throwable) -> Boolean + ): ErrorHandler { + return bind(errorCode, object : MatcherFactory { + override fun build(errorCode: T): Matcher { + val matcher = matcherFactory(errorCode) + return object : Matcher { + override fun matches(throwable: Throwable): Boolean { + return matcher(throwable) + } + } + } + }) + } + + /** + * Bind an `errorCode` `Class` to a `Matcher`, using a `MatcherFactory`. + * + * + * + * For example, when we prefer using plain integers to refer to HTTP errors instead of + * checking the HTTPException status code every time. + * + * + *
+     * ```
+     * ErrorHandler
+     *     .defaultErrorHandler()
+     *     .bindClass(Integer::class) { errorCode ->
+     *         Matcher { throwable ->
+     *             return throwable is HttpException && throwable.code() == errorCode
+     *         }
+     *     }
+     *
+     * // ...
+     *
+     * ErrorHandler
+     *     .create()
+     *     .on(404) { throwable, handler ->
+     *         showResourceNotFoundError()
+     *     }
+     *     .on(500) { throwable, handler ->
+     *         showServerError()
+     *     }
+     * ````
+     * 
+ * + * @param the error code type + * @param errorCodeClass the errorCode class + * @param matcherFactory a factory that given an error code, provides a matcher to match the error against it + * @return the current `ErrorHandler` instance - to use in command chains + */ + fun bindClass( + errorCodeClass: KClass, + matcherFactory: MatcherFactory + ): ErrorHandler { + errorCodeMap[ErrorCodeIdentifier(errorCodeClass)] = matcherFactory + return this + } + + /** + * Kotlin <1.4 lambda compatibility for `[.bindClass(KClass, MatcherFactory)]` + */ + fun bindClass( + errorCodeClass: KClass, + matcherFactory: (T) -> (Throwable) -> Boolean + ): ErrorHandler { + return bindClass(errorCodeClass, object : MatcherFactory { + override fun build(errorCode: T): Matcher { + val matcher = matcherFactory(errorCode) + return object : Matcher { + override fun matches(throwable: Throwable): Boolean { + return matcher(throwable) + } + } + } + }) + } + + @Suppress("UNCHECKED_CAST") + protected fun getMatcherFactoryForErrorCode(errorCode: T): MatcherFactory? { + var matcherFactory: MatcherFactory? + matcherFactory = errorCodeMap[ErrorCodeIdentifier(errorCode)] as? MatcherFactory + if (matcherFactory != null) { + return matcherFactory + } + + matcherFactory = errorCodeMap[ErrorCodeIdentifier(errorCode::class)] as? MatcherFactory + if (matcherFactory != null) { + return matcherFactory + } + return if (parentErrorHandler != null) { + parentErrorHandler?.getMatcherFactoryForErrorCode(errorCode) + } else null + } + + /** + * Clear ErrorHandler instance from all its registered Actions and Matchers. + */ + fun clear() { + actions.clear() + errorCodeMap.clear() + otherwiseActions.clear() + alwaysActions.clear() + localContext.get().clear() + } + + private class Context { + private val keys = HashMap() + var handled = false + var skipDefaults = false + var skipFollowing = false + var skipAlways = false + operator fun get(key: Any?): Any? { + return keys[key] + } + + fun put(key: String, value: Any): Any? { + return keys.put(key, value) + } + + fun remove(key: Any?): Any? { + return keys.remove(key) + } + + fun clear() { + keys.clear() + skipDefaults = false + skipFollowing = false + skipAlways = false + } + } + + /** + * Used to identify an error code either by its "literal" value + * or by its Class. + * + * + * When using custom objects as error codes, + * make sure you implement [Object.equals] to allow ErrorHandler + * perform equality comparisons between instances. + */ + private class ErrorCodeIdentifier { + private val errorCode: T? + private val errorCodeClass: KClass? + + internal constructor(errorCode: T) { + this.errorCode = errorCode + this.errorCodeClass = null + } + + internal constructor(errorCodeClass: KClass) { + this.errorCode = null + this.errorCodeClass = errorCodeClass + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || javaClass != other.javaClass) return false + + val that = other as ErrorCodeIdentifier<*> + + if (if (errorCode != null) errorCode != that.errorCode else that.errorCode != null) return false + return if (errorCodeClass != null) errorCodeClass == that.errorCodeClass else that.errorCodeClass == null + } + + override fun hashCode(): Int { + var result = errorCode?.hashCode() ?: 0 + result = 31 * result + (errorCodeClass?.hashCode() ?: 0) + return result + } + } + + companion object { + private var defaultInstance: ErrorHandler? = null + + /** + * Create a new @{link ErrorHandler}, isolated from the default one. + * + * + * In other words, designed to handle all errors by itself without delegating + * to the default error handler. + * + * @return returns a new `ErrorHandler` instance + */ + @JvmStatic + fun createIsolated(): ErrorHandler { + return ErrorHandler() + } + + /** + * Create a new @{link ErrorHandler}, that delegates to the default one, or the + * parent @{link ErrorHandler} passed in + * + * Any default actions, are always executed after the ones registered on this one. + * + * @param parentErrorHandler `ErrorHandler` to use as the parent + * @return returns a new `ErrorHandler` instance + */ + @JvmStatic + fun create(parentErrorHandler: ErrorHandler? = null): ErrorHandler { + return ErrorHandler(parentErrorHandler ?: defaultErrorHandler()) + } + + /** + * Get the default @{link ErrorHandler}, a singleton object + * to which all other instances by default delegate to. + * + * @return the default @{link ErrorHandler} instance + */ + @JvmStatic + @Synchronized + fun defaultErrorHandler(): ErrorHandler { + if (defaultInstance == null) { + defaultInstance = + ErrorHandler() + } + return defaultInstance!! + } + } +} + +/** + * Wrapper around `[.on(KClass, Action)]` to allow action's `Throwable` parameter + * to be typed to the `Throwable` expected + */ +inline fun ErrorHandler.on( + noinline action: (T, ErrorHandler) -> Unit +): ErrorHandler { + return on(T::class) { throwable, errorHandler -> + action(throwable as T, errorHandler) + } +} + +/** + * Lazy `ErrorHandler` initializer which delegates to a parent, or the `defaultErrorHandler` + * if the parent is not supplied. Uses optional lambda function to add actions and bindings to + * the new `ErrorHandler` + * + * @param parentErrorHandler (optional) error handler to delegate default actions to + * @param apply (optional) apply function for adding actions and binding + * @return lazy initialized `ErrorHandler` + */ +inline fun errorHandler( + parentErrorHandler: ErrorHandler? = null, + noinline apply: (ErrorHandler.() -> Unit)? = null +) = lazy { + val eh = ErrorHandler.create(parentErrorHandler) + apply?.invoke(eh) + return@lazy eh +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/ExceptionMatcher.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/ExceptionMatcher.kt new file mode 100644 index 00000000..4ab02f8a --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/ExceptionMatcher.kt @@ -0,0 +1,9 @@ +package com.hmg.hmgDr.errorhandler + +import kotlin.reflect.KClass + +class ExceptionMatcher(private val errorClass: KClass) : Matcher { + override fun matches(throwable: Throwable): Boolean { + return errorClass.isInstance(throwable) + } +} diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/Matcher .kt b/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/Matcher .kt new file mode 100644 index 00000000..acf8b3c1 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/Matcher .kt @@ -0,0 +1,5 @@ +package com.hmg.hmgDr.errorhandler + +interface Matcher { + fun matches(throwable: Throwable): Boolean +} diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/MatcherFactory.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/MatcherFactory.kt new file mode 100644 index 00000000..af296213 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/MatcherFactory.kt @@ -0,0 +1,11 @@ +package com.hmg.hmgDr.errorhandler + +interface MatcherFactory { + /** + * Build a [Matcher] to match the given error code against an error + * + * @param errorCode the error code + * @return a new [Matcher] + */ + fun build(errorCode: T): Matcher +} diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/UnknownErrorCodeException.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/UnknownErrorCodeException.kt new file mode 100644 index 00000000..46abc572 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/UnknownErrorCodeException.kt @@ -0,0 +1,3 @@ +package com.hmg.hmgDr.errorhandler + +class UnknownErrorCodeException(val errorCode: Any) : RuntimeException() diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/retrofit/Range.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/retrofit/Range.kt new file mode 100644 index 00000000..e6abc82e --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/retrofit/Range.kt @@ -0,0 +1,45 @@ +package com.hmg.hmgDr.errorhandler.retrofit + +/** + * Range class for HTTP status codes + */ +class Range private constructor(val lowerBound: Int, val upperBound: Int) { + + /** + * Checks if the passed httpStatusCode is contained in given range + * + * @param httpStatusCode the status code to check + * @return true if contains, otherwise false + */ + operator fun contains(httpStatusCode: Int): Boolean { + return httpStatusCode in lowerBound..upperBound + } + + override fun equals(o: Any?): Boolean { + if (this === o) return true + if (o == null || javaClass != o.javaClass) return false + val range = + o as Range + return if (lowerBound != range.lowerBound) false else upperBound == range.upperBound + } + + override fun hashCode(): Int { + var result = lowerBound + result = 31 * result + upperBound + return result + } + + companion object { + /** + * Creates a Range object with lower and upper bound + * @param lowerBound lower limit of Range + * @param upperBound upper limit of Range + * + * @return a Range instance + */ + @JvmStatic + fun of(lowerBound: Int, upperBound: Int): Range { + return Range(lowerBound, upperBound) + } + } +} diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/retrofit/RetrofitMatcherFactory.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/retrofit/RetrofitMatcherFactory.kt new file mode 100644 index 00000000..062fc30e --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/errorhandler/retrofit/RetrofitMatcherFactory.kt @@ -0,0 +1,48 @@ +package com.hmg.hmgDr.errorhandler.retrofit + +import com.hmg.hmgDr.errorhandler.Matcher +import com.hmg.hmgDr.errorhandler.MatcherFactory +import retrofit2.adapter.rxjava.HttpException + +object RetrofitMatcherFactory { + + /** + * Creates a [MatcherFactory] that checks HTTP statuses + * + * @return new MatcherFactory for Retrofit Rx HttpException that works with Integer + */ + @JvmStatic + fun create(): MatcherFactory { + return object : MatcherFactory { + override fun build(errorCode: Int): Matcher { + return object : Matcher { + override fun matches(throwable: Throwable): Boolean { + return throwable is HttpException && + throwable.code() == errorCode + } + } + } + } + } + + /** + * Creates a [MatcherFactory] that checks if HTTP status is in given [Range] + * + * @return new MatcherFactory for Retrofit Rx HttpException that works with Range + */ + @JvmStatic + fun createRange(): MatcherFactory { + return object : MatcherFactory { + override fun build(errorCode: Range): Matcher { + return object : Matcher { + override fun matches(throwable: Throwable): Boolean { + return throwable is HttpException && + errorCode.contains(throwable.code()) + } + } + } + } + } + + +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/globalErrorHandler/FileUtil.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/globalErrorHandler/FileUtil.kt new file mode 100644 index 00000000..13fc2dd7 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/globalErrorHandler/FileUtil.kt @@ -0,0 +1,37 @@ +package com.hmg.hmgDr.globalErrorHandler + +import android.os.Environment +import java.io.BufferedWriter +import java.io.File +import java.io.FileWriter +import java.io.IOException +import java.text.SimpleDateFormat +import java.util.* + + +object FileUtil { + + val sdf = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS") + + fun pushLog(body: String?) { + try { + val date = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(Date()) + val time = SimpleDateFormat("HH:MM:SS", Locale.getDefault()).format(Date()) + val root = + File(Environment.getExternalStorageDirectory(),"error_log_dir") + // if external memory exists and folder with name Notes + if (!root.exists()) { + root.mkdirs() // this will create folder. + } + val oldFile = File(root, "error" + sdf.format(Date()).toString() + ".txt") // old file + if (oldFile.exists()) oldFile.delete() + val filepath = File(root, "error$date.txt") // file path to save + val bufferedWriter = BufferedWriter(FileWriter(filepath, true)) + bufferedWriter.append("\r\n") + bufferedWriter.append("\r\n").append(body).append(" Time : ").append(time) + bufferedWriter.flush() + } catch (e: IOException) { + e.printStackTrace() + } + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/globalErrorHandler/LoggingExceptionHandler.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/globalErrorHandler/LoggingExceptionHandler.kt new file mode 100644 index 00000000..cfbd26ca --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/globalErrorHandler/LoggingExceptionHandler.kt @@ -0,0 +1,39 @@ +package com.hmg.hmgDr.globalErrorHandler + +import android.content.Context +import android.content.Intent +import com.hmg.hmgDr.MainActivity +import com.hmg.hmgDr.globalErrorHandler.FileUtil.pushLog + + +class LoggingExceptionHandler(private val context: Context, ErrorFile: String) : + Thread.UncaughtExceptionHandler { + private val rootHandler: Thread.UncaughtExceptionHandler + override fun uncaughtException(t: Thread, e: Throwable) { + object : Thread() { + override fun run() { + pushLog("UnCaught Exception is thrown in $error$e") + try { + sleep(500) + val intent = Intent(context, MainActivity::class.java) + intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP + context.startActivity(intent) + } catch (e1: Exception) { + e1.printStackTrace() + } + } + }.start() + rootHandler.uncaughtException(t, e) + } + + companion object { + private val TAG = LoggingExceptionHandler::class.java.simpleName + lateinit var error: String + } + + init { + error = "$ErrorFile.error " + rootHandler = Thread.getDefaultUncaughtExceptionHandler() + Thread.setDefaultUncaughtExceptionHandler(this) + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/globalErrorHandler/UCEDefaultActivity.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/globalErrorHandler/UCEDefaultActivity.kt new file mode 100644 index 00000000..8ee4bbd0 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/globalErrorHandler/UCEDefaultActivity.kt @@ -0,0 +1,6 @@ +package com.hmg.hmgDr.globalErrorHandler + +import androidx.appcompat.app.AppCompatActivity + +class UCEDefaultActivity : AppCompatActivity() { +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/globalErrorHandler/UCEFileProvider.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/globalErrorHandler/UCEFileProvider.kt new file mode 100644 index 00000000..70376428 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/globalErrorHandler/UCEFileProvider.kt @@ -0,0 +1,6 @@ +package com.hmg.hmgDr.globalErrorHandler + +import androidx.core.content.FileProvider + +class UCEFileProvider : FileProvider() { +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/globalErrorHandler/UCEHandler.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/globalErrorHandler/UCEHandler.kt new file mode 100644 index 00000000..35654d1f --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/globalErrorHandler/UCEHandler.kt @@ -0,0 +1,280 @@ +package com.hmg.hmgDr.globalErrorHandler + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.Application; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.lang.ref.WeakReference; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayDeque; +import java.util.Date; +import java.util.Deque; +import java.util.Locale; +import kotlin.system.exitProcess + +class UCEHandler(val builder: Builder) { + + val EXTRA_STACK_TRACE = "EXTRA_STACK_TRACE" + val EXTRA_ACTIVITY_LOG = "EXTRA_ACTIVITY_LOG" + private val TAG = "UCEHandler" + private val UCE_HANDLER_PACKAGE_NAME = "com.rohitss.uceh" + private val DEFAULT_HANDLER_PACKAGE_NAME = "com.android.internal.os" + private val MAX_STACK_TRACE_SIZE = 131071 //128 KB - 1 + + private val MAX_ACTIVITIES_IN_LOG = 50 + private val SHARED_PREFERENCES_FILE = "uceh_preferences" + private val SHARED_PREFERENCES_FIELD_TIMESTAMP = "last_crash_timestamp" + private val activityLog: Deque = ArrayDeque(MAX_ACTIVITIES_IN_LOG) + var COMMA_SEPARATED_EMAIL_ADDRESSES: String? = null + + @SuppressLint("StaticFieldLeak") + private var application: Application? = null + private var isInBackground = true + private var isBackgroundMode = false + private var isUCEHEnabled = false + private var isTrackActivitiesEnabled = false + private var lastActivityCreated: WeakReference = WeakReference(null) + + fun UCEHandler(builder: Builder) { + isUCEHEnabled = builder.isUCEHEnabled + isTrackActivitiesEnabled = builder.isTrackActivitiesEnabled + isBackgroundMode = builder.isBackgroundModeEnabled + COMMA_SEPARATED_EMAIL_ADDRESSES = builder.commaSeparatedEmailAddresses + setUCEHandler(builder.context) + } + + private fun setUCEHandler(context: Context?) { + try { + if (context != null) { + val oldHandler = Thread.getDefaultUncaughtExceptionHandler() + if (oldHandler != null && oldHandler.javaClass.name.startsWith( + UCE_HANDLER_PACKAGE_NAME + ) + ) { + Log.e(TAG, "UCEHandler was already installed, doing nothing!") + } else { + if (oldHandler != null && !oldHandler.javaClass.name.startsWith( + DEFAULT_HANDLER_PACKAGE_NAME + ) + ) { + Log.e( + TAG, + "You already have an UncaughtExceptionHandler. If you use a custom UncaughtExceptionHandler, it should be initialized after UCEHandler! Installing anyway, but your original handler will not be called." + ) + } + application = context.getApplicationContext() as Application + //Setup UCE Handler. + Thread.setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler { thread, throwable -> + if (isUCEHEnabled) { + Log.e( + TAG, + "App crashed, executing UCEHandler's UncaughtExceptionHandler", + throwable + ) + if (hasCrashedInTheLastSeconds(application!!)) { + Log.e( + TAG, + "App already crashed recently, not starting custom error activity because we could enter a restart loop. Are you sure that your app does not crash directly on init?", + throwable + ) + if (oldHandler != null) { + oldHandler.uncaughtException(thread, throwable) + return@UncaughtExceptionHandler + } + } else { + setLastCrashTimestamp(application!!, Date().getTime()) + if (!isInBackground || isBackgroundMode) { + val intent = Intent(application, UCEDefaultActivity::class.java) + val sw = StringWriter() + val pw = PrintWriter(sw) + throwable.printStackTrace(pw) + var stackTraceString: String = sw.toString() + if (stackTraceString.length > MAX_STACK_TRACE_SIZE) { + val disclaimer = " [stack trace too large]" + stackTraceString = stackTraceString.substring( + 0, + MAX_STACK_TRACE_SIZE - disclaimer.length + ) + disclaimer + } + intent.putExtra(EXTRA_STACK_TRACE, stackTraceString) + if (isTrackActivitiesEnabled) { + val activityLogStringBuilder = StringBuilder() + while (!activityLog.isEmpty()) { + activityLogStringBuilder.append(activityLog.poll()) + } + intent.putExtra( + EXTRA_ACTIVITY_LOG, + activityLogStringBuilder.toString() + ) + } + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + application!!.startActivity(intent) + } else { + if (oldHandler != null) { + oldHandler.uncaughtException(thread, throwable) + return@UncaughtExceptionHandler + } + //If it is null (should not be), we let it continue and kill the process or it will be stuck + } + } + val lastActivity: Activity? = lastActivityCreated.get() + if (lastActivity != null) { + lastActivity.finish() + lastActivityCreated.clear() + } + killCurrentProcess() + } else oldHandler?.uncaughtException(thread, throwable) + }) + application!!.registerActivityLifecycleCallbacks(object : + Application.ActivityLifecycleCallbacks { + val dateFormat: DateFormat = + SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US) + var currentlyStartedActivities = 0 + + override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) { + if (activity.javaClass !== UCEDefaultActivity::class.java) { + lastActivityCreated = WeakReference(activity) + } + if (isTrackActivitiesEnabled) { + activityLog.add( + dateFormat.format(Date()) + .toString() + ": " + activity.javaClass + .getSimpleName() + " created\n" + ) + } + } + + override fun onActivityStarted(activity: Activity) { + currentlyStartedActivities++ + isInBackground = currentlyStartedActivities == 0 + } + + override fun onActivityResumed(activity: Activity) { + if (isTrackActivitiesEnabled) { + activityLog.add( + dateFormat.format(Date()) + .toString() + ": " + activity.javaClass + .simpleName + " resumed\n" + ) + } + } + + override fun onActivityPaused(activity: Activity) { + if (isTrackActivitiesEnabled) { + activityLog.add( + dateFormat.format(Date()) + .toString() + ": " + activity.javaClass + .simpleName + " paused\n" + ) + } + } + + override fun onActivityStopped(activity: Activity) { + currentlyStartedActivities-- + isInBackground = currentlyStartedActivities == 0 + } + + override fun onActivitySaveInstanceState( + activity: Activity, + outState: Bundle + ) {} + override fun onActivityDestroyed(activity: Activity) { + if (isTrackActivitiesEnabled) { + activityLog.add( + dateFormat.format(Date()) + .toString() + ": " + activity.javaClass + .simpleName + " destroyed\n" + ) + } + } + }) + } + Log.i(TAG, "UCEHandler has been installed.") + } else { + Log.e(TAG, "Context can not be null") + } + } catch (throwable: Throwable) { + Log.e( + TAG, + "UCEHandler can not be initialized. Help making it better by reporting this as a bug.", + throwable + ) + } + } + + /** + * INTERNAL method that tells if the app has crashed in the last seconds. + * This is used to avoid restart loops. + * + * @return true if the app has crashed in the last seconds, false otherwise. + */ + private fun hasCrashedInTheLastSeconds(context: Context): Boolean { + val lastTimestamp = getLastCrashTimestamp(context) + val currentTimestamp: Long = Date().getTime() + return lastTimestamp <= currentTimestamp && currentTimestamp - lastTimestamp < 3000 + } + + @SuppressLint("ApplySharedPref") + private fun setLastCrashTimestamp(context: Context, timestamp: Long) { + context.getSharedPreferences(SHARED_PREFERENCES_FILE, Context.MODE_PRIVATE).edit() + .putLong(SHARED_PREFERENCES_FIELD_TIMESTAMP, timestamp).commit() + } + + private fun killCurrentProcess() { +// Process.killProcess(Process.myPid()) + exitProcess(10) + } + + private fun getLastCrashTimestamp(context: Context): Long { + return context.getSharedPreferences(SHARED_PREFERENCES_FILE, Context.MODE_PRIVATE) + .getLong(SHARED_PREFERENCES_FIELD_TIMESTAMP, -1) + } + + fun closeApplication(activity: Activity) { + activity.finish() + killCurrentProcess() + } + + inner class Builder(context: Context) { + val context: Context + var isUCEHEnabled = true + var commaSeparatedEmailAddresses: String? = null + var isTrackActivitiesEnabled = false + var isBackgroundModeEnabled = true + fun setUCEHEnabled(isUCEHEnabled: Boolean): Builder { + this.isUCEHEnabled = isUCEHEnabled + return this + } + + fun setTrackActivitiesEnabled(isTrackActivitiesEnabled: Boolean): Builder { + this.isTrackActivitiesEnabled = isTrackActivitiesEnabled + return this + } + + fun setBackgroundModeEnabled(isBackgroundModeEnabled: Boolean): Builder { + this.isBackgroundModeEnabled = isBackgroundModeEnabled + return this + } + + fun addCommaSeparatedEmailAddresses(commaSeparatedEmailAddresses: String?): Builder { + this.commaSeparatedEmailAddresses = commaSeparatedEmailAddresses ?: "" + return this + } + + fun build() { + return UCEHandler(this) + } + + init { + this.context = context + } + } + +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/util/audio/CustomAudioDevice.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/util/audio/CustomAudioDevice.kt new file mode 100644 index 00000000..ef654844 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/util/audio/CustomAudioDevice.kt @@ -0,0 +1,467 @@ +package com.hmg.hmgDr.util.audio + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.media.AudioFormat +import android.media.AudioManager +import android.media.AudioRecord +import android.media.AudioTrack +import android.media.MediaRecorder.AudioSource +import android.os.Process +import android.util.Log + +import com.opentok.android.BaseAudioDevice + +import java.nio.ByteBuffer +import java.util.concurrent.locks.Condition +import java.util.concurrent.locks.ReentrantLock + +class CustomAudioDevice(context: Context) : BaseAudioDevice() { + + private val m_context: Context = context + private var m_audioTrack: AudioTrack? = null + private var m_audioRecord: AudioRecord? = null + + // Capture & render buffers + private var m_playBuffer: ByteBuffer? = null + private var m_recBuffer: ByteBuffer? = null + private val m_tempBufPlay: ByteArray + private val m_tempBufRec: ByteArray + private val m_rendererLock: ReentrantLock = ReentrantLock(true) + private val m_renderEvent: Condition = m_rendererLock.newCondition() + + @Volatile + private var m_isRendering = false + + @Volatile + private var m_shutdownRenderThread = false + private val m_captureLock: ReentrantLock = ReentrantLock(true) + private val m_captureEvent: Condition = m_captureLock.newCondition() + + @Volatile + private var m_isCapturing = false + + @Volatile + private var m_shutdownCaptureThread = false + private val m_captureSettings: AudioSettings + private val m_rendererSettings: AudioSettings + + // Capturing delay estimation + private var m_estimatedCaptureDelay = 0 + + // Rendering delay estimation + private var m_bufferedPlaySamples = 0 + private var m_playPosition = 0 + private var m_estimatedRenderDelay = 0 + private val m_audioManager: AudioManager + private var isRendererMuted = false + + companion object { + private const val LOG_TAG = "opentok-defaultaudio" + private const val SAMPLING_RATE = 44100 + private const val NUM_CHANNELS_CAPTURING = 1 + private const val NUM_CHANNELS_RENDERING = 1 + private const val MAX_SAMPLES = 2 * 480 * 2 // Max 10 ms @ 48 kHz + } + + init { + try { + m_playBuffer = ByteBuffer.allocateDirect(MAX_SAMPLES) + m_recBuffer = ByteBuffer.allocateDirect(MAX_SAMPLES) + } catch (e: Exception) { + Log.e(LOG_TAG, "${e.message}.") + } + m_tempBufPlay = ByteArray(MAX_SAMPLES) + m_tempBufRec = ByteArray(MAX_SAMPLES) + m_captureSettings = AudioSettings( + SAMPLING_RATE, + NUM_CHANNELS_CAPTURING + ) + m_rendererSettings = AudioSettings( + SAMPLING_RATE, + NUM_CHANNELS_RENDERING + ) + m_audioManager = m_context + .getSystemService(Context.AUDIO_SERVICE) as AudioManager + m_audioManager.mode = AudioManager.MODE_IN_COMMUNICATION + } + + override fun initCapturer(): Boolean { + + // get the minimum buffer size that can be used + val minRecBufSize: Int = AudioRecord.getMinBufferSize( + m_captureSettings + .sampleRate, + if (NUM_CHANNELS_CAPTURING == 1) AudioFormat.CHANNEL_IN_MONO else AudioFormat.CHANNEL_IN_STEREO, + AudioFormat.ENCODING_PCM_16BIT + ) + + // double size to be more safe + val recBufSize = minRecBufSize * 2 + + // release the object + if (m_audioRecord != null) { + m_audioRecord!!.release() + m_audioRecord = null + } + try { + m_audioRecord = AudioRecord( + AudioSource.VOICE_COMMUNICATION, + m_captureSettings.sampleRate, + if (NUM_CHANNELS_CAPTURING == 1) AudioFormat.CHANNEL_IN_MONO else AudioFormat.CHANNEL_IN_STEREO, + AudioFormat.ENCODING_PCM_16BIT, recBufSize + ) + } catch (e: Exception) { + Log.e(LOG_TAG, "${e.message}.") + return false + } + + // check that the audioRecord is ready to be used + if (m_audioRecord!!.state != AudioRecord.STATE_INITIALIZED) { + Log.i( + LOG_TAG, "Audio capture is not initialized " + + m_captureSettings.sampleRate + ) + return false + } + m_shutdownCaptureThread = false + Thread(m_captureThread).start() + return true + } + + override fun destroyCapturer(): Boolean { + m_captureLock.lock() + // release the object + m_audioRecord?.release() + m_audioRecord = null + m_shutdownCaptureThread = true + m_captureEvent.signal() + m_captureLock.unlock() + return true + } + + override fun getEstimatedCaptureDelay(): Int { + return m_estimatedCaptureDelay + } + + override fun startCapturer(): Boolean { + // start recording + try { + m_audioRecord!!.startRecording() + } catch (e: IllegalStateException) { + e.printStackTrace() + return false + } + m_captureLock.lock() + m_isCapturing = true + m_captureEvent.signal() + m_captureLock.unlock() + return true + } + + override fun stopCapturer(): Boolean { + m_captureLock.lock() + try { + // only stop if we are recording + if (m_audioRecord!!.recordingState == AudioRecord.RECORDSTATE_RECORDING) { + // stop recording + try { + m_audioRecord!!.stop() + } catch (e: IllegalStateException) { + e.printStackTrace() + return false + } + } + } finally { + // Ensure we always unlock + m_isCapturing = false + m_captureLock.unlock() + } + return true + } + + private val m_captureThread = Runnable { + val samplesToRec = SAMPLING_RATE / 100 + var samplesRead = 0 + try { + Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO) + } catch (e: Exception) { + e.printStackTrace() + } + while (!m_shutdownCaptureThread) { + m_captureLock.lock() + samplesRead = try { + if (!m_isCapturing) { + m_captureEvent.await() + continue + } else { + if (m_audioRecord == null) { + continue + } + val lengthInBytes = ((samplesToRec shl 1) + * NUM_CHANNELS_CAPTURING) + val readBytes: Int = m_audioRecord!!.read( + m_tempBufRec, 0, + lengthInBytes + ) + m_recBuffer!!.rewind() + m_recBuffer!!.put(m_tempBufRec) + (readBytes shr 1) / NUM_CHANNELS_CAPTURING + } + } catch (e: Exception) { + Log.e(LOG_TAG, "RecordAudio try failed: " + e.message) + continue + } finally { + // Ensure we always unlock + m_captureLock.unlock() + } + audioBus.writeCaptureData(m_recBuffer, samplesRead) + m_estimatedCaptureDelay = samplesRead * 1000 / SAMPLING_RATE + } + } + + override fun initRenderer(): Boolean { + + // get the minimum buffer size that can be used + val minPlayBufSize: Int = AudioTrack.getMinBufferSize( + m_rendererSettings + .sampleRate, + if (NUM_CHANNELS_RENDERING == 1) AudioFormat.CHANNEL_OUT_MONO else AudioFormat.CHANNEL_OUT_STEREO, + AudioFormat.ENCODING_PCM_16BIT + ) + var playBufSize = minPlayBufSize + if (playBufSize < 6000) { + playBufSize *= 2 + } + + // release the object + if (m_audioTrack != null) { + m_audioTrack!!.release() + m_audioTrack = null + } + try { + m_audioTrack = AudioTrack( + AudioManager.STREAM_VOICE_CALL, + m_rendererSettings.sampleRate, + if (NUM_CHANNELS_RENDERING == 1) AudioFormat.CHANNEL_OUT_MONO else AudioFormat.CHANNEL_OUT_STEREO, + AudioFormat.ENCODING_PCM_16BIT, playBufSize, + AudioTrack.MODE_STREAM + ) + } catch (e: Exception) { + Log.e(LOG_TAG, "${e.message}.") + return false + } + + // check that the audioRecord is ready to be used + if (m_audioTrack!!.state != AudioTrack.STATE_INITIALIZED) { + Log.i( + LOG_TAG, "Audio renderer not initialized " + + m_rendererSettings.sampleRate + ) + return false + } + m_bufferedPlaySamples = 0 + setOutputMode(OutputMode.SpeakerPhone) + m_shutdownRenderThread = false + Thread(m_renderThread).start() + return true + } + + override fun destroyRenderer(): Boolean { + m_rendererLock.lock() + // release the object + m_audioTrack!!.release() + m_audioTrack = null + m_shutdownRenderThread = true + m_renderEvent.signal() + m_rendererLock.unlock() + unregisterHeadsetReceiver() + m_audioManager.isSpeakerphoneOn = false + m_audioManager.mode = AudioManager.MODE_NORMAL + return true + } + + override fun getEstimatedRenderDelay(): Int { + return m_estimatedRenderDelay + } + + override fun startRenderer(): Boolean { + // start playout + try { + m_audioTrack!!.play() + } catch (e: IllegalStateException) { + e.printStackTrace() + return false + } + m_rendererLock.lock() + m_isRendering = true + m_renderEvent.signal() + m_rendererLock.unlock() + return true + } + + override fun stopRenderer(): Boolean { + m_rendererLock.lock() + try { + // only stop if we are playing + if (m_audioTrack!!.getPlayState() == AudioTrack.PLAYSTATE_PLAYING) { + // stop playout + try { + m_audioTrack!!.stop() + } catch (e: IllegalStateException) { + e.printStackTrace() + return false + } + + // flush the buffers + m_audioTrack!!.flush() + } + } finally { + // Ensure we always unlock, both for success, exception or error + // return. + m_isRendering = false + m_rendererLock.unlock() + } + return true + } + + private val m_renderThread = Runnable { + val samplesToPlay = SAMPLING_RATE / 100 + try { + Process + .setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO) + } catch (e: Exception) { + e.printStackTrace() + } + while (!m_shutdownRenderThread) { + m_rendererLock.lock() + try { + if (!m_isRendering) { + m_renderEvent.await() + continue + } else { + m_rendererLock.unlock() + + // Don't lock on audioBus calls + m_playBuffer!!.clear() + val samplesRead: Int = audioBus.readRenderData( + m_playBuffer, samplesToPlay + ) + + // Log.d(LOG_TAG, "Samples read: " + samplesRead); + m_rendererLock.lock() + if (!isRendererMuted) { + // After acquiring the lock again + // we must check if we are still playing + if (m_audioTrack == null + || !m_isRendering + ) { + continue + } + val bytesRead = ((samplesRead shl 1) + * NUM_CHANNELS_RENDERING) + m_playBuffer!!.get(m_tempBufPlay, 0, bytesRead) + val bytesWritten: Int = m_audioTrack!!.write( + m_tempBufPlay, 0, + bytesRead + ) + + // increase by number of written samples + m_bufferedPlaySamples += ((bytesWritten shr 1) + / NUM_CHANNELS_RENDERING) + + // decrease by number of played samples + val pos: Int = m_audioTrack!!.getPlaybackHeadPosition() + if (pos < m_playPosition) { + // wrap or reset by driver + m_playPosition = 0 + } + m_bufferedPlaySamples -= pos - m_playPosition + m_playPosition = pos + + // we calculate the estimated delay based on the + // buffered samples + m_estimatedRenderDelay = (m_bufferedPlaySamples * 1000 + / SAMPLING_RATE) + } + } + } catch (e: Exception) { + Log.e(LOG_TAG, "Exception: " + e.message) + e.printStackTrace() + } finally { + m_rendererLock.unlock() + } + } + } + + override fun getCaptureSettings(): AudioSettings { + return m_captureSettings + } + + override fun getRenderSettings(): AudioSettings { + return m_rendererSettings + } + + /** + * Communication modes handling + */ + override fun setOutputMode(mode: OutputMode): Boolean { + super.setOutputMode(mode) + if (mode == OutputMode.Handset) { + unregisterHeadsetReceiver() + m_audioManager.isSpeakerphoneOn = false + } else { + m_audioManager.isSpeakerphoneOn = true + registerHeadsetReceiver() + } + return true + } + + private val m_headsetReceiver: BroadcastReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context?, intent: Intent) { + if (intent.action!!.compareTo(Intent.ACTION_HEADSET_PLUG) == 0) { + val state: Int = intent.getIntExtra("state", 0) + m_audioManager.isSpeakerphoneOn = state == 0 + } + } + } + private var m_receiverRegistered = false + private fun registerHeadsetReceiver() { + if (!m_receiverRegistered) { + val receiverFilter = IntentFilter( + Intent.ACTION_HEADSET_PLUG + ) + m_context.registerReceiver(m_headsetReceiver, receiverFilter) + m_receiverRegistered = true + } + } + + private fun unregisterHeadsetReceiver() { + if (m_receiverRegistered) { + try { + m_context.unregisterReceiver(m_headsetReceiver) + } catch (e: IllegalArgumentException) { + e.printStackTrace() + } + m_receiverRegistered = false + } + } + + override fun onPause() { + if (outputMode == OutputMode.SpeakerPhone) { + unregisterHeadsetReceiver() + } + } + + override fun onResume() { + if (outputMode == OutputMode.SpeakerPhone) { + registerHeadsetReceiver() + } + } + + fun setRendererMute(isRendererMuted: Boolean) { + this.isRendererMuted = isRendererMuted + } +} diff --git a/android/app/src/main/res/layout/default_error_activity.xml b/android/app/src/main/res/layout/default_error_activity.xml new file mode 100644 index 00000000..21af70f2 --- /dev/null +++ b/android/app/src/main/res/layout/default_error_activity.xml @@ -0,0 +1,81 @@ + + + + + + + + + +