From 0fe6d880fdfbaf70ea066a9c11e04cb37e606e18 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Mon, 7 Jun 2021 10:53:36 +0300 Subject: [PATCH 01/72] add livecare send instructions --- lib/config/config.dart | 1 + .../patient/LiveCarePatientServices.dart | 13 +++++++++++++ .../viewModel/LiveCarePatientViewModel.dart | 12 ++++++++++++ lib/screens/live_care/end_call_screen.dart | 19 ++++++++++++++++++- 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 41e3313d..92e4e188 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -89,6 +89,7 @@ const CHECK_ACTIVATION_CODE_FOR_DOCTOR_APP = 'Services/DoctorApplication.svc/RES const GET_DOC_PROFILES = 'Services/Doctors.svc/REST/GetDocProfiles'; const TRANSFERT_TO_ADMIN = 'LiveCareApi/DoctorApp/TransferToAdmin'; +const SEND_SMS_INSTRUCTIONS = 'LiveCareApi/DoctorApp/SendSMSInstruction'; const GET_ALTERNATIVE_SERVICE = 'LiveCareApi/DoctorApp/GetAlternativeServices'; const END_CALL = 'LiveCareApi/DoctorApp/EndCall'; const END_CALL_WITH_CHARGE = 'LiveCareApi/DoctorApp/CompleteCallWithCharge'; diff --git a/lib/core/service/patient/LiveCarePatientServices.dart b/lib/core/service/patient/LiveCarePatientServices.dart index b8712a9b..7e42380d 100644 --- a/lib/core/service/patient/LiveCarePatientServices.dart +++ b/lib/core/service/patient/LiveCarePatientServices.dart @@ -103,6 +103,19 @@ class LiveCarePatientServices extends BaseService { }, isLiveCare: _isLive); } + Future sendSMSInstruction(int vcID) async { + hasError = false; + 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, + }, isLiveCare: _isLive); + } + Future getAlternativeServices(int vcID) async { hasError = false; alternativeServicesList.clear(); diff --git a/lib/core/viewModel/LiveCarePatientViewModel.dart b/lib/core/viewModel/LiveCarePatientViewModel.dart index 032c7a07..d2786388 100644 --- a/lib/core/viewModel/LiveCarePatientViewModel.dart +++ b/lib/core/viewModel/LiveCarePatientViewModel.dart @@ -153,6 +153,18 @@ class LiveCarePatientViewModel extends BaseViewModel { } } + Future sendSMSInstruction(int vcID) async { + setState(ViewState.BusyLocal); + await _liveCarePatientServices.sendSMSInstruction(vcID); + if (_liveCarePatientServices.hasError) { + error = _liveCarePatientServices.error; + setState(ViewState.ErrorLocal); + } else { + await getPendingPatientERForDoctorApp(); + setState(ViewState.Idle); + } + } + searchData(String str) { var strExist = str.length > 0 ? true : false; if (strExist) { diff --git a/lib/screens/live_care/end_call_screen.dart b/lib/screens/live_care/end_call_screen.dart index ee1a036d..c4e52b34 100644 --- a/lib/screens/live_care/end_call_screen.dart +++ b/lib/screens/live_care/end_call_screen.dart @@ -136,7 +136,24 @@ class _EndCallScreenState extends State { TranslationBase.of(context).instruction, "", 'patient/health_summary.png', - onTap: () {}, + onTap: () { + Helpers.showConfirmationDialog(context, + "${TranslationBase.of(context).areYouSureYouWantTo} ${TranslationBase.of(context).sendLC}${TranslationBase.of(context).instruction} ?", + () async { + Navigator.of(context).pop(); + GifLoaderDialogUtils.showMyDialog(context); + liveCareModel.sendSMSInstruction(widget.patient.vcId); + GifLoaderDialogUtils.hideDialog(context); + if (liveCareModel.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(liveCareModel.error); + } else { + DrAppToastMsg.showSuccesToast("You successfully sent SMS instructions"); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + } + }); + }, isInPatient: isInpatient, isDartIcon: true, isDisable: true, From d57b331df2372688ad38fef1579389eb4c70c3be Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 7 Jun 2021 14:46:39 +0300 Subject: [PATCH 02/72] add timer --- ios/Podfile.lock | 327 -------------------------- lib/config/localized_values.dart | 2 +- lib/util/date-utils.dart | 7 +- lib/widgets/patients/PatientCard.dart | 71 +++++- pubspec.lock | 6 +- 5 files changed, 73 insertions(+), 340 deletions(-) delete mode 100644 ios/Podfile.lock diff --git a/ios/Podfile.lock b/ios/Podfile.lock deleted file mode 100644 index 44151727..00000000 --- a/ios/Podfile.lock +++ /dev/null @@ -1,327 +0,0 @@ -PODS: - - Alamofire (5.4.3) - - barcode_scan_fix (0.0.1): - - Flutter - - MTBBarcodeScanner - - connectivity (0.0.1): - - Flutter - - Reachability - - connectivity_for_web (0.1.0): - - Flutter - - connectivity_macos (0.0.1): - - Flutter - - device_info (0.0.1): - - Flutter - - Firebase/CoreOnly (6.33.0): - - FirebaseCore (= 6.10.3) - - Firebase/Messaging (6.33.0): - - Firebase/CoreOnly - - FirebaseMessaging (~> 4.7.0) - - firebase_core (0.5.3): - - Firebase/CoreOnly (~> 6.33.0) - - Flutter - - firebase_core_web (0.1.0): - - Flutter - - firebase_messaging (7.0.3): - - Firebase/CoreOnly (~> 6.33.0) - - Firebase/Messaging (~> 6.33.0) - - firebase_core - - Flutter - - FirebaseCore (6.10.3): - - FirebaseCoreDiagnostics (~> 1.6) - - GoogleUtilities/Environment (~> 6.7) - - GoogleUtilities/Logger (~> 6.7) - - FirebaseCoreDiagnostics (1.7.0): - - GoogleDataTransport (~> 7.4) - - GoogleUtilities/Environment (~> 6.7) - - GoogleUtilities/Logger (~> 6.7) - - nanopb (~> 1.30906.0) - - FirebaseInstallations (1.7.0): - - FirebaseCore (~> 6.10) - - GoogleUtilities/Environment (~> 6.7) - - GoogleUtilities/UserDefaults (~> 6.7) - - PromisesObjC (~> 1.2) - - FirebaseInstanceID (4.8.0): - - FirebaseCore (~> 6.10) - - FirebaseInstallations (~> 1.6) - - GoogleUtilities/Environment (~> 6.7) - - GoogleUtilities/UserDefaults (~> 6.7) - - FirebaseMessaging (4.7.1): - - FirebaseCore (~> 6.10) - - FirebaseInstanceID (~> 4.7) - - GoogleUtilities/AppDelegateSwizzler (~> 6.7) - - GoogleUtilities/Environment (~> 6.7) - - GoogleUtilities/Reachability (~> 6.7) - - GoogleUtilities/UserDefaults (~> 6.7) - - Protobuf (>= 3.9.2, ~> 3.9) - - Flutter (1.0.0) - - flutter_flexible_toast (0.0.1): - - Flutter - - flutter_inappwebview (0.0.1): - - Flutter - - flutter_plugin_android_lifecycle (0.0.1): - - Flutter - - GoogleDataTransport (7.5.1): - - nanopb (~> 1.30906.0) - - GoogleUtilities/AppDelegateSwizzler (6.7.2): - - GoogleUtilities/Environment - - GoogleUtilities/Logger - - GoogleUtilities/Network - - GoogleUtilities/Environment (6.7.2): - - PromisesObjC (~> 1.2) - - GoogleUtilities/Logger (6.7.2): - - GoogleUtilities/Environment - - GoogleUtilities/Network (6.7.2): - - GoogleUtilities/Logger - - "GoogleUtilities/NSData+zlib" - - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (6.7.2)" - - GoogleUtilities/Reachability (6.7.2): - - GoogleUtilities/Logger - - GoogleUtilities/UserDefaults (6.7.2): - - GoogleUtilities/Logger - - hexcolor (0.0.1): - - Flutter - - imei_plugin (0.0.1): - - Flutter - - local_auth (0.0.1): - - Flutter - - maps_launcher (0.0.1): - - Flutter - - MTBBarcodeScanner (5.0.11) - - nanopb (1.30906.0): - - nanopb/decode (= 1.30906.0) - - nanopb/encode (= 1.30906.0) - - nanopb/decode (1.30906.0) - - nanopb/encode (1.30906.0) - - OpenTok (2.15.3) - - path_provider_linux (0.0.1): - - Flutter - - path_provider_windows (0.0.1): - - Flutter - - "permission_handler (5.1.0+2)": - - Flutter - - PromisesObjC (1.2.12) - - Protobuf (3.17.0) - - Reachability (3.2) - - screen (0.0.1): - - Flutter - - shared_preferences (0.0.1): - - Flutter - - shared_preferences_linux (0.0.1): - - Flutter - - shared_preferences_macos (0.0.1): - - Flutter - - shared_preferences_web (0.0.1): - - Flutter - - shared_preferences_windows (0.0.1): - - Flutter - - speech_to_text (0.0.1): - - Flutter - - Try - - Try (2.1.1) - - url_launcher (0.0.1): - - Flutter - - url_launcher_linux (0.0.1): - - Flutter - - url_launcher_macos (0.0.1): - - Flutter - - url_launcher_web (0.0.1): - - Flutter - - url_launcher_windows (0.0.1): - - Flutter - - video_player (0.0.1): - - Flutter - - video_player_web (0.0.1): - - Flutter - - wakelock (0.0.1): - - Flutter - - webview_flutter (0.0.1): - - Flutter - -DEPENDENCIES: - - Alamofire (~> 5.2) - - barcode_scan_fix (from `.symlinks/plugins/barcode_scan_fix/ios`) - - connectivity (from `.symlinks/plugins/connectivity/ios`) - - connectivity_for_web (from `.symlinks/plugins/connectivity_for_web/ios`) - - connectivity_macos (from `.symlinks/plugins/connectivity_macos/ios`) - - device_info (from `.symlinks/plugins/device_info/ios`) - - firebase_core (from `.symlinks/plugins/firebase_core/ios`) - - firebase_core_web (from `.symlinks/plugins/firebase_core_web/ios`) - - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) - - Flutter (from `Flutter`) - - flutter_flexible_toast (from `.symlinks/plugins/flutter_flexible_toast/ios`) - - flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`) - - flutter_plugin_android_lifecycle (from `.symlinks/plugins/flutter_plugin_android_lifecycle/ios`) - - hexcolor (from `.symlinks/plugins/hexcolor/ios`) - - imei_plugin (from `.symlinks/plugins/imei_plugin/ios`) - - local_auth (from `.symlinks/plugins/local_auth/ios`) - - maps_launcher (from `.symlinks/plugins/maps_launcher/ios`) - - OpenTok - - path_provider_linux (from `.symlinks/plugins/path_provider_linux/ios`) - - path_provider_windows (from `.symlinks/plugins/path_provider_windows/ios`) - - permission_handler (from `.symlinks/plugins/permission_handler/ios`) - - screen (from `.symlinks/plugins/screen/ios`) - - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) - - shared_preferences_linux (from `.symlinks/plugins/shared_preferences_linux/ios`) - - shared_preferences_macos (from `.symlinks/plugins/shared_preferences_macos/ios`) - - shared_preferences_web (from `.symlinks/plugins/shared_preferences_web/ios`) - - shared_preferences_windows (from `.symlinks/plugins/shared_preferences_windows/ios`) - - speech_to_text (from `.symlinks/plugins/speech_to_text/ios`) - - url_launcher (from `.symlinks/plugins/url_launcher/ios`) - - url_launcher_linux (from `.symlinks/plugins/url_launcher_linux/ios`) - - url_launcher_macos (from `.symlinks/plugins/url_launcher_macos/ios`) - - url_launcher_web (from `.symlinks/plugins/url_launcher_web/ios`) - - url_launcher_windows (from `.symlinks/plugins/url_launcher_windows/ios`) - - video_player (from `.symlinks/plugins/video_player/ios`) - - video_player_web (from `.symlinks/plugins/video_player_web/ios`) - - wakelock (from `.symlinks/plugins/wakelock/ios`) - - webview_flutter (from `.symlinks/plugins/webview_flutter/ios`) - -SPEC REPOS: - trunk: - - Alamofire - - Firebase - - FirebaseCore - - FirebaseCoreDiagnostics - - FirebaseInstallations - - FirebaseInstanceID - - FirebaseMessaging - - GoogleDataTransport - - GoogleUtilities - - MTBBarcodeScanner - - nanopb - - OpenTok - - PromisesObjC - - Protobuf - - Reachability - - Try - -EXTERNAL SOURCES: - barcode_scan_fix: - :path: ".symlinks/plugins/barcode_scan_fix/ios" - connectivity: - :path: ".symlinks/plugins/connectivity/ios" - connectivity_for_web: - :path: ".symlinks/plugins/connectivity_for_web/ios" - connectivity_macos: - :path: ".symlinks/plugins/connectivity_macos/ios" - device_info: - :path: ".symlinks/plugins/device_info/ios" - firebase_core: - :path: ".symlinks/plugins/firebase_core/ios" - firebase_core_web: - :path: ".symlinks/plugins/firebase_core_web/ios" - firebase_messaging: - :path: ".symlinks/plugins/firebase_messaging/ios" - Flutter: - :path: Flutter - flutter_flexible_toast: - :path: ".symlinks/plugins/flutter_flexible_toast/ios" - flutter_inappwebview: - :path: ".symlinks/plugins/flutter_inappwebview/ios" - flutter_plugin_android_lifecycle: - :path: ".symlinks/plugins/flutter_plugin_android_lifecycle/ios" - hexcolor: - :path: ".symlinks/plugins/hexcolor/ios" - imei_plugin: - :path: ".symlinks/plugins/imei_plugin/ios" - local_auth: - :path: ".symlinks/plugins/local_auth/ios" - maps_launcher: - :path: ".symlinks/plugins/maps_launcher/ios" - path_provider_linux: - :path: ".symlinks/plugins/path_provider_linux/ios" - path_provider_windows: - :path: ".symlinks/plugins/path_provider_windows/ios" - permission_handler: - :path: ".symlinks/plugins/permission_handler/ios" - screen: - :path: ".symlinks/plugins/screen/ios" - shared_preferences: - :path: ".symlinks/plugins/shared_preferences/ios" - shared_preferences_linux: - :path: ".symlinks/plugins/shared_preferences_linux/ios" - shared_preferences_macos: - :path: ".symlinks/plugins/shared_preferences_macos/ios" - shared_preferences_web: - :path: ".symlinks/plugins/shared_preferences_web/ios" - shared_preferences_windows: - :path: ".symlinks/plugins/shared_preferences_windows/ios" - speech_to_text: - :path: ".symlinks/plugins/speech_to_text/ios" - url_launcher: - :path: ".symlinks/plugins/url_launcher/ios" - url_launcher_linux: - :path: ".symlinks/plugins/url_launcher_linux/ios" - url_launcher_macos: - :path: ".symlinks/plugins/url_launcher_macos/ios" - url_launcher_web: - :path: ".symlinks/plugins/url_launcher_web/ios" - url_launcher_windows: - :path: ".symlinks/plugins/url_launcher_windows/ios" - video_player: - :path: ".symlinks/plugins/video_player/ios" - video_player_web: - :path: ".symlinks/plugins/video_player_web/ios" - wakelock: - :path: ".symlinks/plugins/wakelock/ios" - webview_flutter: - :path: ".symlinks/plugins/webview_flutter/ios" - -SPEC CHECKSUMS: - Alamofire: e447a2774a40c996748296fa2c55112fdbbc42f9 - barcode_scan_fix: 80dd65de55f27eec6591dd077c8b85f2b79e31f1 - connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467 - connectivity_for_web: 2b8584556930d4bd490d82b836bcf45067ce345b - connectivity_macos: e2e9731b6b22dda39eb1b128f6969d574460e191 - device_info: d7d233b645a32c40dfdc212de5cf646ca482f175 - Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5 - firebase_core: 5d6a02f3d85acd5f8321c2d6d62877626a670659 - firebase_core_web: d501d8b946b60c8af265428ce483b0fff5ad52d1 - firebase_messaging: 0aea2cd5885b65e19ede58ee3507f485c992cc75 - FirebaseCore: d889d9e12535b7f36ac8bfbf1713a0836a3012cd - FirebaseCoreDiagnostics: 770ac5958e1372ce67959ae4b4f31d8e127c3ac1 - FirebaseInstallations: 466c7b4d1f58fe16707693091da253726a731ed2 - FirebaseInstanceID: bd3ffc24367f901a43c063b36c640b345a4a5dd1 - FirebaseMessaging: 5eca4ef173de76253352511aafef774caa1cba2a - Flutter: 0e3d915762c693b495b44d77113d4970485de6ec - flutter_flexible_toast: 0547e740cae0c33bb7c51bcd931233f4584e1143 - flutter_inappwebview: 69dfbac46157b336ffbec19ca6dfd4638c7bf189 - flutter_plugin_android_lifecycle: dc0b544e129eebb77a6bfb1239d4d1c673a60a35 - GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833 - GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3 - hexcolor: fdfb9c4258ad96e949c2dbcdf790a62194b8aa89 - imei_plugin: cb1af7c223ac2d82dcd1457a7137d93d65d2a3cd - local_auth: 25938960984c3a7f6e3253e3f8d962fdd16852bd - maps_launcher: eae38ee13a9c3f210fa04e04bb4c073fa4c6ed92 - MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb - nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc - OpenTok: fde03ecc5ea31fe0a453242847c4ee1f47e1d735 - path_provider_linux: 4d630dc393e1f20364f3e3b4a2ff41d9674a84e4 - path_provider_windows: a2b81600c677ac1959367280991971cb9a1edb3b - permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0 - PromisesObjC: 3113f7f76903778cf4a0586bd1ab89329a0b7b97 - Protobuf: 7327d4444215b5f18e560a97f879ff5503c4581c - Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 - screen: abd91ca7bf3426e1cc3646d27e9b2358d6bf07b0 - shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d - shared_preferences_linux: afefbfe8d921e207f01ede8b60373d9e3b566b78 - shared_preferences_macos: f3f29b71ccbb56bf40c9dd6396c9acf15e214087 - shared_preferences_web: 141cce0c3ed1a1c5bf2a0e44f52d31eeb66e5ea9 - shared_preferences_windows: 36b76d6f54e76ead957e60b49e2f124b4cd3e6ae - speech_to_text: b43a7d99aef037bd758ed8e45d79bbac035d2dfe - Try: 5ef669ae832617b3cee58cb2c6f99fb767a4ff96 - url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef - url_launcher_linux: ac237cb7a8058736e4aae38bdbcc748a4b394cc0 - url_launcher_macos: fd7894421cd39320dce5f292fc99ea9270b2a313 - url_launcher_web: e5527357f037c87560776e36436bf2b0288b965c - url_launcher_windows: 683d7c283894db8d1914d3ab2223b20cc1ad95d5 - video_player: 9cc823b1d9da7e8427ee591e8438bfbcde500e6e - video_player_web: da8cadb8274ed4f8dbee8d7171b420dedd437ce7 - wakelock: 0d4a70faf8950410735e3f61fb15d517c8a6efc4 - webview_flutter: d2b4d6c66968ad042ad94cbb791f5b72b4678a96 - -PODFILE CHECKSUM: d0a3789a37635365b4345e456835ed9d30398217 - -COCOAPODS: 1.10.1 diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index d1e67692..11f31ba6 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -712,7 +712,7 @@ const Map> localizedValues = { 'days': {'en': "Days", 'ar': "أيام"}, 'months': {'en': "Months", 'ar': "أشهر"}, 'years': {'en': "Years", 'ar': "سنين"}, - 'hr': {'en': "HR", 'ar': "س"}, + 'hr': {'en': "Hr", 'ar': "س"}, 'min': {'en': "Min", 'ar': "د"}, 'appointmentNumber': {'en': "Appointment Number", 'ar': "رقم الموعد"}, 'referralStatusHold': {'en': "Hold", 'ar': "معلق"}, diff --git a/lib/util/date-utils.dart b/lib/util/date-utils.dart index 9ce078ed..297f358e 100644 --- a/lib/util/date-utils.dart +++ b/lib/util/date-utils.dart @@ -68,20 +68,21 @@ class AppDateUtils { return "$days ${TranslationBase.of(context).days}, $months ${TranslationBase.of(context).months}, $years ${TranslationBase.of(context).years}"; } - static String differenceBetweenDateAndCurrent(DateTime firstDate, BuildContext context) { + static String differenceBetweenDateAndCurrent(DateTime firstDate, BuildContext context, {bool isShowSecond = false, bool isShowDays = true }) { DateTime now = DateTime.now(); - // DateTime now = nows.add(Duration(days: 400, minutes: 25, hours: 0)); var difference = now.difference(firstDate); int minutesInDays = difference.inMinutes; + int secondInDays = difference.inSeconds; int hoursInDays = minutesInDays ~/ 60; // ~/ : truncating division to make the result int + int second = secondInDays % 60; int minutes = minutesInDays % 60; int days = hoursInDays ~/ 24; int hours = hoursInDays % 24; double hoursInOneDay = difference.inHours / difference.inDays; - return "$days ${TranslationBase.of(context).days}, $hours ${TranslationBase.of(context).hr}, $minutes ${TranslationBase.of(context).min}"; + return (isShowDays?"$days ${TranslationBase.of(context).days},":"")+ "$hours ${TranslationBase.of(context).hr}, $minutes ${TranslationBase.of(context).min}"+ (isShowSecond?", $second Sec":""); } static String differenceBetweenServerDateAndCurrent(String str, BuildContext context) { diff --git a/lib/widgets/patients/PatientCard.dart b/lib/widgets/patients/PatientCard.dart index 2174e6d5..098cf1e2 100644 --- a/lib/widgets/patients/PatientCard.dart +++ b/lib/widgets/patients/PatientCard.dart @@ -19,7 +19,7 @@ class PatientCard extends StatelessWidget { final bool isFromSearch; final bool isFromLiveCare; - const PatientCard( + PatientCard( {Key key, this.patientInfo, this.onTap, @@ -33,6 +33,7 @@ class PatientCard extends StatelessWidget { @override Widget build(BuildContext context) { + return Container( width: SizeConfig.screenWidth * 0.9, margin: EdgeInsets.all(6), @@ -257,9 +258,9 @@ class PatientCard extends StatelessWidget { patientInfo.fullName) : (Helpers.capitalize( patientInfo.firstName) + - " " + - Helpers.capitalize( - patientInfo.lastName)), + " " + + Helpers.capitalize( + patientInfo.lastName)), fontSize: 16, color: Color(0xff2e303a), fontWeight: FontWeight.w700, @@ -267,6 +268,8 @@ class PatientCard extends StatelessWidget { textOverflow: TextOverflow.ellipsis, ), ), + if(isFromLiveCare) + ShowTimer(patientInfo: patientInfo,), if (patientInfo.gender == 1) Icon( DoctorApp.male_2, @@ -515,12 +518,68 @@ class PatientCard extends StatelessWidget { height: 25, width: 35, )), - ]) - : SizedBox() + ]) + : SizedBox() ], ), onTap: onTap, )), )); } + + +} + +class ShowTimer extends StatefulWidget { + final PatiantInformtion patientInfo; + + + const ShowTimer({ + Key key, this.patientInfo, + }) : super(key: key); + + @override + _ShowTimerState createState() => _ShowTimerState(); +} + +class _ShowTimerState extends State { + + int remainingTime = 600; + String displayTime = ''; + + @override + Widget build(BuildContext context) { + if (displayTime.isEmpty) { + startShowTimer(); + } + return AppText( + "$displayTime", + color: Colors.red, + textAlign: TextAlign.start, + fontWeight: FontWeight.bold, + fontSize: 11, + ); + } + + startShowTimer() { + // this.remainingTime--; + setState(() { + displayTime = this.generateShowTimerString(); + }); + + Future.delayed(Duration(seconds: 1), () { + if (this.remainingTime > 0) { + startShowTimer(); + } + }); + } + + generateShowTimerString() { + DateTime now = DateTime.now(); + DateTime liveCareDate = DateTime.parse(widget.patientInfo.arrivalTime); + String timer = AppDateUtils.differenceBetweenDateAndCurrent( + liveCareDate, context, isShowSecond: true, isShowDays: false); + + return timer; + } } diff --git a/pubspec.lock b/pubspec.lock index 25596d43..77df9848 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -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.10.0 <=2.11.0-213.1.beta" + dart: ">=2.10.0 <2.11.0" flutter: ">=1.22.0 <2.0.0" From f80215b6bb4e8d70741c2bd2a1f67c6ec779e281 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 7 Jun 2021 16:48:58 +0300 Subject: [PATCH 03/72] fix doctor id spelling in live care service, fix colors in --- lib/core/service/patient/LiveCarePatientServices.dart | 3 ++- lib/screens/live_care/end_call_screen.dart | 9 +++++++-- .../profile_screen/PatientProfileCardModel.dart | 5 ++++- .../patients/profile/PatientProfileButton.dart | 11 ++++++----- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/lib/core/service/patient/LiveCarePatientServices.dart b/lib/core/service/patient/LiveCarePatientServices.dart index ed09bbb9..92d2e930 100644 --- a/lib/core/service/patient/LiveCarePatientServices.dart +++ b/lib/core/service/patient/LiveCarePatientServices.dart @@ -1,4 +1,3 @@ -import 'dart:collection'; import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/model/live_care/AlternativeServicesList.dart'; @@ -104,6 +103,8 @@ class LiveCarePatientServices extends BaseService { Future isLogin({LiveCareUserLoginRequestModel isLoginRequestModel, int loginStatus}) async { hasError = false; + await getDoctorProfile( ); + isLoginRequestModel.doctorId = super.doctorProfile.doctorID; await baseAppClient.post(LIVE_CARE_IS_LOGIN, onSuccess: (response, statusCode) async { isLoginResponse = response; }, onFailure: (String error, int statusCode) { diff --git a/lib/screens/live_care/end_call_screen.dart b/lib/screens/live_care/end_call_screen.dart index ee1a036d..0f6db11c 100644 --- a/lib/screens/live_care/end_call_screen.dart +++ b/lib/screens/live_care/end_call_screen.dart @@ -48,7 +48,9 @@ class _EndCallScreenState extends State { final List cardsList = [ PatientProfileCardModel(TranslationBase.of(context).resume, TranslationBase.of(context).theCall, '', 'patient/vital_signs.png', - isInPatient: isInpatient, onTap: () async { + isInPatient: isInpatient, + color: Colors.green[800], + onTap: () async { GifLoaderDialogUtils.showMyDialog(context); await liveCareModel .startCall(isReCall: false, vCID: widget.patient.vcId) @@ -105,7 +107,9 @@ class _EndCallScreenState extends State { TranslationBase.of(context).consultation, '', 'patient/vital_signs.png', - isInPatient: isInpatient, onTap: () { + isInPatient: isInpatient, + color: Colors.red[800], + onTap: () { Helpers.showConfirmationDialog(context, "${TranslationBase.of(context).areYouSureYouWantTo} ${TranslationBase.of(context).endLC} ${TranslationBase.of(context).consultation} ?", () async { @@ -230,6 +234,7 @@ class _EndCallScreenState extends State { isLoading: cardsList[index].isLoading, isDartIcon: cardsList[index].isDartIcon, dartIcon: cardsList[index].dartIcon, + color: cardsList[index].color, ), ), ], diff --git a/lib/screens/patients/profile/profile_screen/PatientProfileCardModel.dart b/lib/screens/patients/profile/profile_screen/PatientProfileCardModel.dart index eb9a3eaa..e4351d91 100644 --- a/lib/screens/patients/profile/profile_screen/PatientProfileCardModel.dart +++ b/lib/screens/patients/profile/profile_screen/PatientProfileCardModel.dart @@ -13,6 +13,7 @@ class PatientProfileCardModel { final bool isSelectInpatient; final bool isDartIcon; final IconData dartIcon; + final Color color; PatientProfileCardModel( this.nameLine1, @@ -25,6 +26,8 @@ class PatientProfileCardModel { this.onTap, this.isDischargedPatient = false, this.isSelectInpatient = false, - this.isDartIcon = false,this.dartIcon + this.isDartIcon = false, + this.dartIcon, + this.color, }); } diff --git a/lib/widgets/patients/profile/PatientProfileButton.dart b/lib/widgets/patients/profile/PatientProfileButton.dart index ef285150..36755502 100644 --- a/lib/widgets/patients/profile/PatientProfileButton.dart +++ b/lib/widgets/patients/profile/PatientProfileButton.dart @@ -28,6 +28,7 @@ class PatientProfileButton extends StatelessWidget { final bool isDartIcon; final IconData dartIcon; final bool isFromLiveCare; + final Color color; PatientProfileButton({ Key key, @@ -47,7 +48,7 @@ class PatientProfileButton extends StatelessWidget { this.isDischargedPatient = false, this.isSelectInpatient = false, this.isDartIcon = false, - this.dartIcon, this.isFromLiveCare = false, + this.dartIcon, this.isFromLiveCare = false, this.color, }) : super(key: key); @override @@ -73,7 +74,7 @@ class PatientProfileButton extends StatelessWidget { children: [ Container( child: isDartIcon ? Icon( - dartIcon, size: 30, color: Color(0xFF333C45),) : new Image + dartIcon, size: 30, color: color?? Color(0xFF333C45),) : new Image .asset( url + icon, width: 30, @@ -93,14 +94,14 @@ class PatientProfileButton extends StatelessWidget { children: [ AppText( !projectsProvider.isArabic ? this.nameLine1 : nameLine2, - color: Color(0xFF2B353E), + color: color??Color(0xFF2B353E), fontWeight: FontWeight.w600, textAlign: TextAlign.left, fontSize: SizeConfig.textMultiplier * 1.5, ), AppText( !projectsProvider.isArabic ? this.nameLine2 : nameLine1, - color: Color(0xFF2B353E), + color: color??Color(0xFF2B353E), fontWeight: FontWeight.w600, textAlign: TextAlign.left, fontSize: SizeConfig.textMultiplier * 1.5, @@ -116,7 +117,7 @@ class PatientProfileButton extends StatelessWidget { color: isDisable ? Colors.grey.withOpacity(0.4) : Colors.white, borderRadius: BorderRadius.all(Radius.circular(10)), border: Border.fromBorderSide(BorderSide( - color: Color(0xffBBBBBB), + color: color??Color(0xffBBBBBB), width: 1, )), ), From ec9f628b67d7749e6c40e505737b65674a3c7fe0 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Mon, 7 Jun 2021 17:00:46 +0300 Subject: [PATCH 04/72] Merge branch 'development' into procedure_refactoring # Conflicts: # lib/core/service/patient/LiveCarePatientServices.dart --- lib/config/config.dart | 8 +- lib/core/enum/PatientType.dart | 4 + .../patient/MyReferralPatientService.dart | 36 +++ .../patient-doctor-referral-service.dart | 31 +++ .../patient/referred_patient_service.dart | 36 --- .../viewModel/patient-referral-viewmodel.dart | 31 ++- lib/core/viewModel/referred_view_model.dart | 24 -- lib/locator.dart | 4 - .../my-referral-inpatient-screen.dart | 4 +- .../referral/referred-patient-screen.dart | 257 +++++++++++------- .../patient-referral-item-widget.dart | 2 +- 11 files changed, 273 insertions(+), 164 deletions(-) create mode 100644 lib/core/enum/PatientType.dart delete mode 100644 lib/core/service/patient/referred_patient_service.dart delete mode 100644 lib/core/viewModel/referred_view_model.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index bd701836..91f8bc9d 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"; @@ -56,6 +56,8 @@ const ADD_REFERRED_DOCTOR_REMARKS = 'Services/DoctorApplication.svc/REST/AddRefe const GET_MY_REFERRED_PATIENT = 'Services/DoctorApplication.svc/REST/GtMyReferredPatient'; +const GET_MY_REFERRED_OUT_PATIENT = 'Services/DoctorApplication.svc/REST/GtMyReferralForOutPatient'; + const GET_PENDING_REFERRAL_PATIENT = 'Services/DoctorApplication.svc/REST/PendingReferrals'; const CREATE_REFERRAL_PATIENT = 'Services/DoctorApplication.svc/REST/CreateReferral'; @@ -179,6 +181,8 @@ const GET_ECG = "Services/Patients.svc/REST/HIS_GetPatientMuseResults"; const GET_MY_REFERRAL_INPATIENT = "Services/DoctorApplication.svc/REST/GtMyReferralPatient"; +const GET_MY_REFERRAL_OUTPATIENT = "Services/DoctorApplication.svc/REST/GtMyReferredOutPatient"; + const GET_MY_DISCHARGE_PATIENT = "Services/DoctorApplication.svc/REST/GtMyDischargeReferralPatient"; const GET_DISCHARGE_PATIENT = "Services/DoctorApplication.svc/REST/GtMyDischargePatient"; diff --git a/lib/core/enum/PatientType.dart b/lib/core/enum/PatientType.dart new file mode 100644 index 00000000..96fd9ae5 --- /dev/null +++ b/lib/core/enum/PatientType.dart @@ -0,0 +1,4 @@ +enum PatientType{ + IN_PATIENT, + OUT_PATIENT, +} \ No newline at end of file diff --git a/lib/core/service/patient/MyReferralPatientService.dart b/lib/core/service/patient/MyReferralPatientService.dart index 536e68a7..05a937ee 100644 --- a/lib/core/service/patient/MyReferralPatientService.dart +++ b/lib/core/service/patient/MyReferralPatientService.dart @@ -42,6 +42,42 @@ class MyReferralInPatientService extends BaseService { ); } + Future getMyReferralOutPatientService() async { + hasError = false; + Map body = Map(); + await getDoctorProfile(); + body['DoctorID'] = doctorProfile.doctorID; + body['FirstName'] = "0"; + body['MiddleName'] = "0"; + body['LastName'] = "0"; + body['PatientMobileNumber'] = "0"; + body['PatientIdentificationID'] = "0"; + body['PatientID'] = 0; + body['From'] = "0"; + body['To'] = "0"; + body['stamp'] = DateTime.now().toIso8601String(); + body['IsLoginForDoctorApp'] = true; + body['IPAdress'] = "11.11.11.11"; + body['PatientOutSA'] = false; + body['PatientTypeID'] = 1; + myReferralPatients.clear(); + await baseAppClient.post( + GET_MY_REFERRAL_OUTPATIENT, + onSuccess: (dynamic response, int statusCode) { + if (response['List_MyReferredOutPatient'] != null) { + response['List_MyReferredOutPatient'].forEach((v) { + myReferralPatients.add(MyReferralPatientModel.fromJson(v)); + }); + } + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: body, + ); + } + Future replay( String referredDoctorRemarks, MyReferralPatientModel referral) async { hasError = false; diff --git a/lib/core/service/patient/patient-doctor-referral-service.dart b/lib/core/service/patient/patient-doctor-referral-service.dart index c83c74c9..c9126845 100644 --- a/lib/core/service/patient/patient-doctor-referral-service.dart +++ b/lib/core/service/patient/patient-doctor-referral-service.dart @@ -157,6 +157,37 @@ class PatientReferralService extends LookupService { ); } + Future getMyReferredOutPatient() async { + hasError = false; + RequestMyReferralPatientModel _requestMyReferralPatient = + RequestMyReferralPatientModel(); + // _requestMyReferralPatient.doctorID = 1002; + DoctorProfileModel doctorProfile = await getDoctorProfile(); + + await baseAppClient.post( + GET_MY_REFERRED_OUT_PATIENT, + onSuccess: (dynamic response, int statusCode) { + listMyReferredPatientModel.clear(); + + response['List_MyOutPatientReferral'].forEach((v) { + MyReferredPatientModel item = MyReferredPatientModel.fromJson(v); + if (doctorProfile != null) { + item.isReferralDoctorSameBranch = + doctorProfile.projectID == item.projectID; + } else { + item.isReferralDoctorSameBranch = false; + } + listMyReferredPatientModel.add(item); + }); + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: _requestMyReferralPatient.toJson(), + ); + } + Future getPendingReferralList() async { hasError = false; DoctorProfileModel doctorProfile = await getDoctorProfile(); diff --git a/lib/core/service/patient/referred_patient_service.dart b/lib/core/service/patient/referred_patient_service.dart deleted file mode 100644 index 0af9b077..00000000 --- a/lib/core/service/patient/referred_patient_service.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:doctor_app_flutter/config/config.dart'; -import 'package:doctor_app_flutter/core/service/base/base_service.dart'; -import 'package:doctor_app_flutter/models/doctor/verify_referral_doctor_remarks.dart'; -import 'package:doctor_app_flutter/models/patient/my_referral/my_referred_patient_model.dart'; -import 'package:doctor_app_flutter/models/patient/request_my_referral_patient_model.dart'; - -class ReferredPatientService extends BaseService { - List _listMyReferredPatientModel = []; - - List get listMyReferredPatientModel => - _listMyReferredPatientModel; - - RequestMyReferralPatientModel _requestMyReferralPatient = - RequestMyReferralPatientModel(); - VerifyReferralDoctorRemarks _verifyreferraldoctorremarks = - VerifyReferralDoctorRemarks(); - - Future getMyReferredPatient() async { - await baseAppClient.post( - GET_MY_REFERRED_PATIENT, - onSuccess: (dynamic response, int statusCode) { - _listMyReferredPatientModel.clear(); - response['List_MyReferredPatient'].forEach((v) { - listMyReferredPatientModel.add(MyReferredPatientModel.fromJson(v)); - }); - // print(response['List_MyReferredPatient']); - }, - onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, - body: _requestMyReferralPatient.toJson(), - ); - } - -} diff --git a/lib/core/viewModel/patient-referral-viewmodel.dart b/lib/core/viewModel/patient-referral-viewmodel.dart index a414c200..6e3e310e 100644 --- a/lib/core/viewModel/patient-referral-viewmodel.dart +++ b/lib/core/viewModel/patient-referral-viewmodel.dart @@ -28,6 +28,7 @@ class PatientReferralViewModel extends BaseViewModel { DischargedPatientService _dischargedPatientService = locator(); + List get myDischargeReferralPatient => _dischargedPatientService.myDischargeReferralPatients; @@ -133,8 +134,11 @@ class PatientReferralViewModel extends BaseViewModel { return null; } - Future getMyReferredPatient() async { - setState(ViewState.Busy); + Future getMyReferredPatient({bool isFirstTime = true}) async { + if (isFirstTime) + setState(ViewState.Busy); + else + setState(ViewState.BusyLocal); await _referralPatientService.getMyReferredPatient(); if (_referralPatientService.hasError) { error = _referralPatientService.error; @@ -143,6 +147,19 @@ class PatientReferralViewModel extends BaseViewModel { setState(ViewState.Idle); } + Future getMyReferredOutPatient({bool isFirstTime = true}) async { + if (isFirstTime) + setState(ViewState.Busy); + else + setState(ViewState.BusyLocal); + await _referralPatientService.getMyReferredOutPatient(); + if (_referralPatientService.hasError) { + error = _referralPatientService.error; + setState(ViewState.Error); + } else + setState(ViewState.Idle); + } + MyReferredPatientModel getReferredPatientItem(int index) { return listMyReferredPatientModel[index]; } @@ -167,6 +184,16 @@ class PatientReferralViewModel extends BaseViewModel { setState(ViewState.Idle); } + Future getMyReferralOutPatientService() async { + setState(ViewState.Busy); + await _myReferralService.getMyReferralOutPatientService(); + if (_myReferralService.hasError) { + error = _myReferralService.error; + setState(ViewState.Error); + } else + setState(ViewState.Idle); + } + Future replay( String referredDoctorRemarks, MyReferralPatientModel referral) async { setState(ViewState.Busy); diff --git a/lib/core/viewModel/referred_view_model.dart b/lib/core/viewModel/referred_view_model.dart deleted file mode 100644 index 173aa60a..00000000 --- a/lib/core/viewModel/referred_view_model.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:doctor_app_flutter/core/enum/viewstate.dart'; -import 'package:doctor_app_flutter/core/service/patient/referred_patient_service.dart'; -import 'package:doctor_app_flutter/models/patient/my_referral/my_referred_patient_model.dart'; - -import '../../locator.dart'; -import 'base_view_model.dart'; - -class ReferredPatientViewModel extends BaseViewModel { - ReferredPatientService _referralPatientService = - locator(); - - List get listMyReferredPatientModel => - _referralPatientService.listMyReferredPatientModel; - - Future getMyReferredPatient() async { - setState(ViewState.Busy); - await _referralPatientService.getMyReferredPatient(); - if (_referralPatientService.hasError) { - error = _referralPatientService.error; - setState(ViewState.Error); - } else - setState(ViewState.Idle); - } -} diff --git a/lib/locator.dart b/lib/locator.dart index 66ec9161..5ee46b4d 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -35,7 +35,6 @@ import 'core/service/patient/patientInPatientService.dart'; import 'core/service/patient_medical_file/prescription/prescriptions_service.dart'; import 'core/service/patient_medical_file/radiology/radiology_service.dart'; import 'core/service/patient/referral_patient_service.dart'; -import 'core/service/patient/referred_patient_service.dart'; import 'core/service/home/schedule_service.dart'; import 'core/viewModel/DischargedPatientViewModel.dart'; import 'core/viewModel/InsuranceViewModel.dart'; @@ -54,7 +53,6 @@ import 'core/viewModel/patient-vital-sign-viewmodel.dart'; import 'core/viewModel/prescriptions_view_model.dart'; import 'core/viewModel/radiology_view_model.dart'; import 'core/viewModel/referral_view_model.dart'; -import 'core/viewModel/referred_view_model.dart'; import 'core/viewModel/schedule_view_model.dart'; GetIt locator = GetIt.instance; @@ -65,7 +63,6 @@ void setupLocator() { locator.registerLazySingleton(() => DoctorReplyService()); locator.registerLazySingleton(() => ScheduleService()); locator.registerLazySingleton(() => ReferralPatientService()); - locator.registerLazySingleton(() => ReferredPatientService()); locator.registerLazySingleton(() => MedicineService()); locator.registerLazySingleton(() => PatientService()); locator.registerLazySingleton(() => DashboardService()); @@ -97,7 +94,6 @@ void setupLocator() { locator.registerFactory(() => DoctorReplayViewModel()); locator.registerFactory(() => ScheduleViewModel()); locator.registerFactory(() => ReferralPatientViewModel()); - locator.registerFactory(() => ReferredPatientViewModel()); locator.registerFactory(() => MedicineViewModel()); locator.registerFactory(() => PatientViewModel()); locator.registerFactory(() => DashboardViewModel()); 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 fcbd11b7..5665a30f 100644 --- a/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart @@ -42,12 +42,10 @@ class MyReferralInPatientScreen extends StatelessWidget { : SingleChildScrollView( child: Container( margin: EdgeInsets.only(top: 70), - // color: Colors.white, - // height: MediaQuery.of(context).size.height, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // SizedBox(height: 50), + ...List.generate( model.myReferralPatients.length, (index) => InkWell( diff --git a/lib/screens/patients/profile/referral/referred-patient-screen.dart b/lib/screens/patients/profile/referral/referred-patient-screen.dart index dc2bf798..c95a28d8 100644 --- a/lib/screens/patients/profile/referral/referred-patient-screen.dart +++ b/lib/screens/patients/profile/referral/referred-patient-screen.dart @@ -1,3 +1,4 @@ +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/referred_patient_detail_in-paint.dart'; @@ -6,12 +7,15 @@ import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/patient-referral-item-widget.dart'; 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/loader/gif_loader_dialog_utils.dart'; 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 { - // previous design page is: MyReferredPatient + + PatientType patientType = PatientType.IN_PATIENT; + @override Widget build(BuildContext context) { return BaseView( @@ -20,103 +24,172 @@ class ReferredPatientScreen extends StatelessWidget { baseViewModel: model, isShowAppBar: false, appBarTitle: TranslationBase.of(context).referredPatient, - body: model.listMyReferredPatientModel == null || - model.listMyReferredPatientModel.length == 0 - ? Center( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Container( - height: 100, + body: Column( + children: [ + Container( + margin: EdgeInsets.only(top: 70), + child: PatientTypeRadioWidget( + (patientType) async { + this.patientType = patientType; + GifLoaderDialogUtils.showMyDialog(context); + if (patientType == PatientType.IN_PATIENT) { + await model.getMyReferredPatient(isFirstTime: false); + } else { + await model.getMyReferredOutPatient(isFirstTime: false); + } + GifLoaderDialogUtils.hideDialog(context); + }, + ), + ), + model.listMyReferredPatientModel == null || + model.listMyReferredPatientModel.length == 0 + ? Center( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + height: 100, + ), + Image.asset('assets/images/no-data.png'), + Padding( + padding: const EdgeInsets.all(8.0), + child: AppText( + TranslationBase.of(context).referralEmptyMsg, + color: Theme.of(context).errorColor, + ), + ) + ], ), - Image.asset('assets/images/no-data.png'), - Padding( - padding: const EdgeInsets.all(8.0), - child: AppText( - TranslationBase.of(context).referralEmptyMsg, - color: Theme.of(context).errorColor, - ), - ) - ], - ), - ) - : SingleChildScrollView( - // DoctorApplication.svc/REST/GtMyReferredPatient - child: Container( - margin: EdgeInsets.only(top: 70), - child: Column( - children: [ - // const Divider( - // color: Color(0xffCCCCCC), - // height: 1, - // thickness: 2, - // indent: 0, - // endIndent: 0, - // ), - ...List.generate( - model.listMyReferredPatientModel.length, - (index) => InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: ReferredPatientDetailScreen( - model.getReferredPatientItem(index)), + ) + : Expanded( + child: SingleChildScrollView( + // DoctorApplication.svc/REST/GtMyReferredPatient + child: Container( + child: Column( + children: [ + ...List.generate( + model.listMyReferredPatientModel.length, + (index) => InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: ReferredPatientDetailScreen( + model.getReferredPatientItem(index)), + ), + ); + }, + child: PatientReferralItemWidget( + referralStatus: model + .getReferredPatientItem(index) + .referralStatusDesc, + referralStatusCode: model + .getReferredPatientItem(index) + .referralStatus, + patientName: + "${model.getReferredPatientItem(index).firstName} ${model.getReferredPatientItem(index).middleName} ${model.getReferredPatientItem(index).lastName}", + patientGender: + model.getReferredPatientItem(index).gender, + referredDate: + AppDateUtils.convertDateFromServerFormat( + model + .getReferredPatientItem(index) + .referralDate, + "dd/MM/yyyy"), + referredTime: + AppDateUtils.convertDateFromServerFormat( + model + .getReferredPatientItem(index) + .referralDate, + "hh:mm a"), + patientID: + "${model.getReferredPatientItem(index).patientID}", + isSameBranch: model + .getReferredPatientItem(index) + .isReferralDoctorSameBranch, + isReferral: false, + remark: model + .getReferredPatientItem(index) + .referringDoctorRemarks, + nationality: model + .getReferredPatientItem(index) + .nationalityName, + nationalityFlag: model + .getReferredPatientItem(index) + .nationalityFlagURL, + doctorAvatar: model + .getReferredPatientItem(index) + .doctorImageURL, + referralDoctorName: + "${TranslationBase.of(context).dr} ${model.getReferredPatientItem(index).referralDoctorName}", + clinicDescription: model + .getReferredPatientItem(index) + .referralClinicDescription, + infoIcon: Icon(FontAwesomeIcons.arrowRight, + size: 25, color: Colors.black), + ), ), - ); - }, - child: PatientReferralItemWidget( - referralStatus:model.getReferredPatientItem(index).referralStatusDesc, - referralStatusCode: model - .getReferredPatientItem(index) - .referralStatus, - patientName: - "${model.getReferredPatientItem(index).firstName} ${model.getReferredPatientItem(index).middleName} ${model.getReferredPatientItem(index).lastName}", - patientGender: - model.getReferredPatientItem(index).gender, - referredDate: AppDateUtils.convertDateFromServerFormat( - model - .getReferredPatientItem(index) - .referralDate, - "dd/MM/yyyy"), - referredTime: AppDateUtils.convertDateFromServerFormat( - model - .getReferredPatientItem(index) - .referralDate, - "hh:mm a"), - patientID: - "${model.getReferredPatientItem(index).patientID}", - isSameBranch: model - .getReferredPatientItem(index) - .isReferralDoctorSameBranch, - isReferral: false, - remark: model - .getReferredPatientItem(index) - .referringDoctorRemarks, - nationality: model - .getReferredPatientItem(index) - .nationalityName, - nationalityFlag: model - .getReferredPatientItem(index) - .nationalityFlagURL, - doctorAvatar: model - .getReferredPatientItem(index) - .doctorImageURL, - referralDoctorName: - "${TranslationBase.of(context).dr} ${model.getReferredPatientItem(index).referralDoctorName}", - clinicDescription: model - .getReferredPatientItem(index) - .referralClinicDescription, - infoIcon: Icon(FontAwesomeIcons.arrowRight, - size: 25, color: Colors.black), - ), + ), + ], ), ), - ], - ), + ), ), - ), + ], + ), ), ); } } + +class PatientTypeRadioWidget extends StatefulWidget { + final Function(PatientType) radioOnChange; + + PatientTypeRadioWidget(this.radioOnChange); + + @override + _PatientTypeRadioWidgetState createState() => + _PatientTypeRadioWidgetState(this.radioOnChange); +} + +class _PatientTypeRadioWidgetState extends State { + final Function(PatientType) radioOnChange; + + _PatientTypeRadioWidgetState(this.radioOnChange); + + PatientType patientType = PatientType.IN_PATIENT; + + @override + Widget build(BuildContext context) { + return Row( + children: [ + Expanded( + child: RadioListTile( + title: AppText(TranslationBase.of(context).inPatient), + value: PatientType.IN_PATIENT, + groupValue: patientType, + onChanged: (PatientType value) { + setState(() { + patientType = value; + radioOnChange(value); + }); + }, + ), + ), + Expanded( + child: RadioListTile( + title: AppText(TranslationBase.of(context).outpatient), + value: PatientType.OUT_PATIENT, + groupValue: patientType, + onChanged: (PatientType value) { + setState(() { + patientType = value; + radioOnChange(value); + }); + }, + ), + ), + ], + ); + } +} diff --git a/lib/widgets/patients/patient-referral-item-widget.dart b/lib/widgets/patients/patient-referral-item-widget.dart index a08282c0..6e581954 100644 --- a/lib/widgets/patients/patient-referral-item-widget.dart +++ b/lib/widgets/patients/patient-referral-item-widget.dart @@ -215,7 +215,7 @@ class PatientReferralItemWidget extends StatelessWidget { ), Expanded( child: AppText( - remark, + remark??"", fontFamily: 'Poppins', fontWeight: FontWeight.w700, fontSize: 1.8 * SizeConfig.textMultiplier, From a1abcaa7c08144ddd65a77b7ac3d5af643d8f5f0 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Mon, 7 Jun 2021 17:05:51 +0300 Subject: [PATCH 05/72] fix live care issues --- android/app/build.gradle | 10 ++++++++-- .../kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java | 6 +++--- android/build.gradle | 2 ++ ios/Runner/VideoViewController.swift | 2 +- lib/core/service/patient/LiveCarePatientServices.dart | 2 +- pubspec.lock | 6 +++--- 6 files changed, 18 insertions(+), 10 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index b7605ad0..16960d54 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -54,6 +54,11 @@ android { signingConfig signingConfigs.debug } } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + } flutter { @@ -74,9 +79,10 @@ dependencies { //permissions implementation 'pub.devrel:easypermissions:0.4.0' //retrofit - implementation 'com.squareup.retrofit2:retrofit:2.6.2' + implementation 'com.squareup.retrofit2:retrofit:2.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.6.2' - implementation 'com.squareup.okhttp3:logging-interceptor:3.14.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.9.1' } apply plugin: 'com.google.gms.google-services' \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java index 1c907089..80f60c33 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java @@ -134,8 +134,8 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi @SuppressLint("ClickableViewAccessibility") private void initUI() { - mPublisherViewContainer = (FrameLayout) findViewById(R.id.local_video_view_container); - mSubscriberViewContainer = (RelativeLayout) findViewById(R.id.remote_video_view_container); + mPublisherViewContainer = findViewById(R.id.local_video_view_container); + mSubscriberViewContainer = findViewById(R.id.remote_video_view_container); apiKey = getIntent().getStringExtra("apiKey"); sessionId = getIntent().getStringExtra("sessionId"); @@ -184,7 +184,7 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi videoCallPresenter.callClintConnected(sessionStatusModel); } }; - mConnectedHandler.postDelayed(mConnectedRunnable, 30 * 1000); + mConnectedHandler.postDelayed(mConnectedRunnable, 55 * 1000); } diff --git a/android/build.gradle b/android/build.gradle index ea0f0026..badc1b18 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -16,10 +16,12 @@ allprojects { repositories { google() jcenter() + mavenCentral() maven { url 'https://tokbox.bintray.com/maven' } } } + rootProject.buildDir = '../build' subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" diff --git a/ios/Runner/VideoViewController.swift b/ios/Runner/VideoViewController.swift index 44e45f3a..0fb39f7c 100644 --- a/ios/Runner/VideoViewController.swift +++ b/ios/Runner/VideoViewController.swift @@ -31,7 +31,7 @@ class ViewController: UIViewController { var callBack: ICallProtocol? var timer = Timer() - var seconds = 30 + var seconds = 55 var isUserConnect : Bool = false diff --git a/lib/core/service/patient/LiveCarePatientServices.dart b/lib/core/service/patient/LiveCarePatientServices.dart index ed09bbb9..949b3de4 100644 --- a/lib/core/service/patient/LiveCarePatientServices.dart +++ b/lib/core/service/patient/LiveCarePatientServices.dart @@ -19,7 +19,7 @@ class LiveCarePatientServices extends BaseService { bool _isFinished = false; - bool _isLive = false; + bool _isLive = true; bool get isFinished => _isFinished; diff --git a/pubspec.lock b/pubspec.lock index 25596d43..77df9848 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -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.10.0 <=2.11.0-213.1.beta" + dart: ">=2.10.0 <2.11.0" flutter: ">=1.22.0 <2.0.0" From 792c85e28ac2b812113ceaef81b49f596ee2cf54 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 7 Jun 2021 17:07:46 +0300 Subject: [PATCH 06/72] fix live care icon size --- lib/screens/home/home_patient_card.dart | 6 ++++-- lib/screens/home/home_screen.dart | 1 + lib/util/date-utils.dart | 7 ++++++- lib/widgets/patients/PatientCard.dart | 6 ++++-- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/screens/home/home_patient_card.dart b/lib/screens/home/home_patient_card.dart index bdaac7a7..6f6712ec 100644 --- a/lib/screens/home/home_patient_card.dart +++ b/lib/screens/home/home_patient_card.dart @@ -10,6 +10,7 @@ class HomePatientCard extends StatelessWidget { final String text; final Color textColor; final Function onTap; + final double iconSize; HomePatientCard({ @required this.backgroundColor, @@ -18,6 +19,7 @@ class HomePatientCard extends StatelessWidget { @required this.text, @required this.textColor, @required this.onTap, + this.iconSize = 30, }); @override @@ -41,7 +43,7 @@ class HomePatientCard extends StatelessWidget { height: 25.0, child: Icon( cardIcon, - size: 60, + size: iconSize * 2, color: backgroundIconColor, ), ), @@ -52,7 +54,7 @@ class HomePatientCard extends StatelessWidget { children: [ Icon( cardIcon, - size: 30, + size: iconSize, color: textColor, ), SizedBox( diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 85ea3506..ab0fe73f 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -329,6 +329,7 @@ class _HomeScreenState extends State { backgroundIconColor: backgroundIconColors[colorIndex], cardIcon: DoctorApp.livecare, textColor: textColors[colorIndex], + iconSize: 24, text: "${TranslationBase.of(context).liveCare}\n${TranslationBase.of(context).patients}", onTap: () { diff --git a/lib/util/date-utils.dart b/lib/util/date-utils.dart index 297f358e..a7d03076 100644 --- a/lib/util/date-utils.dart +++ b/lib/util/date-utils.dart @@ -82,7 +82,12 @@ class AppDateUtils { double hoursInOneDay = difference.inHours / difference.inDays; - return (isShowDays?"$days ${TranslationBase.of(context).days},":"")+ "$hours ${TranslationBase.of(context).hr}, $minutes ${TranslationBase.of(context).min}"+ (isShowSecond?", $second Sec":""); + return (isShowDays + ? (days > 0 ? "$days ${TranslationBase.of(context).days}," : '') + : "") + + (hours > 0 ? "$hours ${TranslationBase.of(context).hr}," : "") + + " $minutes ${TranslationBase.of(context).min}" + + (isShowSecond ? ", $second Sec" : ""); } static String differenceBetweenServerDateAndCurrent(String str, BuildContext context) { diff --git a/lib/widgets/patients/PatientCard.dart b/lib/widgets/patients/PatientCard.dart index 098cf1e2..6f218263 100644 --- a/lib/widgets/patients/PatientCard.dart +++ b/lib/widgets/patients/PatientCard.dart @@ -268,8 +268,7 @@ class PatientCard extends StatelessWidget { textOverflow: TextOverflow.ellipsis, ), ), - if(isFromLiveCare) - ShowTimer(patientInfo: patientInfo,), + if (patientInfo.gender == 1) Icon( DoctorApp.male_2, @@ -280,6 +279,9 @@ class PatientCard extends StatelessWidget { DoctorApp.female_1, color: Colors.pink, ), + + if(isFromLiveCare) + ShowTimer(patientInfo: patientInfo,), ]), ), Row( From 8a8b55d2de45efff498f06890d12335c4a156670 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 7 Jun 2021 17:12:54 +0300 Subject: [PATCH 07/72] move show timer to its own file --- .../live_care/live_care_patient_screen.dart | 2 +- lib/screens/patients/InPatientPage.dart | 3 +- .../out_patient/out_patient_screen.dart | 4 +- .../patient_search_result_screen.dart | 4 +- .../{ => patient_card}/PatientCard.dart | 58 +----------------- .../patients/patient_card/ShowTimer.dart | 59 +++++++++++++++++++ 6 files changed, 66 insertions(+), 64 deletions(-) rename lib/widgets/patients/{ => patient_card}/PatientCard.dart (96%) create mode 100644 lib/widgets/patients/patient_card/ShowTimer.dart diff --git a/lib/screens/live_care/live_care_patient_screen.dart b/lib/screens/live_care/live_care_patient_screen.dart index 51757bf0..0b741989 100644 --- a/lib/screens/live_care/live_care_patient_screen.dart +++ b/lib/screens/live_care/live_care_patient_screen.dart @@ -6,7 +6,7 @@ import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart' import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/PatientCard.dart'; +import 'package:doctor_app_flutter/widgets/patients/patient_card/PatientCard.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/app_texts_widget.dart'; diff --git a/lib/screens/patients/InPatientPage.dart b/lib/screens/patients/InPatientPage.dart index 1b42d305..e9e2c2d1 100644 --- a/lib/screens/patients/InPatientPage.dart +++ b/lib/screens/patients/InPatientPage.dart @@ -1,10 +1,9 @@ import 'package:doctor_app_flutter/core/viewModel/PatientSearchViewModel.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/PatientCard.dart'; +import 'package:doctor_app_flutter/widgets/patients/patient_card/PatientCard.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/errors/error_message.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:flutter/material.dart'; diff --git a/lib/screens/patients/out_patient/out_patient_screen.dart b/lib/screens/patients/out_patient/out_patient_screen.dart index 30400c65..0a85ff26 100644 --- a/lib/screens/patients/out_patient/out_patient_screen.dart +++ b/lib/screens/patients/out_patient/out_patient_screen.dart @@ -1,10 +1,8 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/filter_type.dart'; import 'package:doctor_app_flutter/core/enum/patient_type.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/viewModel/PatientSearchViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; @@ -14,7 +12,7 @@ import 'package:doctor_app_flutter/routes.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/patients/patient_search/patient_search_header.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/PatientCard.dart'; +import 'package:doctor_app_flutter/widgets/patients/patient_card/PatientCard.dart'; 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/errors/error_message.dart'; diff --git a/lib/screens/patients/patient_search/patient_search_result_screen.dart b/lib/screens/patients/patient_search/patient_search_result_screen.dart index 02bde8d0..8044e991 100644 --- a/lib/screens/patients/patient_search/patient_search_result_screen.dart +++ b/lib/screens/patients/patient_search/patient_search_result_screen.dart @@ -10,13 +10,11 @@ import 'package:doctor_app_flutter/routes.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/patients/patient_search/patient_search_header.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/PatientCard.dart'; +import 'package:doctor_app_flutter/widgets/patients/patient_card/PatientCard.dart'; 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/errors/error_message.dart'; -import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/app_text_form_field.dart'; -import 'package:doctor_app_flutter/widgets/shared/text_fields/text_fields_utils.dart'; import 'package:flutter/material.dart'; import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; diff --git a/lib/widgets/patients/PatientCard.dart b/lib/widgets/patients/patient_card/PatientCard.dart similarity index 96% rename from lib/widgets/patients/PatientCard.dart rename to lib/widgets/patients/patient_card/PatientCard.dart index 6f218263..b90eecd3 100644 --- a/lib/widgets/patients/PatientCard.dart +++ b/lib/widgets/patients/patient_card/PatientCard.dart @@ -9,6 +9,8 @@ import 'package:doctor_app_flutter/widgets/shared/card_with_bg_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'ShowTimer.dart'; + class PatientCard extends StatelessWidget { final PatiantInformtion patientInfo; final Function onTap; @@ -530,58 +532,4 @@ class PatientCard extends StatelessWidget { } -} - -class ShowTimer extends StatefulWidget { - final PatiantInformtion patientInfo; - - - const ShowTimer({ - Key key, this.patientInfo, - }) : super(key: key); - - @override - _ShowTimerState createState() => _ShowTimerState(); -} - -class _ShowTimerState extends State { - - int remainingTime = 600; - String displayTime = ''; - - @override - Widget build(BuildContext context) { - if (displayTime.isEmpty) { - startShowTimer(); - } - return AppText( - "$displayTime", - color: Colors.red, - textAlign: TextAlign.start, - fontWeight: FontWeight.bold, - fontSize: 11, - ); - } - - startShowTimer() { - // this.remainingTime--; - setState(() { - displayTime = this.generateShowTimerString(); - }); - - Future.delayed(Duration(seconds: 1), () { - if (this.remainingTime > 0) { - startShowTimer(); - } - }); - } - - generateShowTimerString() { - DateTime now = DateTime.now(); - DateTime liveCareDate = DateTime.parse(widget.patientInfo.arrivalTime); - String timer = AppDateUtils.differenceBetweenDateAndCurrent( - liveCareDate, context, isShowSecond: true, isShowDays: false); - - return timer; - } -} +} \ No newline at end of file diff --git a/lib/widgets/patients/patient_card/ShowTimer.dart b/lib/widgets/patients/patient_card/ShowTimer.dart new file mode 100644 index 00000000..b769588b --- /dev/null +++ b/lib/widgets/patients/patient_card/ShowTimer.dart @@ -0,0 +1,59 @@ + +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/widgets/shared/app_texts_widget.dart'; +import 'package:flutter/material.dart'; + +class ShowTimer extends StatefulWidget { + final PatiantInformtion patientInfo; + + + const ShowTimer({ + Key key, this.patientInfo, + }) : super(key: key); + + @override + _ShowTimerState createState() => _ShowTimerState(); +} + +class _ShowTimerState extends State { + + int remainingTime = 600; + String displayTime = ''; + + @override + Widget build(BuildContext context) { + if (displayTime.isEmpty) { + startShowTimer(); + } + return AppText( + "$displayTime", + color: Colors.red, + textAlign: TextAlign.start, + fontWeight: FontWeight.bold, + fontSize: 11, + ); + } + + startShowTimer() { + // this.remainingTime--; + setState(() { + displayTime = this.generateShowTimerString(); + }); + + Future.delayed(Duration(seconds: 1), () { + if (this.remainingTime > 0) { + startShowTimer(); + } + }); + } + + generateShowTimerString() { + DateTime now = DateTime.now(); + DateTime liveCareDate = DateTime.parse(widget.patientInfo.arrivalTime); + String timer = AppDateUtils.differenceBetweenDateAndCurrent( + liveCareDate, context, isShowSecond: true, isShowDays: false); + + return timer; + } +} From 72966c32695e737e95fddc51e9f1dd295b4b7456 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Tue, 8 Jun 2021 13:05:08 +0300 Subject: [PATCH 08/72] fix referral patient services --- lib/config/config.dart | 8 +- .../referral/MyReferralPatientModel.dart | 4 +- .../MyReferralPatientRequestModel.dart | 104 +++++++++++++ .../patient/MyReferralPatientService.dart | 69 ++++----- .../patient-doctor-referral-service.dart | 3 +- .../viewModel/patient-referral-viewmodel.dart | 12 +- .../my_referred_patient_model.dart | 2 +- .../my-referral-inpatient-screen.dart | 141 +++++++++++------- .../referral_patient_detail_in-paint.dart | 13 +- .../referred_patient_detail_in-paint.dart | 11 +- lib/util/date-utils.dart | 18 +++ 11 files changed, 270 insertions(+), 115 deletions(-) create mode 100644 lib/core/model/referral/MyReferralPatientRequestModel.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index 91f8bc9d..e2f9eb6a 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"; @@ -56,7 +56,7 @@ const ADD_REFERRED_DOCTOR_REMARKS = 'Services/DoctorApplication.svc/REST/AddRefe const GET_MY_REFERRED_PATIENT = 'Services/DoctorApplication.svc/REST/GtMyReferredPatient'; -const GET_MY_REFERRED_OUT_PATIENT = 'Services/DoctorApplication.svc/REST/GtMyReferralForOutPatient'; +const GET_MY_REFERRED_OUT_PATIENT = 'Services/DoctorApplication.svc/REST/GtMyReferredOutPatient'; const GET_PENDING_REFERRAL_PATIENT = 'Services/DoctorApplication.svc/REST/PendingReferrals'; @@ -181,7 +181,7 @@ const GET_ECG = "Services/Patients.svc/REST/HIS_GetPatientMuseResults"; const GET_MY_REFERRAL_INPATIENT = "Services/DoctorApplication.svc/REST/GtMyReferralPatient"; -const GET_MY_REFERRAL_OUTPATIENT = "Services/DoctorApplication.svc/REST/GtMyReferredOutPatient"; +const GET_MY_REFERRAL_OUTPATIENT = "Services/DoctorApplication.svc/REST/GtMyReferralForOutPatient"; const GET_MY_DISCHARGE_PATIENT = "Services/DoctorApplication.svc/REST/GtMyDischargeReferralPatient"; const GET_DISCHARGE_PATIENT = "Services/DoctorApplication.svc/REST/GtMyDischargePatient"; diff --git a/lib/core/model/referral/MyReferralPatientModel.dart b/lib/core/model/referral/MyReferralPatientModel.dart index 797109dd..7aa375b8 100644 --- a/lib/core/model/referral/MyReferralPatientModel.dart +++ b/lib/core/model/referral/MyReferralPatientModel.dart @@ -158,8 +158,8 @@ class MyReferralPatientModel { referringDoctor = json['ReferringDoctor']; referralClinic = json['ReferralClinic']; referringClinic = json['ReferringClinic']; - referralStatus = json['ReferralStatus']; - referralDate = AppDateUtils.convertStringToDate(json['ReferralDate']); + referralStatus = json["ReferralStatus"] is String ?json['ReferralStatus']== "Accepted"?46:json['ReferralStatus']=="Pending"?1:0: json["ReferralStatus"]; + referralDate = AppDateUtils.getDateTimeFromString(json['ReferralDate']); referringDoctorRemarks = json['ReferringDoctorRemarks']; referredDoctorRemarks = json['ReferredDoctorRemarks']; referralResponseOn = json['ReferralResponseOn']; diff --git a/lib/core/model/referral/MyReferralPatientRequestModel.dart b/lib/core/model/referral/MyReferralPatientRequestModel.dart new file mode 100644 index 00000000..08b98a99 --- /dev/null +++ b/lib/core/model/referral/MyReferralPatientRequestModel.dart @@ -0,0 +1,104 @@ +class MyReferralPatientRequestModel { + int channel; + int clinicID; + int doctorID; + int editedBy; + String firstName; + String from; + String iPAdress; + bool isLoginForDoctorApp; + int languageID; + String lastName; + String middleName; + int patientID; + String patientIdentificationID; + String patientMobileNumber; + bool patientOutSA; + int patientTypeID; + int projectID; + String sessionID; + String stamp; + String to; + String tokenID; + double versionID; + String vidaAuthTokenID; + + MyReferralPatientRequestModel( + {this.channel, + this.clinicID, + this.doctorID, + this.editedBy, + this.firstName, + this.from, + this.iPAdress, + this.isLoginForDoctorApp, + this.languageID, + this.lastName, + this.middleName, + this.patientID, + this.patientIdentificationID, + this.patientMobileNumber, + this.patientOutSA, + this.patientTypeID, + this.projectID, + this.sessionID, + this.stamp, + this.to, + this.tokenID, + this.versionID, + this.vidaAuthTokenID}); + + MyReferralPatientRequestModel.fromJson(Map json) { + channel = json['Channel']; + clinicID = json['ClinicID']; + doctorID = json['DoctorID']; + editedBy = json['EditedBy']; + firstName = json['FirstName']; + from = json['From']; + iPAdress = json['IPAdress']; + isLoginForDoctorApp = json['IsLoginForDoctorApp']; + languageID = json['LanguageID']; + lastName = json['LastName']; + middleName = json['MiddleName']; + patientID = json['PatientID']; + patientIdentificationID = json['PatientIdentificationID']; + patientMobileNumber = json['PatientMobileNumber']; + patientOutSA = json['PatientOutSA']; + patientTypeID = json['PatientTypeID']; + projectID = json['ProjectID']; + sessionID = json['SessionID']; + stamp = json['stamp']; + to = json['To']; + tokenID = json['TokenID']; + versionID = json['VersionID']; + vidaAuthTokenID = json['VidaAuthTokenID']; + } + + Map toJson() { + final Map data = new Map(); + data['Channel'] = this.channel; + data['ClinicID'] = this.clinicID; + data['DoctorID'] = this.doctorID; + data['EditedBy'] = this.editedBy; + data['FirstName'] = this.firstName; + data['From'] = this.from; + data['IPAdress'] = this.iPAdress; + data['IsLoginForDoctorApp'] = this.isLoginForDoctorApp; + data['LanguageID'] = this.languageID; + data['LastName'] = this.lastName; + data['MiddleName'] = this.middleName; + data['PatientID'] = this.patientID; + data['PatientIdentificationID'] = this.patientIdentificationID; + data['PatientMobileNumber'] = this.patientMobileNumber; + data['PatientOutSA'] = this.patientOutSA; + data['PatientTypeID'] = this.patientTypeID; + data['ProjectID'] = this.projectID; + data['SessionID'] = this.sessionID; + data['stamp'] = this.stamp; + data['To'] = this.to; + data['TokenID'] = this.tokenID; + data['VersionID'] = this.versionID; + data['VidaAuthTokenID'] = this.vidaAuthTokenID; + return data; + } +} diff --git a/lib/core/service/patient/MyReferralPatientService.dart b/lib/core/service/patient/MyReferralPatientService.dart index 05a937ee..9f29c4dc 100644 --- a/lib/core/service/patient/MyReferralPatientService.dart +++ b/lib/core/service/patient/MyReferralPatientService.dart @@ -1,5 +1,6 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/model/referral/MyReferralPatientModel.dart'; +import 'package:doctor_app_flutter/core/model/referral/MyReferralPatientRequestModel.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.dart'; import 'package:doctor_app_flutter/models/doctor/request_add_referred_doctor_remarks.dart'; @@ -8,22 +9,22 @@ class MyReferralInPatientService extends BaseService { Future getMyReferralPatientService() async { hasError = false; - Map body = Map(); await getDoctorProfile(); - body['DoctorID'] = doctorProfile.doctorID; - body['FirstName'] = "0"; - body['MiddleName'] = "0"; - body['LastName'] = "0"; - body['PatientMobileNumber'] = "0"; - body['PatientIdentificationID'] = "0"; - body['PatientID'] = 0; - body['From'] = "0"; - body['To'] = "0"; - body['stamp'] = DateTime.now().toIso8601String(); - body['IsLoginForDoctorApp'] = true; - body['IPAdress'] = "11.11.11.11"; - body['PatientOutSA'] = false; - body['PatientTypeID'] = 1; + + MyReferralPatientRequestModel myReferralPatientRequestModel = + MyReferralPatientRequestModel( + doctorID: doctorProfile.doctorID, + firstName: "0", + middleName: "0", + lastName: "0", + patientMobileNumber: "0", + patientIdentificationID: "0", + patientID: 0, + from: "0", + to: "0", + stamp: DateTime.now().toIso8601String(), + isLoginForDoctorApp: true, + patientTypeID: 1); myReferralPatients.clear(); await baseAppClient.post( GET_MY_REFERRAL_INPATIENT, @@ -38,34 +39,34 @@ class MyReferralInPatientService extends BaseService { hasError = true; super.error = error; }, - body: body, + body: myReferralPatientRequestModel.toJson(), ); } Future getMyReferralOutPatientService() async { hasError = false; - Map body = Map(); await getDoctorProfile(); - body['DoctorID'] = doctorProfile.doctorID; - body['FirstName'] = "0"; - body['MiddleName'] = "0"; - body['LastName'] = "0"; - body['PatientMobileNumber'] = "0"; - body['PatientIdentificationID'] = "0"; - body['PatientID'] = 0; - body['From'] = "0"; - body['To'] = "0"; - body['stamp'] = DateTime.now().toIso8601String(); - body['IsLoginForDoctorApp'] = true; - body['IPAdress'] = "11.11.11.11"; - body['PatientOutSA'] = false; - body['PatientTypeID'] = 1; + + MyReferralPatientRequestModel myReferralPatientRequestModel = + MyReferralPatientRequestModel( + doctorID: doctorProfile.doctorID, + firstName: "0", + middleName: "0", + lastName: "0", + patientMobileNumber: "0", + patientIdentificationID: "0", + patientID: 0, + from: "0", + to: "0", + stamp: DateTime.now().toIso8601String(), + isLoginForDoctorApp: true, + patientTypeID: 1); myReferralPatients.clear(); await baseAppClient.post( GET_MY_REFERRAL_OUTPATIENT, onSuccess: (dynamic response, int statusCode) { - if (response['List_MyReferredOutPatient'] != null) { - response['List_MyReferredOutPatient'].forEach((v) { + if (response['List_MyOutPatientReferral'] != null) { + response['List_MyOutPatientReferral'].forEach((v) { myReferralPatients.add(MyReferralPatientModel.fromJson(v)); }); } @@ -74,7 +75,7 @@ class MyReferralInPatientService extends BaseService { hasError = true; super.error = error; }, - body: body, + body: myReferralPatientRequestModel.toJson(), ); } diff --git a/lib/core/service/patient/patient-doctor-referral-service.dart b/lib/core/service/patient/patient-doctor-referral-service.dart index c9126845..81529590 100644 --- a/lib/core/service/patient/patient-doctor-referral-service.dart +++ b/lib/core/service/patient/patient-doctor-referral-service.dart @@ -161,7 +161,6 @@ class PatientReferralService extends LookupService { hasError = false; RequestMyReferralPatientModel _requestMyReferralPatient = RequestMyReferralPatientModel(); - // _requestMyReferralPatient.doctorID = 1002; DoctorProfileModel doctorProfile = await getDoctorProfile(); await baseAppClient.post( @@ -169,7 +168,7 @@ class PatientReferralService extends LookupService { onSuccess: (dynamic response, int statusCode) { listMyReferredPatientModel.clear(); - response['List_MyOutPatientReferral'].forEach((v) { + response['List_MyReferredOutPatient'].forEach((v) { MyReferredPatientModel item = MyReferredPatientModel.fromJson(v); if (doctorProfile != null) { item.isReferralDoctorSameBranch = diff --git a/lib/core/viewModel/patient-referral-viewmodel.dart b/lib/core/viewModel/patient-referral-viewmodel.dart index 6e3e310e..01d40e62 100644 --- a/lib/core/viewModel/patient-referral-viewmodel.dart +++ b/lib/core/viewModel/patient-referral-viewmodel.dart @@ -174,22 +174,22 @@ class PatientReferralViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future getMyReferralPatientService() async { - setState(ViewState.Busy); + Future getMyReferralPatientService({bool localBusy = false}) async { + if(localBusy) setState(ViewState.BusyLocal); else setState(ViewState.Busy); await _myReferralService.getMyReferralPatientService(); if (_myReferralService.hasError) { error = _myReferralService.error; - setState(ViewState.Error); + if(localBusy) setState(ViewState.ErrorLocal); else setState(ViewState.Error); } else setState(ViewState.Idle); } - Future getMyReferralOutPatientService() async { - setState(ViewState.Busy); + Future getMyReferralOutPatientService({bool localBusy = false}) async { + if(localBusy) setState(ViewState.BusyLocal); else setState(ViewState.Busy); await _myReferralService.getMyReferralOutPatientService(); if (_myReferralService.hasError) { error = _myReferralService.error; - setState(ViewState.Error); + if(localBusy) setState(ViewState.ErrorLocal); else setState(ViewState.Error); } else setState(ViewState.Idle); } diff --git a/lib/models/patient/my_referral/my_referred_patient_model.dart b/lib/models/patient/my_referral/my_referred_patient_model.dart index 44a427f7..5a755fe8 100644 --- a/lib/models/patient/my_referral/my_referred_patient_model.dart +++ b/lib/models/patient/my_referral/my_referred_patient_model.dart @@ -166,7 +166,7 @@ class MyReferredPatientModel { referringDoctor = json['ReferringDoctor']; referralClinic = json['ReferralClinic']; referringClinic = json['ReferringClinic']; - referralStatus = json['ReferralStatus']; + referralStatus = json["ReferralStatus"] is String?json['ReferralStatus']== "Accepted"?46:json['ReferralStatus']=="Pending"?1:0 : json['ReferralStatus'];// TODO Elham json['ReferralStatus']; referralDate = json['ReferralDate']; referringDoctorRemarks = json['ReferringDoctorRemarks']; referredDoctorRemarks = json['ReferredDoctorRemarks']; 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 5665a30f..9813286e 100644 --- a/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart @@ -1,16 +1,21 @@ +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/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'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/patient-referral-item-widget.dart'; 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/loader/gif_loader_dialog_utils.dart'; 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 MyReferralInPatientScreen extends StatelessWidget { + PatientType patientType = PatientType.IN_PATIENT; + @override Widget build(BuildContext context) { @@ -20,70 +25,90 @@ class MyReferralInPatientScreen extends StatelessWidget { baseViewModel: model, isShowAppBar: false, appBarTitle: TranslationBase.of(context).referPatient, - body: model.myReferralPatients.isEmpty - ? Center( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - height: 100, + body: Column( + children: [ + + Container( + margin: EdgeInsets.only(top: 70), + child: PatientTypeRadioWidget( + (patientType) async { + this.patientType = patientType; + GifLoaderDialogUtils.showMyDialog(context); + if (patientType == PatientType.IN_PATIENT) { + await model.getMyReferralPatientService(localBusy: true); + } else { + await model.getMyReferralOutPatientService(localBusy: true); + } + GifLoaderDialogUtils.hideDialog(context); + }, + ), + ), + model.myReferralPatients.isEmpty + ? Center( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox( + height: 100, + ), + Image.asset('assets/images/no-data.png'), + Padding( + padding: const EdgeInsets.all(8.0), + child: AppText( + TranslationBase.of(context).referralEmptyMsg, + color: Theme.of(context).errorColor, + ), + ) + ], ), - Image.asset('assets/images/no-data.png'), - Padding( - padding: const EdgeInsets.all(8.0), - child: AppText( - TranslationBase.of(context).referralEmptyMsg, - color: Theme.of(context).errorColor, - ), - ) - ], - ), - ) - : SingleChildScrollView( - child: Container( - margin: EdgeInsets.only(top: 70), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ + ) + : SingleChildScrollView( + child: Container( + margin: EdgeInsets.only(top: 70), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ - ...List.generate( - model.myReferralPatients.length, - (index) => InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: ReferralPatientDetailScreen(model.myReferralPatients[index],model), + ...List.generate( + model.myReferralPatients.length, + (index) => InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: ReferralPatientDetailScreen(model.myReferralPatients[index],model), + ), + ); + }, + child: PatientReferralItemWidget( + referralStatus: model.getReferralStatusNameByCode(model.myReferralPatients[index].referralStatus,context), + referralStatusCode: model.myReferralPatients[index].referralStatus, + patientName: model.myReferralPatients[index].patientName, + patientGender: model.myReferralPatients[index].gender, + referredDate: AppDateUtils.getDayMonthYearDateFormatted(model.myReferralPatients[index].referralDate), + referredTime: AppDateUtils.getTimeHHMMA(model.myReferralPatients[index].referralDate), + patientID: "${model.myReferralPatients[index].patientID}", + isSameBranch: false, + isReferral: true, + isReferralClinic: true, + referralClinic:"${model.myReferralPatients[index].referringClinicDescription}", + remark: model.myReferralPatients[index].referringDoctorRemarks, + nationality: model.myReferralPatients[index].nationalityName, + nationalityFlag: model.myReferralPatients[index].nationalityFlagURL, + doctorAvatar: model.myReferralPatients[index].doctorImageURL, + referralDoctorName: model.myReferralPatients[index].referringDoctorName, + clinicDescription: model.myReferralPatients[index].referringClinicDescription, + infoIcon: Icon(FontAwesomeIcons.arrowRight, + size: 25, color: Colors.black), ), - ); - }, - child: PatientReferralItemWidget( - referralStatus: model.getReferralStatusNameByCode(model.myReferralPatients[index].referralStatus,context), - referralStatusCode: model.myReferralPatients[index].referralStatus, - patientName: model.myReferralPatients[index].patientName, - patientGender: model.myReferralPatients[index].gender, - referredDate: AppDateUtils.getDayMonthYearDateFormatted(model.myReferralPatients[index].referralDate), - referredTime: AppDateUtils.getTimeHHMMA(model.myReferralPatients[index].referralDate), - patientID: "${model.myReferralPatients[index].patientID}", - isSameBranch: false, - isReferral: true, - isReferralClinic: true, - referralClinic:"${model.myReferralPatients[index].referringClinicDescription}", - remark: model.myReferralPatients[index].referringDoctorRemarks, - nationality: model.myReferralPatients[index].nationalityName, - nationalityFlag: model.myReferralPatients[index].nationalityFlagURL, - doctorAvatar: model.myReferralPatients[index].doctorImageURL, - referralDoctorName: model.myReferralPatients[index].referringDoctorName, - clinicDescription: model.myReferralPatients[index].referringClinicDescription, - infoIcon: Icon(FontAwesomeIcons.arrowRight, - size: 25, color: Colors.black), + ), ), - ), + ], ), - ], + ), ), - ), - ), + ], + ), ), ); } 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 a949036b..0e7b214b 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 @@ -237,6 +237,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { ), ], ), + if(referredPatient.frequency != null) Row( mainAxisAlignment: MainAxisAlignment.start, @@ -256,7 +257,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { Expanded( child: AppText( referredPatient - .frequencyDescription, + .frequencyDescription??'', fontFamily: 'Poppins', fontWeight: FontWeight.w700, fontSize: 1.8 * @@ -303,6 +304,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { ) ], ), + if(referredPatient.priorityDescription != null) Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, @@ -317,7 +319,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { ), Expanded( child: AppText( - referredPatient.priorityDescription, + referredPatient.priorityDescription??'', fontFamily: 'Poppins', fontWeight: FontWeight.w700, fontSize: @@ -327,6 +329,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { ), ], ), + if(referredPatient.mAXResponseTime != null) Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, @@ -342,9 +345,9 @@ class ReferralPatientDetailScreen extends StatelessWidget { ), Expanded( child: AppText( - AppDateUtils.convertDateFromServerFormat( + referredPatient.mAXResponseTime != null? AppDateUtils.convertDateFromServerFormat( referredPatient.mAXResponseTime, - "dd MMM,yyyy"), + "dd MMM,yyyy"):'', fontFamily: 'Poppins', fontWeight: FontWeight.w700, fontSize: @@ -469,7 +472,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { color: Color(0XFF2E303A), ), AppText( - referredPatient.referringDoctorRemarks, + referredPatient.referringDoctorRemarks??'', fontFamily: 'Poppins', fontWeight: FontWeight.w600, fontSize: 1.8 * SizeConfig.textMultiplier, 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 b4e1ddc5..b3f11c51 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 @@ -236,6 +236,8 @@ class ReferredPatientDetailScreen extends StatelessWidget { ), ], ), + if(referredPatient + .frequencyDescription != null) Row( mainAxisAlignment: MainAxisAlignment.start, @@ -301,6 +303,7 @@ class ReferredPatientDetailScreen extends StatelessWidget { ) ], ), + if(referredPatient.priorityDescription != null) Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, @@ -322,6 +325,7 @@ class ReferredPatientDetailScreen extends StatelessWidget { ), ], ), + if(referredPatient.mAXResponseTime != null) Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, @@ -337,9 +341,9 @@ class ReferredPatientDetailScreen extends StatelessWidget { ), Expanded( child: AppText( - AppDateUtils.convertDateFromServerFormat( + referredPatient.mAXResponseTime != null?AppDateUtils.convertDateFromServerFormat( referredPatient.mAXResponseTime, - "dd MMM,yyyy"), + "dd MMM,yyyy"):'', fontFamily: 'Poppins', fontWeight: FontWeight.w700, fontSize: @@ -515,6 +519,7 @@ class ReferredPatientDetailScreen extends StatelessWidget { ), AppText( referredPatient + .referredDoctorRemarks == null ?'':referredPatient .referredDoctorRemarks.isNotEmpty ? referredPatient.referredDoctorRemarks : TranslationBase.of(context).notRepliedYet, @@ -543,7 +548,7 @@ class ReferredPatientDetailScreen extends StatelessWidget { fontSize: 1.8, hPadding: 8, vPadding: 12, - disabled: referredPatient.referredDoctorRemarks.isNotEmpty + disabled: referredPatient.referredDoctorRemarks == null? true: referredPatient.referredDoctorRemarks.isNotEmpty ? false : true, onPressed: () async { diff --git a/lib/util/date-utils.dart b/lib/util/date-utils.dart index a7d03076..2839c86f 100644 --- a/lib/util/date-utils.dart +++ b/lib/util/date-utils.dart @@ -371,4 +371,22 @@ class AppDateUtils { else return ""; } + + + // handel date like "09/05/2021 17:00" + static DateTime getDateTimeFromString(String str) { + List array = str.split('/'); + int day = int.parse(array[0]); + int month = int.parse(array[1]); + + List array2 = array[2].split(' '); + int year = int.parse(array2[0]); + String hour = array2[1]; + List hourList = hour.split(":"); + + DateTime date = DateTime(year, month, day, int.parse(hourList[0]), int.parse(hourList[1])); + + + return date; + } } From 3df6a55dadf9cd11f0ec96786ee0f5ee0d885257 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Tue, 8 Jun 2021 13:07:33 +0300 Subject: [PATCH 09/72] remove comment --- lib/models/patient/my_referral/my_referred_patient_model.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/models/patient/my_referral/my_referred_patient_model.dart b/lib/models/patient/my_referral/my_referred_patient_model.dart index 5a755fe8..cb61975a 100644 --- a/lib/models/patient/my_referral/my_referred_patient_model.dart +++ b/lib/models/patient/my_referral/my_referred_patient_model.dart @@ -166,7 +166,7 @@ class MyReferredPatientModel { referringDoctor = json['ReferringDoctor']; referralClinic = json['ReferralClinic']; referringClinic = json['ReferringClinic']; - referralStatus = json["ReferralStatus"] is String?json['ReferralStatus']== "Accepted"?46:json['ReferralStatus']=="Pending"?1:0 : json['ReferralStatus'];// TODO Elham json['ReferralStatus']; + referralStatus = json["ReferralStatus"] is String?json['ReferralStatus']== "Accepted"?46:json['ReferralStatus']=="Pending"?1:0 : json['ReferralStatus']; referralDate = json['ReferralDate']; referringDoctorRemarks = json['ReferringDoctorRemarks']; referredDoctorRemarks = json['ReferredDoctorRemarks']; From 9d6a23c1a3b1e4b876c1d63dc6bccfc7b734daac Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Tue, 8 Jun 2021 16:28:35 +0300 Subject: [PATCH 10/72] add NavigationService --- lib/client/base_app_client.dart | 6 +++++ lib/core/service/NavigationService.dart | 12 ++++++++++ lib/locator.dart | 32 +++++++++++++------------ lib/main.dart | 2 ++ 4 files changed, 37 insertions(+), 15 deletions(-) create mode 100644 lib/core/service/NavigationService.dart diff --git a/lib/client/base_app_client.dart b/lib/client/base_app_client.dart index 10181bf4..b1785b0e 100644 --- a/lib/client/base_app_client.dart +++ b/lib/client/base_app_client.dart @@ -3,6 +3,7 @@ import 'dart:io' show Platform; import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; +import 'package:doctor_app_flutter/core/service/NavigationService.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; @@ -12,6 +13,9 @@ import 'package:flutter/cupertino.dart'; import 'package:http/http.dart' as http; import 'package:provider/provider.dart'; +import '../locator.dart'; +import '../routes.dart'; + DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); Helpers helpers = new Helpers(); @@ -116,7 +120,9 @@ class BaseAppClient { await Provider.of(AppGlobal.CONTEX, listen: false) .logout(); + Helpers.showErrorToast('Your session expired Please login again'); + locator().pushNamedAndRemoveUntil(ROOT); } if (isAllowAny) { onFailure(getError(parsed), statusCode); diff --git a/lib/core/service/NavigationService.dart b/lib/core/service/NavigationService.dart new file mode 100644 index 00000000..426ace4d --- /dev/null +++ b/lib/core/service/NavigationService.dart @@ -0,0 +1,12 @@ +import 'package:flutter/material.dart'; + +class NavigationService { + final GlobalKey navigatorKey = + new GlobalKey(); + Future navigateTo(String routeName) { + return navigatorKey.currentState.pushNamed(routeName); + } + Future pushNamedAndRemoveUntil(String routeName) { + return navigatorKey.currentState.pushNamedAndRemoveUntil(routeName,(asd)=>false); + } +} \ No newline at end of file diff --git a/lib/locator.dart b/lib/locator.dart index 66ec9161..6147b114 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -8,35 +8,36 @@ import 'package:doctor_app_flutter/core/viewModel/procedure_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/NavigationService.dart'; import 'core/service/home/dasboard_service.dart'; +import 'core/service/home/doctor_reply_service.dart'; +import 'core/service/home/schedule_service.dart'; +import 'core/service/hospitals/hospitals_service.dart'; import 'core/service/patient/DischargedPatientService.dart'; import 'core/service/patient/LiveCarePatientServices.dart'; -import 'core/service/patient/patient_service.dart'; -import 'core/service/patient_medical_file/insurance/InsuranceCardService.dart'; import 'core/service/patient/MyReferralPatientService.dart'; import 'core/service/patient/PatientMuseService.dart'; import 'core/service/patient/ReferralService.dart'; +import 'core/service/patient/out_patient_service.dart'; +import 'core/service/patient/patient-doctor-referral-service.dart'; +import 'core/service/patient/patientInPatientService.dart'; +import 'core/service/patient/patient_service.dart'; +import 'core/service/patient/referral_patient_service.dart'; +import 'core/service/patient/referred_patient_service.dart'; +import 'core/service/patient_medical_file/admission_request/patient-admission-request-service.dart'; +import 'core/service/patient_medical_file/insurance/InsuranceCardService.dart'; +import 'core/service/patient_medical_file/lab_order/labs_service.dart'; import 'core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart'; import 'core/service/patient_medical_file/medical_report/medical_file_service.dart'; +import 'core/service/patient_medical_file/prescription/medicine_service.dart'; import 'core/service/patient_medical_file/prescription/prescription_service.dart'; +import 'core/service/patient_medical_file/prescription/prescriptions_service.dart'; import 'core/service/patient_medical_file/procedure/procedure_service.dart'; +import 'core/service/patient_medical_file/radiology/radiology_service.dart'; import 'core/service/patient_medical_file/sick_leave/sickleave_service.dart'; import 'core/service/patient_medical_file/soap/SOAP_service.dart'; -import 'core/service/home/doctor_reply_service.dart'; -import 'core/service/hospitals/hospitals_service.dart'; -import 'core/service/patient_medical_file/lab_order/labs_service.dart'; -import 'core/service/patient_medical_file/prescription/medicine_service.dart'; -import 'core/service/patient_medical_file/admission_request/patient-admission-request-service.dart'; -import 'core/service/patient/patient-doctor-referral-service.dart'; import 'core/service/patient_medical_file/ucaf/patient-ucaf-service.dart'; import 'core/service/patient_medical_file/vital_sign/patient-vital-signs-service.dart'; -import 'core/service/patient/out_patient_service.dart'; -import 'core/service/patient/patientInPatientService.dart'; -import 'core/service/patient_medical_file/prescription/prescriptions_service.dart'; -import 'core/service/patient_medical_file/radiology/radiology_service.dart'; -import 'core/service/patient/referral_patient_service.dart'; -import 'core/service/patient/referred_patient_service.dart'; -import 'core/service/home/schedule_service.dart'; import 'core/viewModel/DischargedPatientViewModel.dart'; import 'core/viewModel/InsuranceViewModel.dart'; import 'core/viewModel/LiveCarePatientViewModel.dart'; @@ -92,6 +93,7 @@ void setupLocator() { locator.registerLazySingleton(() => HospitalsService()); locator.registerLazySingleton(() => PatientMedicalReportService()); locator.registerLazySingleton(() => LiveCarePatientServices()); + locator.registerLazySingleton(() => NavigationService()); /// View Model locator.registerFactory(() => DoctorReplayViewModel()); diff --git a/lib/main.dart b/lib/main.dart index a95378e5..c29429b0 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -11,6 +11,7 @@ import 'package:provider/provider.dart'; import './config/size_config.dart'; import './routes.dart'; import 'config/config.dart'; +import 'core/service/NavigationService.dart'; import 'core/viewModel/authentication_view_model.dart'; import 'locator.dart'; @@ -66,6 +67,7 @@ class MyApp extends StatelessWidget { dividerColor: Colors.grey[350], backgroundColor: Color.fromRGBO(255, 255, 255, 1), ), + navigatorKey: locator().navigatorKey, initialRoute: INIT_ROUTE, routes: routes, debugShowCheckedModeBanner: false, From b1062dd5375f607ab4c257774519a09306ed5dcb Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Tue, 8 Jun 2021 17:09:41 +0300 Subject: [PATCH 11/72] fix merge issue --- lib/locator.dart | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib/locator.dart b/lib/locator.dart index 67b09848..1c491b54 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -23,7 +23,6 @@ import 'core/service/patient/patient-doctor-referral-service.dart'; import 'core/service/patient/patientInPatientService.dart'; import 'core/service/patient/patient_service.dart'; import 'core/service/patient/referral_patient_service.dart'; -import 'core/service/patient/referred_patient_service.dart'; import 'core/service/patient_medical_file/admission_request/patient-admission-request-service.dart'; import 'core/service/patient_medical_file/insurance/InsuranceCardService.dart'; import 'core/service/patient_medical_file/lab_order/labs_service.dart'; @@ -38,12 +37,6 @@ import 'core/service/patient_medical_file/sick_leave/sickleave_service.dart'; import 'core/service/patient_medical_file/soap/SOAP_service.dart'; import 'core/service/patient_medical_file/ucaf/patient-ucaf-service.dart'; import 'core/service/patient_medical_file/vital_sign/patient-vital-signs-service.dart'; -import 'core/service/patient/out_patient_service.dart'; -import 'core/service/patient/patientInPatientService.dart'; -import 'core/service/patient_medical_file/prescription/prescriptions_service.dart'; -import 'core/service/patient_medical_file/radiology/radiology_service.dart'; -import 'core/service/patient/referral_patient_service.dart'; -import 'core/service/home/schedule_service.dart'; import 'core/viewModel/DischargedPatientViewModel.dart'; import 'core/viewModel/InsuranceViewModel.dart'; import 'core/viewModel/LiveCarePatientViewModel.dart'; From 176c0ab97cc26fe4141b2deb0c5dda0594465971 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 9 Jun 2021 14:18:16 +0300 Subject: [PATCH 12/72] first step from live care fixes --- .../live_care/AlternativeServicesList.dart | 1 + .../patient/LiveCarePatientServices.dart | 10 +- .../viewModel/LiveCarePatientViewModel.dart | 10 +- lib/models/livecare/start_call_req.dart | 72 +++--- lib/screens/home/home_patient_card.dart | 9 +- lib/screens/home/home_screen.dart | 2 +- lib/screens/live_care/end_call_screen.dart | 9 +- .../live-care_transfer_to_admin.dart | 2 +- .../live_care/live_care_patient_screen.dart | 2 +- .../patient_profile_screen.dart | 231 ++++++++++-------- 10 files changed, 182 insertions(+), 166 deletions(-) diff --git a/lib/core/model/live_care/AlternativeServicesList.dart b/lib/core/model/live_care/AlternativeServicesList.dart index fab11b71..11f27b95 100644 --- a/lib/core/model/live_care/AlternativeServicesList.dart +++ b/lib/core/model/live_care/AlternativeServicesList.dart @@ -11,6 +11,7 @@ class AlternativeService { AlternativeService.fromJson(Map json) { serviceID = json['ServicID']; serviceName = json['ServiceName']; + isSelected = false; } Map toJson() { diff --git a/lib/core/service/patient/LiveCarePatientServices.dart b/lib/core/service/patient/LiveCarePatientServices.dart index e813e017..de381962 100644 --- a/lib/core/service/patient/LiveCarePatientServices.dart +++ b/lib/core/service/patient/LiveCarePatientServices.dart @@ -18,7 +18,7 @@ class LiveCarePatientServices extends BaseService { bool _isFinished = false; - bool _isLive = true; + bool _isLive = false; bool get isFinished => _isFinished; @@ -74,7 +74,7 @@ class LiveCarePatientServices extends BaseService { }, body: startCallReq.toJson(), isLiveCare: _isLive); } - Future endCallWithCharge(int vcID, String altServiceList) async { + Future endCallWithCharge(int vcID, List altServiceList) async { hasError = false; await baseAppClient.post(END_CALL_WITH_CHARGE, onSuccess: (dynamic response, int statusCode) { endCallResponse = response; @@ -84,6 +84,7 @@ class LiveCarePatientServices extends BaseService { }, body: { "VC_ID": vcID, "AltServiceList": altServiceList, + "generalid":GENERAL_ID }, isLiveCare: _isLive); } @@ -110,7 +111,7 @@ class LiveCarePatientServices extends BaseService { hasError = true; super.error = error; }, body: { - "VC_ID": vcID, + "VC_ID": vcID, "generalid": GENERAL_ID }, isLiveCare: _isLive); } @@ -140,6 +141,7 @@ class LiveCarePatientServices extends BaseService { super.error = error; }, body: { "VC_ID": vcID, - }, isLiveCare: _isLive); + "generalid": GENERAL_ID + }, isLiveCare: _isLive); } } diff --git a/lib/core/viewModel/LiveCarePatientViewModel.dart b/lib/core/viewModel/LiveCarePatientViewModel.dart index 8dc83c06..378013bd 100644 --- a/lib/core/viewModel/LiveCarePatientViewModel.dart +++ b/lib/core/viewModel/LiveCarePatientViewModel.dart @@ -101,13 +101,13 @@ class LiveCarePatientViewModel extends BaseViewModel { Future endCallWithCharge(int vcID, bool isConfirmed) async { setState(ViewState.BusyLocal); - String selectedServicesString = ""; + List selectedServices = []; if (isConfirmed) { - selectedServicesString = getSelectedAlternativeServices(); + selectedServices = getSelectedAlternativeServices(); } await _liveCarePatientServices.endCallWithCharge( - vcID, selectedServicesString); + vcID, selectedServices); if (_liveCarePatientServices.hasError) { error = _liveCarePatientServices.error; setState(ViewState.ErrorLocal); @@ -117,14 +117,14 @@ class LiveCarePatientViewModel extends BaseViewModel { } } - String getSelectedAlternativeServices() { + List getSelectedAlternativeServices() { List selectedServices = List(); for (AlternativeService service in alternativeServicesList) { if (service.isSelected) { selectedServices.add(service.serviceID); } } - return selectedServices.toString(); + return selectedServices; } Future getAlternativeServices(int vcID) async { diff --git a/lib/models/livecare/start_call_req.dart b/lib/models/livecare/start_call_req.dart index 1ad04480..b3ceabb5 100644 --- a/lib/models/livecare/start_call_req.dart +++ b/lib/models/livecare/start_call_req.dart @@ -1,56 +1,56 @@ class StartCallReq { - int vCID; - bool isrecall; - String tokenID; - String generalid; + String clincName; + int clinicId; + String docSpec; + String docotrName; int doctorId; + String generalid; bool isOutKsa; + bool isrecall; String projectName; - String docotrName; - String clincName; - String docSpec; - int clinicId; + String tokenID; + int vCID; StartCallReq( - {this.vCID, - this.isrecall, - this.tokenID, - this.generalid, - this.doctorId, - this.isOutKsa, - this.projectName, - this.docotrName, - this.clincName, - this.docSpec, - this.clinicId}); + {this.clincName, + this.clinicId, + this.docSpec, + this.docotrName, + this.doctorId, + this.generalid, + this.isOutKsa, + this.isrecall, + this.projectName, + this.tokenID, + this.vCID}); StartCallReq.fromJson(Map json) { - vCID = json['VC_ID']; - isrecall = json['isrecall']; - tokenID = json['TokenID']; - generalid = json['generalid']; + clincName = json['clincName']; + clinicId = json['ClinicId']; + docSpec = json['Doc_Spec']; + docotrName = json['DocotrName']; doctorId = json['DoctorId']; + generalid = json['generalid']; isOutKsa = json['IsOutKsa']; + isrecall = json['isrecall']; projectName = json['projectName']; - docotrName = json['DocotrName']; - clincName = json['clincName']; - docSpec = json['Doc_Spec']; - clinicId = json['ClinicId']; + tokenID = json['TokenID']; + vCID = json['VC_ID']; } Map toJson() { final Map data = new Map(); - data['VC_ID'] = this.vCID; - data['isrecall'] = this.isrecall; - data['TokenID'] = this.tokenID; - data['generalid'] = this.generalid; + data['clincName'] = this.clincName; + data['ClinicId'] = this.clinicId; + data['Doc_Spec'] = this.docSpec; + data['DocotrName'] = this.docotrName; data['DoctorId'] = this.doctorId; + data['generalid'] = this.generalid; data['IsOutKsa'] = this.isOutKsa; + data['isrecall'] = this.isrecall; data['projectName'] = this.projectName; - data['DocotrName'] = this.docotrName; - data['clincName'] = this.clincName; - data['Doc_Spec'] = this.docSpec; - data['ClinicId'] = this.clinicId; + data['TokenID'] = this.tokenID; + data['VC_ID'] = this.vCID; return data; } -} +} \ No newline at end of file diff --git a/lib/screens/home/home_patient_card.dart b/lib/screens/home/home_patient_card.dart index 6f6712ec..b388a7e2 100644 --- a/lib/screens/home/home_patient_card.dart +++ b/lib/screens/home/home_patient_card.dart @@ -36,11 +36,10 @@ class HomePatientCard extends StatelessWidget { Expanded( child: Stack( children: [ - Positioned( - bottom: 0.1, - right: 0.5, - width: 23.0, - height: 25.0, + Container( + margin: EdgeInsets.only(top: 18, left: 10), + color:Colors.transparent, + child: Icon( cardIcon, size: iconSize * 2, diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index ab0fe73f..82add64c 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -329,7 +329,7 @@ class _HomeScreenState extends State { backgroundIconColor: backgroundIconColors[colorIndex], cardIcon: DoctorApp.livecare, textColor: textColors[colorIndex], - iconSize: 24, + iconSize: 21, text: "${TranslationBase.of(context).liveCare}\n${TranslationBase.of(context).patients}", onTap: () { diff --git a/lib/screens/live_care/end_call_screen.dart b/lib/screens/live_care/end_call_screen.dart index 1b652e36..617eef34 100644 --- a/lib/screens/live_care/end_call_screen.dart +++ b/lib/screens/live_care/end_call_screen.dart @@ -142,25 +142,22 @@ class _EndCallScreenState extends State { 'patient/health_summary.png', onTap: () { Helpers.showConfirmationDialog(context, - "${TranslationBase.of(context).areYouSureYouWantTo} ${TranslationBase.of(context).sendLC}${TranslationBase.of(context).instruction} ?", + "${TranslationBase.of(context).areYouSureYouWantTo} ${TranslationBase.of(context).sendLC} ${TranslationBase.of(context).instruction} ?", () async { Navigator.of(context).pop(); GifLoaderDialogUtils.showMyDialog(context); - liveCareModel.sendSMSInstruction(widget.patient.vcId); + await liveCareModel.sendSMSInstruction(widget.patient.vcId); GifLoaderDialogUtils.hideDialog(context); if (liveCareModel.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(liveCareModel.error); } else { DrAppToastMsg.showSuccesToast("You successfully sent SMS instructions"); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); } }); }, isInPatient: isInpatient, isDartIcon: true, - isDisable: true, + // isDisable: true, dartIcon: DoctorApp.send_instruction), PatientProfileCardModel( TranslationBase.of(context).transferTo, diff --git a/lib/screens/live_care/live-care_transfer_to_admin.dart b/lib/screens/live_care/live-care_transfer_to_admin.dart index 2d0fb7d7..233f59d8 100644 --- a/lib/screens/live_care/live-care_transfer_to_admin.dart +++ b/lib/screens/live_care/live-care_transfer_to_admin.dart @@ -120,7 +120,7 @@ class _LivaCareTransferToAdminState extends State { () async { Navigator.of(context).pop(); GifLoaderDialogUtils.showMyDialog(context); - model.transferToAdmin(widget.patient.vcId, noteController.text); + await model.transferToAdmin(widget.patient.vcId, noteController.text); GifLoaderDialogUtils.hideDialog(context); if (model.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(model.error); diff --git a/lib/screens/live_care/live_care_patient_screen.dart b/lib/screens/live_care/live_care_patient_screen.dart index 0b741989..e6cdad17 100644 --- a/lib/screens/live_care/live_care_patient_screen.dart +++ b/lib/screens/live_care/live_care_patient_screen.dart @@ -31,7 +31,7 @@ class _LiveCarePatientScreenState extends State { super.initState(); timer = Timer.periodic(Duration(seconds: 10), (Timer t) { if (_liveCareViewModel != null) { - _liveCareViewModel.getPendingPatientERForDoctorApp(isFromTimer: true); + // _liveCareViewModel.getPendingPatientERForDoctorApp(isFromTimer: true); } }); } 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 55b2d6f9..e64b582f 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -1,18 +1,13 @@ -import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/PostEpisodeReqModel.dart'; -import 'package:doctor_app_flutter/models/livecare/session_status_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/live_care/end_call_screen.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_InPatient.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_other.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_search.dart'; -import 'package:doctor_app_flutter/util/VideoChannel.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'; import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; @@ -156,51 +151,57 @@ class _PatientProfileScreenState extends State SizedBox( height: MediaQuery.of(context).size.height * 0.05, ) - ], - ), - ), - ], ), - if (patient.patientStatusType != null && - patient.patientStatusType == 43) - BaseView( - onModelReady: (model) async {}, - builder: (_, model, w) => Positioned( - top: 180, - left: 20, - right: 20, - child: Row( - children: [ - Expanded(child: Container()), - if (patient.episodeNo == 0) - AppButton( - title: - "${TranslationBase.of(context).createNew}\n${TranslationBase.of(context).episode}", - color: patient.patientStatusType == 43 - ? Colors.red.shade700 - : Colors.grey.shade700, - fontColor: Colors.white, - vPadding: 8, - radius: 30, - hPadding: 20, - fontWeight: FontWeight.normal, - fontSize: 1.6, - icon: Image.asset( - "assets/images/create-episod.png", - color: Colors.white, + ), + ], + ), + if (isFromLiveCare + ? patient.episodeNo != null + : patient.patientStatusType != null && + patient.patientStatusType == 43) + BaseView( + onModelReady: (model) async {}, + builder: (_, model, w) => Positioned( + top: 180, + left: 20, + right: 20, + child: Row( + children: [ + Expanded(child: Container()), + if (patient.episodeNo == 0) + AppButton( + title: + "${TranslationBase.of(context).createNew}\n${TranslationBase.of(context).episode}", + color: isFromLiveCare + ? Colors.red.shade700 + : patient.patientStatusType == 43 + ? Colors.red.shade700 + : Colors.grey.shade700, + fontColor: Colors.white, + vPadding: 8, + radius: 30, + hPadding: 20, + fontWeight: FontWeight.normal, + fontSize: 1.6, + icon: Image.asset( + "assets/images/create-episod.png", + color: Colors.white, height: 30, ), onPressed: () async { - if (patient.patientStatusType == - 43) { + if ((isFromLiveCare && + patient.appointmentNo != null && + patient.appointmentNo != 0) || + patient.patientStatusType == + 43) { PostEpisodeReqModel - postEpisodeReqModel = - PostEpisodeReqModel( - appointmentNo: - patient.appointmentNo, - patientMRN: - patient.patientMRN); + postEpisodeReqModel = + PostEpisodeReqModel( + appointmentNo: + patient.appointmentNo, + patientMRN: + patient.patientMRN); GifLoaderDialogUtils.showMyDialog( context); await model.postEpisode( @@ -220,11 +221,18 @@ class _PatientProfileScreenState extends State if (patient.episodeNo != 0) AppButton( title: - "${TranslationBase.of(context).update}\n${TranslationBase.of(context).episode}", + "${TranslationBase + .of(context) + .update}\n${TranslationBase + .of(context) + .episode}", color: - patient.patientStatusType == 43 - ? Colors.red.shade700 - : Colors.grey.shade700, + isFromLiveCare + ? Colors.red.shade700 + : patient.patientStatusType == + 43 + ? Colors.red.shade700 + : Colors.grey.shade700, fontColor: Colors.white, vPadding: 8, radius: 30, @@ -237,8 +245,12 @@ class _PatientProfileScreenState extends State height: 30, ), onPressed: () { - if (patient.patientStatusType == - 43) { + if ((isFromLiveCare && + patient.appointmentNo != + null && + patient.appointmentNo != 0) || + patient.patientStatusType == + 43) { Navigator.of(context).pushNamed( UPDATE_EPISODE, arguments: { @@ -283,65 +295,70 @@ class _PatientProfileScreenState extends State TranslationBase.of(context).initiateCall, disabled: model.state == ViewState.BusyLocal, onPressed: () async { - if(isCallFinished) { - Navigator.push(context, MaterialPageRoute( - builder: (BuildContext context) => - EndCallScreen(patient:patient))); - } else { - GifLoaderDialogUtils.showMyDialog(context); - 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 = model.startCallRes.appointmentNo; - patient.episodeNo = 0; + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) => + EndCallScreen(patient:patient))); - GifLoaderDialogUtils.hideDialog(context); - await VideoChannel.openVideoCallScreen( - kToken: model.startCallRes.openTokenID, - kSessionId: model.startCallRes.openSessionID, - kApiKey: '46209962', - vcId: patient.vcId, - tokenID: await model.getToken(), - generalId: GENERAL_ID, - doctorId: model.doctorProfile.doctorID, - onFailure: (String error) { - DrAppToastMsg.showErrorToast(error); - }, - onCallEnd: () { - WidgetsBinding.instance.addPostFrameCallback((_) { - GifLoaderDialogUtils.showMyDialog(context); - model.endCall(patient.vcId, false,).then((value) { - GifLoaderDialogUtils.hideDialog(context); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } - setState(() { - isCallFinished = true; - }); - }); - }); - }, - onCallNotRespond: (SessionStatusModel sessionStatusModel) { - WidgetsBinding.instance.addPostFrameCallback((_) { - GifLoaderDialogUtils.showMyDialog(context); - model.endCall(patient.vcId, sessionStatusModel.sessionStatus == 3,).then((value) { - GifLoaderDialogUtils.hideDialog(context); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } - setState(() { - isCallFinished = true; - }); - }); - }); - }); - } - } + // if(isCallFinished) { + // Navigator.push(context, MaterialPageRoute( + // builder: (BuildContext context) => + // EndCallScreen(patient:patient))); + // } else { + // GifLoaderDialogUtils.showMyDialog(context); + // 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 = model.startCallRes.appointmentNo; + // patient.episodeNo = 0; + // + // GifLoaderDialogUtils.hideDialog(context); + // await VideoChannel.openVideoCallScreen( + // kToken: model.startCallRes.openTokenID, + // kSessionId: model.startCallRes.openSessionID, + // kApiKey: '46209962', + // vcId: patient.vcId, + // tokenID: await model.getToken(), + // generalId: GENERAL_ID, + // doctorId: model.doctorProfile.doctorID, + // onFailure: (String error) { + // DrAppToastMsg.showErrorToast(error); + // }, + // onCallEnd: () { + // WidgetsBinding.instance.addPostFrameCallback((_) { + // GifLoaderDialogUtils.showMyDialog(context); + // model.endCall(patient.vcId, false,).then((value) { + // GifLoaderDialogUtils.hideDialog(context); + // if (model.state == ViewState.ErrorLocal) { + // DrAppToastMsg.showErrorToast(model.error); + // } + // setState(() { + // isCallFinished = true; + // }); + // }); + // }); + // }, + // onCallNotRespond: (SessionStatusModel sessionStatusModel) { + // WidgetsBinding.instance.addPostFrameCallback((_) { + // GifLoaderDialogUtils.showMyDialog(context); + // model.endCall(patient.vcId, sessionStatusModel.sessionStatus == 3,).then((value) { + // GifLoaderDialogUtils.hideDialog(context); + // if (model.state == ViewState.ErrorLocal) { + // DrAppToastMsg.showErrorToast(model.error); + // } + // setState(() { + // isCallFinished = true; + // }); + // }); + // + // }); + // }); + // } + // } }, ), From e76ecf172fe331c10acb068779fcefa65f5ae492 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 9 Jun 2021 14:46:03 +0300 Subject: [PATCH 13/72] video-straming-android-changes --- android/app/build.gradle | 1 + .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 32 +- .../hmgDr/ui/fragment/VideoCallFragment.kt | 385 ++++++++++++++++++ android/app/src/main/res/values/strings.xml | 2 + pubspec.lock | 2 +- 5 files changed, 410 insertions(+), 12 deletions(-) create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt diff --git a/android/app/build.gradle b/android/app/build.gradle index 16960d54..deb42f99 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -70,6 +70,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' 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 612118c9..b95e7cb9 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -2,17 +2,19 @@ package com.hmg.hmgDr import android.app.Activity import android.content.Intent +import android.os.Bundle 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.ui.VideoCallActivity -import com.google.gson.GsonBuilder +import io.flutter.embedding.android.FlutterFragment 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 + class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler { private val CHANNEL = "Dr.cloudSolution/videoCall" @@ -20,6 +22,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler private var call: MethodCall? = null private val LAUNCH_VIDEO: Int = 1 + private val flutterFragment: FlutterFragment? = null override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { GeneratedPluginRegistrant.registerWith(flutterEngine) @@ -27,6 +30,11 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler(this) } + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + } + override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { @@ -59,15 +67,17 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler private fun openVideoCall(apiKey: String?, sessionId: String?, token: String?, appLang: String?, baseUrl: String?, sessionStatusModel: GetSessionStatusModel) { // val videoCallActivity = VideoCallActivity() - val intent = Intent(this, VideoCallActivity::class.java) - intent.putExtra("apiKey", apiKey) - intent.putExtra("sessionId", sessionId) - intent.putExtra("token", token) - intent.putExtra("appLang", appLang) - intent.putExtra("baseUrl", baseUrl) - intent.putExtra("sessionStatusModel", sessionStatusModel) - startActivityForResult(intent, LAUNCH_VIDEO) - +// val intent = Intent(this, VideoCallActivity::class.java) +// intent.putExtra("apiKey", apiKey) +// intent.putExtra("sessionId", sessionId) +// intent.putExtra("token", token) +// intent.putExtra("appLang", appLang) +// intent.putExtra("baseUrl", baseUrl) +// intent.putExtra("sessionStatusModel", sessionStatusModel) +// startActivityForResult(intent, LAUNCH_VIDEO) + + val transaction = supportFragmentManager.beginTransaction() +// transaction.add() } 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 new file mode 100644 index 00000000..be343b89 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -0,0 +1,385 @@ +package com.hmg.hmgDr.ui.fragment + +import android.Manifest +import android.annotation.SuppressLint +import android.app.Activity +import android.content.Intent +import android.opengl.GLSurfaceView +import android.os.Bundle +import android.os.CountDownTimer +import android.os.Handler +import android.os.Looper +import android.util.Log +import android.view.LayoutInflater +import android.view.MotionEvent +import android.view.View +import android.view.ViewGroup +import android.widget.* +import androidx.fragment.app.Fragment +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.VideoCallActivity +import com.hmg.hmgDr.ui.VideoCallContract.VideoCallPresenter +import com.hmg.hmgDr.ui.VideoCallContract.VideoCallView +import com.hmg.hmgDr.ui.VideoCallPresenterImpl +import com.opentok.android.* +import com.opentok.android.PublisherKit.PublisherListener +import pub.devrel.easypermissions.AfterPermissionGranted +import pub.devrel.easypermissions.AppSettingsDialog +import pub.devrel.easypermissions.EasyPermissions +import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks +import java.util.* + +class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListener, PublisherListener, + SubscriberKit.VideoListener, VideoCallView { + + lateinit var videoCallPresenter: VideoCallPresenter + + private var mSession: Session? = null + private var mPublisher: Publisher? = null + private var mSubscriber: Subscriber? = null + + private var mVolHandler: Handler? = null + private var mConnectedHandler: Handler? = null + private var mVolRunnable: Runnable? = null + private var mConnectedRunnable: Runnable? = null + + private var mPublisherViewContainer: FrameLayout? = null + private var mSubscriberViewContainer: RelativeLayout? = null + private var controlPanel: RelativeLayout? = null + + private var apiKey: String? = null + private var sessionId: String? = null + private var token: String? = null + private var appLang: String? = null + private var baseUrl: String? = null + + private var isSwitchCameraClicked = false + private var isCameraClicked = false + private var isSpeckerClicked = false + private var isMicClicked = false + + private var mCallBtn: ImageView? = null + private var mCameraBtn: ImageView? = null + private var mSwitchCameraBtn: ImageView? = null + private var mspeckerBtn: ImageView? = null + private var mMicBtn: ImageView? = null + + private val progressBar: ProgressBar? = null + private val countDownTimer: CountDownTimer? = null + private val progressBarTextView: TextView? = null + private val progressBarLayout: RelativeLayout? = null + + private var isConnected = false + + private var sessionStatusModel: GetSessionStatusModel? = null + + + override fun onCreate(savedInstanceState: Bundle?) { + requireActivity().setTheme(R.style.AppTheme) + super.onCreate(savedInstanceState) + + requestPermissions() + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle?): View? { + + val view = inflater.inflate(R.layout.activity_video_call, container, false) + + Objects.requireNonNull(requireActivity().actionBar)!!.hide() + initUI(view) + + return view + } + + override fun onPause() { + super.onPause() + if (mSession == null) { + return + } + mSession!!.onPause() + if (requireActivity().isFinishing) { + disconnectSession() + } + } + + override fun onResume() { + super.onResume() + if (mSession == null) { + return + } + mSession!!.onResume() + } + + override fun onDestroy() { + disconnectSession() + super.onDestroy() + } + + @SuppressLint("ClickableViewAccessibility") + private fun initUI(view: View) { + mPublisherViewContainer = view.findViewById(R.id.local_video_view_container) + mSubscriberViewContainer = view.findViewById(R.id.remote_video_view_container) + + arguments?.run { + apiKey = getString("apiKey") + sessionId = getString("sessionId") + token = getString("token") + appLang = getString("appLang") + baseUrl = getString("baseUrl") + sessionStatusModel = getParcelable("sessionStatusModel") + } + + controlPanel = view.findViewById(R.id.control_panel) + videoCallPresenter = VideoCallPresenterImpl(this, baseUrl) + mCallBtn = view.findViewById(R.id.btn_call) + mCameraBtn = view.findViewById(R.id.btn_camera) + mSwitchCameraBtn = view.findViewById(R.id.btn_switch_camera) + mspeckerBtn = view.findViewById(R.id.btn_specker) + mMicBtn = view.findViewById(R.id.btn_mic) + + // progressBarLayout=findViewById(R.id.progressBar); + // progressBar=findViewById(R.id.progress_bar); +// progressBarTextView=findViewById(R.id.progress_bar_text); +// progressBar.setVisibility(View.GONE); + hiddenButtons() + checkClientConnected() + mSubscriberViewContainer!!.setOnTouchListener { v: View?, event: MotionEvent? -> + controlPanel!!.visibility = View.VISIBLE + mVolHandler!!.removeCallbacks(mVolRunnable!!) + mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) + true + } + if (appLang == "ar") { + progressBarLayout!!.layoutDirection = View.LAYOUT_DIRECTION_RTL + } + } + + private fun checkClientConnected() { + mConnectedHandler = Handler((Looper.getMainLooper())) + mConnectedRunnable = Runnable { + if (!isConnected) { + videoCallPresenter.callClintConnected(sessionStatusModel) + } + } + mConnectedHandler!!.postDelayed(mConnectedRunnable!!, (55 * 1000).toLong()) + } + + private fun hiddenButtons() { + mVolHandler = Handler() + mVolRunnable = Runnable { controlPanel!!.visibility = View.GONE } + mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) + } + + override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + Log.d(TAG, "onPermissionsGranted:" + requestCode + ":" + perms.size) + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + Log.d(TAG, "onPermissionsDenied:" + requestCode + ":" + perms.size) + if (EasyPermissions.somePermissionPermanentlyDenied(this, 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() + } + } + + @AfterPermissionGranted(RC_VIDEO_APP_PERM) + private fun requestPermissions() { + val perms = arrayOf(Manifest.permission.INTERNET, Manifest.permission.CAMERA) + if (EasyPermissions.hasPermissions(requireContext(), *perms)) { + try { + mSession = Session.Builder(context, apiKey, sessionId).build() + mSession!!.setSessionListener(this) + mSession!!.connect(token) + } catch (e: Exception) { + e.printStackTrace() + } + } else { + EasyPermissions.requestPermissions(this, getString(R.string.remaining_ar), RC_VIDEO_APP_PERM, *perms) + } + } + + override fun onConnected(session: Session?) { + Log.i(TAG, "Session Connected") + mPublisher = Publisher.Builder(requireContext()).build() + mPublisher!!.setPublisherListener(this) + mPublisherViewContainer!!.addView(mPublisher!!.view) + if (mPublisher!!.getView() is GLSurfaceView) { + (mPublisher!!.getView() as GLSurfaceView).setZOrderOnTop(true) + } + mSession!!.publish(mPublisher) + } + + override fun onDisconnected(session: Session) { + Log.d(TAG, "onDisconnected: disconnected from session " + session.sessionId) + mSession = null + } + + override fun onError(session: Session, opentokError: OpentokError) { + Log.d(TAG, "onError: Error (" + opentokError.message + ") in session " + session.sessionId) + Toast.makeText(requireContext(), "Session error. See the logcat please.", Toast.LENGTH_LONG).show() + requireActivity().finish() + } + + override fun onStreamReceived(session: Session, stream: Stream) { + Log.d(TAG, "onStreamReceived: New stream " + stream.streamId + " in session " + session.sessionId) + if (mSubscriber != null) { + isConnected = true + return + } + isConnected = true + subscribeToStream(stream) + videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(3, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) + } + + override fun onStreamDropped(session: Session, stream: Stream) { + Log.d(TAG, "onStreamDropped: Stream " + stream.streamId + " dropped from session " + session.sessionId) + if (mSubscriber == null) { + return + } + if (mSubscriber!!.stream == stream) { + mSubscriberViewContainer!!.removeView(mSubscriber!!.view) + mSubscriber!!.destroy() + mSubscriber = null + } + disconnectSession() + } + + override fun onStreamCreated(publisherKit: PublisherKit?, stream: Stream) { + Log.d(TAG, "onStreamCreated: Own stream " + stream.streamId + " created") + } + + override fun onStreamDestroyed(publisherKit: PublisherKit?, stream: Stream) { + Log.d(TAG, "onStreamDestroyed: Own stream " + stream.streamId + " destroyed") + } + + override fun onError(publisherKit: PublisherKit?, opentokError: OpentokError) { + Log.d(VideoCallFragment.TAG, "onError: Error (" + opentokError.message + ") in publisher") + Toast.makeText(requireContext(), "Session error. See the logcat please.", Toast.LENGTH_LONG).show() + requireActivity().finish() + } + + override fun onVideoDataReceived(subscriberKit: SubscriberKit?) { + mSubscriber!!.setStyle(BaseVideoRenderer.STYLE_VIDEO_SCALE, BaseVideoRenderer.STYLE_VIDEO_FILL) + mSubscriberViewContainer!!.addView(mSubscriber!!.view) + } + + override fun onVideoDisabled(subscriberKit: SubscriberKit?, s: String?) {} + + override fun onVideoEnabled(subscriberKit: SubscriberKit?, s: String?) {} + + override fun onVideoDisableWarning(subscriberKit: SubscriberKit?) {} + + override fun onVideoDisableWarningLifted(subscriberKit: SubscriberKit?) {} + + private fun subscribeToStream(stream: Stream) { + mSubscriber = Subscriber.Builder(requireContext(), stream).build() + mSubscriber!!.setVideoListener(this) + mSession!!.subscribe(mSubscriber) + } + + private fun disconnectSession() { + if (mSession == null) { + requireActivity().setResult(Activity.RESULT_CANCELED) + requireActivity().finish() + return + } + if (mSubscriber != null) { + mSubscriberViewContainer!!.removeView(mSubscriber!!.view) + mSession!!.unsubscribe(mSubscriber) + mSubscriber!!.destroy() + mSubscriber = null + } + if (mPublisher != null) { + mPublisherViewContainer!!.removeView(mPublisher!!.view) + mSession!!.unpublish(mPublisher) + mPublisher!!.destroy() + mPublisher = null + } + mSession!!.disconnect() + countDownTimer?.cancel() + videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(16, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) + requireActivity().finish() + } + + fun onSwitchCameraClicked(view: View?) { + if (mPublisher != null) { + isSwitchCameraClicked = !isSwitchCameraClicked + mPublisher!!.cycleCamera() + val res = if (isSwitchCameraClicked) R.drawable.flip_disapled else R.drawable.flip_enabled + mSwitchCameraBtn!!.setImageResource(res) + } + } + + fun onCameraClicked(view: View?) { + if (mPublisher != null) { + isCameraClicked = !isCameraClicked + mPublisher!!.publishVideo = !isCameraClicked + val res = if (isCameraClicked) R.drawable.video_disanabled else R.drawable.video_enabled + mCameraBtn!!.setImageResource(res) + } + } + + fun onSpeckerClicked(view: View?) { + if (mSubscriber != null) { + isSpeckerClicked = !isSpeckerClicked + mSubscriber!!.subscribeToAudio = !isSpeckerClicked + val res = if (isSpeckerClicked) R.drawable.audio_disabled else R.drawable.audio_enabled + mspeckerBtn!!.setImageResource(res) + } + } + + fun onMicClicked(view: View?) { + if (mPublisher != null) { + isMicClicked = !isMicClicked + mPublisher!!.publishAudio = !isMicClicked + val res = if (isMicClicked) R.drawable.mic_disabled else R.drawable.mic_enabled + mMicBtn!!.setImageResource(res) + } + } + + fun onCallClicked(view: View?) { + disconnectSession() + } + + override fun onCallSuccessful(sessionStatusModel: SessionStatusModel) { + if (sessionStatusModel.sessionStatus == 2 || sessionStatusModel.sessionStatus == 3) { + val returnIntent = Intent() + returnIntent.putExtra("sessionStatusNotRespond", sessionStatusModel) + requireActivity().setResult(Activity.RESULT_OK, returnIntent) + requireActivity().finish() + } + } + + override fun onCallChangeCallStatusSuccessful(sessionStatusModel: SessionStatusModel?) {} + + override fun onFailure() {} + + companion object { + @JvmStatic + fun newInstance(args: Bundle) = + VideoCallFragment().apply { + arguments = args + } + + private val TAG = VideoCallActivity::class.java.simpleName + + private const val RC_SETTINGS_SCREEN_PERM = 123 + private const val RC_VIDEO_APP_PERM = 124 + + } +} \ No newline at end of file diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 74349756..bc694f7c 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -4,5 +4,7 @@ الوقت المتبقي بالثانيه: Settings Cancel + + Hello blank fragment \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 77df9848..49ff6372 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -587,7 +587,7 @@ packages: name: js url: "https://pub.dartlang.org" source: hosted - version: "0.6.3-nullsafety.1" + version: "0.6.2" json_annotation: dependency: transitive description: From 0b52b4009dadc429fda86c2adcc64db68176adaa Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Wed, 9 Jun 2021 14:46:45 +0300 Subject: [PATCH 14/72] fix label on replay referral --- android/app/src/main/AndroidManifest.xml | 13 +++++++++--- .../com/hmg/hmgDr/ui/VideoCallActivity.java | 20 ++++++++++--------- .../referral/AddReplayOnReferralPatient.dart | 10 +++++----- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index c656ebbf..0e71249f 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -9,12 +9,19 @@ additional functionality it is fine to subclass or reimplement FlutterApplication and put your custom class here. --> - - - + + + + + + + + + + controlPanel.setVisibility(View.GONE); mVolHandler.postDelayed(mVolRunnable, 5 * 1000); } @@ -269,8 +265,8 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi public void onError(Session session, OpentokError opentokError) { Log.d(TAG, "onError: Error (" + opentokError.getMessage() + ") in session " + session.getSessionId()); - Toast.makeText(this, "Session error. See the logcat please.", Toast.LENGTH_LONG).show(); - finish(); + // Toast.makeText(this, "Session error. See the logcat please.", Toast.LENGTH_LONG).show(); + //finish(); } @Override @@ -282,6 +278,8 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi } isConnected = true; subscribeToStream(stream); + if(mConnectedHandler!=null && mConnectedRunnable!=null) + mConnectedHandler.removeCallbacks(mConnectedRunnable); videoCallPresenter.callChangeCallStatus(new ChangeCallStatusRequestModel(3,sessionStatusModel.getDoctorId(), sessionStatusModel.getGeneralid(),token,sessionStatusModel.getVCID())); } @@ -315,8 +313,8 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi public void onError(PublisherKit publisherKit, OpentokError opentokError) { Log.d(TAG, "onError: Error (" + opentokError.getMessage() + ") in publisher"); - Toast.makeText(this, "Session error. See the logcat please.", Toast.LENGTH_LONG).show(); - finish(); + // Toast.makeText(this, "onError: Error (" + opentokError.getMessage() + ") in publisher", Toast.LENGTH_LONG).show(); + // finish(); } @Override @@ -427,6 +425,10 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi returnIntent.putExtra("sessionStatusNotRespond", sessionStatusModel); setResult(Activity.RESULT_OK, returnIntent); finish(); + } else if( sessionStatusModel.getSessionStatus() == 4 ){ + isConnected = true; + if(mConnectedHandler!=null && mConnectedRunnable!=null) + mConnectedHandler.removeCallbacks(mConnectedRunnable); } } diff --git a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart index f54a18ac..8055517d 100644 --- a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart +++ b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart @@ -58,7 +58,7 @@ class _AddReplayOnReferralPatientState child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - BottomSheetTitle(title: 'Replay'), + BottomSheetTitle(title: 'Reply'), SizedBox( height: 10.0, ), @@ -70,7 +70,7 @@ class _AddReplayOnReferralPatientState Stack( children: [ AppTextFieldCustom( - hintText: 'Replay your responses here', + hintText: 'Reply your responses here', controller: replayOnReferralController, maxLines: 35, minLines: 25, @@ -128,7 +128,7 @@ class _AddReplayOnReferralPatientState Container( margin: EdgeInsets.all(5), child: AppButton( - title: 'Submit Replay', + title: 'Submit Reply', color: Color(0xff359846), fontWeight: FontWeight.w700, onPressed: () async { @@ -147,12 +147,12 @@ class _AddReplayOnReferralPatientState } else { GifLoaderDialogUtils.hideDialog(context); DrAppToastMsg.showSuccesToast( - "Your Replay Added Successfully"); + "Your Reply Added Successfully"); Navigator.of(context).pop(); Navigator.of(context).pop(); } } else { - Helpers.showErrorToast("You can't add empty replay"); + Helpers.showErrorToast("You can't add empty reply"); setState(() { isSubmitted = false; }); From 36caca0e4659d7d518f59f7e90e7940519fe681a Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 9 Jun 2021 16:07:58 +0300 Subject: [PATCH 15/72] test live care and general result header in lab result --- lib/config/config.dart | 4 +- .../patient/LiveCarePatientServices.dart | 2 +- .../live_care/live_care_patient_screen.dart | 2 +- .../lab_result/laboratory_result_page.dart | 46 ++- .../patient_profile_screen.dart | 129 +++---- .../profile/GeneralLabResultHeader.dart | 347 ++++++++++++++++++ 6 files changed, 445 insertions(+), 85 deletions(-) create mode 100644 lib/widgets/patients/profile/GeneralLabResultHeader.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index e2f9eb6a..97e1d4dd 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/patient/LiveCarePatientServices.dart b/lib/core/service/patient/LiveCarePatientServices.dart index de381962..29b120ec 100644 --- a/lib/core/service/patient/LiveCarePatientServices.dart +++ b/lib/core/service/patient/LiveCarePatientServices.dart @@ -18,7 +18,7 @@ class LiveCarePatientServices extends BaseService { bool _isFinished = false; - bool _isLive = false; + bool _isLive = true; bool get isFinished => _isFinished; diff --git a/lib/screens/live_care/live_care_patient_screen.dart b/lib/screens/live_care/live_care_patient_screen.dart index e6cdad17..0b741989 100644 --- a/lib/screens/live_care/live_care_patient_screen.dart +++ b/lib/screens/live_care/live_care_patient_screen.dart @@ -31,7 +31,7 @@ class _LiveCarePatientScreenState extends State { super.initState(); timer = Timer.periodic(Duration(seconds: 10), (Timer t) { if (_liveCareViewModel != null) { - // _liveCareViewModel.getPendingPatientERForDoctorApp(isFromTimer: true); + _liveCareViewModel.getPendingPatientERForDoctorApp(isFromTimer: true); } }); } diff --git a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart index 5f79038f..91e5145f 100644 --- a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart +++ b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart @@ -2,7 +2,7 @@ import 'package:doctor_app_flutter/core/model/labs/patient_lab_orders.dart'; import 'package:doctor_app_flutter/core/viewModel/labs_view_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/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/GeneralLabResultHeader.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -32,37 +32,45 @@ class _LaboratoryResultPageState extends State { @override Widget build(BuildContext context) { return BaseView( - // onModelReady: (model) => model.getLaboratoryResult( - // invoiceNo: widget.patientLabOrders.invoiceNo, - // clinicID: widget.patientLabOrders.clinicID, - // projectID: widget.patientLabOrders.projectID, - // orderNo: widget.patientLabOrders.orderNo, - // patient: widget.patient, - // isInpatient: widget.patientType == "1"), onModelReady: (model) => model.getPatientLabResult( patientLabOrder: widget.patientLabOrders, patient: widget.patient, isInpatient: true), builder: (_, model, w) => AppScaffold( isShowAppBar: true, - appBar: PatientProfileHeaderWhitAppointmentAppBar( - patient: widget.patient, - patientType: widget.patientType ?? "0", - arrivalType: widget.arrivalType ?? "0", - orderNo: widget.patientLabOrders.orderNo, - appointmentDate: widget.patientLabOrders.orderDate, - doctorName: widget.patientLabOrders.doctorName, - branch: widget.patientLabOrders.projectName, - clinic: widget.patientLabOrders.clinicDescription, - profileUrl: widget.patientLabOrders.doctorImageURL, - invoiceNO: widget.patientLabOrders.invoiceNo, + appBar: GeneralLabResultHeader( + patient: widget.patient, + patientType: widget.patientType ?? "0", + arrivalType: widget.arrivalType ?? "0", + orderNo: widget.patientLabOrders.orderNo, + appointmentDate: widget.patientLabOrders.orderDate, + doctorName: widget.patientLabOrders.doctorName, + branch: widget.patientLabOrders.projectName, + clinic: widget.patientLabOrders.clinicDescription, + profileUrl: widget.patientLabOrders.doctorImageURL, + invoiceNO: widget.patientLabOrders.invoiceNo, ), + + + // PatientProfileHeaderWhitAppointmentAppBar( + // patient: widget.patient, + // patientType: widget.patientType ?? "0", + // arrivalType: widget.arrivalType ?? "0", + // orderNo: widget.patientLabOrders.orderNo, + // appointmentDate: widget.patientLabOrders.orderDate, + // doctorName: widget.patientLabOrders.doctorName, + // branch: widget.patientLabOrders.projectName, + // clinic: widget.patientLabOrders.clinicDescription, + // profileUrl: widget.patientLabOrders.doctorImageURL, + // invoiceNO: widget.patientLabOrders.invoiceNo, + // ), baseViewModel: model, body: AppScaffold( isShowAppBar: false, body: SingleChildScrollView( child: Column( children: [ + LaboratoryResultWidget( onTap: () async {}, billNo: widget.patientLabOrders.invoiceNo, 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 e64b582f..d9aa7d8d 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -1,13 +1,18 @@ +import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/PostEpisodeReqModel.dart'; +import 'package:doctor_app_flutter/models/livecare/session_status_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/live_care/end_call_screen.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_InPatient.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_other.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_search.dart'; +import 'package:doctor_app_flutter/util/VideoChannel.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'; import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; @@ -295,70 +300,70 @@ class _PatientProfileScreenState extends State TranslationBase.of(context).initiateCall, disabled: model.state == ViewState.BusyLocal, onPressed: () async { - Navigator.push(context, MaterialPageRoute( - builder: (BuildContext context) => - EndCallScreen(patient:patient))); + // Navigator.push(context, MaterialPageRoute( + // builder: (BuildContext context) => + // EndCallScreen(patient:patient))); - // if(isCallFinished) { - // Navigator.push(context, MaterialPageRoute( - // builder: (BuildContext context) => - // EndCallScreen(patient:patient))); - // } else { - // GifLoaderDialogUtils.showMyDialog(context); - // 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 = model.startCallRes.appointmentNo; - // patient.episodeNo = 0; - // - // GifLoaderDialogUtils.hideDialog(context); - // await VideoChannel.openVideoCallScreen( - // kToken: model.startCallRes.openTokenID, - // kSessionId: model.startCallRes.openSessionID, - // kApiKey: '46209962', - // vcId: patient.vcId, - // tokenID: await model.getToken(), - // generalId: GENERAL_ID, - // doctorId: model.doctorProfile.doctorID, - // onFailure: (String error) { - // DrAppToastMsg.showErrorToast(error); - // }, - // onCallEnd: () { - // WidgetsBinding.instance.addPostFrameCallback((_) { - // GifLoaderDialogUtils.showMyDialog(context); - // model.endCall(patient.vcId, false,).then((value) { - // GifLoaderDialogUtils.hideDialog(context); - // if (model.state == ViewState.ErrorLocal) { - // DrAppToastMsg.showErrorToast(model.error); - // } - // setState(() { - // isCallFinished = true; - // }); - // }); - // }); - // }, - // onCallNotRespond: (SessionStatusModel sessionStatusModel) { - // WidgetsBinding.instance.addPostFrameCallback((_) { - // GifLoaderDialogUtils.showMyDialog(context); - // model.endCall(patient.vcId, sessionStatusModel.sessionStatus == 3,).then((value) { - // GifLoaderDialogUtils.hideDialog(context); - // if (model.state == ViewState.ErrorLocal) { - // DrAppToastMsg.showErrorToast(model.error); - // } - // setState(() { - // isCallFinished = true; - // }); - // }); - // - // }); - // }); - // } - // } + if(isCallFinished) { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) => + EndCallScreen(patient:patient))); + } else { + GifLoaderDialogUtils.showMyDialog(context); + 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 = model.startCallRes.appointmentNo; + patient.episodeNo = 0; + + GifLoaderDialogUtils.hideDialog(context); + await VideoChannel.openVideoCallScreen( + kToken: model.startCallRes.openTokenID, + kSessionId: model.startCallRes.openSessionID, + kApiKey: '46209962', + vcId: patient.vcId, + tokenID: await model.getToken(), + generalId: GENERAL_ID, + doctorId: model.doctorProfile.doctorID, + onFailure: (String error) { + DrAppToastMsg.showErrorToast(error); + }, + onCallEnd: () { + WidgetsBinding.instance.addPostFrameCallback((_) { + GifLoaderDialogUtils.showMyDialog(context); + model.endCall(patient.vcId, false,).then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); + } + setState(() { + isCallFinished = true; + }); + }); + }); + }, + onCallNotRespond: (SessionStatusModel sessionStatusModel) { + WidgetsBinding.instance.addPostFrameCallback((_) { + GifLoaderDialogUtils.showMyDialog(context); + model.endCall(patient.vcId, sessionStatusModel.sessionStatus == 3,).then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); + } + setState(() { + isCallFinished = true; + }); + }); + + }); + }); + } + } }, ), diff --git a/lib/widgets/patients/profile/GeneralLabResultHeader.dart b/lib/widgets/patients/profile/GeneralLabResultHeader.dart new file mode 100644 index 00000000..5f22459a --- /dev/null +++ b/lib/widgets/patients/profile/GeneralLabResultHeader.dart @@ -0,0 +1,347 @@ +import 'package:doctor_app_flutter/config/config.dart'; +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/icons_app/doctor_app_icons.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'; +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'; +import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class GeneralLabResultHeader extends StatelessWidget + with PreferredSizeWidget { + final PatiantInformtion patient; + final String patientType; + final String arrivalType; + final String doctorName; + final String branch; + final DateTime appointmentDate; + final String profileUrl; + final String invoiceNO; + final String orderNo; + final bool isPrescriptions; + final bool isMedicalFile; + final String episode; + final String vistDate; + + final String clinic; + GeneralLabResultHeader( + {this.patient, + this.patientType, + this.arrivalType, + this.doctorName, + this.branch, + this.appointmentDate, + this.profileUrl, + this.invoiceNO, + this.orderNo, + this.isPrescriptions = false, + this.clinic, + this.isMedicalFile = false, + this.episode, + this.vistDate}); + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + int gender = 1; + if (patient.patientDetails != null) { + gender = patient.patientDetails.gender; + } else { + gender = patient.gender; + } + + return Container( + padding: EdgeInsets.only(left: 0, right: 5, bottom: 5, top: 5), + decoration: BoxDecoration( + color: Colors.white, + ), + height: MediaQuery.of(context).size.height * 0.23, + child: Container( + padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), + margin: EdgeInsets.only(top: 50), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + 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( + patient.firstName != null + ? (Helpers.capitalize(patient.firstName) + + " " + + Helpers.capitalize(patient.lastName)) + : Helpers.capitalize(patient.fullName??patient?.patientDetails?.fullName??""), + fontSize: SizeConfig.textMultiplier * 2.2, + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + ), + ), + gender == 1 + ? Icon( + DoctorApp.male_2, + color: Colors.blue, + ) + : Icon( + DoctorApp.female_1, + color: Colors.pink, + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 4), + child: InkWell( + onTap: () { + launch("tel://" + patient?.mobileNumber??""); + }, + child: Icon( + Icons.phone, + color: Colors.black87, + ), + ), + ) + ]), + ), + Row(children: [ + Padding( + padding: EdgeInsets.only(left: 12.0), + child: Container( + width: 60, + height: 60, + child: Image.asset( + gender == 1 + ? 'assets/images/male_avatar.png' + : 'assets/images/female_avatar.png', + fit: BoxFit.cover, + ), + ), + ), + SizedBox( + width: 10, + ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SERVICES_PATIANT2[int.parse(patientType)] == + "patientArrivalList" + ? Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + patient.patientStatusType == 43 + ? AppText( + TranslationBase.of(context).arrivedP, + color: Colors.green, + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + fontSize: 12, + ) + : AppText( + TranslationBase.of(context).notArrived, + color: Colors.red[800], + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + fontSize: 12, + ), + arrivalType == '1' || patient.arrivedOn == null + ? AppText( + patient.startTime != null + ? patient.startTime + : '', + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + ) + : AppText( + AppDateUtils.convertStringToDateFormat( + patient.arrivedOn, + 'MM-dd-yyyy HH:mm'), + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + ) + ], + )) + : SizedBox(), + if (SERVICES_PATIANT2[int.parse(patientType)] == + "List_MyOutPatient") + Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).appointmentDate + + " : ", + fontSize: 14, + ), + patient.startTime != null + ? Container( + height: 15, + width: 60, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(25), + color: HexColor("#20A169"), + ), + child: AppText( + patient.startTime ?? "", + color: Colors.white, + fontSize: 1.5 * SizeConfig.textMultiplier, + textAlign: TextAlign.center, + fontWeight: FontWeight.bold, + ), + ) + : SizedBox(), + SizedBox( + width: 3.5, + ), + Container( + child: AppText( + convertDateFormat2( + patient.appointmentDate.toString() ?? ''), + fontSize: 1.5 * SizeConfig.textMultiplier, + fontWeight: FontWeight.bold, + ), + ), + SizedBox( + height: 0.5, + ) + ], + ), + margin: EdgeInsets.only( + top: 8, + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + RichText( + text: TextSpan( + style: TextStyle( + fontSize: 1.6 * SizeConfig.textMultiplier, + color: Colors.black), + children: [ + new TextSpan( + text: TranslationBase.of(context).fileNumber, + style: TextStyle( + fontSize: 12, fontFamily: 'Poppins')), + new TextSpan( + text: patient?.patientId?.toString() ?? "", + style: TextStyle( + fontWeight: FontWeight.w700, + fontFamily: 'Poppins', + fontSize: 14)), + ], + ), + ), + Row( + children: [ + AppText( + patient.nationalityName ?? + patient.nationality ?? + "", + fontWeight: FontWeight.bold, + fontSize: 12, + ), + patient.nationality != null + ? ClipRRect( + borderRadius: BorderRadius.circular(20.0), + child: Image.network( + patient?.nationalityFlagURL??"", + height: 25, + width: 30, + errorBuilder: (BuildContext context, + Object exception, + StackTrace stackTrace) { + return Text('No Image'); + }, + )) + : SizedBox() + ], + ) + ], + ), + Container( + child: RichText( + text: new TextSpan( + style: new TextStyle( + fontSize: 1.6 * SizeConfig.textMultiplier, + color: Colors.black, + fontFamily: 'Poppins', + ), + children: [ + 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)}", + style: TextStyle( + fontWeight: FontWeight.w700, fontSize: 14)), + ], + ), + ), + ), + Container( + child: RichText( + text: new TextSpan( + style: new TextStyle( + fontSize: 1.6 * SizeConfig.textMultiplier, + color: Colors.black, + fontFamily: 'Poppins', + ), + children: [ + new TextSpan( + text: "Result Date: ", + style: TextStyle(fontSize: 14)), + new TextSpan( + text: + '${AppDateUtils.getDayMonthYearDateFormatted(appointmentDate, isArabic: projectViewModel.isArabic)}', + style: TextStyle( + fontWeight: FontWeight.w700, fontSize: 14)), + ], + ), + ), + ), + ], + ), + ), + ]), + ], + ), + ), + ); + } + + convertDateFormat2(String str) { + String newDate = ""; + const start = "/Date("; + const end = "+0300)"; + + if (str.isNotEmpty) { + 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))); + newDate = date.year.toString() + + "/" + + date.month.toString().padLeft(2, '0') + + "/" + + date.day.toString().padLeft(2, '0'); + } + + return newDate.toString(); + } + + + + @override + Size get preferredSize => Size(double.maxFinite, 310); +} From cb5abfb2ec4a68f079bfefdaebb1395f040d80c7 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 9 Jun 2021 16:10:24 +0300 Subject: [PATCH 16/72] remove comment code --- .../profile/lab_result/laboratory_result_page.dart | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart index 91e5145f..c7a98924 100644 --- a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart +++ b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart @@ -51,19 +51,6 @@ class _LaboratoryResultPageState extends State { invoiceNO: widget.patientLabOrders.invoiceNo, ), - - // PatientProfileHeaderWhitAppointmentAppBar( - // patient: widget.patient, - // patientType: widget.patientType ?? "0", - // arrivalType: widget.arrivalType ?? "0", - // orderNo: widget.patientLabOrders.orderNo, - // appointmentDate: widget.patientLabOrders.orderDate, - // doctorName: widget.patientLabOrders.doctorName, - // branch: widget.patientLabOrders.projectName, - // clinic: widget.patientLabOrders.clinicDescription, - // profileUrl: widget.patientLabOrders.doctorImageURL, - // invoiceNO: widget.patientLabOrders.invoiceNo, - // ), baseViewModel: model, body: AppScaffold( isShowAppBar: false, From 4cdc654348df8b084ba8877e658dbf3b5b67cdbe Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 9 Jun 2021 16:50:35 +0300 Subject: [PATCH 17/72] fix font size in header --- lib/widgets/patients/profile/GeneralLabResultHeader.dart | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/widgets/patients/profile/GeneralLabResultHeader.dart b/lib/widgets/patients/profile/GeneralLabResultHeader.dart index 5f22459a..153a4ccf 100644 --- a/lib/widgets/patients/profile/GeneralLabResultHeader.dart +++ b/lib/widgets/patients/profile/GeneralLabResultHeader.dart @@ -224,13 +224,15 @@ class GeneralLabResultHeader extends StatelessWidget RichText( text: TextSpan( style: TextStyle( - fontSize: 1.6 * SizeConfig.textMultiplier, - color: Colors.black), + fontSize: 1.6 * SizeConfig.textMultiplier, + color: Colors.black, + fontFamily: 'Poppins', + ), children: [ new TextSpan( text: TranslationBase.of(context).fileNumber, style: TextStyle( - fontSize: 12, fontFamily: 'Poppins')), + fontSize: 14, fontFamily: 'Poppins')), new TextSpan( text: patient?.patientId?.toString() ?? "", style: TextStyle( From 10441e4af08fc3797376e1879d2f18fceacf3d0a Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 9 Jun 2021 17:10:39 +0300 Subject: [PATCH 18/72] referral changes --- lib/config/config.dart | 2 +- lib/config/localized_values.dart | 2 + .../referral/MyReferralPatientModel.dart | 7 +- .../patient/MyReferralPatientService.dart | 2 +- .../referral/AddReplayOnReferralPatient.dart | 131 ++++---- .../ReplySummeryOnReferralPatient.dart | 119 ++++++++ .../my-referral-inpatient-screen.dart | 1 - .../referral_patient_detail_in-paint.dart | 279 +++++++++++------- lib/util/translations_delegate_base.dart | 2 + .../patient-referral-item-widget.dart | 16 +- 10 files changed, 385 insertions(+), 176 deletions(-) create mode 100644 lib/screens/patients/profile/referral/ReplySummeryOnReferralPatient.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index e2f9eb6a..eb946dea 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -181,7 +181,7 @@ const GET_ECG = "Services/Patients.svc/REST/HIS_GetPatientMuseResults"; const GET_MY_REFERRAL_INPATIENT = "Services/DoctorApplication.svc/REST/GtMyReferralPatient"; -const GET_MY_REFERRAL_OUTPATIENT = "Services/DoctorApplication.svc/REST/GtMyReferralForOutPatient"; +const GET_MY_REFERRAL_OUT_PATIENT = "Services/DoctorApplication.svc/REST/GtMyReferralForOutPatient"; const GET_MY_DISCHARGE_PATIENT = "Services/DoctorApplication.svc/REST/GtMyDischargeReferralPatient"; const GET_DISCHARGE_PATIENT = "Services/DoctorApplication.svc/REST/GtMyDischargePatient"; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 11f31ba6..4d0436aa 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1008,4 +1008,6 @@ const Map> localizedValues = { "allLab": {"en": "All Lab", "ar": "جميع المختبرات"}, "allPrescription": {"en": "All Prescription", "ar": "جميع الوصفات"}, "addPrescription": {"en": "Add prescription", "ar": "إضافة الوصفات"}, + "edit": {"en": "Edit", "ar": "تعديل"}, + "summeryReply": {"en": "Summary Reply", "ar": "موجز الرد"}, }; diff --git a/lib/core/model/referral/MyReferralPatientModel.dart b/lib/core/model/referral/MyReferralPatientModel.dart index 7aa375b8..ebf12857 100644 --- a/lib/core/model/referral/MyReferralPatientModel.dart +++ b/lib/core/model/referral/MyReferralPatientModel.dart @@ -159,7 +159,12 @@ class MyReferralPatientModel { referralClinic = json['ReferralClinic']; referringClinic = json['ReferringClinic']; referralStatus = json["ReferralStatus"] is String ?json['ReferralStatus']== "Accepted"?46:json['ReferralStatus']=="Pending"?1:0: json["ReferralStatus"]; - referralDate = AppDateUtils.getDateTimeFromString(json['ReferralDate']); + try { + referralDate = AppDateUtils.getDateTimeFromString(json['ReferralDate']); + } catch (e){ + referralDate = AppDateUtils.convertStringToDate(json['ReferralDate']); + } + referringDoctorRemarks = json['ReferringDoctorRemarks']; referredDoctorRemarks = json['ReferredDoctorRemarks']; referralResponseOn = json['ReferralResponseOn']; diff --git a/lib/core/service/patient/MyReferralPatientService.dart b/lib/core/service/patient/MyReferralPatientService.dart index 9f29c4dc..39a75e8f 100644 --- a/lib/core/service/patient/MyReferralPatientService.dart +++ b/lib/core/service/patient/MyReferralPatientService.dart @@ -63,7 +63,7 @@ class MyReferralInPatientService extends BaseService { patientTypeID: 1); myReferralPatients.clear(); await baseAppClient.post( - GET_MY_REFERRAL_OUTPATIENT, + GET_MY_REFERRAL_OUT_PATIENT, onSuccess: (dynamic response, int statusCode) { if (response['List_MyOutPatientReferral'] != null) { response['List_MyOutPatientReferral'].forEach((v) { diff --git a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart index f54a18ac..df941a5d 100644 --- a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart +++ b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart @@ -14,17 +14,24 @@ import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dar import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/shared/speech-text-popup.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; +import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:speech_to_text/speech_recognition_error.dart'; import 'package:speech_to_text/speech_to_text.dart' as stt; +import 'ReplySummeryOnReferralPatient.dart'; + class AddReplayOnReferralPatient extends StatefulWidget { final PatientReferralViewModel patientReferralViewModel; final MyReferralPatientModel myReferralInPatientModel; + final bool isEdited; const AddReplayOnReferralPatient( - {Key key, this.patientReferralViewModel, this.myReferralInPatientModel}) + {Key key, + this.patientReferralViewModel, + this.myReferralInPatientModel, + this.isEdited}) : super(key: key); @override @@ -39,10 +46,13 @@ class _AddReplayOnReferralPatientState var reconizedWord; var event = RobotProvider(); TextEditingController replayOnReferralController = TextEditingController(); + @override void initState() { requestPermissions(); super.initState(); + replayOnReferralController.text = widget.myReferralInPatientModel.referredDoctorRemarks?? ""; + } @override @@ -51,11 +61,9 @@ class _AddReplayOnReferralPatientState isShowAppBar: false, backgroundColor: Theme.of(context).scaffoldBackgroundColor, body: SingleChildScrollView( - child: Container( - height: MediaQuery.of(context).size.height * 1.0, - child: Padding( - padding: EdgeInsets.all(0.0), - child: Column( + child: Column( + children: [ + Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ BottomSheetTitle(title: 'Replay'), @@ -103,61 +111,70 @@ class _AddReplayOnReferralPatientState ), ], ), - ), - ), - ), - bottomSheet: Container( - height: replayOnReferralController.text.isNotEmpty ? 130 : 70, - margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), - child: Column( - children: [ - replayOnReferralController.text.isEmpty - ? SizedBox() - : Container( + Container( + height: replayOnReferralController.text.isNotEmpty ? 130 : 70, + margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), + child: Column( + children: [ + replayOnReferralController.text.isEmpty + ? SizedBox() + : Container( margin: EdgeInsets.all(5), child: Expanded( child: AppButton( - title: TranslationBase.of(context).clearText, - onPressed: () { - setState(() { - replayOnReferralController.text = ''; - }); - }, - )), + title: TranslationBase.of(context).clearText, + onPressed: () { + setState(() { + replayOnReferralController.text = ''; + }); + }, + )), ), - Container( - margin: EdgeInsets.all(5), - child: AppButton( - title: 'Submit Replay', - 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 Replay Added Successfully"); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - } - } else { - Helpers.showErrorToast("You can't add empty replay"); - setState(() { - isSubmitted = false; - }); - } - })), + Container( + margin: EdgeInsets.all(5), + child: AppButton( + title: 'Submit Replay', + 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 Replay 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 replay"); + setState(() { + isSubmitted = false; + }); + } + })), + ], + ), + ), ], ), ), diff --git a/lib/screens/patients/profile/referral/ReplySummeryOnReferralPatient.dart b/lib/screens/patients/profile/referral/ReplySummeryOnReferralPatient.dart new file mode 100644 index 00000000..2a48e079 --- /dev/null +++ b/lib/screens/patients/profile/referral/ReplySummeryOnReferralPatient.dart @@ -0,0 +1,119 @@ +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/viewModel/patient-referral-viewmodel.dart'; +import 'package:doctor_app_flutter/icons_app/doctor_app_icons.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'; +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/app_texts_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; +import 'package:flutter/material.dart'; + +import '../../../../routes.dart'; + +class ReplySummeryOnReferralPatient extends StatefulWidget { + final MyReferralPatientModel referredPatient; + final String doctorReply; + + ReplySummeryOnReferralPatient(this.referredPatient, this.doctorReply); + + @override + _ReplySummeryOnReferralPatientState createState() => + _ReplySummeryOnReferralPatientState(this.referredPatient); +} + +class _ReplySummeryOnReferralPatientState + extends State { + final MyReferralPatientModel referredPatient; + + _ReplySummeryOnReferralPatientState(this.referredPatient); + + @override + Widget build(BuildContext context) { + return BaseView( + builder: (_, model, w) => AppScaffold( + baseViewModel: model, + isShowAppBar: true, + appBarTitle: TranslationBase.of(context).summeryReply, + body: Container( + child: Column( + children: [ + + Expanded( + child: SingleChildScrollView( + child: Container( + width: double.infinity, + margin: + EdgeInsets.symmetric(horizontal: 16, vertical: 16), + padding: EdgeInsets.symmetric( + horizontal: 16, vertical: 16), + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all(Radius.circular(8)), + border: Border.fromBorderSide(BorderSide( + color: Colors.white, + width: 1.0, + )), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).reply, + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 2.4 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + AppText( + widget.doctorReply ?? '', + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + fontSize: 1.8 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + SizedBox( + height: 8, + ), + ], + ), + ), + ), + ), + Container( + margin: + EdgeInsets.symmetric(horizontal: 16, vertical: 16), + child: Row( + children: [ + Expanded( + child: AppButton( + onPressed: () { + Navigator.of(context).pop(); + }, + title: TranslationBase.of(context).cancel, + fontColor: Colors.white, + color: Colors.red[600], + ), + ), + SizedBox(width: 4,), + Expanded( + child: AppButton( + onPressed: () {}, + title: TranslationBase.of(context).noteConfirm, + fontColor: Colors.white, + color: Colors.green[600], + ), + ), + ], + ), + ), + ], + ), + ), + )); + } +} 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 9813286e..636a596f 100644 --- a/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart @@ -64,7 +64,6 @@ class MyReferralInPatientScreen extends StatelessWidget { ) : SingleChildScrollView( child: Container( - margin: EdgeInsets.only(top: 70), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ 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 0e7b214b..e2175bae 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 @@ -19,6 +19,7 @@ import 'AddReplayOnReferralPatient.dart'; class ReferralPatientDetailScreen extends StatelessWidget { final MyReferralPatientModel referredPatient; final PatientReferralViewModel patientReferralViewModel; + ReferralPatientDetailScreen( this.referredPatient, this.patientReferralViewModel); @@ -214,30 +215,6 @@ class ReferralPatientDetailScreen extends StatelessWidget { Expanded( child: Column( children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - AppText( - "${TranslationBase.of(context).refClinic}: ", - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - fontSize: 1.7 * - SizeConfig.textMultiplier, - color: Color(0XFF575757), - ), - AppText( - referredPatient - .referringClinicDescription, - fontFamily: 'Poppins', - fontWeight: FontWeight.w700, - fontSize: 1.8 * - SizeConfig.textMultiplier, - color: Color(0XFF2E303A), - ), - ], - ), - if(referredPatient.frequency != null) Row( mainAxisAlignment: MainAxisAlignment.start, @@ -245,9 +222,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { CrossAxisAlignment.start, children: [ AppText( - TranslationBase.of(context) - .frequency + - ": ", + "${TranslationBase.of(context).refClinic}: ", fontFamily: 'Poppins', fontWeight: FontWeight.w600, fontSize: 1.7 * @@ -257,7 +232,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { Expanded( child: AppText( referredPatient - .frequencyDescription??'', + .referringClinicDescription, fontFamily: 'Poppins', fontWeight: FontWeight.w700, fontSize: 1.8 * @@ -267,6 +242,38 @@ class ReferralPatientDetailScreen extends StatelessWidget { ), ], ), + if (referredPatient.frequency != 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 ?? + '', + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 1.8 * + SizeConfig + .textMultiplier, + color: Color(0XFF2E303A), + ), + ), + ], + ), ], ), ), @@ -304,59 +311,69 @@ class ReferralPatientDetailScreen 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), - ), - Expanded( - child: AppText( - referredPatient.priorityDescription??'', + 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, - color: Color(0XFF2E303A), + 1.7 * SizeConfig.textMultiplier, + color: Color(0XFF575757), ), - ), - ], - ), - 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"):'', + Expanded( + child: AppText( + referredPatient.priorityDescription ?? + '', + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: + 1.8 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + ), + ], + ), + if (referredPatient.mAXResponseTime != null) + Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context) + .maxResponseTime + + ": ", fontFamily: 'Poppins', - fontWeight: FontWeight.w700, + fontWeight: FontWeight.w600, fontSize: - 1.8 * SizeConfig.textMultiplier, - color: Color(0XFF2E303A), + 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: [ @@ -448,48 +465,93 @@ class ReferralPatientDetailScreen extends StatelessWidget { ), Expanded( child: SingleChildScrollView( - child: Container( - width: double.infinity, - margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), - padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16), - decoration: BoxDecoration( - color: Colors.white, - shape: BoxShape.rectangle, - borderRadius: BorderRadius.all(Radius.circular(8)), - border: Border.fromBorderSide(BorderSide( - color: Colors.white, - width: 1.0, - )), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).remarks, - fontFamily: 'Poppins', - fontWeight: FontWeight.w700, - fontSize: 2.4 * SizeConfig.textMultiplier, - color: Color(0XFF2E303A), + child: Column( + children: [ + Container( + width: double.infinity, + margin: + EdgeInsets.symmetric(horizontal: 16, vertical: 16), + padding: + EdgeInsets.symmetric(horizontal: 16, vertical: 16), + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all(Radius.circular(8)), + border: Border.fromBorderSide(BorderSide( + color: Colors.white, + width: 1.0, + )), ), - AppText( - referredPatient.referringDoctorRemarks??'', - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - fontSize: 1.8 * SizeConfig.textMultiplier, - color: Color(0XFF2E303A), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).remarks, + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 2.4 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + AppText( + referredPatient.referringDoctorRemarks ?? '', + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + fontSize: 1.8 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + SizedBox( + height: 8, + ), + ], ), - SizedBox( - height: 8, + ), + if (referredPatient.referredDoctorRemarks.isNotEmpty) + Container( + width: double.infinity, + margin: + EdgeInsets.symmetric(horizontal: 16, vertical: 0), + padding: EdgeInsets.symmetric( + horizontal: 16, vertical: 16), + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all(Radius.circular(8)), + border: Border.fromBorderSide(BorderSide( + color: Colors.white, + width: 1.0, + )), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).reply, + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 2.4 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + AppText( + referredPatient.referredDoctorRemarks ?? '', + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + fontSize: 1.8 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + SizedBox( + height: 8, + ), + ], + ), ), - ], - ), + ], ), ), ), Container( margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), child: AppButton( - title: TranslationBase.of(context).replay, + title: referredPatient.referredDoctorRemarks.isEmpty ? TranslationBase.of(context).replay : TranslationBase.of(context).edit, color: Colors.red[700], fontColor: Colors.white, fontWeight: FontWeight.w700, @@ -503,6 +565,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { widget: AddReplayOnReferralPatient( patientReferralViewModel: patientReferralViewModel, myReferralInPatientModel: referredPatient, + isEdited: referredPatient.referredDoctorRemarks.isNotEmpty, ), ), ); diff --git a/lib/util/translations_delegate_base.dart b/lib/util/translations_delegate_base.dart index 16ae07bd..165a9bb5 100644 --- a/lib/util/translations_delegate_base.dart +++ b/lib/util/translations_delegate_base.dart @@ -1363,6 +1363,8 @@ class TranslationBase { String get allLab => localizedValues['allLab'][locale.languageCode]; String get allPrescription => localizedValues['allPrescription'][locale.languageCode]; String get addPrescription => localizedValues['addPrescription'][locale.languageCode]; + String get edit => localizedValues['edit'][locale.languageCode]; + String get summeryReply => localizedValues['summeryReply'][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { diff --git a/lib/widgets/patients/patient-referral-item-widget.dart b/lib/widgets/patients/patient-referral-item-widget.dart index 6e581954..02b2d241 100644 --- a/lib/widgets/patients/patient-referral-item-widget.dart +++ b/lib/widgets/patients/patient-referral-item-widget.dart @@ -155,6 +155,7 @@ class PatientReferralItemWidget extends StatelessWidget { ), Row( mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( isSameBranch ? TranslationBase.of(context).referredFrom :TranslationBase.of(context).refClinic, @@ -163,13 +164,14 @@ class PatientReferralItemWidget extends StatelessWidget { fontSize: 1.7 * SizeConfig.textMultiplier, color: Color(0XFF575757), ), - - AppText( - !isReferralClinic? isSameBranch ? TranslationBase.of(context).sameBranch : TranslationBase.of(context).otherBranch: " "+referralClinic, - fontFamily: 'Poppins', - fontWeight: FontWeight.w700, - fontSize: 1.8 * SizeConfig.textMultiplier, - color: Color(0XFF2E303A), + Expanded( + child: AppText( + !isReferralClinic? isSameBranch ? TranslationBase.of(context).sameBranch : TranslationBase.of(context).otherBranch: " "+referralClinic, + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 1.8 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), ), ], ), From 23feb2c354d304fbaa659c6e05a4fcd63baa8b98 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 9 Jun 2021 17:11:52 +0300 Subject: [PATCH 19/72] remove unused code --- .../vital_sign/vital-signs-screen.dart | 1074 ----------------- .../prescription/prescription_screen.dart | 591 --------- .../prescription_screen_history.dart | 516 -------- .../profile/patient-page-header-widget.dart | 114 -- 4 files changed, 2295 deletions(-) delete mode 100644 lib/screens/patients/profile/vital_sign/vital-signs-screen.dart delete mode 100644 lib/screens/prescription/prescription_screen.dart delete mode 100644 lib/screens/prescription/prescription_screen_history.dart delete mode 100644 lib/widgets/patients/profile/patient-page-header-widget.dart diff --git a/lib/screens/patients/profile/vital_sign/vital-signs-screen.dart b/lib/screens/patients/profile/vital_sign/vital-signs-screen.dart deleted file mode 100644 index 0bf2197b..00000000 --- a/lib/screens/patients/profile/vital_sign/vital-signs-screen.dart +++ /dev/null @@ -1,1074 +0,0 @@ -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/viewModel/patient-vital-sign-viewmodel.dart'; -import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -import 'package:doctor_app_flutter/models/patient/vital_sign/patient-vital-sign-data.dart'; -import 'package:doctor_app_flutter/screens/base/base_view.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-page-header-widget.dart'; -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/expandable-widget-header-body.dart'; -import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; - -class PatientVitalSignScreen extends StatelessWidget { - @override - Widget build(BuildContext context) { - final routeArgs = ModalRoute.of(context).settings.arguments as Map; - PatiantInformtion patient = routeArgs['patient']; - String from = routeArgs['from']; - String to = routeArgs['to']; - - return BaseView( - onModelReady: (model) => model.getPatientVitalSign(patient), - builder: (_, model, w) => AppScaffold( - baseViewModel: model, - appBarTitle: TranslationBase.of(context).vitalSign, - body: model.patientVitalSigns != null - ? SingleChildScrollView( - child: Container( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - PatientPageHeaderWidget(patient), - SizedBox( - height: 16, - ), - Container( - margin: - EdgeInsets.symmetric(horizontal: 16, vertical: 16), - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - AppText( - "${TranslationBase.of(context).weight} :", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - SizedBox( - width: 8, - ), - AppText( - "${model.patientVitalSigns.weightKg} ${TranslationBase.of(context).kg}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - Row( - children: [ - AppText( - "${TranslationBase.of(context).idealBodyWeight} :", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - SizedBox( - width: 8, - ), - AppText( - "${model.patientVitalSigns.idealBodyWeightLbs} ${TranslationBase.of(context).kg}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - ], - ), - SizedBox( - height: 4, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - AppText( - "${TranslationBase.of(context).height} :", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - SizedBox( - width: 8, - ), - AppText( - "${model.patientVitalSigns.heightCm} ${TranslationBase.of(context).cm}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - ], - ), - SizedBox( - height: 4, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - /*Row( - children: [ - AppText( - "${TranslationBase.of(context).waistSize} :", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - SizedBox( - width: 8, - ), - AppText( - "${model.patientVitalSigns.waistSizeInch} ${TranslationBase.of(context).inch}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ),*/ - Row( - children: [ - AppText( - "${TranslationBase.of(context).headCircum} :", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - SizedBox( - width: 8, - ), - AppText( - "${model.patientVitalSigns.headCircumCm} ${TranslationBase.of(context).cm}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - ], - ), - SizedBox( - height: 16, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - AppText( - "${TranslationBase.of(context).leanBodyWeight} :", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - SizedBox( - width: 8, - ), - AppText( - "${model.patientVitalSigns.leanBodyWeightLbs} ${TranslationBase.of(context).kg}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - ], - ), - SizedBox( - height: 4, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - AppText( - "${TranslationBase.of(context).bodyMassIndex} :", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - SizedBox( - width: 8, - ), - AppText( - "${model.patientVitalSigns.bodyMassIndex}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - SizedBox( - width: 8, - ), - Container( - color: Colors.green, - child: Padding( - padding: EdgeInsets.symmetric( - vertical: 2, horizontal: 8), - child: AppText( - "${model.getBMI(model.patientVitalSigns.bodyMassIndex)}", - fontSize: - SizeConfig.textMultiplier * 2, - color: Colors.white, - fontWeight: FontWeight.bold, - ), - ), - ) - ], - ), - ], - ), - SizedBox( - height: 4, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - AppText( - "G.C.S :", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - SizedBox( - width: 8, - ), - AppText( - "N/A", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - ], - ), - SizedBox( - height: 16, - ), - const Divider( - color: Color(0xffCCCCCC), - height: 1, - thickness: 2, - indent: 0, - endIndent: 0, - ), - SizedBox( - height: 16, - ), - TemperatureWidget(model, model.patientVitalSigns), - SizedBox( - height: 16, - ), - const Divider( - color: Color(0xffCCCCCC), - height: 1, - thickness: 2, - indent: 0, - endIndent: 0, - ), - SizedBox( - height: 16, - ), - PulseWidget(model.patientVitalSigns), - SizedBox( - height: 16, - ), - const Divider( - color: Color(0xffCCCCCC), - height: 1, - thickness: 2, - indent: 0, - endIndent: 0, - ), - SizedBox( - height: 16, - ), - RespirationWidget(model.patientVitalSigns), - SizedBox( - height: 16, - ), - const Divider( - color: Color(0xffCCCCCC), - height: 1, - thickness: 2, - indent: 0, - endIndent: 0, - ), - SizedBox( - height: 16, - ), - BloodPressureWidget(model.patientVitalSigns), - SizedBox( - height: 16, - ), - const Divider( - color: Color(0xffCCCCCC), - height: 1, - thickness: 2, - indent: 0, - endIndent: 0, - ), - SizedBox( - height: 16, - ), - OxygenationWidget(model.patientVitalSigns), - SizedBox( - height: 16, - ), - const Divider( - color: Color(0xffCCCCCC), - height: 1, - thickness: 2, - indent: 0, - endIndent: 0, - ), - SizedBox( - height: 16, - ), - PainScaleWidget(model.patientVitalSigns), - SizedBox( - height: 16, - ), - const Divider( - color: Color(0xffCCCCCC), - height: 1, - thickness: 2, - indent: 0, - endIndent: 0, - ), - SizedBox( - height: 16, - ), - ], - ), - ) - ], - ), - ), - ) - : Center( - child: AppText( - "${TranslationBase.of(context).vitalSignEmptyMsg}", - fontSize: SizeConfig.textMultiplier * 2.5, - color: HexColor("#B8382B"), - fontWeight: FontWeight.normal, - ), - ), - ), - ); - } -} - -class TemperatureWidget extends StatefulWidget { - final VitalSignsViewModel model; - final VitalSignData vitalSign; - - TemperatureWidget(this.model, this.vitalSign); - - @override - _TemperatureWidgetState createState() => _TemperatureWidgetState(); -} - -class _TemperatureWidgetState extends State { - bool isExpand = false; - - @override - Widget build(BuildContext context) { - return Container( - child: HeaderBodyExpandableNotifier( - headerWidget: Container( - margin: EdgeInsets.symmetric(vertical: 16.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - "${TranslationBase.of(context).temperature}", - fontSize: SizeConfig.textMultiplier * 2.5, - color: Colors.black, - fontWeight: isExpand ? FontWeight.bold : FontWeight.normal, - ), - InkWell( - onTap: () { - setState(() { - isExpand = !isExpand; - }); - }, - child: Icon(isExpand ? Icons.remove : Icons.add), - ), - ], - ), - ), - bodyWidget: Container( - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: AppText( - "${TranslationBase.of(context).temperature} (C):", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - ), - SizedBox( - width: 8, - ), - Expanded( - child: AppText( - "${widget.vitalSign.temperatureCelcius}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ), - ], - ), - ), - Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: AppText( - "${TranslationBase.of(context).temperature} (F):", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - ), - SizedBox( - width: 8, - ), - Expanded( - child: AppText( - "${widget.vitalSign.temperatureCelcius * (9 / 5) + 32}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ), - ], - ), - ), - ], - ), - SizedBox( - height: 4, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - AppText( - "${TranslationBase.of(context).method} :", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - SizedBox( - width: 8, - ), - AppText( - "${widget.model.getTempratureMethod(widget.vitalSign.temperatureCelciusMethod)}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - ], - ), - ], - ), - ), - isExpand: isExpand, - ), - ); - } -} - -class PulseWidget extends StatefulWidget { - final VitalSignData vitalSign; - - PulseWidget(this.vitalSign); - - @override - _PulseWidgetState createState() => _PulseWidgetState(); -} - -class _PulseWidgetState extends State { - bool isExpand = false; - - @override - Widget build(BuildContext context) { - return Container( - child: HeaderBodyExpandableNotifier( - headerWidget: Container( - margin: EdgeInsets.symmetric(vertical: 16.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - "${TranslationBase.of(context).pulse}", - fontSize: SizeConfig.textMultiplier * 2.5, - color: Colors.black, - fontWeight: isExpand ? FontWeight.bold : FontWeight.normal, - ), - InkWell( - onTap: () { - setState(() { - isExpand = !isExpand; - }); - }, - child: Icon(isExpand ? Icons.remove : Icons.add), - ), - ], - ), - ), - bodyWidget: Container( - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: AppText( - "${TranslationBase.of(context).pulseBeats}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - ), - SizedBox( - width: 8, - ), - Expanded( - child: AppText( - "${widget.vitalSign.pulseBeatPerMinute}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ), - ], - ), - ), - Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: AppText( - "${TranslationBase.of(context).rhythm}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - ), - SizedBox( - width: 8, - ), - Expanded( - child: AppText( - "${widget.vitalSign.pulseRhythm}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ), - ], - ), - ), - ], - ), - ], - ), - ), - isExpand: isExpand, - ), - ); - } -} - -class RespirationWidget extends StatefulWidget { - final VitalSignData vitalSign; - - RespirationWidget(this.vitalSign); - - @override - _RespirationWidgetState createState() => _RespirationWidgetState(); -} - -class _RespirationWidgetState extends State { - bool isExpand = false; - - @override - Widget build(BuildContext context) { - return Container( - child: HeaderBodyExpandableNotifier( - headerWidget: Container( - margin: EdgeInsets.symmetric(vertical: 16.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - "${TranslationBase.of(context).respiration}", - fontSize: SizeConfig.textMultiplier * 2.5, - color: Colors.black, - fontWeight: isExpand ? FontWeight.bold : FontWeight.normal, - ), - InkWell( - onTap: () { - setState(() { - isExpand = !isExpand; - }); - }, - child: Icon(isExpand ? Icons.remove : Icons.add), - ), - ], - ), - ), - bodyWidget: Container( - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: AppText( - "${TranslationBase.of(context).respBeats}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - ), - SizedBox( - width: 8, - ), - Expanded( - child: AppText( - "${widget.vitalSign.respirationBeatPerMinute}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ), - ], - ), - ), - Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: AppText( - "${TranslationBase.of(context).patternOfRespiration}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - ), - SizedBox( - width: 8, - ), - Expanded( - child: AppText( - "${widget.vitalSign.respirationPattern}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ), - ], - ), - ), - ], - ), - ], - ), - ), - isExpand: isExpand, - ), - ); - } -} - -class BloodPressureWidget extends StatefulWidget { - final VitalSignData vitalSign; - - BloodPressureWidget(this.vitalSign); - - @override - _BloodPressureWidgetState createState() => _BloodPressureWidgetState(); -} - -class _BloodPressureWidgetState extends State { - bool isExpand = false; - - @override - Widget build(BuildContext context) { - return Container( - child: HeaderBodyExpandableNotifier( - headerWidget: Container( - margin: EdgeInsets.symmetric(vertical: 16.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - "${TranslationBase.of(context).bloodPressure}", - fontSize: SizeConfig.textMultiplier * 2.5, - color: Colors.black, - fontWeight: isExpand ? FontWeight.bold : FontWeight.normal, - ), - InkWell( - onTap: () { - setState(() { - isExpand = !isExpand; - }); - }, - child: Icon(isExpand ? Icons.remove : Icons.add), - ), - ], - ), - ), - bodyWidget: Container( - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: AppText( - "${TranslationBase.of(context).bloodPressureDiastoleAndSystole}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - ), - SizedBox( - width: 8, - ), - Expanded( - child: AppText( - "${widget.vitalSign.bloodPressureHigher}, ${widget.vitalSign.bloodPressureLower}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ), - ], - ), - ), - Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: AppText( - "${TranslationBase.of(context).cuffLocation}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - ), - SizedBox( - width: 8, - ), - Expanded( - child: AppText( - "${widget.vitalSign.bloodPressureCuffLocation}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ), - ], - ), - ), - ], - ), - SizedBox( - height: 4, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: AppText( - "${TranslationBase.of(context).patientPosition}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - ), - SizedBox( - width: 8, - ), - Expanded( - child: AppText( - "${widget.vitalSign.bloodPressurePatientPosition}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ), - ], - ), - ), - Expanded( - child: Row( - children: [ - AppText( - "${TranslationBase.of(context).cuffSize}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - SizedBox( - width: 8, - ), - AppText( - "${widget.vitalSign.bloodPressureCuffSize}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - ), - ], - ), - ], - ), - ), - isExpand: isExpand, - ), - ); - } -} - -class OxygenationWidget extends StatefulWidget { - final VitalSignData vitalSign; - - OxygenationWidget(this.vitalSign); - - @override - _OxygenationWidgetState createState() => _OxygenationWidgetState(); -} - -class _OxygenationWidgetState extends State { - bool isExpand = false; - - @override - Widget build(BuildContext context) { - return Container( - child: HeaderBodyExpandableNotifier( - headerWidget: Container( - margin: EdgeInsets.symmetric(vertical: 16.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - "${TranslationBase.of(context).oxygenation}", - fontSize: SizeConfig.textMultiplier * 2.5, - color: Colors.black, - fontWeight: isExpand ? FontWeight.bold : FontWeight.normal, - ), - InkWell( - onTap: () { - setState(() { - isExpand = !isExpand; - }); - }, - child: Icon(isExpand ? Icons.remove : Icons.add), - ), - ], - ), - ), - bodyWidget: Container( - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - AppText( - "${TranslationBase.of(context).sao2}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - SizedBox( - width: 8, - ), - AppText( - "${widget.vitalSign.sao2}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - Row( - children: [ - AppText( - "${TranslationBase.of(context).fio2}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - SizedBox( - width: 8, - ), - AppText( - "${widget.vitalSign.fio2}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - ], - ), - ], - ), - ), - isExpand: isExpand, - ), - ); - } -} - -class PainScaleWidget extends StatefulWidget { - final VitalSignData vitalSign; - - PainScaleWidget(this.vitalSign); - - @override - _PainScaleWidgetState createState() => _PainScaleWidgetState(); -} - -class _PainScaleWidgetState extends State { - bool isExpand = false; - - @override - Widget build(BuildContext context) { - return Container( - child: HeaderBodyExpandableNotifier( - headerWidget: Container( - margin: EdgeInsets.symmetric(vertical: 16.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - "${TranslationBase.of(context).painScale}", - fontSize: SizeConfig.textMultiplier * 2.5, - color: Colors.black, - fontWeight: isExpand ? FontWeight.bold : FontWeight.normal, - ), - InkWell( - onTap: () { - setState(() { - isExpand = !isExpand; - }); - }, - child: Icon(isExpand ? Icons.remove : Icons.add), - ), - ], - ), - ), - bodyWidget: Container( - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Row( - children: [ - AppText( - "${TranslationBase.of(context).painScale}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - SizedBox( - width: 8, - ), - AppText( - "${widget.vitalSign.painScore}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - ), - Expanded( - child: Row( - children: [ - AppText( - "${TranslationBase.of(context).painManagement}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - SizedBox( - width: 8, - ), - AppText( - "${widget.vitalSign.isPainManagementDone}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - ), - ], - ), - ], - ), - ), - isExpand: isExpand, - ), - ); - } -} diff --git a/lib/screens/prescription/prescription_screen.dart b/lib/screens/prescription/prescription_screen.dart deleted file mode 100644 index d5a94c61..00000000 --- a/lib/screens/prescription/prescription_screen.dart +++ /dev/null @@ -1,591 +0,0 @@ -import 'package:doctor_app_flutter/core/viewModel/prescription_view_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/prescription/add_prescription_form.dart'; -import 'package:doctor_app_flutter/screens/prescription/update_prescription_form.dart'; -import 'package:doctor_app_flutter/util/date-utils.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-page-header-widget.dart'; -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/network_base_view.dart'; -import 'package:flutter/material.dart'; - -class NewPrescriptionScreen extends StatefulWidget { - @override - _NewPrescriptionScreenState createState() => _NewPrescriptionScreenState(); -} - -class _NewPrescriptionScreenState extends State { - PersistentBottomSheetController _controller; - TextEditingController strengthController = TextEditingController(); - int testNum = 0; - int strengthChar; - PatiantInformtion patient; - - @override - void initState() { - super.initState(); - } - - Widget build(BuildContext context) { - final screenSize = MediaQuery.of(context).size; - final routeArgs = ModalRoute.of(context).settings.arguments as Map; - patient = routeArgs['patient']; - return BaseView( - onModelReady: (model) => model.getPrescription(mrn: patient.patientId), - builder: (BuildContext context, PrescriptionViewModel model, Widget child) => AppScaffold( - isShowAppBar: true, - appBarTitle: TranslationBase.of(context).prescription, - body: NetworkBaseView( - baseViewModel: model, - child: SingleChildScrollView( - child: Container( - color: Colors.white, - child: Column( - children: [ - PatientPageHeaderWidget(patient), - Divider( - height: 1.0, - thickness: 1.0, - color: Colors.grey, - ), - (model.prescriptionList.length != 0) - ? SizedBox(height: model.prescriptionList[0].rowcount == 0 ? 200.0 : 10.0) - : SizedBox(height: 200.0), - //model.prescriptionList == null - (model.prescriptionList.length != 0) - ? model.prescriptionList[0].rowcount == 0 - ? Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - InkWell( - onTap: () { - addPrescriptionForm(context, model, patient, model.prescriptionList); - //model.postPrescription(); - }, - child: CircleAvatar( - radius: 65, - backgroundColor: Color(0XFFB8382C), - child: CircleAvatar( - radius: 60, - backgroundColor: Colors.white, - child: Icon( - Icons.add, - color: Colors.black, - size: 45.0, - ), - ), - ), - ), - SizedBox( - height: 15.0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AppText( - TranslationBase.of(context).noPrescriptionListed, - color: Colors.black, - fontWeight: FontWeight.w900, - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AppText( - TranslationBase.of(context).addNow, - color: Color(0XFFB8382C), - fontWeight: FontWeight.w900, - ), - ], - ), - ], - ) - : Padding( - padding: EdgeInsets.all(14.0), - child: NetworkBaseView( - baseViewModel: model, - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - InkWell( - child: Container( - height: 50.0, - width: 450.0, - decoration: BoxDecoration( - color: Colors.white, - border: Border.all(color: Colors.grey), - borderRadius: BorderRadius.circular(10.0), - ), - child: Padding( - padding: EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - ' Add more medication', - fontWeight: FontWeight.w100, - fontSize: 12.5, - ), - Icon( - Icons.add, - color: Color(0XFFB8382C), - ) - ], - ), - ), - ), - onTap: () { - addPrescriptionForm(context, model, patient, model.prescriptionList); - //model.postPrescription(); - }, - ), - SizedBox( - height: 10.0, - ), - ...List.generate( - model.prescriptionList[0].rowcount, - (index) => Container( - color: Colors.white, - child: Column( - children: [ - SizedBox( - height: MediaQuery.of(context).size.height * 0.022, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - // crossAxisAlignment: - // CrossAxisAlignment.start, - children: [ - Container( - color: Colors.white, - height: MediaQuery.of(context).size.height * 0.21, - width: MediaQuery.of(context).size.width * 0.1, - child: Column( - children: [ - AppText( - (DateTime.parse(model.prescriptionList[0].entityList[index] - .createdOn) != - null - ? (DateTime.parse(model.prescriptionList[0] - .entityList[index].createdOn) - .year) - .toString() - : DateTime.now().year) - .toString(), - color: Colors.green, - fontSize: 13.5, - ), - AppText( - AppDateUtils.getMonth(model.prescriptionList[0] - .entityList[index].createdOn != - null - ? (DateTime.parse(model.prescriptionList[0] - .entityList[index].createdOn) - .month) - : DateTime.now().month) - .toUpperCase(), - color: Colors.green, - ), - AppText( - DateTime.parse( - model.prescriptionList[0].entityList[index].createdOn) - .day - .toString(), - color: Colors.green, - ), - AppText( - AppDateUtils.getTimeFormated(DateTime.parse(model - .prescriptionList[0].entityList[index].createdOn)) - .toString(), - color: Colors.green, - ), - ], - ), - ), - Container( - color: Colors.white, - // height: MediaQuery.of( - // context) - // .size - // .height * - // 0.3499, - width: MediaQuery.of(context).size.width * 0.77, - child: Column( - children: [ - Row( - children: [ - AppText( - 'Start Date:', - fontWeight: FontWeight.w700, - fontSize: 14.0, - ), - Expanded( - child: AppText( - AppDateUtils.getDateFormatted(DateTime.parse(model - .prescriptionList[0].entityList[index].startDate)), - fontSize: 13.5, - ), - ), - SizedBox( - width: 6.0, - ), - AppText( - 'Order Type:', - fontWeight: FontWeight.w700, - fontSize: 14.0, - ), - Expanded( - child: AppText( - model.prescriptionList[0].entityList[index] - .orderTypeDescription, - fontSize: 13.0, - ), - ), - ], - ), - SizedBox( - height: 5.5, - ), - Row( - children: [ - Container( - color: Colors.white, - child: Expanded( - child: AppText( - model.prescriptionList[0].entityList[index] - .medicationName, - fontWeight: FontWeight.w700, - fontSize: 15.0, - ), - ), - ) - ], - ), - SizedBox( - height: 5.5, - ), - Row( - children: [ - Expanded( - child: AppText( - model.prescriptionList[0].entityList[index].doseDetail, - fontSize: 15.0, - ), - ) - ], - ), - SizedBox( - height: 10.0, - ), - Row( - children: [ - AppText( - 'Indication: ', - fontWeight: FontWeight.w700, - fontSize: 17.0, - ), - Expanded( - child: RichText( - maxLines: 3, - overflow: TextOverflow.ellipsis, - strutStyle: StrutStyle(fontSize: 12.0), - text: TextSpan( - style: TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList[index] - .indication), - ), - ), - ], - ), - Row( - children: [ - AppText( - 'UOM: ', - fontWeight: FontWeight.w700, - fontSize: 17.0, - ), - Expanded( - child: RichText( - maxLines: 3, - overflow: TextOverflow.ellipsis, - strutStyle: StrutStyle(fontSize: 12.0), - text: TextSpan( - style: TextStyle(color: Colors.black), - text: model - .prescriptionList[0].entityList[index].uom), - ), - ), - ], - ), - Row( - children: [ - AppText( - 'BOX Quantity: ', - fontWeight: FontWeight.w700, - fontSize: 17.0, - ), - Expanded( - child: RichText( - maxLines: 3, - overflow: TextOverflow.ellipsis, - strutStyle: StrutStyle(fontSize: 12.0), - text: TextSpan( - style: TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList[index] - .quantity - .toString() == - null - ? "" - : model.prescriptionList[0].entityList[index] - .quantity - .toString()), - ), - ), - ], - ), - Row( - children: [ - AppText( - 'pharmacy Intervention ', - fontWeight: FontWeight.w700, - fontSize: 17.0, - ), - Expanded( - child: RichText( - maxLines: 3, - overflow: TextOverflow.ellipsis, - strutStyle: StrutStyle(fontSize: 12.0), - text: TextSpan( - style: TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList[index] - .pharmacyInervention == - null - ? "" - : model.prescriptionList[0].entityList[index] - .pharmacyInervention - .toString()), - ), - ), - ], - ), - SizedBox(height: 5.0), - Row( - children: [ - AppText( - 'pharmacist Remarks : ', - fontWeight: FontWeight.w700, - fontSize: 15.0, - ), - Expanded( - child: AppText( - model.prescriptionList[0].entityList[index] - .pharmacistRemarks == - null - ? "" - : model.prescriptionList[0].entityList[index] - .pharmacistRemarks, - fontSize: 15.0), - ) - ], - ), - SizedBox( - height: 20.0, - ), - Row( - children: [ - AppText( - TranslationBase.of(context).doctorName + ": ", - fontWeight: FontWeight.w600, - ), - Expanded( - child: AppText( - model.prescriptionList[0].entityList[index].doctorName, - fontWeight: FontWeight.w700, - ), - ) - ], - ), - SizedBox( - height: 8.0, - ), - Row( - children: [ - AppText( - 'Doctor Remarks : ', - fontWeight: FontWeight.w700, - fontSize: 13.0, - ), - Expanded( - child: Container( - color: Colors.white, - // height: MediaQuery.of(context).size.height * - // 0.038, - child: RichText( - // maxLines: - // 2, - // overflow: - // TextOverflow.ellipsis, - strutStyle: StrutStyle(fontSize: 10.0), - text: TextSpan( - style: TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList[index] - .remarks != - null - ? model.prescriptionList[0].entityList[index] - .remarks - : "", - ), - ), - ), - ), - ], - ), - SizedBox( - height: 10.0, - ), - - // SizedBox( - // height: 40, - // ), - ], - ), - ), - Container( - color: Colors.white, - height: MediaQuery.of(context).size.height * 0.16, - width: MediaQuery.of(context).size.width * 0.06, - child: Column( - children: [ - InkWell( - child: Icon(Icons.edit), - onTap: () { - updatePrescriptionForm( - box: model - .prescriptionList[0].entityList[index].quantity, - uom: model.prescriptionList[0].entityList[index].uom, - drugNameGeneric: model.prescriptionList[0] - .entityList[index].medicationName, - doseUnit: model.prescriptionList[0].entityList[index] - .doseDailyUnitID - .toString(), - doseStreangth: model.prescriptionList[0] - .entityList[index].doseDailyQuantity - .toString(), - duration: model.prescriptionList[0].entityList[index] - .doseDurationDays - .toString(), - startDate: model - .prescriptionList[0].entityList[index].startDate - .toString(), - dose: model.prescriptionList[0].entityList[index].doseTimingID - .toString(), - frequency: model - .prescriptionList[0].entityList[index].frequencyID - .toString(), - rouat: model.prescriptionList[0].entityList[index].routeID - .toString(), - patient: patient, - drugId: model.prescriptionList[0].entityList[index].medicineCode, - drugName: model.prescriptionList[0].entityList[index].medicationName, - remarks: model.prescriptionList[0].entityList[index].remarks, - model: model, - enteredRemarks: model.prescriptionList[0].entityList[index].remarks, - context: context); - //model.postPrescription(); - }, - ), - ], - ), - ), - ], - ), - Divider( - height: 0, - thickness: 1.0, - color: Colors.grey, - ), - ], - ), - ), - ), - ], - ), - ), - ) - : Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - InkWell( - onTap: () { - addPrescriptionForm(context, model, patient, model.prescriptionList); - //model.postPrescription(); - }, - child: CircleAvatar( - radius: 65, - backgroundColor: Color(0XFFB8382C), - child: CircleAvatar( - radius: 60, - backgroundColor: Colors.white, - child: Icon( - Icons.add, - color: Colors.black, - size: 45.0, - ), - ), - ), - ), - SizedBox( - height: 15.0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AppText( - TranslationBase.of(context).noPrescriptionListed, - color: Colors.black, - fontWeight: FontWeight.w900, - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AppText( - TranslationBase.of(context).addNow, - color: Color(0XFFB8382C), - fontWeight: FontWeight.w900, - ), - ], - ), - ], - ) - ], - ), - ), - ), - )), - ); - } - - selectDate(BuildContext context, PrescriptionViewModel model) async { - DateTime selectedDate; - selectedDate = DateTime.now(); - final DateTime picked = await showDatePicker( - context: context, - initialDate: selectedDate, - firstDate: DateTime.now().add(Duration(hours: 2)), - lastDate: DateTime(2040), - initialEntryMode: DatePickerEntryMode.calendar, - ); - if (picked != null && picked != selectedDate) { - setState(() { - selectedDate = picked; - }); - } - } -} diff --git a/lib/screens/prescription/prescription_screen_history.dart b/lib/screens/prescription/prescription_screen_history.dart deleted file mode 100644 index 5ce98c54..00000000 --- a/lib/screens/prescription/prescription_screen_history.dart +++ /dev/null @@ -1,516 +0,0 @@ -import 'package:doctor_app_flutter/core/viewModel/prescription_view_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/util/date-utils.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-page-header-widget.dart'; -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/network_base_view.dart'; -import 'package:flutter/material.dart'; - -class NewPrescriptionHistoryScreen extends StatefulWidget { - @override - _NewPrescriptionHistoryScreenState createState() => - _NewPrescriptionHistoryScreenState(); -} - -class _NewPrescriptionHistoryScreenState - extends State { - PersistentBottomSheetController _controller; - final _scaffoldKey = GlobalKey(); - TextEditingController strengthController = TextEditingController(); - int testNum = 0; - int strengthChar; - PatiantInformtion patient; - - @override - void initState() { - super.initState(); - } - - Widget build(BuildContext context) { - final screenSize = MediaQuery.of(context).size; - final routeArgs = ModalRoute.of(context).settings.arguments as Map; - patient = routeArgs['patient']; - return BaseView( - onModelReady: (model) => model.getPrescription(mrn: patient.patientId), - builder: - (BuildContext context, PrescriptionViewModel model, Widget child) => - AppScaffold( - isShowAppBar: true, - appBarTitle: TranslationBase.of(context).prescription, - body: NetworkBaseView( - baseViewModel: model, - child: SingleChildScrollView( - child: Container( - color: Colors.white, - child: Column( - children: [ - PatientPageHeaderWidget(patient), - Divider( - height: 1.0, - thickness: 1.0, - color: Colors.grey, - ), - (model.prescriptionList.length != 0) - ? SizedBox( - height: - model.prescriptionList[0].rowcount == 0 - ? 200.0 - : 10.0) - : SizedBox(height: 200.0), - //model.prescriptionList == null - (model.prescriptionList.length != 0) - ? model.prescriptionList[0].rowcount == 0 - ? Container( - child: AppText( - 'Sorry , Theres no prescriptions for this patient', - color: Color(0xFFB9382C), - ), - ) - : Padding( - padding: EdgeInsets.all(14.0), - child: NetworkBaseView( - baseViewModel: model, - child: Column( - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - ...List.generate( - model.prescriptionList[0] - .rowcount, - (index) => Container( - color: Colors.white, - child: Column( - children: [ - SizedBox( - height: MediaQuery.of( - context) - .size - .height * - 0.022, - ), - Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, - // crossAxisAlignment: - // CrossAxisAlignment.start, - children: [ - Container( - height: MediaQuery.of( - context) - .size - .height * - 0.21, - width: MediaQuery.of( - context) - .size - .width * - 0.1, - child: Column( - children: [ - AppText( - (DateTime.parse(model.prescriptionList[0].entityList[index].createdOn) != - null - ? (DateTime.parse(model.prescriptionList[0].entityList[index].createdOn).year) - .toString() - : DateTime.now() - .year) - .toString(), - color: Colors - .green, - fontSize: - 13.5, - ), - AppText( - AppDateUtils.getMonth(model.prescriptionList[0].entityList[index].createdOn != - null - ? (DateTime.parse(model.prescriptionList[0].entityList[index].createdOn) - .month) - : DateTime.now() - .month) - .toUpperCase(), - color: Colors - .green, - ), - AppText( - DateTime.parse(model - .prescriptionList[ - 0] - .entityList[ - index] - .createdOn) - .day - .toString(), - color: Colors - .green, - ), - AppText( - AppDateUtils.getTimeFormated(DateTime.parse(model - .prescriptionList[ - 0] - .entityList[ - index] - .createdOn)) - .toString(), - color: Colors - .green, - ), - ], - ), - ), - Container( - // height: MediaQuery.of( - // context) - // .size - // .height * - // 0.3499, - width: MediaQuery.of( - context) - .size - .width * - 0.77, - child: Column( - children: [ - Row( - children: [ - AppText( - 'Start Date:', - fontWeight: - FontWeight - .w700, - fontSize: - 14.0, - ), - Expanded( - child: - AppText( - AppDateUtils.getDateFormatted(DateTime.parse(model - .prescriptionList[0] - .entityList[index] - .startDate)), - fontSize: - 13.5, - ), - ), - SizedBox( - width: - 6.0, - ), - AppText( - 'Order Type:', - fontWeight: - FontWeight - .w700, - fontSize: - 14.0, - ), - Expanded( - child: - AppText( - model - .prescriptionList[0] - .entityList[index] - .orderTypeDescription, - fontSize: - 13.0, - ), - ), - ], - ), - SizedBox( - height: 5.5, - ), - Row( - children: [ - Container( - child: - Expanded( - child: - AppText( - model - .prescriptionList[0] - .entityList[index] - .medicationName, - fontWeight: - FontWeight.w700, - fontSize: - 15.0, - ), - ), - ) - ], - ), - SizedBox( - height: 5.5, - ), - Row( - children: [ - Expanded( - child: - AppText( - model - .prescriptionList[0] - .entityList[index] - .doseDetail, - fontSize: - 15.0, - ), - ) - ], - ), - SizedBox( - height: 10.0, - ), - Row( - children: [ - AppText( - 'Indication: ', - fontWeight: - FontWeight - .w700, - fontSize: - 17.0, - ), - Expanded( - child: - RichText( - maxLines: - 3, - overflow: - TextOverflow.ellipsis, - strutStyle: - StrutStyle(fontSize: 12.0), - text: TextSpan( - style: - TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList[index].indication), - ), - ), - ], - ), - Row( - children: [ - AppText( - 'UOM: ', - fontWeight: - FontWeight - .w700, - fontSize: - 17.0, - ), - Expanded( - child: - RichText( - maxLines: - 3, - overflow: - TextOverflow.ellipsis, - strutStyle: - StrutStyle(fontSize: 12.0), - text: TextSpan( - style: - TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList[index].uom), - ), - ), - ], - ), - Row( - children: [ - AppText( - 'BOX Quantity: ', - fontWeight: - FontWeight - .w700, - fontSize: - 17.0, - ), - Expanded( - child: - RichText( - maxLines: - 3, - overflow: - TextOverflow.ellipsis, - strutStyle: - StrutStyle(fontSize: 12.0), - text: TextSpan( - style: - TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList[index].quantity.toString() == null ? "" : model.prescriptionList[0].entityList[index].quantity.toString()), - ), - ), - ], - ), - Row( - children: [ - AppText( - 'pharmacy Intervention ', - fontWeight: - FontWeight - .w700, - fontSize: - 17.0, - ), - Expanded( - child: - RichText( - maxLines: - 3, - overflow: - TextOverflow.ellipsis, - strutStyle: - StrutStyle(fontSize: 12.0), - text: TextSpan( - style: - TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList[index].pharmacyInervention == null ? "" : model.prescriptionList[0].entityList[index].pharmacyInervention.toString()), - ), - ), - ], - ), - SizedBox( - height: - 5.0), - Row( - children: [ - AppText( - 'pharmacist Remarks : ', - fontWeight: - FontWeight - .w700, - fontSize: - 15.0, - ), - Expanded( - child: AppText( - // commening below code because there is an error coming in the model please fix it before pushing it - model.prescriptionList[0].entityList[index].pharmacistRemarks == null ? "" : model.prescriptionList[0].entityList[index].pharmacistRemarks, - fontSize: 15.0), - ) - ], - ), - SizedBox( - height: 20.0, - ), - Row( - children: [ - AppText( - TranslationBase.of(context) - .doctorName + - ": ", - fontWeight: - FontWeight - .w600, - ), - Expanded( - child: - AppText( - model - .prescriptionList[0] - .entityList[index] - .doctorName, - fontWeight: - FontWeight.w700, - ), - ) - ], - ), - SizedBox( - height: 8.0, - ), - Row( - children: [ - AppText( - 'Doctor Remarks : ', - fontWeight: - FontWeight - .w700, - fontSize: - 13.0, - ), - Expanded( - child: - Container( - // height: MediaQuery.of(context).size.height * - // 0.038, - child: - RichText( - // maxLines: - // 2, - // overflow: - // TextOverflow.ellipsis, - strutStyle: - StrutStyle(fontSize: 10.0), - text: - TextSpan( - style: - TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList[index].remarks != null - ? model.prescriptionList[0].entityList[index].remarks - : "", - ), - ), - ), - ), - ], - ), - SizedBox( - height: 10.0, - ), - - // SizedBox( - // height: 40, - // ), - ], - ), - ), - ], - ), - Divider( - height: 0, - thickness: 1.0, - color: Colors.grey, - ), - ], - ), - ), - ), - ], - ), - ), - ) - : Container( - child: AppText( - 'Sorry , theres no prescriptions listed for this patient', - color: Color(0xFFB9382C), - ), - ) - ], - ), - ), - ), - )), - ); - } - - selectDate(BuildContext context, PrescriptionViewModel model) async { - DateTime selectedDate; - selectedDate = DateTime.now(); - final DateTime picked = await showDatePicker( - context: context, - initialDate: selectedDate, - firstDate: DateTime.now().add(Duration(hours: 2)), - lastDate: DateTime(2040), - initialEntryMode: DatePickerEntryMode.calendar, - ); - if (picked != null && picked != selectedDate) { - setState(() { - selectedDate = picked; - }); - } - } -} diff --git a/lib/widgets/patients/profile/patient-page-header-widget.dart b/lib/widgets/patients/profile/patient-page-header-widget.dart deleted file mode 100644 index 49ad8f4e..00000000 --- a/lib/widgets/patients/profile/patient-page-header-widget.dart +++ /dev/null @@ -1,114 +0,0 @@ -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/core/viewModel/project_view_model.dart'; -import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; -import 'package:doctor_app_flutter/models/SOAP/GeneralGetReqForSOAP.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/profile_screen/patient_profile_screen.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:provider/provider.dart'; - -class PatientPageHeaderWidget extends StatelessWidget { - - final PatiantInformtion patient; - PatientPageHeaderWidget(this.patient); - - @override - Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); - - return BaseView( - onModelReady: (model) async { - GeneralGetReqForSOAP generalGetReqForSOAP = GeneralGetReqForSOAP( - patientMRN: patient.patientMRN??patient.patientId, - doctorID: '', - editedBy: ''); - await model.getPatientAllergy(generalGetReqForSOAP); - if (model.allergiesList.length == 0) { - await model.getMasterLookup(MasterKeysService.Allergies); - } - if (model.allergySeverityList.length == 0) { - await model.getMasterLookup(MasterKeysService.AllergySeverity); - } - - }, - builder: (_, model, w) => Container( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - AvatarWidget( - Icon( - patient.genderDescription == "Male" - ? DoctorApp.male - : DoctorApp.female_icon, - size: 70, - color: Colors.white, - ), - ), - SizedBox( - width: 20, - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - SizedBox( - height: 5, - ), - AppText( - patient.patientDetails.fullName != null ? patient.patientDetails.fullName : patient.firstName, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).age , - color: Colors.black, - fontWeight: FontWeight.bold, - ), - SizedBox( - width: 20, - ), - AppText( - patient.age.toString(), - color: Colors.black, - fontWeight: FontWeight.normal, - ), - ], - ), - model.patientAllergiesList.isNotEmpty && model.getAllergicNames(projectViewModel.isArabic)!='' ?AppText( - TranslationBase.of(context).allergicTO +" : "+model.getAllergicNames(projectViewModel.isArabic), - color: Color(0xFFB9382C), - fontWeight: FontWeight.bold, - ) : AppText(''), - ], - ), - ) - ], - ), - ), - Container( - width: double.infinity, - height: 1, - color: Color(0xffCCCCCC), - ), - SizedBox( - width: 20, - ), - ], - ), - )); - } -} From ca0cc745d5a3647d03db6a912c9e2890a1608baf Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 9 Jun 2021 17:15:23 +0300 Subject: [PATCH 20/72] remove headers --- ...-profile-header-new-design_in_patient.dart | 242 --------- ..._profile_header_with_appointment_card.dart | 507 ------------------ 2 files changed, 749 deletions(-) delete mode 100644 lib/widgets/patients/profile/patient-profile-header-new-design_in_patient.dart delete mode 100644 lib/widgets/patients/profile/patient_profile_header_with_appointment_card.dart diff --git a/lib/widgets/patients/profile/patient-profile-header-new-design_in_patient.dart b/lib/widgets/patients/profile/patient-profile-header-new-design_in_patient.dart deleted file mode 100644 index c3a8638f..00000000 --- a/lib/widgets/patients/profile/patient-profile-header-new-design_in_patient.dart +++ /dev/null @@ -1,242 +0,0 @@ -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/icons_app/doctor_app_icons.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'; -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:intl/intl.dart'; -import 'package:url_launcher/url_launcher.dart'; - -class PatientProfileHeaderNewDesignInPatient extends StatelessWidget { - final PatiantInformtion patient; - final String patientType; - final String arrivalType; - final double height; - - PatientProfileHeaderNewDesignInPatient( - this.patient, this.patientType, this.arrivalType, - {this.height = 0.0}); - - @override - Widget build(BuildContext context) { - int gender = 1; - if (patient.patientDetails != null) { - gender = patient.patientDetails.gender; - } else { - gender = patient.gender; - } - - return Container( - padding: EdgeInsets.only( - left: 0, - right: 5, - bottom: 5, - ), - decoration: BoxDecoration( - color: Colors.white, - ), - height: height == 0 ? 200 : height, - 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( - patient.firstName != null - ? (Helpers.capitalize(patient.firstName) + - " " + - Helpers.capitalize(patient.lastName)) - : Helpers.capitalize(patient.patientDetails.fullName), - fontSize: SizeConfig.textMultiplier * 2.2, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - ), - ), - gender == 1 - ? Icon( - DoctorApp.male_2, - color: Colors.blue, - ) - : Icon( - DoctorApp.female_1, - color: Colors.pink, - ), - Container( - margin: EdgeInsets.symmetric(horizontal: 4), - child: InkWell( - onTap: () { - launch("tel://" + patient.mobileNumber); - }, - child: Icon( - Icons.phone, - color: Colors.black87, - ), - ), - ), - ]), - ), - Row(children: [ - Padding( - padding: EdgeInsets.only(left: 12.0), - child: Container( - width: 60, - height: 60, - child: Image.asset( - gender == 1 - ? 'assets/images/male_avatar.png' - : 'assets/images/female_avatar.png', - fit: BoxFit.cover, - ), - ), - ), - SizedBox( - width: 10, - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - AppText( - TranslationBase.of(context).fileNumber, - fontSize: 1.2 * SizeConfig.textMultiplier, - ), - AppText(patient.patientId.toString(), - fontSize: 1.4 * SizeConfig.textMultiplier, - fontWeight: FontWeight.w700), - ], - ), - if(patient.admissionDate!=null) - Row( - children: [ - AppText( - AppDateUtils.convertDateFromServerFormat( - patient.admissionDate, "hh:mm a"), - fontWeight: FontWeight.bold, - fontSize: 1.4 * SizeConfig.textMultiplier, - ), - ], - ) - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - if(patient.admissionDate!=null) - Row( - children: [ - AppText( - "${TranslationBase.of(context).admissionDate}: ", - fontSize: 1.2 * SizeConfig.textMultiplier, - ), - AppText( - AppDateUtils.convertDateFromServerFormat( - patient.admissionDate, "dd MMM,yyyy"), - fontSize: 1.4 * SizeConfig.textMultiplier, - fontWeight: FontWeight.w700), - ], - ), - Row( - children: [ - AppText( - patient.nationalityName ?? - patient.nationality ?? - patient.nationalityId ?? - '', - fontWeight: FontWeight.bold, - fontSize: 1.4 * SizeConfig.textMultiplier, - ), - patient.nationalityFlagURL != null - ? ClipRRect( - borderRadius: BorderRadius.circular(20.0), - child: Image.network( - patient.nationalityFlagURL, - height: 25, - width: 30, - errorBuilder: (BuildContext context, - Object exception, - StackTrace stackTrace) { - return Text('No Image'); - }, - )) - : SizedBox() - ], - ) - ], - ), - if(patient.admissionDate!=null) - Row( - children: [ - AppText( - "${TranslationBase.of(context).numOfDays}: ", - fontSize: 1.2 * SizeConfig.textMultiplier, - ), - AppText( - "${DateTime.now().difference(AppDateUtils.getDateTimeFromServerFormat(patient.admissionDate)).inDays + 1}", - fontSize: 1.4 * SizeConfig.textMultiplier, - fontWeight: FontWeight.w700), - ], - ), - ], - ), - ), - ]), - ], - ), - ), - ); - } - - convertDateFormat2(String str) { - String newDate; - const start = "/Date("; - if (str.isNotEmpty) { - const end = "+0300)"; - - 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))); - newDate = date.year.toString() + - "/" + - date.month.toString().padLeft(2, '0') + - "/" + - date.day.toString().padLeft(2, '0'); - } - - return newDate.toString(); - } - - 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()); - } - - myBoxDecoration() { - return BoxDecoration( - border: Border( - top: BorderSide( - color: Colors.green, - width: 5, - ), - ), - borderRadius: BorderRadius.circular(10)); - } -} diff --git a/lib/widgets/patients/profile/patient_profile_header_with_appointment_card.dart b/lib/widgets/patients/profile/patient_profile_header_with_appointment_card.dart deleted file mode 100644 index f3e01316..00000000 --- a/lib/widgets/patients/profile/patient_profile_header_with_appointment_card.dart +++ /dev/null @@ -1,507 +0,0 @@ -import 'package:doctor_app_flutter/config/config.dart'; -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/icons_app/doctor_app_icons.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'; -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'; -import 'package:intl/intl.dart'; -import 'package:provider/provider.dart'; -import 'package:url_launcher/url_launcher.dart'; - -import 'large_avatar.dart'; - -class PatientProfileHeaderWhitAppointment extends StatelessWidget { - - final PatiantInformtion patient; - final String patientType; - final String arrivalType; - final String doctorName; - final String branch; - final DateTime appointmentDate; - final String profileUrl; - final String invoiceNO; - final String orderNo; - final bool isPrescriptions; - final String clinic; - PatientProfileHeaderWhitAppointment( - {this.patient, - this.patientType, - this.arrivalType, - this.doctorName, - this.branch, - this.appointmentDate, - this.profileUrl, - this.invoiceNO, - this.orderNo, this.isPrescriptions = false, this.clinic}); - - @override - Widget build(BuildContext context) { - int gender = 1; - if (patient.patientDetails != null) { - gender = patient.patientDetails.gender; - } else { - gender = patient.gender; - } - - ProjectViewModel projectViewModel = Provider.of(context); - return Container( - padding: EdgeInsets.only( - left: 0, right: 5, bottom: 5, top: 5), - decoration: BoxDecoration( - color: Colors.white, - ), - //height: 300, - child: Container( - padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), - margin: EdgeInsets.only(top: 50), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - 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( - patient.firstName != null ? - (Helpers.capitalize(patient.firstName) + - " " + - Helpers.capitalize( - patient.lastName)) : Helpers.capitalize(patient.patientDetails.fullName), - fontSize: SizeConfig.textMultiplier *2.2, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - ), - ), - gender == 1 - ? Icon( - DoctorApp.male_2, - color: Colors.blue, - ) - : Icon( - DoctorApp.female_1, - color: Colors.pink, - ), - Container( - margin: EdgeInsets.symmetric(horizontal: 4), - child: InkWell( - onTap: () { - launch("tel://" + patient.mobileNumber); - }, - child: Icon( - Icons.phone, - color: Colors.black87, - ), - ), - ) - ]), - ), - Row(children: [ - Padding( - padding: EdgeInsets.only(left: 12.0), - child: Container( - width: 60, - height: 60, - child: Image.asset( - gender == 1 - ? 'assets/images/male_avatar.png' - : 'assets/images/female_avatar.png', - fit: BoxFit.cover, - ), - ), - ), - SizedBox( - width: 10, - ), - Expanded( - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - SERVICES_PATIANT2[ - int.parse(patientType)] == - "patientArrivalList" - ? Container( - child: Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, - children: [ - patient.patientStatusType == - 43 - ? AppText( - TranslationBase.of( - context) - .arrivedP, - color: Colors.green, - fontWeight: - FontWeight.bold, - fontFamily: - 'Poppins', - fontSize: 12, - ) - : AppText( - TranslationBase.of( - context) - .notArrived, - color: - Colors.red[800], - fontWeight: - FontWeight.bold, - fontFamily: - 'Poppins', - fontSize: 12, - ), - arrivalType == '1' || patient.arrivedOn == null - ? AppText( - patient.startTime != - null - ? patient - .startTime - : '', - fontFamily: - 'Poppins', - fontWeight: - FontWeight.w600, - ) - : AppText( - AppDateUtils.convertStringToDateFormat( - patient - .arrivedOn, - 'MM-dd-yyyy HH:mm'), - fontFamily: - 'Poppins', - fontWeight: - FontWeight.w600, - ) - ], - )) - : SizedBox(), - if (SERVICES_PATIANT2[ - int.parse(patientType)] == - "List_MyOutPatient") - Container( - child: Row( - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context) - .appointmentDate + - " : ", - fontSize: 14, - ), - patient.startTime != null - ? Container( - height: 15, - width: 60, - decoration: - BoxDecoration( - borderRadius: - BorderRadius - .circular( - 25), - color: HexColor( - "#20A169"), - ), - child: AppText( - patient.startTime, - color: Colors.white, - fontSize: 1.5 * - SizeConfig - .textMultiplier, - textAlign: TextAlign - .center, - fontWeight: - FontWeight.bold, - ), - ) - : SizedBox(), - SizedBox( - width: 3.5, - ), - Container( - child: AppText( - convertDateFormat2(patient.appointmentDate.toString()?? ''), - fontSize: 1.5 * - SizeConfig - .textMultiplier, - fontWeight: - FontWeight.bold, - ), - ), - SizedBox( - height: 0.5, - ) - ], - ), - margin: EdgeInsets.only( - top: 8, - ), - ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - RichText( - text: TextSpan( - style: TextStyle( - fontSize: 1.6 * - SizeConfig - .textMultiplier, - color: Colors.black), - children: [ - new TextSpan( - text: - TranslationBase.of( - context) - .fileNumber, - style: TextStyle( - fontSize: 12, - fontFamily: - 'Poppins')), - new TextSpan( - text: patient.patientId - .toString(), - style: TextStyle( - fontWeight: - FontWeight.w700, - fontFamily: - 'Poppins', - fontSize: 14)), - ], - ), - ), - Row( - children: [ - AppText( - patient.nationalityName ?? - patient.nationality??"", - fontWeight: FontWeight.bold, - fontSize: 12, - ), - patient.nationality != null - ? ClipRRect( - borderRadius: - BorderRadius - .circular( - 20.0), - child: Image.network( - patient.nationalityFlagURL, - height: 25, - width: 30, - errorBuilder: - (BuildContext - context, - Object - exception, - StackTrace - stackTrace) { - return Text( - 'No Image'); - }, - )) - : SizedBox() - ], - ) - ], - ), - Container( - child: RichText( - text: new TextSpan( - style: new TextStyle( - fontSize: 1.6 * - SizeConfig.textMultiplier, - color: Colors.black, - fontFamily: 'Poppins', - ), - children: [ - 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)}", - style: TextStyle( - fontWeight: - FontWeight.w700, - fontSize: 14)), - ], - ), - ), - ), - ], - ), - ), - ]), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - width: 30, - height: 30, - margin: EdgeInsets.only(left: projectViewModel.isArabic?10:85, right: projectViewModel.isArabic?85:10,top: 5), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - border: Border( - bottom:BorderSide(color: Colors.grey[400],width: 2.5), - left: BorderSide(color: Colors.grey[400],width: 2.5), - ) - ), - ), - Expanded( - child: Container( - margin: EdgeInsets.only(top: 10), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - child: LargeAvatar( - name: doctorName, - url: profileUrl, - ), - width: 25, - height: 25, - margin: EdgeInsets.only(top: 10), - ), - Expanded( - flex: 4, - child: Container( - margin: EdgeInsets.all(10), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - '${TranslationBase.of(context).dr}.$doctorName', - color: Colors.black, - fontWeight: FontWeight.w600, - fontSize: 14, - ), - if (orderNo != null && !isPrescriptions) - Row( - children: [ - AppText( - 'Order No:', - color: Colors.grey[800], - ), - AppText( - orderNo ?? '', - ) - ], - ), - if (invoiceNO != null && !isPrescriptions) - Row( - children: [ - AppText( - 'Invoice:', - color: Colors.grey[800], - ), - AppText( - invoiceNO, - ) - ], - ), - if(isPrescriptions) - Row( - children: [ - AppText( - 'Branch:', - color: Colors.grey[800], - ), - AppText( - branch?? '', - ) - ], - ), - if(isPrescriptions) - Row( - children: [ - AppText( - 'Clinic:', - color: Colors.grey[800], - ), - AppText( - clinic?? '', - ) - ], - ), - Row( - children: [ - AppText( - !isPrescriptions? 'Result Date:': 'Prescriptions Date', - color: Colors.grey[800], - ), - Expanded( - child: AppText( - '${AppDateUtils.getDayMonthYearDateFormatted(appointmentDate, isArabic: projectViewModel.isArabic)}', - ), - ) - ], - ) - ]), - ), - ), - - ], - ), - ), - ), - ], - ) - ], - ), - ), - ); - } - - convertDateFormat2(String str) { - String newDate =""; - const start = "/Date("; - const end = "+0300)"; - - if (str.isNotEmpty) { - 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))); - newDate = date.year.toString() + - "/" + - date.month.toString().padLeft(2, '0') + - "/" + - date.day.toString().padLeft(2, '0'); - } - - return newDate.toString(); - } - - 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()); - } - - myBoxDecoration() { - return BoxDecoration( - border: Border( - top: BorderSide( - color: Colors.green, - width: 5, - ), - ), - borderRadius: BorderRadius.circular(10)); - } -} From 017669c406e4868b7fe64084806240beecea37cc Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 10 Jun 2021 09:51:34 +0300 Subject: [PATCH 21/72] Merge branch 'development' into procedure_refactoring # Conflicts: # lib/core/service/patient/LiveCarePatientServices.dart --- .../referral/MyReferralPatientModel.dart | 2 + .../my_referred_patient_model.dart | 4 +- .../referral/AddReplayOnReferralPatient.dart | 212 +++++++++--------- 3 files changed, 111 insertions(+), 107 deletions(-) diff --git a/lib/core/model/referral/MyReferralPatientModel.dart b/lib/core/model/referral/MyReferralPatientModel.dart index ebf12857..ac069e8d 100644 --- a/lib/core/model/referral/MyReferralPatientModel.dart +++ b/lib/core/model/referral/MyReferralPatientModel.dart @@ -163,6 +163,8 @@ class MyReferralPatientModel { referralDate = AppDateUtils.getDateTimeFromString(json['ReferralDate']); } catch (e){ referralDate = AppDateUtils.convertStringToDate(json['ReferralDate']); + } finally { + referralDate = DateTime.now(); } referringDoctorRemarks = json['ReferringDoctorRemarks']; diff --git a/lib/models/patient/my_referral/my_referred_patient_model.dart b/lib/models/patient/my_referral/my_referred_patient_model.dart index cb61975a..b353e587 100644 --- a/lib/models/patient/my_referral/my_referred_patient_model.dart +++ b/lib/models/patient/my_referral/my_referred_patient_model.dart @@ -166,8 +166,9 @@ class MyReferredPatientModel { referringDoctor = json['ReferringDoctor']; referralClinic = json['ReferralClinic']; referringClinic = json['ReferringClinic']; + createdOn = json['CreatedOn']; referralStatus = json["ReferralStatus"] is String?json['ReferralStatus']== "Accepted"?46:json['ReferralStatus']=="Pending"?1:0 : json['ReferralStatus']; - referralDate = json['ReferralDate']; + referralDate = json['ReferralDate'] ?? createdOn; referringDoctorRemarks = json['ReferringDoctorRemarks']; referredDoctorRemarks = json['ReferredDoctorRemarks']; referralResponseOn = json['ReferralResponseOn']; @@ -179,7 +180,6 @@ class MyReferredPatientModel { appointmentDate = json['AppointmentDate']; appointmentType = json['AppointmentType']; patientMRN = json['PatientMRN']; - createdOn = json['CreatedOn']; clinicID = json['ClinicID']; nationalityID = json['NationalityID']; age = json['Age']; diff --git a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart index 97db3d40..aadcd5f0 100644 --- a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart +++ b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart @@ -51,8 +51,8 @@ class _AddReplayOnReferralPatientState void initState() { requestPermissions(); super.initState(); - replayOnReferralController.text = widget.myReferralInPatientModel.referredDoctorRemarks?? ""; - + replayOnReferralController.text = + widget.myReferralInPatientModel.referredDoctorRemarks ?? ""; } @override @@ -60,67 +60,70 @@ class _AddReplayOnReferralPatientState return AppScaffold( isShowAppBar: false, backgroundColor: Theme.of(context).scaffoldBackgroundColor, - body: SingleChildScrollView( - child: Column( - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - BottomSheetTitle(title: 'Reply'), - SizedBox( - height: 10.0, - ), - Center( - child: FractionallySizedBox( - widthFactor: 0.9, - child: Column( - children: [ - Stack( - children: [ - AppTextFieldCustom( - hintText: 'Reply your responses here', - controller: replayOnReferralController, - maxLines: 35, - minLines: 25, - hasBorder: true, - validationError: - replayOnReferralController.text.isEmpty && - isSubmitted - ? TranslationBase.of(context).emptyMessage - : null, - ), - Positioned( - top: 0, //MediaQuery.of(context).size.height * 0, - right: 15, - child: IconButton( - icon: Icon( - DoctorApp.speechtotext, - color: Colors.black, - size: 35, - ), - onPressed: () { - onVoiceText(); - }, + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BottomSheetTitle(title: 'Reply'), + SizedBox( + height: 10.0, + ), + Center( + child: FractionallySizedBox( + widthFactor: 0.9, + child: Column( + children: [ + Stack( + children: [ + AppTextFieldCustom( + hintText: 'Reply your responses here', + controller: replayOnReferralController, + maxLines: 35, + minLines: 25, + hasBorder: true, + validationError: replayOnReferralController + .text.isEmpty && + isSubmitted + ? TranslationBase.of(context).emptyMessage + : null, ), - ) - ], - ), - ], + Positioned( + top: 0, + //MediaQuery.of(context).size.height * 0, + right: 15, + child: IconButton( + icon: Icon( + DoctorApp.speechtotext, + color: Colors.black, + size: 35, + ), + onPressed: () { + onVoiceText(); + }, + ), + ) + ], + ), + ], + ), ), ), - ), - ], + ], + ), ), - Container( - height: replayOnReferralController.text.isNotEmpty ? 130 : 70, - margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), - child: Column( - children: [ - replayOnReferralController.text.isEmpty - ? SizedBox() - : Container( - margin: EdgeInsets.all(5), - child: Expanded( + ), + Container( + height: replayOnReferralController.text.isNotEmpty ? 130 : 70, + margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), + child: Column( + children: [ + replayOnReferralController.text.isEmpty + ? SizedBox() + : Container( + margin: EdgeInsets.all(5), child: AppButton( title: TranslationBase.of(context).clearText, onPressed: () { @@ -128,55 +131,54 @@ class _AddReplayOnReferralPatientState replayOnReferralController.text = ''; }); }, - )), - ), - 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()), - ), - ); - } + ), + ), + 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 { - Helpers.showErrorToast("You can't add empty reply"); - setState(() { - isSubmitted = false; - }); + 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; + }); + } + })), + ], ), - ], - ), + ), + ], ), ); } From 6aef8b5878d6944ec0b0b04a8248a0ea83ebd3ba Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Thu, 10 Jun 2021 11:11:27 +0300 Subject: [PATCH 22/72] first step refactor headers --- lib/screens/live_care/end_call_screen.dart | 4 +- .../medical-file/health_summary_page.dart | 4 +- .../medical-file/medical_file_details.dart | 13 +- lib/screens/patients/ECGPage.dart | 4 +- .../insurance_approval_screen_patient.dart | 4 +- .../patients/insurance_approvals_details.dart | 4 +- .../profile/UCAF/UCAF-detail-screen.dart | 4 +- .../profile/UCAF/UCAF-input-screen.dart | 4 +- .../admission-request-first-screen.dart | 4 +- .../admission-request-third-screen.dart | 4 +- .../admission-request_second-screen.dart | 4 +- .../lab_result/laboratory_result_page.dart | 20 +- .../profile/lab_result/labs_home_page.dart | 4 +- .../MedicalReportDetailPage.dart | 4 +- .../medical_report/MedicalReportPage.dart | 4 +- .../profile/note/progress_note_screen.dart | 4 +- .../patient_profile_screen.dart | 4 +- .../radiology/radiology_details_page.dart | 13 +- .../radiology/radiology_home_page.dart | 4 +- .../refer-patient-screen-in-patient.dart | 4 +- .../referral/refer-patient-screen.dart | 4 +- .../soap_update/update_soap_index.dart | 4 +- .../vital_sign/vital_sign_details_screen.dart | 4 +- .../vital_sign_item_details_screen.dart | 4 +- .../prescription_item_in_patient_page.dart | 4 +- .../prescription/prescription_items_page.dart | 12 +- .../prescription/prescriptions_page.dart | 4 +- lib/screens/procedures/procedure_screen.dart | 4 +- lib/screens/sick-leave/add-sickleave.dart | 4 +- lib/screens/sick-leave/show-sickleave.dart | 4 +- lib/util/date-utils.dart | 22 + .../profile/GeneralLabResultHeader.dart | 349 ---------- .../profile/PatientHeaderWidgetNoAvatar.dart | 73 --- .../profile/patient-profile-app-bar.dart | 599 ++++++++++++++++++ ...ent-profile-header-new-design-app-bar.dart | 371 ----------- .../patient-profile-header-new-design.dart | 316 --------- ..._header_with_appointment_card_app_bar.dart | 456 ------------- .../profile/profile_header_widget.dart | 39 -- 38 files changed, 702 insertions(+), 1685 deletions(-) delete mode 100644 lib/widgets/patients/profile/GeneralLabResultHeader.dart delete mode 100644 lib/widgets/patients/profile/PatientHeaderWidgetNoAvatar.dart create mode 100644 lib/widgets/patients/profile/patient-profile-app-bar.dart delete mode 100644 lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart delete mode 100644 lib/widgets/patients/profile/patient-profile-header-new-design.dart delete mode 100644 lib/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart delete mode 100644 lib/widgets/patients/profile/profile_header_widget.dart diff --git a/lib/screens/live_care/end_call_screen.dart b/lib/screens/live_care/end_call_screen.dart index 617eef34..411079fc 100644 --- a/lib/screens/live_care/end_call_screen.dart +++ b/lib/screens/live_care/end_call_screen.dart @@ -13,7 +13,7 @@ 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'; import 'package:doctor_app_flutter/widgets/patients/profile/PatientProfileButton.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; 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'; @@ -184,7 +184,7 @@ class _EndCallScreenState extends State { appBarTitle: TranslationBase.of(context).patientProfile, backgroundColor: Theme.of(context).scaffoldBackgroundColor, isShowAppBar: true, - appBar: PatientProfileHeaderNewDesignAppBar( + appBar: PatientProfileAppBar( widget.patient, arrivalType ?? '7', '1', isInpatient: isInpatient, height: (widget.patient.patientStatusType != null && diff --git a/lib/screens/medical-file/health_summary_page.dart b/lib/screens/medical-file/health_summary_page.dart index ad7f13cb..ee4726e2 100644 --- a/lib/screens/medical-file/health_summary_page.dart +++ b/lib/screens/medical-file/health_summary_page.dart @@ -4,7 +4,7 @@ import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/medical-file/medical_file_details.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; 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/doctor_card.dart'; @@ -30,7 +30,7 @@ class _HealthSummaryPageState extends State { builder: (BuildContext context, MedicalFileViewModel model, Widget child) => AppScaffold( - appBar: PatientProfileHeaderNewDesignAppBar( + appBar: PatientProfileAppBar( patient, patientType.toString() ?? "0", arrivalType, diff --git a/lib/screens/medical-file/medical_file_details.dart b/lib/screens/medical-file/medical_file_details.dart index 9bfde511..64d76f06 100644 --- a/lib/screens/medical-file/medical_file_details.dart +++ b/lib/screens/medical-file/medical_file_details.dart @@ -4,7 +4,7 @@ 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'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; 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/expandable-widget-header-body.dart'; @@ -102,20 +102,21 @@ class _MedicalFileDetailsState extends State { builder: (BuildContext context, MedicalFileViewModel model, Widget child) => AppScaffold( - appBar: PatientProfileHeaderWhitAppointmentAppBar( - patient: patient, - patientType: patient.patientType.toString() ?? "0", - arrivalType: patient.arrivedOn.toString() ?? 0, + appBar: PatientProfileAppBar( + patient, + patient.patientType.toString() ?? "0", + patient.arrivedOn.toString() ?? 0, doctorName: doctorName, profileUrl: doctorImage, clinic: clinicName, isPrescriptions: true, isMedicalFile: true, episode: episode, - vistDate: + visitDate: '${AppDateUtils.getDayMonthYearDateFormatted(AppDateUtils.getDateTimeFromServerFormat( vistDate, ), isArabic: projectViewModel.isArabic)}', + isAppointmentHeader: true, ), isShowAppBar: true, appBarTitle: TranslationBase.of(context).medicalReport.toUpperCase(), diff --git a/lib/screens/patients/ECGPage.dart b/lib/screens/patients/ECGPage.dart index 33692628..97923959 100644 --- a/lib/screens/patients/ECGPage.dart +++ b/lib/screens/patients/ECGPage.dart @@ -6,7 +6,7 @@ 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'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/cupertino.dart'; @@ -31,7 +31,7 @@ class ECGPage extends StatelessWidget { baseViewModel: model, isShowAppBar: true, backgroundColor: Color(0xffF8F8F8), - appBar: PatientProfileHeaderNewDesignAppBar(patient,arrivalType??'0',patientType), + appBar: PatientProfileAppBar(patient,arrivalType??'0',patientType), body: SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(8.0), diff --git a/lib/screens/patients/insurance_approval_screen_patient.dart b/lib/screens/patients/insurance_approval_screen_patient.dart index 2bffdda5..3d03589b 100644 --- a/lib/screens/patients/insurance_approval_screen_patient.dart +++ b/lib/screens/patients/insurance_approval_screen_patient.dart @@ -4,7 +4,7 @@ import 'package:doctor_app_flutter/core/viewModel/project_view_model.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'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; 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/doctor_card_insurance.dart'; @@ -44,7 +44,7 @@ class _InsuranceApprovalScreenNewState : (model) => model.getInsuranceApproval(patient), builder: (BuildContext context, InsuranceViewModel model, Widget child) => AppScaffold( - appBar: PatientProfileHeaderNewDesignAppBar( + appBar: PatientProfileAppBar( patient, patientType.toString() ?? "0", patientType, diff --git a/lib/screens/patients/insurance_approvals_details.dart b/lib/screens/patients/insurance_approvals_details.dart index 92910394..57af55d8 100644 --- a/lib/screens/patients/insurance_approvals_details.dart +++ b/lib/screens/patients/insurance_approvals_details.dart @@ -5,7 +5,7 @@ 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'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/cupertino.dart'; @@ -54,7 +54,7 @@ class _InsuranceApprovalsDetailsState extends State { AppScaffold( isShowAppBar: true, baseViewModel: model, - appBar: PatientProfileHeaderNewDesignAppBar( + appBar: PatientProfileAppBar( patient, patient.patientType.toString(), patient.arrivedOn), body: patient.admissionNo != null ? SingleChildScrollView( diff --git a/lib/screens/patients/profile/UCAF/UCAF-detail-screen.dart b/lib/screens/patients/profile/UCAF/UCAF-detail-screen.dart index 6890d74f..af61de0d 100644 --- a/lib/screens/patients/profile/UCAF/UCAF-detail-screen.dart +++ b/lib/screens/patients/profile/UCAF/UCAF-detail-screen.dart @@ -12,7 +12,7 @@ import 'package:doctor_app_flutter/screens/patients/profile/UCAF/page-stepper-wi 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'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; 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'; @@ -47,7 +47,7 @@ class _UcafDetailScreenState extends State { builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, - appBar: PatientProfileHeaderNewDesignAppBar( + appBar: PatientProfileAppBar( patient, patientType, arrivalType), appBarTitle: TranslationBase.of(context).ucaf, body: Column( diff --git a/lib/screens/patients/profile/UCAF/UCAF-input-screen.dart b/lib/screens/patients/profile/UCAF/UCAF-input-screen.dart index 5f7b91f3..7c163a79 100644 --- a/lib/screens/patients/profile/UCAF/UCAF-input-screen.dart +++ b/lib/screens/patients/profile/UCAF/UCAF-input-screen.dart @@ -7,7 +7,7 @@ import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/patients/profile/UCAF/page-stepper-widget.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/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; 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'; @@ -65,7 +65,7 @@ class _UCAFInputScreenState extends State { builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, - appBar: PatientProfileHeaderNewDesignAppBar( + appBar: PatientProfileAppBar( patient, patientType, arrivalType), appBarTitle: TranslationBase.of(context).ucaf, body: model.patientVitalSignsHistory.length > 0 && 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 08a69907..dd6d9d76 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 @@ -7,7 +7,7 @@ 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'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; 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'; @@ -61,7 +61,7 @@ class _AdmissionRequestThirdScreenState builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, - appBar: PatientProfileHeaderNewDesignAppBar( + appBar: PatientProfileAppBar( patient, patientType, arrivalType), appBarTitle: TranslationBase.of(context).admissionRequest, body: GestureDetector( 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 120b6adf..175f5669 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 @@ -8,7 +8,7 @@ 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'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; 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'; @@ -52,7 +52,7 @@ class _AdmissionRequestThirdScreenState builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, - appBar: PatientProfileHeaderNewDesignAppBar( + appBar: PatientProfileAppBar( patient, patientType, arrivalType), appBarTitle: TranslationBase.of(context).admissionRequest, body: GestureDetector( 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 bea487f7..f7e03533 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 @@ -10,7 +10,7 @@ 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'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; 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'; @@ -74,7 +74,7 @@ class _AdmissionRequestSecondScreenState builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, - appBar: PatientProfileHeaderNewDesignAppBar( + appBar: PatientProfileAppBar( patient, patientType, arrivalType), appBarTitle: TranslationBase.of(context).admissionRequest, body: GestureDetector( diff --git a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart index c7a98924..23b17830 100644 --- a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart +++ b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart @@ -2,7 +2,7 @@ import 'package:doctor_app_flutter/core/model/labs/patient_lab_orders.dart'; import 'package:doctor_app_flutter/core/viewModel/labs_view_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/widgets/patients/profile/GeneralLabResultHeader.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -38,17 +38,12 @@ class _LaboratoryResultPageState extends State { isInpatient: true), builder: (_, model, w) => AppScaffold( isShowAppBar: true, - appBar: GeneralLabResultHeader( - patient: widget.patient, - patientType: widget.patientType ?? "0", - arrivalType: widget.arrivalType ?? "0", - orderNo: widget.patientLabOrders.orderNo, - appointmentDate: widget.patientLabOrders.orderDate, - doctorName: widget.patientLabOrders.doctorName, - branch: widget.patientLabOrders.projectName, - clinic: widget.patientLabOrders.clinicDescription, - profileUrl: widget.patientLabOrders.doctorImageURL, - invoiceNO: widget.patientLabOrders.invoiceNo, + appBar: PatientProfileAppBar( + widget.patient, + widget.patientType ?? "0", + widget.arrivalType ?? "0", + isFromLabResult: true, + appointmentDate: widget.patientLabOrders.orderDate, ), baseViewModel: model, @@ -57,7 +52,6 @@ class _LaboratoryResultPageState extends State { body: SingleChildScrollView( child: Column( children: [ - LaboratoryResultWidget( onTap: () async {}, billNo: widget.patientLabOrders.invoiceNo, 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 0f0367af..96b64675 100644 --- a/lib/screens/patients/profile/lab_result/labs_home_page.dart +++ b/lib/screens/patients/profile/lab_result/labs_home_page.dart @@ -7,7 +7,7 @@ import 'package:doctor_app_flutter/screens/procedures/ProcedureType.dart'; import 'package:doctor_app_flutter/screens/procedures/base_add_procedure_tab_page.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/add-order/addNewOrder.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; 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/doctor_card.dart'; @@ -52,7 +52,7 @@ class _LabsHomePageState extends State { baseViewModel: model, backgroundColor: Colors.grey[100], isShowAppBar: true, - appBar: PatientProfileHeaderNewDesignAppBar( + appBar: PatientProfileAppBar( patient, patient.patientType.toString() ?? '0', patientType, diff --git a/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart index 7bf6f1d9..7b787f44 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart @@ -7,7 +7,7 @@ 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/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/large_avatar.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; 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/errors/dr_app_embedded_error.dart'; @@ -31,7 +31,7 @@ class MedicalReportDetailPage extends StatelessWidget { baseViewModel: model, isShowAppBar: true, backgroundColor: Theme.of(context).scaffoldBackgroundColor, - appBar: PatientProfileHeaderNewDesignAppBar( + appBar: PatientProfileAppBar( patient, patientType, arrivalType, diff --git a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart index e2da651b..6f036ff2 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart @@ -10,7 +10,7 @@ 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/patients/profile/add-order/addNewOrder.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/large_avatar.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; 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/card_with_bg_widget.dart'; @@ -43,7 +43,7 @@ class MedicalReportPage extends StatelessWidget { baseViewModel: model, isShowAppBar: true, backgroundColor: Theme.of(context).scaffoldBackgroundColor, - appBar: PatientProfileHeaderNewDesignAppBar( + appBar: PatientProfileAppBar( patient, patientType, arrivalType, diff --git a/lib/screens/patients/profile/note/progress_note_screen.dart b/lib/screens/patients/profile/note/progress_note_screen.dart index be912a60..087cab80 100644 --- a/lib/screens/patients/profile/note/progress_note_screen.dart +++ b/lib/screens/patients/profile/note/progress_note_screen.dart @@ -10,7 +10,7 @@ import 'package:doctor_app_flutter/screens/patients/profile/note/update_note.dar import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/add-order/addNewOrder.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/card_with_bg_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/divider_with_spaces_around.dart'; import 'package:doctor_app_flutter/widgets/shared/errors/dr_app_embedded_error.dart'; @@ -88,7 +88,7 @@ class _ProgressNoteState extends State { .of(context) .scaffoldBackgroundColor, // appBarTitle: TranslationBase.of(context).progressNote, - appBar: PatientProfileHeaderNewDesignAppBar( + appBar: PatientProfileAppBar( patient, patient.patientType.toString() ?? '0', arrivalType, 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 d9aa7d8d..cc71dd6d 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -14,7 +14,7 @@ import 'package:doctor_app_flutter/util/VideoChannel.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'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.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'; @@ -102,7 +102,7 @@ class _PatientProfileScreenState extends State children: [ Column( children: [ - PatientProfileHeaderNewDesignAppBar( + PatientProfileAppBar( patient, arrivalType ?? '0', patientType, isInpatient: isInpatient, isFromLiveCare: isFromLiveCare, diff --git a/lib/screens/patients/profile/radiology/radiology_details_page.dart b/lib/screens/patients/profile/radiology/radiology_details_page.dart index acc79d19..54dfe3ec 100644 --- a/lib/screens/patients/profile/radiology/radiology_details_page.dart +++ b/lib/screens/patients/profile/radiology/radiology_details_page.dart @@ -3,7 +3,7 @@ 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'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; 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/secondary_button.dart'; @@ -33,16 +33,19 @@ class RadiologyDetailsPage extends StatelessWidget { lineItem: finalRadiology.invoiceLineItemNo, invoiceNo: finalRadiology.invoiceNo), builder: (_, model, widget) => AppScaffold( - appBar: PatientProfileHeaderWhitAppointmentAppBar( - patient: patient, - patientType: patientType ?? "0", - arrivalType: arrivalType ?? "0", + appBar: PatientProfileAppBar( + patient, + patientType ?? "0", + arrivalType ?? "0", appointmentDate: finalRadiology.orderDate, doctorName: finalRadiology.doctorName, clinic: finalRadiology.clinicDescription, branch: finalRadiology.projectName, profileUrl: finalRadiology.doctorImageURL, invoiceNO: finalRadiology.invoiceNo.toString(), + isAppointmentHeader: true, + height: 325, + ), isShowAppBar: true, baseViewModel: model, diff --git a/lib/screens/patients/profile/radiology/radiology_home_page.dart b/lib/screens/patients/profile/radiology/radiology_home_page.dart index 9f93df35..bf50ea11 100644 --- a/lib/screens/patients/profile/radiology/radiology_home_page.dart +++ b/lib/screens/patients/profile/radiology/radiology_home_page.dart @@ -7,7 +7,7 @@ import 'package:doctor_app_flutter/screens/procedures/ProcedureType.dart'; import 'package:doctor_app_flutter/screens/procedures/base_add_procedure_tab_page.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/add-order/addNewOrder.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; 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/doctor_card.dart'; @@ -50,7 +50,7 @@ class _RadiologyHomePageState extends State { isShowAppBar: true, backgroundColor: Colors.grey[100], // appBarTitle: TranslationBase.of(context).radiology, - appBar: PatientProfileHeaderNewDesignAppBar( + appBar: PatientProfileAppBar( patient, patient.patientType.toString() ?? '0', arrivalType, diff --git a/lib/screens/patients/profile/referral/refer-patient-screen-in-patient.dart b/lib/screens/patients/profile/referral/refer-patient-screen-in-patient.dart index 658ad895..11ace2f6 100644 --- a/lib/screens/patients/profile/referral/refer-patient-screen-in-patient.dart +++ b/lib/screens/patients/profile/referral/refer-patient-screen-in-patient.dart @@ -8,7 +8,7 @@ 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'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; 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'; @@ -136,7 +136,7 @@ class _PatientMakeInPatientReferralScreenState extends State { baseViewModel: model, appBarTitle: TranslationBase.of(context).referPatient, isShowAppBar: true, - appBar: PatientProfileHeaderNewDesignAppBar( + appBar: PatientProfileAppBar( patient, patientType, arrivalType), body: SingleChildScrollView( child: Container( 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 d9af7457..ab5e02d0 100644 --- a/lib/screens/patients/profile/soap_update/update_soap_index.dart +++ b/lib/screens/patients/profile/soap_update/update_soap_index.dart @@ -7,7 +7,7 @@ import 'package:doctor_app_flutter/models/SOAP/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'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -82,7 +82,7 @@ class _UpdateSoapIndexState extends State mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ - PatientProfileHeaderNewDesign(patient, '7', '7',), + PatientProfileAppBar(patient, '7', '7',isFromSOAP: true,), Container( width: double.infinity, height: 1, 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 37a7a60f..a67e213f 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 @@ -6,7 +6,7 @@ import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/patients/profile/vital_sign/vital_sign_item.dart'; import 'package:doctor_app_flutter/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; 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/errors/error_message.dart'; @@ -40,7 +40,7 @@ class VitalSignDetailsScreen extends StatelessWidget { baseViewModel: mode, isShowAppBar: true, backgroundColor: Theme.of(context).scaffoldBackgroundColor, - appBar: PatientProfileHeaderNewDesignAppBar( + appBar: PatientProfileAppBar( patient, patientType, arrivalType), appBarTitle: TranslationBase.of(context).vitalSign, body: mode.patientVitalSignsHistory.length > 0 diff --git a/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart b/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart index 49f82c2f..0c41386c 100644 --- a/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart +++ b/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart @@ -7,7 +7,7 @@ import 'package:doctor_app_flutter/screens/patients/profile/vital_sign/vital_sig import 'package:doctor_app_flutter/screens/patients/profile/vital_sign/vital_sing_chart_and_detials.dart'; import 'package:doctor_app_flutter/screens/patients/profile/vital_sign/vital_sing_chart_blood_pressure.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/material.dart'; @@ -190,7 +190,7 @@ class VitalSignItemDetailsScreen extends StatelessWidget { appBarTitle: pageTitle, backgroundColor: Color.fromRGBO(248, 248, 248, 1), isShowAppBar: true, - appBar: PatientProfileHeaderNewDesignAppBar( + appBar: PatientProfileAppBar( patient, patientType, arrivalType), body: SingleChildScrollView( child: Column( diff --git a/lib/screens/prescription/prescription_item_in_patient_page.dart b/lib/screens/prescription/prescription_item_in_patient_page.dart index b6d27af6..472f6dd8 100644 --- a/lib/screens/prescription/prescription_item_in_patient_page.dart +++ b/lib/screens/prescription/prescription_item_in_patient_page.dart @@ -5,7 +5,7 @@ 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'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/cupertino.dart'; @@ -44,7 +44,7 @@ class PrescriptionItemsInPatientPage extends StatelessWidget { isShowAppBar: true, backgroundColor: Colors.grey[100], baseViewModel: model, - appBar: PatientProfileHeaderNewDesignAppBar( + appBar: PatientProfileAppBar( patient, patient.patientType.toString(), patient.arrivedOn), body: SingleChildScrollView( child: Container( diff --git a/lib/screens/prescription/prescription_items_page.dart b/lib/screens/prescription/prescription_items_page.dart index a68f6f56..ac9ebb2a 100644 --- a/lib/screens/prescription/prescription_items_page.dart +++ b/lib/screens/prescription/prescription_items_page.dart @@ -4,7 +4,7 @@ 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'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; 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/dialogs/ShowImageDialog.dart'; @@ -28,16 +28,18 @@ class PrescriptionItemsPage extends StatelessWidget { isShowAppBar: true, backgroundColor: Colors.grey[100], baseViewModel: model, - appBar: PatientProfileHeaderWhitAppointmentAppBar( - patient: patient, - patientType: patientType??"0", - arrivalType: arrivalType??"0", + appBar: PatientProfileAppBar( + patient, + patientType??"0", + arrivalType??"0", clinic: prescriptions.clinicDescription, branch: prescriptions.name, isPrescriptions: true, appointmentDate: AppDateUtils.getDateTimeFromServerFormat(prescriptions.appointmentDate), doctorName: prescriptions.doctorName, profileUrl: prescriptions.doctorImageURL, + isAppointmentHeader: true, + height: 325, ), body: SingleChildScrollView( child: Container( diff --git a/lib/screens/prescription/prescriptions_page.dart b/lib/screens/prescription/prescriptions_page.dart index 224d30e4..17b36233 100644 --- a/lib/screens/prescription/prescriptions_page.dart +++ b/lib/screens/prescription/prescriptions_page.dart @@ -8,7 +8,7 @@ import 'package:doctor_app_flutter/screens/procedures/base_add_procedure_tab_pag import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/add-order/addNewOrder.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; 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/doctor_card.dart'; @@ -35,7 +35,7 @@ class PrescriptionsPage extends StatelessWidget { baseViewModel: model, isShowAppBar: true, backgroundColor: Colors.grey[100], - appBar: PatientProfileHeaderNewDesignAppBar( + appBar: PatientProfileAppBar( patient, patientType ?? '0', arrivalType, diff --git a/lib/screens/procedures/procedure_screen.dart b/lib/screens/procedures/procedure_screen.dart index 756a19a0..aa51fc18 100644 --- a/lib/screens/procedures/procedure_screen.dart +++ b/lib/screens/procedures/procedure_screen.dart @@ -8,7 +8,7 @@ import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/procedures/update-procedure.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/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/material.dart'; @@ -44,7 +44,7 @@ class ProcedureScreen extends StatelessWidget { isShowAppBar: true, backgroundColor: Colors.grey[100], baseViewModel: model, - appBar: PatientProfileHeaderNewDesignAppBar( + appBar: PatientProfileAppBar( patient, arrivalType ?? '0', patientType, diff --git a/lib/screens/sick-leave/add-sickleave.dart b/lib/screens/sick-leave/add-sickleave.dart index 734e849a..d7759f9e 100644 --- a/lib/screens/sick-leave/add-sickleave.dart +++ b/lib/screens/sick-leave/add-sickleave.dart @@ -9,7 +9,7 @@ import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/sick-leave/sick_leave.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; 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/rounded_container_widget.dart'; @@ -34,7 +34,7 @@ class AddSickLeavScreen extends StatelessWidget { baseViewModel: model, isShowAppBar: true, backgroundColor: Colors.grey[100], - appBar: PatientProfileHeaderNewDesignAppBar( + appBar: PatientProfileAppBar( patient, routeArgs['patientType'] ?? "0", routeArgs['arrivalType'] ?? "0", diff --git a/lib/screens/sick-leave/show-sickleave.dart b/lib/screens/sick-leave/show-sickleave.dart index 3fbb3287..4ead8cd3 100644 --- a/lib/screens/sick-leave/show-sickleave.dart +++ b/lib/screens/sick-leave/show-sickleave.dart @@ -5,7 +5,7 @@ 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'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; 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/rounded_container_widget.dart'; @@ -25,7 +25,7 @@ class ShowSickLeaveScreen extends StatelessWidget { baseViewModel: model, isShowAppBar: true, backgroundColor: Colors.grey[100], - appBar: PatientProfileHeaderNewDesignAppBar( + appBar: PatientProfileAppBar( patient, routeArgs['patientType'] ?? "0", routeArgs['arrivalType'] ?? "0", diff --git a/lib/util/date-utils.dart b/lib/util/date-utils.dart index 2839c86f..511b99e9 100644 --- a/lib/util/date-utils.dart +++ b/lib/util/date-utils.dart @@ -389,4 +389,26 @@ class AppDateUtils { return date; } + + + static convertDateFormatImproved(String str) { + String newDate; + const start = "/Date("; + if (str.isNotEmpty) { + const end = "+0300)"; + + 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))); + newDate = date.year.toString() + + "/" + + date.month.toString().padLeft(2, '0') + + "/" + + date.day.toString().padLeft(2, '0'); + } + + return newDate??''; + } } diff --git a/lib/widgets/patients/profile/GeneralLabResultHeader.dart b/lib/widgets/patients/profile/GeneralLabResultHeader.dart deleted file mode 100644 index 153a4ccf..00000000 --- a/lib/widgets/patients/profile/GeneralLabResultHeader.dart +++ /dev/null @@ -1,349 +0,0 @@ -import 'package:doctor_app_flutter/config/config.dart'; -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/icons_app/doctor_app_icons.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'; -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'; -import 'package:provider/provider.dart'; -import 'package:url_launcher/url_launcher.dart'; - -class GeneralLabResultHeader extends StatelessWidget - with PreferredSizeWidget { - final PatiantInformtion patient; - final String patientType; - final String arrivalType; - final String doctorName; - final String branch; - final DateTime appointmentDate; - final String profileUrl; - final String invoiceNO; - final String orderNo; - final bool isPrescriptions; - final bool isMedicalFile; - final String episode; - final String vistDate; - - final String clinic; - GeneralLabResultHeader( - {this.patient, - this.patientType, - this.arrivalType, - this.doctorName, - this.branch, - this.appointmentDate, - this.profileUrl, - this.invoiceNO, - this.orderNo, - this.isPrescriptions = false, - this.clinic, - this.isMedicalFile = false, - this.episode, - this.vistDate}); - - @override - Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); - int gender = 1; - if (patient.patientDetails != null) { - gender = patient.patientDetails.gender; - } else { - gender = patient.gender; - } - - return Container( - padding: EdgeInsets.only(left: 0, right: 5, bottom: 5, top: 5), - decoration: BoxDecoration( - color: Colors.white, - ), - height: MediaQuery.of(context).size.height * 0.23, - child: Container( - padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), - margin: EdgeInsets.only(top: 50), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - 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( - patient.firstName != null - ? (Helpers.capitalize(patient.firstName) + - " " + - Helpers.capitalize(patient.lastName)) - : Helpers.capitalize(patient.fullName??patient?.patientDetails?.fullName??""), - fontSize: SizeConfig.textMultiplier * 2.2, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - ), - ), - gender == 1 - ? Icon( - DoctorApp.male_2, - color: Colors.blue, - ) - : Icon( - DoctorApp.female_1, - color: Colors.pink, - ), - Container( - margin: EdgeInsets.symmetric(horizontal: 4), - child: InkWell( - onTap: () { - launch("tel://" + patient?.mobileNumber??""); - }, - child: Icon( - Icons.phone, - color: Colors.black87, - ), - ), - ) - ]), - ), - Row(children: [ - Padding( - padding: EdgeInsets.only(left: 12.0), - child: Container( - width: 60, - height: 60, - child: Image.asset( - gender == 1 - ? 'assets/images/male_avatar.png' - : 'assets/images/female_avatar.png', - fit: BoxFit.cover, - ), - ), - ), - SizedBox( - width: 10, - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SERVICES_PATIANT2[int.parse(patientType)] == - "patientArrivalList" - ? Container( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - patient.patientStatusType == 43 - ? AppText( - TranslationBase.of(context).arrivedP, - color: Colors.green, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - fontSize: 12, - ) - : AppText( - TranslationBase.of(context).notArrived, - color: Colors.red[800], - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - fontSize: 12, - ), - arrivalType == '1' || patient.arrivedOn == null - ? AppText( - patient.startTime != null - ? patient.startTime - : '', - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - ) - : AppText( - AppDateUtils.convertStringToDateFormat( - patient.arrivedOn, - 'MM-dd-yyyy HH:mm'), - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - ) - ], - )) - : SizedBox(), - if (SERVICES_PATIANT2[int.parse(patientType)] == - "List_MyOutPatient") - Container( - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).appointmentDate + - " : ", - fontSize: 14, - ), - patient.startTime != null - ? Container( - height: 15, - width: 60, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(25), - color: HexColor("#20A169"), - ), - child: AppText( - patient.startTime ?? "", - color: Colors.white, - fontSize: 1.5 * SizeConfig.textMultiplier, - textAlign: TextAlign.center, - fontWeight: FontWeight.bold, - ), - ) - : SizedBox(), - SizedBox( - width: 3.5, - ), - Container( - child: AppText( - convertDateFormat2( - patient.appointmentDate.toString() ?? ''), - fontSize: 1.5 * SizeConfig.textMultiplier, - fontWeight: FontWeight.bold, - ), - ), - SizedBox( - height: 0.5, - ) - ], - ), - margin: EdgeInsets.only( - top: 8, - ), - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - RichText( - text: TextSpan( - style: TextStyle( - fontSize: 1.6 * SizeConfig.textMultiplier, - color: Colors.black, - fontFamily: 'Poppins', - ), - children: [ - new TextSpan( - text: TranslationBase.of(context).fileNumber, - style: TextStyle( - fontSize: 14, fontFamily: 'Poppins')), - new TextSpan( - text: patient?.patientId?.toString() ?? "", - style: TextStyle( - fontWeight: FontWeight.w700, - fontFamily: 'Poppins', - fontSize: 14)), - ], - ), - ), - Row( - children: [ - AppText( - patient.nationalityName ?? - patient.nationality ?? - "", - fontWeight: FontWeight.bold, - fontSize: 12, - ), - patient.nationality != null - ? ClipRRect( - borderRadius: BorderRadius.circular(20.0), - child: Image.network( - patient?.nationalityFlagURL??"", - height: 25, - width: 30, - errorBuilder: (BuildContext context, - Object exception, - StackTrace stackTrace) { - return Text('No Image'); - }, - )) - : SizedBox() - ], - ) - ], - ), - Container( - child: RichText( - text: new TextSpan( - style: new TextStyle( - fontSize: 1.6 * SizeConfig.textMultiplier, - color: Colors.black, - fontFamily: 'Poppins', - ), - children: [ - 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)}", - style: TextStyle( - fontWeight: FontWeight.w700, fontSize: 14)), - ], - ), - ), - ), - Container( - child: RichText( - text: new TextSpan( - style: new TextStyle( - fontSize: 1.6 * SizeConfig.textMultiplier, - color: Colors.black, - fontFamily: 'Poppins', - ), - children: [ - new TextSpan( - text: "Result Date: ", - style: TextStyle(fontSize: 14)), - new TextSpan( - text: - '${AppDateUtils.getDayMonthYearDateFormatted(appointmentDate, isArabic: projectViewModel.isArabic)}', - style: TextStyle( - fontWeight: FontWeight.w700, fontSize: 14)), - ], - ), - ), - ), - ], - ), - ), - ]), - ], - ), - ), - ); - } - - convertDateFormat2(String str) { - String newDate = ""; - const start = "/Date("; - const end = "+0300)"; - - if (str.isNotEmpty) { - 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))); - newDate = date.year.toString() + - "/" + - date.month.toString().padLeft(2, '0') + - "/" + - date.day.toString().padLeft(2, '0'); - } - - return newDate.toString(); - } - - - - @override - Size get preferredSize => Size(double.maxFinite, 310); -} diff --git a/lib/widgets/patients/profile/PatientHeaderWidgetNoAvatar.dart b/lib/widgets/patients/profile/PatientHeaderWidgetNoAvatar.dart deleted file mode 100644 index aef7a161..00000000 --- a/lib/widgets/patients/profile/PatientHeaderWidgetNoAvatar.dart +++ /dev/null @@ -1,73 +0,0 @@ -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:flutter/material.dart'; - -class PatientHeaderWidgetNoAvatar extends StatelessWidget { - final PatiantInformtion patient; - - PatientHeaderWidgetNoAvatar(this.patient); - - @override - Widget build(BuildContext context) { - return Column( - children: [ - Container( - margin: EdgeInsets.all(16), - child: Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - patient.firstName + ' ' + patient.lastName, - fontWeight: FontWeight.bold, - fontSize: SizeConfig.textMultiplier * 2.2, - ), - Row( - children: [ - AppText( - "VIP", - fontWeight: FontWeight.bold, - fontSize: SizeConfig.textMultiplier * 2.2, - ), - SizedBox( - width: 8, - ), - AppText( - " ${patient.age}", - fontWeight: FontWeight.normal, - fontSize: SizeConfig.textMultiplier * 2.0, - ), - ], - ), - AppText( - patient.visitType ?? "", - fontWeight: FontWeight.bold, - fontSize: SizeConfig.textMultiplier * 2.0, - ), - AppText( - "${patient.companyName != null ? patient.companyName : ""}", - fontWeight: FontWeight.bold, - fontSize: SizeConfig.textMultiplier * 2.0, - ), - ], - ), - ), - Icon( - Icons.info_outline, - color: Colors.black, - ), - ], - ), - ), - Container( - width: double.infinity, - height: 1, - color: Color(0xffCCCCCC), - ), - ], - ); - } -} diff --git a/lib/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart new file mode 100644 index 00000000..dd0c48e4 --- /dev/null +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -0,0 +1,599 @@ +import 'package:doctor_app_flutter/config/config.dart'; +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/icons_app/doctor_app_icons.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'; +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'; +import 'package:intl/intl.dart'; +import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher.dart'; + +import 'large_avatar.dart'; + +class PatientProfileAppBar extends StatelessWidget + with PreferredSizeWidget { + final PatiantInformtion patient; + final String patientType; + final String arrivalType; + final double height; + final bool isInpatient; + final bool isDischargedPatient; + final bool isFromLiveCare; + + final String doctorName; + final String branch; + final DateTime appointmentDate; + final String profileUrl; + final String invoiceNO; + final String orderNo; + final bool isPrescriptions; + final bool isMedicalFile; + final String episode; + final String visitDate; + final String clinic; + final bool isAppointmentHeader; + final bool isFromSOAP; + final bool isFromLabResult; + + PatientProfileAppBar( + this.patient, this.patientType, this.arrivalType, + {this.height = 0.0, + this.isInpatient = false, + this.isDischargedPatient = false, + this.isFromLiveCare = false, + this.doctorName, + this.branch, + this.appointmentDate, + this.profileUrl, + this.invoiceNO, + this.orderNo, + this.isPrescriptions = false, + this.clinic, + this.isMedicalFile = false, + this.episode, + this.visitDate, + this.isAppointmentHeader = false, + this.isFromSOAP = false, + this.isFromLabResult = false}); + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + + int gender = 1; + if (patient.patientDetails != null) { + gender = patient.patientDetails.gender; + } else { + gender = patient.gender; + } + + return Container( + padding: EdgeInsets.only( + left: 0, + right: 5, + bottom: 5, + ), + decoration: BoxDecoration( + color: Colors.white, + ), + height: height == 0 + ? isInpatient + ? 215 + : isAppointmentHeader + ? 310 + : 200 + : height, + 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( + patient.firstName != null + ? (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', + ), + ), + gender == 1 + ? Icon( + DoctorApp.male_2, + color: Colors.blue, + ) + : Icon( + DoctorApp.female_1, + color: Colors.pink, + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 4), + child: InkWell( + onTap: () { + launch("tel://" + patient.mobileNumber); + }, + child: Icon( + Icons.phone, + color: Colors.black87, + ), + ), + ), + ]), + ), + Row(children: [ + Padding( + padding: EdgeInsets.only(left: 12.0), + child: Container( + width: 60, + height: 60, + child: Image.asset( + gender == 1 + ? 'assets/images/male_avatar.png' + : 'assets/images/female_avatar.png', + fit: BoxFit.cover, + ), + ), + ), + SizedBox( + width: 10, + ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SERVICES_PATIANT2[int.parse(patientType)] == + "patientArrivalList" + ? Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + patient.patientStatusType == 43 + ? AppText( + TranslationBase + .of(context) + .arrivedP, + color: Colors.green, + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + fontSize: 12, + ) + : AppText( + TranslationBase + .of(context) + .notArrived, + color: Colors.red[800], + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + fontSize: 12, + ), + arrivalType == '1' || patient.arrivedOn == null + ? AppText( + patient.startTime != null + ? patient.startTime + : '', + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + ) + : AppText( + patient.arrivedOn != null + ? (isFromSOAP ? AppDateUtils + .getDayMonthYearDateFormatted( + AppDateUtils.convertStringToDate( + patient.arrivedOn)) : AppDateUtils + .convertStringToDateFormat( + patient.arrivedOn, + 'MM-dd-yyyy HH:mm')) + : '', + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + ) + ], + )) + : SizedBox(), + if (SERVICES_PATIANT2[int.parse(patientType)] == + "List_MyOutPatient" && !isFromLiveCare) + Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + AppText( + TranslationBase + .of(context) + .appointmentDate + + " : ", + fontSize: 14, + ), + patient.startTime != null + ? Container( + height: 15, + width: 60, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(25), + color: HexColor("#20A169"), + ), + child: AppText( + patient.startTime ?? "", + color: Colors.white, + fontSize: 1.5 * SizeConfig.textMultiplier, + textAlign: TextAlign.center, + fontWeight: FontWeight.bold, + ), + ) + : SizedBox(), + SizedBox( + width: 3.5, + ), + Container( + child: AppText( + AppDateUtils.convertDateFormatImproved( + patient.appointmentDate ?? ''), + fontSize: 1.5 * SizeConfig.textMultiplier, + fontWeight: FontWeight.bold, + ), + ), + SizedBox( + height: 0.5, + ) + ], + ), + margin: EdgeInsets.only( + top: 8, + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + RichText( + text: TextSpan( + style: TextStyle( + fontSize: 1.6 * SizeConfig.textMultiplier, + color: Colors.black), + children: [ + new TextSpan( + text: TranslationBase.of(context).fileNumber, + style: TextStyle( + fontSize: 12, fontFamily: 'Poppins')), + new TextSpan( + text: patient.patientId.toString(), + style: TextStyle( + fontWeight: FontWeight.w700, + fontFamily: 'Poppins', + fontSize: 14)), + ], + ), + ), + Row( + children: [ + AppText( + patient.nationalityName ?? patient.nationality?? patient.nationalityId ?? '', + fontWeight: FontWeight.bold, + fontSize: 12, + ), + patient.nationalityFlagURL != null + ? ClipRRect( + borderRadius: BorderRadius.circular(20.0), + child: Image.network( + patient.nationalityFlagURL, + height: 25, + width: 30, + errorBuilder: (BuildContext context, + Object exception, + StackTrace stackTrace) { + return Text('No Image'); + }, + )) + : SizedBox() + ], + ) + ], + ), + Container( + child: RichText( + text: new TextSpan( + style: new TextStyle( + fontSize: 1.6 * SizeConfig.textMultiplier, + color: Colors.black, + fontFamily: 'Poppins', + ), + children: [ + 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)), + ], + ), + ), + ), + if(isFromLabResult)Container( + child: RichText( + text: new TextSpan( + style: new TextStyle( + fontSize: 1.6 * SizeConfig.textMultiplier, + color: Colors.black, + fontFamily: 'Poppins', + ), + children: [ + new TextSpan( + text: "Result Date: ", + style: TextStyle(fontSize: 14)), + new TextSpan( + text: + '${AppDateUtils.getDayMonthYearDateFormatted(appointmentDate, isArabic: projectViewModel.isArabic)}', + style: TextStyle( + fontWeight: FontWeight.w700, fontSize: 14)), + ], + ), + ), + ), + if(isInpatient) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + child: RichText( + text: new TextSpan( + style: new TextStyle( + 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)), + ]))), + if (patient.admissionDate != null) + Row( + children: [ + AppText( + "${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) + else + AppText( + "${DateTime + .now() + .difference(AppDateUtils + .getDateTimeFromServerFormat( + patient.admissionDate)) + .inDays + 1}", + fontSize: 15, + fontWeight: FontWeight.w700), + ], + ), + ], + ), + if(isAppointmentHeader) + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: 30, + height: 30, + margin: EdgeInsets.only( + left: projectViewModel.isArabic ? 10 : 85, + right: projectViewModel.isArabic ? 85 : 10, + top: 5), + decoration: BoxDecoration( + shape: BoxShape.rectangle, + border: Border( + bottom: BorderSide( + color: Colors.grey[400], width: 2.5), + left: BorderSide( + color: Colors.grey[400], width: 2.5), + )), + ), + Expanded( + child: Container( + margin: EdgeInsets.only(top: 10), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + child: LargeAvatar( + name: doctorName ?? "", + url: profileUrl, + ), + width: 25, + height: 25, + margin: EdgeInsets.only(top: 10), + ), + + + Expanded( + flex: 5, + child: Container( + margin: EdgeInsets.all(10), + child: Column( + crossAxisAlignment: CrossAxisAlignment + .start, + children: [ + AppText( + '${TranslationBase + .of(context) + .dr}$doctorName', + color: Colors.black, + fontWeight: FontWeight.w600, + fontSize: 9, + ), + if (orderNo != null && + !isPrescriptions) + Row( + children: [ + AppText('Order No: ', + color: Colors.grey[800], + fontSize: 12), + AppText(orderNo ?? '', + fontSize: 12) + ], + ), + if (invoiceNO != null && + !isPrescriptions) + Row( + children: [ + AppText('Invoice: ', + color: Colors.grey[800], + fontSize: 12), + AppText(invoiceNO ?? "", + fontSize: 12) + ], + ), + if (branch != null) + Row( + children: [ + AppText('Branch: ', + color: Colors.grey[800], + fontSize: 12), + AppText(branch ?? '', + fontSize: 12) + ], + ), + + if (clinic != null) + Row( + children: [ + AppText('Clinic: ', + color: Colors.grey[800], + fontSize: 12), + AppText(clinic ?? '', + fontSize: 12) + ], + ), + if (isMedicalFile && + episode != null) + Row( + children: [ + AppText('Episode: ', + color: Colors.grey[800], + fontSize: 12), + AppText(episode ?? '', + fontSize: 12) + ], + ), + if (isMedicalFile && + visitDate != null) + Row( + children: [ + AppText('Visit Date: ', + color: Colors.grey[800], + fontSize: 12), + AppText(visitDate ?? '', + fontSize: 12) + ], + ), + if (!isMedicalFile) + Row( + children: [ + Expanded( + child: AppText( + !isPrescriptions + ? 'Result Date: ' + : 'Prescriptions Date ', + color: Colors.grey[800], + fontSize: 12, + ), + ), + AppText( + '${AppDateUtils + .getDayMonthYearDateFormatted( + appointmentDate, + isArabic: projectViewModel + .isArabic)}', + fontSize: 14, + ) + ], + ) + ]), + ), + ), + ], + ), + ), + ), + ], + ) + ], + ), + ), + ]), + ], + ), + ), + ); + } + + + + + 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()); + } + + myBoxDecoration() { + return BoxDecoration( + border: Border( + top: BorderSide( + color: Colors.green, + width: 5, + ), + ), + borderRadius: BorderRadius.circular(10)); + } + + @override + Size get preferredSize => + Size(double.maxFinite, height == 0 + ? isInpatient ? 215 : isAppointmentHeader ? 310 : 200 + : height); +} 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 deleted file mode 100644 index 995ac57a..00000000 --- a/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart +++ /dev/null @@ -1,371 +0,0 @@ -import 'package:doctor_app_flutter/config/config.dart'; -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/icons_app/doctor_app_icons.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'; -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'; -import 'package:intl/intl.dart'; -import 'package:url_launcher/url_launcher.dart'; - -class PatientProfileHeaderNewDesignAppBar extends StatelessWidget - with PreferredSizeWidget { - final PatiantInformtion patient; - final String patientType; - final String arrivalType; - final double height; - final bool isInpatient; - final bool isDischargedPatient; - final bool isFromLiveCare; - - PatientProfileHeaderNewDesignAppBar( - this.patient, this.patientType, this.arrivalType, {this.height = 0.0, this.isInpatient=false, this.isDischargedPatient=false, this.isFromLiveCare = false}); - - @override - Widget build(BuildContext context) { - int gender = 1; - if (patient.patientDetails != null) { - gender = patient.patientDetails.gender; - } else { - gender = patient.gender; - } - return Container( - padding: EdgeInsets.only( - left: 0, - right: 5, - bottom: 5, - ), - decoration: BoxDecoration( - color: Colors.white, - ), - height: height == 0 ? isInpatient? 215:200 : height, - 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( - patient.firstName != null - ? (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', - ), - ), - gender == 1 - ? Icon( - DoctorApp.male_2, - color: Colors.blue, - ) - : Icon( - DoctorApp.female_1, - color: Colors.pink, - ), - Container( - margin: EdgeInsets.symmetric(horizontal: 4), - child: InkWell( - onTap: () { - launch("tel://" + patient.mobileNumber); - }, - child: Icon( - Icons.phone, - color: Colors.black87, - ), - ), - ), - ]), - ), - Row(children: [ - Padding( - padding: EdgeInsets.only(left: 12.0), - child: Container( - width: 60, - height: 60, - child: Image.asset( - gender == 1 - ? 'assets/images/male_avatar.png' - : 'assets/images/female_avatar.png', - fit: BoxFit.cover, - ), - ), - ), - SizedBox( - width: 10, - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SERVICES_PATIANT2[int.parse(patientType)] == - "patientArrivalList" - ? Container( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - patient.patientStatusType == 43 - ? AppText( - TranslationBase.of(context).arrivedP, - color: Colors.green, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - fontSize: 12, - ) - : AppText( - TranslationBase.of(context).notArrived, - color: Colors.red[800], - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - fontSize: 12, - ), - arrivalType == '1'|| patient.arrivedOn == null - ? AppText( - patient.startTime != null - ? patient.startTime - : '', - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - ) - : AppText( - patient.arrivedOn != null - ? AppDateUtils.convertStringToDateFormat( - patient.arrivedOn, - 'MM-dd-yyyy HH:mm') - : '', - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - ) - ], - )) - : SizedBox(), - if (SERVICES_PATIANT2[int.parse(patientType)] == - "List_MyOutPatient" && !isFromLiveCare) - Container( - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).appointmentDate + - " : ", - fontSize: 14, - ), - patient.startTime != null - ? Container( - height: 15, - width: 60, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(25), - color: HexColor("#20A169"), - ), - child: AppText( - patient.startTime??"", - color: Colors.white, - fontSize: 1.5 * SizeConfig.textMultiplier, - textAlign: TextAlign.center, - fontWeight: FontWeight.bold, - ), - ) - : SizedBox(), - SizedBox( - width: 3.5, - ), - Container( - child: AppText( - convertDateFormat2( - patient.appointmentDate ?? ''), - fontSize: 1.5 * SizeConfig.textMultiplier, - fontWeight: FontWeight.bold, - ), - ), - SizedBox( - height: 0.5, - ) - ], - ), - margin: EdgeInsets.only( - top: 8, - ), - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - RichText( - text: TextSpan( - style: TextStyle( - fontSize: 1.6 * SizeConfig.textMultiplier, - color: Colors.black), - children: [ - new TextSpan( - text: TranslationBase.of(context).fileNumber, - style: TextStyle( - fontSize: 12, fontFamily: 'Poppins')), - new TextSpan( - text: patient.patientId.toString(), - style: TextStyle( - fontWeight: FontWeight.w700, - fontFamily: 'Poppins', - fontSize: 14)), - ], - ), - ), - Row( - children: [ - AppText( - patient.nationalityName ?? patient.nationality?? patient.nationalityId ?? '', - fontWeight: FontWeight.bold, - fontSize: 12, - ), - patient.nationalityFlagURL != null - ? ClipRRect( - borderRadius: BorderRadius.circular(20.0), - child: Image.network( - patient.nationalityFlagURL, - height: 25, - width: 30, - errorBuilder: (BuildContext context, - Object exception, - StackTrace stackTrace) { - return Text('No Image'); - }, - )) - : SizedBox() - ], - ) - ], - ), - Container( - child: RichText( - text: new TextSpan( - style: new TextStyle( - fontSize: 1.6 * SizeConfig.textMultiplier, - color: Colors.black, - fontFamily: 'Poppins', - ), - children: [ - 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)), - ], - ), - ), - ), - if(isInpatient) - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - child: RichText( - text: new TextSpan( - style: new TextStyle( - 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)), - ]))), - if (patient.admissionDate != null) - Row( - children: [ - AppText( - "${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) - else - AppText( - "${DateTime.now().difference(AppDateUtils.getDateTimeFromServerFormat(patient.admissionDate)).inDays + 1}", - fontSize: 15, - fontWeight: FontWeight.w700), - ], - ), - ], - ) - ], - ), - ), - ]), - ], - ), - ), - ); - } - - convertDateFormat2(String str) { - String newDate; - const start = "/Date("; - if (str.isNotEmpty) { - const end = "+0300)"; - - 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))); - newDate = date.year.toString() + - "/" + - date.month.toString().padLeft(2, '0') + - "/" + - date.day.toString().padLeft(2, '0'); - } - - 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()); - } - - myBoxDecoration() { - return BoxDecoration( - border: Border( - top: BorderSide( - color: Colors.green, - width: 5, - ), - ), - borderRadius: BorderRadius.circular(10)); - } - - @override - Size get preferredSize => Size(double.maxFinite, 200); -} diff --git a/lib/widgets/patients/profile/patient-profile-header-new-design.dart b/lib/widgets/patients/profile/patient-profile-header-new-design.dart deleted file mode 100644 index 1db29087..00000000 --- a/lib/widgets/patients/profile/patient-profile-header-new-design.dart +++ /dev/null @@ -1,316 +0,0 @@ -import 'package:doctor_app_flutter/config/config.dart'; -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/icons_app/doctor_app_icons.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'; -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'; -import 'package:intl/intl.dart'; -import 'package:url_launcher/url_launcher.dart'; - -class PatientProfileHeaderNewDesign extends StatelessWidget { - final PatiantInformtion patient; - final String patientType; - final String arrivalType; - final double height; - final bool isHaveMargin; - - PatientProfileHeaderNewDesign( - this.patient, this.patientType, this.arrivalType, - {this.height = 0.0, this.isHaveMargin=true}); - - @override - Widget build(BuildContext context) { - int gender = 1; - if (patient.patientDetails != null) { - gender = patient.patientDetails.gender; - } else { - gender = patient.gender; - } - - return Container( - padding: EdgeInsets.only( - left: 0, - right: 5, - bottom: 5, - ), - decoration: BoxDecoration( - color: Colors.white, - ), - height: height == 0 ? 200 : height, - 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( - patient.firstName != null - ? (Helpers.capitalize(patient.firstName) + - " " + - Helpers.capitalize(patient.lastName)) - : Helpers.capitalize(patient.patientDetails.fullName), - fontSize: SizeConfig.textMultiplier * 2.2, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - ), - ), - gender == 1 - ? Icon( - DoctorApp.male_2, - color: Colors.blue, - ) - : Icon( - DoctorApp.female_1, - color: Colors.pink, - ), - Container( - margin: EdgeInsets.symmetric(horizontal: 4), - child: InkWell( - onTap: () { - launch("tel://" + patient.mobileNumber); - }, - child: Icon( - Icons.phone, - color: Colors.black87, - ), - ), - ), - ]), - ), - Row(children: [ - Padding( - padding: EdgeInsets.only(left: 12.0), - child: Container( - width: 60, - height: 60, - child: Image.asset( - gender == 1 - ? 'assets/images/male_avatar.png' - : 'assets/images/female_avatar.png', - fit: BoxFit.cover, - ), - ), - ), - SizedBox( - width: 10, - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SERVICES_PATIANT2[int.parse(patientType)] == - "patientArrivalList" - ? Container( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - patient.patientStatusType == 43 - ? AppText( - TranslationBase.of(context).arrivedP, - color: Colors.green, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - fontSize: 12, - ) - : AppText( - TranslationBase.of(context).notArrived, - color: Colors.red[800], - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - fontSize: 12, - ), - arrivalType == '1' || patient.arrivedOn == null - ? AppText( - patient.startTime != null - ? patient.startTime - : '', - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - ) - : AppText( - AppDateUtils.getDayMonthYearDateFormatted(AppDateUtils.convertStringToDate(patient.arrivedOn)), - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - ) - ], - )) - : SizedBox(), - if (SERVICES_PATIANT2[int.parse(patientType)] == - "List_MyOutPatient") - Container( - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).appointmentDate + - " : ", - fontSize: 14, - ), - patient.startTime != null - ? Container( - height: 15, - width: 60, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(25), - color: HexColor("#20A169"), - ), - child: AppText( - patient.startTime ?? "", - color: Colors.white, - fontSize: 1.5 * SizeConfig.textMultiplier, - textAlign: TextAlign.center, - fontWeight: FontWeight.bold, - ), - ) - : SizedBox(), - SizedBox( - width: 3.5, - ), - Container( - child: AppText( - convertDateFormat2( - patient.appointmentDate.toString() ?? ''), - fontSize: 1.5 * SizeConfig.textMultiplier, - fontWeight: FontWeight.bold, - ), - ), - SizedBox( - height: 0.5, - ) - ], - ), - margin: EdgeInsets.only( - top: 8, - ), - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - RichText( - text: TextSpan( - style: TextStyle( - fontSize: 1.6 * SizeConfig.textMultiplier, - color: Colors.black), - children: [ - new TextSpan( - text: TranslationBase.of(context).fileNumber, - style: TextStyle( - fontSize: 12, fontFamily: 'Poppins')), - new TextSpan( - text: patient.patientId.toString(), - style: TextStyle( - fontWeight: FontWeight.w700, - fontFamily: 'Poppins', - fontSize: 14)), - ], - ), - ), - Row( - children: [ - AppText( - patient.nationalityName ?? - patient.nationality ?? - patient.nationalityId ?? - '', - fontWeight: FontWeight.bold, - fontSize: 12, - ), - patient.nationalityFlagURL != null - ? ClipRRect( - borderRadius: BorderRadius.circular(20.0), - child: Image.network( - patient.nationalityFlagURL, - height: 25, - width: 30, - errorBuilder: (BuildContext context, - Object exception, - StackTrace stackTrace) { - return Text('No Image'); - }, - )) - : SizedBox() - ], - ) - ], - ), - Container( - child: RichText( - text: new TextSpan( - style: new TextStyle( - fontSize: 1.6 * SizeConfig.textMultiplier, - color: Colors.black, - fontFamily: 'Poppins', - ), - children: [ - 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)}", - style: TextStyle( - fontWeight: FontWeight.w700, fontSize: 14)), - ], - ), - ), - ), - ], - ), - ), - ]), - ], - ), - ), - ); - } - - convertDateFormat2(String str) { - String newDate; - const start = "/Date("; - if (str.isNotEmpty) { - const end = "+0300)"; - - 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))); - newDate = date.year.toString() + - "/" + - date.month.toString().padLeft(2, '0') + - "/" + - date.day.toString().padLeft(2, '0'); - } - - return newDate.toString(); - } - - 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()); - } - - myBoxDecoration() { - return BoxDecoration( - border: Border( - top: BorderSide( - color: Colors.green, - width: 5, - ), - ), - borderRadius: BorderRadius.circular(10)); - } -} diff --git a/lib/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart b/lib/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart deleted file mode 100644 index 5d46e745..00000000 --- a/lib/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart +++ /dev/null @@ -1,456 +0,0 @@ -import 'package:doctor_app_flutter/config/config.dart'; -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/icons_app/doctor_app_icons.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'; -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'; -import 'package:intl/intl.dart'; -import 'package:provider/provider.dart'; -import 'package:url_launcher/url_launcher.dart'; - -import 'large_avatar.dart'; - -class PatientProfileHeaderWhitAppointmentAppBar extends StatelessWidget - with PreferredSizeWidget { - final PatiantInformtion patient; - final String patientType; - final String arrivalType; - final String doctorName; - final String branch; - final DateTime appointmentDate; - final String profileUrl; - final String invoiceNO; - final String orderNo; - final bool isPrescriptions; - final bool isMedicalFile; - final String episode; - final String vistDate; - - final String clinic; - PatientProfileHeaderWhitAppointmentAppBar( - {this.patient, - this.patientType, - this.arrivalType, - this.doctorName, - this.branch, - this.appointmentDate, - this.profileUrl, - this.invoiceNO, - this.orderNo, - this.isPrescriptions = false, - this.clinic, - this.isMedicalFile = false, - this.episode, - this.vistDate}); - - @override - Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); - int gender = 1; - if (patient.patientDetails != null) { - gender = patient.patientDetails.gender; - } else { - gender = patient.gender; - } - - return Container( - padding: EdgeInsets.only(left: 0, right: 5, bottom: 5, top: 5), - decoration: BoxDecoration( - color: Colors.white, - ), - //height: 300, - child: Container( - padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), - margin: EdgeInsets.only(top: 50), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - 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( - patient.firstName != null - ? (Helpers.capitalize(patient.firstName) + - " " + - Helpers.capitalize(patient.lastName)) - : Helpers.capitalize(patient.fullName??patient?.patientDetails?.fullName??""), - fontSize: SizeConfig.textMultiplier * 2.2, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - ), - ), - gender == 1 - ? Icon( - DoctorApp.male_2, - color: Colors.blue, - ) - : Icon( - DoctorApp.female_1, - color: Colors.pink, - ), - Container( - margin: EdgeInsets.symmetric(horizontal: 4), - child: InkWell( - onTap: () { - launch("tel://" + patient?.mobileNumber??""); - }, - child: Icon( - Icons.phone, - color: Colors.black87, - ), - ), - ) - ]), - ), - Row(children: [ - Padding( - padding: EdgeInsets.only(left: 12.0), - child: Container( - width: 60, - height: 60, - child: Image.asset( - gender == 1 - ? 'assets/images/male_avatar.png' - : 'assets/images/female_avatar.png', - fit: BoxFit.cover, - ), - ), - ), - SizedBox( - width: 10, - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SERVICES_PATIANT2[int.parse(patientType)] == - "patientArrivalList" - ? Container( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - patient.patientStatusType == 43 - ? AppText( - TranslationBase.of(context).arrivedP, - color: Colors.green, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - fontSize: 12, - ) - : AppText( - TranslationBase.of(context).notArrived, - color: Colors.red[800], - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - fontSize: 12, - ), - arrivalType == '1' || patient.arrivedOn == null - ? AppText( - patient.startTime != null - ? patient.startTime - : '', - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - ) - : AppText( - AppDateUtils.convertStringToDateFormat( - patient.arrivedOn, - 'MM-dd-yyyy HH:mm'), - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - ) - ], - )) - : SizedBox(), - if (SERVICES_PATIANT2[int.parse(patientType)] == - "List_MyOutPatient") - Container( - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).appointmentDate + - " : ", - fontSize: 14, - ), - patient.startTime != null - ? Container( - height: 15, - width: 60, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(25), - color: HexColor("#20A169"), - ), - child: AppText( - patient.startTime ?? "", - color: Colors.white, - fontSize: 1.5 * SizeConfig.textMultiplier, - textAlign: TextAlign.center, - fontWeight: FontWeight.bold, - ), - ) - : SizedBox(), - SizedBox( - width: 3.5, - ), - Container( - child: AppText( - convertDateFormat2( - patient.appointmentDate.toString() ?? ''), - fontSize: 1.5 * SizeConfig.textMultiplier, - fontWeight: FontWeight.bold, - ), - ), - SizedBox( - height: 0.5, - ) - ], - ), - margin: EdgeInsets.only( - top: 8, - ), - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - RichText( - text: TextSpan( - style: TextStyle( - fontSize: 1.6 * SizeConfig.textMultiplier, - color: Colors.black), - children: [ - new TextSpan( - text: TranslationBase.of(context).fileNumber, - style: TextStyle( - fontSize: 12, fontFamily: 'Poppins')), - new TextSpan( - text: patient?.patientId?.toString() ?? "", - style: TextStyle( - fontWeight: FontWeight.w700, - fontFamily: 'Poppins', - fontSize: 14)), - ], - ), - ), - Row( - children: [ - AppText( - patient.nationalityName ?? - patient.nationality ?? - "", - fontWeight: FontWeight.bold, - fontSize: 12, - ), - patient.nationality != null - ? ClipRRect( - borderRadius: BorderRadius.circular(20.0), - child: Image.network( - patient?.nationalityFlagURL??"", - height: 25, - width: 30, - errorBuilder: (BuildContext context, - Object exception, - StackTrace stackTrace) { - return Text('No Image'); - }, - )) - : SizedBox() - ], - ) - ], - ), - Container( - child: RichText( - text: new TextSpan( - style: new TextStyle( - fontSize: 1.6 * SizeConfig.textMultiplier, - color: Colors.black, - fontFamily: 'Poppins', - ), - children: [ - 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)}", - style: TextStyle( - fontWeight: FontWeight.w700, fontSize: 14)), - ], - ), - ), - ), - ], - ), - ), - ]), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - width: 30, - height: 30, - margin: EdgeInsets.only( - left: projectViewModel.isArabic ? 10 : 85, - right: projectViewModel.isArabic ? 85 : 10, - top: 5), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - border: Border( - bottom: BorderSide(color: Colors.grey[400], width: 2.5), - left: BorderSide(color: Colors.grey[400], width: 2.5), - )), - ), - Expanded( - child: Container( - margin: EdgeInsets.only(top: 10), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - child: LargeAvatar( - name: doctorName ?? "", - url: profileUrl, - ), - width: 25, - height: 25, - margin: EdgeInsets.only(top: 10), - ), - Expanded( - flex: 5, - child: Container( - margin: EdgeInsets.all(10), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - '${TranslationBase.of(context).dr}$doctorName', - color: Colors.black, - fontWeight: FontWeight.w600, - fontSize: 9, - ), - if (orderNo != null && !isPrescriptions) - Row( - children: [ - AppText('Order No: ', - color: Colors.grey[800], - fontSize: 12), - AppText(orderNo ?? '', fontSize: 12) - ], - ), - if (invoiceNO != null && !isPrescriptions) - Row( - children: [ - AppText('Invoice: ', - color: Colors.grey[800], - fontSize: 12), - AppText(invoiceNO??"", fontSize: 12) - ], - ), - if (branch != null) - Row( - children: [ - AppText('Branch: ', - color: Colors.grey[800], - fontSize: 12), - AppText(branch ?? '', fontSize: 12) - ], - ), - - if (clinic != null) - Row( - children: [ - AppText('Clinic: ', - color: Colors.grey[800], - fontSize: 12), - AppText(clinic ?? '', fontSize: 12) - ], - ), - if (isMedicalFile && episode != null) - Row( - children: [ - AppText('Episode: ', - color: Colors.grey[800], - fontSize: 12), - AppText(episode ?? '', fontSize: 12) - ], - ), - if (isMedicalFile && vistDate != null) - Row( - children: [ - AppText('Visit Date: ', - color: Colors.grey[800], - fontSize: 12), - AppText(vistDate ?? '', fontSize: 12) - ], - ), - if (!isMedicalFile) - Row( - children: [ - Expanded( - child: AppText( - !isPrescriptions - ? 'Result Date: ' - : 'Prescriptions Date ', - color: Colors.grey[800], - fontSize: 12, - ), - ), - AppText( - '${AppDateUtils.getDayMonthYearDateFormatted(appointmentDate, isArabic: projectViewModel.isArabic)}', - fontSize: 14, - ) - ], - ) - ]), - ), - ), - ], - ), - ), - ), - ], - ) - ], - ), - ), - ); - } - - convertDateFormat2(String str) { - String newDate = ""; - const start = "/Date("; - const end = "+0300)"; - - if (str.isNotEmpty) { - 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))); - newDate = date.year.toString() + - "/" + - date.month.toString().padLeft(2, '0') + - "/" + - date.day.toString().padLeft(2, '0'); - } - - return newDate.toString(); - } - - - - @override - Size get preferredSize => Size(double.maxFinite, 310); -} diff --git a/lib/widgets/patients/profile/profile_header_widget.dart b/lib/widgets/patients/profile/profile_header_widget.dart deleted file mode 100644 index df958106..00000000 --- a/lib/widgets/patients/profile/profile_header_widget.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; - -import '../../../config/size_config.dart'; -import '../../shared/profile_image_widget.dart'; - -/* - *@author: Elham Rababah - *@Date:21/4/2020 - *@param: - *@return: - *@desc: Profile Header Widget class - */ -class ProfileHeaderWidget extends StatelessWidget { - ProfileHeaderWidget({ - Key key, - this.patient - }) : super(key: key); - - PatiantInformtion patient; - - @override - Widget build(BuildContext context) { - // PatientsProvider patientsProv = Provider.of(context); - // patient = patientsProv.getSelectedPatient(); - return Container( - height: SizeConfig.heightMultiplier * 30, - child: ProfileImageWidget( - url: - "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", - name: patient.firstName + ' ' + patient.lastName, - des: patient.patientId.toString(), - height: SizeConfig.heightMultiplier * 17, - width: SizeConfig.heightMultiplier * 17, - color: HexColor('#58434F')), - ); - } -} From 95425d956856746a9a576f731496849307fd2842 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Thu, 10 Jun 2021 12:10:33 +0300 Subject: [PATCH 23/72] fix issues in header --- .../radiology/radiology_details_page.dart | 5 +- .../radiology/radiology_home_page.dart | 1 + .../prescription/prescription_items_page.dart | 1 - lib/widgets/patients/profile/_1.dart | 507 ++++++++++++++++++ .../profile/patient-profile-app-bar.dart | 284 +++++----- 5 files changed, 653 insertions(+), 145 deletions(-) create mode 100644 lib/widgets/patients/profile/_1.dart diff --git a/lib/screens/patients/profile/radiology/radiology_details_page.dart b/lib/screens/patients/profile/radiology/radiology_details_page.dart index 54dfe3ec..cb0cd99a 100644 --- a/lib/screens/patients/profile/radiology/radiology_details_page.dart +++ b/lib/screens/patients/profile/radiology/radiology_details_page.dart @@ -16,13 +16,15 @@ class RadiologyDetailsPage extends StatelessWidget { final PatiantInformtion patient; final String patientType; final String arrivalType; + final bool isInpatient; RadiologyDetailsPage( {Key key, this.finalRadiology, this.patient, this.patientType, - this.arrivalType}); + this.arrivalType, + this.isInpatient = false}); @override Widget build(BuildContext context) { @@ -44,7 +46,6 @@ class RadiologyDetailsPage extends StatelessWidget { profileUrl: finalRadiology.doctorImageURL, invoiceNO: finalRadiology.invoiceNo.toString(), isAppointmentHeader: true, - height: 325, ), isShowAppBar: true, diff --git a/lib/screens/patients/profile/radiology/radiology_home_page.dart b/lib/screens/patients/profile/radiology/radiology_home_page.dart index bf50ea11..8d0946c5 100644 --- a/lib/screens/patients/profile/radiology/radiology_home_page.dart +++ b/lib/screens/patients/profile/radiology/radiology_home_page.dart @@ -210,6 +210,7 @@ class _RadiologyHomePageState extends State { finalRadiology: model.radiologyList[index], patient: patient, + isInpatient:isInpatient ), ), ); diff --git a/lib/screens/prescription/prescription_items_page.dart b/lib/screens/prescription/prescription_items_page.dart index ac9ebb2a..e888dddd 100644 --- a/lib/screens/prescription/prescription_items_page.dart +++ b/lib/screens/prescription/prescription_items_page.dart @@ -39,7 +39,6 @@ class PrescriptionItemsPage extends StatelessWidget { doctorName: prescriptions.doctorName, profileUrl: prescriptions.doctorImageURL, isAppointmentHeader: true, - height: 325, ), body: SingleChildScrollView( child: Container( diff --git a/lib/widgets/patients/profile/_1.dart b/lib/widgets/patients/profile/_1.dart new file mode 100644 index 00000000..df9f11df --- /dev/null +++ b/lib/widgets/patients/profile/_1.dart @@ -0,0 +1,507 @@ +import 'package:doctor_app_flutter/config/config.dart'; +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/icons_app/doctor_app_icons.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'; +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'; +import 'package:intl/intl.dart'; +import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher.dart'; + +import 'large_avatar.dart'; + +class PatientProfileHeaderWhitAppointment extends StatelessWidget { + + final PatiantInformtion patient; + final String patientType; + final String arrivalType; + final String doctorName; + final String branch; + final DateTime appointmentDate; + final String profileUrl; + final String invoiceNO; + final String orderNo; + final bool isPrescriptions; + final String clinic; + PatientProfileHeaderWhitAppointment( + {this.patient, + this.patientType, + this.arrivalType, + this.doctorName, + this.branch, + this.appointmentDate, + this.profileUrl, + this.invoiceNO, + this.orderNo, this.isPrescriptions = false, this.clinic}); + + @override + Widget build(BuildContext context) { + int gender = 1; + if (patient.patientDetails != null) { + gender = patient.patientDetails.gender; + } else { + gender = patient.gender; + } + + ProjectViewModel projectViewModel = Provider.of(context); + return Container( + padding: EdgeInsets.only( + left: 0, right: 5, bottom: 5, top: 5), + decoration: BoxDecoration( + color: Colors.white, + ), + //height: 300, + child: Container( + padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), + margin: EdgeInsets.only(top: 50), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + 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( + patient.firstName != null ? + (Helpers.capitalize(patient.firstName) + + " " + + Helpers.capitalize( + patient.lastName)) : Helpers.capitalize(patient.patientDetails.fullName), + fontSize: SizeConfig.textMultiplier *2.2, + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + ), + ), + gender == 1 + ? Icon( + DoctorApp.male_2, + color: Colors.blue, + ) + : Icon( + DoctorApp.female_1, + color: Colors.pink, + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 4), + child: InkWell( + onTap: () { + launch("tel://" + patient.mobileNumber); + }, + child: Icon( + Icons.phone, + color: Colors.black87, + ), + ), + ) + ]), + ), + Row(children: [ + Padding( + padding: EdgeInsets.only(left: 12.0), + child: Container( + width: 60, + height: 60, + child: Image.asset( + gender == 1 + ? 'assets/images/male_avatar.png' + : 'assets/images/female_avatar.png', + fit: BoxFit.cover, + ), + ), + ), + SizedBox( + width: 10, + ), + Expanded( + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + SERVICES_PATIANT2[ + int.parse(patientType)] == + "patientArrivalList" + ? Container( + child: Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + patient.patientStatusType == + 43 + ? AppText( + TranslationBase.of( + context) + .arrivedP, + color: Colors.green, + fontWeight: + FontWeight.bold, + fontFamily: + 'Poppins', + fontSize: 12, + ) + : AppText( + TranslationBase.of( + context) + .notArrived, + color: + Colors.red[800], + fontWeight: + FontWeight.bold, + fontFamily: + 'Poppins', + fontSize: 12, + ), + arrivalType == '1' || patient.arrivedOn == null + ? AppText( + patient.startTime != + null + ? patient + .startTime + : '', + fontFamily: + 'Poppins', + fontWeight: + FontWeight.w600, + ) + : AppText( + AppDateUtils.convertStringToDateFormat( + patient + .arrivedOn, + 'MM-dd-yyyy HH:mm'), + fontFamily: + 'Poppins', + fontWeight: + FontWeight.w600, + ) + ], + )) + : SizedBox(), + if (SERVICES_PATIANT2[ + int.parse(patientType)] == + "List_MyOutPatient") + Container( + child: Row( + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context) + .appointmentDate + + " : ", + fontSize: 14, + ), + patient.startTime != null + ? Container( + height: 15, + width: 60, + decoration: + BoxDecoration( + borderRadius: + BorderRadius + .circular( + 25), + color: HexColor( + "#20A169"), + ), + child: AppText( + patient.startTime, + color: Colors.white, + fontSize: 1.5 * + SizeConfig + .textMultiplier, + textAlign: TextAlign + .center, + fontWeight: + FontWeight.bold, + ), + ) + : SizedBox(), + SizedBox( + width: 3.5, + ), + Container( + child: AppText( + convertDateFormat2(patient.appointmentDate.toString()?? ''), + fontSize: 1.5 * + SizeConfig + .textMultiplier, + fontWeight: + FontWeight.bold, + ), + ), + SizedBox( + height: 0.5, + ) + ], + ), + margin: EdgeInsets.only( + top: 8, + ), + ), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + RichText( + text: TextSpan( + style: TextStyle( + fontSize: 1.6 * + SizeConfig + .textMultiplier, + color: Colors.black), + children: [ + new TextSpan( + text: + TranslationBase.of( + context) + .fileNumber, + style: TextStyle( + fontSize: 12, + fontFamily: + 'Poppins')), + new TextSpan( + text: patient.patientId + .toString(), + style: TextStyle( + fontWeight: + FontWeight.w700, + fontFamily: + 'Poppins', + fontSize: 14)), + ], + ), + ), + Row( + children: [ + AppText( + patient.nationalityName ?? + patient.nationality??"", + fontWeight: FontWeight.bold, + fontSize: 12, + ), + patient.nationality != null + ? ClipRRect( + borderRadius: + BorderRadius + .circular( + 20.0), + child: Image.network( + patient.nationalityFlagURL, + height: 25, + width: 30, + errorBuilder: + (BuildContext + context, + Object + exception, + StackTrace + stackTrace) { + return Text( + 'No Image'); + }, + )) + : SizedBox() + ], + ) + ], + ), + Container( + child: RichText( + text: new TextSpan( + style: new TextStyle( + fontSize: 1.6 * + SizeConfig.textMultiplier, + color: Colors.black, + fontFamily: 'Poppins', + ), + children: [ + 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)}", + style: TextStyle( + fontWeight: + FontWeight.w700, + fontSize: 14)), + ], + ), + ), + ), + ], + ), + ), + ]), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: 30, + height: 30, + margin: EdgeInsets.only(left: projectViewModel.isArabic?10:85, right: projectViewModel.isArabic?85:10,top: 5), + decoration: BoxDecoration( + shape: BoxShape.rectangle, + border: Border( + bottom:BorderSide(color: Colors.grey[400],width: 2.5), + left: BorderSide(color: Colors.grey[400],width: 2.5), + ) + ), + ), + Expanded( + child: Container( + margin: EdgeInsets.only(top: 10), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + child: LargeAvatar( + name: doctorName, + url: profileUrl, + ), + width: 25, + height: 25, + margin: EdgeInsets.only(top: 10), + ), + Expanded( + flex: 4, + child: Container( + margin: EdgeInsets.all(10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + '${TranslationBase.of(context).dr}.$doctorName', + color: Colors.black, + fontWeight: FontWeight.w600, + fontSize: 14, + ), + if (orderNo != null && !isPrescriptions) + Row( + children: [ + AppText( + 'Order No:', + color: Colors.grey[800], + ), + AppText( + orderNo ?? '', + ) + ], + ), + if (invoiceNO != null && !isPrescriptions) + Row( + children: [ + AppText( + 'Invoice:', + color: Colors.grey[800], + ), + AppText( + invoiceNO, + ) + ], + ), + if(isPrescriptions) + Row( + children: [ + AppText( + 'Branch:', + color: Colors.grey[800], + ), + AppText( + branch?? '', + ) + ], + ), + if(isPrescriptions) + Row( + children: [ + AppText( + 'Clinic:', + color: Colors.grey[800], + ), + AppText( + clinic?? '', + ) + ], + ), + Row( + children: [ + AppText( + !isPrescriptions? 'Result Date:': 'Prescriptions Date', + color: Colors.grey[800], + ), + Expanded( + child: AppText( + '${AppDateUtils.getDayMonthYearDateFormatted(appointmentDate, isArabic: projectViewModel.isArabic)}', + ), + ) + ], + ) + ]), + ), + ), + + ], + ), + ), + ), + ], + ) + ], + ), + ), + ); + } + + convertDateFormat2(String str) { + String newDate =""; + const start = "/Date("; + const end = "+0300)"; + + if (str.isNotEmpty) { + 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))); + newDate = date.year.toString() + + "/" + + date.month.toString().padLeft(2, '0') + + "/" + + date.day.toString().padLeft(2, '0'); + } + + return newDate.toString(); + } + + 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()); + } + + myBoxDecoration() { + return BoxDecoration( + border: Border( + top: BorderSide( + color: Colors.green, + width: 5, + ), + ), + borderRadius: BorderRadius.circular(10)); + } +} diff --git a/lib/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart index dd0c48e4..e5a51838 100644 --- a/lib/widgets/patients/profile/patient-profile-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -412,159 +412,159 @@ class PatientProfileAppBar extends StatelessWidget ), ], ), - if(isAppointmentHeader) - Row( + ], + ), + ), + ]), + if(isAppointmentHeader) + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: 30, + height: 30, + margin: EdgeInsets.only( + left: projectViewModel.isArabic ? 10 : 85, + right: projectViewModel.isArabic ? 85 : 10, + top: 5), + decoration: BoxDecoration( + shape: BoxShape.rectangle, + border: Border( + bottom: BorderSide( + color: Colors.grey[400], width: 2.5), + left: BorderSide( + color: Colors.grey[400], width: 2.5), + )), + ), + Expanded( + child: Container( + margin: EdgeInsets.only(top: 10), + child: Row( crossAxisAlignment: CrossAxisAlignment.start, - children: [ + children: [ Container( - width: 30, - height: 30, - margin: EdgeInsets.only( - left: projectViewModel.isArabic ? 10 : 85, - right: projectViewModel.isArabic ? 85 : 10, - top: 5), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - border: Border( - bottom: BorderSide( - color: Colors.grey[400], width: 2.5), - left: BorderSide( - color: Colors.grey[400], width: 2.5), - )), + child: LargeAvatar( + name: doctorName ?? "", + url: profileUrl, + ), + width: 25, + height: 25, + margin: EdgeInsets.only(top: 10), ), + + Expanded( + flex: 5, child: Container( - margin: EdgeInsets.only(top: 10), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - child: LargeAvatar( - name: doctorName ?? "", - url: profileUrl, + margin: EdgeInsets.all(10), + child: Column( + crossAxisAlignment: CrossAxisAlignment + .start, + children: [ + AppText( + '${TranslationBase + .of(context) + .dr}$doctorName', + color: Colors.black, + fontWeight: FontWeight.w600, + fontSize: 9, ), - width: 25, - height: 25, - margin: EdgeInsets.only(top: 10), - ), - + if (orderNo != null && + !isPrescriptions) + Row( + children: [ + AppText('Order No: ', + color: Colors.grey[800], + fontSize: 12), + AppText(orderNo ?? '', + fontSize: 12) + ], + ), + if (invoiceNO != null && + !isPrescriptions) + Row( + children: [ + AppText('Invoice: ', + color: Colors.grey[800], + fontSize: 12), + AppText(invoiceNO ?? "", + fontSize: 12) + ], + ), + if (branch != null) + Row( + children: [ + AppText('Branch: ', + color: Colors.grey[800], + fontSize: 12), + AppText(branch ?? '', + fontSize: 12) + ], + ), - Expanded( - flex: 5, - child: Container( - margin: EdgeInsets.all(10), - child: Column( - crossAxisAlignment: CrossAxisAlignment - .start, - children: [ - AppText( - '${TranslationBase - .of(context) - .dr}$doctorName', - color: Colors.black, - fontWeight: FontWeight.w600, - fontSize: 9, + if (clinic != null) + Row( + children: [ + AppText('Clinic: ', + color: Colors.grey[800], + fontSize: 12), + AppText(clinic ?? '', + fontSize: 12) + ], + ), + if (isMedicalFile && + episode != null) + Row( + children: [ + AppText('Episode: ', + color: Colors.grey[800], + fontSize: 12), + AppText(episode ?? '', + fontSize: 12) + ], + ), + if (isMedicalFile && + visitDate != null) + Row( + children: [ + AppText('Visit Date: ', + color: Colors.grey[800], + fontSize: 12), + AppText(visitDate ?? '', + fontSize: 12) + ], + ), + if (!isMedicalFile) + Row( + children: [ + Expanded( + child: AppText( + !isPrescriptions + ? 'Result Date: ' + : 'Prescriptions Date ', + color: Colors.grey[800], + fontSize: 12, ), - if (orderNo != null && - !isPrescriptions) - Row( - children: [ - AppText('Order No: ', - color: Colors.grey[800], - fontSize: 12), - AppText(orderNo ?? '', - fontSize: 12) - ], - ), - if (invoiceNO != null && - !isPrescriptions) - Row( - children: [ - AppText('Invoice: ', - color: Colors.grey[800], - fontSize: 12), - AppText(invoiceNO ?? "", - fontSize: 12) - ], - ), - if (branch != null) - Row( - children: [ - AppText('Branch: ', - color: Colors.grey[800], - fontSize: 12), - AppText(branch ?? '', - fontSize: 12) - ], - ), - - if (clinic != null) - Row( - children: [ - AppText('Clinic: ', - color: Colors.grey[800], - fontSize: 12), - AppText(clinic ?? '', - fontSize: 12) - ], - ), - if (isMedicalFile && - episode != null) - Row( - children: [ - AppText('Episode: ', - color: Colors.grey[800], - fontSize: 12), - AppText(episode ?? '', - fontSize: 12) - ], - ), - if (isMedicalFile && - visitDate != null) - Row( - children: [ - AppText('Visit Date: ', - color: Colors.grey[800], - fontSize: 12), - AppText(visitDate ?? '', - fontSize: 12) - ], - ), - if (!isMedicalFile) - Row( - children: [ - Expanded( - child: AppText( - !isPrescriptions - ? 'Result Date: ' - : 'Prescriptions Date ', - color: Colors.grey[800], - fontSize: 12, - ), - ), - AppText( - '${AppDateUtils - .getDayMonthYearDateFormatted( - appointmentDate, - isArabic: projectViewModel - .isArabic)}', - fontSize: 14, - ) - ], - ) - ]), - ), - ), - ], - ), + ), + AppText( + '${AppDateUtils + .getDayMonthYearDateFormatted( + appointmentDate, + isArabic: projectViewModel + .isArabic)}', + fontSize: 14, + ) + ], + ) + ]), ), ), ], - ) - ], - ), - ), - ]), + ), + ), + ), + ], + ) ], ), ), From 57399c3dcb48d231333b8a7d8150f660c52501c8 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Thu, 10 Jun 2021 12:10:55 +0300 Subject: [PATCH 24/72] fix issues in header --- lib/widgets/patients/profile/_1.dart | 507 --------------------------- 1 file changed, 507 deletions(-) delete mode 100644 lib/widgets/patients/profile/_1.dart diff --git a/lib/widgets/patients/profile/_1.dart b/lib/widgets/patients/profile/_1.dart deleted file mode 100644 index df9f11df..00000000 --- a/lib/widgets/patients/profile/_1.dart +++ /dev/null @@ -1,507 +0,0 @@ -import 'package:doctor_app_flutter/config/config.dart'; -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/icons_app/doctor_app_icons.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'; -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'; -import 'package:intl/intl.dart'; -import 'package:provider/provider.dart'; -import 'package:url_launcher/url_launcher.dart'; - -import 'large_avatar.dart'; - -class PatientProfileHeaderWhitAppointment extends StatelessWidget { - - final PatiantInformtion patient; - final String patientType; - final String arrivalType; - final String doctorName; - final String branch; - final DateTime appointmentDate; - final String profileUrl; - final String invoiceNO; - final String orderNo; - final bool isPrescriptions; - final String clinic; - PatientProfileHeaderWhitAppointment( - {this.patient, - this.patientType, - this.arrivalType, - this.doctorName, - this.branch, - this.appointmentDate, - this.profileUrl, - this.invoiceNO, - this.orderNo, this.isPrescriptions = false, this.clinic}); - - @override - Widget build(BuildContext context) { - int gender = 1; - if (patient.patientDetails != null) { - gender = patient.patientDetails.gender; - } else { - gender = patient.gender; - } - - ProjectViewModel projectViewModel = Provider.of(context); - return Container( - padding: EdgeInsets.only( - left: 0, right: 5, bottom: 5, top: 5), - decoration: BoxDecoration( - color: Colors.white, - ), - //height: 300, - child: Container( - padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), - margin: EdgeInsets.only(top: 50), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - 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( - patient.firstName != null ? - (Helpers.capitalize(patient.firstName) + - " " + - Helpers.capitalize( - patient.lastName)) : Helpers.capitalize(patient.patientDetails.fullName), - fontSize: SizeConfig.textMultiplier *2.2, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - ), - ), - gender == 1 - ? Icon( - DoctorApp.male_2, - color: Colors.blue, - ) - : Icon( - DoctorApp.female_1, - color: Colors.pink, - ), - Container( - margin: EdgeInsets.symmetric(horizontal: 4), - child: InkWell( - onTap: () { - launch("tel://" + patient.mobileNumber); - }, - child: Icon( - Icons.phone, - color: Colors.black87, - ), - ), - ) - ]), - ), - Row(children: [ - Padding( - padding: EdgeInsets.only(left: 12.0), - child: Container( - width: 60, - height: 60, - child: Image.asset( - gender == 1 - ? 'assets/images/male_avatar.png' - : 'assets/images/female_avatar.png', - fit: BoxFit.cover, - ), - ), - ), - SizedBox( - width: 10, - ), - Expanded( - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - SERVICES_PATIANT2[ - int.parse(patientType)] == - "patientArrivalList" - ? Container( - child: Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, - children: [ - patient.patientStatusType == - 43 - ? AppText( - TranslationBase.of( - context) - .arrivedP, - color: Colors.green, - fontWeight: - FontWeight.bold, - fontFamily: - 'Poppins', - fontSize: 12, - ) - : AppText( - TranslationBase.of( - context) - .notArrived, - color: - Colors.red[800], - fontWeight: - FontWeight.bold, - fontFamily: - 'Poppins', - fontSize: 12, - ), - arrivalType == '1' || patient.arrivedOn == null - ? AppText( - patient.startTime != - null - ? patient - .startTime - : '', - fontFamily: - 'Poppins', - fontWeight: - FontWeight.w600, - ) - : AppText( - AppDateUtils.convertStringToDateFormat( - patient - .arrivedOn, - 'MM-dd-yyyy HH:mm'), - fontFamily: - 'Poppins', - fontWeight: - FontWeight.w600, - ) - ], - )) - : SizedBox(), - if (SERVICES_PATIANT2[ - int.parse(patientType)] == - "List_MyOutPatient") - Container( - child: Row( - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context) - .appointmentDate + - " : ", - fontSize: 14, - ), - patient.startTime != null - ? Container( - height: 15, - width: 60, - decoration: - BoxDecoration( - borderRadius: - BorderRadius - .circular( - 25), - color: HexColor( - "#20A169"), - ), - child: AppText( - patient.startTime, - color: Colors.white, - fontSize: 1.5 * - SizeConfig - .textMultiplier, - textAlign: TextAlign - .center, - fontWeight: - FontWeight.bold, - ), - ) - : SizedBox(), - SizedBox( - width: 3.5, - ), - Container( - child: AppText( - convertDateFormat2(patient.appointmentDate.toString()?? ''), - fontSize: 1.5 * - SizeConfig - .textMultiplier, - fontWeight: - FontWeight.bold, - ), - ), - SizedBox( - height: 0.5, - ) - ], - ), - margin: EdgeInsets.only( - top: 8, - ), - ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - RichText( - text: TextSpan( - style: TextStyle( - fontSize: 1.6 * - SizeConfig - .textMultiplier, - color: Colors.black), - children: [ - new TextSpan( - text: - TranslationBase.of( - context) - .fileNumber, - style: TextStyle( - fontSize: 12, - fontFamily: - 'Poppins')), - new TextSpan( - text: patient.patientId - .toString(), - style: TextStyle( - fontWeight: - FontWeight.w700, - fontFamily: - 'Poppins', - fontSize: 14)), - ], - ), - ), - Row( - children: [ - AppText( - patient.nationalityName ?? - patient.nationality??"", - fontWeight: FontWeight.bold, - fontSize: 12, - ), - patient.nationality != null - ? ClipRRect( - borderRadius: - BorderRadius - .circular( - 20.0), - child: Image.network( - patient.nationalityFlagURL, - height: 25, - width: 30, - errorBuilder: - (BuildContext - context, - Object - exception, - StackTrace - stackTrace) { - return Text( - 'No Image'); - }, - )) - : SizedBox() - ], - ) - ], - ), - Container( - child: RichText( - text: new TextSpan( - style: new TextStyle( - fontSize: 1.6 * - SizeConfig.textMultiplier, - color: Colors.black, - fontFamily: 'Poppins', - ), - children: [ - 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)}", - style: TextStyle( - fontWeight: - FontWeight.w700, - fontSize: 14)), - ], - ), - ), - ), - ], - ), - ), - ]), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - width: 30, - height: 30, - margin: EdgeInsets.only(left: projectViewModel.isArabic?10:85, right: projectViewModel.isArabic?85:10,top: 5), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - border: Border( - bottom:BorderSide(color: Colors.grey[400],width: 2.5), - left: BorderSide(color: Colors.grey[400],width: 2.5), - ) - ), - ), - Expanded( - child: Container( - margin: EdgeInsets.only(top: 10), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - child: LargeAvatar( - name: doctorName, - url: profileUrl, - ), - width: 25, - height: 25, - margin: EdgeInsets.only(top: 10), - ), - Expanded( - flex: 4, - child: Container( - margin: EdgeInsets.all(10), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - '${TranslationBase.of(context).dr}.$doctorName', - color: Colors.black, - fontWeight: FontWeight.w600, - fontSize: 14, - ), - if (orderNo != null && !isPrescriptions) - Row( - children: [ - AppText( - 'Order No:', - color: Colors.grey[800], - ), - AppText( - orderNo ?? '', - ) - ], - ), - if (invoiceNO != null && !isPrescriptions) - Row( - children: [ - AppText( - 'Invoice:', - color: Colors.grey[800], - ), - AppText( - invoiceNO, - ) - ], - ), - if(isPrescriptions) - Row( - children: [ - AppText( - 'Branch:', - color: Colors.grey[800], - ), - AppText( - branch?? '', - ) - ], - ), - if(isPrescriptions) - Row( - children: [ - AppText( - 'Clinic:', - color: Colors.grey[800], - ), - AppText( - clinic?? '', - ) - ], - ), - Row( - children: [ - AppText( - !isPrescriptions? 'Result Date:': 'Prescriptions Date', - color: Colors.grey[800], - ), - Expanded( - child: AppText( - '${AppDateUtils.getDayMonthYearDateFormatted(appointmentDate, isArabic: projectViewModel.isArabic)}', - ), - ) - ], - ) - ]), - ), - ), - - ], - ), - ), - ), - ], - ) - ], - ), - ), - ); - } - - convertDateFormat2(String str) { - String newDate =""; - const start = "/Date("; - const end = "+0300)"; - - if (str.isNotEmpty) { - 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))); - newDate = date.year.toString() + - "/" + - date.month.toString().padLeft(2, '0') + - "/" + - date.day.toString().padLeft(2, '0'); - } - - return newDate.toString(); - } - - 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()); - } - - myBoxDecoration() { - return BoxDecoration( - border: Border( - top: BorderSide( - color: Colors.green, - width: 5, - ), - ), - borderRadius: BorderRadius.circular(10)); - } -} From 717468b637f54b7403c1ed9afa143e3bd7f21caa Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Thu, 10 Jun 2021 14:30:02 +0300 Subject: [PATCH 25/72] fix design issue --- .../patients/profile/patient-profile-app-bar.dart | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart index e5a51838..750ee9d5 100644 --- a/lib/widgets/patients/profile/patient-profile-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -213,11 +213,12 @@ class PatientProfileAppBar extends StatelessWidget mainAxisAlignment: MainAxisAlignment.start, children: [ AppText( - TranslationBase - .of(context) - .appointmentDate + + TranslationBase.of(context).appointmentDate + " : ", fontSize: 14, + fontWeight: FontWeight.normal, + fontFamily: 'Poppins', + color: Colors.black, ), patient.startTime != null ? Container( @@ -266,9 +267,11 @@ class PatientProfileAppBar extends StatelessWidget color: Colors.black), children: [ new TextSpan( - text: TranslationBase.of(context).fileNumber, + text: TranslationBase + .of(context) + .fileNumber, style: TextStyle( - fontSize: 12, fontFamily: 'Poppins')), + fontSize: 14, fontFamily: 'Poppins')), new TextSpan( text: patient.patientId.toString(), style: TextStyle( From e530dc016855849dde4b6f268eebf109eab5076e Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Thu, 10 Jun 2021 15:50:46 +0300 Subject: [PATCH 26/72] first step from fix medical report --- ios/Podfile.lock | 327 ------------------ .../AddVerifyMedicalReport.dart | 8 +- 2 files changed, 3 insertions(+), 332 deletions(-) delete mode 100644 ios/Podfile.lock diff --git a/ios/Podfile.lock b/ios/Podfile.lock deleted file mode 100644 index 44151727..00000000 --- a/ios/Podfile.lock +++ /dev/null @@ -1,327 +0,0 @@ -PODS: - - Alamofire (5.4.3) - - barcode_scan_fix (0.0.1): - - Flutter - - MTBBarcodeScanner - - connectivity (0.0.1): - - Flutter - - Reachability - - connectivity_for_web (0.1.0): - - Flutter - - connectivity_macos (0.0.1): - - Flutter - - device_info (0.0.1): - - Flutter - - Firebase/CoreOnly (6.33.0): - - FirebaseCore (= 6.10.3) - - Firebase/Messaging (6.33.0): - - Firebase/CoreOnly - - FirebaseMessaging (~> 4.7.0) - - firebase_core (0.5.3): - - Firebase/CoreOnly (~> 6.33.0) - - Flutter - - firebase_core_web (0.1.0): - - Flutter - - firebase_messaging (7.0.3): - - Firebase/CoreOnly (~> 6.33.0) - - Firebase/Messaging (~> 6.33.0) - - firebase_core - - Flutter - - FirebaseCore (6.10.3): - - FirebaseCoreDiagnostics (~> 1.6) - - GoogleUtilities/Environment (~> 6.7) - - GoogleUtilities/Logger (~> 6.7) - - FirebaseCoreDiagnostics (1.7.0): - - GoogleDataTransport (~> 7.4) - - GoogleUtilities/Environment (~> 6.7) - - GoogleUtilities/Logger (~> 6.7) - - nanopb (~> 1.30906.0) - - FirebaseInstallations (1.7.0): - - FirebaseCore (~> 6.10) - - GoogleUtilities/Environment (~> 6.7) - - GoogleUtilities/UserDefaults (~> 6.7) - - PromisesObjC (~> 1.2) - - FirebaseInstanceID (4.8.0): - - FirebaseCore (~> 6.10) - - FirebaseInstallations (~> 1.6) - - GoogleUtilities/Environment (~> 6.7) - - GoogleUtilities/UserDefaults (~> 6.7) - - FirebaseMessaging (4.7.1): - - FirebaseCore (~> 6.10) - - FirebaseInstanceID (~> 4.7) - - GoogleUtilities/AppDelegateSwizzler (~> 6.7) - - GoogleUtilities/Environment (~> 6.7) - - GoogleUtilities/Reachability (~> 6.7) - - GoogleUtilities/UserDefaults (~> 6.7) - - Protobuf (>= 3.9.2, ~> 3.9) - - Flutter (1.0.0) - - flutter_flexible_toast (0.0.1): - - Flutter - - flutter_inappwebview (0.0.1): - - Flutter - - flutter_plugin_android_lifecycle (0.0.1): - - Flutter - - GoogleDataTransport (7.5.1): - - nanopb (~> 1.30906.0) - - GoogleUtilities/AppDelegateSwizzler (6.7.2): - - GoogleUtilities/Environment - - GoogleUtilities/Logger - - GoogleUtilities/Network - - GoogleUtilities/Environment (6.7.2): - - PromisesObjC (~> 1.2) - - GoogleUtilities/Logger (6.7.2): - - GoogleUtilities/Environment - - GoogleUtilities/Network (6.7.2): - - GoogleUtilities/Logger - - "GoogleUtilities/NSData+zlib" - - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (6.7.2)" - - GoogleUtilities/Reachability (6.7.2): - - GoogleUtilities/Logger - - GoogleUtilities/UserDefaults (6.7.2): - - GoogleUtilities/Logger - - hexcolor (0.0.1): - - Flutter - - imei_plugin (0.0.1): - - Flutter - - local_auth (0.0.1): - - Flutter - - maps_launcher (0.0.1): - - Flutter - - MTBBarcodeScanner (5.0.11) - - nanopb (1.30906.0): - - nanopb/decode (= 1.30906.0) - - nanopb/encode (= 1.30906.0) - - nanopb/decode (1.30906.0) - - nanopb/encode (1.30906.0) - - OpenTok (2.15.3) - - path_provider_linux (0.0.1): - - Flutter - - path_provider_windows (0.0.1): - - Flutter - - "permission_handler (5.1.0+2)": - - Flutter - - PromisesObjC (1.2.12) - - Protobuf (3.17.0) - - Reachability (3.2) - - screen (0.0.1): - - Flutter - - shared_preferences (0.0.1): - - Flutter - - shared_preferences_linux (0.0.1): - - Flutter - - shared_preferences_macos (0.0.1): - - Flutter - - shared_preferences_web (0.0.1): - - Flutter - - shared_preferences_windows (0.0.1): - - Flutter - - speech_to_text (0.0.1): - - Flutter - - Try - - Try (2.1.1) - - url_launcher (0.0.1): - - Flutter - - url_launcher_linux (0.0.1): - - Flutter - - url_launcher_macos (0.0.1): - - Flutter - - url_launcher_web (0.0.1): - - Flutter - - url_launcher_windows (0.0.1): - - Flutter - - video_player (0.0.1): - - Flutter - - video_player_web (0.0.1): - - Flutter - - wakelock (0.0.1): - - Flutter - - webview_flutter (0.0.1): - - Flutter - -DEPENDENCIES: - - Alamofire (~> 5.2) - - barcode_scan_fix (from `.symlinks/plugins/barcode_scan_fix/ios`) - - connectivity (from `.symlinks/plugins/connectivity/ios`) - - connectivity_for_web (from `.symlinks/plugins/connectivity_for_web/ios`) - - connectivity_macos (from `.symlinks/plugins/connectivity_macos/ios`) - - device_info (from `.symlinks/plugins/device_info/ios`) - - firebase_core (from `.symlinks/plugins/firebase_core/ios`) - - firebase_core_web (from `.symlinks/plugins/firebase_core_web/ios`) - - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) - - Flutter (from `Flutter`) - - flutter_flexible_toast (from `.symlinks/plugins/flutter_flexible_toast/ios`) - - flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`) - - flutter_plugin_android_lifecycle (from `.symlinks/plugins/flutter_plugin_android_lifecycle/ios`) - - hexcolor (from `.symlinks/plugins/hexcolor/ios`) - - imei_plugin (from `.symlinks/plugins/imei_plugin/ios`) - - local_auth (from `.symlinks/plugins/local_auth/ios`) - - maps_launcher (from `.symlinks/plugins/maps_launcher/ios`) - - OpenTok - - path_provider_linux (from `.symlinks/plugins/path_provider_linux/ios`) - - path_provider_windows (from `.symlinks/plugins/path_provider_windows/ios`) - - permission_handler (from `.symlinks/plugins/permission_handler/ios`) - - screen (from `.symlinks/plugins/screen/ios`) - - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) - - shared_preferences_linux (from `.symlinks/plugins/shared_preferences_linux/ios`) - - shared_preferences_macos (from `.symlinks/plugins/shared_preferences_macos/ios`) - - shared_preferences_web (from `.symlinks/plugins/shared_preferences_web/ios`) - - shared_preferences_windows (from `.symlinks/plugins/shared_preferences_windows/ios`) - - speech_to_text (from `.symlinks/plugins/speech_to_text/ios`) - - url_launcher (from `.symlinks/plugins/url_launcher/ios`) - - url_launcher_linux (from `.symlinks/plugins/url_launcher_linux/ios`) - - url_launcher_macos (from `.symlinks/plugins/url_launcher_macos/ios`) - - url_launcher_web (from `.symlinks/plugins/url_launcher_web/ios`) - - url_launcher_windows (from `.symlinks/plugins/url_launcher_windows/ios`) - - video_player (from `.symlinks/plugins/video_player/ios`) - - video_player_web (from `.symlinks/plugins/video_player_web/ios`) - - wakelock (from `.symlinks/plugins/wakelock/ios`) - - webview_flutter (from `.symlinks/plugins/webview_flutter/ios`) - -SPEC REPOS: - trunk: - - Alamofire - - Firebase - - FirebaseCore - - FirebaseCoreDiagnostics - - FirebaseInstallations - - FirebaseInstanceID - - FirebaseMessaging - - GoogleDataTransport - - GoogleUtilities - - MTBBarcodeScanner - - nanopb - - OpenTok - - PromisesObjC - - Protobuf - - Reachability - - Try - -EXTERNAL SOURCES: - barcode_scan_fix: - :path: ".symlinks/plugins/barcode_scan_fix/ios" - connectivity: - :path: ".symlinks/plugins/connectivity/ios" - connectivity_for_web: - :path: ".symlinks/plugins/connectivity_for_web/ios" - connectivity_macos: - :path: ".symlinks/plugins/connectivity_macos/ios" - device_info: - :path: ".symlinks/plugins/device_info/ios" - firebase_core: - :path: ".symlinks/plugins/firebase_core/ios" - firebase_core_web: - :path: ".symlinks/plugins/firebase_core_web/ios" - firebase_messaging: - :path: ".symlinks/plugins/firebase_messaging/ios" - Flutter: - :path: Flutter - flutter_flexible_toast: - :path: ".symlinks/plugins/flutter_flexible_toast/ios" - flutter_inappwebview: - :path: ".symlinks/plugins/flutter_inappwebview/ios" - flutter_plugin_android_lifecycle: - :path: ".symlinks/plugins/flutter_plugin_android_lifecycle/ios" - hexcolor: - :path: ".symlinks/plugins/hexcolor/ios" - imei_plugin: - :path: ".symlinks/plugins/imei_plugin/ios" - local_auth: - :path: ".symlinks/plugins/local_auth/ios" - maps_launcher: - :path: ".symlinks/plugins/maps_launcher/ios" - path_provider_linux: - :path: ".symlinks/plugins/path_provider_linux/ios" - path_provider_windows: - :path: ".symlinks/plugins/path_provider_windows/ios" - permission_handler: - :path: ".symlinks/plugins/permission_handler/ios" - screen: - :path: ".symlinks/plugins/screen/ios" - shared_preferences: - :path: ".symlinks/plugins/shared_preferences/ios" - shared_preferences_linux: - :path: ".symlinks/plugins/shared_preferences_linux/ios" - shared_preferences_macos: - :path: ".symlinks/plugins/shared_preferences_macos/ios" - shared_preferences_web: - :path: ".symlinks/plugins/shared_preferences_web/ios" - shared_preferences_windows: - :path: ".symlinks/plugins/shared_preferences_windows/ios" - speech_to_text: - :path: ".symlinks/plugins/speech_to_text/ios" - url_launcher: - :path: ".symlinks/plugins/url_launcher/ios" - url_launcher_linux: - :path: ".symlinks/plugins/url_launcher_linux/ios" - url_launcher_macos: - :path: ".symlinks/plugins/url_launcher_macos/ios" - url_launcher_web: - :path: ".symlinks/plugins/url_launcher_web/ios" - url_launcher_windows: - :path: ".symlinks/plugins/url_launcher_windows/ios" - video_player: - :path: ".symlinks/plugins/video_player/ios" - video_player_web: - :path: ".symlinks/plugins/video_player_web/ios" - wakelock: - :path: ".symlinks/plugins/wakelock/ios" - webview_flutter: - :path: ".symlinks/plugins/webview_flutter/ios" - -SPEC CHECKSUMS: - Alamofire: e447a2774a40c996748296fa2c55112fdbbc42f9 - barcode_scan_fix: 80dd65de55f27eec6591dd077c8b85f2b79e31f1 - connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467 - connectivity_for_web: 2b8584556930d4bd490d82b836bcf45067ce345b - connectivity_macos: e2e9731b6b22dda39eb1b128f6969d574460e191 - device_info: d7d233b645a32c40dfdc212de5cf646ca482f175 - Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5 - firebase_core: 5d6a02f3d85acd5f8321c2d6d62877626a670659 - firebase_core_web: d501d8b946b60c8af265428ce483b0fff5ad52d1 - firebase_messaging: 0aea2cd5885b65e19ede58ee3507f485c992cc75 - FirebaseCore: d889d9e12535b7f36ac8bfbf1713a0836a3012cd - FirebaseCoreDiagnostics: 770ac5958e1372ce67959ae4b4f31d8e127c3ac1 - FirebaseInstallations: 466c7b4d1f58fe16707693091da253726a731ed2 - FirebaseInstanceID: bd3ffc24367f901a43c063b36c640b345a4a5dd1 - FirebaseMessaging: 5eca4ef173de76253352511aafef774caa1cba2a - Flutter: 0e3d915762c693b495b44d77113d4970485de6ec - flutter_flexible_toast: 0547e740cae0c33bb7c51bcd931233f4584e1143 - flutter_inappwebview: 69dfbac46157b336ffbec19ca6dfd4638c7bf189 - flutter_plugin_android_lifecycle: dc0b544e129eebb77a6bfb1239d4d1c673a60a35 - GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833 - GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3 - hexcolor: fdfb9c4258ad96e949c2dbcdf790a62194b8aa89 - imei_plugin: cb1af7c223ac2d82dcd1457a7137d93d65d2a3cd - local_auth: 25938960984c3a7f6e3253e3f8d962fdd16852bd - maps_launcher: eae38ee13a9c3f210fa04e04bb4c073fa4c6ed92 - MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb - nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc - OpenTok: fde03ecc5ea31fe0a453242847c4ee1f47e1d735 - path_provider_linux: 4d630dc393e1f20364f3e3b4a2ff41d9674a84e4 - path_provider_windows: a2b81600c677ac1959367280991971cb9a1edb3b - permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0 - PromisesObjC: 3113f7f76903778cf4a0586bd1ab89329a0b7b97 - Protobuf: 7327d4444215b5f18e560a97f879ff5503c4581c - Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 - screen: abd91ca7bf3426e1cc3646d27e9b2358d6bf07b0 - shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d - shared_preferences_linux: afefbfe8d921e207f01ede8b60373d9e3b566b78 - shared_preferences_macos: f3f29b71ccbb56bf40c9dd6396c9acf15e214087 - shared_preferences_web: 141cce0c3ed1a1c5bf2a0e44f52d31eeb66e5ea9 - shared_preferences_windows: 36b76d6f54e76ead957e60b49e2f124b4cd3e6ae - speech_to_text: b43a7d99aef037bd758ed8e45d79bbac035d2dfe - Try: 5ef669ae832617b3cee58cb2c6f99fb767a4ff96 - url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef - url_launcher_linux: ac237cb7a8058736e4aae38bdbcc748a4b394cc0 - url_launcher_macos: fd7894421cd39320dce5f292fc99ea9270b2a313 - url_launcher_web: e5527357f037c87560776e36436bf2b0288b965c - url_launcher_windows: 683d7c283894db8d1914d3ab2223b20cc1ad95d5 - video_player: 9cc823b1d9da7e8427ee591e8438bfbcde500e6e - video_player_web: da8cadb8274ed4f8dbee8d7171b420dedd437ce7 - wakelock: 0d4a70faf8950410735e3f61fb15d517c8a6efc4 - webview_flutter: d2b4d6c66968ad042ad94cbb791f5b72b4678a96 - -PODFILE CHECKSUM: d0a3789a37635365b4345e456835ed9d30398217 - -COCOAPODS: 1.10.1 diff --git a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart index a3fa91e9..63dbb18b 100644 --- a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart +++ b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart @@ -32,7 +32,7 @@ class _AddVerifyMedicalReportState extends State { : null; return BaseView( - onModelReady: (model) => model.getMedicalReportTemplate(), + // onModelReady: (model) => model.getMedicalReportTemplate(), builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, @@ -53,11 +53,9 @@ class _AddVerifyMedicalReportState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (model.medicalReportTemplate.length > 0) + // if (model.medicalReportTemplate.length > 0) HtmlRichEditor( - initialText: model - .medicalReportTemplate[0] - .templateTextHtml, + initialText:(medicalReport != null? medicalReport.reportDataHtml:""), height: MediaQuery.of(context).size.height * 0.75, From 1834d9f7766d8bc0a63aca09b490cc2f25ff4f00 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 10 Jun 2021 16:01:27 +0300 Subject: [PATCH 27/72] change video streaming design --- .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 3 +- .../hmgDr/Model/GetSessionStatusModel.java | 18 +- .../com/hmg/hmgDr/ui/VideoCallActivity.java | 40 ++- android/app/src/main/res/drawable/ic_mini.xml | 16 ++ .../src/main/res/drawable/shape_capsule.xml | 7 + .../main/res/layout/activity_video_call.xml | 234 +++++++++--------- android/app/src/main/res/values/colors.xml | 6 + android/app/src/main/res/values/dimens.xml | 19 +- lib/screens/live_care/end_call_screen.dart | 1 + lib/screens/live_care/video_call.dart | 1 + .../patient_profile_screen.dart | 1 + lib/util/VideoChannel.dart | 3 +- 12 files changed, 231 insertions(+), 118 deletions(-) create mode 100644 android/app/src/main/res/drawable/ic_mini.xml create mode 100644 android/app/src/main/res/drawable/shape_capsule.xml 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 612118c9..ddecef6e 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -45,8 +45,9 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler val tokenID = call.argument("TokenID") val generalId = call.argument("generalId") val doctorId = call.argument("DoctorId") + val patientName = call.argument("patientName") - val sessionStatusModel = GetSessionStatusModel(VC_ID, tokenID, generalId, doctorId) + val sessionStatusModel = GetSessionStatusModel(VC_ID, tokenID, generalId, doctorId, patientName) openVideoCall(apiKey, sessionId, token, appLang, baseUrl, sessionStatusModel) 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 index d41aa146..60350539 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 @@ -20,15 +20,19 @@ public class GetSessionStatusModel implements Parcelable { @SerializedName("DoctorId") @Expose private Integer doctorId; + @SerializedName("PatientName") + @Expose + private String patientName; public GetSessionStatusModel() { } - public GetSessionStatusModel(Integer vCID, String tokenID, String generalid, Integer doctorId) { + public GetSessionStatusModel(Integer vCID, String tokenID, String generalid, Integer doctorId, String patientName) { this.vCID = vCID; this.tokenID = tokenID; this.generalid = generalid; this.doctorId = doctorId; + this.patientName = patientName; } protected GetSessionStatusModel(Parcel in) { @@ -44,6 +48,7 @@ public class GetSessionStatusModel implements Parcelable { } else { doctorId = in.readInt(); } + patientName = in.readString(); } public static final Creator CREATOR = new Creator() { @@ -90,6 +95,16 @@ public class GetSessionStatusModel implements Parcelable { this.doctorId = doctorId; } + public String getPatientName() { + if (patientName == null) + patientName = "-"; + return patientName; + } + + public void setPatientName(String patientName) { + this.patientName = patientName; + } + @Override public int describeContents() { return 0; @@ -111,5 +126,6 @@ public class GetSessionStatusModel implements Parcelable { dest.writeByte((byte) 1); dest.writeInt(doctorId); } + dest.writeString(patientName); } } diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java index 26560967..be4ebfb8 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java @@ -11,8 +11,10 @@ import android.opengl.GLSurfaceView; import android.os.Bundle; import android.os.CountDownTimer; import android.os.Handler; +import android.os.SystemClock; import android.util.Log; import android.view.View; +import android.widget.Chronometer; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.ProgressBar; @@ -75,7 +77,13 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi private boolean isSpeckerClicked; private boolean isMicClicked; + private TextView patientName; + private Chronometer cmTimer; + long elapsedTime; + Boolean resume = false; + private ImageView mCallBtn; + private ImageView btnMinimize; private ImageView mCameraBtn; private ImageView mSwitchCameraBtn; private ImageView mspeckerBtn; @@ -128,7 +136,7 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi @Override protected void onDestroy() { disconnectSession(); - + cmTimer.stop(); super.onDestroy(); } @@ -148,8 +156,28 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi videoCallPresenter = new VideoCallPresenterImpl(this, baseUrl); + patientName = findViewById(R.id.patient_name); + patientName.setText(sessionStatusModel.getPatientName()); + + cmTimer = findViewById(R.id.cmTimer); + cmTimer.setFormat("mm:ss"); + cmTimer.setOnChronometerTickListener(arg0 -> { + long minutes; + long seconds; + if (!resume) { + minutes = ((SystemClock.elapsedRealtime() - cmTimer.getBase()) / 1000) / 60; + seconds = ((SystemClock.elapsedRealtime() - cmTimer.getBase()) / 1000) % 60; + elapsedTime = SystemClock.elapsedRealtime(); + } else { + minutes = ((elapsedTime - cmTimer.getBase()) / 1000) / 60; + seconds = ((elapsedTime - cmTimer.getBase()) / 1000) % 60; + elapsedTime = elapsedTime + 1000; + } + Log.d(TAG, "onChronometerTick: " + minutes + " : " + seconds); + }); mCallBtn = findViewById(R.id.btn_call); + btnMinimize = findViewById(R.id.btn_minimize); mCameraBtn = findViewById(R.id.btn_camera); mSwitchCameraBtn = findViewById(R.id.btn_switch_camera); mspeckerBtn = findViewById(R.id.btn_specker); @@ -252,6 +280,11 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi } mSession.publish(mPublisher); + + if (!resume) { + cmTimer.setBase(SystemClock.elapsedRealtime()); + } + cmTimer.start(); } @Override @@ -259,6 +292,7 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi Log.d(TAG, "onDisconnected: disconnected from session " + session.getSessionId()); mSession = null; + cmTimer.stop(); } @Override @@ -377,6 +411,10 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi finish(); } + public void onMinimizedClicked(View view) { + + } + public void onSwitchCameraClicked(View view) { if (mPublisher != null) { isSwitchCameraClicked = !isSwitchCameraClicked; diff --git a/android/app/src/main/res/drawable/ic_mini.xml b/android/app/src/main/res/drawable/ic_mini.xml new file mode 100644 index 00000000..29df8da2 --- /dev/null +++ b/android/app/src/main/res/drawable/ic_mini.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/android/app/src/main/res/drawable/shape_capsule.xml b/android/app/src/main/res/drawable/shape_capsule.xml new file mode 100644 index 00000000..a5dcdd09 --- /dev/null +++ b/android/app/src/main/res/drawable/shape_capsule.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file 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 2dcf2ba4..a3c2ced1 100644 --- a/android/app/src/main/res/layout/activity_video_call.xml +++ b/android/app/src/main/res/layout/activity_video_call.xml @@ -1,169 +1,181 @@ - + android:background="@color/text_color" + android:orientation="vertical"> + - - + + + + + android:layout_alignParentEnd="true" + android:background="@drawable/shape_capsule" + android:padding="@dimen/padding_space_small"> + + + + - + android:layout_height="0dp" + android:layout_weight="1" + tools:context=".ui.VideoCallActivity"> + + + + + + + + + android:background="@color/remoteBackground"> + - - - + - - + + + + + + + android:padding="@dimen/padding_space_big_2"> + android:src="@drawable/ic_mini" /> + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml index d1d2a305..29782be0 100644 --- a/android/app/src/main/res/values/colors.xml +++ b/android/app/src/main/res/values/colors.xml @@ -8,4 +8,10 @@ #827b92 #484258 + #FF2E303A + + #fff + #000 + #389842 + #d51e26 diff --git a/android/app/src/main/res/values/dimens.xml b/android/app/src/main/res/values/dimens.xml index 79f3d269..2d53d554 100644 --- a/android/app/src/main/res/values/dimens.xml +++ b/android/app/src/main/res/values/dimens.xml @@ -8,7 +8,11 @@ 60dp 54dp + 64dp + + 24dp + 25dp 88dp 117dp @@ -16,7 +20,16 @@ 100dp 90dp - - 24dp - 25dp + + 14sp + 16sp + 24sp + + + 4dp + 8sp + 16dp + 24dp + + diff --git a/lib/screens/live_care/end_call_screen.dart b/lib/screens/live_care/end_call_screen.dart index 617eef34..83a2d0f5 100644 --- a/lib/screens/live_care/end_call_screen.dart +++ b/lib/screens/live_care/end_call_screen.dart @@ -65,6 +65,7 @@ class _EndCallScreenState extends State { kSessionId: liveCareModel.startCallRes.openSessionID, kApiKey: '46209962', vcId: widget.patient.vcId, + patientName: widget.patient.fullName ?? widget.patient.firstName != null ? "${widget.patient.firstName} ${widget.patient.lastName}" : "-", tokenID: await liveCareModel.getToken(), generalId: GENERAL_ID, doctorId: liveCareModel.doctorProfile.doctorID, diff --git a/lib/screens/live_care/video_call.dart b/lib/screens/live_care/video_call.dart index c6f9a885..07de1943 100644 --- a/lib/screens/live_care/video_call.dart +++ b/lib/screens/live_care/video_call.dart @@ -66,6 +66,7 @@ class _VideoCallPageState extends State { //'1_MX40NjgwMzIyNH5-MTU5MzY4MzYzODYwM35ucExWYVRVSm5Hcy9uWGZmM1lOa3czZHV-fg', kApiKey: '46209962', vcId: widget.patientData.vcId, + patientName: widget.patientData.fullName ?? widget.patientData.firstName != null ? "${widget.patientData.firstName} ${widget.patientData.lastName}" : "-", tokenID: token, //"hfkjshdf347r8743", generalId: "Cs2020@2016\$2958", doctorId: doctorprofile['DoctorID'], 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 d9aa7d8d..69bbb97a 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -327,6 +327,7 @@ class _PatientProfileScreenState extends State kSessionId: model.startCallRes.openSessionID, kApiKey: '46209962', vcId: patient.vcId, + patientName: patient.fullName ?? patient.firstName != null ? "${patient.firstName} ${patient.lastName}" : "-", tokenID: await model.getToken(), generalId: GENERAL_ID, doctorId: model.doctorProfile.doctorID, diff --git a/lib/util/VideoChannel.dart b/lib/util/VideoChannel.dart index a0962010..0104f55b 100644 --- a/lib/util/VideoChannel.dart +++ b/lib/util/VideoChannel.dart @@ -10,7 +10,7 @@ class VideoChannel{ /// channel name static const _channel = const MethodChannel("Dr.cloudSolution/videoCall"); static openVideoCallScreen( - {kApiKey, kSessionId, kToken, callDuration, warningDuration,int vcId,String tokenID,String generalId,int doctorId, Function() onCallEnd , Function(SessionStatusModel sessionStatusModel) onCallNotRespond ,Function(String error) onFailure}) async { + {kApiKey, kSessionId, kToken, callDuration, warningDuration,int vcId,String tokenID,String generalId,int doctorId, String patientName, Function() onCallEnd , Function(SessionStatusModel sessionStatusModel) onCallNotRespond ,Function(String error) onFailure}) async { var result; try { result = await _channel.invokeMethod( @@ -25,6 +25,7 @@ class VideoChannel{ "TokenID": tokenID, "generalId": generalId, "DoctorId": doctorId , + "patientName": patientName, }, ); if(result['callResponse'] == 'CallEnd') { From 30bf59458c5f8453e5f828141ae97489e031c6e8 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Thu, 10 Jun 2021 16:51:10 +0300 Subject: [PATCH 28/72] finish medical report --- .../PatientMedicalReportViewModel.dart | 16 +- .../AddVerifyMedicalReport.dart | 43 +- .../medical_report/MedicalReportPage.dart | 37 +- pubspec.lock | 1123 ----------------- 4 files changed, 62 insertions(+), 1157 deletions(-) delete mode 100644 pubspec.lock diff --git a/lib/core/viewModel/PatientMedicalReportViewModel.dart b/lib/core/viewModel/PatientMedicalReportViewModel.dart index 999a0530..293cf587 100644 --- a/lib/core/viewModel/PatientMedicalReportViewModel.dart +++ b/lib/core/viewModel/PatientMedicalReportViewModel.dart @@ -25,12 +25,24 @@ 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.Busy); + setState(ViewState.BusyLocal); await _service.getMedicalReportTemplate(); if (_service.hasError) { error = _service.error; - setState(ViewState.Error); + setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); } diff --git a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart index 63dbb18b..a73eb90f 100644 --- a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart +++ b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart @@ -6,6 +6,7 @@ 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'; 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'; @@ -32,7 +33,7 @@ class _AddVerifyMedicalReportState extends State { : null; return BaseView( - // onModelReady: (model) => model.getMedicalReportTemplate(), + onModelReady: (model) => model.getMedicalReportTemplate(), builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, @@ -40,25 +41,35 @@ class _AddVerifyMedicalReportState extends State { ? TranslationBase.of(context).medicalReportAdd : TranslationBase.of(context).medicalReportVerify, backgroundColor: Theme.of(context).scaffoldBackgroundColor, - body: Column( - children: [ - Expanded( - child: Container( - margin: EdgeInsets.all(16), - child: Column( - children: [ - Expanded( - child: SingleChildScrollView( - child: Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + 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:""), + initialText: (medicalReport != null + ? medicalReport.reportDataHtml + : model.medicalReportTemplate + .length > 0 ? model + .medicalReportTemplate[0] : ""), + hint: "Write the medical report ", height: - MediaQuery.of(context).size.height * - 0.75, + MediaQuery + .of(context) + .size + .height * + 0.75, ), ], ), diff --git a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart index e2da651b..7baa109d 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart @@ -7,6 +7,7 @@ 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'; 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'; import 'package:doctor_app_flutter/widgets/patients/profile/add-order/addNewOrder.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/large_avatar.dart'; @@ -17,7 +18,6 @@ import 'package:doctor_app_flutter/widgets/shared/card_with_bg_widget.dart'; import 'package:eva_icons_flutter/eva_icons_flutter.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_html/flutter_html.dart'; import 'package:provider/provider.dart'; import '../../../../routes.dart'; @@ -75,13 +75,18 @@ class MedicalReportPage extends StatelessWidget { ), AddNewOrder( onTap: () { - Navigator.of(context) - .pushNamed(PATIENT_MEDICAL_REPORT_INSERT, arguments: { - 'patient': patient, - 'patientType': patientType, - 'arrivalType': arrivalType, - 'type': MedicalReportStatus.ADD - }); + if (model.hasOnHold()) { + 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 + }); + } }, label: TranslationBase.of(context).createNewMedicalReport, ), @@ -92,7 +97,7 @@ class MedicalReportPage extends StatelessWidget { onTap: () { if (model.medicalReportList[index].status == 1) { Navigator.of(context).pushNamed( - PATIENT_MEDICAL_REPORT_DETAIL, + PATIENT_MEDICAL_REPORT_INSERT, arguments: { 'patient': patient, 'patientType': patientType, @@ -101,7 +106,7 @@ class MedicalReportPage extends StatelessWidget { }); } else { Navigator.of(context).pushNamed( - PATIENT_MEDICAL_REPORT_INSERT, + PATIENT_MEDICAL_REPORT_DETAIL, arguments: { 'patient': patient, 'patientType': patientType, @@ -116,7 +121,7 @@ class MedicalReportPage extends StatelessWidget { child: CardWithBgWidget( hasBorder: false, bgColor: model.medicalReportList[index].status == 1 - ? Colors.red[700] + ? Color(0xFFCC9B14) : Colors.green[700], widget: Column( children: [ @@ -132,9 +137,9 @@ class MedicalReportPage extends StatelessWidget { : TranslationBase.of(context) .verified, color: model.medicalReportList[index] - .status == - 1 - ? Colors.red[700] + .status == + 1 + ? Color(0xFFCC9B14) : Colors.green[700], fontSize: 1.4 * SizeConfig.textMultiplier, bold: true, @@ -226,8 +231,8 @@ class MedicalReportPage extends StatelessWidget { Icon( model.medicalReportList[index].status == 1 - ? EvaIcons.eye - : DoctorApp.edit_1, + ? DoctorApp.edit_1 + :EvaIcons.eye , ), ], ), diff --git a/pubspec.lock b/pubspec.lock deleted file mode 100644 index 25596d43..00000000 --- a/pubspec.lock +++ /dev/null @@ -1,1123 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - _fe_analyzer_shared: - dependency: transitive - description: - name: _fe_analyzer_shared - url: "https://pub.dartlang.org" - source: hosted - version: "12.0.0" - analyzer: - dependency: transitive - description: - name: analyzer - url: "https://pub.dartlang.org" - source: hosted - version: "0.40.6" - archive: - dependency: transitive - description: - name: archive - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.13" - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.5.0-nullsafety.1" - autocomplete_textfield: - dependency: "direct main" - description: - name: autocomplete_textfield - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.3" - barcode_scan_fix: - dependency: "direct main" - description: - name: barcode_scan_fix - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - bazel_worker: - dependency: transitive - description: - name: bazel_worker - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.25" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0-nullsafety.1" - build: - dependency: transitive - description: - name: build - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.2" - build_config: - dependency: transitive - description: - name: build_config - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.5" - build_daemon: - dependency: transitive - description: - name: build_daemon - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.7" - build_modules: - dependency: transitive - description: - name: build_modules - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.4" - build_resolvers: - dependency: transitive - description: - name: build_resolvers - url: "https://pub.dartlang.org" - source: hosted - version: "1.5.3" - build_runner: - dependency: "direct dev" - description: - name: build_runner - url: "https://pub.dartlang.org" - source: hosted - version: "1.11.1" - build_runner_core: - dependency: transitive - description: - name: build_runner_core - url: "https://pub.dartlang.org" - source: hosted - version: "6.1.7" - build_web_compilers: - dependency: "direct dev" - description: - name: build_web_compilers - url: "https://pub.dartlang.org" - source: hosted - version: "2.12.2" - built_collection: - dependency: transitive - description: - name: built_collection - url: "https://pub.dartlang.org" - source: hosted - version: "4.3.2" - built_value: - dependency: transitive - description: - name: built_value - url: "https://pub.dartlang.org" - source: hosted - version: "7.1.0" - characters: - dependency: transitive - description: - name: characters - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0-nullsafety.3" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0-nullsafety.1" - charts_common: - dependency: transitive - description: - name: charts_common - url: "https://pub.dartlang.org" - source: hosted - version: "0.9.0" - charts_flutter: - dependency: "direct main" - description: - name: charts_flutter - url: "https://pub.dartlang.org" - source: hosted - version: "0.9.0" - checked_yaml: - dependency: transitive - description: - name: checked_yaml - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - chewie: - dependency: transitive - description: - name: chewie - url: "https://pub.dartlang.org" - source: hosted - version: "0.9.10" - chewie_audio: - dependency: transitive - description: - name: chewie_audio - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.0+1" - cli_util: - dependency: transitive - description: - name: cli_util - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0-nullsafety.1" - code_builder: - dependency: transitive - description: - name: code_builder - url: "https://pub.dartlang.org" - source: hosted - version: "3.7.0" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.15.0-nullsafety.3" - connectivity: - dependency: "direct main" - description: - name: connectivity - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.9+5" - connectivity_for_web: - dependency: transitive - description: - name: connectivity_for_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.1+4" - connectivity_macos: - dependency: transitive - description: - name: connectivity_macos - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.0+7" - connectivity_platform_interface: - dependency: transitive - description: - name: connectivity_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.6" - convert: - dependency: transitive - description: - name: convert - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" - crypto: - dependency: transitive - description: - name: crypto - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.5" - css_colors: - dependency: transitive - description: - name: css_colors - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - csslib: - dependency: transitive - description: - name: csslib - url: "https://pub.dartlang.org" - source: hosted - version: "0.16.2" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - dart_style: - dependency: transitive - description: - name: dart_style - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.10" - date_time_picker: - dependency: "direct main" - description: - name: date_time_picker - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - device_info: - dependency: "direct main" - description: - name: device_info - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.2+10" - device_info_platform_interface: - dependency: transitive - description: - name: device_info_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - dropdown_search: - dependency: "direct main" - description: - name: dropdown_search - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.9" - equatable: - dependency: transitive - description: - name: equatable - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.6" - eva_icons_flutter: - dependency: "direct main" - description: - name: eva_icons_flutter - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.1" - expandable: - dependency: "direct main" - description: - name: expandable - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.4" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0-nullsafety.1" - ffi: - dependency: transitive - description: - name: ffi - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - file: - dependency: transitive - description: - name: file - url: "https://pub.dartlang.org" - source: hosted - version: "5.2.1" - firebase_core: - dependency: transitive - description: - name: firebase_core - url: "https://pub.dartlang.org" - source: hosted - version: "0.5.3" - firebase_core_platform_interface: - dependency: transitive - description: - name: firebase_core_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - firebase_core_web: - dependency: transitive - description: - name: firebase_core_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.1+1" - firebase_messaging: - dependency: "direct main" - description: - name: firebase_messaging - url: "https://pub.dartlang.org" - source: hosted - version: "7.0.3" - fixnum: - dependency: transitive - description: - name: fixnum - url: "https://pub.dartlang.org" - source: hosted - version: "0.10.11" - fl_chart: - dependency: "direct main" - description: - name: fl_chart - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.3" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_device_type: - dependency: "direct main" - description: - name: flutter_device_type - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0" - flutter_flexible_toast: - dependency: "direct main" - description: - name: flutter_flexible_toast - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.4" - flutter_gifimage: - dependency: "direct main" - description: - name: flutter_gifimage - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - flutter_html: - dependency: "direct main" - description: - name: flutter_html - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - flutter_inappwebview: - dependency: transitive - description: - name: flutter_inappwebview - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.0+4" - flutter_localizations: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_page_indicator: - dependency: transitive - description: - name: flutter_page_indicator - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.3" - flutter_plugin_android_lifecycle: - dependency: transitive - description: - name: flutter_plugin_android_lifecycle - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.11" - flutter_staggered_grid_view: - dependency: "direct main" - description: - name: flutter_staggered_grid_view - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.4" - flutter_svg: - dependency: transitive - description: - name: flutter_svg - url: "https://pub.dartlang.org" - source: hosted - version: "0.18.1" - flutter_swiper: - dependency: "direct main" - description: - name: flutter_swiper - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - font_awesome_flutter: - dependency: "direct main" - description: - name: font_awesome_flutter - url: "https://pub.dartlang.org" - source: hosted - version: "8.12.0" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.4" - glob: - dependency: transitive - description: - name: glob - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" - graphs: - dependency: transitive - description: - name: graphs - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0" - hexcolor: - dependency: "direct main" - description: - name: hexcolor - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.6" - html: - dependency: "direct main" - description: - name: html - url: "https://pub.dartlang.org" - source: hosted - version: "0.14.0+4" - html_editor_enhanced: - dependency: "direct main" - description: - name: html_editor_enhanced - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.0" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.2" - http_interceptor: - dependency: "direct main" - description: - name: http_interceptor - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0" - http_multi_server: - dependency: transitive - description: - name: http_multi_server - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.0" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.4" - imei_plugin: - dependency: "direct main" - description: - name: imei_plugin - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" - intl: - dependency: "direct main" - description: - name: intl - url: "https://pub.dartlang.org" - source: hosted - version: "0.16.1" - io: - dependency: transitive - description: - name: io - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.5" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.3-nullsafety.1" - json_annotation: - dependency: transitive - description: - name: json_annotation - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.1" - local_auth: - dependency: "direct main" - description: - name: local_auth - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.3+4" - logging: - dependency: transitive - description: - name: logging - url: "https://pub.dartlang.org" - source: hosted - version: "0.11.4" - maps_launcher: - dependency: "direct main" - description: - name: maps_launcher - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.2+2" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.10-nullsafety.1" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.0-nullsafety.4" - mime: - dependency: transitive - description: - name: mime - url: "https://pub.dartlang.org" - source: hosted - version: "0.9.7" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - node_interop: - dependency: transitive - description: - name: node_interop - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.1" - node_io: - dependency: transitive - description: - name: node_io - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" - open_iconic_flutter: - dependency: transitive - description: - name: open_iconic_flutter - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.0" - package_config: - dependency: transitive - description: - name: package_config - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0-nullsafety.1" - path_drawing: - dependency: transitive - description: - name: path_drawing - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.1+1" - path_parsing: - dependency: transitive - description: - name: path_parsing - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.4" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+2" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - path_provider_windows: - dependency: transitive - description: - name: path_provider_windows - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4+3" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.2" - percent_indicator: - dependency: "direct main" - description: - name: percent_indicator - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.9+1" - permission_handler: - dependency: "direct main" - description: - name: permission_handler - url: "https://pub.dartlang.org" - source: hosted - version: "5.1.0+2" - permission_handler_platform_interface: - dependency: transitive - description: - name: permission_handler_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.2" - petitparser: - dependency: transitive - description: - name: petitparser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.0" - platform: - dependency: transitive - description: - name: platform - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.1" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.3" - pool: - dependency: transitive - description: - name: pool - url: "https://pub.dartlang.org" - source: hosted - version: "1.4.0" - process: - dependency: transitive - description: - name: process - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.13" - progress_hud_v2: - dependency: "direct main" - description: - name: progress_hud_v2 - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - protobuf: - dependency: transitive - description: - name: protobuf - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.3.3" - pub_semver: - dependency: transitive - description: - name: pub_semver - url: "https://pub.dartlang.org" - source: hosted - version: "1.4.4" - pubspec_parse: - dependency: transitive - description: - name: pubspec_parse - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.8" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.5" - scratch_space: - dependency: transitive - description: - name: scratch_space - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4+3" - screen: - dependency: transitive - description: - name: screen - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.5" - shared_preferences: - dependency: "direct main" - description: - name: shared_preferences - url: "https://pub.dartlang.org" - source: hosted - version: "0.5.12+4" - shared_preferences_linux: - dependency: transitive - description: - name: shared_preferences_linux - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.2+4" - shared_preferences_macos: - dependency: transitive - description: - name: shared_preferences_macos - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+11" - shared_preferences_platform_interface: - dependency: transitive - description: - name: shared_preferences_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - shared_preferences_web: - dependency: transitive - description: - name: shared_preferences_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.2+7" - shared_preferences_windows: - dependency: transitive - description: - name: shared_preferences_windows - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.2+3" - shelf: - dependency: transitive - description: - name: shelf - url: "https://pub.dartlang.org" - source: hosted - version: "0.7.9" - shelf_web_socket: - dependency: transitive - description: - name: shelf_web_socket - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.4+1" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_maps: - dependency: transitive - description: - name: source_maps - url: "https://pub.dartlang.org" - source: hosted - version: "0.10.9" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0-nullsafety.2" - speech_to_text: - dependency: "direct main" - description: - path: speech_to_text - relative: true - source: path - version: "0.0.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.10.0-nullsafety.2" - sticky_headers: - dependency: "direct main" - description: - name: sticky_headers - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.8+1" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0-nullsafety.1" - stream_transform: - dependency: transitive - description: - name: stream_transform - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0-nullsafety.1" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0-nullsafety.1" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.19-nullsafety.2" - timing: - dependency: transitive - description: - name: timing - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1+3" - transformer_page_view: - dependency: transitive - description: - name: transformer_page_view - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.6" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.0-nullsafety.3" - url_launcher: - dependency: "direct main" - description: - name: url_launcher - url: "https://pub.dartlang.org" - source: hosted - version: "5.7.10" - url_launcher_linux: - dependency: transitive - description: - name: url_launcher_linux - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+4" - url_launcher_macos: - dependency: transitive - description: - name: url_launcher_macos - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+9" - url_launcher_platform_interface: - dependency: transitive - description: - name: url_launcher_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.9" - url_launcher_web: - dependency: transitive - description: - name: url_launcher_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.5+3" - url_launcher_windows: - dependency: transitive - description: - name: url_launcher_windows - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+3" - uuid: - dependency: transitive - description: - name: uuid - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.2" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0-nullsafety.3" - video_player: - dependency: transitive - description: - name: video_player - url: "https://pub.dartlang.org" - source: hosted - version: "0.10.12+5" - video_player_platform_interface: - dependency: transitive - description: - name: video_player_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.0" - video_player_web: - dependency: transitive - description: - name: video_player_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.4+1" - wakelock: - dependency: transitive - description: - name: wakelock - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.4+2" - watcher: - dependency: transitive - description: - name: watcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.9.7+15" - web_socket_channel: - dependency: transitive - description: - name: web_socket_channel - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" - webview_flutter: - dependency: transitive - description: - name: webview_flutter - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.24" - win32: - dependency: transitive - description: - name: win32 - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.4+1" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.2" - xml: - dependency: transitive - description: - name: xml - url: "https://pub.dartlang.org" - source: hosted - version: "4.5.1" - yaml: - dependency: transitive - description: - name: yaml - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.1" -sdks: - dart: ">=2.10.0 <=2.11.0-213.1.beta" - flutter: ">=1.22.0 <2.0.0" From 726d3ab885f5bcee72b55d18e9d88761749df4f6 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Thu, 10 Jun 2021 16:52:16 +0300 Subject: [PATCH 29/72] Fix video call issue android --- android/app/build.gradle | 2 +- lib/config/config.dart | 4 ++-- lib/screens/live_care/end_call_screen.dart | 2 +- .../profile/profile_screen/patient_profile_screen.dart | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 16960d54..e18e8ae5 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -39,7 +39,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.hmg.hmgDr" - minSdkVersion 18 + minSdkVersion 21 targetSdkVersion 30 versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/lib/config/config.dart b/lib/config/config.dart index 4bbbd40e..eb946dea 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/screens/live_care/end_call_screen.dart b/lib/screens/live_care/end_call_screen.dart index 83a2d0f5..b7383703 100644 --- a/lib/screens/live_care/end_call_screen.dart +++ b/lib/screens/live_care/end_call_screen.dart @@ -65,7 +65,7 @@ class _EndCallScreenState extends State { kSessionId: liveCareModel.startCallRes.openSessionID, kApiKey: '46209962', vcId: widget.patient.vcId, - patientName: widget.patient.fullName ?? widget.patient.firstName != null ? "${widget.patient.firstName} ${widget.patient.lastName}" : "-", + patientName: widget.patient.fullName ?? (widget.patient.firstName != null ? "${widget.patient.firstName} ${widget.patient.lastName}" : "-"), tokenID: await liveCareModel.getToken(), generalId: GENERAL_ID, doctorId: liveCareModel.doctorProfile.doctorID, 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 69bbb97a..298e7d18 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -327,7 +327,7 @@ class _PatientProfileScreenState extends State kSessionId: model.startCallRes.openSessionID, kApiKey: '46209962', vcId: patient.vcId, - patientName: patient.fullName ?? patient.firstName != null ? "${patient.firstName} ${patient.lastName}" : "-", + patientName: patient.fullName ?? (patient.firstName != null ? "${patient.firstName} ${patient.lastName}" : "-"), tokenID: await model.getToken(), generalId: GENERAL_ID, doctorId: model.doctorProfile.doctorID, From c44b3d74bb1741f35c0921aa57c2988a74185bfc Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 10 Jun 2021 17:05:03 +0300 Subject: [PATCH 30/72] reply changes --- lib/config/config.dart | 4 +- .../referral/MyReferralPatientModel.dart | 132 ++++++++-------- .../referral/AddReplayOnReferralPatient.dart | 148 +++++++++++++----- .../my-referral-inpatient-screen.dart | 82 +++++----- .../referral_patient_detail_in-paint.dart | 48 +++--- .../patient-referral-item-widget.dart | 4 +- 6 files changed, 245 insertions(+), 173 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 4bbbd40e..eb946dea 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/model/referral/MyReferralPatientModel.dart b/lib/core/model/referral/MyReferralPatientModel.dart index ac069e8d..1072e098 100644 --- a/lib/core/model/referral/MyReferralPatientModel.dart +++ b/lib/core/model/referral/MyReferralPatientModel.dart @@ -64,65 +64,65 @@ class MyReferralPatientModel { MyReferralPatientModel( {this.rowID, - this.projectID, - this.lineItemNo, - this.doctorID, - this.patientID, - this.doctorName, - this.doctorNameN, - this.firstName, - this.middleName, - this.lastName, - this.firstNameN, - this.middleNameN, - this.lastNameN, - this.gender, - this.dateofBirth, - this.mobileNumber, - this.emailAddress, - this.patientIdentificationNo, - this.patientType, - this.admissionNo, - this.admissionDate, - this.roomID, - this.bedID, - this.nursingStationID, - this.description, - this.nationalityName, - this.nationalityNameN, - this.clinicDescription, - this.clinicDescriptionN, - this.referralDoctor, - this.referringDoctor, - this.referralClinic, - this.referringClinic, - this.referralStatus, - this.referralDate, - this.referringDoctorRemarks, - this.referredDoctorRemarks, - 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.projectID, + this.lineItemNo, + this.doctorID, + this.patientID, + this.doctorName, + this.doctorNameN, + this.firstName, + this.middleName, + this.lastName, + this.firstNameN, + this.middleNameN, + this.lastNameN, + this.gender, + this.dateofBirth, + this.mobileNumber, + this.emailAddress, + this.patientIdentificationNo, + this.patientType, + this.admissionNo, + this.admissionDate, + this.roomID, + this.bedID, + this.nursingStationID, + this.description, + this.nationalityName, + this.nationalityNameN, + this.clinicDescription, + this.clinicDescriptionN, + this.referralDoctor, + this.referringDoctor, + this.referralClinic, + this.referringClinic, + this.referralStatus, + this.referralDate, + this.referringDoctorRemarks, + this.referredDoctorRemarks, + 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}); MyReferralPatientModel.fromJson(Map json) { rowID = json['RowID']; @@ -158,13 +158,19 @@ class MyReferralPatientModel { referringDoctor = json['ReferringDoctor']; referralClinic = json['ReferralClinic']; referringClinic = json['ReferringClinic']; - referralStatus = json["ReferralStatus"] is String ?json['ReferralStatus']== "Accepted"?46:json['ReferralStatus']=="Pending"?1:0: json["ReferralStatus"]; + referralStatus = json["ReferralStatus"] is String + ? json['ReferralStatus'] == "Accepted" + ? 46 + : json['ReferralStatus'] == "Pending" + ? 1 + : 0 + : json["ReferralStatus"]; try { referralDate = AppDateUtils.getDateTimeFromString(json['ReferralDate']); - } catch (e){ + } catch (e) { referralDate = AppDateUtils.convertStringToDate(json['ReferralDate']); } finally { - referralDate = DateTime.now(); + referralDate = DateTime.now(); } referringDoctorRemarks = json['ReferringDoctorRemarks']; @@ -260,6 +266,6 @@ class MyReferralPatientModel { } get patientName { - return this.firstName+" "+this.lastName; + return this.firstName + " " + this.lastName; } } diff --git a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart index aadcd5f0..c246a3ad 100644 --- a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart +++ b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart @@ -116,14 +116,14 @@ class _AddReplayOnReferralPatientState ), ), Container( - height: replayOnReferralController.text.isNotEmpty ? 130 : 70, - margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), + // height: replayOnReferralController.text.isNotEmpty ? 130 : 70, + // margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), child: Column( children: [ replayOnReferralController.text.isEmpty ? SizedBox() : Container( - margin: EdgeInsets.all(5), + margin: EdgeInsets.all(16), child: AppButton( title: TranslationBase.of(context).clearText, onPressed: () { @@ -134,47 +134,111 @@ class _AddReplayOnReferralPatientState ), ), 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"); + margin: EdgeInsets.fromLTRB(16, 0, 16, 16), + child: Row( + children: [ + Expanded( + child: AppButton( + onPressed: () { + Navigator.of(context).pop(); + }, + title: TranslationBase.of(context).reject, + fontColor: Colors.white, + color: Colors.red[600], + ), + ), + SizedBox( + width: 4, + ), + Expanded( + child: AppButton( + onPressed: () async { setState(() { - isSubmitted = false; + 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; + }); + } + }, + title: TranslationBase.of(context).noteConfirm, + fontColor: Colors.white, + color: Colors.green[600], + ), + ), + ], + ), + ), + // 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-inpatient-screen.dart b/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart index 636a596f..f4a002d6 100644 --- a/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart @@ -27,7 +27,6 @@ class MyReferralInPatientScreen extends StatelessWidget { appBarTitle: TranslationBase.of(context).referPatient, body: Column( children: [ - Container( margin: EdgeInsets.only(top: 70), child: PatientTypeRadioWidget( @@ -62,50 +61,51 @@ class MyReferralInPatientScreen extends StatelessWidget { ], ), ) - : SingleChildScrollView( - child: Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - - ...List.generate( - model.myReferralPatients.length, - (index) => InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: ReferralPatientDetailScreen(model.myReferralPatients[index],model), - ), - ); - }, - child: PatientReferralItemWidget( - referralStatus: model.getReferralStatusNameByCode(model.myReferralPatients[index].referralStatus,context), - referralStatusCode: model.myReferralPatients[index].referralStatus, - patientName: model.myReferralPatients[index].patientName, - patientGender: model.myReferralPatients[index].gender, - referredDate: AppDateUtils.getDayMonthYearDateFormatted(model.myReferralPatients[index].referralDate), - referredTime: AppDateUtils.getTimeHHMMA(model.myReferralPatients[index].referralDate), - patientID: "${model.myReferralPatients[index].patientID}", - isSameBranch: false, - isReferral: true, - isReferralClinic: true, - referralClinic:"${model.myReferralPatients[index].referringClinicDescription}", - remark: model.myReferralPatients[index].referringDoctorRemarks, - nationality: model.myReferralPatients[index].nationalityName, - nationalityFlag: model.myReferralPatients[index].nationalityFlagURL, - doctorAvatar: model.myReferralPatients[index].doctorImageURL, - referralDoctorName: model.myReferralPatients[index].referringDoctorName, - clinicDescription: model.myReferralPatients[index].referringClinicDescription, - infoIcon: Icon(FontAwesomeIcons.arrowRight, - size: 25, color: Colors.black), + : Expanded( + child: SingleChildScrollView( + child: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ...List.generate( + model.myReferralPatients.length, + (index) => InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: ReferralPatientDetailScreen(model.myReferralPatients[index],model), + ), + ); + }, + child: PatientReferralItemWidget( + referralStatus: model.getReferralStatusNameByCode(model.myReferralPatients[index].referralStatus,context), + referralStatusCode: model.myReferralPatients[index].referralStatus, + patientName: model.myReferralPatients[index].patientName, + patientGender: model.myReferralPatients[index].gender, + referredDate: AppDateUtils.getDayMonthYearDateFormatted(model.myReferralPatients[index].referralDate), + referredTime: AppDateUtils.getTimeHHMMA(model.myReferralPatients[index].referralDate), + patientID: "${model.myReferralPatients[index].patientID}", + isSameBranch: false, + isReferral: true, + isReferralClinic: true, + referralClinic:"${model.myReferralPatients[index].referringClinicDescription}", + remark: model.myReferralPatients[index].referringDoctorRemarks, + nationality: model.myReferralPatients[index].nationalityName, + nationalityFlag: model.myReferralPatients[index].nationalityFlagURL, + doctorAvatar: model.myReferralPatients[index].doctorImageURL, + referralDoctorName: model.myReferralPatients[index].referringDoctorName, + clinicDescription: model.myReferralPatients[index].referringClinicDescription, + infoIcon: Icon(FontAwesomeIcons.arrowRight, + size: 25, color: Colors.black), + ), ), ), - ), - ], + ], + ), ), ), - ), + ), ], ), ), 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 e2175bae..7f0cd146 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 @@ -154,7 +154,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { fontWeight: FontWeight.w700, color: referredPatient.referralStatus == 1 ? Color(0xffc4aa54) - : referredPatient.referralStatus == 46 + : referredPatient.referralStatus == 46 || referredPatient.referralStatus == 2 ? Colors.green[700] : Colors.red[700], ), @@ -548,30 +548,32 @@ class ReferralPatientDetailScreen extends StatelessWidget { ), ), ), - Container( - margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), - child: AppButton( - title: referredPatient.referredDoctorRemarks.isEmpty ? TranslationBase.of(context).replay : TranslationBase.of(context).edit, - color: Colors.red[700], - fontColor: Colors.white, - fontWeight: FontWeight.w700, - fontSize: 1.8, - hPadding: 8, - vPadding: 12, - onPressed: () async { - Navigator.push( - context, - SlideUpPageRoute( - widget: AddReplayOnReferralPatient( - patientReferralViewModel: patientReferralViewModel, - myReferralInPatientModel: referredPatient, - isEdited: referredPatient.referredDoctorRemarks.isNotEmpty, + if (referredPatient.referralStatus == 1) + Container( + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), + child: AppButton( + title: TranslationBase.of(context).replay, + color: Colors.red[700], + fontColor: Colors.white, + fontWeight: FontWeight.w700, + fontSize: 1.8, + hPadding: 8, + vPadding: 12, + onPressed: () async { + Navigator.push( + context, + SlideUpPageRoute( + widget: AddReplayOnReferralPatient( + patientReferralViewModel: patientReferralViewModel, + myReferralInPatientModel: referredPatient, + isEdited: referredPatient + .referredDoctorRemarks.isNotEmpty, + ), ), - ), - ); - }, + ); + }, + ), ), - ), ], ), ), diff --git a/lib/widgets/patients/patient-referral-item-widget.dart b/lib/widgets/patients/patient-referral-item-widget.dart index 02b2d241..a898e39c 100644 --- a/lib/widgets/patients/patient-referral-item-widget.dart +++ b/lib/widgets/patients/patient-referral-item-widget.dart @@ -58,7 +58,7 @@ class PatientReferralItemWidget extends StatelessWidget { child: CardWithBgWidget( bgColor: referralStatusCode == 1 ? Color(0xffc4aa54) - : referralStatusCode == 46 + : referralStatusCode == 46 || referralStatusCode == 2 ? Colors.green[700] : Colors.red[700], hasBorder: false, @@ -78,7 +78,7 @@ class PatientReferralItemWidget extends StatelessWidget { fontWeight: FontWeight.w700, color: referralStatusCode == 1 ? Color(0xffc4aa54) - : referralStatusCode == 46 + : referralStatusCode == 46 || referralStatusCode == 2 ? Colors.green[700] : Colors.red[700], ), From 3fefcf60d7d304274af6fbfdbe93b3bf9d4d593f Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Sun, 13 Jun 2021 10:06:42 +0300 Subject: [PATCH 31/72] match the app header design --- lib/config/config.dart | 4 +- .../profile/patient-profile-app-bar.dart | 130 ++++++++---------- 2 files changed, 59 insertions(+), 75 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index eb946dea..4bbbd40e 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/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart index 750ee9d5..770137a2 100644 --- a/lib/widgets/patients/profile/patient-profile-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -9,7 +9,6 @@ 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'; -import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -98,7 +97,7 @@ class PatientProfileAppBar extends StatelessWidget child: Row(children: [ IconButton( icon: Icon(Icons.arrow_back_ios), - color: Colors.black, //Colors.black, + color: Color(0xFF2B353E), //Colors.black, onPressed: () => Navigator.pop(context), ), Expanded( @@ -111,6 +110,7 @@ class PatientProfileAppBar extends StatelessWidget fontSize: SizeConfig.textMultiplier * 1.8, fontWeight: FontWeight.bold, fontFamily: 'Poppins', + color: Color(0xFF2B353E), ), ), gender == 1 @@ -215,10 +215,10 @@ class PatientProfileAppBar extends StatelessWidget AppText( TranslationBase.of(context).appointmentDate + " : ", - fontSize: 14, - fontWeight: FontWeight.normal, + fontSize: 10, + color: Color(0xFF575757), + fontWeight: FontWeight.w600, fontFamily: 'Poppins', - color: Colors.black, ), patient.startTime != null ? Container( @@ -231,7 +231,7 @@ class PatientProfileAppBar extends StatelessWidget child: AppText( patient.startTime ?? "", color: Colors.white, - fontSize: 1.5 * SizeConfig.textMultiplier, + fontSize: 12, textAlign: TextAlign.center, fontWeight: FontWeight.bold, ), @@ -244,7 +244,7 @@ class PatientProfileAppBar extends StatelessWidget child: AppText( AppDateUtils.convertDateFormatImproved( patient.appointmentDate ?? ''), - fontSize: 1.5 * SizeConfig.textMultiplier, + fontSize: 12, fontWeight: FontWeight.bold, ), ), @@ -267,17 +267,23 @@ class PatientProfileAppBar extends StatelessWidget color: Colors.black), children: [ new TextSpan( - text: TranslationBase - .of(context) - .fileNumber, - style: TextStyle( - fontSize: 14, fontFamily: 'Poppins')), + text: TranslationBase + .of(context) + .fileNumber, + + style: TextStyle( + fontSize: 10, + fontFamily: 'Poppins', + color: Color(0xFF575757), + fontWeight: FontWeight.w600, + + ),), new TextSpan( text: patient.patientId.toString(), style: TextStyle( - fontWeight: FontWeight.w700, - fontFamily: 'Poppins', - fontSize: 14)), + fontWeight: FontWeight.w700, + fontFamily: 'Poppins', + fontSize: 12, color: Color(0xFF2E303A),)), ], ), ), @@ -316,8 +322,10 @@ class PatientProfileAppBar extends StatelessWidget ), children: [ new TextSpan( - text: TranslationBase.of(context).age+ " : ", - style: TextStyle(fontSize: 14)), + text: TranslationBase + .of(context) + .age + " : ", + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757),)), new TextSpan( text: "${AppDateUtils.getAgeByBirthday( @@ -327,7 +335,9 @@ class PatientProfileAppBar extends StatelessWidget : patient.dateofBirth ?? "", context, isServerFormat: !isFromLiveCare)}", style: TextStyle( - fontWeight: FontWeight.w700, fontSize: 14)), + fontWeight: FontWeight.w700, + fontSize: 12, + color: Color(0xFF2E303A),)), ], ), ), @@ -361,9 +371,7 @@ class PatientProfileAppBar extends StatelessWidget child: RichText( text: new TextSpan( style: new TextStyle( - fontSize: - 2.0 * SizeConfig.textMultiplier, - color: Colors.black, + fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757), fontFamily: 'Poppins', ), children: [ @@ -373,21 +381,22 @@ class PatientProfileAppBar extends StatelessWidget : TranslationBase.of(context) .admissionDate + " : ", - style: TextStyle(fontSize: 14)), + style: TextStyle(fontSize: 10)), new TextSpan( text: patient.admissionDate == null ? "" : "${AppDateUtils.convertDateFromServerFormat(patient.admissionDate.toString(), 'yyyy-MM-dd')}", style: TextStyle( - fontWeight: FontWeight.w700, - fontSize: 15)), + fontWeight: FontWeight.w700, + fontSize: 12, + color: Color(0xFF2E303A),)), ]))), if (patient.admissionDate != null) Row( children: [ AppText( "${TranslationBase.of(context).numOfDays}: ", - fontSize: 15, + fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757) ), if(isDischargedPatient && patient.dischargeDate != null) @@ -399,8 +408,10 @@ class PatientProfileAppBar extends StatelessWidget .getDateTimeFromServerFormat( patient.admissionDate)) .inDays + 1}", - fontSize: 15, - fontWeight: FontWeight.w700) + fontWeight: FontWeight.w700, + fontSize: 12, + color: Color(0xFF2E303A), + ) else AppText( "${DateTime @@ -409,8 +420,9 @@ class PatientProfileAppBar extends StatelessWidget .getDateTimeFromServerFormat( patient.admissionDate)) .inDays + 1}", - fontSize: 15, - fontWeight: FontWeight.w700), + fontWeight: FontWeight.w700, + fontSize: 12, + color: Color(0xFF2E303A),), ], ), ], @@ -468,17 +480,17 @@ class PatientProfileAppBar extends StatelessWidget '${TranslationBase .of(context) .dr}$doctorName', - color: Colors.black, - fontWeight: FontWeight.w600, - fontSize: 9, + color: Color(0xFF2E303A), + fontWeight: FontWeight.w700, + fontSize: 12, ), if (orderNo != null && !isPrescriptions) Row( children: [ AppText('Order No: ', - color: Colors.grey[800], - fontSize: 12), + + fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757),), AppText(orderNo ?? '', fontSize: 12) ], @@ -488,8 +500,7 @@ class PatientProfileAppBar extends StatelessWidget Row( children: [ AppText('Invoice: ', - color: Colors.grey[800], - fontSize: 12), + fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757),), AppText(invoiceNO ?? "", fontSize: 12) ], @@ -498,8 +509,7 @@ class PatientProfileAppBar extends StatelessWidget Row( children: [ AppText('Branch: ', - color: Colors.grey[800], - fontSize: 12), + fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757),), AppText(branch ?? '', fontSize: 12) ], @@ -509,8 +519,7 @@ class PatientProfileAppBar extends StatelessWidget Row( children: [ AppText('Clinic: ', - color: Colors.grey[800], - fontSize: 12), + fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757),), AppText(clinic ?? '', fontSize: 12) ], @@ -520,8 +529,7 @@ class PatientProfileAppBar extends StatelessWidget Row( children: [ AppText('Episode: ', - color: Colors.grey[800], - fontSize: 12), + fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757),), AppText(episode ?? '', fontSize: 12) ], @@ -531,23 +539,20 @@ class PatientProfileAppBar extends StatelessWidget Row( children: [ AppText('Visit Date: ', - color: Colors.grey[800], - fontSize: 12), + fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757),), AppText(visitDate ?? '', fontSize: 12) ], ), if (!isMedicalFile) Row( + children: [ - Expanded( - child: AppText( - !isPrescriptions - ? 'Result Date: ' - : 'Prescriptions Date ', - color: Colors.grey[800], - fontSize: 12, - ), + AppText( + !isPrescriptions + ? 'Result Date:' + : 'Prescriptions Date ', + fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757), ), AppText( '${AppDateUtils @@ -573,27 +578,6 @@ class PatientProfileAppBar extends StatelessWidget ), ); } - - - - - 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()); - } - - myBoxDecoration() { - return BoxDecoration( - border: Border( - top: BorderSide( - color: Colors.green, - width: 5, - ), - ), - borderRadius: BorderRadius.circular(10)); - } - @override Size get preferredSize => Size(double.maxFinite, height == 0 From bc53ca7b8aab8aa5d992b98ef2e79cfd781bc3cf Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Sun, 13 Jun 2021 13:07:39 +0300 Subject: [PATCH 32/72] fix appointment date in header --- .../patient_profile_screen.dart | 2 +- lib/util/date-utils.dart | 6 +- .../profile/patient-profile-app-bar.dart | 113 +++++++----------- 3 files changed, 48 insertions(+), 73 deletions(-) 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 cc71dd6d..e0bea0b7 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -108,7 +108,7 @@ class _PatientProfileScreenState extends State isFromLiveCare: isFromLiveCare, height: (patient.patientStatusType != null && patient.patientStatusType == 43) - ? 210 + ? 220 : isDischargedPatient ? 240 : 0, diff --git a/lib/util/date-utils.dart b/lib/util/date-utils.dart index 511b99e9..9b00ba2b 100644 --- a/lib/util/date-utils.dart +++ b/lib/util/date-utils.dart @@ -16,7 +16,11 @@ class AppDateUtils { } static String convertStringToDateFormat(String date, String dateFormat) { - DateTime dateTime = DateTime.parse(date); + DateTime dateTime ; + if(date.contains("/Date")) + dateTime= getDateTimeFromServerFormat(date); + else + dateTime = DateTime.parse(date); return convertDateToFormat(dateTime, dateFormat); } diff --git a/lib/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart index 770137a2..5d676061 100644 --- a/lib/widgets/patients/profile/patient-profile-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -60,6 +60,7 @@ class PatientProfileAppBar extends StatelessWidget this.isFromSOAP = false, this.isFromLabResult = false}); + @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); @@ -84,8 +85,8 @@ class PatientProfileAppBar extends StatelessWidget ? isInpatient ? 215 : isAppointmentHeader - ? 310 - : 200 + ? 325 + : 215 : height, child: Container( padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), @@ -157,8 +158,7 @@ class PatientProfileAppBar extends StatelessWidget child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SERVICES_PATIANT2[int.parse(patientType)] == - "patientArrivalList" + patient.patientStatusType != null ? Container( child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -182,81 +182,18 @@ class PatientProfileAppBar extends StatelessWidget fontFamily: 'Poppins', fontSize: 12, ), - arrivalType == '1' || patient.arrivedOn == null + patient.startTime != null ? AppText( patient.startTime != null ? patient.startTime : '', fontFamily: 'Poppins', fontWeight: FontWeight.w600, - ) - : AppText( - patient.arrivedOn != null - ? (isFromSOAP ? AppDateUtils - .getDayMonthYearDateFormatted( - AppDateUtils.convertStringToDate( - patient.arrivedOn)) : AppDateUtils - .convertStringToDateFormat( - patient.arrivedOn, - 'MM-dd-yyyy HH:mm')) - : '', - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - ) + ):SizedBox() ], )) : SizedBox(), - if (SERVICES_PATIANT2[int.parse(patientType)] == - "List_MyOutPatient" && !isFromLiveCare) - Container( - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).appointmentDate + - " : ", - fontSize: 10, - color: Color(0xFF575757), - fontWeight: FontWeight.w600, - fontFamily: 'Poppins', - ), - patient.startTime != null - ? Container( - height: 15, - width: 60, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(25), - color: HexColor("#20A169"), - ), - child: AppText( - patient.startTime ?? "", - color: Colors.white, - fontSize: 12, - textAlign: TextAlign.center, - fontWeight: FontWeight.bold, - ), - ) - : SizedBox(), - SizedBox( - width: 3.5, - ), - Container( - child: AppText( - AppDateUtils.convertDateFormatImproved( - patient.appointmentDate ?? ''), - fontSize: 12, - fontWeight: FontWeight.bold, - ), - ), - SizedBox( - height: 0.5, - ) - ], - ), - margin: EdgeInsets.only( - top: 8, - ), - ), + Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -342,6 +279,40 @@ class PatientProfileAppBar extends StatelessWidget ), ), ), + + if ( patient.appointmentDate != null && patient.appointmentDate.isNotEmpty) + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).appointmentDate + + " : ", + fontSize: 10, + color: Color(0xFF575757), + fontWeight: FontWeight.w600, + fontFamily: 'Poppins', + ), + SizedBox( + width: 3.5, + ), + AppText( + (isFromSOAP ? AppDateUtils + .getDayMonthYearDateFormatted( + AppDateUtils.convertStringToDate( + patient.appointmentDate)) : AppDateUtils + .convertStringToDateFormat( + patient.appointmentDate, + 'MM-dd-yyyy')) + , + fontWeight: FontWeight.w700, + fontSize: 12, + color: Color(0xFF2E303A), + ), + SizedBox( + height: 0.5, + ) + ], + ), if(isFromLabResult)Container( child: RichText( text: new TextSpan( @@ -581,6 +552,6 @@ class PatientProfileAppBar extends StatelessWidget @override Size get preferredSize => Size(double.maxFinite, height == 0 - ? isInpatient ? 215 : isAppointmentHeader ? 310 : 200 + ? isInpatient ? 215 : isAppointmentHeader ? 325 : 215 : height); } From 411746da984b7d83592a578421260170b5dff3b0 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Sun, 13 Jun 2021 15:00:54 +0300 Subject: [PATCH 33/72] remove patient type and arrival type form patient profile header --- lib/screens/live_care/end_call_screen.dart | 2 +- .../medical-file/health_summary_page.dart | 2 - .../medical-file/medical_file_details.dart | 2 - lib/screens/patients/ECGPage.dart | 2 +- .../insurance_approval_screen_patient.dart | 2 - .../patients/insurance_approvals_details.dart | 2 +- .../profile/UCAF/UCAF-detail-screen.dart | 2 +- .../profile/UCAF/UCAF-input-screen.dart | 2 +- .../admission-request-first-screen.dart | 2 +- .../admission-request-third-screen.dart | 2 +- .../admission-request_second-screen.dart | 2 +- .../lab_result/laboratory_result_page.dart | 3 +- .../profile/lab_result/labs_home_page.dart | 3 +- .../MedicalReportDetailPage.dart | 2 - .../medical_report/MedicalReportPage.dart | 2 - .../profile/note/progress_note_screen.dart | 2 - .../patient_profile_screen.dart | 3 +- .../radiology/radiology_details_page.dart | 2 - .../radiology/radiology_home_page.dart | 2 - .../refer-patient-screen-in-patient.dart | 2 - .../referral/refer-patient-screen.dart | 2 +- .../soap_update/update_soap_index.dart | 2 +- .../vital_sign/vital_sign_details_screen.dart | 2 +- .../vital_sign_item_details_screen.dart | 2 +- .../prescription_item_in_patient_page.dart | 2 +- .../prescription/prescription_items_page.dart | 2 - .../prescription/prescriptions_page.dart | 2 - lib/screens/procedures/procedure_screen.dart | 2 - lib/screens/sick-leave/add-sickleave.dart | 2 - lib/screens/sick-leave/show-sickleave.dart | 2 - .../profile/patient-profile-app-bar.dart | 61 +++++++++---------- 31 files changed, 44 insertions(+), 80 deletions(-) diff --git a/lib/screens/live_care/end_call_screen.dart b/lib/screens/live_care/end_call_screen.dart index 411079fc..754ccb47 100644 --- a/lib/screens/live_care/end_call_screen.dart +++ b/lib/screens/live_care/end_call_screen.dart @@ -185,7 +185,7 @@ class _EndCallScreenState extends State { backgroundColor: Theme.of(context).scaffoldBackgroundColor, isShowAppBar: true, appBar: PatientProfileAppBar( - widget.patient, arrivalType ?? '7', '1', + widget.patient, isInpatient: isInpatient, height: (widget.patient.patientStatusType != null && widget.patient.patientStatusType == 43) diff --git a/lib/screens/medical-file/health_summary_page.dart b/lib/screens/medical-file/health_summary_page.dart index ee4726e2..6b4b066c 100644 --- a/lib/screens/medical-file/health_summary_page.dart +++ b/lib/screens/medical-file/health_summary_page.dart @@ -32,8 +32,6 @@ class _HealthSummaryPageState extends State { AppScaffold( appBar: PatientProfileAppBar( patient, - patientType.toString() ?? "0", - arrivalType, isInpatient: isInpatient, ), isShowAppBar: true, diff --git a/lib/screens/medical-file/medical_file_details.dart b/lib/screens/medical-file/medical_file_details.dart index 64d76f06..b53284a9 100644 --- a/lib/screens/medical-file/medical_file_details.dart +++ b/lib/screens/medical-file/medical_file_details.dart @@ -104,8 +104,6 @@ class _MedicalFileDetailsState extends State { AppScaffold( appBar: PatientProfileAppBar( patient, - patient.patientType.toString() ?? "0", - patient.arrivedOn.toString() ?? 0, doctorName: doctorName, profileUrl: doctorImage, clinic: clinicName, diff --git a/lib/screens/patients/ECGPage.dart b/lib/screens/patients/ECGPage.dart index 97923959..ba4c108c 100644 --- a/lib/screens/patients/ECGPage.dart +++ b/lib/screens/patients/ECGPage.dart @@ -31,7 +31,7 @@ class ECGPage extends StatelessWidget { baseViewModel: model, isShowAppBar: true, backgroundColor: Color(0xffF8F8F8), - appBar: PatientProfileAppBar(patient,arrivalType??'0',patientType), + appBar: PatientProfileAppBar(patient), body: SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(8.0), diff --git a/lib/screens/patients/insurance_approval_screen_patient.dart b/lib/screens/patients/insurance_approval_screen_patient.dart index 3d03589b..1ab0734b 100644 --- a/lib/screens/patients/insurance_approval_screen_patient.dart +++ b/lib/screens/patients/insurance_approval_screen_patient.dart @@ -46,8 +46,6 @@ class _InsuranceApprovalScreenNewState AppScaffold( appBar: PatientProfileAppBar( patient, - patientType.toString() ?? "0", - patientType, isInpatient: isInpatient, ), isShowAppBar: true, diff --git a/lib/screens/patients/insurance_approvals_details.dart b/lib/screens/patients/insurance_approvals_details.dart index 57af55d8..0945df37 100644 --- a/lib/screens/patients/insurance_approvals_details.dart +++ b/lib/screens/patients/insurance_approvals_details.dart @@ -55,7 +55,7 @@ class _InsuranceApprovalsDetailsState extends State { isShowAppBar: true, baseViewModel: model, appBar: PatientProfileAppBar( - patient, patient.patientType.toString(), patient.arrivedOn), + patient), body: patient.admissionNo != null ? SingleChildScrollView( child: Container( diff --git a/lib/screens/patients/profile/UCAF/UCAF-detail-screen.dart b/lib/screens/patients/profile/UCAF/UCAF-detail-screen.dart index af61de0d..081f1a6e 100644 --- a/lib/screens/patients/profile/UCAF/UCAF-detail-screen.dart +++ b/lib/screens/patients/profile/UCAF/UCAF-detail-screen.dart @@ -48,7 +48,7 @@ class _UcafDetailScreenState extends State { baseViewModel: model, isShowAppBar: true, appBar: PatientProfileAppBar( - patient, patientType, arrivalType), + patient), appBarTitle: TranslationBase.of(context).ucaf, body: Column( children: [ diff --git a/lib/screens/patients/profile/UCAF/UCAF-input-screen.dart b/lib/screens/patients/profile/UCAF/UCAF-input-screen.dart index 7c163a79..3bbc6637 100644 --- a/lib/screens/patients/profile/UCAF/UCAF-input-screen.dart +++ b/lib/screens/patients/profile/UCAF/UCAF-input-screen.dart @@ -66,7 +66,7 @@ class _UCAFInputScreenState extends State { baseViewModel: model, isShowAppBar: true, appBar: PatientProfileAppBar( - patient, patientType, arrivalType), + patient), appBarTitle: TranslationBase.of(context).ucaf, body: model.patientVitalSignsHistory.length > 0 && model.patientChiefComplaintList != null && 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 dd6d9d76..f0ccaece 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 @@ -62,7 +62,7 @@ class _AdmissionRequestThirdScreenState baseViewModel: model, isShowAppBar: true, appBar: PatientProfileAppBar( - patient, patientType, arrivalType), + patient), appBarTitle: TranslationBase.of(context).admissionRequest, body: GestureDetector( onTap: () { 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 175f5669..563b4827 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 @@ -53,7 +53,7 @@ class _AdmissionRequestThirdScreenState baseViewModel: model, isShowAppBar: true, appBar: PatientProfileAppBar( - patient, patientType, arrivalType), + patient), appBarTitle: TranslationBase.of(context).admissionRequest, body: GestureDetector( onTap: () { 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 f7e03533..dc79b2be 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 @@ -75,7 +75,7 @@ class _AdmissionRequestSecondScreenState baseViewModel: model, isShowAppBar: true, appBar: PatientProfileAppBar( - patient, patientType, arrivalType), + patient), appBarTitle: TranslationBase.of(context).admissionRequest, body: GestureDetector( onTap: () { diff --git a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart index 23b17830..d6b4d2bc 100644 --- a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart +++ b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart @@ -40,8 +40,7 @@ class _LaboratoryResultPageState extends State { isShowAppBar: true, appBar: PatientProfileAppBar( widget.patient, - widget.patientType ?? "0", - widget.arrivalType ?? "0", + isFromLabResult: true, appointmentDate: widget.patientLabOrders.orderDate, ), 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 96b64675..b2bfa2fd 100644 --- a/lib/screens/patients/profile/lab_result/labs_home_page.dart +++ b/lib/screens/patients/profile/lab_result/labs_home_page.dart @@ -54,8 +54,7 @@ class _LabsHomePageState extends State { isShowAppBar: true, appBar: PatientProfileAppBar( patient, - patient.patientType.toString() ?? '0', - patientType, + isInpatient: isInpatient, ), body: SingleChildScrollView( diff --git a/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart index 7b787f44..ab24f8e0 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart @@ -33,8 +33,6 @@ class MedicalReportDetailPage extends StatelessWidget { backgroundColor: Theme.of(context).scaffoldBackgroundColor, appBar: PatientProfileAppBar( patient, - patientType, - arrivalType, ), body: Container( child: SingleChildScrollView( diff --git a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart index 5f6b3eea..aa9d0b58 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart @@ -45,8 +45,6 @@ class MedicalReportPage extends StatelessWidget { backgroundColor: Theme.of(context).scaffoldBackgroundColor, appBar: PatientProfileAppBar( patient, - patientType, - arrivalType, ), body: SingleChildScrollView( physics: BouncingScrollPhysics(), diff --git a/lib/screens/patients/profile/note/progress_note_screen.dart b/lib/screens/patients/profile/note/progress_note_screen.dart index 087cab80..723ee75f 100644 --- a/lib/screens/patients/profile/note/progress_note_screen.dart +++ b/lib/screens/patients/profile/note/progress_note_screen.dart @@ -90,8 +90,6 @@ class _ProgressNoteState extends State { // appBarTitle: TranslationBase.of(context).progressNote, appBar: PatientProfileAppBar( patient, - patient.patientType.toString() ?? '0', - arrivalType, isInpatient: true, ), body: model.patientProgressNoteList == null || 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 e0bea0b7..8a831c4d 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -103,8 +103,7 @@ class _PatientProfileScreenState extends State Column( children: [ PatientProfileAppBar( - patient, arrivalType ?? '0', patientType, - isInpatient: isInpatient, + patient, isFromLiveCare: isFromLiveCare, height: (patient.patientStatusType != null && patient.patientStatusType == 43) diff --git a/lib/screens/patients/profile/radiology/radiology_details_page.dart b/lib/screens/patients/profile/radiology/radiology_details_page.dart index cb0cd99a..48bef68a 100644 --- a/lib/screens/patients/profile/radiology/radiology_details_page.dart +++ b/lib/screens/patients/profile/radiology/radiology_details_page.dart @@ -37,8 +37,6 @@ class RadiologyDetailsPage extends StatelessWidget { builder: (_, model, widget) => AppScaffold( appBar: PatientProfileAppBar( patient, - patientType ?? "0", - arrivalType ?? "0", appointmentDate: finalRadiology.orderDate, doctorName: finalRadiology.doctorName, clinic: finalRadiology.clinicDescription, diff --git a/lib/screens/patients/profile/radiology/radiology_home_page.dart b/lib/screens/patients/profile/radiology/radiology_home_page.dart index 8d0946c5..3d8d527c 100644 --- a/lib/screens/patients/profile/radiology/radiology_home_page.dart +++ b/lib/screens/patients/profile/radiology/radiology_home_page.dart @@ -52,8 +52,6 @@ class _RadiologyHomePageState extends State { // appBarTitle: TranslationBase.of(context).radiology, appBar: PatientProfileAppBar( patient, - patient.patientType.toString() ?? '0', - arrivalType, isInpatient: isInpatient, ), baseViewModel: model, diff --git a/lib/screens/patients/profile/referral/refer-patient-screen-in-patient.dart b/lib/screens/patients/profile/referral/refer-patient-screen-in-patient.dart index 11ace2f6..66fd22fd 100644 --- a/lib/screens/patients/profile/referral/refer-patient-screen-in-patient.dart +++ b/lib/screens/patients/profile/referral/refer-patient-screen-in-patient.dart @@ -138,8 +138,6 @@ class _PatientMakeInPatientReferralScreenState extends State { appBarTitle: TranslationBase.of(context).referPatient, isShowAppBar: true, appBar: PatientProfileAppBar( - patient, patientType, arrivalType), + patient), body: SingleChildScrollView( child: Container( child: Column( 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 ab5e02d0..60597b11 100644 --- a/lib/screens/patients/profile/soap_update/update_soap_index.dart +++ b/lib/screens/patients/profile/soap_update/update_soap_index.dart @@ -82,7 +82,7 @@ class _UpdateSoapIndexState extends State mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ - PatientProfileAppBar(patient, '7', '7',isFromSOAP: true,), + PatientProfileAppBar(patient), Container( width: double.infinity, height: 1, 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 a67e213f..23266095 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 @@ -41,7 +41,7 @@ class VitalSignDetailsScreen extends StatelessWidget { isShowAppBar: true, backgroundColor: Theme.of(context).scaffoldBackgroundColor, appBar: PatientProfileAppBar( - patient, patientType, arrivalType), + patient), appBarTitle: TranslationBase.of(context).vitalSign, body: mode.patientVitalSignsHistory.length > 0 ? Column( diff --git a/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart b/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart index 0c41386c..0ed9da56 100644 --- a/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart +++ b/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart @@ -191,7 +191,7 @@ class VitalSignItemDetailsScreen extends StatelessWidget { backgroundColor: Color.fromRGBO(248, 248, 248, 1), isShowAppBar: true, appBar: PatientProfileAppBar( - patient, patientType, arrivalType), + patient,), body: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/screens/prescription/prescription_item_in_patient_page.dart b/lib/screens/prescription/prescription_item_in_patient_page.dart index 472f6dd8..7cf33935 100644 --- a/lib/screens/prescription/prescription_item_in_patient_page.dart +++ b/lib/screens/prescription/prescription_item_in_patient_page.dart @@ -45,7 +45,7 @@ class PrescriptionItemsInPatientPage extends StatelessWidget { backgroundColor: Colors.grey[100], baseViewModel: model, appBar: PatientProfileAppBar( - patient, patient.patientType.toString(), patient.arrivedOn), + patient), body: SingleChildScrollView( child: Container( child: Column( diff --git a/lib/screens/prescription/prescription_items_page.dart b/lib/screens/prescription/prescription_items_page.dart index e888dddd..b97343c4 100644 --- a/lib/screens/prescription/prescription_items_page.dart +++ b/lib/screens/prescription/prescription_items_page.dart @@ -30,8 +30,6 @@ class PrescriptionItemsPage extends StatelessWidget { baseViewModel: model, appBar: PatientProfileAppBar( patient, - patientType??"0", - arrivalType??"0", clinic: prescriptions.clinicDescription, branch: prescriptions.name, isPrescriptions: true, diff --git a/lib/screens/prescription/prescriptions_page.dart b/lib/screens/prescription/prescriptions_page.dart index 17b36233..1a99299b 100644 --- a/lib/screens/prescription/prescriptions_page.dart +++ b/lib/screens/prescription/prescriptions_page.dart @@ -37,8 +37,6 @@ class PrescriptionsPage extends StatelessWidget { backgroundColor: Colors.grey[100], appBar: PatientProfileAppBar( patient, - patientType ?? '0', - arrivalType, isInpatient: isInpatient, ), body: patient.admissionNo == null diff --git a/lib/screens/procedures/procedure_screen.dart b/lib/screens/procedures/procedure_screen.dart index aa51fc18..79371459 100644 --- a/lib/screens/procedures/procedure_screen.dart +++ b/lib/screens/procedures/procedure_screen.dart @@ -46,8 +46,6 @@ class ProcedureScreen extends StatelessWidget { baseViewModel: model, appBar: PatientProfileAppBar( patient, - arrivalType ?? '0', - patientType, isInpatient: isInpatient, ), body: SingleChildScrollView( diff --git a/lib/screens/sick-leave/add-sickleave.dart b/lib/screens/sick-leave/add-sickleave.dart index d7759f9e..7b065321 100644 --- a/lib/screens/sick-leave/add-sickleave.dart +++ b/lib/screens/sick-leave/add-sickleave.dart @@ -36,8 +36,6 @@ class AddSickLeavScreen extends StatelessWidget { backgroundColor: Colors.grey[100], appBar: PatientProfileAppBar( patient, - routeArgs['patientType'] ?? "0", - routeArgs['arrivalType'] ?? "0", isInpatient: isInpatient, ), body: SingleChildScrollView( diff --git a/lib/screens/sick-leave/show-sickleave.dart b/lib/screens/sick-leave/show-sickleave.dart index 4ead8cd3..726524d8 100644 --- a/lib/screens/sick-leave/show-sickleave.dart +++ b/lib/screens/sick-leave/show-sickleave.dart @@ -27,8 +27,6 @@ class ShowSickLeaveScreen extends StatelessWidget { backgroundColor: Colors.grey[100], appBar: PatientProfileAppBar( patient, - routeArgs['patientType'] ?? "0", - routeArgs['arrivalType'] ?? "0", ), body: SingleChildScrollView( child: Column( diff --git a/lib/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart index 5d676061..467d681b 100644 --- a/lib/widgets/patients/profile/patient-profile-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -1,4 +1,3 @@ -import 'package:doctor_app_flutter/config/config.dart'; 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/icons_app/doctor_app_icons.dart'; @@ -8,7 +7,6 @@ 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:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -17,8 +15,6 @@ import 'large_avatar.dart'; class PatientProfileAppBar extends StatelessWidget with PreferredSizeWidget { final PatiantInformtion patient; - final String patientType; - final String arrivalType; final double height; final bool isInpatient; final bool isDischargedPatient; @@ -36,11 +32,10 @@ class PatientProfileAppBar extends StatelessWidget final String visitDate; final String clinic; final bool isAppointmentHeader; - final bool isFromSOAP; final bool isFromLabResult; PatientProfileAppBar( - this.patient, this.patientType, this.arrivalType, + this.patient, {this.height = 0.0, this.isInpatient = false, this.isDischargedPatient = false, @@ -57,7 +52,6 @@ class PatientProfileAppBar extends StatelessWidget this.episode, this.visitDate, this.isAppointmentHeader = false, - this.isFromSOAP = false, this.isFromLabResult = false}); @@ -86,7 +80,7 @@ class PatientProfileAppBar extends StatelessWidget ? 215 : isAppointmentHeader ? 325 - : 215 + : 200 : height, child: Container( padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), @@ -173,25 +167,24 @@ class PatientProfileAppBar extends StatelessWidget fontFamily: 'Poppins', fontSize: 12, ) - : AppText( - TranslationBase - .of(context) - .notArrived, - color: Colors.red[800], - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - fontSize: 12, - ), - patient.startTime != null - ? AppText( + : AppText( + TranslationBase.of(context).notArrived, + color: Colors.red[800], + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + fontSize: 12, + ), patient.startTime != null - ? patient.startTime - : '', - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - ):SizedBox() - ], - )) + ? AppText( + patient.startTime != null + ? patient.startTime + : '', + fontWeight: FontWeight.w700, + fontSize: 12, + color: Color(0xFF2E303A)) + : SizedBox() + ], + )) : SizedBox(), Row( @@ -296,13 +289,10 @@ class PatientProfileAppBar extends StatelessWidget width: 3.5, ), AppText( - (isFromSOAP ? AppDateUtils + AppDateUtils .getDayMonthYearDateFormatted( AppDateUtils.convertStringToDate( - patient.appointmentDate)) : AppDateUtils - .convertStringToDateFormat( - patient.appointmentDate, - 'MM-dd-yyyy')) + patient.appointmentDate)) , fontWeight: FontWeight.w700, fontSize: 12, @@ -356,7 +346,12 @@ class PatientProfileAppBar extends StatelessWidget new TextSpan( text: patient.admissionDate == null ? "" - : "${AppDateUtils.convertDateFromServerFormat(patient.admissionDate.toString(), 'yyyy-MM-dd')}", + : "${AppDateUtils + .getDayMonthYearDateFormatted( + (AppDateUtils + .getDateTimeFromServerFormat( + patient.admissionDate + .toString())))}", style: TextStyle( fontWeight: FontWeight.w700, fontSize: 12, @@ -552,6 +547,6 @@ class PatientProfileAppBar extends StatelessWidget @override Size get preferredSize => Size(double.maxFinite, height == 0 - ? isInpatient ? 215 : isAppointmentHeader ? 325 : 215 + ? isInpatient ? 215 : isAppointmentHeader ? 325 : 200 : height); } From 142fbb93fd533379857803f1e560cb6280c4f386 Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Sun, 13 Jun 2021 15:09:27 +0300 Subject: [PATCH 34/72] Referrel Doctor reply --- dart | 0 lib/config/config.dart | 1 + .../referral/MyReferralPatientModel.dart | 6 +- .../add_referred_remarks_request.dart | 72 +++++++ .../patient/MyReferralPatientService.dart | 71 ++++--- .../viewModel/patient-referral-viewmodel.dart | 103 +++++---- .../referral/AddReplayOnReferralPatient.dart | 86 +++++--- .../my-referral-inpatient-screen.dart | 20 +- .../referral_patient_detail_in-paint.dart | 201 ++++++------------ lib/screens/qr_reader/QR_reader_screen.dart | 28 +-- pubspec.lock | 6 +- 11 files changed, 311 insertions(+), 283 deletions(-) create mode 100644 dart create mode 100644 lib/core/model/referral/add_referred_remarks_request.dart diff --git a/dart b/dart new file mode 100644 index 00000000..e69de29b diff --git a/lib/config/config.dart b/lib/config/config.dart index eb946dea..492d7ada 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -224,6 +224,7 @@ const GET_PENDING_PATIENT_ER_FOR_DOCTOR_APP = 'Services/DoctorApplication.svc/RE const DOCTOR_CHECK_HAS_LIVE_CARE = "Services/DoctorApplication.svc/REST/CheckDoctorHasLiveCare"; const LIVE_CARE_IS_LOGIN = "LiveCareApi/DoctorApp/UseIsLogin"; +const ADD_REFERRED_REMARKS_NEW = "Services/DoctorApplication.svc/REST/AddReferredDoctorRemarks_New"; var selectedPatientType = 1; diff --git a/lib/core/model/referral/MyReferralPatientModel.dart b/lib/core/model/referral/MyReferralPatientModel.dart index 1072e098..ce8a6447 100644 --- a/lib/core/model/referral/MyReferralPatientModel.dart +++ b/lib/core/model/referral/MyReferralPatientModel.dart @@ -61,6 +61,7 @@ class MyReferralPatientModel { String priorityDescription; String referringClinicDescription; String referringDoctorName; + int referalStatus; MyReferralPatientModel( {this.rowID, @@ -122,10 +123,12 @@ class MyReferralPatientModel { this.nursingStationName, this.priorityDescription, this.referringClinicDescription, - this.referringDoctorName}); + this.referringDoctorName, + this.referalStatus}); MyReferralPatientModel.fromJson(Map json) { rowID = json['RowID']; + referalStatus = json['ReferalStatus']; projectID = json['ProjectID']; lineItemNo = json['LineItemNo']; doctorID = json['DoctorID']; @@ -203,6 +206,7 @@ class MyReferralPatientModel { Map toJson() { final Map data = new Map(); data['RowID'] = this.rowID; + data['ReferalStatus'] = this.referalStatus; data['ProjectID'] = this.projectID; data['LineItemNo'] = this.lineItemNo; data['DoctorID'] = this.doctorID; diff --git a/lib/core/model/referral/add_referred_remarks_request.dart b/lib/core/model/referral/add_referred_remarks_request.dart new file mode 100644 index 00000000..14089513 --- /dev/null +++ b/lib/core/model/referral/add_referred_remarks_request.dart @@ -0,0 +1,72 @@ +class AddReferredRemarksRequestModel { + int projectID; + int admissionNo; + int lineItemNo; + String referredDoctorRemarks; + int editedBy; + int referalStatus; + bool isLoginForDoctorApp; + String iPAdress; + bool patientOutSA; + String tokenID; + int languageID; + double versionID; + int channel; + String sessionID; + int deviceTypeID; + + AddReferredRemarksRequestModel( + {this.projectID, + this.admissionNo, + this.lineItemNo, + this.referredDoctorRemarks, + this.editedBy, + this.referalStatus, + this.isLoginForDoctorApp, + this.iPAdress, + this.patientOutSA, + this.tokenID, + this.languageID, + this.versionID, + this.channel, + this.sessionID, + this.deviceTypeID}); + + AddReferredRemarksRequestModel.fromJson(Map json) { + projectID = json['ProjectID']; + admissionNo = json['AdmissionNo']; + lineItemNo = json['LineItemNo']; + referredDoctorRemarks = json['ReferredDoctorRemarks']; + editedBy = json['EditedBy']; + referalStatus = json['ReferalStatus']; + isLoginForDoctorApp = json['IsLoginForDoctorApp']; + iPAdress = json['IPAdress']; + patientOutSA = json['PatientOutSA']; + tokenID = json['TokenID']; + languageID = json['LanguageID']; + versionID = json['VersionID']; + channel = json['Channel']; + sessionID = json['SessionID']; + deviceTypeID = json['DeviceTypeID']; + } + + Map toJson() { + final Map data = new Map(); + data['ProjectID'] = this.projectID; + data['AdmissionNo'] = this.admissionNo; + data['LineItemNo'] = this.lineItemNo; + data['ReferredDoctorRemarks'] = this.referredDoctorRemarks; + data['EditedBy'] = this.editedBy; + data['ReferalStatus'] = this.referalStatus; + data['IsLoginForDoctorApp'] = this.isLoginForDoctorApp; + data['IPAdress'] = this.iPAdress; + data['PatientOutSA'] = this.patientOutSA; + data['TokenID'] = this.tokenID; + data['LanguageID'] = this.languageID; + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['SessionID'] = this.sessionID; + data['DeviceTypeID'] = this.deviceTypeID; + return data; + } +} diff --git a/lib/core/service/patient/MyReferralPatientService.dart b/lib/core/service/patient/MyReferralPatientService.dart index 39a75e8f..87fcdd23 100644 --- a/lib/core/service/patient/MyReferralPatientService.dart +++ b/lib/core/service/patient/MyReferralPatientService.dart @@ -1,6 +1,7 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/model/referral/MyReferralPatientModel.dart'; import 'package:doctor_app_flutter/core/model/referral/MyReferralPatientRequestModel.dart'; +import 'package:doctor_app_flutter/core/model/referral/add_referred_remarks_request.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.dart'; import 'package:doctor_app_flutter/models/doctor/request_add_referred_doctor_remarks.dart'; @@ -11,20 +12,19 @@ class MyReferralInPatientService extends BaseService { hasError = false; await getDoctorProfile(); - MyReferralPatientRequestModel myReferralPatientRequestModel = - MyReferralPatientRequestModel( - doctorID: doctorProfile.doctorID, - firstName: "0", - middleName: "0", - lastName: "0", - patientMobileNumber: "0", - patientIdentificationID: "0", - patientID: 0, - from: "0", - to: "0", - stamp: DateTime.now().toIso8601String(), - isLoginForDoctorApp: true, - patientTypeID: 1); + MyReferralPatientRequestModel myReferralPatientRequestModel = MyReferralPatientRequestModel( + doctorID: doctorProfile.doctorID, + firstName: "0", + middleName: "0", + lastName: "0", + patientMobileNumber: "0", + patientIdentificationID: "0", + patientID: 0, + from: "0", + to: "0", + stamp: DateTime.now().toIso8601String(), + isLoginForDoctorApp: true, + patientTypeID: 1); myReferralPatients.clear(); await baseAppClient.post( GET_MY_REFERRAL_INPATIENT, @@ -47,8 +47,7 @@ class MyReferralInPatientService extends BaseService { hasError = false; await getDoctorProfile(); - MyReferralPatientRequestModel myReferralPatientRequestModel = - MyReferralPatientRequestModel( + MyReferralPatientRequestModel myReferralPatientRequestModel = MyReferralPatientRequestModel( doctorID: doctorProfile.doctorID, firstName: "0", middleName: "0", @@ -79,18 +78,14 @@ class MyReferralInPatientService extends BaseService { ); } - Future replay( - String referredDoctorRemarks, MyReferralPatientModel referral) async { + Future replay(String referredDoctorRemarks, MyReferralPatientModel referral) async { hasError = false; await getDoctorProfile(); - RequestAddReferredDoctorRemarks _requestAddReferredDoctorRemarks = - RequestAddReferredDoctorRemarks(); + RequestAddReferredDoctorRemarks _requestAddReferredDoctorRemarks = RequestAddReferredDoctorRemarks(); _requestAddReferredDoctorRemarks.projectID = referral.projectID; - _requestAddReferredDoctorRemarks.admissionNo = - referral.admissionNo.toString(); + _requestAddReferredDoctorRemarks.admissionNo = referral.admissionNo.toString(); _requestAddReferredDoctorRemarks.lineItemNo = referral.lineItemNo; - _requestAddReferredDoctorRemarks.referredDoctorRemarks = - referredDoctorRemarks; + _requestAddReferredDoctorRemarks.referredDoctorRemarks = referredDoctorRemarks; _requestAddReferredDoctorRemarks.editedBy = doctorProfile.doctorID; _requestAddReferredDoctorRemarks.patientID = referral.patientID; _requestAddReferredDoctorRemarks.referringDoctor = referral.referringDoctor; @@ -104,4 +99,32 @@ class MyReferralInPatientService extends BaseService { }, ); } + + Future replayReferred(String referredDoctorRemarks, MyReferralPatientModel referral, int referalStatus) async { + hasError = false; + await getDoctorProfile(); + AddReferredRemarksRequestModel _requestAddReferredDoctorRemarks = AddReferredRemarksRequestModel( + editedBy: doctorProfile.doctorID, + projectID: doctorProfile.projectID, + referredDoctorRemarks: referredDoctorRemarks, + referalStatus: referalStatus); + _requestAddReferredDoctorRemarks.projectID = referral.projectID; + _requestAddReferredDoctorRemarks.admissionNo = int.parse(referral.admissionNo); + _requestAddReferredDoctorRemarks.lineItemNo = referral.lineItemNo; + _requestAddReferredDoctorRemarks.referredDoctorRemarks = referredDoctorRemarks; + _requestAddReferredDoctorRemarks.editedBy = doctorProfile.doctorID; + _requestAddReferredDoctorRemarks.referalStatus = referalStatus; + + // _requestAddReferredDoctorRemarks.patientID = referral.patientID; + // _requestAddReferredDoctorRemarks.referringDoctor = referral.referringDoctor; + await baseAppClient.post( + ADD_REFERRED_REMARKS_NEW, + body: _requestAddReferredDoctorRemarks.toJson(), + onSuccess: (dynamic body, int statusCode) {}, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + ); + } } diff --git a/lib/core/viewModel/patient-referral-viewmodel.dart b/lib/core/viewModel/patient-referral-viewmodel.dart index 01d40e62..9e852978 100644 --- a/lib/core/viewModel/patient-referral-viewmodel.dart +++ b/lib/core/viewModel/patient-referral-viewmodel.dart @@ -2,6 +2,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/model/referral/DischargeReferralPatient.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/service/patient/DischargedPatientService.dart'; import 'package:doctor_app_flutter/core/service/patient/MyReferralPatientService.dart'; import 'package:doctor_app_flutter/core/service/patient/ReferralService.dart'; @@ -18,16 +19,13 @@ import 'package:flutter/cupertino.dart'; import '../../locator.dart'; class PatientReferralViewModel extends BaseViewModel { - PatientReferralService _referralPatientService = - locator(); + PatientReferralService _referralPatientService = locator(); ReferralService _referralService = locator(); - MyReferralInPatientService _myReferralService = - locator(); + MyReferralInPatientService _myReferralService = locator(); - DischargedPatientService _dischargedPatientService = - locator(); + DischargedPatientService _dischargedPatientService = locator(); List get myDischargeReferralPatient => _dischargedPatientService.myDischargeReferralPatients; @@ -36,28 +34,21 @@ class PatientReferralViewModel extends BaseViewModel { List get clinicsList => _referralPatientService.clinicsList; - List get referralFrequencyList => - _referralPatientService.frequencyList; + List get referralFrequencyList => _referralPatientService.frequencyList; List doctorsList = []; - List get clinicDoctorsList => - _referralPatientService.doctorsList; + List get clinicDoctorsList => _referralPatientService.doctorsList; - List get myReferralPatients => - _myReferralService.myReferralPatients; + List get myReferralPatients => _myReferralService.myReferralPatients; - List get listMyReferredPatientModel => - _referralPatientService.listMyReferredPatientModel; + List get listMyReferredPatientModel => _referralPatientService.listMyReferredPatientModel; - List get pendingReferral => - _referralPatientService.pendingReferralList; + List get pendingReferral => _referralPatientService.pendingReferralList; - List get patientReferral => - _referralPatientService.patientReferralList; + List get patientReferral => _referralPatientService.patientReferralList; - List get patientArrivalList => - _referralPatientService.patientArrivalList; + List get patientArrivalList => _referralPatientService.patientArrivalList; Future getPatientReferral(PatiantInformtion patient) async { setState(ViewState.Busy); @@ -106,8 +97,7 @@ class PatientReferralViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future getClinicDoctors( - PatiantInformtion patient, int clinicId, int branchId) async { + Future getClinicDoctors(PatiantInformtion patient, int clinicId, int branchId) async { setState(ViewState.BusyLocal); await _referralPatientService.getDoctorsList(patient, clinicId, branchId); if (_referralPatientService.hasError) { @@ -125,10 +115,7 @@ class PatientReferralViewModel extends BaseViewModel { Future getDoctorBranch() async { DoctorProfileModel doctorProfile = await getDoctorProfile(); if (doctorProfile != null) { - dynamic _selectedBranch = { - "facilityId": doctorProfile.projectID, - "facilityName": doctorProfile.projectName - }; + dynamic _selectedBranch = {"facilityId": doctorProfile.projectID, "facilityName": doctorProfile.projectName}; return _selectedBranch; } return null; @@ -175,27 +162,38 @@ class PatientReferralViewModel extends BaseViewModel { } Future getMyReferralPatientService({bool localBusy = false}) async { - if(localBusy) setState(ViewState.BusyLocal); else setState(ViewState.Busy); + if (localBusy) + setState(ViewState.BusyLocal); + else + setState(ViewState.Busy); await _myReferralService.getMyReferralPatientService(); if (_myReferralService.hasError) { error = _myReferralService.error; - if(localBusy) setState(ViewState.ErrorLocal); else setState(ViewState.Error); + if (localBusy) + setState(ViewState.ErrorLocal); + else + setState(ViewState.Error); } else setState(ViewState.Idle); } Future getMyReferralOutPatientService({bool localBusy = false}) async { - if(localBusy) setState(ViewState.BusyLocal); else setState(ViewState.Busy); + if (localBusy) + setState(ViewState.BusyLocal); + else + setState(ViewState.Busy); await _myReferralService.getMyReferralOutPatientService(); if (_myReferralService.hasError) { error = _myReferralService.error; - if(localBusy) setState(ViewState.ErrorLocal); else setState(ViewState.Error); + if (localBusy) + setState(ViewState.ErrorLocal); + else + setState(ViewState.Error); } else setState(ViewState.Idle); } - Future replay( - String referredDoctorRemarks, MyReferralPatientModel referral) async { + Future replay(String referredDoctorRemarks, MyReferralPatientModel referral) async { setState(ViewState.Busy); await _myReferralService.replay(referredDoctorRemarks, referral); if (_myReferralService.hasError) { @@ -205,8 +203,7 @@ class PatientReferralViewModel extends BaseViewModel { getMyReferralPatientService(); } - Future responseReferral( - PendingReferral pendingReferral, bool isAccepted) async { + Future responseReferral(PendingReferral pendingReferral, bool isAccepted) async { setState(ViewState.Busy); await _referralPatientService.responseReferral(pendingReferral, isAccepted); if (_referralPatientService.hasError) { @@ -216,11 +213,10 @@ class PatientReferralViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future makeReferral(PatiantInformtion patient, String isoStringDate, - int projectID, int clinicID, int doctorID, String remarks) async { + Future makeReferral(PatiantInformtion patient, String isoStringDate, int projectID, int clinicID, int doctorID, + String remarks) async { setState(ViewState.Busy); - await _referralPatientService.makeReferral( - patient, isoStringDate, projectID, clinicID, doctorID, remarks); + await _referralPatientService.makeReferral(patient, isoStringDate, projectID, clinicID, doctorID, remarks); if (_referralPatientService.hasError) { error = _referralPatientService.error; setState(ViewState.Error); @@ -260,12 +256,10 @@ class PatientReferralViewModel extends BaseViewModel { } } - Future getPatientDetails( - String fromDate, String toDate, int patientMrn, int appointmentNo) async { + Future getPatientDetails(String fromDate, String toDate, int patientMrn, int appointmentNo) async { setState(ViewState.Busy); - await _referralPatientService.getPatientArrivalList(toDate, - fromDate: fromDate, patientMrn: patientMrn); + await _referralPatientService.getPatientArrivalList(toDate, fromDate: fromDate, patientMrn: patientMrn); if (_referralPatientService.hasError) { error = _referralPatientService.error; setState(ViewState.Error); @@ -284,8 +278,7 @@ class PatientReferralViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future verifyReferralDoctorRemarks( - MyReferredPatientModel referredPatient) async { + Future verifyReferralDoctorRemarks(MyReferredPatientModel referredPatient) async { setState(ViewState.Busy); await _referralPatientService.verifyReferralDoctorRemarks(referredPatient); if (_referralPatientService.hasError) { @@ -324,8 +317,7 @@ class PatientReferralViewModel extends BaseViewModel { } } - PatiantInformtion getPatientFromReferral( - MyReferredPatientModel referredPatient) { + PatiantInformtion getPatientFromReferral(MyReferredPatientModel referredPatient) { PatiantInformtion patient = PatiantInformtion(); patient.doctorId = referredPatient.doctorID; patient.doctorName = referredPatient.doctorName; @@ -350,8 +342,7 @@ class PatientReferralViewModel extends BaseViewModel { return patient; } - PatiantInformtion getPatientFromReferralO( - MyReferralPatientModel referredPatient) { + PatiantInformtion getPatientFromReferralO(MyReferralPatientModel referredPatient) { PatiantInformtion patient = PatiantInformtion(); patient.doctorId = referredPatient.doctorID; patient.doctorName = referredPatient.doctorName; @@ -376,8 +367,7 @@ class PatientReferralViewModel extends BaseViewModel { return patient; } - PatiantInformtion getPatientFromDischargeReferralPatient( - DischargeReferralPatient referredPatient) { + PatiantInformtion getPatientFromDischargeReferralPatient(DischargeReferralPatient referredPatient) { PatiantInformtion patient = PatiantInformtion(); patient.doctorId = referredPatient.doctorID; patient.doctorName = referredPatient.doctorName; @@ -396,10 +386,19 @@ class PatientReferralViewModel extends BaseViewModel { patient.roomId = referredPatient.roomID; patient.bedId = referredPatient.bedID; patient.nationalityName = referredPatient.nationalityName; - patient.nationalityFlagURL = - ''; // TODO from backend referredPatient.nationalityFlagURL; + patient.nationalityFlagURL = ''; // TODO from backend referredPatient.nationalityFlagURL; patient.age = referredPatient.age; patient.clinicDescription = referredPatient.clinicDescription; return patient; } + + Future replayReferred(String referredDoctorRemarks, MyReferralPatientModel referral, int referalStatus) async { + setState(ViewState.Busy); + await _myReferralService.replayReferred(referredDoctorRemarks, referral, referalStatus); + if (_myReferralService.hasError) { + error = _myReferralService.error; + setState(ViewState.ErrorLocal); + } else + getMyReferralPatientService(); + } } diff --git a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart index c246a3ad..56ff85c4 100644 --- a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart +++ b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart @@ -1,7 +1,7 @@ import 'package:doctor_app_flutter/config/config.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/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/viewModel/patient-referral-viewmodel.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; @@ -14,7 +14,6 @@ import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dar import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/shared/speech-text-popup.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; -import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:speech_to_text/speech_recognition_error.dart'; @@ -25,23 +24,25 @@ import 'ReplySummeryOnReferralPatient.dart'; class AddReplayOnReferralPatient extends StatefulWidget { final PatientReferralViewModel patientReferralViewModel; final MyReferralPatientModel myReferralInPatientModel; + final AddReferredRemarksRequestModel myReferralInPatientRequestModel; final bool isEdited; const AddReplayOnReferralPatient( {Key key, this.patientReferralViewModel, this.myReferralInPatientModel, - this.isEdited}) + this.isEdited, + this.myReferralInPatientRequestModel}) : super(key: key); @override - _AddReplayOnReferralPatientState createState() => - _AddReplayOnReferralPatientState(); + _AddReplayOnReferralPatientState createState() => _AddReplayOnReferralPatientState(); } -class _AddReplayOnReferralPatientState - extends State { +class _AddReplayOnReferralPatientState extends State { bool isSubmitted = false; + int replay = 1; + int reject = 2; stt.SpeechToText speech = stt.SpeechToText(); var reconizedWord; var event = RobotProvider(); @@ -51,8 +52,7 @@ class _AddReplayOnReferralPatientState void initState() { requestPermissions(); super.initState(); - replayOnReferralController.text = - widget.myReferralInPatientModel.referredDoctorRemarks ?? ""; + replayOnReferralController.text = widget.myReferralInPatientModel.referredDoctorRemarks ?? ""; } @override @@ -84,9 +84,7 @@ class _AddReplayOnReferralPatientState maxLines: 35, minLines: 25, hasBorder: true, - validationError: replayOnReferralController - .text.isEmpty && - isSubmitted + validationError: replayOnReferralController.text.isEmpty && isSubmitted ? TranslationBase.of(context).emptyMessage : null, ), @@ -139,8 +137,33 @@ class _AddReplayOnReferralPatientState children: [ Expanded( child: AppButton( - onPressed: () { - Navigator.of(context).pop(); + onPressed: () async { + if (replayOnReferralController.text.isNotEmpty) { + GifLoaderDialogUtils.showMyDialog(context); + await widget.patientReferralViewModel.replayReferred( + replayOnReferralController.text.trim(), widget.myReferralInPatientModel, reject); + if (widget.patientReferralViewModel.state == ViewState.ErrorLocal) { + Helpers.showErrorToast(widget.patientReferralViewModel.error); + } else { + GifLoaderDialogUtils.hideDialog(context); + 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"); + setState(() { + isSubmitted = false; + }); + } }, title: TranslationBase.of(context).reject, fontColor: Colors.white, @@ -158,32 +181,26 @@ class _AddReplayOnReferralPatientState }); 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); + await widget.patientReferralViewModel.replayReferred( + replayOnReferralController.text.trim(), widget.myReferralInPatientModel, replay); + if (widget.patientReferralViewModel.state == ViewState.ErrorLocal) { + Helpers.showErrorToast(widget.patientReferralViewModel.error); } else { GifLoaderDialogUtils.hideDialog(context); - DrAppToastMsg.showSuccesToast( - "Your Reply Added Successfully"); + 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()), - ), - ); + // Navigator.push( + // context, + // FadePage( + // page: ReplySummeryOnReferralPatient( + // widget.myReferralInPatientModel, replayOnReferralController.text.trim()), + // ), + // ); } } else { - Helpers.showErrorToast( - "You can't add empty reply"); + Helpers.showErrorToast("You can't add empty reply"); setState(() { isSubmitted = false; }); @@ -250,8 +267,7 @@ class _AddReplayOnReferralPatientState onVoiceText() async { new SpeechToText(context: context).showAlertDialog(context); var lang = TranslationBase.of(AppGlobal.CONTEX).locale.languageCode; - bool available = await speech.initialize( - onStatus: statusListener, onError: errorListener); + bool available = await speech.initialize(onStatus: statusListener, onError: errorListener); if (available) { speech.listen( onResult: resultListener, 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 f4a002d6..3ebd7896 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,6 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart'; class MyReferralInPatientScreen extends StatelessWidget { PatientType patientType = PatientType.IN_PATIENT; - @override Widget build(BuildContext context) { return BaseView( @@ -30,7 +29,7 @@ class MyReferralInPatientScreen extends StatelessWidget { Container( margin: EdgeInsets.only(top: 70), child: PatientTypeRadioWidget( - (patientType) async { + (patientType) async { this.patientType = patientType; GifLoaderDialogUtils.showMyDialog(context); if (patientType == PatientType.IN_PATIENT) { @@ -62,7 +61,7 @@ class MyReferralInPatientScreen extends StatelessWidget { ), ) : Expanded( - child: SingleChildScrollView( + child: SingleChildScrollView( child: Container( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -74,30 +73,31 @@ class MyReferralInPatientScreen extends StatelessWidget { Navigator.push( context, FadePage( - page: ReferralPatientDetailScreen(model.myReferralPatients[index],model), + page: ReferralPatientDetailScreen(model.myReferralPatients[index], model), ), ); }, child: PatientReferralItemWidget( - referralStatus: model.getReferralStatusNameByCode(model.myReferralPatients[index].referralStatus,context), + referralStatus: model.getReferralStatusNameByCode( + model.myReferralPatients[index].referralStatus, context), referralStatusCode: model.myReferralPatients[index].referralStatus, patientName: model.myReferralPatients[index].patientName, patientGender: model.myReferralPatients[index].gender, - referredDate: AppDateUtils.getDayMonthYearDateFormatted(model.myReferralPatients[index].referralDate), + referredDate: AppDateUtils.getDayMonthYearDateFormatted( + model.myReferralPatients[index].referralDate), referredTime: AppDateUtils.getTimeHHMMA(model.myReferralPatients[index].referralDate), patientID: "${model.myReferralPatients[index].patientID}", isSameBranch: false, isReferral: true, isReferralClinic: true, - referralClinic:"${model.myReferralPatients[index].referringClinicDescription}", + referralClinic: "${model.myReferralPatients[index].referringClinicDescription}", remark: model.myReferralPatients[index].referringDoctorRemarks, nationality: model.myReferralPatients[index].nationalityName, nationalityFlag: model.myReferralPatients[index].nationalityFlagURL, doctorAvatar: model.myReferralPatients[index].doctorImageURL, referralDoctorName: model.myReferralPatients[index].referringDoctorName, clinicDescription: model.myReferralPatients[index].referringClinicDescription, - infoIcon: Icon(FontAwesomeIcons.arrowRight, - size: 25, color: Colors.black), + infoIcon: Icon(FontAwesomeIcons.arrowRight, size: 25, color: Colors.black), ), ), ), @@ -105,7 +105,7 @@ class MyReferralInPatientScreen extends StatelessWidget { ), ), ), - ), + ), ], ), ), 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 7f0cd146..66e01364 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 @@ -20,8 +20,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { final MyReferralPatientModel referredPatient; final PatientReferralViewModel patientReferralViewModel; - ReferralPatientDetailScreen( - this.referredPatient, this.patientReferralViewModel); + ReferralPatientDetailScreen(this.referredPatient, this.patientReferralViewModel); @override Widget build(BuildContext context) { @@ -52,8 +51,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { ), Expanded( child: AppText( - (Helpers.capitalize( - "${referredPatient.firstName} ${referredPatient.lastName}")), + (Helpers.capitalize("${referredPatient.firstName} ${referredPatient.lastName}")), fontSize: SizeConfig.textMultiplier * 2.5, fontWeight: FontWeight.bold, fontFamily: 'Poppins', @@ -70,18 +68,14 @@ class ReferralPatientDetailScreen extends StatelessWidget { ), InkWell( onTap: () { - PatiantInformtion patient = model - .getPatientFromReferralO(referredPatient); - Navigator.of(context) - .pushNamed(PATIENTS_PROFILE, arguments: { + PatiantInformtion patient = model.getPatientFromReferralO(referredPatient); + Navigator.of(context).pushNamed(PATIENTS_PROFILE, arguments: { "patient": patient, "patientType": "1", "isInpatient": true, "arrivalType": "1", - "from": AppDateUtils.convertDateToFormat( - DateTime.now(), 'yyyy-MM-dd'), - "to": AppDateUtils.convertDateToFormat( - DateTime.now(), 'yyyy-MM-dd'), + "from": AppDateUtils.convertDateToFormat(DateTime.now(), 'yyyy-MM-dd'), + "to": AppDateUtils.convertDateToFormat(DateTime.now(), 'yyyy-MM-dd'), }); }, child: Icon( @@ -98,18 +92,14 @@ class ReferralPatientDetailScreen extends StatelessWidget { children: [ InkWell( onTap: () { - PatiantInformtion patient = model - .getPatientFromReferralO(referredPatient); - Navigator.of(context) - .pushNamed(PATIENTS_PROFILE, arguments: { + PatiantInformtion patient = model.getPatientFromReferralO(referredPatient); + Navigator.of(context).pushNamed(PATIENTS_PROFILE, arguments: { "patient": patient, "patientType": "1", "isInpatient": true, "arrivalType": "1", - "from": AppDateUtils.convertDateToFormat( - DateTime.now(), 'yyyy-MM-dd'), - "to": AppDateUtils.convertDateToFormat( - DateTime.now(), 'yyyy-MM-dd'), + "from": AppDateUtils.convertDateToFormat(DateTime.now(), 'yyyy-MM-dd'), + "to": AppDateUtils.convertDateToFormat(DateTime.now(), 'yyyy-MM-dd'), }); }, child: Padding( @@ -144,8 +134,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { child: Column( children: [ Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ AppText( "${model.getReferralStatusNameByCode(referredPatient.referralStatus, context)}", @@ -170,28 +159,23 @@ class ReferralPatientDetailScreen extends StatelessWidget { ], ), 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( "${referredPatient.patientID}", fontFamily: 'Poppins', fontWeight: FontWeight.w700, - fontSize: - 1.8 * SizeConfig.textMultiplier, + fontSize: 1.8 * SizeConfig.textMultiplier, color: Color(0XFF2E303A), ), ], @@ -208,35 +192,29 @@ class ReferralPatientDetailScreen extends StatelessWidget { ], ), Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( child: Column( children: [ Row( - mainAxisAlignment: - MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( "${TranslationBase.of(context).refClinic}: ", fontFamily: 'Poppins', fontWeight: FontWeight.w600, - fontSize: 1.7 * - SizeConfig.textMultiplier, + fontSize: 1.7 * SizeConfig.textMultiplier, color: Color(0XFF575757), ), Expanded( child: AppText( - referredPatient - .referringClinicDescription, + referredPatient.referringClinicDescription, fontFamily: 'Poppins', fontWeight: FontWeight.w700, - fontSize: 1.8 * - SizeConfig.textMultiplier, + fontSize: 1.8 * SizeConfig.textMultiplier, color: Color(0XFF2E303A), ), ), @@ -244,31 +222,22 @@ class ReferralPatientDetailScreen extends StatelessWidget { ), if (referredPatient.frequency != null) Row( - mainAxisAlignment: - MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( - TranslationBase.of(context) - .frequency + - ": ", + TranslationBase.of(context).frequency + ": ", fontFamily: 'Poppins', fontWeight: FontWeight.w600, - fontSize: 1.7 * - SizeConfig.textMultiplier, + fontSize: 1.7 * SizeConfig.textMultiplier, color: Color(0XFF575757), ), Expanded( child: AppText( - referredPatient - .frequencyDescription ?? - '', + referredPatient.frequencyDescription ?? '', fontFamily: 'Poppins', fontWeight: FontWeight.w700, - fontSize: 1.8 * - SizeConfig - .textMultiplier, + fontSize: 1.8 * SizeConfig.textMultiplier, color: Color(0XFF2E303A), ), ), @@ -280,29 +249,22 @@ class ReferralPatientDetailScreen extends StatelessWidget { Row( children: [ AppText( - referredPatient.nationalityName != - null + referredPatient.nationalityName != null ? referredPatient.nationalityName : "", fontWeight: FontWeight.bold, color: Color(0xFF2E303A), - fontSize: - 1.4 * SizeConfig.textMultiplier, + fontSize: 1.4 * SizeConfig.textMultiplier, ), - referredPatient.nationalityFlagURL != - null + referredPatient.nationalityFlagURL != null ? ClipRRect( - borderRadius: - BorderRadius.circular(20.0), + borderRadius: BorderRadius.circular(20.0), child: Image.network( - referredPatient - .nationalityFlagURL, + referredPatient.nationalityFlagURL, height: 25, width: 30, - errorBuilder: (BuildContext - context, - Object exception, - StackTrace stackTrace) { + errorBuilder: + (BuildContext context, Object exception, StackTrace stackTrace) { return Text('No Image'); }, )) @@ -314,26 +276,21 @@ class ReferralPatientDetailScreen extends StatelessWidget { if (referredPatient.priorityDescription != null) Row( mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( - TranslationBase.of(context).priority + - ": ", + TranslationBase.of(context).priority + ": ", fontFamily: 'Poppins', fontWeight: FontWeight.w600, - fontSize: - 1.7 * SizeConfig.textMultiplier, + fontSize: 1.7 * SizeConfig.textMultiplier, color: Color(0XFF575757), ), Expanded( child: AppText( - referredPatient.priorityDescription ?? - '', + referredPatient.priorityDescription ?? '', fontFamily: 'Poppins', fontWeight: FontWeight.w700, - fontSize: - 1.8 * SizeConfig.textMultiplier, + fontSize: 1.8 * SizeConfig.textMultiplier, color: Color(0XFF2E303A), ), ), @@ -342,33 +299,24 @@ class ReferralPatientDetailScreen extends StatelessWidget { if (referredPatient.mAXResponseTime != null) Row( mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( - TranslationBase.of(context) - .maxResponseTime + - ": ", + TranslationBase.of(context).maxResponseTime + ": ", fontFamily: 'Poppins', fontWeight: FontWeight.w600, - fontSize: - 1.7 * SizeConfig.textMultiplier, + fontSize: 1.7 * SizeConfig.textMultiplier, color: Color(0XFF575757), ), Expanded( child: AppText( - referredPatient.mAXResponseTime != - null - ? AppDateUtils - .convertDateFromServerFormat( - referredPatient - .mAXResponseTime, - "dd MMM,yyyy") + referredPatient.mAXResponseTime != null + ? AppDateUtils.convertDateFromServerFormat( + referredPatient.mAXResponseTime, "dd MMM,yyyy") : '', fontFamily: 'Poppins', fontWeight: FontWeight.w700, - fontSize: - 1.8 * SizeConfig.textMultiplier, + fontSize: 1.8 * SizeConfig.textMultiplier, color: Color(0XFF2E303A), ), ), @@ -378,8 +326,7 @@ class ReferralPatientDetailScreen 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, @@ -387,26 +334,17 @@ class ReferralPatientDetailScreen extends StatelessWidget { ), ), Container( - margin: EdgeInsets.only( - left: 0, - top: 25, - right: 0, - bottom: 0), - padding: EdgeInsets.only( - left: 4.0, right: 4.0), - child: referredPatient.doctorImageURL != - null + margin: EdgeInsets.only(left: 0, top: 25, right: 0, bottom: 0), + padding: EdgeInsets.only(left: 4.0, right: 4.0), + child: referredPatient.doctorImageURL != null ? ClipRRect( - borderRadius: - BorderRadius.circular(20.0), + borderRadius: BorderRadius.circular(20.0), child: Image.network( referredPatient.doctorImageURL, height: 25, width: 30, errorBuilder: - (BuildContext context, - Object exception, - StackTrace stackTrace) { + (BuildContext context, Object exception, StackTrace stackTrace) { return Text('No Image'); }, )) @@ -422,30 +360,22 @@ class ReferralPatientDetailScreen extends StatelessWidget { Expanded( flex: 4, child: Container( - margin: EdgeInsets.only( - left: 10, - top: 30, - right: 10, - bottom: 0), + margin: EdgeInsets.only(left: 10, top: 30, right: 10, bottom: 0), child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( "${TranslationBase.of(context).dr} ${referredPatient.referringDoctorName}", fontFamily: 'Poppins', fontWeight: FontWeight.w800, - fontSize: 1.5 * - SizeConfig.textMultiplier, + fontSize: 1.5 * SizeConfig.textMultiplier, color: Colors.black, ), AppText( - referredPatient - .referringClinicDescription, + referredPatient.referringClinicDescription, fontFamily: 'Poppins', fontWeight: FontWeight.w700, - fontSize: 1.3 * - SizeConfig.textMultiplier, + fontSize: 1.3 * SizeConfig.textMultiplier, color: Color(0XFF2E303A), ), ], @@ -469,10 +399,8 @@ class ReferralPatientDetailScreen extends StatelessWidget { children: [ Container( width: double.infinity, - margin: - EdgeInsets.symmetric(horizontal: 16, vertical: 16), - padding: - EdgeInsets.symmetric(horizontal: 16, vertical: 16), + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16), decoration: BoxDecoration( color: Colors.white, shape: BoxShape.rectangle, @@ -508,10 +436,8 @@ class ReferralPatientDetailScreen extends StatelessWidget { if (referredPatient.referredDoctorRemarks.isNotEmpty) Container( width: double.infinity, - margin: - EdgeInsets.symmetric(horizontal: 16, vertical: 0), - padding: EdgeInsets.symmetric( - horizontal: 16, vertical: 16), + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 0), + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16), decoration: BoxDecoration( color: Colors.white, shape: BoxShape.rectangle, @@ -566,8 +492,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { widget: AddReplayOnReferralPatient( patientReferralViewModel: patientReferralViewModel, myReferralInPatientModel: referredPatient, - isEdited: referredPatient - .referredDoctorRemarks.isNotEmpty, + isEdited: referredPatient.referredDoctorRemarks.isNotEmpty, ), ), ); diff --git a/lib/screens/qr_reader/QR_reader_screen.dart b/lib/screens/qr_reader/QR_reader_screen.dart index 30c05fef..a411aaa7 100644 --- a/lib/screens/qr_reader/QR_reader_screen.dart +++ b/lib/screens/qr_reader/QR_reader_screen.dart @@ -61,8 +61,7 @@ class _QrReaderScreenState extends State { builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: false, - appBarTitle: - TranslationBase.of(context).qr + TranslationBase.of(context).reader, + appBarTitle: TranslationBase.of(context).qr + TranslationBase.of(context).reader, body: Center( child: Container( margin: EdgeInsets.only(top: SizeConfig.realScreenHeight / 7), @@ -80,9 +79,7 @@ class _QrReaderScreenState extends State { height: 7, ), AppText(TranslationBase.of(context).scanQrCode, - fontSize: 14, - fontWeight: FontWeight.w400, - textAlign: TextAlign.center), + fontSize: 14, fontWeight: FontWeight.w400, textAlign: TextAlign.center), SizedBox( height: 15, ), @@ -106,18 +103,13 @@ class _QrReaderScreenState extends State { margin: EdgeInsets.only(top: 8), decoration: BoxDecoration( borderRadius: BorderRadius.circular(6.0), - color: - Theme.of(context).errorColor.withOpacity(0.06), + color: Theme.of(context).errorColor.withOpacity(0.06), ), - padding: EdgeInsets.symmetric( - vertical: 8.0, horizontal: 12.0), + padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 12.0), child: Row( children: [ Expanded( - child: AppText( - error ?? - TranslationBase.of(context) - .errorMessage, + child: AppText(error ?? TranslationBase.of(context).errorMessage, color: Theme.of(context).errorColor)), ], ), @@ -162,9 +154,7 @@ class _QrReaderScreenState extends State { case "0": if (response['List_MyOutPatient'] != null) { setState(() { - patientList = - ModelResponse.fromJson(response['List_MyOutPatient']) - .list; + patientList = ModelResponse.fromJson(response['List_MyOutPatient']).list; isLoading = false; }); Navigator.of(context).pushNamed(PATIENTS_PROFILE, arguments: { @@ -181,8 +171,7 @@ class _QrReaderScreenState extends State { case "1": if (response['List_MyInPatient'] != null) { setState(() { - patientList = - ModelResponse.fromJson(response['List_MyInPatient']).list; + patientList = ModelResponse.fromJson(response['List_MyInPatient']).list; isLoading = false; error = ""; }); @@ -203,8 +192,7 @@ class _QrReaderScreenState extends State { isLoading = false; isError = true; }); - DrAppToastMsg.showErrorToast( - response['ErrorEndUserMessage'] ?? response['ErrorMessage']); + DrAppToastMsg.showErrorToast(response['ErrorEndUserMessage'] ?? response['ErrorMessage']); } }).catchError((error) { setState(() { diff --git a/pubspec.lock b/pubspec.lock index 77df9848..25596d43 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -629,7 +629,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: @@ -921,7 +921,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: @@ -1119,5 +1119,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 161cb1e872b2416d7cf94a915f13940d0930b200 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Sun, 13 Jun 2021 15:51:44 +0300 Subject: [PATCH 35/72] fix profile height size --- lib/config/config.dart | 4 ++-- .../patient_profile_screen.dart | 1 + .../profile/patient-profile-app-bar.dart | 19 ++++++++++--------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 4bbbd40e..eb946dea 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/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index 8a831c4d..21515268 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -105,6 +105,7 @@ class _PatientProfileScreenState extends State PatientProfileAppBar( patient, isFromLiveCare: isFromLiveCare, + isInpatient: isInpatient, height: (patient.patientStatusType != null && patient.patientStatusType == 43) ? 220 diff --git a/lib/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart index 467d681b..09c987fd 100644 --- a/lib/widgets/patients/profile/patient-profile-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -75,13 +75,13 @@ class PatientProfileAppBar extends StatelessWidget decoration: BoxDecoration( color: Colors.white, ), - height: height == 0 - ? isInpatient - ? 215 - : isAppointmentHeader - ? 325 - : 200 - : height, + // height: height == 0 + // ? isInpatient + // ? 215 + // : isAppointmentHeader + // ? 325 + // : 200 + // : height, child: Container( padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), margin: EdgeInsets.only(top: 50), @@ -324,10 +324,11 @@ class PatientProfileAppBar extends StatelessWidget ), ), ), - if(isInpatient) + // if(isInpatient) Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + if(patient.admissionDate != null && patient.admissionDate.isNotEmpty) Container( child: RichText( text: new TextSpan( @@ -547,6 +548,6 @@ class PatientProfileAppBar extends StatelessWidget @override Size get preferredSize => Size(double.maxFinite, height == 0 - ? isInpatient ? 215 : isAppointmentHeader ? 325 : 200 + ? isInpatient ? 160 : isAppointmentHeader ? 290 : 160 : height); } From 712a742aa230355c881da306055719ba2143499f Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Sun, 13 Jun 2021 17:26:14 +0300 Subject: [PATCH 36/72] fix small issue --- .../patients/profile/patient-profile-app-bar.dart | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart index 09c987fd..1a47dd00 100644 --- a/lib/widgets/patients/profile/patient-profile-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -314,12 +314,15 @@ class PatientProfileAppBar extends StatelessWidget children: [ new TextSpan( text: "Result Date: ", - style: TextStyle(fontSize: 14)), + style: TextStyle( fontSize: 10, + color: Color(0xFF575757), + fontWeight: FontWeight.w600, + fontFamily: 'Poppins',)), new TextSpan( text: '${AppDateUtils.getDayMonthYearDateFormatted(appointmentDate, isArabic: projectViewModel.isArabic)}', style: TextStyle( - fontWeight: FontWeight.w700, fontSize: 14)), + fontWeight: FontWeight.w700, fontSize: 12)), ], ), ), @@ -519,7 +522,7 @@ class PatientProfileAppBar extends StatelessWidget !isPrescriptions ? 'Result Date:' : 'Prescriptions Date ', - fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757), + fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757), ), AppText( '${AppDateUtils @@ -527,7 +530,7 @@ class PatientProfileAppBar extends StatelessWidget appointmentDate, isArabic: projectViewModel .isArabic)}', - fontSize: 14, + fontSize: 12, ) ], ) @@ -548,6 +551,6 @@ class PatientProfileAppBar extends StatelessWidget @override Size get preferredSize => Size(double.maxFinite, height == 0 - ? isInpatient ? 160 : isAppointmentHeader ? 290 : 160 + ? isInpatient ? 160 : isAppointmentHeader ? 290 : 170 : height); } From 6fca263109ff61765d0660ce9341508993c08330 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Mon, 14 Jun 2021 14:05:14 +0300 Subject: [PATCH 37/72] video_streaming draggable popup --- .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 8 +- .../com/hmg/hmgDr/ui/VideoCallActivity.java | 30 +- .../hmgDr/ui/fragment/VideoCallFragment.kt | 290 ++++++++++++++++-- .../main/res/layout/activity_video_call.xml | 7 +- android/app/src/main/res/values/styles.xml | 17 + 5 files changed, 297 insertions(+), 55 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 b57f5732..f013d281 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -7,7 +7,7 @@ import androidx.annotation.NonNull import com.google.gson.GsonBuilder import com.hmg.hmgDr.Model.GetSessionStatusModel import com.hmg.hmgDr.Model.SessionStatusModel -import io.flutter.embedding.android.FlutterFragment +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 @@ -22,7 +22,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler private var call: MethodCall? = null private val LAUNCH_VIDEO: Int = 1 - private val flutterFragment: FlutterFragment? = null + lateinit var dialogFragment: VideoCallFragment override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { GeneratedPluginRegistrant.registerWith(flutterEngine) @@ -78,7 +78,9 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler // startActivityForResult(intent, LAUNCH_VIDEO) val transaction = supportFragmentManager.beginTransaction() -// transaction.add() + dialogFragment = VideoCallFragment.newInstance(Bundle()) + dialogFragment.isCancelable = false + dialogFragment.show(transaction, "dialog") } diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java index be4ebfb8..0fb061f1 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java @@ -411,10 +411,6 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi finish(); } - public void onMinimizedClicked(View view) { - - } - public void onSwitchCameraClicked(View view) { if (mPublisher != null) { isSwitchCameraClicked = !isSwitchCameraClicked; @@ -424,6 +420,14 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi } } + public void onCallClicked(View view) { + disconnectSession(); + } + + public void onMinimizedClicked(View view) { + + } + public void onCameraClicked(View view) { if (mPublisher != null) { isCameraClicked = !isCameraClicked; @@ -433,15 +437,6 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi } } - public void onSpeckerClicked(View view) { - if (mSubscriber != null) { - isSpeckerClicked = !isSpeckerClicked; - mSubscriber.setSubscribeToAudio(!isSpeckerClicked); - int res = isSpeckerClicked ? R.drawable.audio_disabled : R.drawable.audio_enabled; - mspeckerBtn.setImageResource(res); - } - } - public void onMicClicked(View view) { if (mPublisher != null) { @@ -452,8 +447,13 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi } } - public void onCallClicked(View view) { - disconnectSession(); + public void onSpeckerClicked(View view) { + if (mSubscriber != null) { + isSpeckerClicked = !isSpeckerClicked; + mSubscriber.setSubscribeToAudio(!isSpeckerClicked); + int res = isSpeckerClicked ? R.drawable.audio_disabled : R.drawable.audio_enabled; + mspeckerBtn.setImageResource(res); + } } @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 be343b89..d5a5d5da 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 @@ -3,24 +3,26 @@ package com.hmg.hmgDr.ui.fragment import android.Manifest import android.annotation.SuppressLint import android.app.Activity +import android.app.Dialog +import android.content.Context import android.content.Intent +import android.graphics.Color +import android.graphics.Point +import android.graphics.drawable.ColorDrawable import android.opengl.GLSurfaceView import android.os.Bundle import android.os.CountDownTimer import android.os.Handler import android.os.Looper import android.util.Log -import android.view.LayoutInflater -import android.view.MotionEvent -import android.view.View -import android.view.ViewGroup +import android.view.* import android.widget.* -import androidx.fragment.app.Fragment +import androidx.annotation.Nullable +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.R -import com.hmg.hmgDr.ui.VideoCallActivity import com.hmg.hmgDr.ui.VideoCallContract.VideoCallPresenter import com.hmg.hmgDr.ui.VideoCallContract.VideoCallView import com.hmg.hmgDr.ui.VideoCallPresenterImpl @@ -31,10 +33,20 @@ import pub.devrel.easypermissions.AppSettingsDialog import pub.devrel.easypermissions.EasyPermissions import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks import java.util.* +import kotlin.math.ceil -class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListener, PublisherListener, +class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.SessionListener, PublisherListener, SubscriberKit.VideoListener, VideoCallView { + var isFullScreen: Boolean = true + private var x_init_cord = 0 + private var y_init_cord:Int = 0 + private var x_init_margin:Int = 0 + private var y_init_margin:Int = 0 + private val szWindow: Point = Point() + private lateinit var mWindowManager: WindowManager + private var isLeft = true + lateinit var videoCallPresenter: VideoCallPresenter private var mSession: Session? = null @@ -61,11 +73,13 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen private var isSpeckerClicked = false private var isMicClicked = false - private var mCallBtn: ImageView? = null - private var mCameraBtn: ImageView? = null - private var mSwitchCameraBtn: ImageView? = null - private var mspeckerBtn: ImageView? = null - private var mMicBtn: ImageView? = null + private lateinit var videoCallContainer: LinearLayout + private lateinit var mCallBtn: ImageView + private lateinit var btnMinimize: ImageView + private lateinit var mCameraBtn: ImageView + private lateinit var mSwitchCameraBtn: ImageView + private lateinit var mspeckerBtn: ImageView + private lateinit var mMicBtn: ImageView private val progressBar: ProgressBar? = null private val countDownTimer: CountDownTimer? = null @@ -84,6 +98,45 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen requestPermissions() } + override fun onStart() { + super.onStart() + + dialog?.window?.setLayout( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.MATCH_PARENT + ) + } + + override fun getTheme(): Int { + return R.style.dialogTheme + } + + override fun onCreateDialog(@Nullable savedInstanceState: Bundle?): Dialog { + val dialog: Dialog = super.onCreateDialog(savedInstanceState) + return dialog + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + // This is done in a post() since the dialog must be drawn before locating. + requireView().post { + val dialogWindow = dialog!!.window + + if (dialog != null && dialogWindow != null) { + dialogWindow.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)); + } + + // Make the dialog possible to be outside touch + dialogWindow!!.setFlags( + WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, + WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL + ) + dialogWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) + requireView().invalidate() + } + } + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { @@ -91,6 +144,7 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen Objects.requireNonNull(requireActivity().actionBar)!!.hide() initUI(view) + handleDragDialog() return view } @@ -121,6 +175,7 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen @SuppressLint("ClickableViewAccessibility") private fun initUI(view: View) { + videoCallContainer = view.findViewById(R.id.video_call_ll) mPublisherViewContainer = view.findViewById(R.id.local_video_view_container) mSubscriberViewContainer = view.findViewById(R.id.remote_video_view_container) @@ -136,11 +191,29 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen controlPanel = view.findViewById(R.id.control_panel) videoCallPresenter = VideoCallPresenterImpl(this, baseUrl) mCallBtn = view.findViewById(R.id.btn_call) + mCallBtn.setOnClickListener { + onCallClicked(it) + } + btnMinimize = view.findViewById(R.id.btn_minimize) + btnMinimize.setOnClickListener { + onMinimizedClicked(it) + } mCameraBtn = view.findViewById(R.id.btn_camera) + mCameraBtn.setOnClickListener { + onCameraClicked(it) + } mSwitchCameraBtn = view.findViewById(R.id.btn_switch_camera) + mSwitchCameraBtn.setOnClickListener { + onSwitchCameraClicked(it) + } mspeckerBtn = view.findViewById(R.id.btn_specker) + mspeckerBtn.setOnClickListener { + onSpeckerClicked(it) + } mMicBtn = view.findViewById(R.id.btn_mic) - + mMicBtn.setOnClickListener { + onMicClicked(it) + } // progressBarLayout=findViewById(R.id.progressBar); // progressBar=findViewById(R.id.progress_bar); // progressBarTextView=findViewById(R.id.progress_bar_text); @@ -316,6 +389,20 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen requireActivity().finish() } + + override fun onCallSuccessful(sessionStatusModel: SessionStatusModel) { + if (sessionStatusModel.sessionStatus == 2 || sessionStatusModel.sessionStatus == 3) { + val returnIntent = Intent() + returnIntent.putExtra("sessionStatusNotRespond", sessionStatusModel) + requireActivity().setResult(Activity.RESULT_OK, returnIntent) + requireActivity().finish() + } + } + + override fun onCallChangeCallStatusSuccessful(sessionStatusModel: SessionStatusModel?) {} + + override fun onFailure() {} + fun onSwitchCameraClicked(view: View?) { if (mPublisher != null) { isSwitchCameraClicked = !isSwitchCameraClicked @@ -325,6 +412,25 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen } } + fun onCallClicked(view: View?) { + disconnectSession() + } + + fun onMinimizedClicked(view: View?) { + if (isFullScreen) { + dialog?.window?.setLayout( + 400, + 600 + ) + } else { + dialog?.window?.setLayout( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.MATCH_PARENT + ) + } + isFullScreen = !isFullScreen + } + fun onCameraClicked(view: View?) { if (mPublisher != null) { isCameraClicked = !isCameraClicked @@ -334,6 +440,15 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen } } + fun onMicClicked(view: View?) { + if (mPublisher != null) { + isMicClicked = !isMicClicked + mPublisher!!.publishAudio = !isMicClicked + val res = if (isMicClicked) R.drawable.mic_disabled else R.drawable.mic_enabled + mMicBtn!!.setImageResource(res) + } + } + fun onSpeckerClicked(view: View?) { if (mSubscriber != null) { isSpeckerClicked = !isSpeckerClicked @@ -343,31 +458,144 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen } } - fun onMicClicked(view: View?) { - if (mPublisher != null) { - isMicClicked = !isMicClicked - mPublisher!!.publishAudio = !isMicClicked - val res = if (isMicClicked) R.drawable.mic_disabled else R.drawable.mic_enabled - mMicBtn!!.setImageResource(res) + @SuppressLint("ClickableViewAccessibility") + fun handleDragDialog(){ + mWindowManager = requireActivity().getSystemService(Context.WINDOW_SERVICE) as WindowManager + getWindowManagerDefaultDisplay() + + videoCallContainer.setOnTouchListener { _, event -> + //Get Floating widget view params + //Get Floating widget view params + val layoutParams : WindowManager.LayoutParams = dialog!!.window!!.attributes + //get the touch location coordinates + val x_cord = event.rawX.toInt() + val y_cord = event.rawY.toInt() + val x_cord_Destination: Int + var y_cord_Destination: Int + + when (event.action) { + MotionEvent.ACTION_DOWN -> { + x_init_cord = x_cord + y_init_cord = y_cord + + //remember the initial position. + x_init_margin = layoutParams.x + y_init_margin = layoutParams.y + } + MotionEvent.ACTION_UP -> { + //Get the difference between initial coordinate and current coordinate + val x_diff: Int = x_cord - x_init_cord + val y_diff: Int = y_cord - y_init_cord + + y_cord_Destination = y_init_margin + y_diff + val barHeight: Int = getStatusBarHeight() + if (y_cord_Destination < 0) { +// y_cord_Destination = 0 + y_cord_Destination = + -(szWindow.y - (videoCallContainer.height /*+ barHeight*/)) + } else if (y_cord_Destination + (videoCallContainer.height + barHeight) > szWindow.y) { + y_cord_Destination = + szWindow.y - (videoCallContainer.height + barHeight) + } + layoutParams.y = y_cord_Destination + + //reset position if user drags the floating view + resetPosition(x_cord) + } + MotionEvent.ACTION_MOVE -> { + val x_diff_move: Int = x_cord - x_init_cord + val y_diff_move: Int = y_cord - y_init_cord + x_cord_Destination = x_init_margin + x_diff_move + y_cord_Destination = y_init_margin + y_diff_move + + layoutParams.x = x_cord_Destination + layoutParams.y = y_cord_Destination + + dialog!!.window!!.attributes = layoutParams + } + } + true } } - fun onCallClicked(view: View?) { - disconnectSession() + /* Reset position of Floating Widget view on dragging */ + private fun resetPosition(x_cord_now: Int) { + if (x_cord_now <= szWindow.x / 2) { + isLeft = true + moveToLeft(x_cord_now) + } else { + isLeft = false + moveToRight(x_cord_now) + } } - override fun onCallSuccessful(sessionStatusModel: SessionStatusModel) { - if (sessionStatusModel.sessionStatus == 2 || sessionStatusModel.sessionStatus == 3) { - val returnIntent = Intent() - returnIntent.putExtra("sessionStatusNotRespond", sessionStatusModel) - requireActivity().setResult(Activity.RESULT_OK, returnIntent) - requireActivity().finish() - } + /* Method to move the Floating widget view to Left */ + private fun moveToLeft(current_x_cord: Int) { + + var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes + + mParams.x = + (szWindow.x - current_x_cord * current_x_cord - videoCallContainer.width).toInt() + + dialog!!.window!!.attributes = mParams + val x = szWindow.x - current_x_cord + object : CountDownTimer(500, 5) { + //get params of Floating Widget view + var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes + override fun onTick(t: Long) { + val step = (500 - t) / 5 + // mParams.x = 0 - (current_x_cord * current_x_cord * step).toInt() + mParams.x = + (szWindow.x - current_x_cord * current_x_cord * step - videoCallContainer.width).toInt() + + dialog!!.window!!.attributes = mParams + } + + override fun onFinish() { + mParams.x = -(szWindow.x - videoCallContainer.width) + + dialog!!.window!!.attributes = mParams + } + }.start() } - override fun onCallChangeCallStatusSuccessful(sessionStatusModel: SessionStatusModel?) {} + /* Method to move the Floating widget view to Right */ + private fun moveToRight(current_x_cord: Int) { +// var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes +// mParams.x = +// (szWindow.x + current_x_cord * current_x_cord - videoCallContainer.width).toInt() +// +// dialog!!.window!!.attributes = mParams + object : CountDownTimer(500, 5) { + //get params of Floating Widget view + var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes + override fun onTick(t: Long) { + val step = (500 - t) / 5 + mParams.x = + (szWindow.x + current_x_cord * current_x_cord * step - videoCallContainer.width).toInt() + + dialog!!.window!!.attributes = mParams + } - override fun onFailure() {} + override fun onFinish() { + mParams.x = szWindow.x - videoCallContainer.width + + dialog!!.window!!.attributes = mParams + } + }.start() + } + + private fun getWindowManagerDefaultDisplay() { + mWindowManager.getDefaultDisplay() + .getSize(szWindow) + } + + /* return status bar height on basis of device display metrics */ + private fun getStatusBarHeight(): Int { + return ceil( + (25 * requireActivity().applicationContext.resources.displayMetrics.density).toDouble() + ).toInt() + } companion object { @JvmStatic @@ -376,7 +604,7 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen arguments = args } - private val TAG = VideoCallActivity::class.java.simpleName + private val TAG = VideoCallFragment::class.java.simpleName private const val RC_SETTINGS_SCREEN_PERM = 123 private const val RC_VIDEO_APP_PERM = 124 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 a3c2ced1..b7ca8d8d 100644 --- a/android/app/src/main/res/layout/activity_video_call.xml +++ b/android/app/src/main/res/layout/activity_video_call.xml @@ -1,6 +1,7 @@ @@ -132,7 +132,6 @@ android:layout_width="@dimen/video_icon_size" android:layout_height="@dimen/video_icon_size" android:layout_alignParentEnd="true" - android:onClick="onCallClicked" android:scaleType="centerCrop" android:src="@drawable/call" /> @@ -141,7 +140,6 @@ android:layout_width="@dimen/video_icon_size" android:layout_height="@dimen/video_icon_size" android:layout_alignParentStart="true" - android:onClick="onMinimizedClicked" android:layout_marginEnd="@dimen/padding_space_small" android:scaleType="centerCrop" android:src="@drawable/ic_mini" /> @@ -151,7 +149,6 @@ android:layout_width="@dimen/video_icon_size" android:layout_height="@dimen/video_icon_size" android:layout_toEndOf="@id/btn_minimize" - android:onClick="onCameraClicked" android:scaleType="centerCrop" android:layout_marginEnd="@dimen/padding_space_small" android:src="@drawable/video_enabled" /> @@ -161,7 +158,6 @@ android:layout_width="@dimen/video_icon_size" android:layout_height="@dimen/video_icon_size" android:layout_toEndOf="@id/btn_camera" - android:onClick="onMicClicked" android:layout_marginEnd="@dimen/padding_space_small" android:scaleType="centerCrop" android:src="@drawable/mic_enabled" /> @@ -171,7 +167,6 @@ android:layout_width="@dimen/video_icon_size" android:layout_height="@dimen/video_icon_size" android:layout_toEndOf="@id/btn_mic" - android:onClick="onSpeckerClicked" android:scaleType="centerCrop" android:layout_marginEnd="@dimen/padding_space_small" android:src="@drawable/audio_enabled" /> diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml index 24355fae..e13b5b14 100644 --- a/android/app/src/main/res/values/styles.xml +++ b/android/app/src/main/res/values/styles.xml @@ -16,4 +16,21 @@ true @null + + + From 1edd375fd7002f8cd24e9f37ce918292fac4d5a9 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 14 Jun 2021 16:30:55 +0300 Subject: [PATCH 38/72] first step from special clinic --- lib/config/config.dart | 1 + lib/core/service/home/dasboard_service.dart | 26 +++++++++++++-- lib/core/viewModel/dashboard_view_model.dart | 14 ++++++++ ...cial_clinical_care_List_Respose_Model.dart | 32 +++++++++++++++++++ lib/screens/home/home_screen.dart | 2 ++ 5 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 lib/models/dashboard/get_special_clinical_care_List_Respose_Model.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index 588976ba..851eb832 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -219,6 +219,7 @@ const GET_PENDING_PATIENT_ER_FOR_DOCTOR_APP = 'Services/DoctorApplication.svc/RE const DOCTOR_CHECK_HAS_LIVE_CARE = "Services/DoctorApplication.svc/REST/CheckDoctorHasLiveCare"; const LIVE_CARE_IS_LOGIN = "LiveCareApi/DoctorApp/UseIsLogin"; +const GET_SPECIAL_CLINICAL_CARE_LIST = "Services/DoctorApplication.svc/REST/GetSpecialClinicalCareList"; var selectedPatientType = 1; diff --git a/lib/core/service/home/dasboard_service.dart b/lib/core/service/home/dasboard_service.dart index b35d24f2..8bb0e586 100644 --- a/lib/core/service/home/dasboard_service.dart +++ b/lib/core/service/home/dasboard_service.dart @@ -1,10 +1,14 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.dart'; import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; +import 'package:doctor_app_flutter/models/dashboard/get_special_clinical_care_List_Respose_Model.dart'; class DashboardService extends BaseService { List _dashboardItemsList = []; List get dashboardItemsList => _dashboardItemsList; + + List _specialClinicalCareList = []; + List get specialClinicalCareList => _specialClinicalCareList; bool hasVirtualClinic = false; String sServiceID; @@ -24,8 +28,6 @@ class DashboardService extends BaseService { super.error = error; }, body: { - // "VidaAuthTokenID": - // "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyODA0IiwianRpIjoiZDYxZmM5MTQtZWFhYy00YjQ4LTgyMmEtMmE3OTNlZDMzZGYwIiwiZW1haWwiOiJNb2hhbWVkLlJlc3dhbkBjbG91ZHNvbHV0aW9uLXNhLmNvbSIsImlkIjoiMjgwNCIsIk5hbWUiOiJNVUhBTU1BRCBBWkFNIiwiRW1wbG95ZWVJZCI6IjE0ODUiLCJGYWNpbGl0eUdyb3VwSWQiOiIwMTAyNjYiLCJGYWNpbGl0eUlkIjoiMTUiLCJQaGFyYW1jeUZhY2lsaXR5SWQiOiI1NSIsIklTX1BIQVJNQUNZX0NPTk5FQ1RFRCI6IlRydWUiLCJEb2N0b3JJZCI6IjE0ODUiLCJTRVNTSU9OSUQiOiIyMTU3NTgwOCIsIkNsaW5pY0lkIjoiMyIsInJvbGUiOlsiU0VDVVJJVFkgQURNSU5JU1RSQVRPUlMiLCJTRVRVUCBBRE1JTklTVFJBVE9SUyIsIkNFTydTIiwiRVhFQ1VUSVZFIERJUkVDVE9SUyIsIk1BTkFHRVJTIiwiU1VQRVJWSVNPUlMiLCJDTElFTlQgU0VSVklDRVMgQ09PUkRJTkFUT1JTIiwiQ0xJRU5UIFNFUlZJQ0VTIFNVUEVSVklTT1JTIiwiQ0xJRU5UIFNFUlZJQ0VTIE1BTkdFUlMiLCJIRUFEIE5VUlNFUyIsIkRPQ1RPUlMiLCJDSElFRiBPRiBNRURJQ0FMIFNUQUZGUyIsIkJJTy1NRURJQ0FMIFRFQ0hOSUNJQU5TIiwiQklPLU1FRElDQUwgRU5HSU5FRVJTIiwiQklPLU1FRElDQUwgREVQQVJUTUVOVCBIRUFEUyIsIklUIEhFTFAgREVTSyIsIkFETUlOSVNUUkFUT1JTIiwiTEFCIEFETUlOSVNUUkFUT1IiLCJMQUIgVEVDSE5JQ0lBTiIsIkJVU0lORVNTIE9GRklDRSBTVEFGRiIsIkZJTkFOQ0UgQUNDT1VOVEFOVFMiLCJQSEFSTUFDWSBTVEFGRiIsIkFDQ09VTlRTIFNUQUZGIiwiTEFCIFJFQ0VQVElPTklTVCIsIkVSIE5VUlNFIiwiSU5QQVRJRU5UIEJJTExJTkcgU1VQRVJWSVNPUiIsIkxEUi1PUiBOVVJTRVMiLCJBRE1JU1NJT04gU1RBRkYiLCJIRUxQIERFU0sgQURNSU4iLCJBUFBST1ZBTCBTVEFGRiIsIklOUEFUSUVOVCBCSUxMSU5HIENPT1JESU5BVE9SIiwiQklMTElORyBTVEFGRiIsIkNPTlNFTlQgIiwiQ29uc2VudCAtIERlbnRhbCIsIldFQkVNUiJdLCJuYmYiOjE2MDgwMjg0NzQsImV4cCI6MTYwODg5MjQ3NCwiaWF0IjoxNjA4MDI4NDc0fQ.8OJcy6vUuPnNTi_qSjip8YCrFdaRLtJKbNKXcMtnQxk" }, ); } @@ -48,4 +50,24 @@ class DashboardService extends BaseService { }, ); } + Future getSpecialClinicalCareList() async { + hasError = false; + await getDoctorProfile(isGetProfile: true); + await baseAppClient.post( + GET_SPECIAL_CLINICAL_CARE_LIST, + onSuccess: (dynamic response, int statusCode) { + + _specialClinicalCareList.clear(); + response['List_SpecialClinicalCareList'].forEach((v) { + _specialClinicalCareList.add(GetSpecialClinicalCareListResponseModel.fromJson(v)); + });}, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: { + }, + ); + } + } diff --git a/lib/core/viewModel/dashboard_view_model.dart b/lib/core/viewModel/dashboard_view_model.dart index bbbef0b6..fe160c3c 100644 --- a/lib/core/viewModel/dashboard_view_model.dart +++ b/lib/core/viewModel/dashboard_view_model.dart @@ -4,6 +4,7 @@ import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/service/home/dasboard_service.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; +import 'package:doctor_app_flutter/models/dashboard/get_special_clinical_care_List_Respose_Model.dart'; import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; @@ -22,6 +23,9 @@ class DashboardViewModel extends BaseViewModel { String get sServiceID => _dashboardService.sServiceID; + List get specialClinicalCareList => _dashboardService.specialClinicalCareList; + + Future setFirebaseNotification(ProjectViewModel projectsProvider, AuthenticationViewModel authProvider) async { setState(ViewState.Busy); @@ -64,6 +68,16 @@ class DashboardViewModel extends BaseViewModel { setState(ViewState.Idle); } + Future getSpecialClinicalCareList() async { + setState(ViewState.Busy); + await _dashboardService.getSpecialClinicalCareList(); + if (_dashboardService.hasError) { + error = _dashboardService.error; + setState(ViewState.Error); + } else + setState(ViewState.Idle); + } + Future changeClinic( int clinicId, AuthenticationViewModel authProvider) async { setState(ViewState.BusyLocal); diff --git a/lib/models/dashboard/get_special_clinical_care_List_Respose_Model.dart b/lib/models/dashboard/get_special_clinical_care_List_Respose_Model.dart new file mode 100644 index 00000000..ec19abb0 --- /dev/null +++ b/lib/models/dashboard/get_special_clinical_care_List_Respose_Model.dart @@ -0,0 +1,32 @@ +class GetSpecialClinicalCareListResponseModel { + int projectID; + int clinicID; + String clinicDescription; + String clinicDescriptionN; + bool isActive; + + GetSpecialClinicalCareListResponseModel( + {this.projectID, + this.clinicID, + this.clinicDescription, + this.clinicDescriptionN, + this.isActive}); + + GetSpecialClinicalCareListResponseModel.fromJson(Map json) { + projectID = json['ProjectID']; + clinicID = json['ClinicID']; + clinicDescription = json['ClinicDescription']; + clinicDescriptionN = json['ClinicDescriptionN']; + isActive = json['IsActive']; + } + + Map toJson() { + final Map data = new Map(); + data['ProjectID'] = this.projectID; + data['ClinicID'] = this.clinicID; + data['ClinicDescription'] = this.clinicDescription; + data['ClinicDescriptionN'] = this.clinicDescriptionN; + data['IsActive'] = this.isActive; + return data; + } +} diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 85ea3506..eba91cc2 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -69,6 +69,8 @@ class _HomeScreenState extends State { await model.getDashboard(); await model.getDoctorProfile(isGetProfile: true); await model.checkDoctorHasLiveCare(); + + await model.getSpecialClinicalCareList(); }, builder: (_, model, w) => AppScaffold( baseViewModel: model, From 3913f8936c14894c4871fb1790804e4fe44a2d23 Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Mon, 14 Jun 2021 17:03:09 +0300 Subject: [PATCH 39/72] Scan QR Code fix --- lib/config/config.dart | 4 +- lib/core/service/patient/patient_service.dart | 57 ++++++-- lib/core/viewModel/patient_view_model.dart | 61 ++++---- lib/screens/qr_reader/QR_reader_screen.dart | 134 +++--------------- 4 files changed, 94 insertions(+), 162 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 492d7ada..f2dbbf18 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/patient/patient_service.dart b/lib/core/service/patient/patient_service.dart index e15cc8d1..25e9481b 100644 --- a/lib/core/service/patient/patient_service.dart +++ b/lib/core/service/patient/patient_service.dart @@ -4,6 +4,7 @@ import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/model/note/CreateNoteModel.dart'; 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/model/patient_muse/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.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'; @@ -12,6 +13,7 @@ import 'package:doctor_app_flutter/models/patient/get_list_stp_referral_frequenc import 'package:doctor_app_flutter/models/patient/lab_orders/lab_orders_res_model.dart'; import 'package:doctor_app_flutter/models/patient/lab_result/lab_result.dart'; import 'package:doctor_app_flutter/models/patient/lab_result/lab_result_req_model.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/models/patient/prescription/prescription_report.dart'; import 'package:doctor_app_flutter/models/patient/prescription/prescription_report_for_in_patient.dart'; import 'package:doctor_app_flutter/models/patient/prescription/prescription_res_model.dart'; @@ -22,20 +24,19 @@ import 'package:doctor_app_flutter/models/patient/vital_sign/vital_sign_res_mode class PatientService extends BaseService { List _patientVitalSignList = []; List patientVitalSignOrderdSubList = []; + List inPatientList = List(); + List myInPatientList = List(); List get patientVitalSignList => _patientVitalSignList; List _patientLabResultOrdersList = []; - List get patientLabResultOrdersList => - _patientLabResultOrdersList; + List get patientLabResultOrdersList => _patientLabResultOrdersList; - List get patientPrescriptionsList => - _patientPrescriptionsList; + List get patientPrescriptionsList => _patientPrescriptionsList; List _patientPrescriptionsList = []; - List get prescriptionReportForInPatientList => - _prescriptionReportForInPatientList; + List get prescriptionReportForInPatientList => _prescriptionReportForInPatientList; List _prescriptionReportForInPatientList = []; List _patientRadiologyList = []; @@ -79,12 +80,9 @@ class PatientService extends BaseService { get referalFrequancyList => _referalFrequancyList; - DoctorsByClinicIdRequest _doctorsByClinicIdRequest = - DoctorsByClinicIdRequest(); - STPReferralFrequencyRequest _referralFrequencyRequest = - STPReferralFrequencyRequest(); - ClinicByProjectIdRequest _clinicByProjectIdRequest = - ClinicByProjectIdRequest(); + DoctorsByClinicIdRequest _doctorsByClinicIdRequest = DoctorsByClinicIdRequest(); + STPReferralFrequencyRequest _referralFrequencyRequest = STPReferralFrequencyRequest(); + ClinicByProjectIdRequest _clinicByProjectIdRequest = ClinicByProjectIdRequest(); ReferToDoctorRequest _referToDoctorRequest; Future getPatientList(patient, patientType, {isView}) async { @@ -138,6 +136,38 @@ class PatientService extends BaseService { return Future.value(localRes); } + Future getInPatient(PatientSearchRequestModel requestModel, bool isMyInpatient) async { + hasError = false; + await getDoctorProfile(); + + if (isMyInpatient) { + requestModel.doctorID = doctorProfile.doctorID; + } else { + requestModel.doctorID = 0; + } + + await baseAppClient.post( + GET_PATIENT_IN_PATIENT_LIST, + onSuccess: (dynamic response, int statusCode) { + inPatientList.clear(); + myInPatientList.clear(); + + response['List_MyInPatient'].forEach((v) { + PatiantInformtion patient = PatiantInformtion.fromJson(v); + inPatientList.add(patient); + if (patient.doctorId == doctorProfile.doctorID) { + myInPatientList.add(patient); + } + }); + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: requestModel.toJson(), + ); + } + Future getLabResultOrders(patient) async { hasError = false; await baseAppClient.post( @@ -181,8 +211,7 @@ class PatientService extends BaseService { onSuccess: (dynamic response, int statusCode) { _prescriptionReportForInPatientList = []; response['List_PrescriptionReportForInPatient'].forEach((v) { - prescriptionReportForInPatientList - .add(PrescriptionReportForInPatient.fromJson(v)); + prescriptionReportForInPatientList.add(PrescriptionReportForInPatient.fromJson(v)); }); }, onFailure: (String error, int statusCode) { diff --git a/lib/core/viewModel/patient_view_model.dart b/lib/core/viewModel/patient_view_model.dart index de40afde..5bc6250f 100644 --- a/lib/core/viewModel/patient_view_model.dart +++ b/lib/core/viewModel/patient_view_model.dart @@ -2,9 +2,11 @@ import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/note/CreateNoteModel.dart'; 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/model/patient_muse/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/service/patient/patient_service.dart'; import 'package:doctor_app_flutter/models/patient/lab_orders/lab_orders_res_model.dart'; import 'package:doctor_app_flutter/models/patient/lab_result/lab_result.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/models/patient/prescription/prescription_report.dart'; import 'package:doctor_app_flutter/models/patient/prescription/prescription_report_for_in_patient.dart'; import 'package:doctor_app_flutter/models/patient/prescription/prescription_res_model.dart'; @@ -17,51 +19,43 @@ import 'base_view_model.dart'; class PatientViewModel extends BaseViewModel { PatientService _patientService = locator(); - List get patientVitalSignList => - _patientService.patientVitalSignList; + List get inPatientList => _patientService.inPatientList; - List get patientVitalSignOrderdSubList => - _patientService.patientVitalSignOrderdSubList; + List get patientVitalSignList => _patientService.patientVitalSignList; - List get patientLabResultOrdersList => - _patientService.patientLabResultOrdersList; + List get patientVitalSignOrderdSubList => _patientService.patientVitalSignOrderdSubList; - List get patientPrescriptionsList => - _patientService.patientPrescriptionsList; + List get patientLabResultOrdersList => _patientService.patientLabResultOrdersList; + + List get patientPrescriptionsList => _patientService.patientPrescriptionsList; List get prescriptionReportForInPatientList => _patientService.prescriptionReportForInPatientList; - List get prescriptionReport => - _patientService.prescriptionReport; + List get prescriptionReport => _patientService.prescriptionReport; - List get patientRadiologyList => - _patientService.patientRadiologyList; + List get patientRadiologyList => _patientService.patientRadiologyList; List get labResultList => _patientService.labResultList; get insuranceApporvalsList => _patientService.insuranceApporvalsList; - List get patientProgressNoteList => - _patientService.patientProgressNoteList; + List get patientProgressNoteList => _patientService.patientProgressNoteList; List get clinicsList => _patientService.clinicsList; List get doctorsList => _patientService.doctorsList; - List get referralFrequencyList => - _patientService.referalFrequancyList; + List get referralFrequencyList => _patientService.referalFrequancyList; - Future getPatientList(patient, patientType, - {bool isBusyLocal = false, isView}) async { + Future getPatientList(patient, patientType, {bool isBusyLocal = false, isView}) async { var localRes; if (isBusyLocal) { setState(ViewState.BusyLocal); } else { setState(ViewState.Busy); } - localRes = await _patientService.getPatientList(patient, patientType, - isView: isView); + localRes = await _patientService.getPatientList(patient, patientType, isView: isView); if (_patientService.hasError) { error = _patientService.error; @@ -210,16 +204,12 @@ class PatientViewModel extends BaseViewModel { } List getDoctorNameList() { - var doctorNamelist = _patientService.doctorsList - .map((value) => value['DoctorName'].toString()) - .toList(); + var doctorNamelist = _patientService.doctorsList.map((value) => value['DoctorName'].toString()).toList(); return doctorNamelist; } List getClinicNameList() { - var clinicsNameslist = _patientService.clinicsList - .map((value) => value['ClinicDescription'].toString()) - .toList(); + var clinicsNameslist = _patientService.clinicsList.map((value) => value['ClinicDescription'].toString()).toList(); return clinicsNameslist; } @@ -234,9 +224,8 @@ class PatientViewModel extends BaseViewModel { } List getReferralNamesList() { - var referralNamesList = _patientService.referalFrequancyList - .map((value) => value['Description'].toString()) - .toList(); + var referralNamesList = + _patientService.referalFrequancyList.map((value) => value['Description'].toString()).toList(); return referralNamesList; } @@ -281,4 +270,18 @@ class PatientViewModel extends BaseViewModel { } else setState(ViewState.Idle); } + + Future getInPatientList(PatientSearchRequestModel requestModel, {bool isMyInpatient = false}) async { + await getDoctorProfile(); + setState(ViewState.Busy); + + await _patientService.getInPatient(requestModel, false); + if (_patientService.hasError) { + error = _patientService.error; + setState(ViewState.ErrorLocal); + } else { + // setDefaultInPatientList(); + setState(ViewState.Idle); + } + } } diff --git a/lib/screens/qr_reader/QR_reader_screen.dart b/lib/screens/qr_reader/QR_reader_screen.dart index a411aaa7..848b3f9a 100644 --- a/lib/screens/qr_reader/QR_reader_screen.dart +++ b/lib/screens/qr_reader/QR_reader_screen.dart @@ -1,11 +1,8 @@ import 'package:barcode_scan_fix/barcode_scan.dart'; -import 'package:doctor_app_flutter/config/shared_pref_kay.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/viewModel/patient_view_model.dart'; -import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -import 'package:doctor_app_flutter/models/patient/patient_model.dart'; -import 'package:doctor_app_flutter/models/patient/topten_users_res_model.dart'; -import 'package:doctor_app_flutter/util/dr_app_shared_pref.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'; @@ -26,38 +23,9 @@ class QrReaderScreen extends StatefulWidget { } class _QrReaderScreenState extends State { - DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); - - bool isLoading = false; - bool isError = false; - PatientModel patient = PatientModel( - ProjectID: 15, - ClinicID: 0, - DoctorID: 1485, - FirstName: "0", - MiddleName: "0", - LastName: "0", - PatientMobileNumber: "0", - PatientIdentificationID: "0", - PatientID: 0, - From: "0", - To: "0", - LanguageID: 2, - stamp: "2020-03-02T13:56:39.170Z", - IPAdress: "11.11.11.11", - VersionID: 5.5, - Channel: 9, - TokenID: "@dm!n", - SessionID: "5G0yXn0Jnq", - IsLoginForDoctorApp: true, - PatientOutSA: false); - List patientList = []; - String error = ''; - @override Widget build(BuildContext context) { return BaseView( - onModelReady: (model) => model.getClinicsList(), builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: false, @@ -95,26 +63,8 @@ class _QrReaderScreenState extends State { onPressed: () { _scanQrAndGetPatient(context, model); }, - loading: isLoading, icon: Image.asset('assets/images/qr_code_white.png'), ), - isError - ? Container( - margin: EdgeInsets.only(top: 8), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(6.0), - color: Theme.of(context).errorColor.withOpacity(0.06), - ), - padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 12.0), - child: Row( - children: [ - Expanded( - child: AppText(error ?? TranslationBase.of(context).errorMessage, - color: Theme.of(context).errorColor)), - ], - ), - ) - : Container(), ], ), ), @@ -131,75 +81,25 @@ class _QrReaderScreenState extends State { var result = await BarcodeScanner.scan(); if (result != "") { List listOfParams = result.split(','); - String patientType = "1"; - setState(() { - isLoading = true; - isError = false; - patientList = []; - }); - String token = await sharedPref.getString(TOKEN); -// Map profile = await sharedPref.getObj(DOCTOR_PROFILE); -// DoctorProfileModel doctorProfile = new DoctorProfileModel.fromJson(profile); -// patient.PatientID = 8808; -// patient.TokenID = token; -// patient.setDoctorID = doctorProfile.projectID; -// patient.setClinicID = doctorProfile.clinicID; -// patient.setProjectID = doctorProfile.projectID; -// Provider.of(context, listen: false); - patient.PatientID = 8808; - patient.TokenID = token; - model.getPatientList(patient, "1", isBusyLocal: true).then((response) { - if (response['MessageStatus'] == 1) { - switch (patientType) { - case "0": - if (response['List_MyOutPatient'] != null) { - setState(() { - patientList = ModelResponse.fromJson(response['List_MyOutPatient']).list; - isLoading = false; - }); - Navigator.of(context).pushNamed(PATIENTS_PROFILE, arguments: { - "patient": patientList[0], - }); - } else { - setState(() { - isError = true; - isLoading = false; - }); - DrAppToastMsg.showErrorToast('No patient'); - } - break; - case "1": - if (response['List_MyInPatient'] != null) { - setState(() { - patientList = ModelResponse.fromJson(response['List_MyInPatient']).list; - isLoading = false; - error = ""; - }); - Navigator.of(context).pushNamed(PATIENTS_PROFILE, arguments: { - "patient": patientList[0], - }); - } else { - setState(() { - isError = true; - isLoading = false; - }); - DrAppToastMsg.showErrorToast('No patient'); - break; - } - } + int patientID = 0; + if (listOfParams[1].length != 0) patientID = int.parse(listOfParams[1]); + PatientSearchRequestModel patientSearchRequestModel = PatientSearchRequestModel( + patientID: patientID, + ); + + await model.getInPatientList(patientSearchRequestModel, isMyInpatient: true).then((d) { + if (model.state != ViewState.ErrorLocal) { + if (model.inPatientList.isEmpty) + DrAppToastMsg.showErrorToast('No patient'); + else + Navigator.of(context).pushNamed(PATIENTS_PROFILE, arguments: { + "patient": model.inPatientList[0], + }); } else { - setState(() { - isLoading = false; - isError = true; - }); - DrAppToastMsg.showErrorToast(response['ErrorEndUserMessage'] ?? response['ErrorMessage']); + DrAppToastMsg.showErrorToast(model.error); } }).catchError((error) { - setState(() { - isLoading = false; - }); Helpers.showErrorToast(error.message); - //DrAppToastMsg.showErrorToast(error); }); } } From 363b55069faf22e4696ebf875f256caf0bca563c Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 14 Jun 2021 18:04:20 +0300 Subject: [PATCH 40/72] first step form Special Clinic --- lib/config/config.dart | 1 + .../PatientSearchRequestModel.dart | 32 ++-- lib/core/service/home/dasboard_service.dart | 21 --- .../special_clinic_service.dart | 57 +++++++ .../viewModel/PatientSearchViewModel.dart | 42 +++++- lib/core/viewModel/dashboard_view_model.dart | 23 ++- lib/locator.dart | 2 + ...nical_care_mapping_List_Respose_Model.dart | 37 +++++ lib/screens/home/home_screen.dart | 3 +- .../patients/PatientsInPatientScreen.dart | 142 +++++++++++++++++- 10 files changed, 315 insertions(+), 45 deletions(-) create mode 100644 lib/core/service/special_clinics/special_clinic_service.dart create mode 100644 lib/models/dashboard/get_special_clinical_care_mapping_List_Respose_Model.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index c8eac881..eb361798 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -226,6 +226,7 @@ const DOCTOR_CHECK_HAS_LIVE_CARE = "Services/DoctorApplication.svc/REST/CheckDoc const LIVE_CARE_IS_LOGIN = "LiveCareApi/DoctorApp/UseIsLogin"; const ADD_REFERRED_REMARKS_NEW = "Services/DoctorApplication.svc/REST/AddReferredDoctorRemarks_New"; const GET_SPECIAL_CLINICAL_CARE_LIST = "Services/DoctorApplication.svc/REST/GetSpecialClinicalCareList"; +const GET_SPECIAL_CLINICAL_CARE_MAPPING_LIST = "Services/DoctorApplication.svc/REST/GetSpecialClinicalCareMappingList"; var selectedPatientType = 1; diff --git a/lib/core/model/patient_muse/PatientSearchRequestModel.dart b/lib/core/model/patient_muse/PatientSearchRequestModel.dart index 437c5885..2918a393 100644 --- a/lib/core/model/patient_muse/PatientSearchRequestModel.dart +++ b/lib/core/model/patient_muse/PatientSearchRequestModel.dart @@ -11,20 +11,24 @@ class PatientSearchRequestModel { int searchType; String mobileNo; String identificationNo; + int nursingStationID; + int clinicID; PatientSearchRequestModel( - {this.doctorID =0, - this.firstName ="0", - this.middleName ="0", - this.lastName ="0", - this.patientMobileNumber ="0", - this.patientIdentificationID ="0", - this.patientID =0, - this.searchType =1, - this.mobileNo="", - this.identificationNo="0", - this.from ="0", - this.to ="0"}); + {this.doctorID = 0, + this.firstName = "0", + this.middleName = "0", + this.lastName = "0", + this.patientMobileNumber = "0", + this.patientIdentificationID = "0", + this.patientID = 0, + this.searchType = 1, + this.mobileNo = "", + this.identificationNo = "0", + this.from = "0", + this.to = "0", + this.clinicID, + this.nursingStationID = 0}); PatientSearchRequestModel.fromJson(Map json) { doctorID = json['DoctorID']; @@ -39,6 +43,8 @@ class PatientSearchRequestModel { searchType = json['SearchType']; mobileNo = json['MobileNo']; identificationNo = json['IdentificationNo']; + nursingStationID = json['NursingStationID']; + clinicID = json['ClinicID']; } Map toJson() { @@ -55,6 +61,8 @@ class PatientSearchRequestModel { data['SearchType'] = this.searchType; data['MobileNo'] = this.mobileNo; data['IdentificationNo'] = this.identificationNo; + data['NursingStationID'] = this.nursingStationID; + data['ClinicID'] = this.clinicID; return data; } } diff --git a/lib/core/service/home/dasboard_service.dart b/lib/core/service/home/dasboard_service.dart index 8bb0e586..ad3ec887 100644 --- a/lib/core/service/home/dasboard_service.dart +++ b/lib/core/service/home/dasboard_service.dart @@ -7,8 +7,6 @@ class DashboardService extends BaseService { List _dashboardItemsList = []; List get dashboardItemsList => _dashboardItemsList; - List _specialClinicalCareList = []; - List get specialClinicalCareList => _specialClinicalCareList; bool hasVirtualClinic = false; String sServiceID; @@ -50,24 +48,5 @@ class DashboardService extends BaseService { }, ); } - Future getSpecialClinicalCareList() async { - hasError = false; - await getDoctorProfile(isGetProfile: true); - await baseAppClient.post( - GET_SPECIAL_CLINICAL_CARE_LIST, - onSuccess: (dynamic response, int statusCode) { - - _specialClinicalCareList.clear(); - response['List_SpecialClinicalCareList'].forEach((v) { - _specialClinicalCareList.add(GetSpecialClinicalCareListResponseModel.fromJson(v)); - });}, - onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, - body: { - }, - ); - } } diff --git a/lib/core/service/special_clinics/special_clinic_service.dart b/lib/core/service/special_clinics/special_clinic_service.dart new file mode 100644 index 00000000..49237331 --- /dev/null +++ b/lib/core/service/special_clinics/special_clinic_service.dart @@ -0,0 +1,57 @@ +import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/core/service/base/base_service.dart'; +import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; +import 'package:doctor_app_flutter/models/dashboard/get_special_clinical_care_List_Respose_Model.dart'; +import 'package:doctor_app_flutter/models/dashboard/get_special_clinical_care_mapping_List_Respose_Model.dart'; + +class SpecialClinicsService extends BaseService { + + + List _specialClinicalCareList = []; + List get specialClinicalCareList => _specialClinicalCareList; + + List _specialClinicalCareMappingList = []; + List get specialClinicalCareMappingList => _specialClinicalCareMappingList; + Future getSpecialClinicalCareList() async { + hasError = false; + await baseAppClient.post( + GET_SPECIAL_CLINICAL_CARE_LIST, + onSuccess: (dynamic response, int statusCode) { + + _specialClinicalCareList.clear(); + response['List_SpecialClinicalCareList'].forEach((v) { + _specialClinicalCareList.add(GetSpecialClinicalCareListResponseModel.fromJson(v)); + });}, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: { + }, + ); + } + + + Future getSpecialClinicalCareMappingList(int clinicId) async { + hasError = false; + await baseAppClient.post( + GET_SPECIAL_CLINICAL_CARE_MAPPING_LIST, + onSuccess: (dynamic response, int statusCode) { + + _specialClinicalCareMappingList.clear(); + response['List_SpecialClinicalCareMappingList'].forEach((v) { + _specialClinicalCareMappingList.add(GetSpecialClinicalCareMappingListResponseModel.fromJson(v)); + });}, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: { + "ClinicID": clinicId, + "DoctorID":0, + "EditedBy":0 + }, + ); + } + +} diff --git a/lib/core/viewModel/PatientSearchViewModel.dart b/lib/core/viewModel/PatientSearchViewModel.dart index a0cd68d9..6b83461b 100644 --- a/lib/core/viewModel/PatientSearchViewModel.dart +++ b/lib/core/viewModel/PatientSearchViewModel.dart @@ -4,6 +4,8 @@ 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/patient/out_patient_service.dart'; import 'package:doctor_app_flutter/core/service/patient/patientInPatientService.dart'; +import 'package:doctor_app_flutter/core/service/special_clinics/special_clinic_service.dart'; +import 'package:doctor_app_flutter/models/dashboard/get_special_clinical_care_mapping_List_Respose_Model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; @@ -12,8 +14,10 @@ import 'base_view_model.dart'; class PatientSearchViewModel extends BaseViewModel { OutPatientService _outPatientService = locator(); + SpecialClinicsService _specialClinicsService = locator(); List get patientList => _outPatientService.patientList; + List get specialClinicalCareMappingList => _specialClinicsService.specialClinicalCareMappingList; List filterData = []; @@ -143,15 +147,22 @@ class PatientSearchViewModel extends BaseViewModel { List filteredInPatientItems = List(); Future getInPatientList(PatientSearchRequestModel requestModel, - {bool isMyInpatient = false}) async { + {bool isMyInpatient = false, bool isLocalBusy = false}) async { await getDoctorProfile(); - setState(ViewState.Busy); - + if(isLocalBusy) { + setState(ViewState.BusyLocal); + } else{ + setState(ViewState.Busy); + } if (inPatientList.length == 0) await _inPatientService.getInPatientList(requestModel, false); if (_inPatientService.hasError) { error = _inPatientService.error; + if(isLocalBusy) { + setState(ViewState.ErrorLocal); + } else{ setState(ViewState.Error); + } } else { // setDefaultInPatientList(); setState(ViewState.Idle); @@ -166,6 +177,9 @@ class PatientSearchViewModel extends BaseViewModel { setState(ViewState.Idle); } + + + void clearPatientList() { _inPatientService.inPatientList = []; _inPatientService.myInPatientList = []; @@ -195,4 +209,26 @@ class PatientSearchViewModel extends BaseViewModel { notifyListeners(); } } + + + getSpecialClinicalCareMappingList(clinicId, + {bool isLocalBusy = false}) async { + if (isLocalBusy) { + setState(ViewState.BusyLocal); + } else { + setState(ViewState.Busy); + } + //TODO Elham* change clinic id to dynamic + await _specialClinicsService.getSpecialClinicalCareMappingList(221); + if (_specialClinicsService.hasError) { + error = _specialClinicsService.error; + if (isLocalBusy) { + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Error); + } + } else { + setState(ViewState.Idle); + } + } } diff --git a/lib/core/viewModel/dashboard_view_model.dart b/lib/core/viewModel/dashboard_view_model.dart index fe160c3c..95028f52 100644 --- a/lib/core/viewModel/dashboard_view_model.dart +++ b/lib/core/viewModel/dashboard_view_model.dart @@ -2,6 +2,7 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/service/home/dasboard_service.dart'; +import 'package:doctor_app_flutter/core/service/special_clinics/special_clinic_service.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; import 'package:doctor_app_flutter/models/dashboard/get_special_clinical_care_List_Respose_Model.dart'; @@ -15,6 +16,7 @@ import 'base_view_model.dart'; class DashboardViewModel extends BaseViewModel { final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); DashboardService _dashboardService = locator(); + SpecialClinicsService _specialClinicsService = locator(); List get dashboardItemsList => _dashboardService.dashboardItemsList; @@ -23,7 +25,7 @@ class DashboardViewModel extends BaseViewModel { String get sServiceID => _dashboardService.sServiceID; - List get specialClinicalCareList => _dashboardService.specialClinicalCareList; + List get specialClinicalCareList => _specialClinicsService.specialClinicalCareList; Future setFirebaseNotification(ProjectViewModel projectsProvider, @@ -70,9 +72,9 @@ class DashboardViewModel extends BaseViewModel { Future getSpecialClinicalCareList() async { setState(ViewState.Busy); - await _dashboardService.getSpecialClinicalCareList(); - if (_dashboardService.hasError) { - error = _dashboardService.error; + await _specialClinicsService.getSpecialClinicalCareList(); + if (_specialClinicsService.hasError) { + error = _specialClinicsService.error; setState(ViewState.Error); } else setState(ViewState.Idle); @@ -99,4 +101,17 @@ class DashboardViewModel extends BaseViewModel { return value.toString(); } + + + bool isSpecialClinic(clinicId){ + bool isSpecial = false; + specialClinicalCareList.forEach((element) { + if(element.clinicID == 1){ + isSpecial = true; + } + }); + + return isSpecial; + + } } diff --git a/lib/locator.dart b/lib/locator.dart index 1c491b54..de493196 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -37,6 +37,7 @@ import 'core/service/patient_medical_file/sick_leave/sickleave_service.dart'; import 'core/service/patient_medical_file/soap/SOAP_service.dart'; import 'core/service/patient_medical_file/ucaf/patient-ucaf-service.dart'; import 'core/service/patient_medical_file/vital_sign/patient-vital-signs-service.dart'; +import 'core/service/special_clinics/special_clinic_service.dart'; import 'core/viewModel/DischargedPatientViewModel.dart'; import 'core/viewModel/InsuranceViewModel.dart'; import 'core/viewModel/LiveCarePatientViewModel.dart'; @@ -91,6 +92,7 @@ void setupLocator() { locator.registerLazySingleton(() => PatientMedicalReportService()); locator.registerLazySingleton(() => LiveCarePatientServices()); locator.registerLazySingleton(() => NavigationService()); + locator.registerLazySingleton(() => SpecialClinicsService()); /// View Model locator.registerFactory(() => DoctorReplayViewModel()); diff --git a/lib/models/dashboard/get_special_clinical_care_mapping_List_Respose_Model.dart b/lib/models/dashboard/get_special_clinical_care_mapping_List_Respose_Model.dart new file mode 100644 index 00000000..287f40f1 --- /dev/null +++ b/lib/models/dashboard/get_special_clinical_care_mapping_List_Respose_Model.dart @@ -0,0 +1,37 @@ +class GetSpecialClinicalCareMappingListResponseModel { + int mappingProjectID; + int clinicID; + int nursingStationID; + bool isActive; + int projectID; + String description; + + GetSpecialClinicalCareMappingListResponseModel( + {this.mappingProjectID, + this.clinicID, + this.nursingStationID, + this.isActive, + this.projectID, + this.description}); + + GetSpecialClinicalCareMappingListResponseModel.fromJson( + Map json) { + mappingProjectID = json['MappingProjectID']; + clinicID = json['ClinicID']; + nursingStationID = json['NursingStationID']; + isActive = json['IsActive']; + projectID = json['ProjectID']; + description = json['Description']; + } + + Map toJson() { + final Map data = new Map(); + data['MappingProjectID'] = this.mappingProjectID; + data['ClinicID'] = this.clinicID; + data['NursingStationID'] = this.nursingStationID; + data['IsActive'] = this.isActive; + data['ProjectID'] = this.projectID; + data['Description'] = this.description; + return data; + } +} diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index f2a8da6a..294541b0 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -69,7 +69,6 @@ class _HomeScreenState extends State { await model.getDashboard(); await model.getDoctorProfile(isGetProfile: true); await model.checkDoctorHasLiveCare(); - await model.getSpecialClinicalCareList(); }, builder: (_, model, w) => AppScaffold( @@ -356,7 +355,7 @@ class _HomeScreenState extends State { Navigator.push( context, FadePage( - page: PatientInPatientScreen(), + page: PatientInPatientScreen(specialClinic: model.specialClinicalCareList[0],), ), ); }, diff --git a/lib/screens/patients/PatientsInPatientScreen.dart b/lib/screens/patients/PatientsInPatientScreen.dart index 60446887..1d8e91b9 100644 --- a/lib/screens/patients/PatientsInPatientScreen.dart +++ b/lib/screens/patients/PatientsInPatientScreen.dart @@ -1,17 +1,27 @@ 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/viewModel/PatientSearchViewModel.dart'; +import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/models/dashboard/get_special_clinical_care_List_Respose_Model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.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_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/text_fields_utils.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'DischargedPatientPage.dart'; import 'InPatientPage.dart'; class PatientInPatientScreen extends StatefulWidget { + GetSpecialClinicalCareListResponseModel specialClinic; + + PatientInPatientScreen({Key key, this.specialClinic}); + @override _PatientInPatientScreenState createState() => _PatientInPatientScreenState(); } @@ -21,6 +31,9 @@ class _PatientInPatientScreenState extends State TabController _tabController; int _activeTab = 0; + int selectedMapId; + + @override void initState() { super.initState(); @@ -42,15 +55,23 @@ class _PatientInPatientScreenState extends State @override Widget build(BuildContext context) { - final screenSize = MediaQuery.of(context).size; + final screenSize = MediaQuery + .of(context) + .size; PatientSearchRequestModel requestModel = PatientSearchRequestModel(); + ProjectViewModel projectsProvider = Provider.of(context); + return BaseView( onModelReady: (model) async { model.clearPatientList(); + if (widget.specialClinic != null) + await model.getSpecialClinicalCareMappingList( + widget.specialClinic.clinicID); model.getInPatientList(requestModel); }, - builder: (_, model, w) => AppScaffold( + builder: (_, model, w) => + AppScaffold( baseViewModel: model, isShowAppBar: false, body: Column( @@ -72,12 +93,127 @@ class _PatientInPatientScreenState extends State ), Expanded( child: AppText( - TranslationBase.of(context).inPatient, + TranslationBase + .of(context) + .inPatient, fontSize: SizeConfig.textMultiplier * 2.8, fontWeight: FontWeight.bold, color: Color(0xFF2B353E), ), ), + if(model.specialClinicalCareMappingList.isNotEmpty && + widget.specialClinic != null) + Container( + width: MediaQuery + .of(context) + .size + .width * .3, + child: DropdownButtonHideUnderline( + child: DropdownButton( + dropdownColor: Colors.white, + iconEnabledColor: Colors.black, + isExpanded: true, + value: selectedMapId == null ? model + .specialClinicalCareMappingList[0] + .nursingStationID : selectedMapId, + iconSize: 25, + elevation: 16, + selectedItemBuilder: + (BuildContext context) { + return model + .specialClinicalCareMappingList + .map((item) { + return Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.end, + children: [ + Column( + mainAxisAlignment: + MainAxisAlignment + .center, + children: [ + Container( + padding: + EdgeInsets.all(2), + margin: + EdgeInsets.all(2), + decoration: + new BoxDecoration( + color: + Colors.red[800], + borderRadius: + BorderRadius + .circular( + 20), + ), + constraints: + BoxConstraints( + minWidth: 20, + minHeight: 20, + ), + child: Center( + child: AppText( + model + .specialClinicalCareMappingList + .length + .toString(), + color: + Colors.white, + fontSize: + projectsProvider + .isArabic + ? 10 + : 11, + textAlign: + TextAlign + .center, + ), + )), + ], + ), + AppText(item.description, + fontSize: 12, + color: Colors.black, + fontWeight: + FontWeight.bold, + textAlign: TextAlign.end), + ], + ); + }).toList(); + }, + onChanged: (newValue) async { + setState(() { + selectedMapId = newValue; + }); + model.clearPatientList(); + GifLoaderDialogUtils.showMyDialog( + context); + + PatientSearchRequestModel requestModel = PatientSearchRequestModel( + nursingStationID: selectedMapId, clinicID: 0); + await model.getInPatientList(requestModel, isLocalBusy: true); + GifLoaderDialogUtils.hideDialog( + context); + if (model.state == + ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast( + model.error); + } + }, + items: model + .specialClinicalCareMappingList + .map((item) { + return DropdownMenuItem( + child: AppText( + item.description, + textAlign: TextAlign.left, + ), + value: item.nursingStationID, + ); + }).toList(), + )), + ) ]), ), ), From 7b71bd752fd892334fa20a953ce033dd65a7ecce Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 14 Jun 2021 18:08:24 +0300 Subject: [PATCH 41/72] add to do --- lib/screens/patients/PatientsInPatientScreen.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/screens/patients/PatientsInPatientScreen.dart b/lib/screens/patients/PatientsInPatientScreen.dart index 1d8e91b9..fe908b8d 100644 --- a/lib/screens/patients/PatientsInPatientScreen.dart +++ b/lib/screens/patients/PatientsInPatientScreen.dart @@ -68,6 +68,8 @@ class _PatientInPatientScreenState extends State if (widget.specialClinic != null) await model.getSpecialClinicalCareMappingList( widget.specialClinic.clinicID); + + //TODO Elham* check why he call it without await and handel the special clinic part. model.getInPatientList(requestModel); }, builder: (_, model, w) => From 7f3ae19fd2394002b8d2407c298136b098a00a83 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Tue, 15 Jun 2021 09:42:50 +0300 Subject: [PATCH 42/72] remove todo --- lib/screens/patients/PatientsInPatientScreen.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/screens/patients/PatientsInPatientScreen.dart b/lib/screens/patients/PatientsInPatientScreen.dart index fe908b8d..1d8e91b9 100644 --- a/lib/screens/patients/PatientsInPatientScreen.dart +++ b/lib/screens/patients/PatientsInPatientScreen.dart @@ -68,8 +68,6 @@ class _PatientInPatientScreenState extends State if (widget.specialClinic != null) await model.getSpecialClinicalCareMappingList( widget.specialClinic.clinicID); - - //TODO Elham* check why he call it without await and handel the special clinic part. model.getInPatientList(requestModel); }, builder: (_, model, w) => From 1c3391baed0787bf6833599d7443104a5c08544b Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Tue, 15 Jun 2021 12:04:37 +0300 Subject: [PATCH 43/72] Scan qr code refactoring --- lib/core/service/home/scan_qr_service.dart | 41 +++++++++++++++++++++ lib/core/viewModel/scan_qr_view_model.dart | 26 +++++++++++++ lib/locator.dart | 4 ++ lib/screens/qr_reader/QR_reader_screen.dart | 5 ++- 4 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 lib/core/service/home/scan_qr_service.dart create mode 100644 lib/core/viewModel/scan_qr_view_model.dart diff --git a/lib/core/service/home/scan_qr_service.dart b/lib/core/service/home/scan_qr_service.dart new file mode 100644 index 00000000..bc6c8820 --- /dev/null +++ b/lib/core/service/home/scan_qr_service.dart @@ -0,0 +1,41 @@ +import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/core/model/patient_muse/PatientSearchRequestModel.dart'; +import 'package:doctor_app_flutter/core/service/base/base_service.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; + +class ScanQrService extends BaseService { + List myInPatientList = List(); + List inPatientList = List(); + + Future getInPatient(PatientSearchRequestModel requestModel, bool isMyInpatient) async { + hasError = false; + await getDoctorProfile(); + + if (isMyInpatient) { + requestModel.doctorID = doctorProfile.doctorID; + } else { + requestModel.doctorID = 0; + } + + await baseAppClient.post( + GET_PATIENT_IN_PATIENT_LIST, + onSuccess: (dynamic response, int statusCode) { + inPatientList.clear(); + myInPatientList.clear(); + + response['List_MyInPatient'].forEach((v) { + PatiantInformtion patient = PatiantInformtion.fromJson(v); + inPatientList.add(patient); + if (patient.doctorId == doctorProfile.doctorID) { + myInPatientList.add(patient); + } + }); + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: requestModel.toJson(), + ); + } +} diff --git a/lib/core/viewModel/scan_qr_view_model.dart b/lib/core/viewModel/scan_qr_view_model.dart new file mode 100644 index 00000000..ff934f79 --- /dev/null +++ b/lib/core/viewModel/scan_qr_view_model.dart @@ -0,0 +1,26 @@ +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/home/scan_qr_service.dart'; +import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; +import 'package:doctor_app_flutter/locator.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; + +class ScanQrViewModel extends BaseViewModel { + ScanQrService _scanQrService = locator(); + List get inPatientList => _scanQrService.inPatientList; + + Future getInPatientList(PatientSearchRequestModel requestModel, {bool isMyInpatient = false}) async { + await getDoctorProfile(); + setState(ViewState.Busy); + + await _scanQrService.getInPatient(requestModel, false); + if (_scanQrService.hasError) { + error = _scanQrService.error; + + setState(ViewState.ErrorLocal); + } else { + // setDefaultInPatientList(); + setState(ViewState.Idle); + } + } +} diff --git a/lib/locator.dart b/lib/locator.dart index 1c491b54..0b5d8c5c 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -1,10 +1,12 @@ import 'package:doctor_app_flutter/core/service/authentication_service.dart'; +import 'package:doctor_app_flutter/core/service/home/scan_qr_service.dart'; import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/hospitals_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/medical_file_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; +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'; @@ -91,6 +93,7 @@ void setupLocator() { locator.registerLazySingleton(() => PatientMedicalReportService()); locator.registerLazySingleton(() => LiveCarePatientServices()); locator.registerLazySingleton(() => NavigationService()); + locator.registerLazySingleton(() => ScanQrService()); /// View Model locator.registerFactory(() => DoctorReplayViewModel()); @@ -118,4 +121,5 @@ void setupLocator() { locator.registerFactory(() => HospitalViewModel()); locator.registerFactory(() => LiveCarePatientViewModel()); locator.registerFactory(() => PatientMedicalReportViewModel()); + locator.registerFactory(() => ScanQrViewModel()); } diff --git a/lib/screens/qr_reader/QR_reader_screen.dart b/lib/screens/qr_reader/QR_reader_screen.dart index 848b3f9a..c70563f9 100644 --- a/lib/screens/qr_reader/QR_reader_screen.dart +++ b/lib/screens/qr_reader/QR_reader_screen.dart @@ -3,6 +3,7 @@ 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/viewModel/patient_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/scan_qr_view_model.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'; @@ -25,7 +26,7 @@ class QrReaderScreen extends StatefulWidget { class _QrReaderScreenState extends State { @override Widget build(BuildContext context) { - return BaseView( + return BaseView( builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: false, @@ -74,7 +75,7 @@ class _QrReaderScreenState extends State { ); } - _scanQrAndGetPatient(BuildContext context, PatientViewModel model) async { + _scanQrAndGetPatient(BuildContext context, ScanQrViewModel model) async { /// When give qr we will change this method to get data /// var result = await BarcodeScanner.scan(); /// int patientID = get from qr result From 37e68539769ba73a3c924b564f4338d7d8a765b4 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Tue, 15 Jun 2021 12:10:04 +0300 Subject: [PATCH 44/72] add special one first calling --- .../patients/PatientsInPatientScreen.dart | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/screens/patients/PatientsInPatientScreen.dart b/lib/screens/patients/PatientsInPatientScreen.dart index 1d8e91b9..4971b636 100644 --- a/lib/screens/patients/PatientsInPatientScreen.dart +++ b/lib/screens/patients/PatientsInPatientScreen.dart @@ -65,9 +65,13 @@ class _PatientInPatientScreenState extends State return BaseView( onModelReady: (model) async { model.clearPatientList(); - if (widget.specialClinic != null) - await model.getSpecialClinicalCareMappingList( - widget.specialClinic.clinicID); + if (widget.specialClinic != null) { + await model + .getSpecialClinicalCareMappingList(widget.specialClinic.clinicID); + requestModel.nursingStationID = + model.specialClinicalCareMappingList[0].nursingStationID; + requestModel.clinicID = 0; + } model.getInPatientList(requestModel); }, builder: (_, model, w) => @@ -101,19 +105,17 @@ class _PatientInPatientScreenState extends State color: Color(0xFF2B353E), ), ), - if(model.specialClinicalCareMappingList.isNotEmpty && - widget.specialClinic != null) + if (model.specialClinicalCareMappingList.isNotEmpty && + widget.specialClinic != null && + _activeTab != 2) Container( - width: MediaQuery - .of(context) - .size - .width * .3, + width: MediaQuery.of(context).size.width * .3, child: DropdownButtonHideUnderline( child: DropdownButton( - dropdownColor: Colors.white, - iconEnabledColor: Colors.black, - isExpanded: true, - value: selectedMapId == null ? model + dropdownColor: Colors.white, + iconEnabledColor: Colors.black, + isExpanded: true, + value: selectedMapId == null ? model .specialClinicalCareMappingList[0] .nursingStationID : selectedMapId, iconSize: 25, From 883778d27813700ff6aaa82ffaf5bb95f813ab2e Mon Sep 17 00:00:00 2001 From: mosazaid Date: Tue, 15 Jun 2021 12:17:24 +0300 Subject: [PATCH 45/72] video call --- .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 41 ++- .../hmg/hmgDr/ui/VideoCallResponseListener.kt | 8 + .../hmgDr/ui/fragment/VideoCallFragment.kt | 310 +++++++++++++----- .../main/res/drawable/layout_rounded_bg.xml | 7 + .../main/res/layout/activity_video_call.xml | 96 +++--- android/app/src/main/res/values/dimens.xml | 8 +- .../viewModel/authentication_view_model.dart | 4 +- .../patient_profile_screen.dart | 1 + ...ent-profile-header-new-design-app-bar.dart | 21 +- 9 files changed, 359 insertions(+), 137 deletions(-) create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt create mode 100644 android/app/src/main/res/drawable/layout_rounded_bg.xml 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 f013d281..d595be97 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -7,6 +7,7 @@ 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.ui.VideoCallResponseListener import com.hmg.hmgDr.ui.fragment.VideoCallFragment import io.flutter.embedding.android.FlutterFragmentActivity import io.flutter.embedding.engine.FlutterEngine @@ -15,7 +16,7 @@ import io.flutter.plugin.common.MethodChannel import io.flutter.plugins.GeneratedPluginRegistrant -class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler { +class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, VideoCallResponseListener { private val CHANNEL = "Dr.cloudSolution/videoCall" private var result: MethodChannel.Result? = null @@ -67,7 +68,6 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler private fun openVideoCall(apiKey: String?, sessionId: String?, token: String?, appLang: String?, baseUrl: String?, sessionStatusModel: GetSessionStatusModel) { // val videoCallActivity = VideoCallActivity() - // val intent = Intent(this, VideoCallActivity::class.java) // intent.putExtra("apiKey", apiKey) // intent.putExtra("sessionId", sessionId) @@ -77,14 +77,23 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler // intent.putExtra("sessionStatusModel", sessionStatusModel) // startActivityForResult(intent, LAUNCH_VIDEO) + val arguments = Bundle() + arguments.putString("apiKey", apiKey) + arguments.putString("sessionId", sessionId) + arguments.putString("token", token) + arguments.putString("appLang", appLang) + arguments.putString("baseUrl", baseUrl) + arguments.putParcelable("sessionStatusModel", sessionStatusModel) + val transaction = supportFragmentManager.beginTransaction() - dialogFragment = VideoCallFragment.newInstance(Bundle()) - dialogFragment.isCancelable = false + dialogFragment = VideoCallFragment.newInstance(arguments) + dialogFragment.setCallListener(this) + dialogFragment.isCancelable = true dialogFragment.show(transaction, "dialog") } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + /* override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) var asd = ""; if (requestCode == LAUNCH_VIDEO) { @@ -108,6 +117,28 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler result?.success(callResponse) } } + }*/ + + override fun onCallFinished(resultCode: Int, intent: Intent?) { + if (resultCode == Activity.RESULT_OK) { + val result : SessionStatusModel? = intent?.getParcelableExtra("sessionStatusNotRespond") + val callResponse : HashMap = HashMap() + + val sessionStatus : HashMap = HashMap() + val gson = GsonBuilder().serializeNulls().create() + + callResponse["callResponse"] = "CallNotRespond" + val jsonRes = gson.toJson(result) + callResponse["sessionStatus"] = jsonRes + + this.result?.success(callResponse) + } + if (resultCode == Activity.RESULT_CANCELED) { + val callResponse : HashMap = HashMap() + callResponse["callResponse"] = "CallEnd" + + result?.success(callResponse) + } } diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt new file mode 100644 index 00000000..e32630b4 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt @@ -0,0 +1,8 @@ +package com.hmg.hmgDr.ui + +import android.content.Intent + +interface VideoCallResponseListener { + + fun onCallFinished(resultCode : Int, intent: Intent? = null) +} \ No newline at end of file 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 d5a5d5da..dd4613bd 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 @@ -10,39 +10,38 @@ import android.graphics.Color import android.graphics.Point import android.graphics.drawable.ColorDrawable import android.opengl.GLSurfaceView -import android.os.Bundle -import android.os.CountDownTimer -import android.os.Handler -import android.os.Looper +import android.os.* import android.util.Log import android.view.* import android.widget.* import androidx.annotation.Nullable +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.constraintlayout.widget.ConstraintSet 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.R import com.hmg.hmgDr.ui.VideoCallContract.VideoCallPresenter import com.hmg.hmgDr.ui.VideoCallContract.VideoCallView import com.hmg.hmgDr.ui.VideoCallPresenterImpl +import com.hmg.hmgDr.ui.VideoCallResponseListener import com.opentok.android.* import com.opentok.android.PublisherKit.PublisherListener import pub.devrel.easypermissions.AfterPermissionGranted import pub.devrel.easypermissions.AppSettingsDialog import pub.devrel.easypermissions.EasyPermissions import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks -import java.util.* import kotlin.math.ceil + class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.SessionListener, PublisherListener, SubscriberKit.VideoListener, VideoCallView { var isFullScreen: Boolean = true private var x_init_cord = 0 - private var y_init_cord:Int = 0 - private var x_init_margin:Int = 0 - private var y_init_margin:Int = 0 + private var y_init_cord: Int = 0 + private var x_init_margin: Int = 0 + private var y_init_margin: Int = 0 private val szWindow: Point = Point() private lateinit var mWindowManager: WindowManager private var isLeft = true @@ -58,9 +57,11 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private var mVolRunnable: Runnable? = null private var mConnectedRunnable: Runnable? = null - private var mPublisherViewContainer: FrameLayout? = null - private var mSubscriberViewContainer: RelativeLayout? = null - private var controlPanel: RelativeLayout? = null + private lateinit var mPublisherViewContainer: FrameLayout + private lateinit var mPublisherViewIcon: View + private lateinit var mSubscriberViewContainer: FrameLayout + private lateinit var mSubscriberViewIcon: ImageView + private var controlPanel: ConstraintLayout? = null private var apiKey: String? = null private var sessionId: String? = null @@ -73,7 +74,9 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private var isSpeckerClicked = false private var isMicClicked = false - private lateinit var videoCallContainer: LinearLayout + private lateinit var parentView: View + private lateinit var videoCallContainer: ConstraintLayout + private lateinit var layoutName: RelativeLayout private lateinit var mCallBtn: ImageView private lateinit var btnMinimize: ImageView private lateinit var mCameraBtn: ImageView @@ -81,6 +84,11 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private lateinit var mspeckerBtn: ImageView private lateinit var mMicBtn: ImageView + private lateinit var patientName: TextView + private lateinit var cmTimer: Chronometer + var elapsedTime: Long = 0 + var resume = false + private val progressBar: ProgressBar? = null private val countDownTimer: CountDownTimer? = null private val progressBarTextView: TextView? = null @@ -89,6 +97,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private var isConnected = false private var sessionStatusModel: GetSessionStatusModel? = null + private var videoCallResponseListener: VideoCallResponseListener? =null override fun onCreate(savedInstanceState: Bundle?) { @@ -137,16 +146,20 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } } + fun setCallListener(videoCallResponseListener: VideoCallResponseListener){ + this.videoCallResponseListener = videoCallResponseListener + } + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - val view = inflater.inflate(R.layout.activity_video_call, container, false) + parentView = inflater.inflate(R.layout.activity_video_call, container, false) - Objects.requireNonNull(requireActivity().actionBar)!!.hide() - initUI(view) +// Objects.requireNonNull(requireActivity().actionBar)!!.hide() + initUI(parentView) handleDragDialog() - return view + return parentView } override fun onPause() { @@ -170,14 +183,18 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onDestroy() { disconnectSession() + cmTimer.stop() super.onDestroy() } @SuppressLint("ClickableViewAccessibility") private fun initUI(view: View) { - videoCallContainer = view.findViewById(R.id.video_call_ll) - mPublisherViewContainer = view.findViewById(R.id.local_video_view_container) - mSubscriberViewContainer = view.findViewById(R.id.remote_video_view_container) + videoCallContainer = view.findViewById(R.id.video_call_ll) + layoutName = view.findViewById(R.id.layout_name) + mPublisherViewContainer = view.findViewById(R.id.local_video_view_container) + mPublisherViewIcon = view.findViewById(R.id.local_video_view_icon) + mSubscriberViewIcon = view.findViewById(R.id.remote_video_view_icon) + mSubscriberViewContainer = view.findViewById(R.id.remote_video_view_container) arguments?.run { apiKey = getString("apiKey") @@ -188,7 +205,27 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session sessionStatusModel = getParcelable("sessionStatusModel") } - controlPanel = view.findViewById(R.id.control_panel) + patientName = view.findViewById(R.id.patient_name) + patientName.text = sessionStatusModel!!.patientName + + cmTimer = view.findViewById(R.id.cmTimer) + cmTimer.format = "mm:ss" + cmTimer.onChronometerTickListener = Chronometer.OnChronometerTickListener { arg0: Chronometer? -> + val minutes: Long + val seconds: Long + if (!resume) { + minutes = (SystemClock.elapsedRealtime() - cmTimer.base) / 1000 / 60 + seconds = (SystemClock.elapsedRealtime() - cmTimer.base) / 1000 % 60 + elapsedTime = SystemClock.elapsedRealtime() + } else { + minutes = (elapsedTime - cmTimer.base) / 1000 / 60 + seconds = (elapsedTime - cmTimer.base) / 1000 % 60 + elapsedTime = elapsedTime + 1000 + } + Log.d(VideoCallFragment.TAG, "onChronometerTick: $minutes : $seconds") + } + + controlPanel = view.findViewById(R.id.control_panel) videoCallPresenter = VideoCallPresenterImpl(this, baseUrl) mCallBtn = view.findViewById(R.id.btn_call) mCallBtn.setOnClickListener { @@ -295,17 +332,23 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session (mPublisher!!.getView() as GLSurfaceView).setZOrderOnTop(true) } mSession!!.publish(mPublisher) + + if (!resume) { + cmTimer.base = SystemClock.elapsedRealtime() + } + cmTimer.start() } override fun onDisconnected(session: Session) { Log.d(TAG, "onDisconnected: disconnected from session " + session.sessionId) mSession = null + cmTimer.stop() } override fun onError(session: Session, opentokError: OpentokError) { Log.d(TAG, "onError: Error (" + opentokError.message + ") in session " + session.sessionId) - Toast.makeText(requireContext(), "Session error. See the logcat please.", Toast.LENGTH_LONG).show() - requireActivity().finish() +// Toast.makeText(requireContext(), "Session error. See the logcat please.", Toast.LENGTH_LONG).show() +// requireActivity().finish() } override fun onStreamReceived(session: Session, stream: Stream) { @@ -316,7 +359,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } isConnected = true subscribeToStream(stream) - videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(3, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) +// videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(3, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) } override fun onStreamDropped(session: Session, stream: Stream) { @@ -342,8 +385,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onError(publisherKit: PublisherKit?, opentokError: OpentokError) { Log.d(VideoCallFragment.TAG, "onError: Error (" + opentokError.message + ") in publisher") - Toast.makeText(requireContext(), "Session error. See the logcat please.", Toast.LENGTH_LONG).show() - requireActivity().finish() +// Toast.makeText(requireContext(), "Session error. See the logcat please.", Toast.LENGTH_LONG).show() +// requireActivity().finish() } override fun onVideoDataReceived(subscriberKit: SubscriberKit?) { @@ -367,8 +410,9 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private fun disconnectSession() { if (mSession == null) { - requireActivity().setResult(Activity.RESULT_CANCELED) - requireActivity().finish() + videoCallResponseListener?.onCallFinished(Activity.RESULT_CANCELED) +// requireActivity().setResult(Activity.RESULT_CANCELED) + dialog?.dismiss() return } if (mSubscriber != null) { @@ -385,8 +429,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } mSession!!.disconnect() countDownTimer?.cancel() - videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(16, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) - requireActivity().finish() +// videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(16, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) + dialog?.dismiss() } @@ -394,8 +438,9 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session if (sessionStatusModel.sessionStatus == 2 || sessionStatusModel.sessionStatus == 3) { val returnIntent = Intent() returnIntent.putExtra("sessionStatusNotRespond", sessionStatusModel) - requireActivity().setResult(Activity.RESULT_OK, returnIntent) - requireActivity().finish() + videoCallResponseListener?.onCallFinished(Activity.RESULT_OK, returnIntent) +// requireActivity().setResult(Activity.RESULT_OK, returnIntent) + dialog?.dismiss() } } @@ -403,7 +448,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onFailure() {} - fun onSwitchCameraClicked(view: View?) { + private fun onSwitchCameraClicked(view: View?) { if (mPublisher != null) { isSwitchCameraClicked = !isSwitchCameraClicked mPublisher!!.cycleCamera() @@ -412,11 +457,11 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } } - fun onCallClicked(view: View?) { + private fun onCallClicked(view: View?) { disconnectSession() } - fun onMinimizedClicked(view: View?) { + private fun onMinimizedClicked(view: View?) { if (isFullScreen) { dialog?.window?.setLayout( 400, @@ -429,9 +474,89 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session ) } isFullScreen = !isFullScreen + setViewsVisibility() + } + + private fun setViewsVisibility() { + initUI(parentView) + val iconSize : Int = context!!.resources.getDimension(R.dimen.video_icon_size).toInt() + val iconSizeSmall : Int = context!!.resources.getDimension(R.dimen.video_icon_size_small).toInt() + val btnMinimizeLayoutParam : ConstraintLayout.LayoutParams = btnMinimize.layoutParams as ConstraintLayout.LayoutParams + val mCallBtnLayoutParam : ConstraintLayout.LayoutParams = mCallBtn.layoutParams as ConstraintLayout.LayoutParams + +// val localPreviewMargin : Int = context!!.resources.getDimension(R.dimen.local_preview_margin_top).toInt() +// val localPreviewWidth : Int = context!!.resources.getDimension(R.dimen.local_preview_width).toInt() +// val localPreviewHeight : Int = context!!.resources.getDimension(R.dimen.local_preview_height).toInt() +// val localPreviewIconSize: Int = context!!.resources.getDimension(R.dimen.local_back_icon_size).toInt() +// val localPreviewMarginSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_margin_small).toInt() +// val localPreviewWidthSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_width_small).toInt() +// val localPreviewHeightSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_height_small).toInt() +// val localPreviewIconSmall: Int = context!!.resources.getDimension(R.dimen.local_back_icon_size_small).toInt() +// val localPreviewLayoutIconParam : FrameLayout.LayoutParams +// val localPreviewLayoutParam : RelativeLayout.LayoutParams = mPublisherViewContainer.layoutParams as RelativeLayout.LayoutParams + + val remotePreviewIconSize: Int = context!!.resources.getDimension(R.dimen.remote_back_icon_size).toInt() + val remotePreviewIconSizeSmall: Int = context!!.resources.getDimension(R.dimen.remote_back_icon_size_small).toInt() + val remotePreviewLayoutParam : FrameLayout.LayoutParams = mSubscriberViewIcon.layoutParams as FrameLayout.LayoutParams + + val constraintSet = ConstraintSet() + //layoutParam.constrain +// constraintSet. + if (isFullScreen) { + layoutName.visibility = View.VISIBLE + mCameraBtn.visibility = View.VISIBLE + mSwitchCameraBtn.visibility = View.VISIBLE + mspeckerBtn.visibility = View.VISIBLE + mMicBtn.visibility = View.VISIBLE + mPublisherViewContainer.visibility = View.VISIBLE + +// layoutParam = ConstraintLayout.LayoutParams(iconSize, iconSize) + btnMinimizeLayoutParam.width = iconSize + btnMinimizeLayoutParam.height = iconSize + mCallBtnLayoutParam.width = iconSize + mCallBtnLayoutParam.height = iconSize +// localPreviewLayoutIconParam = FrameLayout.LayoutParams(localPreviewIconSize, localPreviewIconSize) +//// localPreviewLayoutParam = RelativeLayout.LayoutParams(localPreviewWidth, localPreviewHeight) +// localPreviewLayoutParam.width = localPreviewIconSize +// localPreviewLayoutParam.height = localPreviewIconSize +// localPreviewLayoutParam.setMargins(0,localPreviewMargin, localPreviewMargin, 0) +// remotePreviewLayoutParam = FrameLayout.LayoutParams(remotePreviewIconSize, remotePreviewIconSize) + remotePreviewLayoutParam.width = remotePreviewIconSize + remotePreviewLayoutParam.height = remotePreviewIconSize + } else { + layoutName.visibility = View.GONE + mCameraBtn.visibility = View.GONE + mSwitchCameraBtn.visibility = View.GONE + mspeckerBtn.visibility = View.GONE + mMicBtn.visibility = View.GONE + mPublisherViewContainer.visibility = View.GONE + +// layoutParam = ConstraintLayout.LayoutParams(iconSizeSmall, iconSizeSmall) + btnMinimizeLayoutParam.width = iconSizeSmall + btnMinimizeLayoutParam.height = iconSizeSmall + mCallBtnLayoutParam.width = iconSizeSmall + mCallBtnLayoutParam.height = iconSizeSmall + +// localPreviewLayoutIconParam = FrameLayout.LayoutParams(localPreviewIconSmall, localPreviewIconSmall) +//// localPreviewLayoutParam = RelativeLayout.LayoutParams(localPreviewWidthSmall, localPreviewHeightSmall) +// localPreviewLayoutParam.width = localPreviewWidthSmall +// localPreviewLayoutParam.height = localPreviewWidthSmall +// localPreviewLayoutParam.setMargins(0,localPreviewMarginSmall, localPreviewMarginSmall, 0) +// remotePreviewLayoutParam = FrameLayout.LayoutParams(remotePreviewIconSizeSmall, remotePreviewIconSizeSmall) + remotePreviewLayoutParam.width = remotePreviewIconSizeSmall + remotePreviewLayoutParam.height = remotePreviewIconSizeSmall + } + +// mPublisherViewContainer.layoutParams = localPreviewLayoutParam +// mPublisherViewIcon.layoutParams = localPreviewLayoutIconParam + mSubscriberViewIcon.layoutParams = remotePreviewLayoutParam + + btnMinimize.layoutParams = btnMinimizeLayoutParam + mCallBtn.layoutParams = mCallBtnLayoutParam + } - fun onCameraClicked(view: View?) { + private fun onCameraClicked(view: View?) { if (mPublisher != null) { isCameraClicked = !isCameraClicked mPublisher!!.publishVideo = !isCameraClicked @@ -440,7 +565,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } } - fun onMicClicked(view: View?) { + private fun onMicClicked(view: View?) { if (mPublisher != null) { isMicClicked = !isMicClicked mPublisher!!.publishAudio = !isMicClicked @@ -449,7 +574,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } } - fun onSpeckerClicked(view: View?) { + private fun onSpeckerClicked(view: View?) { if (mSubscriber != null) { isSpeckerClicked = !isSpeckerClicked mSubscriber!!.subscribeToAudio = !isSpeckerClicked @@ -458,64 +583,69 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } } + @SuppressLint("ClickableViewAccessibility") - fun handleDragDialog(){ + fun handleDragDialog() { mWindowManager = requireActivity().getSystemService(Context.WINDOW_SERVICE) as WindowManager getWindowManagerDefaultDisplay() - videoCallContainer.setOnTouchListener { _, event -> - //Get Floating widget view params - //Get Floating widget view params - val layoutParams : WindowManager.LayoutParams = dialog!!.window!!.attributes - //get the touch location coordinates - val x_cord = event.rawX.toInt() - val y_cord = event.rawY.toInt() - val x_cord_Destination: Int - var y_cord_Destination: Int - - when (event.action) { - MotionEvent.ACTION_DOWN -> { - x_init_cord = x_cord - y_init_cord = y_cord - - //remember the initial position. - x_init_margin = layoutParams.x - y_init_margin = layoutParams.y - } - MotionEvent.ACTION_UP -> { - //Get the difference between initial coordinate and current coordinate - val x_diff: Int = x_cord - x_init_cord - val y_diff: Int = y_cord - y_init_cord - - y_cord_Destination = y_init_margin + y_diff - val barHeight: Int = getStatusBarHeight() - if (y_cord_Destination < 0) { + videoCallContainer.setOnTouchListener(dragListener) +// mSubscriberViewContainer.setOnTouchListener(dragListener) + } + + @SuppressLint("ClickableViewAccessibility") + val dragListener : View.OnTouchListener = View.OnTouchListener{ _, event -> + //Get Floating widget view params + //Get Floating widget view params + val layoutParams: WindowManager.LayoutParams = dialog!!.window!!.attributes + //get the touch location coordinates + val x_cord = event.rawX.toInt() + val y_cord = event.rawY.toInt() + val x_cord_Destination: Int + var y_cord_Destination: Int + + when (event.action) { + MotionEvent.ACTION_DOWN -> { + x_init_cord = x_cord + y_init_cord = y_cord + + //remember the initial position. + x_init_margin = layoutParams.x + y_init_margin = layoutParams.y + } + MotionEvent.ACTION_UP -> { + //Get the difference between initial coordinate and current coordinate + val x_diff: Int = x_cord - x_init_cord + val y_diff: Int = y_cord - y_init_cord + + y_cord_Destination = y_init_margin + y_diff + val barHeight: Int = getStatusBarHeight() + if (y_cord_Destination < 0) { // y_cord_Destination = 0 - y_cord_Destination = - -(szWindow.y - (videoCallContainer.height /*+ barHeight*/)) - } else if (y_cord_Destination + (videoCallContainer.height + barHeight) > szWindow.y) { - y_cord_Destination = - szWindow.y - (videoCallContainer.height + barHeight) - } - layoutParams.y = y_cord_Destination - - //reset position if user drags the floating view - resetPosition(x_cord) + y_cord_Destination = + -(szWindow.y - (videoCallContainer.height /*+ barHeight*/)) + } else if (y_cord_Destination + (videoCallContainer.height + barHeight) > szWindow.y) { + y_cord_Destination = + szWindow.y - (videoCallContainer.height + barHeight) } - MotionEvent.ACTION_MOVE -> { - val x_diff_move: Int = x_cord - x_init_cord - val y_diff_move: Int = y_cord - y_init_cord - x_cord_Destination = x_init_margin + x_diff_move - y_cord_Destination = y_init_margin + y_diff_move + layoutParams.y = y_cord_Destination + + //reset position if user drags the floating view + resetPosition(x_cord) + } + MotionEvent.ACTION_MOVE -> { + val x_diff_move: Int = x_cord - x_init_cord + val y_diff_move: Int = y_cord - y_init_cord + x_cord_Destination = x_init_margin + x_diff_move + y_cord_Destination = y_init_margin + y_diff_move - layoutParams.x = x_cord_Destination - layoutParams.y = y_cord_Destination + layoutParams.x = x_cord_Destination + layoutParams.y = y_cord_Destination - dialog!!.window!!.attributes = layoutParams - } + dialog!!.window!!.attributes = layoutParams } - true } + true } /* Reset position of Floating Widget view on dragging */ @@ -532,16 +662,16 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session /* Method to move the Floating widget view to Left */ private fun moveToLeft(current_x_cord: Int) { - var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes + var mParams: WindowManager.LayoutParams = dialog!!.window!!.attributes mParams.x = - (szWindow.x - current_x_cord * current_x_cord - videoCallContainer.width).toInt() + (szWindow.x - current_x_cord * current_x_cord - videoCallContainer.width).toInt() dialog!!.window!!.attributes = mParams val x = szWindow.x - current_x_cord object : CountDownTimer(500, 5) { //get params of Floating Widget view - var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes + var mParams: WindowManager.LayoutParams = dialog!!.window!!.attributes override fun onTick(t: Long) { val step = (500 - t) / 5 // mParams.x = 0 - (current_x_cord * current_x_cord * step).toInt() @@ -568,7 +698,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session // dialog!!.window!!.attributes = mParams object : CountDownTimer(500, 5) { //get params of Floating Widget view - var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes + var mParams: WindowManager.LayoutParams = dialog!!.window!!.attributes override fun onTick(t: Long) { val step = (500 - t) / 5 mParams.x = diff --git a/android/app/src/main/res/drawable/layout_rounded_bg.xml b/android/app/src/main/res/drawable/layout_rounded_bg.xml new file mode 100644 index 00000000..0c46f49b --- /dev/null +++ b/android/app/src/main/res/drawable/layout_rounded_bg.xml @@ -0,0 +1,7 @@ + + + + + + + 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 b7ca8d8d..0b3baff7 100644 --- a/android/app/src/main/res/layout/activity_video_call.xml +++ b/android/app/src/main/res/layout/activity_video_call.xml @@ -1,5 +1,6 @@ - + android:padding="@dimen/padding_space_medium" + app:layout_constraintTop_toTopOf="parent"> + tools:text="25:45" /> @@ -47,7 +50,8 @@ android:id="@+id/activity_clingo_video_call" android:layout_width="match_parent" android:layout_height="0dp" - android:layout_weight="1" + app:layout_constraintBottom_toTopOf="@id/control_panel" + app:layout_constraintTop_toBottomOf="@+id/layout_name" tools:context=".ui.VideoCallActivity"> - - + - + - + android:padding="@dimen/padding_space_big" + app:layout_constraintBottom_toBottomOf="parent"> + android:src="@drawable/call" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + android:src="@drawable/ic_mini" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + android:scaleType="centerCrop" + android:src="@drawable/video_enabled" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/btn_minimize" + app:layout_constraintTop_toTopOf="parent" + /> + android:src="@drawable/mic_enabled" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/btn_camera" + app:layout_constraintTop_toTopOf="parent" + /> - - - + android:scaleType="centerCrop" + android:src="@drawable/audio_enabled" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/btn_mic" + app:layout_constraintTop_toTopOf="parent" + /> + + + diff --git a/android/app/src/main/res/values/dimens.xml b/android/app/src/main/res/values/dimens.xml index 2d53d554..2a4d695f 100644 --- a/android/app/src/main/res/values/dimens.xml +++ b/android/app/src/main/res/values/dimens.xml @@ -3,21 +3,27 @@ 16dp 16dp 28dp + 12dp 24dp 60dp 54dp - 64dp + 52dp + 24dp 24dp 25dp 88dp + 40dp 117dp + 50dp 50dp + 25dp 100dp + 40dp 90dp diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index 58df9331..189dea42 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -254,8 +254,8 @@ class AuthenticationViewModel extends BaseViewModel { /// add  token to shared preferences in case of send activation code is success setDataAfterSendActivationSuccess(SendActivationCodeForDoctorAppResponseModel sendActivationCodeForDoctorAppResponseModel) { - print("VerificationCode : " + - sendActivationCodeForDoctorAppResponseModel.verificationCode); + print("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/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index e0053b81..d755af4a 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -17,6 +17,7 @@ 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'; import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.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'; 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 995ac57a..f2a32e63 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 @@ -21,8 +21,10 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget final bool isDischargedPatient; final bool isFromLiveCare; + final Stream videoCallDurationStream; + PatientProfileHeaderNewDesignAppBar( - this.patient, this.patientType, this.arrivalType, {this.height = 0.0, this.isInpatient=false, this.isDischargedPatient=false, this.isFromLiveCare = false}); + 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) { @@ -88,6 +90,23 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget ), ), ), + StreamBuilder( + stream: videoCallDurationStream, + builder: (BuildContext context, AsyncSnapshot snapshot) { + if(snapshot.hasData && snapshot.data != null) + return InkWell( + 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),), + ), + ); + else + return Container(); + }, + ), ]), ), Row(children: [ From fee36336d8e1967ea0cd14326980f74265500e8f Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Tue, 15 Jun 2021 14:40:11 +0300 Subject: [PATCH 46/72] fix out patient header --- lib/widgets/patients/profile/patient-profile-app-bar.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart index 1a47dd00..5cfdc1b6 100644 --- a/lib/widgets/patients/profile/patient-profile-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -273,7 +273,7 @@ class PatientProfileAppBar extends StatelessWidget ), ), - if ( patient.appointmentDate != null && patient.appointmentDate.isNotEmpty) + if ( patient.appointmentDate != null && patient.appointmentDate.isNotEmpty && !isFromLabResult) Row( mainAxisAlignment: MainAxisAlignment.start, children: [ From 3cf4ef43488466248c6aed4bbfdafca1229012e7 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Tue, 15 Jun 2021 14:57:42 +0300 Subject: [PATCH 47/72] check if special in home page --- lib/core/viewModel/dashboard_view_model.dart | 8 ++++---- lib/screens/home/home_screen.dart | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/core/viewModel/dashboard_view_model.dart b/lib/core/viewModel/dashboard_view_model.dart index 95028f52..f35a4a2a 100644 --- a/lib/core/viewModel/dashboard_view_model.dart +++ b/lib/core/viewModel/dashboard_view_model.dart @@ -103,15 +103,15 @@ class DashboardViewModel extends BaseViewModel { } - bool isSpecialClinic(clinicId){ - bool isSpecial = false; + GetSpecialClinicalCareListResponseModel getSpecialClinic(clinicId){ + GetSpecialClinicalCareListResponseModel special ; specialClinicalCareList.forEach((element) { if(element.clinicID == 1){ - isSpecial = true; + special = element; } }); - return isSpecial; + return special; } } diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 294541b0..aaf4d9b9 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -288,7 +288,7 @@ class _HomeScreenState extends State { child: ListView( scrollDirection: Axis.horizontal, children: [ - ...homePatientsCardsWidget(model), + ...homePatientsCardsWidget(model, projectsProvider), ])), SizedBox( height: 20, @@ -306,7 +306,7 @@ class _HomeScreenState extends State { ); } - List homePatientsCardsWidget(DashboardViewModel model) { + List homePatientsCardsWidget(DashboardViewModel model,projectsProvider) { colorIndex = 0; List backgroundColors = List(3); @@ -355,7 +355,8 @@ class _HomeScreenState extends State { Navigator.push( context, FadePage( - page: PatientInPatientScreen(specialClinic: model.specialClinicalCareList[0],), + page: PatientInPatientScreen(specialClinic: model.getSpecialClinic(clinicId??projectsProvider + .doctorClinicsList[0].clinicID),), ), ); }, From f76bac898bc81ca10544ed7e107c6a9e68efb2a0 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Tue, 15 Jun 2021 15:20:33 +0300 Subject: [PATCH 48/72] make clinic id dynamic --- lib/core/viewModel/PatientSearchViewModel.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/core/viewModel/PatientSearchViewModel.dart b/lib/core/viewModel/PatientSearchViewModel.dart index 6b83461b..e0ee8948 100644 --- a/lib/core/viewModel/PatientSearchViewModel.dart +++ b/lib/core/viewModel/PatientSearchViewModel.dart @@ -218,8 +218,7 @@ class PatientSearchViewModel extends BaseViewModel { } else { setState(ViewState.Busy); } - //TODO Elham* change clinic id to dynamic - await _specialClinicsService.getSpecialClinicalCareMappingList(221); + await _specialClinicsService.getSpecialClinicalCareMappingList(clinicId); if (_specialClinicsService.hasError) { error = _specialClinicsService.error; if (isLocalBusy) { From 890a356d8c4afe3e931d0a6ed77ca19c79b8b1a1 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Tue, 15 Jun 2021 15:52:28 +0300 Subject: [PATCH 49/72] video fix bugs --- .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 42 +++++++++------ .../hmg/hmgDr/ui/VideoCallResponseListener.kt | 2 + .../hmgDr/ui/fragment/VideoCallFragment.kt | 53 +++++++++++-------- .../main/res/layout/activity_video_call.xml | 40 +++----------- 4 files changed, 66 insertions(+), 71 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 d595be97..d3c58371 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -3,6 +3,7 @@ package com.hmg.hmgDr import android.app.Activity import android.content.Intent import android.os.Bundle +import android.widget.Toast import androidx.annotation.NonNull import com.google.gson.GsonBuilder import com.hmg.hmgDr.Model.GetSessionStatusModel @@ -23,7 +24,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, private var call: MethodCall? = null private val LAUNCH_VIDEO: Int = 1 - lateinit var dialogFragment: VideoCallFragment + private var dialogFragment: VideoCallFragment? = null override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { GeneratedPluginRegistrant.registerWith(flutterEngine) @@ -77,19 +78,23 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, // intent.putExtra("sessionStatusModel", sessionStatusModel) // startActivityForResult(intent, LAUNCH_VIDEO) - val arguments = Bundle() - arguments.putString("apiKey", apiKey) - arguments.putString("sessionId", sessionId) - arguments.putString("token", token) - arguments.putString("appLang", appLang) - arguments.putString("baseUrl", baseUrl) - arguments.putParcelable("sessionStatusModel", sessionStatusModel) - - val transaction = supportFragmentManager.beginTransaction() - dialogFragment = VideoCallFragment.newInstance(arguments) - dialogFragment.setCallListener(this) - dialogFragment.isCancelable = true - dialogFragment.show(transaction, "dialog") + if (dialogFragment == null){ + val arguments = Bundle() + arguments.putString("apiKey", apiKey) + arguments.putString("sessionId", sessionId) + arguments.putString("token", token) + arguments.putString("appLang", appLang) + arguments.putString("baseUrl", baseUrl) + arguments.putParcelable("sessionStatusModel", sessionStatusModel) + + val transaction = supportFragmentManager.beginTransaction() + dialogFragment = VideoCallFragment.newInstance(arguments) + dialogFragment?.let { + it.setCallListener(this) + it.isCancelable = true + it.show(transaction, "dialog") + } + } } @@ -120,6 +125,8 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, }*/ override fun onCallFinished(resultCode: Int, intent: Intent?) { + dialogFragment = null + if (resultCode == Activity.RESULT_OK) { val result : SessionStatusModel? = intent?.getParcelableExtra("sessionStatusNotRespond") val callResponse : HashMap = HashMap() @@ -132,8 +139,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, callResponse["sessionStatus"] = jsonRes this.result?.success(callResponse) - } - if (resultCode == Activity.RESULT_CANCELED) { + } else if (resultCode == Activity.RESULT_CANCELED) { val callResponse : HashMap = HashMap() callResponse["callResponse"] = "CallEnd" @@ -141,5 +147,9 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, } } + override fun errorHandle(message: String) { + Toast.makeText(this, message, Toast.LENGTH_LONG).show() + } + } diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt index e32630b4..d2ed15e0 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt @@ -5,4 +5,6 @@ import android.content.Intent interface VideoCallResponseListener { fun onCallFinished(resultCode : Int, intent: Intent? = null) + + fun errorHandle(message: String) } \ No newline at end of file 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 dd4613bd..6c07f462 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 @@ -103,8 +103,6 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onCreate(savedInstanceState: Bundle?) { requireActivity().setTheme(R.style.AppTheme) super.onCreate(savedInstanceState) - - requestPermissions() } override fun onStart() { @@ -155,8 +153,18 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session parentView = inflater.inflate(R.layout.activity_video_call, container, false) -// Objects.requireNonNull(requireActivity().actionBar)!!.hide() + // Objects.requireNonNull(requireActivity().actionBar)!!.hide() + arguments?.run { + apiKey = getString("apiKey") + sessionId = getString("sessionId") + token = getString("token") + appLang = getString("appLang") + baseUrl = getString("baseUrl") + sessionStatusModel = getParcelable("sessionStatusModel") + } initUI(parentView) + requestPermissions() + handleDragDialog() return parentView @@ -196,15 +204,6 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session mSubscriberViewIcon = view.findViewById(R.id.remote_video_view_icon) mSubscriberViewContainer = view.findViewById(R.id.remote_video_view_container) - arguments?.run { - apiKey = getString("apiKey") - sessionId = getString("sessionId") - token = getString("token") - appLang = getString("appLang") - baseUrl = getString("baseUrl") - sessionStatusModel = getParcelable("sessionStatusModel") - } - patientName = view.findViewById(R.id.patient_name) patientName.text = sessionStatusModel!!.patientName @@ -220,8 +219,9 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } else { minutes = (elapsedTime - cmTimer.base) / 1000 / 60 seconds = (elapsedTime - cmTimer.base) / 1000 % 60 - elapsedTime = elapsedTime + 1000 + elapsedTime += 1000 } + arg0?.text = "$minutes:$seconds" Log.d(VideoCallFragment.TAG, "onChronometerTick: $minutes : $seconds") } @@ -257,12 +257,19 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session // progressBar.setVisibility(View.GONE); hiddenButtons() checkClientConnected() - mSubscriberViewContainer!!.setOnTouchListener { v: View?, event: MotionEvent? -> + + mSubscriberViewContainer.setOnClickListener { controlPanel!!.visibility = View.VISIBLE mVolHandler!!.removeCallbacks(mVolRunnable!!) mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) - true } + +// mSubscriberViewContainer!!.setOnTouchListener { v: View?, event: MotionEvent? -> +// controlPanel!!.visibility = View.VISIBLE +// mVolHandler!!.removeCallbacks(mVolRunnable!!) +// mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) +// true +// } if (appLang == "ar") { progressBarLayout!!.layoutDirection = View.LAYOUT_DIRECTION_RTL } @@ -347,8 +354,9 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onError(session: Session, opentokError: OpentokError) { Log.d(TAG, "onError: Error (" + opentokError.message + ") in session " + session.sessionId) -// Toast.makeText(requireContext(), "Session error. See the logcat please.", Toast.LENGTH_LONG).show() -// requireActivity().finish() + + videoCallResponseListener?.errorHandle("onError: Error (" + opentokError.message + ") in session ") + dialog?.dismiss() } override fun onStreamReceived(session: Session, stream: Stream) { @@ -385,8 +393,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onError(publisherKit: PublisherKit?, opentokError: OpentokError) { Log.d(VideoCallFragment.TAG, "onError: Error (" + opentokError.message + ") in publisher") -// Toast.makeText(requireContext(), "Session error. See the logcat please.", Toast.LENGTH_LONG).show() -// requireActivity().finish() + videoCallResponseListener?.errorHandle("onError: Error (" + opentokError.message + ") in publisher") + dialog?.dismiss() } override fun onVideoDataReceived(subscriberKit: SubscriberKit?) { @@ -408,6 +416,11 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session mSession!!.subscribe(mSubscriber) } + override fun dismiss() { + videoCallResponseListener?.onCallFinished(1000) + super.dismiss() + } + private fun disconnectSession() { if (mSession == null) { videoCallResponseListener?.onCallFinished(Activity.RESULT_CANCELED) @@ -478,7 +491,6 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } private fun setViewsVisibility() { - initUI(parentView) val iconSize : Int = context!!.resources.getDimension(R.dimen.video_icon_size).toInt() val iconSizeSmall : Int = context!!.resources.getDimension(R.dimen.video_icon_size_small).toInt() val btnMinimizeLayoutParam : ConstraintLayout.LayoutParams = btnMinimize.layoutParams as ConstraintLayout.LayoutParams @@ -553,7 +565,6 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session btnMinimize.layoutParams = btnMinimizeLayoutParam mCallBtn.layoutParams = mCallBtnLayoutParam - } private fun onCameraClicked(view: View?) { 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 0b3baff7..586f5b60 100644 --- a/android/app/src/main/res/layout/activity_video_call.xml +++ b/android/app/src/main/res/layout/activity_video_call.xml @@ -54,30 +54,6 @@ app:layout_constraintTop_toBottomOf="@+id/layout_name" tools:context=".ui.VideoCallActivity"> - - - - - - + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toTopOf="parent" /> From bc661a6f38ada1f1470fc175cf334a578a67b4f0 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Tue, 15 Jun 2021 16:56:51 +0300 Subject: [PATCH 50/72] fix bugs --- .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 47 +++++++++++------- .../com/hmg/hmgDr/ui/VideoCallActivity.java | 2 +- .../hmgDr/ui/fragment/VideoCallFragment.kt | 23 +++++---- android/app/src/main/res/drawable/call.png | Bin 13229 -> 21324 bytes .../app/src/main/res/drawable/camera_back.png | Bin 0 -> 6409 bytes .../src/main/res/drawable/camera_front.png | Bin 0 -> 7100 bytes android/app/src/main/res/drawable/expand.png | Bin 0 -> 5366 bytes .../src/main/res/drawable/flip_disapled.png | Bin 6138 -> 0 bytes .../src/main/res/drawable/flip_enabled.png | Bin 6753 -> 0 bytes android/app/src/main/res/drawable/ic_mini.xml | 16 ------ .../src/main/res/drawable/mic_disabled.png | Bin 5783 -> 6537 bytes .../app/src/main/res/drawable/mic_enabled.png | Bin 6020 -> 5904 bytes .../app/src/main/res/drawable/reducing.png | Bin 0 -> 4953 bytes .../main/res/drawable/video_disanabled.png | Bin 5113 -> 6438 bytes .../src/main/res/drawable/video_enabled.png | Bin 5338 -> 5715 bytes .../main/res/layout/activity_video_call.xml | 29 +++++------ android/app/src/main/res/values/dimens.xml | 2 +- 17 files changed, 60 insertions(+), 59 deletions(-) create mode 100644 android/app/src/main/res/drawable/camera_back.png create mode 100644 android/app/src/main/res/drawable/camera_front.png create mode 100644 android/app/src/main/res/drawable/expand.png delete mode 100644 android/app/src/main/res/drawable/flip_disapled.png delete mode 100644 android/app/src/main/res/drawable/flip_enabled.png delete mode 100644 android/app/src/main/res/drawable/ic_mini.xml create mode 100644 android/app/src/main/res/drawable/reducing.png 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 d3c58371..9d9581fe 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -43,27 +43,36 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, this.result = result this.call = call - if (call.method == "openVideoCall") { - val apiKey = call.argument("kApiKey") - val sessionId = call.argument("kSessionId") - val token = call.argument("kToken") - val appLang = call.argument("appLang") - val baseUrl = call.argument("baseUrl") + when (call.method) { + "openVideoCall" -> { + val apiKey = call.argument("kApiKey") + val sessionId = call.argument("kSessionId") + val token = call.argument("kToken") + val appLang = call.argument("appLang") + val baseUrl = call.argument("baseUrl") - // Session Status model - val VC_ID = call.argument("VC_ID") - val tokenID = call.argument("TokenID") - val generalId = call.argument("generalId") - val doctorId = call.argument("DoctorId") - val patientName = call.argument("patientName") + // Session Status model + val VC_ID = call.argument("VC_ID") + val tokenID = call.argument("TokenID") + val generalId = call.argument("generalId") + val doctorId = call.argument("DoctorId") + val patientName = call.argument("patientName") - val sessionStatusModel = GetSessionStatusModel(VC_ID, tokenID, generalId, doctorId, patientName) + val sessionStatusModel = GetSessionStatusModel(VC_ID, tokenID, generalId, doctorId, patientName) - openVideoCall(apiKey, sessionId, token, appLang, baseUrl, sessionStatusModel) + openVideoCall(apiKey, sessionId, token, appLang, baseUrl, sessionStatusModel) - } else { - result.notImplemented() + } + "closeVideoCall" -> { + dialogFragment?.onCallClicked() + } + "onCallConnected"->{ + + } + else -> { + result.notImplemented() + } } } @@ -94,6 +103,9 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, it.isCancelable = true it.show(transaction, "dialog") } + } else if (!dialogFragment!!.isVisible){ + val transaction = supportFragmentManager.beginTransaction() + dialogFragment!!.show(transaction, "dialog") } } @@ -148,7 +160,8 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, } override fun errorHandle(message: String) { - Toast.makeText(this, message, Toast.LENGTH_LONG).show() + dialogFragment = null +// Toast.makeText(this, message, Toast.LENGTH_LONG).show() } diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java index 0fb061f1..daf372ed 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java @@ -415,7 +415,7 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi if (mPublisher != null) { isSwitchCameraClicked = !isSwitchCameraClicked; mPublisher.cycleCamera(); - int res = isSwitchCameraClicked ? R.drawable.flip_disapled : R.drawable.flip_enabled; + int res = isSwitchCameraClicked ? R.drawable.camera_front : R.drawable.camera_back; mSwitchCameraBtn.setImageResource(res); } } 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 6c07f462..e0a92206 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 @@ -229,7 +229,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session videoCallPresenter = VideoCallPresenterImpl(this, baseUrl) mCallBtn = view.findViewById(R.id.btn_call) mCallBtn.setOnClickListener { - onCallClicked(it) + onCallClicked() } btnMinimize = view.findViewById(R.id.btn_minimize) btnMinimize.setOnClickListener { @@ -355,8 +355,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onError(session: Session, opentokError: OpentokError) { Log.d(TAG, "onError: Error (" + opentokError.message + ") in session " + session.sessionId) - videoCallResponseListener?.errorHandle("onError: Error (" + opentokError.message + ") in session ") - dialog?.dismiss() + videoCallResponseListener?.errorHandle("Error (" + opentokError.message + ") in session ") +// dialog?.dismiss() } override fun onStreamReceived(session: Session, stream: Stream) { @@ -393,8 +393,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onError(publisherKit: PublisherKit?, opentokError: OpentokError) { Log.d(VideoCallFragment.TAG, "onError: Error (" + opentokError.message + ") in publisher") - videoCallResponseListener?.errorHandle("onError: Error (" + opentokError.message + ") in publisher") - dialog?.dismiss() + videoCallResponseListener?.errorHandle("Error (" + opentokError.message + ") in publisher") +// dialog?.dismiss() } override fun onVideoDataReceived(subscriberKit: SubscriberKit?) { @@ -465,12 +465,12 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session if (mPublisher != null) { isSwitchCameraClicked = !isSwitchCameraClicked mPublisher!!.cycleCamera() - val res = if (isSwitchCameraClicked) R.drawable.flip_disapled else R.drawable.flip_enabled - mSwitchCameraBtn!!.setImageResource(res) + val res = if (isSwitchCameraClicked) R.drawable.camera_front else R.drawable.camera_back + mSwitchCameraBtn.setImageResource(res) } } - private fun onCallClicked(view: View?) { + fun onCallClicked() { disconnectSession() } @@ -487,6 +487,9 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session ) } isFullScreen = !isFullScreen + + val res = if (isFullScreen) R.drawable.reducing else R.drawable.expand + btnMinimize.setImageResource(res) setViewsVisibility() } @@ -518,7 +521,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session layoutName.visibility = View.VISIBLE mCameraBtn.visibility = View.VISIBLE mSwitchCameraBtn.visibility = View.VISIBLE - mspeckerBtn.visibility = View.VISIBLE +// mspeckerBtn.visibility = View.VISIBLE mMicBtn.visibility = View.VISIBLE mPublisherViewContainer.visibility = View.VISIBLE @@ -539,7 +542,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session layoutName.visibility = View.GONE mCameraBtn.visibility = View.GONE mSwitchCameraBtn.visibility = View.GONE - mspeckerBtn.visibility = View.GONE +// mspeckerBtn.visibility = View.GONE mMicBtn.visibility = View.GONE mPublisherViewContainer.visibility = View.GONE diff --git a/android/app/src/main/res/drawable/call.png b/android/app/src/main/res/drawable/call.png index fc00f4f942d7ef38336bf493a5e9ba2980692c55..52f8e267234d686e31be8a6e1b44287ab98364db 100644 GIT binary patch literal 21324 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 F@_+AV*hT;V literal 13229 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

*Md~6?Fz~6 zzsQ)=AsN)tmj4qmzOK4w*%;#<-M~yk%&+g{f$dc_+OBy)0BpCtlr&Bu-!3Bs<}4*f zZfoVhWSn-iuJyX^*p?C|nfOHjOt+U6dPAM~qLEnd#eDg>SW!QtLVVJ;4+( z#iu`WLE+kwkutepQjY+H*p8`kmPsRL7df6& z0S_-LB+~20W%oq7nX3*aIRZ>!qr1{QX-aZUq_|Mmpr*t)tb(4eE6majfd~*dFJjb& z)Xp(R(MT1z*0F){Me8Z)j@?Uu<97!H9}zT1`tWi$lBK;UBTyN#`BMGQ(+1uXK!yoahWIF>O91ir|9wpC+V6C*GELmgxN zU3e>iEOXQd;G_6zYgvgHVj$bmSs67k1VTpOQtqp*ZCr^M)S?PM(ZL4dts%D?210oDp>jJ)s< zbmVs%CWb%=2;htOWGCrN3^9|D|9jGyf9cl=M7uc{1n|LkbD!*FRA*vPy9{CHt^KyT z)1$DPJs@zoYY0`?;Ds0zCW9b`ZA~wbwd2qTe3kp4mwLSsBe&*V9qs@4d3iKeNDBn; zIl_5w;*}U;>`htrzBlWvAVZ)T0`JTBynZ2jB?fJffxIc5*Y21Y0z)9cYc{>Vo!>h# zawOQFGX2-EL!e`ItR({Y*hhV|ycc4K!M9}WJ5sORTOR;enb9JEZ@nX5>t&gs7h(Xl z3}&I_f)tXN7y>>Kz^5+cKIXIBX<5AygBoNw)3;t{3#OLa$+{vy5Aj~^TfJe>D>1NI z4PanoThx1dglktYTgkl-w&zjoofuT8hOqeOe2MP7VfNV&s6c?tfge{~_kL**V&qm| z)N$eeDSK~`6__dl_|9N!WP=eyOeZ#ErmE9+;8dTwwabYB)3UwIKvmT|7%`|^*T_ian8H@b$1! zh(YT`j(c_B4eAf_*~Ac-Lx8D%dJ2B;Gq{XK3|cC35XwC#-Qcr{A&?`$bS!HXqb&}P zN(?{{Ik4fV^f9T4A;1gLMqd;jofw55h#*hv{3pd{JFX=HpNbSr>yIwM5CbGcj;D0^ z>FB7K0b?NWkw`Jf;$4%*1w{-D7CC;b!_TD*&P~!sfWb8{T@LDf$iWc79M1^4=;Ac=t=h#c6)xZ`m?n!Fc0{^hs%yZIIom3xnz_QeK;RE4Ic) z?NlPj{Q~@7qz}ageB$=F4`7>5H|7lNw#%F7dBPlo16oQAgr1*{$RIma_y^nh$CKu z5X?4xEJ6ggdff$=WF1EYVb+SlIV zD4wJULRdw3MVMuagat6wM;7NG1V12RJh3*icEl(@S&@Y4U4H+;K;8CX-2sQS2L{x< z^)Jcs!<}Zj|E@JL%Fu`;59l)lLDy|P1Oi-@cK-j^DkBLoVpKdvk>s#0(~~?RO?5_# znI+!F!OI7t+Q%fDdlw^y1LAxxE#Ae5(E?Ht z1-uBkHlzhvLY)F;_6P!?kl~-}Hh@-}R~942%Fx}pQDk9ei_MJlI@CCY@c{$o85Ifa z{lEfcRWV|$id@ZoA`CrAK^Dlv=Ryg`=Ff|@6&B9;wkOQtIDgJ(oE{>4W8sic=t2G; X_h{;p&xF^300000NkvXXu0mjfo)PYq literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable/camera_front.png b/android/app/src/main/res/drawable/camera_front.png new file mode 100644 index 0000000000000000000000000000000000000000..332ab0f54dc44ca81ed878c6788b6accf5b35039 GIT binary patch literal 7100 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 M07*qoM6N<$f_}5^H~;_u diff --git a/android/app/src/main/res/drawable/flip_enabled.png b/android/app/src/main/res/drawable/flip_enabled.png deleted file mode 100644 index 152dc10e559c1d207f693225258f9a4ca77723f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6753 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 diff --git a/android/app/src/main/res/drawable/ic_mini.xml b/android/app/src/main/res/drawable/ic_mini.xml deleted file mode 100644 index 29df8da2..00000000 --- a/android/app/src/main/res/drawable/ic_mini.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - diff --git a/android/app/src/main/res/drawable/mic_disabled.png b/android/app/src/main/res/drawable/mic_disabled.png index 3603df754eb3df74c1cf7730a90df21bfa5f7337..266cb6c72418b5aba18b32c421c2b4e75f05e47e 100644 GIT binary patch literal 6537 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 VdluGjNo@cC002ovPDHLkV1l9-OF94m diff --git a/android/app/src/main/res/drawable/mic_enabled.png b/android/app/src/main/res/drawable/mic_enabled.png index 5d9aa6770cc43554a3767cf6b1c45fd3a8851410..ef7617f7ac43e7d7f55f48bcc1df718661b48f00 100644 GIT binary patch literal 5904 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 Bb}|3} diff --git a/android/app/src/main/res/drawable/reducing.png b/android/app/src/main/res/drawable/reducing.png new file mode 100644 index 0000000000000000000000000000000000000000..59f2c9e6faa03d35596a52689b19f99db9e09036 GIT binary patch literal 4953 zcmYLNcTm&K(+`mZ_)v~<>4pG-(4|=@Qp83L5Ksgu(m@ElCDMBf zsFX;ND!nM86e-db@Q44r@9gaD-rZ+z_ilFgZtexf=q4+`2Y^5zR$U!U?5U*vV@Bv{ zyXZVubSmh4us78~Z~OU|Pdf_E7P>Bmh9JpPoe@MAaSufQ4|2+UrwjstN#Oq*p^?t~ zzy5EM>%lZ52*fd&V=1M$;O)c? zZou4nN{7gizWPqOXJy?cJQxu6?PBbQjLU7Ya*VYMIa zO2yQo#*224O{;#!6t~9LRdiahn|XKT{52wwOR zgs_O`f2_-P>S)@JJ?F3+4LcHswF@wkMCbDp@pm&hR=v7#O?1aNV~b@};OwIJKg^V(Z&1jXj^vJn*`crof@dKzQnPZl^TV10{&KrzeN6EVG z-WYl&pBf{H@q1a-ND)7uPOBn(Yq~7)b%?OekG=ecZ;!PLq#(<4=^l>SzwqxLaHO-q z&>bCY1IT&m6q$Mn;<>i0;&NOu=+1Gv(v`q0Ov>U(Zt2?jPHgbH+FHdobdxHbje8N=&X%3?FoKGObNV>(@=pH?|u&&kA#ng3ozP zv+AZhEckqck)~BjWv@+6y5$Dvuw1^D>BX_{k$B_L#%d18dHHD~#kg}8%Am!2+ds^U z!v#D=Rx^O${swFCzU1A&S%-$?u&}q?oUU`)fAt(7yZDAxa$TP6D}tWUV(Q{<7jJOf zPC9Xch+Bvkxq21UqnsTc7o1YL8kMeLN zOTt%4ztAI}S8S0Sk;5kseQo{U11u%f7Z_;ntcVg)Z-xo7@2M4F@QO?X?^I%;xt69F zO<7d8Umv9?raR6TGcS;+wZy4ib(e&^9o1Zw7uyHqk*HrKUk_@ppYD_X+<-0-xs^|< z9FA=Pm&)?eTsC^&OOBJpRB5Imvx<-C^|8TQaF>$(+F8LAa<aZ~aDDbxZsxlcaki%C@=NPdkTh$BHb^y0Gv(#6Iq&V6xu8B#4O-Xb#N}Jn zD^9tIzs`r|JU?c(7|jnebFnp6unC|^y#jqaFJw?_|42l1IU&a&%bi0|e4`qZexxnl zI8j3x)1TZe{5exK>todLC$~d6^?N+A?JvdB`TNF<{KbQ2`r)1F-Wu1$qhTe#d$9=i zK3W@+_tEoQtOkE{jr*D*+!&$3Th_8~ zgn4+aw77c9`Thfi+|a_rWJSd_8-c!;S3U(-w)lJ?Sz^UXGffaxRIF$7KNEHeY%9n z%N=?cQ#hJe^~kXbtdE)ZNIazZ3QD5mWKFede%6W>eZPL`G>?>2saE%WNh3I|{EDZA z@NO%@BT^CIkjmZ0oVBm9 zp0C)j*Kt5u3e1(%m<4|+FmKQ)UcV;t^+qZy#yU4j+<#7)H@+39Z3_GV9e%O3(jsN7 zy!AWNW-s(QxxU_YR7+#X{BZB{Mmyt1X8pvdZF8%6GnRwy4{eXTkS|{S#a7+TO=A|? zK}TInuF$sR#s}F5t2BTo{%Yn&q0sowP^3OlNW#Q9 zEuanzv?nEj!$m0HD;Px9`HWVxdE%=x8H(}OTAHsLE1m6(&D)k5Gx6rpS?ev+mz}wT zc&b787D|g6#Wu5RrpmtCP7o2m zTWRI(xDkE?pN4F3(SJGC*IJaUlYfe~xySt~^Su=K&h(LGNBr2xl5rZB(S-my1aT1Q1`7X16v-cnZOY}Qr=HH{`WU&u@q`9Q$dez32t7D^l2xp>W!X^PundSLnCYrxU}GN%xG7D z69RG-mcFd|XDvYXa)#ZEjp22T(J$Qg%%X&K8tWNHZffUv&c z%FIQ@*MSXT^)8sS?nR%Zx6~S|{k^@`WMEy`_L;HgNhz$J>B0zdd^bz}#1%rO(n0=3 z*!V3)l2K^ccfO3OFq7XbDNCe*$Y?O^GxDe4MEXzZ)ERhl)%Mt$cTH;czkqU!9A2E7 zQYv20FA?)v4D9ECy0YqpVSlH6nQvR+_?bo9nd6S#VihE2N?Z9sEG(aY_WeFCagN|T`5O)<|O}_M{t#oB)kajw}9NdO19|%JqYQcgk!3^+msHlPS))N}K z_$Z(ln9o{!>`nQMWUQPMvno;QuY)rJZsnfr3CAU!-gp8LRo)(g#y`2|xrc%mK|ciQ z<=<5)mx9P0aaIPFYu}!OpN#)I*l`E@0BXgjZ_EJ-wx^YX9dd%>T($FcyJzBXe=%i| zoyBdO3wb{`Ok2Fimt)rvUSn;RG+8tV< z6G`+l2)A|8i0^3Qfz(X`&4rs|{`5LQHIbktXC#FVwkBnZtL0d`_ zWo^?F-;lyei_N@`DP4_B&uhLIcy8`8tv4)MVGGVTa7C+~^HNZ*X#q2p_8Ckk!?ADi zI$yKkERmW#gO|c9Teg$@lm{5a?-~%VwFOc>9i$a_{ke{kA%Gv69v4a=qwm9Hvl;Q( zABHX2-^npRF3A(adgY*^NFTJ-EmtOoC$A~sgoSN)>>L0)*B$j`l8`DVzu$nf7lsrW zT2gL*1`=Y6t0tdWJLib6P3_@=EB|;+Sy+Y&b2OYQA1AB50y4~aUEInOYoNq&-wTbA z@?$sd`Y*z3pV;z$}-rF3R{j7)`N$Os;XCk;JwZ z4)GS86@L1n8S5v7HEnSY%{^|clCA`Qm7wymXYDoENMkgSqxe;UFcqe~8XPGUELcL` z^X7a;P!CB2C1v&c3Rp1o1?ai}{%>U)w>a5shUU&Ecn-%@AHUTH`$xlhFmyB#=c+m_ zI<5CZ^vb!^F&79HV{ay=F|qb06G@5%L>VI_fR+}YZ;a$%ngjB+arJX3P;A_>X|`6T z`Sj|mya@1tsPV_!rWp0kA~Q=vg;k;F(lw{)^L#0pe3Sn_Se#psv(4=w0TV(|V9&FT z+)(w!5aRMd7J05ai$Y}t{K=IOW&ATxI-;p$yTOAOlSWaQem51wA)ES8tBZGKFddxs z9Fyig&-nWF;{oe)B7!Wbm1wl_msGjUO!bYpK_M;AX*`NL(EWy2i6JyZ{R@PdjjNnx z=+UA;?FUJSYoG@13p4;Dk3bz0q@Iw zje{%VrJJnBzo+#i-5lkh?4uS2kWp-|g6;l4oq$i%ztv(5DlM0tNQgRn#ge`%AmYHI z3JeG4%iB;oV&`2_U@*;dQjhO%XLPvx*Wn3gfK7d1gE3w=f?JFMV%(v3Nc9fekVCP< zke#~Pt1~576()>MhP@)WPlBj?;9=DaHb^cM({)(8$csU8g+S~eS&+F8wbl>|;?51U zEY045Gxar?NYBhQw3E`|MO+*zygCtX5`38>&~h;Yp?jZvaUuk1zaD2V4!avau~Y^! zB=19X;;Z^zLx|o&7C)Gji#_G%+^fujJ?ylnmKXGf;-UE%1M2mXfiS5dtGubHH^8T6 zC22Lw*oiwF!hn`t>_!fK(2t1C%&y)6VTs zGFVXE1eIz_vBA1P^x}Bwd_D08xM~0${N>PDCF!R<^9C5^@0>y zf)*N_t(>apcvj-zTe*5ly;b8AX-R8#gl_Lnbb3pcWBN5D(LP&OdxNLlhDMY*t{vgq zak7CS@Ow@*Jtx9y67=U}7LzaYq&WxblGzJpl4emZ2bE*eC*8ts#w4<;G1@1q^-QnL z>Yw8VEL~Ds&eLl>U)U0h`Ie~;Xo(%xK3QB?cEJL%;)5$kb$0DML{fXO%|d-!a* zSM>_9m!$SX2A&SAE8l&#`Fbe@m(>hZ5T%!7+AVt5G9i4xM~>?Oi0$ZA54X3D z@!im&`C>*s{-AXllwJ*CxOqagpDZ1cVa-thU&^I5p9K{(qQ)1 zzOVJ}S67<~dVF*<@N1-^Z{B~it44XZUjbF(J;-$-)!H`+(sw#EdL?e4dr2(9tI~0R zFjRp#_<%*hp!9arNyE6gQ~}|F;ldr6GPjQ^&|{oEW4P0tyg6T0-QP1)kzeTilj-39 PzPNO?j5Ob>+lTxQOg$37 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable/video_disanabled.png b/android/app/src/main/res/drawable/video_disanabled.png index 5c20c7bdecf06cb8401b40b1a27bce46cf35c4a9..d6ccbe7ad12d75da1c17e054c8af03e00273c8ef 100644 GIT binary patch literal 6438 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 diff --git a/android/app/src/main/res/drawable/video_enabled.png b/android/app/src/main/res/drawable/video_enabled.png index 23331e3083cbd75a5c17e37bbdd3e89a291141f7..6fcbe75041fb80538006600a8620f7081c215d2d 100644 GIT binary patch literal 5715 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 Becu28 literal 5338 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 he`HdmC}gyD$L5b3dLYnWBmD1P5u&cAR- @@ -89,18 +90,6 @@ android:src="@drawable/video_off_fill" /> - - @@ -152,6 +141,17 @@ app:layout_constraintStart_toEndOf="@id/btn_camera" app:layout_constraintTop_toTopOf="parent" /> + + diff --git a/android/app/src/main/res/values/dimens.xml b/android/app/src/main/res/values/dimens.xml index 2a4d695f..0694f5f4 100644 --- a/android/app/src/main/res/values/dimens.xml +++ b/android/app/src/main/res/values/dimens.xml @@ -29,7 +29,7 @@ 14sp 16sp - 24sp + 22sp 4dp From 259a63384e658cbaf18a722c57f9d234e2b363b9 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 16 Jun 2021 09:53:28 +0300 Subject: [PATCH 51/72] fix draggable bugs --- .../com/hmg/hmgDr/ui/VideoCallActivity.java | 5 +- .../hmgDr/ui/fragment/VideoCallFragment.kt | 68 ++++++++++-------- ...ideo_disanabled.png => video_disabled.png} | Bin lib/config/config.dart | 4 +- 4 files changed, 42 insertions(+), 35 deletions(-) rename android/app/src/main/res/drawable/{video_disanabled.png => video_disabled.png} (100%) diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java index daf372ed..75590b76 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java @@ -20,7 +20,6 @@ import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; -import android.widget.Toast; import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel; import com.hmg.hmgDr.Model.GetSessionStatusModel; @@ -63,7 +62,7 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi private Runnable mVolRunnable, mConnectedRunnable; private FrameLayout mPublisherViewContainer; - private RelativeLayout mSubscriberViewContainer; + private FrameLayout mSubscriberViewContainer; private RelativeLayout controlPanel; private String apiKey; @@ -432,7 +431,7 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi if (mPublisher != null) { isCameraClicked = !isCameraClicked; mPublisher.setPublishVideo(!isCameraClicked); - int res = isCameraClicked ? R.drawable.video_disanabled : R.drawable.video_enabled; + int res = isCameraClicked ? R.drawable.video_disabled : R.drawable.video_enabled; mCameraBtn.setImageResource(res); } } 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 e0a92206..95f54ca8 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 @@ -17,6 +17,7 @@ import android.widget.* import androidx.annotation.Nullable import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet +import androidx.core.view.GestureDetectorCompat import androidx.fragment.app.DialogFragment import com.hmg.hmgDr.Model.GetSessionStatusModel import com.hmg.hmgDr.Model.SessionStatusModel @@ -97,8 +98,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private var isConnected = false private var sessionStatusModel: GetSessionStatusModel? = null - private var videoCallResponseListener: VideoCallResponseListener? =null - + private var videoCallResponseListener: VideoCallResponseListener? = null + private lateinit var mDetector: GestureDetectorCompat override fun onCreate(savedInstanceState: Bundle?) { requireActivity().setTheme(R.style.AppTheme) @@ -144,12 +145,12 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } } - fun setCallListener(videoCallResponseListener: VideoCallResponseListener){ + fun setCallListener(videoCallResponseListener: VideoCallResponseListener) { this.videoCallResponseListener = videoCallResponseListener } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle?): View? { + savedInstanceState: Bundle?): View { parentView = inflater.inflate(R.layout.activity_video_call, container, false) @@ -166,10 +167,12 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session requestPermissions() handleDragDialog() + mDetector = GestureDetectorCompat(context, MyGestureListener { showControlPanelTemporarily() }) return parentView } + override fun onPause() { super.onPause() if (mSession == null) { @@ -258,18 +261,6 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session hiddenButtons() checkClientConnected() - mSubscriberViewContainer.setOnClickListener { - controlPanel!!.visibility = View.VISIBLE - mVolHandler!!.removeCallbacks(mVolRunnable!!) - mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) - } - -// mSubscriberViewContainer!!.setOnTouchListener { v: View?, event: MotionEvent? -> -// controlPanel!!.visibility = View.VISIBLE -// mVolHandler!!.removeCallbacks(mVolRunnable!!) -// mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) -// true -// } if (appLang == "ar") { progressBarLayout!!.layoutDirection = View.LAYOUT_DIRECTION_RTL } @@ -474,7 +465,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session disconnectSession() } - private fun onMinimizedClicked(view: View?) { + private fun onMinimizedClicked(view: View?) { if (isFullScreen) { dialog?.window?.setLayout( 400, @@ -494,10 +485,10 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } private fun setViewsVisibility() { - val iconSize : Int = context!!.resources.getDimension(R.dimen.video_icon_size).toInt() - val iconSizeSmall : Int = context!!.resources.getDimension(R.dimen.video_icon_size_small).toInt() - val btnMinimizeLayoutParam : ConstraintLayout.LayoutParams = btnMinimize.layoutParams as ConstraintLayout.LayoutParams - val mCallBtnLayoutParam : ConstraintLayout.LayoutParams = mCallBtn.layoutParams as ConstraintLayout.LayoutParams + val iconSize: Int = context!!.resources.getDimension(R.dimen.video_icon_size).toInt() + val iconSizeSmall: Int = context!!.resources.getDimension(R.dimen.video_icon_size_small).toInt() + val btnMinimizeLayoutParam: ConstraintLayout.LayoutParams = btnMinimize.layoutParams as ConstraintLayout.LayoutParams + val mCallBtnLayoutParam: ConstraintLayout.LayoutParams = mCallBtn.layoutParams as ConstraintLayout.LayoutParams // val localPreviewMargin : Int = context!!.resources.getDimension(R.dimen.local_preview_margin_top).toInt() // val localPreviewWidth : Int = context!!.resources.getDimension(R.dimen.local_preview_width).toInt() @@ -512,7 +503,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session val remotePreviewIconSize: Int = context!!.resources.getDimension(R.dimen.remote_back_icon_size).toInt() val remotePreviewIconSizeSmall: Int = context!!.resources.getDimension(R.dimen.remote_back_icon_size_small).toInt() - val remotePreviewLayoutParam : FrameLayout.LayoutParams = mSubscriberViewIcon.layoutParams as FrameLayout.LayoutParams + val remotePreviewLayoutParam: FrameLayout.LayoutParams = mSubscriberViewIcon.layoutParams as FrameLayout.LayoutParams val constraintSet = ConstraintSet() //layoutParam.constrain @@ -574,7 +565,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session if (mPublisher != null) { isCameraClicked = !isCameraClicked mPublisher!!.publishVideo = !isCameraClicked - val res = if (isCameraClicked) R.drawable.video_disanabled else R.drawable.video_enabled + val res = if (isCameraClicked) R.drawable.video_disabled else R.drawable.video_enabled mCameraBtn!!.setImageResource(res) } } @@ -604,12 +595,13 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session getWindowManagerDefaultDisplay() videoCallContainer.setOnTouchListener(dragListener) -// mSubscriberViewContainer.setOnTouchListener(dragListener) + mSubscriberViewContainer.setOnTouchListener(dragListener) } @SuppressLint("ClickableViewAccessibility") - val dragListener : View.OnTouchListener = View.OnTouchListener{ _, event -> - //Get Floating widget view params + val dragListener: View.OnTouchListener = View.OnTouchListener { _, event -> + mDetector.onTouchEvent(event) + //Get Floating widget view params val layoutParams: WindowManager.LayoutParams = dialog!!.window!!.attributes //get the touch location coordinates @@ -636,11 +628,12 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session val barHeight: Int = getStatusBarHeight() if (y_cord_Destination < 0) { // y_cord_Destination = 0 - y_cord_Destination = - -(szWindow.y - (videoCallContainer.height /*+ barHeight*/)) +// y_cord_Destination = +// -(szWindow.y - (videoCallContainer.height /*+ barHeight*/)) + 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 - (videoCallContainer.height + barHeight) + y_cord_Destination = (szWindow.y/2) } layoutParams.y = y_cord_Destination @@ -662,6 +655,12 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session true } + private fun showControlPanelTemporarily() { + controlPanel!!.visibility = View.VISIBLE + mVolHandler!!.removeCallbacks(mVolRunnable!!) + mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) + } + /* Reset position of Floating Widget view on dragging */ private fun resetPosition(x_cord_now: Int) { if (x_cord_now <= szWindow.x / 2) { @@ -741,6 +740,15 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session ).toInt() } + private class MyGestureListener(val onTabCall: () -> Unit) : GestureDetector.SimpleOnGestureListener() { + + override fun onSingleTapConfirmed(event: MotionEvent): Boolean { + onTabCall() + return true + } + + } + companion object { @JvmStatic fun newInstance(args: Bundle) = diff --git a/android/app/src/main/res/drawable/video_disanabled.png b/android/app/src/main/res/drawable/video_disabled.png similarity index 100% rename from android/app/src/main/res/drawable/video_disanabled.png rename to android/app/src/main/res/drawable/video_disabled.png diff --git a/lib/config/config.dart b/lib/config/config.dart index 8241b36c..eb361798 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 1ed22e68e3f96b113d569abeeef5f441e5652ae1 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 16 Jun 2021 10:13:58 +0300 Subject: [PATCH 52/72] video fix bugs --- .../hmgDr/ui/fragment/VideoCallFragment.kt | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) 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 95f54ca8..f7f70e40 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 @@ -325,7 +325,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session Log.i(TAG, "Session Connected") mPublisher = Publisher.Builder(requireContext()).build() mPublisher!!.setPublisherListener(this) - mPublisherViewContainer!!.addView(mPublisher!!.view) + mPublisherViewContainer.addView(mPublisher!!.view) if (mPublisher!!.getView() is GLSurfaceView) { (mPublisher!!.getView() as GLSurfaceView).setZOrderOnTop(true) } @@ -490,42 +490,37 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session val btnMinimizeLayoutParam: ConstraintLayout.LayoutParams = btnMinimize.layoutParams as ConstraintLayout.LayoutParams val mCallBtnLayoutParam: ConstraintLayout.LayoutParams = mCallBtn.layoutParams as ConstraintLayout.LayoutParams -// val localPreviewMargin : Int = context!!.resources.getDimension(R.dimen.local_preview_margin_top).toInt() -// val localPreviewWidth : Int = context!!.resources.getDimension(R.dimen.local_preview_width).toInt() -// val localPreviewHeight : Int = context!!.resources.getDimension(R.dimen.local_preview_height).toInt() + val localPreviewMargin : Int = context!!.resources.getDimension(R.dimen.local_preview_margin_top).toInt() + val localPreviewWidth : Int = context!!.resources.getDimension(R.dimen.local_preview_width).toInt() + val localPreviewHeight : Int = context!!.resources.getDimension(R.dimen.local_preview_height).toInt() // val localPreviewIconSize: Int = context!!.resources.getDimension(R.dimen.local_back_icon_size).toInt() // val localPreviewMarginSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_margin_small).toInt() // val localPreviewWidthSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_width_small).toInt() // val localPreviewHeightSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_height_small).toInt() // val localPreviewIconSmall: Int = context!!.resources.getDimension(R.dimen.local_back_icon_size_small).toInt() // val localPreviewLayoutIconParam : FrameLayout.LayoutParams -// val localPreviewLayoutParam : RelativeLayout.LayoutParams = mPublisherViewContainer.layoutParams as RelativeLayout.LayoutParams + val localPreviewLayoutParam : RelativeLayout.LayoutParams = mPublisherViewContainer.layoutParams as RelativeLayout.LayoutParams val remotePreviewIconSize: Int = context!!.resources.getDimension(R.dimen.remote_back_icon_size).toInt() val remotePreviewIconSizeSmall: Int = context!!.resources.getDimension(R.dimen.remote_back_icon_size_small).toInt() val remotePreviewLayoutParam: FrameLayout.LayoutParams = mSubscriberViewIcon.layoutParams as FrameLayout.LayoutParams - val constraintSet = ConstraintSet() - //layoutParam.constrain -// constraintSet. if (isFullScreen) { layoutName.visibility = View.VISIBLE mCameraBtn.visibility = View.VISIBLE mSwitchCameraBtn.visibility = View.VISIBLE // mspeckerBtn.visibility = View.VISIBLE mMicBtn.visibility = View.VISIBLE - mPublisherViewContainer.visibility = View.VISIBLE -// layoutParam = ConstraintLayout.LayoutParams(iconSize, iconSize) btnMinimizeLayoutParam.width = iconSize btnMinimizeLayoutParam.height = iconSize mCallBtnLayoutParam.width = iconSize mCallBtnLayoutParam.height = iconSize // localPreviewLayoutIconParam = FrameLayout.LayoutParams(localPreviewIconSize, localPreviewIconSize) //// localPreviewLayoutParam = RelativeLayout.LayoutParams(localPreviewWidth, localPreviewHeight) -// localPreviewLayoutParam.width = localPreviewIconSize -// localPreviewLayoutParam.height = localPreviewIconSize -// localPreviewLayoutParam.setMargins(0,localPreviewMargin, localPreviewMargin, 0) + localPreviewLayoutParam.width = localPreviewWidth + localPreviewLayoutParam.height = localPreviewHeight + localPreviewLayoutParam.setMargins(0,localPreviewMargin, localPreviewMargin, 0) // remotePreviewLayoutParam = FrameLayout.LayoutParams(remotePreviewIconSize, remotePreviewIconSize) remotePreviewLayoutParam.width = remotePreviewIconSize remotePreviewLayoutParam.height = remotePreviewIconSize @@ -535,7 +530,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session mSwitchCameraBtn.visibility = View.GONE // mspeckerBtn.visibility = View.GONE mMicBtn.visibility = View.GONE - mPublisherViewContainer.visibility = View.GONE +// mPublisherViewContainer.visibility = View.GONE +// mPublisherViewIcon.visibility = View.GONE // layoutParam = ConstraintLayout.LayoutParams(iconSizeSmall, iconSizeSmall) btnMinimizeLayoutParam.width = iconSizeSmall @@ -543,6 +539,9 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session mCallBtnLayoutParam.width = iconSizeSmall mCallBtnLayoutParam.height = iconSizeSmall + localPreviewLayoutParam.width = 0 + localPreviewLayoutParam.height = 0 + localPreviewLayoutParam.setMargins(0,localPreviewMargin / 2, localPreviewMargin/ 2, 0) // localPreviewLayoutIconParam = FrameLayout.LayoutParams(localPreviewIconSmall, localPreviewIconSmall) //// localPreviewLayoutParam = RelativeLayout.LayoutParams(localPreviewWidthSmall, localPreviewHeightSmall) // localPreviewLayoutParam.width = localPreviewWidthSmall @@ -553,7 +552,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session remotePreviewLayoutParam.height = remotePreviewIconSizeSmall } -// mPublisherViewContainer.layoutParams = localPreviewLayoutParam + mPublisherViewContainer.layoutParams = localPreviewLayoutParam // mPublisherViewIcon.layoutParams = localPreviewLayoutIconParam mSubscriberViewIcon.layoutParams = remotePreviewLayoutParam From 7c7aa781aa67e9d68f0e989f9d70e4f7f6b0763b Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 16 Jun 2021 11:12:48 +0300 Subject: [PATCH 53/72] video fix bugs --- .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 74 ++++++++++--------- .../hmg/hmgDr/ui/VideoCallResponseListener.kt | 2 + .../hmgDr/ui/fragment/VideoCallFragment.kt | 6 +- 3 files changed, 44 insertions(+), 38 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 9d9581fe..7ddc03e4 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -20,6 +20,7 @@ import io.flutter.plugins.GeneratedPluginRegistrant class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, VideoCallResponseListener { private val CHANNEL = "Dr.cloudSolution/videoCall" + private lateinit var methodChannel: MethodChannel private var result: MethodChannel.Result? = null private var call: MethodCall? = null private val LAUNCH_VIDEO: Int = 1 @@ -29,15 +30,10 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { GeneratedPluginRegistrant.registerWith(flutterEngine) - MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler(this) + methodChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL) + methodChannel.setMethodCallHandler(this) } - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - } - - override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { this.result = result @@ -67,7 +63,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, "closeVideoCall" -> { dialogFragment?.onCallClicked() } - "onCallConnected"->{ + "onCallConnected" -> { } else -> { @@ -87,7 +83,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, // intent.putExtra("sessionStatusModel", sessionStatusModel) // startActivityForResult(intent, LAUNCH_VIDEO) - if (dialogFragment == null){ + if (dialogFragment == null) { val arguments = Bundle() arguments.putString("apiKey", apiKey) arguments.putString("sessionId", sessionId) @@ -103,47 +99,47 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, it.isCancelable = true it.show(transaction, "dialog") } - } else if (!dialogFragment!!.isVisible){ + } else if (!dialogFragment!!.isVisible) { val transaction = supportFragmentManager.beginTransaction() dialogFragment!!.show(transaction, "dialog") } } - /* override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - var asd = ""; - if (requestCode == LAUNCH_VIDEO) { - if (resultCode == Activity.RESULT_OK) { - val result : SessionStatusModel? = data?.getParcelableExtra("sessionStatusNotRespond") - val callResponse : HashMap = HashMap() + /* override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + var asd = ""; + if (requestCode == LAUNCH_VIDEO) { + if (resultCode == Activity.RESULT_OK) { + val result : SessionStatusModel? = data?.getParcelableExtra("sessionStatusNotRespond") + val callResponse : HashMap = HashMap() - val sessionStatus : HashMap = HashMap() - val gson = GsonBuilder().serializeNulls().create() + val sessionStatus : HashMap = HashMap() + val gson = GsonBuilder().serializeNulls().create() - callResponse["callResponse"] = "CallNotRespond" - val jsonRes = gson.toJson(result) - callResponse["sessionStatus"] = jsonRes + callResponse["callResponse"] = "CallNotRespond" + val jsonRes = gson.toJson(result) + callResponse["sessionStatus"] = jsonRes - this.result?.success(callResponse) - } - if (resultCode == Activity.RESULT_CANCELED) { - val callResponse : HashMap = HashMap() - callResponse["callResponse"] = "CallEnd" + this.result?.success(callResponse) + } + if (resultCode == Activity.RESULT_CANCELED) { + val callResponse : HashMap = HashMap() + callResponse["callResponse"] = "CallEnd" - result?.success(callResponse) - } - } - }*/ + result?.success(callResponse) + } + } + }*/ override fun onCallFinished(resultCode: Int, intent: Intent?) { dialogFragment = null if (resultCode == Activity.RESULT_OK) { - val result : SessionStatusModel? = intent?.getParcelableExtra("sessionStatusNotRespond") - val callResponse : HashMap = HashMap() + val result: SessionStatusModel? = intent?.getParcelableExtra("sessionStatusNotRespond") + val callResponse: HashMap = HashMap() - val sessionStatus : HashMap = HashMap() + val sessionStatus: HashMap = HashMap() val gson = GsonBuilder().serializeNulls().create() callResponse["callResponse"] = "CallNotRespond" @@ -152,9 +148,8 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, this.result?.success(callResponse) } else if (resultCode == Activity.RESULT_CANCELED) { - val callResponse : HashMap = HashMap() + val callResponse: HashMap = HashMap() callResponse["callResponse"] = "CallEnd" - result?.success(callResponse) } } @@ -164,5 +159,12 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, // Toast.makeText(this, message, Toast.LENGTH_LONG).show() } + override fun minimizeVideoEvent(isMinimize: Boolean) { + if (isMinimize) + methodChannel.invokeMethod("onCallConnected", null) + else + methodChannel.invokeMethod("onCallDisconnected", null) + } + } diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt index d2ed15e0..eceed01e 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt @@ -7,4 +7,6 @@ interface VideoCallResponseListener { fun onCallFinished(resultCode : Int, intent: Intent? = null) fun errorHandle(message: String) + + fun minimizeVideoEvent(isMinimize : Boolean) } \ No newline at end of file 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 f7f70e40..03883361 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 @@ -420,13 +420,13 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session return } if (mSubscriber != null) { - mSubscriberViewContainer!!.removeView(mSubscriber!!.view) + mSubscriberViewContainer.removeView(mSubscriber!!.view) mSession!!.unsubscribe(mSubscriber) mSubscriber!!.destroy() mSubscriber = null } if (mPublisher != null) { - mPublisherViewContainer!!.removeView(mPublisher!!.view) + mPublisherViewContainer.removeView(mPublisher!!.view) mSession!!.unpublish(mPublisher) mPublisher!!.destroy() mPublisher = null @@ -482,6 +482,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session val res = if (isFullScreen) R.drawable.reducing else R.drawable.expand btnMinimize.setImageResource(res) setViewsVisibility() + + videoCallResponseListener?.minimizeVideoEvent(!isFullScreen) } private fun setViewsVisibility() { From c1ed1dc737fbdb27c0b5c2353a10296f0693d4b8 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 16 Jun 2021 11:13:35 +0300 Subject: [PATCH 54/72] add loader --- lib/screens/patients/InPatientPage.dart | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/screens/patients/InPatientPage.dart b/lib/screens/patients/InPatientPage.dart index e9e2c2d1..ec2a8107 100644 --- a/lib/screens/patients/InPatientPage.dart +++ b/lib/screens/patients/InPatientPage.dart @@ -1,9 +1,12 @@ +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/PatientSearchViewModel.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/patient_card/PatientCard.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/errors/error_message.dart'; +import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_container.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; import 'package:flutter/material.dart'; @@ -59,7 +62,7 @@ class _InPatientPageState extends State { model.filterSearchResults(value); }), ), - model.filteredInPatientItems.length > 0 + model.state == ViewState.Idle?model.filteredInPatientItems.length > 0 ? Expanded( child: Container( margin: EdgeInsets.symmetric(horizontal: 16.0), @@ -154,6 +157,13 @@ class _InPatientPageState extends State { error: TranslationBase.of(context).noDataAvailable)), ), + ): Center( + child: Container( + height: 300, + width: 300, + child: Image.asset( + "assets/images/progress-loading-red.gif"), + ), ), ], ), From 5312c221d129d5a0200e7e8cb7b35800fa4e6014 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 16 Jun 2021 11:14:32 +0300 Subject: [PATCH 55/72] video fix bugs --- .../kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 03883361..1dc3d267 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 @@ -19,6 +19,7 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet 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.R @@ -358,7 +359,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } isConnected = true subscribeToStream(stream) -// videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(3, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) + videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(3, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) } override fun onStreamDropped(session: Session, stream: Stream) { @@ -433,7 +434,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } mSession!!.disconnect() countDownTimer?.cancel() -// videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(16, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) + videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(16, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) dialog?.dismiss() } @@ -589,7 +590,6 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } } - @SuppressLint("ClickableViewAccessibility") fun handleDragDialog() { mWindowManager = requireActivity().getSystemService(Context.WINDOW_SERVICE) as WindowManager From 0868de7961ab6053cd50e61216fd7b471498ef09 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 16 Jun 2021 14:05:04 +0300 Subject: [PATCH 56/72] video fix bugs --- android/app/src/main/AndroidManifest.xml | 1 - .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 28 +- .../com/hmg/hmgDr/ui/VideoCallActivity.java | 481 ------------------ .../hmg/hmgDr/ui/VideoCallResponseListener.kt | 2 + .../hmgDr/ui/fragment/VideoCallFragment.kt | 34 +- .../src/main/res/drawable/circle_shape.xml | 14 + .../main/res/drawable/layout_rounded_bg.xml | 14 +- 7 files changed, 64 insertions(+), 510 deletions(-) delete mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java create mode 100644 android/app/src/main/res/drawable/circle_shape.xml diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 0e71249f..bf0d3766 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -27,7 +27,6 @@ android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:label="HMG Doctor"> - = HashMap() callResponse["callResponse"] = "CallEnd" @@ -166,5 +167,8 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, methodChannel.invokeMethod("onCallDisconnected", null) } + override fun onBackPressed() { + super.onBackPressed() + } } diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java deleted file mode 100644 index 75590b76..00000000 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java +++ /dev/null @@ -1,481 +0,0 @@ -package com.hmg.hmgDr.ui; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; - -import android.Manifest; -import android.annotation.SuppressLint; -import android.app.Activity; -import android.content.Intent; -import android.opengl.GLSurfaceView; -import android.os.Bundle; -import android.os.CountDownTimer; -import android.os.Handler; -import android.os.SystemClock; -import android.util.Log; -import android.view.View; -import android.widget.Chronometer; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.ProgressBar; -import android.widget.RelativeLayout; -import android.widget.TextView; - -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.opentok.android.Session; -import com.opentok.android.Stream; -import com.opentok.android.Publisher; -import com.opentok.android.PublisherKit; -import com.opentok.android.Subscriber; -import com.opentok.android.BaseVideoRenderer; -import com.opentok.android.OpentokError; -import com.opentok.android.SubscriberKit; - -import java.util.List; -import java.util.Objects; - -import pub.devrel.easypermissions.AfterPermissionGranted; -import pub.devrel.easypermissions.AppSettingsDialog; -import pub.devrel.easypermissions.EasyPermissions; - -public class VideoCallActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks, - Session.SessionListener, - Publisher.PublisherListener, - Subscriber.VideoListener, VideoCallContract.VideoCallView { - - private static final String TAG = VideoCallActivity.class.getSimpleName(); - - VideoCallContract.VideoCallPresenter videoCallPresenter; - - private static final int RC_SETTINGS_SCREEN_PERM = 123; - private static final int RC_VIDEO_APP_PERM = 124; - - - private Session mSession; - private Publisher mPublisher; - private Subscriber mSubscriber; - - private Handler mVolHandler, mConnectedHandler; - private Runnable mVolRunnable, mConnectedRunnable; - - private FrameLayout mPublisherViewContainer; - private FrameLayout mSubscriberViewContainer; - private RelativeLayout controlPanel; - - private String apiKey; - private String sessionId; - private String token; - private String appLang; - private String baseUrl; - - private boolean isSwitchCameraClicked; - private boolean isCameraClicked; - private boolean isSpeckerClicked; - private boolean isMicClicked; - - private TextView patientName; - private Chronometer cmTimer; - long elapsedTime; - Boolean resume = false; - - private ImageView mCallBtn; - private ImageView btnMinimize; - private ImageView mCameraBtn; - private ImageView mSwitchCameraBtn; - private ImageView mspeckerBtn; - private ImageView mMicBtn; - - private ProgressBar progressBar; - private CountDownTimer countDownTimer; - private TextView progressBarTextView; - private RelativeLayout progressBarLayout; - - private boolean isConnected = false; - - private GetSessionStatusModel sessionStatusModel; - - - @Override - protected void onCreate(Bundle savedInstanceState) { - setTheme(R.style.AppTheme); - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_video_call); - Objects.requireNonNull(getSupportActionBar()).hide(); - initUI(); - requestPermissions(); - } - - @Override - protected void onPause() { - super.onPause(); - - if (mSession == null) { - return; - } - mSession.onPause(); - - if (isFinishing()) { - disconnectSession(); - } - } - - @Override - protected void onResume() { - super.onResume(); - - if (mSession == null) { - return; - } - mSession.onResume(); - } - - @Override - protected void onDestroy() { - disconnectSession(); - cmTimer.stop(); - super.onDestroy(); - } - - @SuppressLint("ClickableViewAccessibility") - private void initUI() { - mPublisherViewContainer = findViewById(R.id.local_video_view_container); - mSubscriberViewContainer = findViewById(R.id.remote_video_view_container); - - apiKey = getIntent().getStringExtra("apiKey"); - sessionId = getIntent().getStringExtra("sessionId"); - token = getIntent().getStringExtra("token"); - appLang = getIntent().getStringExtra("appLang"); - baseUrl = getIntent().getStringExtra("baseUrl"); - sessionStatusModel = getIntent().getParcelableExtra("sessionStatusModel"); - - controlPanel = findViewById(R.id.control_panel); - - videoCallPresenter = new VideoCallPresenterImpl(this, baseUrl); - - patientName = findViewById(R.id.patient_name); - patientName.setText(sessionStatusModel.getPatientName()); - - cmTimer = findViewById(R.id.cmTimer); - cmTimer.setFormat("mm:ss"); - cmTimer.setOnChronometerTickListener(arg0 -> { - long minutes; - long seconds; - if (!resume) { - minutes = ((SystemClock.elapsedRealtime() - cmTimer.getBase()) / 1000) / 60; - seconds = ((SystemClock.elapsedRealtime() - cmTimer.getBase()) / 1000) % 60; - elapsedTime = SystemClock.elapsedRealtime(); - } else { - minutes = ((elapsedTime - cmTimer.getBase()) / 1000) / 60; - seconds = ((elapsedTime - cmTimer.getBase()) / 1000) % 60; - elapsedTime = elapsedTime + 1000; - } - Log.d(TAG, "onChronometerTick: " + minutes + " : " + seconds); - }); - - mCallBtn = findViewById(R.id.btn_call); - btnMinimize = findViewById(R.id.btn_minimize); - mCameraBtn = findViewById(R.id.btn_camera); - mSwitchCameraBtn = findViewById(R.id.btn_switch_camera); - mspeckerBtn = findViewById(R.id.btn_specker); - mMicBtn = findViewById(R.id.btn_mic); - - // progressBarLayout=findViewById(R.id.progressBar); - // progressBar=findViewById(R.id.progress_bar); -// progressBarTextView=findViewById(R.id.progress_bar_text); -// progressBar.setVisibility(View.GONE); - - hiddenButtons(); - - checkClientConnected(); - - mSubscriberViewContainer.setOnTouchListener((v, event) -> { - controlPanel.setVisibility(View.VISIBLE); - mVolHandler.removeCallbacks(mVolRunnable); - mVolHandler.postDelayed(mVolRunnable, 5 * 1000); - return true; - }); - - if (appLang.equals("ar")) { - progressBarLayout.setLayoutDirection(View.LAYOUT_DIRECTION_RTL); - } - - } - - private void checkClientConnected() { - mConnectedHandler = new Handler(); - mConnectedRunnable = () -> { - if (!isConnected) { - videoCallPresenter.callClintConnected(sessionStatusModel); - } - }; - mConnectedHandler.postDelayed(mConnectedRunnable, 55 * 1000); - - } - - private void hiddenButtons() { - mVolHandler = new Handler(); - mVolRunnable = () -> controlPanel.setVisibility(View.GONE); - mVolHandler.postDelayed(mVolRunnable, 5 * 1000); - } - - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); - } - - @Override - public void onPermissionsGranted(int requestCode, List perms) { - Log.d(TAG, "onPermissionsGranted:" + requestCode + ":" + perms.size()); - } - - @Override - public void onPermissionsDenied(int requestCode, List perms) { - Log.d(TAG, "onPermissionsDenied:" + requestCode + ":" + perms.size()); - - if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { - new 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(); - } - } - - @AfterPermissionGranted(RC_VIDEO_APP_PERM) - private void requestPermissions() { - String[] perms = {Manifest.permission.INTERNET, Manifest.permission.CAMERA,}; - if (EasyPermissions.hasPermissions(this, perms)) { - try { - mSession = new Session.Builder(this, apiKey, sessionId).build(); - mSession.setSessionListener(this); - mSession.connect(token); - } catch (Exception e) { - e.printStackTrace(); - } - } else { - EasyPermissions.requestPermissions(this, getString(R.string.remaining_ar), RC_VIDEO_APP_PERM, perms); - } - } - - @Override - public void onConnected(Session session) { - Log.i(TAG, "Session Connected"); - - mPublisher = new Publisher.Builder(this).build(); - mPublisher.setPublisherListener(this); - - mPublisherViewContainer.addView(mPublisher.getView()); - - if (mPublisher.getView() instanceof GLSurfaceView) { - ((GLSurfaceView) mPublisher.getView()).setZOrderOnTop(true); - } - - mSession.publish(mPublisher); - - if (!resume) { - cmTimer.setBase(SystemClock.elapsedRealtime()); - } - cmTimer.start(); - } - - @Override - public void onDisconnected(Session session) { - Log.d(TAG, "onDisconnected: disconnected from session " + session.getSessionId()); - - mSession = null; - cmTimer.stop(); - } - - @Override - public void onError(Session session, OpentokError opentokError) { - Log.d(TAG, "onError: Error (" + opentokError.getMessage() + ") in session " + session.getSessionId()); - - // Toast.makeText(this, "Session error. See the logcat please.", Toast.LENGTH_LONG).show(); - //finish(); - } - - @Override - public void onStreamReceived(Session session, Stream stream) { - Log.d(TAG, "onStreamReceived: New stream " + stream.getStreamId() + " in session " + session.getSessionId()); - if (mSubscriber != null) { - isConnected = true; - return; - } - isConnected = true; - subscribeToStream(stream); - if(mConnectedHandler!=null && mConnectedRunnable!=null) - mConnectedHandler.removeCallbacks(mConnectedRunnable); - videoCallPresenter.callChangeCallStatus(new ChangeCallStatusRequestModel(3,sessionStatusModel.getDoctorId(), sessionStatusModel.getGeneralid(),token,sessionStatusModel.getVCID())); - } - - @Override - public void onStreamDropped(Session session, Stream stream) { - Log.d(TAG, "onStreamDropped: Stream " + stream.getStreamId() + " dropped from session " + session.getSessionId()); - - if (mSubscriber == null) { - return; - } - - if (mSubscriber.getStream().equals(stream)) { - mSubscriberViewContainer.removeView(mSubscriber.getView()); - mSubscriber.destroy(); - mSubscriber = null; - } - disconnectSession(); - } - - @Override - public void onStreamCreated(PublisherKit publisherKit, Stream stream) { - Log.d(TAG, "onStreamCreated: Own stream " + stream.getStreamId() + " created"); - } - - @Override - public void onStreamDestroyed(PublisherKit publisherKit, Stream stream) { - Log.d(TAG, "onStreamDestroyed: Own stream " + stream.getStreamId() + " destroyed"); - } - - @Override - public void onError(PublisherKit publisherKit, OpentokError opentokError) { - Log.d(TAG, "onError: Error (" + opentokError.getMessage() + ") in publisher"); - - // Toast.makeText(this, "onError: Error (" + opentokError.getMessage() + ") in publisher", Toast.LENGTH_LONG).show(); - // finish(); - } - - @Override - public void onVideoDataReceived(SubscriberKit subscriberKit) { - mSubscriber.setStyle(BaseVideoRenderer.STYLE_VIDEO_SCALE, BaseVideoRenderer.STYLE_VIDEO_FILL); - mSubscriberViewContainer.addView(mSubscriber.getView()); - } - - @Override - public void onVideoDisabled(SubscriberKit subscriberKit, String s) { - - } - - @Override - public void onVideoEnabled(SubscriberKit subscriberKit, String s) { - - } - - @Override - public void onVideoDisableWarning(SubscriberKit subscriberKit) { - - } - - @Override - public void onVideoDisableWarningLifted(SubscriberKit subscriberKit) { - - } - - private void subscribeToStream(Stream stream) { - mSubscriber = new Subscriber.Builder(VideoCallActivity.this, stream).build(); - mSubscriber.setVideoListener(this); - mSession.subscribe(mSubscriber); - } - - private void disconnectSession() { - if (mSession == null) { - setResult(Activity.RESULT_CANCELED); - finish(); - return; - } - - if (mSubscriber != null) { - mSubscriberViewContainer.removeView(mSubscriber.getView()); - mSession.unsubscribe(mSubscriber); - mSubscriber.destroy(); - mSubscriber = null; - } - - if (mPublisher != null) { - mPublisherViewContainer.removeView(mPublisher.getView()); - mSession.unpublish(mPublisher); - mPublisher.destroy(); - mPublisher = null; - } - mSession.disconnect(); - if (countDownTimer != null) { - countDownTimer.cancel(); - } - videoCallPresenter.callChangeCallStatus(new ChangeCallStatusRequestModel(16,sessionStatusModel.getDoctorId(), sessionStatusModel.getGeneralid(),token,sessionStatusModel.getVCID())); - finish(); - } - - public void onSwitchCameraClicked(View view) { - if (mPublisher != null) { - isSwitchCameraClicked = !isSwitchCameraClicked; - mPublisher.cycleCamera(); - int res = isSwitchCameraClicked ? R.drawable.camera_front : R.drawable.camera_back; - mSwitchCameraBtn.setImageResource(res); - } - } - - public void onCallClicked(View view) { - disconnectSession(); - } - - public void onMinimizedClicked(View view) { - - } - - public void onCameraClicked(View view) { - if (mPublisher != null) { - isCameraClicked = !isCameraClicked; - mPublisher.setPublishVideo(!isCameraClicked); - int res = isCameraClicked ? R.drawable.video_disabled : R.drawable.video_enabled; - mCameraBtn.setImageResource(res); - } - } - - public void onMicClicked(View view) { - - if (mPublisher != null) { - isMicClicked = !isMicClicked; - mPublisher.setPublishAudio(!isMicClicked); - int res = isMicClicked ? R.drawable.mic_disabled : R.drawable.mic_enabled; - mMicBtn.setImageResource(res); - } - } - - public void onSpeckerClicked(View view) { - if (mSubscriber != null) { - isSpeckerClicked = !isSpeckerClicked; - mSubscriber.setSubscribeToAudio(!isSpeckerClicked); - int res = isSpeckerClicked ? R.drawable.audio_disabled : R.drawable.audio_enabled; - mspeckerBtn.setImageResource(res); - } - } - - @Override - public void onCallSuccessful(SessionStatusModel sessionStatusModel) { - if (sessionStatusModel.getSessionStatus() == 2 || sessionStatusModel.getSessionStatus() == 3) { - Intent returnIntent = new Intent(); - returnIntent.putExtra("sessionStatusNotRespond", sessionStatusModel); - setResult(Activity.RESULT_OK, returnIntent); - finish(); - } else if( sessionStatusModel.getSessionStatus() == 4 ){ - isConnected = true; - if(mConnectedHandler!=null && mConnectedRunnable!=null) - mConnectedHandler.removeCallbacks(mConnectedRunnable); - } - } - - @Override - public void onCallChangeCallStatusSuccessful(SessionStatusModel sessionStatusModel) { - - } - - @Override - public void onFailure() { - - } -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt index eceed01e..204568a4 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt @@ -9,4 +9,6 @@ interface VideoCallResponseListener { fun errorHandle(message: String) fun minimizeVideoEvent(isMinimize : Boolean) + + fun onBackHandle(){} } \ No newline at end of file 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 1dc3d267..f7e6c4b2 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 @@ -16,7 +16,6 @@ import android.view.* import android.widget.* import androidx.annotation.Nullable import androidx.constraintlayout.widget.ConstraintLayout -import androidx.constraintlayout.widget.ConstraintSet import androidx.core.view.GestureDetectorCompat import androidx.fragment.app.DialogFragment import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel @@ -39,7 +38,7 @@ import kotlin.math.ceil class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.SessionListener, PublisherListener, SubscriberKit.VideoListener, VideoCallView { - var isFullScreen: Boolean = true + private var isFullScreen: Boolean = true private var x_init_cord = 0 private var y_init_cord: Int = 0 private var x_init_margin: Int = 0 @@ -48,7 +47,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private lateinit var mWindowManager: WindowManager private var isLeft = true - lateinit var videoCallPresenter: VideoCallPresenter + private lateinit var videoCallPresenter: VideoCallPresenter private var mSession: Session? = null private var mPublisher: Publisher? = null @@ -88,8 +87,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private lateinit var patientName: TextView private lateinit var cmTimer: Chronometer - var elapsedTime: Long = 0 - var resume = false + private var elapsedTime: Long = 0 + private var resume = false private val progressBar: ProgressBar? = null private val countDownTimer: CountDownTimer? = null @@ -122,6 +121,18 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onCreateDialog(@Nullable savedInstanceState: Bundle?): Dialog { val dialog: Dialog = super.onCreateDialog(savedInstanceState) + + // Add back button listener + // Add back button listener + dialog.setOnKeyListener { _, keyCode, keyEvent -> + // getAction to make sure this doesn't double fire + if (keyCode == KeyEvent.KEYCODE_BACK && keyEvent.action == KeyEvent.ACTION_UP) { + videoCallResponseListener?.onBackHandle() + false // Capture onKey + } else true + // Don't capture + } + return dialog } @@ -438,7 +449,6 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session dialog?.dismiss() } - override fun onCallSuccessful(sessionStatusModel: SessionStatusModel) { if (sessionStatusModel.sessionStatus == 2 || sessionStatusModel.sessionStatus == 3) { val returnIntent = Intent() @@ -523,7 +533,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session //// localPreviewLayoutParam = RelativeLayout.LayoutParams(localPreviewWidth, localPreviewHeight) localPreviewLayoutParam.width = localPreviewWidth localPreviewLayoutParam.height = localPreviewHeight - localPreviewLayoutParam.setMargins(0,localPreviewMargin, localPreviewMargin, 0) + localPreviewLayoutParam.setMargins(0, localPreviewMargin, localPreviewMargin, 0) // remotePreviewLayoutParam = FrameLayout.LayoutParams(remotePreviewIconSize, remotePreviewIconSize) remotePreviewLayoutParam.width = remotePreviewIconSize remotePreviewLayoutParam.height = remotePreviewIconSize @@ -544,7 +554,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session localPreviewLayoutParam.width = 0 localPreviewLayoutParam.height = 0 - localPreviewLayoutParam.setMargins(0,localPreviewMargin / 2, localPreviewMargin/ 2, 0) + localPreviewLayoutParam.setMargins(0, localPreviewMargin / 2, localPreviewMargin / 2, 0) // localPreviewLayoutIconParam = FrameLayout.LayoutParams(localPreviewIconSmall, localPreviewIconSmall) //// localPreviewLayoutParam = RelativeLayout.LayoutParams(localPreviewWidthSmall, localPreviewHeightSmall) // localPreviewLayoutParam.width = localPreviewWidthSmall @@ -591,7 +601,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } @SuppressLint("ClickableViewAccessibility") - fun handleDragDialog() { + private fun handleDragDialog() { mWindowManager = requireActivity().getSystemService(Context.WINDOW_SERVICE) as WindowManager getWindowManagerDefaultDisplay() @@ -600,7 +610,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } @SuppressLint("ClickableViewAccessibility") - val dragListener: View.OnTouchListener = View.OnTouchListener { _, event -> + private val dragListener: View.OnTouchListener = View.OnTouchListener { _, event -> mDetector.onTouchEvent(event) //Get Floating widget view params @@ -631,10 +641,10 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session // 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 / 2) } layoutParams.y = y_cord_Destination diff --git a/android/app/src/main/res/drawable/circle_shape.xml b/android/app/src/main/res/drawable/circle_shape.xml new file mode 100644 index 00000000..2cb09469 --- /dev/null +++ b/android/app/src/main/res/drawable/circle_shape.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/drawable/layout_rounded_bg.xml b/android/app/src/main/res/drawable/layout_rounded_bg.xml index 0c46f49b..ce73e763 100644 --- a/android/app/src/main/res/drawable/layout_rounded_bg.xml +++ b/android/app/src/main/res/drawable/layout_rounded_bg.xml @@ -1,7 +1,13 @@ - - - - + + + + From 746f44157ed9f20db0b991b96b70c6cd4d22f706 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Wed, 16 Jun 2021 14:54:10 +0300 Subject: [PATCH 57/72] Add video call service --- .../hmgDr/ui/fragment/VideoCallFragment.kt | 2 + lib/core/service/NavigationService.dart | 10 +- lib/core/service/VideoCallService.dart | 88 +++++++++++++++ lib/landing_page.dart | 3 +- lib/locator.dart | 2 + lib/routes.dart | 3 + lib/screens/live_care/end_call_screen.dart | 44 +++++--- .../patient_profile_screen.dart | 102 ++++++++++-------- .../profile/patient-profile-app-bar.dart | 9 +- lib/widgets/shared/app_scaffold_widget.dart | 8 +- 10 files changed, 203 insertions(+), 68 deletions(-) create mode 100644 lib/core/service/VideoCallService.dart 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 f7e6c4b2..9a2deab6 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 @@ -370,6 +370,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } isConnected = true subscribeToStream(stream) + if (mConnectedHandler != null && mConnectedRunnable != null) + mConnectedHandler!!.removeCallbacks(mConnectedRunnable!!) videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(3, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) } diff --git a/lib/core/service/NavigationService.dart b/lib/core/service/NavigationService.dart index 426ace4d..26191ffc 100644 --- a/lib/core/service/NavigationService.dart +++ b/lib/core/service/NavigationService.dart @@ -3,9 +3,15 @@ import 'package:flutter/material.dart'; class NavigationService { final GlobalKey navigatorKey = new GlobalKey(); - Future navigateTo(String routeName) { - return navigatorKey.currentState.pushNamed(routeName); + Future navigateTo(String routeName,{Object arguments}) { + return navigatorKey.currentState.pushNamed(routeName,arguments: arguments); } + + Future pushReplacementNamed(String routeName,{Object arguments}) { + return navigatorKey.currentState.pushReplacementNamed(routeName,arguments: arguments); + } + + Future pushNamedAndRemoveUntil(String routeName) { return navigatorKey.currentState.pushNamedAndRemoveUntil(routeName,(asd)=>false); } diff --git a/lib/core/service/VideoCallService.dart b/lib/core/service/VideoCallService.dart new file mode 100644 index 00000000..af832aad --- /dev/null +++ b/lib/core/service/VideoCallService.dart @@ -0,0 +1,88 @@ +import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; +import 'package:doctor_app_flutter/core/service/base/base_service.dart'; +import 'package:doctor_app_flutter/core/service/patient/LiveCarePatientServices.dart'; +import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; +import 'package:doctor_app_flutter/models/livecare/end_call_req.dart'; +import 'package:doctor_app_flutter/models/livecare/session_status_model.dart'; +import 'package:doctor_app_flutter/models/livecare/start_call_res.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/util/VideoChannel.dart'; +import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; +import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; +import 'package:flutter/cupertino.dart'; + +import '../../locator.dart'; +import '../../routes.dart'; +import 'NavigationService.dart'; + +class VideoCallService extends BaseService{ + + StartCallRes startCallRes; + PatiantInformtion patient; + LiveCarePatientServices _liveCarePatientServices = locator(); + + openVideo(StartCallRes startModel,PatiantInformtion patientModel,VoidCallback onCallConnected, VoidCallback onCallDisconnected)async{ + this.startCallRes = startModel; + this.patient = patientModel; + DoctorProfileModel doctorProfile = await getDoctorProfile(isGetProfile: true); + await VideoChannel.openVideoCallScreen( + kToken: "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==",//startCallRes.openTokenID, + kSessionId: "1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg",//startCallRes.openSessionID, + kApiKey: '47247954',//'46209962', + vcId: patient.vcId, + patientName: patient.fullName ?? (patient.firstName != null ? "${patient.firstName} ${patient.lastName}" : "-"), + tokenID: await sharedPref.getString(TOKEN), + generalId: GENERAL_ID, + doctorId: doctorProfile.doctorID, + onFailure: (String error) { + DrAppToastMsg.showErrorToast(error); + },onCallConnected: onCallConnected, + onCallEnd: () { + WidgetsBinding.instance.addPostFrameCallback((_) async { + GifLoaderDialogUtils.showMyDialog(locator().navigatorKey.currentContext); + endCall(patient.vcId, false,).then((value) { + GifLoaderDialogUtils.hideDialog(locator().navigatorKey.currentContext); + if (hasError) { + DrAppToastMsg.showErrorToast(error); + }else + locator().navigateTo(PATIENTS_END_Call,arguments: { + "patient": patient, + }); + + }); + }); + }, + onCallNotRespond: (SessionStatusModel sessionStatusModel) { + WidgetsBinding.instance.addPostFrameCallback((_) { + GifLoaderDialogUtils.showMyDialog(locator().navigatorKey.currentContext); + endCall(patient.vcId, sessionStatusModel.sessionStatus == 3,).then((value) { + GifLoaderDialogUtils.hideDialog(locator().navigatorKey.currentContext); + if (hasError) { + DrAppToastMsg.showErrorToast(error); + } else { + locator().navigateTo(PATIENTS_END_Call,arguments: { + "patient": patient, + }); + } + + }); + + }); + }); + } + Future endCall(int vCID, bool isPatient) async { + hasError = false; + // await getDoctorProfile(isGetProfile: true); + EndCallReq endCallReq = new EndCallReq(); + endCallReq.doctorId = doctorProfile.doctorID; + endCallReq.generalid = 'Cs2020@2016\$2958'; + endCallReq.vCID = vCID; + endCallReq.isDestroy = isPatient; + //await _liveCarePatientServices.endCall(endCallReq); + if (_liveCarePatientServices.hasError) { + error = _liveCarePatientServices.error; + } + } + +} \ No newline at end of file diff --git a/lib/landing_page.dart b/lib/landing_page.dart index cd7a8171..5bce4f71 100644 --- a/lib/landing_page.dart +++ b/lib/landing_page.dart @@ -4,6 +4,7 @@ import 'package:doctor_app_flutter/screens/home/home_screen.dart'; import 'package:doctor_app_flutter/screens/qr_reader/QR_reader_screen.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_drawer_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/bottom_nav_bar.dart'; import 'package:doctor_app_flutter/widgets/shared/user-guid/app_showcase_widget.dart'; import 'package:flutter/cupertino.dart'; @@ -33,7 +34,7 @@ class _LandingPageState extends State { @override Widget build(BuildContext context) { - return Scaffold( + return AppScaffold( appBar: currentTab != 0 ? AppBar( elevation: 0, diff --git a/lib/locator.dart b/lib/locator.dart index 1e4bcb4c..d74fad8b 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -11,6 +11,7 @@ import 'package:doctor_app_flutter/core/viewModel/sick_leave_view_model.dart'; import 'package:get_it/get_it.dart'; import 'core/service/NavigationService.dart'; +import 'core/service/VideoCallService.dart'; import 'core/service/home/dasboard_service.dart'; import 'core/service/home/doctor_reply_service.dart'; import 'core/service/home/schedule_service.dart'; @@ -96,6 +97,7 @@ void setupLocator() { locator.registerLazySingleton(() => NavigationService()); locator.registerLazySingleton(() => ScanQrService()); locator.registerLazySingleton(() => SpecialClinicsService()); + locator.registerLazySingleton(() => VideoCallService()); /// View Model locator.registerFactory(() => DoctorReplayViewModel()); diff --git a/lib/routes.dart b/lib/routes.dart index 33aa5636..0826c76e 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -1,4 +1,5 @@ import 'package:doctor_app_flutter/root_page.dart'; +import 'package:doctor_app_flutter/screens/live_care/end_call_screen.dart'; import 'package:doctor_app_flutter/screens/medical-file/health_summary_page.dart'; import 'package:doctor_app_flutter/screens/patients/ECGPage.dart'; import 'package:doctor_app_flutter/screens/patients/insurance_approval_screen_patient.dart'; @@ -37,6 +38,7 @@ const String LOGIN = 'login'; const String VERIFICATION_METHODS = 'verification-methods'; const String PATIENTS = 'patients/patients'; const String PATIENTS_PROFILE = 'patients/patients-profile'; +const String PATIENTS_END_Call = 'patients/patients-profile/endCall'; const String IN_PATIENTS_PROFILE = 'inpatients/patients-profile'; const String LAB_RESULT = 'patients/lab_result'; const String HEALTH_SUMMARY = 'patients/health-summary'; @@ -88,6 +90,7 @@ var routes = { PATIENT_MEDICAL_REPORT: (_) => MedicalReportPage(), PATIENT_MEDICAL_REPORT_INSERT: (_) => AddVerifyMedicalReport(), PATIENT_MEDICAL_REPORT_DETAIL: (_) => MedicalReportDetailPage(), + PATIENTS_END_Call: (_) => EndCallScreen(), CREATE_EPISODE: (_) => UpdateSoapIndex( isUpdate: true, ), diff --git a/lib/screens/live_care/end_call_screen.dart b/lib/screens/live_care/end_call_screen.dart index 76e87a87..d355473d 100644 --- a/lib/screens/live_care/end_call_screen.dart +++ b/lib/screens/live_care/end_call_screen.dart @@ -23,9 +23,9 @@ import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:hexcolor/hexcolor.dart'; class EndCallScreen extends StatefulWidget { - final PatiantInformtion patient; - const EndCallScreen({Key key, this.patient}) : super(key: key); + + const EndCallScreen({Key key,}) : super(key: key); @override _EndCallScreenState createState() => _EndCallScreenState(); @@ -33,7 +33,7 @@ class EndCallScreen extends StatefulWidget { class _EndCallScreenState extends State { bool isInpatient = false; - + PatiantInformtion patient; bool isDischargedPatient = false; bool isSearchAndOut = false; String patientType; @@ -43,6 +43,13 @@ class _EndCallScreenState extends State { LiveCarePatientViewModel liveCareModel; + @override + void didChangeDependencies() { + super.didChangeDependencies(); + final routeArgs = ModalRoute.of(context).settings.arguments as Map; + patient = routeArgs['patient']; + } + @override Widget build(BuildContext context) { final List cardsList = [ @@ -53,7 +60,7 @@ class _EndCallScreenState extends State { onTap: () async { GifLoaderDialogUtils.showMyDialog(context); await liveCareModel - .startCall(isReCall: false, vCID: widget.patient.vcId) + .startCall(isReCall: false, vCID: patient.vcId) .then((value) async { await liveCareModel.getDoctorProfile(); GifLoaderDialogUtils.hideDialog(context); @@ -64,8 +71,8 @@ class _EndCallScreenState extends State { kToken: liveCareModel.startCallRes.openTokenID, kSessionId: liveCareModel.startCallRes.openSessionID, kApiKey: '46209962', - vcId: widget.patient.vcId, - patientName: widget.patient.fullName ?? (widget.patient.firstName != null ? "${widget.patient.firstName} ${widget.patient.lastName}" : "-"), + vcId: patient.vcId, + patientName: patient.fullName ?? (patient.firstName != null ? "${patient.firstName} ${patient.lastName}" : "-"), tokenID: await liveCareModel.getToken(), generalId: GENERAL_ID, doctorId: liveCareModel.doctorProfile.doctorID, @@ -76,7 +83,7 @@ class _EndCallScreenState extends State { GifLoaderDialogUtils.showMyDialog(context); GifLoaderDialogUtils.showMyDialog(context); await liveCareModel.endCall( - widget.patient.vcId, + patient.vcId, false, ); GifLoaderDialogUtils.hideDialog(context); @@ -89,7 +96,7 @@ class _EndCallScreenState extends State { GifLoaderDialogUtils.showMyDialog(context); GifLoaderDialogUtils.showMyDialog(context); await liveCareModel.endCall( - widget.patient.vcId, + patient.vcId, sessionStatusModel.sessionStatus == 3, ); GifLoaderDialogUtils.hideDialog(context); @@ -116,14 +123,14 @@ class _EndCallScreenState extends State { () async { Navigator.of(context).pop(); GifLoaderDialogUtils.showMyDialog(context); - await liveCareModel.getAlternativeServices(widget.patient.vcId); + await liveCareModel.getAlternativeServices(patient.vcId); GifLoaderDialogUtils.hideDialog(context); if (liveCareModel.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(liveCareModel.error); } else { showAlternativesDialog(context, liveCareModel, (bool isConfirmed) async { GifLoaderDialogUtils.showMyDialog(context); - await liveCareModel.endCallWithCharge(widget.patient.vcId, isConfirmed); + await liveCareModel.endCallWithCharge(patient.vcId, isConfirmed); GifLoaderDialogUtils.hideDialog(context); if (liveCareModel.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(liveCareModel.error); @@ -147,7 +154,7 @@ class _EndCallScreenState extends State { () async { Navigator.of(context).pop(); GifLoaderDialogUtils.showMyDialog(context); - await liveCareModel.sendSMSInstruction(widget.patient.vcId); + await liveCareModel.sendSMSInstruction(patient.vcId); GifLoaderDialogUtils.hideDialog(context); if (liveCareModel.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(liveCareModel.error); @@ -169,7 +176,7 @@ class _EndCallScreenState extends State { context, MaterialPageRoute( builder: (BuildContext context) => - LivaCareTransferToAdmin(patient: widget.patient))); + LivaCareTransferToAdmin(patient: patient))); }, isInPatient: isInpatient, isDartIcon: true, @@ -186,10 +193,14 @@ class _EndCallScreenState extends State { backgroundColor: Theme.of(context).scaffoldBackgroundColor, isShowAppBar: true, appBar: PatientProfileAppBar( - widget.patient, + patient, + onPressed: (){ + Navigator.pop(context); + + }, isInpatient: isInpatient, - height: (widget.patient.patientStatusType != null && - widget.patient.patientStatusType == 43) + height: (patient.patientStatusType != null && + patient.patientStatusType == 43) ? 210 : isDischargedPatient ? 240 @@ -232,7 +243,7 @@ class _EndCallScreenState extends State { staggeredTileBuilder: (int index) => StaggeredTile.fit(1), itemBuilder: (BuildContext context, int index) => PatientProfileButton( - patient: widget.patient, + patient: patient, patientType: patientType, arrivalType: arrivalType, from: from, @@ -331,6 +342,7 @@ class _EndCallScreenState extends State { ), AppButton( onPressed: () { + Navigator.of(context).pop(); Navigator.of(context).pop(); okFunction(false); }, 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 d755af4a..9aa95d16 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.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'; import 'package:doctor_app_flutter/models/SOAP/PostEpisodeReqModel.dart'; @@ -25,6 +26,7 @@ import 'package:flutter/material.dart'; import 'package:hexcolor/hexcolor.dart'; import 'package:quiver/async.dart'; +import '../../../../locator.dart'; import '../../../../routes.dart'; class PatientProfileScreen extends StatefulWidget { @@ -91,6 +93,9 @@ class _PatientProfileScreenState extends State if(routeArgs.containsKey("isFromLiveCare")) { isFromLiveCare = routeArgs['isFromLiveCare']; } + if(routeArgs.containsKey("isCallFinished")) { + isCallFinished = routeArgs['isCallFinished']; + } if (isInpatient) _activeTab = 0; else @@ -333,9 +338,9 @@ class _PatientProfileScreenState extends State if(isCallFinished) { - Navigator.push(context, MaterialPageRoute( - builder: (BuildContext context) => - EndCallScreen(patient:patient))); + // Navigator.push(context, MaterialPageRoute( + // builder: (BuildContext context) => EndCallScreen(patient:patient))); + var asd = ""; } else { GifLoaderDialogUtils.showMyDialog(context); // await model.startCall( isReCall : false, vCID: patient.vcId); @@ -349,49 +354,54 @@ class _PatientProfileScreenState extends State patient.episodeNo = 0; GifLoaderDialogUtils.hideDialog(context); - await VideoChannel.openVideoCallScreen( - kToken: "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==",//model.startCallRes.openTokenID, - kSessionId:"1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg",// model.startCallRes.openSessionID, - kApiKey: '47247954',//46209962 - vcId: patient.vcId, - patientName: patient.fullName ?? (patient.firstName != null ? "${patient.firstName} ${patient.lastName}" : "-"), - tokenID: await model.getToken(), - generalId: GENERAL_ID, - doctorId: model.doctorProfile.doctorID, - onFailure: (String error) { - DrAppToastMsg.showErrorToast(error); - },onCallConnected: callConnected, - onCallEnd: () { - var asd=""; - // WidgetsBinding.instance.addPostFrameCallback((_) { - // GifLoaderDialogUtils.showMyDialog(context); - // model.endCall(patient.vcId, false,).then((value) { - // GifLoaderDialogUtils.hideDialog(context); - // if (model.state == ViewState.ErrorLocal) { - // DrAppToastMsg.showErrorToast(model.error); - // } - // setState(() { - // isCallFinished = true; - // }); - // }); - // }); - }, - onCallNotRespond: (SessionStatusModel sessionStatusModel) { - var asd=""; - // WidgetsBinding.instance.addPostFrameCallback((_) { - // GifLoaderDialogUtils.showMyDialog(context); - // model.endCall(patient.vcId, sessionStatusModel.sessionStatus == 3,).then((value) { - // GifLoaderDialogUtils.hideDialog(context); - // if (model.state == ViewState.ErrorLocal) { - // DrAppToastMsg.showErrorToast(model.error); - // } - // setState(() { - // isCallFinished = true; - // }); - // }); - // - // }); - }); + locator().openVideo(model.startCallRes, patient, callConnected, callDisconnected); + + // await VideoChannel.openVideoCallScreen( + // kToken: "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==",//model.startCallRes.openTokenID, + // kSessionId:"1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg",// model.startCallRes.openSessionID, + // kApiKey: '47247954',//46209962 + // vcId: patient.vcId, + // patientName: patient.fullName ?? (patient.firstName != null ? "${patient.firstName} ${patient.lastName}" : "-"), + // tokenID: await model.getToken(), + // generalId: GENERAL_ID, + // doctorId: model.doctorProfile.doctorID, + // onFailure: (String error) { + // DrAppToastMsg.showErrorToast(error); + // },onCallConnected: callConnected, + // onCallEnd: () { + // var asd=""; + // WidgetsBinding.instance.addPostFrameCallback((_) { + // GifLoaderDialogUtils.showMyDialog(context); + // model.endCall(patient.vcId, false,).then((value) { + // GifLoaderDialogUtils.hideDialog(context); + // if (model.state == ViewState.ErrorLocal) { + // DrAppToastMsg.showErrorToast(model.error); + // } + // setState(() { + // isCallFinished = true; + // }); + // }); + // }); + // Navigator.push(context, MaterialPageRoute( + // builder: (BuildContext context) => + // EndCallScreen(patient:patient))); + // }, + // onCallNotRespond: (SessionStatusModel sessionStatusModel) { + // var asd=""; + // // WidgetsBinding.instance.addPostFrameCallback((_) { + // // GifLoaderDialogUtils.showMyDialog(context); + // // model.endCall(patient.vcId, sessionStatusModel.sessionStatus == 3,).then((value) { + // // GifLoaderDialogUtils.hideDialog(context); + // // if (model.state == ViewState.ErrorLocal) { + // // DrAppToastMsg.showErrorToast(model.error); + // // } + // // setState(() { + // // isCallFinished = true; + // // }); + // // }); + // // + // // }); + // }); } } diff --git a/lib/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart index 5cfdc1b6..de374f04 100644 --- a/lib/widgets/patients/profile/patient-profile-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -33,6 +33,7 @@ class PatientProfileAppBar extends StatelessWidget final String clinic; final bool isAppointmentHeader; final bool isFromLabResult; + final VoidCallback onPressed; PatientProfileAppBar( this.patient, @@ -52,7 +53,7 @@ class PatientProfileAppBar extends StatelessWidget this.episode, this.visitDate, this.isAppointmentHeader = false, - this.isFromLabResult = false}); + this.isFromLabResult = false, this.onPressed}); @override @@ -93,7 +94,11 @@ class PatientProfileAppBar extends StatelessWidget IconButton( icon: Icon(Icons.arrow_back_ios), color: Color(0xFF2B353E), //Colors.black, - onPressed: () => Navigator.pop(context), + onPressed: () { + if(onPressed!=null) + onPressed(); + Navigator.pop(context); + }, ), Expanded( child: AppText( diff --git a/lib/widgets/shared/app_scaffold_widget.dart b/lib/widgets/shared/app_scaffold_widget.dart index e957b5d4..b930c21a 100644 --- a/lib/widgets/shared/app_scaffold_widget.dart +++ b/lib/widgets/shared/app_scaffold_widget.dart @@ -19,8 +19,11 @@ class AppScaffold extends StatelessWidget { final Widget bottomSheet; final Color backgroundColor; final Widget appBar; + final Widget drawer; + final Widget bottomNavigationBar; final String subtitle; final bool isHomeIcon; + final bool extendBody; AppScaffold( {this.appBarTitle = '', this.body, @@ -30,7 +33,7 @@ class AppScaffold extends StatelessWidget { this.bottomSheet, this.backgroundColor, this.isHomeIcon = true, - this.appBar, this.subtitle}); + this.appBar, this.subtitle, this.drawer, this.extendBody = false, this.bottomNavigationBar}); @override Widget build(BuildContext context) { @@ -42,6 +45,9 @@ class AppScaffold extends StatelessWidget { }, child: Scaffold( backgroundColor: backgroundColor ?? Colors.white, + drawer: drawer, + extendBody: extendBody, + bottomNavigationBar: bottomNavigationBar, appBar: isShowAppBar ? appBar ?? AppBar( From 7614b4aa5c7406da5c3c209f6057e65c04ca8661 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Wed, 16 Jun 2021 15:12:25 +0300 Subject: [PATCH 58/72] fix the video call issues --- lib/config/config.dart | 4 ++-- lib/core/service/VideoCallService.dart | 10 +++++----- lib/core/viewModel/authentication_view_model.dart | 2 +- lib/screens/home/home_screen.dart | 2 +- lib/screens/patients/PatientsInPatientScreen.dart | 13 ++++++------- 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index eb361798..8241b36c 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/VideoCallService.dart b/lib/core/service/VideoCallService.dart index af832aad..0ae61a55 100644 --- a/lib/core/service/VideoCallService.dart +++ b/lib/core/service/VideoCallService.dart @@ -27,9 +27,9 @@ class VideoCallService extends BaseService{ this.patient = patientModel; 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, + kSessionId: startCallRes.openSessionID, + kApiKey: '46209962',//'46209962', vcId: patient.vcId, patientName: patient.fullName ?? (patient.firstName != null ? "${patient.firstName} ${patient.lastName}" : "-"), tokenID: await sharedPref.getString(TOKEN), @@ -73,13 +73,13 @@ class VideoCallService extends BaseService{ } Future endCall(int vCID, bool isPatient) async { hasError = false; - // await getDoctorProfile(isGetProfile: true); + await getDoctorProfile(isGetProfile: true); EndCallReq endCallReq = new EndCallReq(); endCallReq.doctorId = doctorProfile.doctorID; endCallReq.generalid = 'Cs2020@2016\$2958'; endCallReq.vCID = vCID; endCallReq.isDestroy = isPatient; - //await _liveCarePatientServices.endCall(endCallReq); + await _liveCarePatientServices.endCall(endCallReq); if (_liveCarePatientServices.hasError) { error = _liveCarePatientServices.error; } diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index 189dea42..9da1933a 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/home/home_screen.dart b/lib/screens/home/home_screen.dart index aaf4d9b9..d448083f 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -69,7 +69,7 @@ class _HomeScreenState extends State { await model.getDashboard(); await model.getDoctorProfile(isGetProfile: true); await model.checkDoctorHasLiveCare(); - await model.getSpecialClinicalCareList(); + // await model.getSpecialClinicalCareList(); }, builder: (_, model, w) => AppScaffold( baseViewModel: model, diff --git a/lib/screens/patients/PatientsInPatientScreen.dart b/lib/screens/patients/PatientsInPatientScreen.dart index 4971b636..ae0fbb59 100644 --- a/lib/screens/patients/PatientsInPatientScreen.dart +++ b/lib/screens/patients/PatientsInPatientScreen.dart @@ -65,13 +65,12 @@ class _PatientInPatientScreenState extends State return BaseView( onModelReady: (model) async { model.clearPatientList(); - if (widget.specialClinic != null) { - await model - .getSpecialClinicalCareMappingList(widget.specialClinic.clinicID); - requestModel.nursingStationID = - model.specialClinicalCareMappingList[0].nursingStationID; - requestModel.clinicID = 0; - } + // if (widget.specialClinic != null) { + // await model.getSpecialClinicalCareMappingList(widget.specialClinic.clinicID); + // requestModel.nursingStationID = + // model.specialClinicalCareMappingList[0].nursingStationID; + // requestModel.clinicID = 0; + // } model.getInPatientList(requestModel); }, builder: (_, model, w) => From 78903043d95aa89cc135ee4dbf0788bbadfbc3d7 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 16 Jun 2021 16:18:54 +0300 Subject: [PATCH 59/72] fix header --- .../patients/profile/lab_result/laboratory_result_page.dart | 2 +- lib/screens/patients/profile/lab_result/labs_home_page.dart | 1 - lib/widgets/patients/profile/patient-profile-app-bar.dart | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart index d6b4d2bc..e58d4ef5 100644 --- a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart +++ b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart @@ -40,7 +40,7 @@ class _LaboratoryResultPageState extends State { isShowAppBar: true, appBar: PatientProfileAppBar( widget.patient, - + isInpatient:widget.isInpatient, isFromLabResult: true, appointmentDate: widget.patientLabOrders.orderDate, ), 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 b2bfa2fd..7da55967 100644 --- a/lib/screens/patients/profile/lab_result/labs_home_page.dart +++ b/lib/screens/patients/profile/lab_result/labs_home_page.dart @@ -54,7 +54,6 @@ class _LabsHomePageState extends State { isShowAppBar: true, appBar: PatientProfileAppBar( patient, - isInpatient: isInpatient, ), body: SingleChildScrollView( diff --git a/lib/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart index 5cfdc1b6..497e8ad5 100644 --- a/lib/widgets/patients/profile/patient-profile-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -551,6 +551,6 @@ class PatientProfileAppBar extends StatelessWidget @override Size get preferredSize => Size(double.maxFinite, height == 0 - ? isInpatient ? 160 : isAppointmentHeader ? 290 : 170 + ? isInpatient ? (isFromLabResult?170:175) : isAppointmentHeader ? 290 : 175 : height); } From b9711fce653035bc97f559f8a1e01b1554172f7d Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 16 Jun 2021 16:35:48 +0300 Subject: [PATCH 60/72] fix header from lab result details --- lib/widgets/patients/profile/patient-profile-app-bar.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart index 497e8ad5..e39cd5f6 100644 --- a/lib/widgets/patients/profile/patient-profile-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -551,6 +551,6 @@ class PatientProfileAppBar extends StatelessWidget @override Size get preferredSize => Size(double.maxFinite, height == 0 - ? isInpatient ? (isFromLabResult?170:175) : isAppointmentHeader ? 290 : 175 + ? isInpatient ? (isFromLabResult?200:170) : isAppointmentHeader ? 290 : 175 : height); } From 4e6237f2ce31ad216349d267fff1ed149e0ed0d2 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 16 Jun 2021 16:47:03 +0300 Subject: [PATCH 61/72] fix header from lab --- lib/config/config.dart | 4 ++-- lib/widgets/patients/profile/patient-profile-app-bar.dart | 2 +- pubspec.lock | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 8241b36c..eb361798 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/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart index e39cd5f6..83186b02 100644 --- a/lib/widgets/patients/profile/patient-profile-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -551,6 +551,6 @@ class PatientProfileAppBar extends StatelessWidget @override Size get preferredSize => Size(double.maxFinite, height == 0 - ? isInpatient ? (isFromLabResult?200:170) : isAppointmentHeader ? 290 : 175 + ? isInpatient ? (isFromLabResult?200:170) : isAppointmentHeader ? 290 : 170 : height); } diff --git a/pubspec.lock b/pubspec.lock index 25596d43..77df9848 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -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.10.0 <=2.11.0-213.1.beta" + dart: ">=2.10.0 <2.11.0" flutter: ">=1.22.0 <2.0.0" From edca552f789024cae097bb67b91056776225459e Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 16 Jun 2021 17:18:12 +0300 Subject: [PATCH 62/72] video fix bugs --- .../hmgDr/ui/fragment/VideoCallFragment.kt | 62 ++++++++++++++++++- .../src/main/res/drawable/circle_shape.xml | 6 +- android/app/src/main/res/drawable/ic_mini.xml | 5 ++ .../main/res/layout/activity_video_call.xml | 22 ++++++- android/app/src/main/res/values/colors.xml | 4 ++ lib/config/config.dart | 4 +- lib/core/service/VideoCallService.dart | 6 +- 7 files changed, 98 insertions(+), 11 deletions(-) create mode 100644 android/app/src/main/res/drawable/ic_mini.xml 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 9a2deab6..68db00fb 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 @@ -16,6 +16,7 @@ import android.view.* import android.widget.* import androidx.annotation.Nullable 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 @@ -39,6 +40,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session SubscriberKit.VideoListener, VideoCallView { private var isFullScreen: Boolean = true + private var isCircle: Boolean = false private var x_init_cord = 0 private var y_init_cord: Int = 0 private var x_init_margin: Int = 0 @@ -78,6 +80,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private lateinit var parentView: View private lateinit var videoCallContainer: ConstraintLayout private lateinit var layoutName: RelativeLayout + private lateinit var layoutMini: RelativeLayout + private lateinit var icMini: ImageButton private lateinit var mCallBtn: ImageView private lateinit var btnMinimize: ImageView private lateinit var mCameraBtn: ImageView @@ -179,7 +183,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session requestPermissions() handleDragDialog() - mDetector = GestureDetectorCompat(context, MyGestureListener { showControlPanelTemporarily() }) + mDetector = GestureDetectorCompat(context, MyGestureListener({ showControlPanelTemporarily() }, { miniCircleDoubleTap() })) return parentView } @@ -214,6 +218,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private fun initUI(view: View) { videoCallContainer = view.findViewById(R.id.video_call_ll) layoutName = view.findViewById(R.id.layout_name) + layoutMini = view.findViewById(R.id.layout_mini) + icMini = view.findViewById(R.id.ic_mini) mPublisherViewContainer = view.findViewById(R.id.local_video_view_container) mPublisherViewIcon = view.findViewById(R.id.local_video_view_icon) mSubscriberViewIcon = view.findViewById(R.id.remote_video_view_icon) @@ -240,6 +246,10 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session Log.d(VideoCallFragment.TAG, "onChronometerTick: $minutes : $seconds") } + icMini.setOnClickListener { + onMiniCircleClicked() + } + controlPanel = view.findViewById(R.id.control_panel) videoCallPresenter = VideoCallPresenterImpl(this, baseUrl) mCallBtn = view.findViewById(R.id.btn_call) @@ -478,6 +488,39 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session disconnectSession() } + private fun miniCircleDoubleTap(){ + if (isCircle){ + onMiniCircleClicked() + } + } + + private fun onMiniCircleClicked(){ + if (isCircle) { + dialog?.window?.setLayout( + 400, + 600 + ) + videoCallContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_color)) + mSubscriberViewContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.remoteBackground)) + } else { + dialog?.window?.setLayout( + 200, + 200 + ) + videoCallContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) + mSubscriberViewContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) + } + isCircle = !isCircle + + if(isCircle){ + controlPanel?.visibility = View.GONE + layoutMini.visibility = View.GONE + } else { + controlPanel?.visibility = View.VISIBLE + layoutMini.visibility = View.VISIBLE + } + } + private fun onMinimizedClicked(view: View?) { if (isFullScreen) { dialog?.window?.setLayout( @@ -522,6 +565,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session if (isFullScreen) { layoutName.visibility = View.VISIBLE + layoutMini.visibility = View.GONE mCameraBtn.visibility = View.VISIBLE mSwitchCameraBtn.visibility = View.VISIBLE // mspeckerBtn.visibility = View.VISIBLE @@ -541,6 +585,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session remotePreviewLayoutParam.height = remotePreviewIconSize } else { layoutName.visibility = View.GONE + layoutMini.visibility = View.VISIBLE mCameraBtn.visibility = View.GONE mSwitchCameraBtn.visibility = View.GONE // mspeckerBtn.visibility = View.GONE @@ -565,6 +610,14 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session // remotePreviewLayoutParam = FrameLayout.LayoutParams(remotePreviewIconSizeSmall, remotePreviewIconSizeSmall) remotePreviewLayoutParam.width = remotePreviewIconSizeSmall remotePreviewLayoutParam.height = remotePreviewIconSizeSmall + + if(isCircle){ + controlPanel?.visibility = View.GONE + layoutMini.visibility = View.GONE + } else { + controlPanel?.visibility = View.VISIBLE + layoutMini.visibility = View.VISIBLE + } } mPublisherViewContainer.layoutParams = localPreviewLayoutParam @@ -753,13 +806,18 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session ).toInt() } - private class MyGestureListener(val onTabCall: () -> Unit) : GestureDetector.SimpleOnGestureListener() { + private class MyGestureListener(val onTabCall: () -> Unit, val miniCircleDoubleTap: () -> Unit) : GestureDetector.SimpleOnGestureListener() { override fun onSingleTapConfirmed(event: MotionEvent): Boolean { onTabCall() return true } + override fun onDoubleTap(e: MotionEvent?): Boolean { + miniCircleDoubleTap() + return super.onDoubleTap(e) + } + } companion object { diff --git a/android/app/src/main/res/drawable/circle_shape.xml b/android/app/src/main/res/drawable/circle_shape.xml index 2cb09469..27b49f9b 100644 --- a/android/app/src/main/res/drawable/circle_shape.xml +++ b/android/app/src/main/res/drawable/circle_shape.xml @@ -3,10 +3,10 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> - - + - + + + 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 6dbdaa1f..efc97746 100644 --- a/android/app/src/main/res/layout/activity_video_call.xml +++ b/android/app/src/main/res/layout/activity_video_call.xml @@ -47,12 +47,32 @@ + + + + + diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml index 29782be0..f52c2cf2 100644 --- a/android/app/src/main/res/values/colors.xml +++ b/android/app/src/main/res/values/colors.xml @@ -5,6 +5,10 @@ #fc3850 #e4e9f2 + #80757575 + #00ffffff + + #827b92 #484258 diff --git a/lib/config/config.dart b/lib/config/config.dart index 8241b36c..eb361798 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/VideoCallService.dart b/lib/core/service/VideoCallService.dart index 0ae61a55..114d627f 100644 --- a/lib/core/service/VideoCallService.dart +++ b/lib/core/service/VideoCallService.dart @@ -27,9 +27,9 @@ class VideoCallService extends BaseService{ this.patient = patientModel; DoctorProfileModel doctorProfile = await getDoctorProfile(isGetProfile: true); await VideoChannel.openVideoCallScreen( - kToken: startCallRes.openTokenID, - kSessionId: startCallRes.openSessionID, - kApiKey: '46209962',//'46209962', + kToken:"T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==", //startCallRes.openTokenID, + kSessionId: "1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg",//startCallRes.openSessionID, + kApiKey:'47247954',// '46209962', vcId: patient.vcId, patientName: patient.fullName ?? (patient.firstName != null ? "${patient.firstName} ${patient.lastName}" : "-"), tokenID: await sharedPref.getString(TOKEN), From b8de9c9a14f98e41e90264e437c6533d6690bcf3 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 17 Jun 2021 10:11:19 +0300 Subject: [PATCH 63/72] circle screen fix bug, and mini screen design --- .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 6 ++- .../hmgDr/ui/fragment/VideoCallFragment.kt | 28 +++++----- android/app/src/main/res/drawable/ic_mini.xml | 2 +- .../main/res/layout/activity_video_call.xml | 53 +++++++++---------- 4 files changed, 47 insertions(+), 42 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 af19306d..fcc3f2e3 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -151,7 +151,11 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, } else if (resultCode == Activity.RESULT_CANCELED) { val callResponse: HashMap = HashMap() callResponse["callResponse"] = "CallEnd" - result?.success(callResponse) + try { + result?.success(callResponse) + } catch (e : Exception){ + Log.e("onVideoCallFinished", "${e.message}.") + } } } 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 68db00fb..51ce1948 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 @@ -64,7 +64,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private lateinit var mPublisherViewIcon: View private lateinit var mSubscriberViewContainer: FrameLayout private lateinit var mSubscriberViewIcon: ImageView - private var controlPanel: ConstraintLayout? = null + private lateinit var controlPanel: ConstraintLayout private var apiKey: String? = null private var sessionId: String? = null @@ -300,7 +300,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private fun hiddenButtons() { mVolHandler = Handler() - mVolRunnable = Runnable { controlPanel!!.visibility = View.GONE } + mVolRunnable = Runnable { controlPanel.visibility = View.GONE } mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) } @@ -496,27 +496,27 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private fun onMiniCircleClicked(){ if (isCircle) { + videoCallContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_color)) + mSubscriberViewContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.remoteBackground)) dialog?.window?.setLayout( 400, 600 ) - videoCallContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_color)) - mSubscriberViewContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.remoteBackground)) } else { + videoCallContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) + mSubscriberViewContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) dialog?.window?.setLayout( 200, 200 ) - videoCallContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) - mSubscriberViewContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) } isCircle = !isCircle if(isCircle){ - controlPanel?.visibility = View.GONE + controlPanel.visibility = View.GONE layoutMini.visibility = View.GONE } else { - controlPanel?.visibility = View.VISIBLE + controlPanel.visibility = View.VISIBLE layoutMini.visibility = View.VISIBLE } } @@ -612,10 +612,10 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session remotePreviewLayoutParam.height = remotePreviewIconSizeSmall if(isCircle){ - controlPanel?.visibility = View.GONE + controlPanel.visibility = View.GONE layoutMini.visibility = View.GONE } else { - controlPanel?.visibility = View.VISIBLE + controlPanel.visibility = View.VISIBLE layoutMini.visibility = View.VISIBLE } } @@ -722,9 +722,11 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } private fun showControlPanelTemporarily() { - controlPanel!!.visibility = View.VISIBLE - mVolHandler!!.removeCallbacks(mVolRunnable!!) - mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) + if (!isCircle){ + controlPanel.visibility = View.VISIBLE + mVolHandler!!.removeCallbacks(mVolRunnable!!) + mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) + } } /* Reset position of Floating Widget view on dragging */ diff --git a/android/app/src/main/res/drawable/ic_mini.xml b/android/app/src/main/res/drawable/ic_mini.xml index 300a9358..128a7430 100644 --- a/android/app/src/main/res/drawable/ic_mini.xml +++ b/android/app/src/main/res/drawable/ic_mini.xml @@ -1,5 +1,5 @@ - + 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 efc97746..a7470da3 100644 --- a/android/app/src/main/res/layout/activity_video_call.xml +++ b/android/app/src/main/res/layout/activity_video_call.xml @@ -37,9 +37,9 @@ android:id="@+id/cmTimer" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:padding="4dp" android:textColor="@color/white" android:textSize="16sp" - android:padding="4dp" android:textStyle="bold" tools:text="25:45" /> @@ -47,39 +47,38 @@ - - - - - + app:layout_constraintTop_toBottomOf="@+id/layout_name"> + + + + + android:src="@drawable/camera_back" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/btn_mic" + app:layout_constraintTop_toTopOf="parent" /> Date: Thu, 17 Jun 2021 10:14:00 +0300 Subject: [PATCH 64/72] fix drop video call issue --- .../kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt | 4 ++-- lib/config/config.dart | 4 ++-- .../model/patient_muse/PatientSearchRequestModel.dart | 3 ++- lib/core/service/VideoCallService.dart | 8 ++++---- lib/core/viewModel/scan_qr_view_model.dart | 2 +- .../profile/profile_screen/patient_profile_screen.dart | 4 ++-- 6 files changed, 13 insertions(+), 12 deletions(-) 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 9a2deab6..66777d93 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 @@ -358,7 +358,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onError(session: Session, opentokError: OpentokError) { Log.d(TAG, "onError: Error (" + opentokError.message + ") in session " + session.sessionId) - videoCallResponseListener?.errorHandle("Error (" + opentokError.message + ") in session ") + // videoCallResponseListener?.errorHandle("Error (" + opentokError.message + ") in session ") // dialog?.dismiss() } @@ -398,7 +398,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onError(publisherKit: PublisherKit?, opentokError: OpentokError) { Log.d(VideoCallFragment.TAG, "onError: Error (" + opentokError.message + ") in publisher") - videoCallResponseListener?.errorHandle("Error (" + opentokError.message + ") in publisher") + // videoCallResponseListener?.errorHandle("Error (" + opentokError.message + ") in publisher") // dialog?.dismiss() } diff --git a/lib/config/config.dart b/lib/config/config.dart index 8241b36c..eb361798 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/model/patient_muse/PatientSearchRequestModel.dart b/lib/core/model/patient_muse/PatientSearchRequestModel.dart index 2918a393..c2658c9f 100644 --- a/lib/core/model/patient_muse/PatientSearchRequestModel.dart +++ b/lib/core/model/patient_muse/PatientSearchRequestModel.dart @@ -12,7 +12,7 @@ class PatientSearchRequestModel { String mobileNo; String identificationNo; int nursingStationID; - int clinicID; + int clinicID=0; PatientSearchRequestModel( {this.doctorID = 0, @@ -63,6 +63,7 @@ class PatientSearchRequestModel { data['IdentificationNo'] = this.identificationNo; data['NursingStationID'] = this.nursingStationID; data['ClinicID'] = this.clinicID; + data['ProjectID'] = 0; return data; } } diff --git a/lib/core/service/VideoCallService.dart b/lib/core/service/VideoCallService.dart index 0ae61a55..b3bc3c8d 100644 --- a/lib/core/service/VideoCallService.dart +++ b/lib/core/service/VideoCallService.dart @@ -27,9 +27,9 @@ class VideoCallService extends BaseService{ this.patient = patientModel; DoctorProfileModel doctorProfile = await getDoctorProfile(isGetProfile: true); await VideoChannel.openVideoCallScreen( - kToken: startCallRes.openTokenID, - kSessionId: startCallRes.openSessionID, - kApiKey: '46209962',//'46209962', + kToken: "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==",//tartCallRes.openTokenID, + kSessionId: '1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg',//startCallRes.openSessionID, + kApiKey: '47247954',//'46209962', vcId: patient.vcId, patientName: patient.fullName ?? (patient.firstName != null ? "${patient.firstName} ${patient.lastName}" : "-"), tokenID: await sharedPref.getString(TOKEN), @@ -79,7 +79,7 @@ class VideoCallService extends BaseService{ endCallReq.generalid = 'Cs2020@2016\$2958'; endCallReq.vCID = vCID; endCallReq.isDestroy = isPatient; - await _liveCarePatientServices.endCall(endCallReq); + // await _liveCarePatientServices.endCall(endCallReq); if (_liveCarePatientServices.hasError) { error = _liveCarePatientServices.error; } diff --git a/lib/core/viewModel/scan_qr_view_model.dart b/lib/core/viewModel/scan_qr_view_model.dart index ff934f79..86e975e3 100644 --- a/lib/core/viewModel/scan_qr_view_model.dart +++ b/lib/core/viewModel/scan_qr_view_model.dart @@ -13,7 +13,7 @@ class ScanQrViewModel extends BaseViewModel { await getDoctorProfile(); setState(ViewState.Busy); - await _scanQrService.getInPatient(requestModel, false); + await _scanQrService.getInPatient(requestModel, true); if (_scanQrService.hasError) { error = _scanQrService.error; 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 9aa95d16..d0117b40 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -343,14 +343,14 @@ class _PatientProfileScreenState extends State var asd = ""; } 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 = model.startCallRes.appointmentNo; + // patient.appointmentNo = model.startCallRes.appointmentNo; patient.episodeNo = 0; GifLoaderDialogUtils.hideDialog(context); From 3c2abb66c62d2ba59218a7ef77bcd9622059a66b Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 17 Jun 2021 10:29:52 +0300 Subject: [PATCH 65/72] add video call permissions --- .../com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 52bafdfb..833855a0 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 @@ -329,7 +329,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session @AfterPermissionGranted(RC_VIDEO_APP_PERM) private fun requestPermissions() { - val perms = arrayOf(Manifest.permission.INTERNET, Manifest.permission.CAMERA) + val perms = arrayOf(Manifest.permission.INTERNET, Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO, Manifest.permission.MODIFY_AUDIO_SETTINGS, Manifest.permission.CALL_PHONE) if (EasyPermissions.hasPermissions(requireContext(), *perms)) { try { mSession = Session.Builder(context, apiKey, sessionId).build() @@ -496,19 +496,19 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private fun onMiniCircleClicked(){ if (isCircle) { - videoCallContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_color)) - mSubscriberViewContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.remoteBackground)) dialog?.window?.setLayout( 400, 600 ) + videoCallContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_color)) + mSubscriberViewContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.remoteBackground)) } else { - videoCallContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) - mSubscriberViewContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) dialog?.window?.setLayout( 200, 200 ) + videoCallContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) + mSubscriberViewContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) } isCircle = !isCircle From 654a86a9b64d7cf8c58d8232c9d17916e276fdc4 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Thu, 17 Jun 2021 12:17:56 +0300 Subject: [PATCH 66/72] Add App Permissions Utils --- lib/core/service/VideoCallService.dart | 1 + .../patient_profile_screen.dart | 6 +- lib/util/NotificationPermissionUtils.dart | 42 +++++++++ lib/widgets/dialog/AskPermissionDialog.dart | 90 +++++++++++++++++++ 4 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 lib/util/NotificationPermissionUtils.dart create mode 100644 lib/widgets/dialog/AskPermissionDialog.dart diff --git a/lib/core/service/VideoCallService.dart b/lib/core/service/VideoCallService.dart index b3bc3c8d..53739c9c 100644 --- a/lib/core/service/VideoCallService.dart +++ b/lib/core/service/VideoCallService.dart @@ -70,6 +70,7 @@ class VideoCallService extends BaseService{ }); }); + } Future endCall(int vCID, bool isPatient) async { hasError = false; 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 d0117b40..ea61359a 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -13,6 +13,7 @@ import 'package:doctor_app_flutter/screens/live_care/end_call_screen.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_InPatient.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_other.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_search.dart'; +import 'package:doctor_app_flutter/util/NotificationPermissionUtils.dart'; import 'package:doctor_app_flutter/util/VideoChannel.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; @@ -354,7 +355,10 @@ class _PatientProfileScreenState extends State patient.episodeNo = 0; GifLoaderDialogUtils.hideDialog(context); - locator().openVideo(model.startCallRes, patient, callConnected, callDisconnected); + AppPermissionsUtils.requestVideoCallPermission(context: context,onTapGrant: (){ + locator().openVideo(model.startCallRes, patient, callConnected, callDisconnected); + }); + // await VideoChannel.openVideoCallScreen( // kToken: "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==",//model.startCallRes.openTokenID, diff --git a/lib/util/NotificationPermissionUtils.dart b/lib/util/NotificationPermissionUtils.dart new file mode 100644 index 00000000..8950fae3 --- /dev/null +++ b/lib/util/NotificationPermissionUtils.dart @@ -0,0 +1,42 @@ +import 'package:doctor_app_flutter/widgets/dialog/AskPermissionDialog.dart'; +import 'package:doctor_app_flutter/widgets/transitions/slide_up_page.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:permission_handler/permission_handler.dart'; + + +class AppPermissionsUtils { + + static requestVideoCallPermission({BuildContext context, String type,Function onTapGrant}) async { + + var cameraPermission = Permission.camera; + var microphonePermission = Permission.microphone; + PermissionStatus permissionCameraStatus = await cameraPermission.status; + PermissionStatus permissionMicrophoneStatus = await microphonePermission.status; + + if (permissionCameraStatus.isPermanentlyDenied || permissionMicrophoneStatus.isPermanentlyDenied) { + await _showPermissionDialog(context, type,onTapGrant); + } else if (!permissionCameraStatus.isGranted || !permissionMicrophoneStatus.isGranted) { + permissionCameraStatus = await cameraPermission.request(); + permissionMicrophoneStatus = await microphonePermission.request(); + if (permissionCameraStatus.isDenied || permissionMicrophoneStatus.isDenied) + await _showPermissionDialog(context, type,onTapGrant); + else + onTapGrant(); + } else if (permissionCameraStatus.isDenied || permissionMicrophoneStatus.isDenied) + await _showPermissionDialog(context, type,onTapGrant); + else + onTapGrant(); + } + + static _showPermissionDialog(BuildContext context, String type,Function onTapGrant) async { + Navigator.push( + context, SlideUpPageRoute(widget: AskPermissionDialog(type: type,onTapGrant: onTapGrant,))); + } + + static Future isVideoCallPermissionGranted() async { + PermissionStatus permissionCameraStatus = await Permission.camera.status; + PermissionStatus permissionMicrophoneStatus = await Permission.microphone.status; + return permissionCameraStatus.isGranted && permissionMicrophoneStatus.isGranted; + } +} diff --git a/lib/widgets/dialog/AskPermissionDialog.dart b/lib/widgets/dialog/AskPermissionDialog.dart new file mode 100644 index 00000000..58718373 --- /dev/null +++ b/lib/widgets/dialog/AskPermissionDialog.dart @@ -0,0 +1,90 @@ +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/buttons/secondary_button.dart'; +import 'package:eva_icons_flutter/eva_icons_flutter.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:permission_handler/permission_handler.dart'; + +class AskPermissionDialog extends StatefulWidget { + final String type; + final Function onTapGrant; + + AskPermissionDialog({this.type, this.onTapGrant}); + + @override + _AskPermissionDialogState createState() => _AskPermissionDialogState(); +} + +class _AskPermissionDialogState extends State { + getText() { + return "Turn on your Camera, Microphone to start video call"; + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + automaticallyImplyLeading: false, + elevation: 0.5, + actions: [ + Padding( + padding: EdgeInsets.only(right: 18.0), + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: Feedback.wrapForTap(() { + Navigator.pop(context); + }, context), + child: + Icon(EvaIcons.close, color: Theme.of(context).primaryColor), + ), + ) + ], + ), + body: Container( + margin: EdgeInsets.symmetric(horizontal: 48), + child: Center( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + AppText( + "🙋‍♀", + style: "headline1", + color: Colors.black, + ), + AppText( + "Don't miss out!", + style: "headline4", + color: Colors.black, + ), + SizedBox( + height: 8, + ), + AppText( + getText(), + color: Colors.grey, + style: "bodyText2", + textAlign: TextAlign.center, + ), + SizedBox( + height: MediaQuery.of(context).size.height / 6, + ), + AppButton( + fontColor: Theme.of(context).backgroundColor, + color: Colors.red[700], + title: "Turn On Camera, Microphone", + onPressed: () async { + openAppSettings().then((value) { + Navigator.pop(context); + widget.onTapGrant(); + }); + }, + ), + ], + ), + ), + ), + ); + } +} From c67f3d10ad1b43b2d9e7c7e289e5384f297da1c8 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 17 Jun 2021 13:54:50 +0300 Subject: [PATCH 67/72] fix circle video stream --- .../hmgDr/ui/fragment/VideoCallFragment.kt | 96 +++-- .../hmg/hmgDr/util/DynamicVideoRenderer.kt | 379 ++++++++++++++++++ .../util/ThumbnailCircleVideoRenderer.kt | 357 +++++++++++++++++ .../main/res/layout/activity_video_call.xml | 13 +- 4 files changed, 817 insertions(+), 28 deletions(-) create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/util/DynamicVideoRenderer.kt create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/util/ThumbnailCircleVideoRenderer.kt 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 833855a0..5b98b27d 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 @@ -27,6 +27,8 @@ import com.hmg.hmgDr.ui.VideoCallContract.VideoCallPresenter import com.hmg.hmgDr.ui.VideoCallContract.VideoCallView import com.hmg.hmgDr.ui.VideoCallPresenterImpl import com.hmg.hmgDr.ui.VideoCallResponseListener +import com.hmg.hmgDr.util.DynamicVideoRenderer +import com.hmg.hmgDr.util.ThumbnailCircleVideoRenderer import com.opentok.android.* import com.opentok.android.PublisherKit.PublisherListener import pub.devrel.easypermissions.AfterPermissionGranted @@ -60,6 +62,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private var mVolRunnable: Runnable? = null private var mConnectedRunnable: Runnable? = null + private lateinit var thumbnail_container: FrameLayout private lateinit var mPublisherViewContainer: FrameLayout private lateinit var mPublisherViewIcon: View private lateinit var mSubscriberViewContainer: FrameLayout @@ -220,6 +223,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session layoutName = view.findViewById(R.id.layout_name) layoutMini = view.findViewById(R.id.layout_mini) icMini = view.findViewById(R.id.ic_mini) + thumbnail_container = view.findViewById(R.id.thumbnail_container) mPublisherViewContainer = view.findViewById(R.id.local_video_view_container) mPublisherViewIcon = view.findViewById(R.id.local_video_view_icon) mSubscriberViewIcon = view.findViewById(R.id.remote_video_view_icon) @@ -345,12 +349,16 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onConnected(session: Session?) { Log.i(TAG, "Session Connected") - mPublisher = Publisher.Builder(requireContext()).build() + mPublisher = Publisher.Builder(requireContext()) +// .name("publisher") +// .renderer(ThumbnailCircleVideoRenderer(requireContext())) + .build() mPublisher!!.setPublisherListener(this) - mPublisherViewContainer.addView(mPublisher!!.view) - if (mPublisher!!.getView() is GLSurfaceView) { - (mPublisher!!.getView() as GLSurfaceView).setZOrderOnTop(true) + if (mPublisher!!.view is GLSurfaceView) { + (mPublisher!!.view as GLSurfaceView).setZOrderOnTop(true) } + + mPublisherViewContainer.addView(mPublisher!!.view) mSession!!.publish(mPublisher) if (!resume) { @@ -368,7 +376,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onError(session: Session, opentokError: OpentokError) { Log.d(TAG, "onError: Error (" + opentokError.message + ") in session " + session.sessionId) - // videoCallResponseListener?.errorHandle("Error (" + opentokError.message + ") in session ") + // videoCallResponseListener?.errorHandle("Error (" + opentokError.message + ") in session ") // dialog?.dismiss() } @@ -391,7 +399,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session return } if (mSubscriber!!.stream == stream) { - mSubscriberViewContainer!!.removeView(mSubscriber!!.view) + mSubscriberViewContainer.removeView(mSubscriber!!.view) mSubscriber!!.destroy() mSubscriber = null } @@ -408,13 +416,49 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onError(publisherKit: PublisherKit?, opentokError: OpentokError) { Log.d(VideoCallFragment.TAG, "onError: Error (" + opentokError.message + ") in publisher") - // videoCallResponseListener?.errorHandle("Error (" + opentokError.message + ") in publisher") + // videoCallResponseListener?.errorHandle("Error (" + opentokError.message + ") in publisher") // dialog?.dismiss() } override fun onVideoDataReceived(subscriberKit: SubscriberKit?) { mSubscriber!!.setStyle(BaseVideoRenderer.STYLE_VIDEO_SCALE, BaseVideoRenderer.STYLE_VIDEO_FILL) - mSubscriberViewContainer!!.addView(mSubscriber!!.view) + (mSubscriber!!.renderer as DynamicVideoRenderer).enableThumbnailCircle(false) + mSubscriberViewContainer.addView(mSubscriber!!.view) +// switchToThumbnailCircle() + } + + fun switchToThumbnailCircle() { + thumbnail_container.postDelayed({ + val view = mSubscriber!!.view + if (view.parent != null) { + (view.parent as ViewGroup).removeView(view) + } + if (view is GLSurfaceView) { + view.setZOrderOnTop(true) + if (mSubscriber!!.renderer is DynamicVideoRenderer) { + (mSubscriber!!.renderer as DynamicVideoRenderer).enableThumbnailCircle(true) + thumbnail_container.addView(view) + } + } + switchToFullScreenView() + }, 4000) + } + + fun switchToFullScreenView() { + mSubscriberViewContainer.postDelayed({ + val view = mSubscriber!!.view + if (view.parent != null) { + (view.parent as ViewGroup).removeView(view) + } + if (view is GLSurfaceView) { + view.setZOrderOnTop(false) + if (mSubscriber!!.renderer is DynamicVideoRenderer) { + (mSubscriber!!.renderer as DynamicVideoRenderer).enableThumbnailCircle(false) + mSubscriberViewContainer.addView(view) + } + } + switchToThumbnailCircle() + }, 4000) } override fun onVideoDisabled(subscriberKit: SubscriberKit?, s: String?) {} @@ -426,7 +470,9 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onVideoDisableWarningLifted(subscriberKit: SubscriberKit?) {} private fun subscribeToStream(stream: Stream) { - mSubscriber = Subscriber.Builder(requireContext(), stream).build() + mSubscriber = Subscriber.Builder(requireContext(), stream) + .renderer(DynamicVideoRenderer(requireContext())) + .build() mSubscriber!!.setVideoListener(this) mSession!!.subscribe(mSubscriber) } @@ -488,31 +534,29 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session disconnectSession() } - private fun miniCircleDoubleTap(){ - if (isCircle){ + private fun miniCircleDoubleTap() { + if (isCircle) { onMiniCircleClicked() } } - private fun onMiniCircleClicked(){ + private fun onMiniCircleClicked() { if (isCircle) { dialog?.window?.setLayout( 400, 600 ) - videoCallContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_color)) - mSubscriberViewContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.remoteBackground)) + (mSubscriber!!.renderer as DynamicVideoRenderer).enableThumbnailCircle(false) } else { dialog?.window?.setLayout( - 200, - 200 + 300, + 300 ) - videoCallContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) - mSubscriberViewContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) + (mSubscriber!!.renderer as DynamicVideoRenderer).enableThumbnailCircle(true) } isCircle = !isCircle - if(isCircle){ + if (isCircle) { controlPanel.visibility = View.GONE layoutMini.visibility = View.GONE } else { @@ -548,16 +592,16 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session val btnMinimizeLayoutParam: ConstraintLayout.LayoutParams = btnMinimize.layoutParams as ConstraintLayout.LayoutParams val mCallBtnLayoutParam: ConstraintLayout.LayoutParams = mCallBtn.layoutParams as ConstraintLayout.LayoutParams - val localPreviewMargin : Int = context!!.resources.getDimension(R.dimen.local_preview_margin_top).toInt() - val localPreviewWidth : Int = context!!.resources.getDimension(R.dimen.local_preview_width).toInt() - val localPreviewHeight : Int = context!!.resources.getDimension(R.dimen.local_preview_height).toInt() + val localPreviewMargin: Int = context!!.resources.getDimension(R.dimen.local_preview_margin_top).toInt() + val localPreviewWidth: Int = context!!.resources.getDimension(R.dimen.local_preview_width).toInt() + val localPreviewHeight: Int = context!!.resources.getDimension(R.dimen.local_preview_height).toInt() // val localPreviewIconSize: Int = context!!.resources.getDimension(R.dimen.local_back_icon_size).toInt() // val localPreviewMarginSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_margin_small).toInt() // val localPreviewWidthSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_width_small).toInt() // val localPreviewHeightSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_height_small).toInt() // val localPreviewIconSmall: Int = context!!.resources.getDimension(R.dimen.local_back_icon_size_small).toInt() // val localPreviewLayoutIconParam : FrameLayout.LayoutParams - val localPreviewLayoutParam : RelativeLayout.LayoutParams = mPublisherViewContainer.layoutParams as RelativeLayout.LayoutParams + val localPreviewLayoutParam: RelativeLayout.LayoutParams = mPublisherViewContainer.layoutParams as RelativeLayout.LayoutParams val remotePreviewIconSize: Int = context!!.resources.getDimension(R.dimen.remote_back_icon_size).toInt() val remotePreviewIconSizeSmall: Int = context!!.resources.getDimension(R.dimen.remote_back_icon_size_small).toInt() @@ -611,7 +655,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session remotePreviewLayoutParam.width = remotePreviewIconSizeSmall remotePreviewLayoutParam.height = remotePreviewIconSizeSmall - if(isCircle){ + if (isCircle) { controlPanel.visibility = View.GONE layoutMini.visibility = View.GONE } else { @@ -651,7 +695,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session isSpeckerClicked = !isSpeckerClicked mSubscriber!!.subscribeToAudio = !isSpeckerClicked val res = if (isSpeckerClicked) R.drawable.audio_disabled else R.drawable.audio_enabled - mspeckerBtn!!.setImageResource(res) + mspeckerBtn.setImageResource(res) } } @@ -722,7 +766,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } private fun showControlPanelTemporarily() { - if (!isCircle){ + if (!isCircle) { controlPanel.visibility = View.VISIBLE mVolHandler!!.removeCallbacks(mVolRunnable!!) mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/util/DynamicVideoRenderer.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/util/DynamicVideoRenderer.kt new file mode 100644 index 00000000..1a307eb5 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/util/DynamicVideoRenderer.kt @@ -0,0 +1,379 @@ +package com.hmg.hmgDr.util + +import android.content.Context +import android.content.res.Resources +import android.graphics.PixelFormat +import android.opengl.GLES20 +import android.opengl.GLSurfaceView +import android.opengl.Matrix +import android.view.View +import com.opentok.android.BaseVideoRenderer +import java.nio.ByteBuffer +import java.nio.ByteOrder +import java.nio.FloatBuffer +import java.nio.ShortBuffer +import java.util.concurrent.locks.ReentrantLock +import javax.microedition.khronos.egl.EGLConfig +import javax.microedition.khronos.opengles.GL10 + +/* +* https://nhancv.medium.com/android-how-to-make-a-circular-view-as-a-thumbnail-of-opentok-27992aee15c9 +* to solve make circle video stream +* */ + +class DynamicVideoRenderer(private val mContext: Context) : BaseVideoRenderer() { + private val mView: GLSurfaceView = GLSurfaceView(mContext) + private val mRenderer: MyRenderer + + interface DynamicVideoRendererMetadataListener { + fun onMetadataReady(metadata: ByteArray?) + } + + fun setDynamicVideoRendererMetadataListener(metadataListener: DynamicVideoRendererMetadataListener?) { + mRenderer.metadataListener = metadataListener + } + + fun enableThumbnailCircle(enable: Boolean) { + mRenderer.requestEnableThumbnailCircle = enable + } + + internal class MyRenderer : GLSurfaceView.Renderer { + var mTextureIds = IntArray(3) + var mScaleMatrix = FloatArray(16) + private val mVertexBuffer: FloatBuffer + private val mTextureBuffer: FloatBuffer + private val mDrawListBuffer: ShortBuffer + var requestEnableThumbnailCircle = false + var mVideoFitEnabled = true + var mVideoDisabled = false + private val mVertexIndex = shortArrayOf(0, 1, 2, 0, 2, 3) // order to draw + + // vertices + private val vertexShaderCode = """uniform mat4 uMVPMatrix;attribute vec4 aPosition; +attribute vec2 aTextureCoord; +varying vec2 vTextureCoord; +void main() { + gl_Position = uMVPMatrix * aPosition; + vTextureCoord = aTextureCoord; +} +""" + private val fragmentShaderCode = """precision mediump float; +uniform sampler2D Ytex; +uniform sampler2D Utex,Vtex; +uniform int enableCircle; +uniform vec2 radiusDp; +varying vec2 vTextureCoord; +void main(void) { + float nx,ny,r,g,b,y,u,v; + mediump vec4 txl,ux,vx; nx=vTextureCoord[0]; + ny=vTextureCoord[1]; + y=texture2D(Ytex,vec2(nx,ny)).r; + u=texture2D(Utex,vec2(nx,ny)).r; + v=texture2D(Vtex,vec2(nx,ny)).r; + y=1.1643*(y-0.0625); + u=u-0.5; + v=v-0.5; + r=y+1.5958*v; + g=y-0.39173*u-0.81290*v; + b=y+2.017*u; + if (enableCircle > 0) { + float radius = 0.5; + vec4 color0 = vec4(0.0, 0.0, 0.0, 0.0); + vec4 color1 = vec4(r, g, b, 1.0); + vec2 st = (gl_FragCoord.xy/radiusDp.xy); float dist = radius - distance(st,vec2(0.5)); + float t = 1.0; + if (dist < 0.0) t = 0.0; + gl_FragColor = mix(color0, color1, t); + } + else { + gl_FragColor = vec4(r, g, b, 1.0); + } +} +""" + var mFrameLock = ReentrantLock() + var mCurrentFrame: Frame? = null + private var mProgram = 0 + private var mTextureWidth = 0 + private var mTextureHeight = 0 + private var mViewportWidth = 0 + private var mViewportHeight = 0 + override fun onSurfaceCreated(gl: GL10, config: EGLConfig) { + gl.glClearColor(0f, 0f, 0f, 1f) + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) + val vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, + vertexShaderCode) + val fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, + fragmentShaderCode) + mProgram = GLES20.glCreateProgram() // create empty OpenGL ES + // Program + GLES20.glAttachShader(mProgram, vertexShader) // add the vertex + // shader to program + GLES20.glAttachShader(mProgram, fragmentShader) // add the fragment + // shader to + // program + GLES20.glLinkProgram(mProgram) + val positionHandle = GLES20.glGetAttribLocation(mProgram, + "aPosition") + val textureHandle = GLES20.glGetAttribLocation(mProgram, + "aTextureCoord") + GLES20.glVertexAttribPointer(positionHandle, COORDS_PER_VERTEX, + GLES20.GL_FLOAT, false, COORDS_PER_VERTEX * 4, + mVertexBuffer) + GLES20.glEnableVertexAttribArray(positionHandle) + GLES20.glVertexAttribPointer(textureHandle, + TEXTURECOORDS_PER_VERTEX, GLES20.GL_FLOAT, false, + TEXTURECOORDS_PER_VERTEX * 4, mTextureBuffer) + GLES20.glEnableVertexAttribArray(textureHandle) + GLES20.glUseProgram(mProgram) + var i = GLES20.glGetUniformLocation(mProgram, "Ytex") + GLES20.glUniform1i(i, 0) /* Bind Ytex to texture unit 0 */ + i = GLES20.glGetUniformLocation(mProgram, "Utex") + GLES20.glUniform1i(i, 1) /* Bind Utex to texture unit 1 */ + i = GLES20.glGetUniformLocation(mProgram, "Vtex") + GLES20.glUniform1i(i, 2) /* Bind Vtex to texture unit 2 */ + val radiusDpLocation = GLES20.glGetUniformLocation(mProgram, "radiusDp") + val radiusDp = (Resources.getSystem().displayMetrics.density * THUMBNAIL_SIZE).toInt() + GLES20.glUniform2f(radiusDpLocation, radiusDp.toFloat(), radiusDp.toFloat()) + mTextureWidth = 0 + mTextureHeight = 0 + } + + fun enableThumbnailCircle(enable: Boolean) { + GLES20.glUseProgram(mProgram) + val enableCircleLocation = GLES20.glGetUniformLocation(mProgram, "enableCircle") + GLES20.glUniform1i(enableCircleLocation, if (enable) 1 else 0) + } + + fun setupTextures(frame: Frame) { + if (mTextureIds[0] != 0) { + GLES20.glDeleteTextures(3, mTextureIds, 0) + } + GLES20.glGenTextures(3, mTextureIds, 0) + val w = frame.width + val h = frame.height + val hw = w + 1 shr 1 + val hh = h + 1 shr 1 + initializeTexture(GLES20.GL_TEXTURE0, mTextureIds[0], w, h) + initializeTexture(GLES20.GL_TEXTURE1, mTextureIds[1], hw, hh) + initializeTexture(GLES20.GL_TEXTURE2, mTextureIds[2], hw, hh) + mTextureWidth = frame.width + mTextureHeight = frame.height + } + + fun updateTextures(frame: Frame) { + val width = frame.width + val height = frame.height + val half_width = width + 1 shr 1 + val half_height = height + 1 shr 1 + val y_size = width * height + val uv_size = half_width * half_height + val bb = frame.buffer + // If we are reusing this frame, make sure we reset position and + // limit + bb.clear() + if (bb.remaining() == y_size + uv_size * 2) { + bb.position(0) + GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT, 1) + GLES20.glPixelStorei(GLES20.GL_PACK_ALIGNMENT, 1) + GLES20.glActiveTexture(GLES20.GL_TEXTURE0) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIds[0]) + GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, width, + height, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, + bb) + bb.position(y_size) + GLES20.glActiveTexture(GLES20.GL_TEXTURE1) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIds[1]) + GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, + half_width, half_height, GLES20.GL_LUMINANCE, + GLES20.GL_UNSIGNED_BYTE, bb) + bb.position(y_size + uv_size) + GLES20.glActiveTexture(GLES20.GL_TEXTURE2) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIds[2]) + GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, + half_width, half_height, GLES20.GL_LUMINANCE, + GLES20.GL_UNSIGNED_BYTE, bb) + } else { + mTextureWidth = 0 + mTextureHeight = 0 + } + } + + override fun onSurfaceChanged(gl: GL10, width: Int, height: Int) { + GLES20.glViewport(0, 0, width, height) + mViewportWidth = width + mViewportHeight = height + } + + var metadataListener: DynamicVideoRendererMetadataListener? = null + override fun onDrawFrame(gl: GL10) { + gl.glClearColor(0f, 0f, 0f, 0f) + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) + mFrameLock.lock() + if (mCurrentFrame != null && !mVideoDisabled) { + GLES20.glUseProgram(mProgram) + if (mTextureWidth != mCurrentFrame!!.width + || mTextureHeight != mCurrentFrame!!.height) { + setupTextures(mCurrentFrame!!) + } + updateTextures(mCurrentFrame!!) + Matrix.setIdentityM(mScaleMatrix, 0) + var scaleX = 1.0f + var scaleY = 1.0f + val ratio = (mCurrentFrame!!.width.toFloat() + / mCurrentFrame!!.height) + val vratio = mViewportWidth.toFloat() / mViewportHeight + if (mVideoFitEnabled) { + if (ratio > vratio) { + scaleY = vratio / ratio + } else { + scaleX = ratio / vratio + } + } else { + if (ratio < vratio) { + scaleY = vratio / ratio + } else { + scaleX = ratio / vratio + } + } + Matrix.scaleM(mScaleMatrix, 0, + scaleX * if (mCurrentFrame!!.isMirroredX) -1.0f else 1.0f, + scaleY, 1f) + metadataListener?.onMetadataReady(mCurrentFrame!!.metadata) + val mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, + "uMVPMatrix") + GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, + mScaleMatrix, 0) + enableThumbnailCircle(requestEnableThumbnailCircle) + GLES20.glDrawElements(GLES20.GL_TRIANGLES, mVertexIndex.size, + GLES20.GL_UNSIGNED_SHORT, mDrawListBuffer) + } else { + //black frame when video is disabled + gl.glClearColor(0f, 0f, 0f, 1f) + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) + } + mFrameLock.unlock() + } + + fun displayFrame(frame: Frame?) { + mFrameLock.lock() + if (mCurrentFrame != null) { + mCurrentFrame!!.recycle() + } + mCurrentFrame = frame + mFrameLock.unlock() + } + + fun disableVideo(b: Boolean) { + mFrameLock.lock() + mVideoDisabled = b + if (mVideoDisabled) { + if (mCurrentFrame != null) { + mCurrentFrame!!.recycle() + } + mCurrentFrame = null + } + mFrameLock.unlock() + } + + fun enableVideoFit(enableVideoFit: Boolean) { + mVideoFitEnabled = enableVideoFit + } + + companion object { + // number of coordinates per vertex in this array + const val COORDS_PER_VERTEX = 3 + const val TEXTURECOORDS_PER_VERTEX = 2 + var mXYZCoords = floatArrayOf( + -1.0f, 1.0f, 0.0f, // top left + -1.0f, -1.0f, 0.0f, // bottom left + 1.0f, -1.0f, 0.0f, // bottom right + 1.0f, 1.0f, 0.0f // top right + ) + var mUVCoords = floatArrayOf(0f, 0f, 0f, 1f, 1f, 1f, 1f, 0f) + fun initializeTexture(name: Int, id: Int, width: Int, height: Int) { + GLES20.glActiveTexture(name) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, id) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST.toFloat()) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR.toFloat()) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE.toFloat()) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE.toFloat()) + GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, + width, height, 0, GLES20.GL_LUMINANCE, + GLES20.GL_UNSIGNED_BYTE, null) + } + + fun loadShader(type: Int, shaderCode: String?): Int { + val shader = GLES20.glCreateShader(type) + GLES20.glShaderSource(shader, shaderCode) + GLES20.glCompileShader(shader) + return shader + } + } + + init { + val bb = ByteBuffer.allocateDirect(mXYZCoords.size * 4) + bb.order(ByteOrder.nativeOrder()) + mVertexBuffer = bb.asFloatBuffer() + mVertexBuffer.put(mXYZCoords) + mVertexBuffer.position(0) + val tb = ByteBuffer.allocateDirect(mUVCoords.size * 4) + tb.order(ByteOrder.nativeOrder()) + mTextureBuffer = tb.asFloatBuffer() + mTextureBuffer.put(mUVCoords) + mTextureBuffer.position(0) + val dlb = ByteBuffer.allocateDirect(mVertexIndex.size * 2) + dlb.order(ByteOrder.nativeOrder()) + mDrawListBuffer = dlb.asShortBuffer() + mDrawListBuffer.put(mVertexIndex) + mDrawListBuffer.position(0) + } + } + + override fun onFrame(frame: Frame) { + mRenderer.displayFrame(frame) + mView.requestRender() + } + + override fun setStyle(key: String, value: String) { + if (STYLE_VIDEO_SCALE == key) { + if (STYLE_VIDEO_FIT == value) { + mRenderer.enableVideoFit(true) + } else if (STYLE_VIDEO_FILL == value) { + mRenderer.enableVideoFit(false) + } + } + } + + override fun onVideoPropertiesChanged(videoEnabled: Boolean) { + mRenderer.disableVideo(!videoEnabled) + } + + override fun getView(): View { + return mView + } + + override fun onPause() { + mView.onPause() + } + + override fun onResume() { + mView.onResume() + } + + companion object { + private const val THUMBNAIL_SIZE = 90 //in dp + } + + init { + mView.setEGLContextClientVersion(2) + mView.setEGLConfigChooser(8, 8, 8, 8, 16, 0) + mView.holder.setFormat(PixelFormat.TRANSLUCENT) + mRenderer = MyRenderer() + mView.setRenderer(mRenderer) + mView.renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/util/ThumbnailCircleVideoRenderer.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/util/ThumbnailCircleVideoRenderer.kt new file mode 100644 index 00000000..b9b5a245 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/util/ThumbnailCircleVideoRenderer.kt @@ -0,0 +1,357 @@ +package com.hmg.hmgDr.util + +import android.content.Context +import android.content.res.Resources +import android.graphics.PixelFormat +import android.opengl.GLES20 +import android.opengl.GLSurfaceView +import android.opengl.Matrix +import android.view.View +import com.opentok.android.BaseVideoRenderer +import java.nio.ByteBuffer +import java.nio.ByteOrder +import java.nio.FloatBuffer +import java.nio.ShortBuffer +import java.util.concurrent.locks.ReentrantLock +import javax.microedition.khronos.egl.EGLConfig +import javax.microedition.khronos.opengles.GL10 + + +class ThumbnailCircleVideoRenderer(private val mContext: Context) : BaseVideoRenderer() { + private val mView: GLSurfaceView = GLSurfaceView(mContext) + private val mRenderer: MyRenderer + + interface ThumbnailCircleVideoRendererMetadataListener { + fun onMetadataReady(metadata: ByteArray?) + } + + fun setThumbnailCircleVideoRendererMetadataListener(metadataListener: ThumbnailCircleVideoRendererMetadataListener?) { + mRenderer.metadataListener = metadataListener + } + + internal class MyRenderer : GLSurfaceView.Renderer { + var mTextureIds = IntArray(3) + var mScaleMatrix = FloatArray(16) + private val mVertexBuffer: FloatBuffer + private val mTextureBuffer: FloatBuffer + private val mDrawListBuffer: ShortBuffer + var mVideoFitEnabled = true + var mVideoDisabled = false + private val mVertexIndex = shortArrayOf(0, 1, 2, 0, 2, 3) // order to draw + + // vertices + private val vertexShaderCode = """uniform mat4 uMVPMatrix;attribute vec4 aPosition; +attribute vec2 aTextureCoord; +varying vec2 vTextureCoord; +void main() { + gl_Position = uMVPMatrix * aPosition; + vTextureCoord = aTextureCoord; +} +""" + private val fragmentShaderCode = """precision mediump float; +uniform sampler2D Ytex; +uniform sampler2D Utex,Vtex; +uniform vec2 radiusDp; +varying vec2 vTextureCoord; +void main(void) { + float nx,ny,r,g,b,y,u,v; + mediump vec4 txl,ux,vx; nx=vTextureCoord[0]; + ny=vTextureCoord[1]; + y=texture2D(Ytex,vec2(nx,ny)).r; + u=texture2D(Utex,vec2(nx,ny)).r; + v=texture2D(Vtex,vec2(nx,ny)).r; + y=1.1643*(y-0.0625); + u=u-0.5; + v=v-0.5; + r=y+1.5958*v; + g=y-0.39173*u-0.81290*v; + b=y+2.017*u; + float radius = 0.5; + vec4 color0 = vec4(0.0, 0.0, 0.0, 0.0); + vec4 color1 = vec4(r, g, b, 1.0); + vec2 st = (gl_FragCoord.xy/radiusDp.xy); float dist = radius - distance(st,vec2(0.5)); + float t = 1.0; + if (dist < 0.0) t = 0.0; + gl_FragColor = mix(color0, color1, t); +} +""" + var mFrameLock = ReentrantLock() + var mCurrentFrame: Frame? = null + private var mProgram = 0 + private var mTextureWidth = 0 + private var mTextureHeight = 0 + private var mViewportWidth = 0 + private var mViewportHeight = 0 + override fun onSurfaceCreated(gl: GL10, config: EGLConfig) { + gl.glClearColor(0f, 0f, 0f, 1f) + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) + val vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, + vertexShaderCode) + val fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, + fragmentShaderCode) + mProgram = GLES20.glCreateProgram() // create empty OpenGL ES + // Program + GLES20.glAttachShader(mProgram, vertexShader) // add the vertex + // shader to program + GLES20.glAttachShader(mProgram, fragmentShader) // add the fragment + // shader to + // program + GLES20.glLinkProgram(mProgram) + val positionHandle = GLES20.glGetAttribLocation(mProgram, + "aPosition") + val textureHandle = GLES20.glGetAttribLocation(mProgram, + "aTextureCoord") + GLES20.glVertexAttribPointer(positionHandle, COORDS_PER_VERTEX, + GLES20.GL_FLOAT, false, COORDS_PER_VERTEX * 4, + mVertexBuffer) + GLES20.glEnableVertexAttribArray(positionHandle) + GLES20.glVertexAttribPointer(textureHandle, + TEXTURECOORDS_PER_VERTEX, GLES20.GL_FLOAT, false, + TEXTURECOORDS_PER_VERTEX * 4, mTextureBuffer) + GLES20.glEnableVertexAttribArray(textureHandle) + GLES20.glUseProgram(mProgram) + var i = GLES20.glGetUniformLocation(mProgram, "Ytex") + GLES20.glUniform1i(i, 0) /* Bind Ytex to texture unit 0 */ + i = GLES20.glGetUniformLocation(mProgram, "Utex") + GLES20.glUniform1i(i, 1) /* Bind Utex to texture unit 1 */ + i = GLES20.glGetUniformLocation(mProgram, "Vtex") + GLES20.glUniform1i(i, 2) /* Bind Vtex to texture unit 2 */ + val radiusDpLocation = GLES20.glGetUniformLocation(mProgram, "radiusDp") + val radiusDp = (Resources.getSystem().displayMetrics.density * THUMBNAIL_SIZE).toInt() + GLES20.glUniform2f(radiusDpLocation, radiusDp.toFloat(), radiusDp.toFloat()) + mTextureWidth = 0 + mTextureHeight = 0 + } + + fun setupTextures(frame: Frame) { + if (mTextureIds[0] != 0) { + GLES20.glDeleteTextures(3, mTextureIds, 0) + } + GLES20.glGenTextures(3, mTextureIds, 0) + val w = frame.width + val h = frame.height + val hw = w + 1 shr 1 + val hh = h + 1 shr 1 + initializeTexture(GLES20.GL_TEXTURE0, mTextureIds[0], w, h) + initializeTexture(GLES20.GL_TEXTURE1, mTextureIds[1], hw, hh) + initializeTexture(GLES20.GL_TEXTURE2, mTextureIds[2], hw, hh) + mTextureWidth = frame.width + mTextureHeight = frame.height + } + + fun updateTextures(frame: Frame) { + val width = frame.width + val height = frame.height + val half_width = width + 1 shr 1 + val half_height = height + 1 shr 1 + val y_size = width * height + val uv_size = half_width * half_height + val bb = frame.buffer + // If we are reusing this frame, make sure we reset position and + // limit + bb.clear() + if (bb.remaining() == y_size + uv_size * 2) { + bb.position(0) + GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT, 1) + GLES20.glPixelStorei(GLES20.GL_PACK_ALIGNMENT, 1) + GLES20.glActiveTexture(GLES20.GL_TEXTURE0) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIds[0]) + GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, width, + height, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, + bb) + bb.position(y_size) + GLES20.glActiveTexture(GLES20.GL_TEXTURE1) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIds[1]) + GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, + half_width, half_height, GLES20.GL_LUMINANCE, + GLES20.GL_UNSIGNED_BYTE, bb) + bb.position(y_size + uv_size) + GLES20.glActiveTexture(GLES20.GL_TEXTURE2) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIds[2]) + GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, + half_width, half_height, GLES20.GL_LUMINANCE, + GLES20.GL_UNSIGNED_BYTE, bb) + } else { + mTextureWidth = 0 + mTextureHeight = 0 + } + } + + override fun onSurfaceChanged(gl: GL10, width: Int, height: Int) { + GLES20.glViewport(0, 0, width, height) + mViewportWidth = width + mViewportHeight = height + } + + var metadataListener: ThumbnailCircleVideoRendererMetadataListener? = null + override fun onDrawFrame(gl: GL10) { + gl.glClearColor(0f, 0f, 0f, 0f) + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) + mFrameLock.lock() + if (mCurrentFrame != null && !mVideoDisabled) { + GLES20.glUseProgram(mProgram) + if (mTextureWidth != mCurrentFrame!!.width + || mTextureHeight != mCurrentFrame!!.height) { + setupTextures(mCurrentFrame!!) + } + updateTextures(mCurrentFrame!!) + Matrix.setIdentityM(mScaleMatrix, 0) + var scaleX = 1.0f + var scaleY = 1.0f + val ratio = (mCurrentFrame!!.width.toFloat() + / mCurrentFrame!!.height) + val vratio = mViewportWidth.toFloat() / mViewportHeight + if (mVideoFitEnabled) { + if (ratio > vratio) { + scaleY = vratio / ratio + } else { + scaleX = ratio / vratio + } + } else { + if (ratio < vratio) { + scaleY = vratio / ratio + } else { + scaleX = ratio / vratio + } + } + Matrix.scaleM(mScaleMatrix, 0, + scaleX * if (mCurrentFrame!!.isMirroredX) -1.0f else 1.0f, + scaleY, 1f) + metadataListener?.onMetadataReady(mCurrentFrame!!.metadata) + val mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, + "uMVPMatrix") + GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, + mScaleMatrix, 0) + GLES20.glDrawElements(GLES20.GL_TRIANGLES, mVertexIndex.size, + GLES20.GL_UNSIGNED_SHORT, mDrawListBuffer) + } else { + //black frame when video is disabled + gl.glClearColor(0f, 0f, 0f, 1f) + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) + } + mFrameLock.unlock() + } + + fun displayFrame(frame: Frame?) { + mFrameLock.lock() + if (mCurrentFrame != null) { + mCurrentFrame!!.recycle() + } + mCurrentFrame = frame + mFrameLock.unlock() + } + + fun disableVideo(b: Boolean) { + mFrameLock.lock() + mVideoDisabled = b + if (mVideoDisabled) { + if (mCurrentFrame != null) { + mCurrentFrame!!.recycle() + } + mCurrentFrame = null + } + mFrameLock.unlock() + } + + fun enableVideoFit(enableVideoFit: Boolean) { + mVideoFitEnabled = enableVideoFit + } + + companion object { + // number of coordinates per vertex in this array + const val COORDS_PER_VERTEX = 3 + const val TEXTURECOORDS_PER_VERTEX = 2 + var mXYZCoords = floatArrayOf( + -1.0f, 1.0f, 0.0f, // top left + -1.0f, -1.0f, 0.0f, // bottom left + 1.0f, -1.0f, 0.0f, // bottom right + 1.0f, 1.0f, 0.0f // top right + ) + var mUVCoords = floatArrayOf(0f, 0f, 0f, 1f, 1f, 1f, 1f, 0f) + fun initializeTexture(name: Int, id: Int, width: Int, height: Int) { + GLES20.glActiveTexture(name) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, id) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST.toFloat()) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR.toFloat()) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE.toFloat()) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE.toFloat()) + GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, + width, height, 0, GLES20.GL_LUMINANCE, + GLES20.GL_UNSIGNED_BYTE, null) + } + + fun loadShader(type: Int, shaderCode: String?): Int { + val shader = GLES20.glCreateShader(type) + GLES20.glShaderSource(shader, shaderCode) + GLES20.glCompileShader(shader) + return shader + } + } + + init { + val bb = ByteBuffer.allocateDirect(mXYZCoords.size * 4) + bb.order(ByteOrder.nativeOrder()) + mVertexBuffer = bb.asFloatBuffer() + mVertexBuffer.put(mXYZCoords) + mVertexBuffer.position(0) + val tb = ByteBuffer.allocateDirect(mUVCoords.size * 4) + tb.order(ByteOrder.nativeOrder()) + mTextureBuffer = tb.asFloatBuffer() + mTextureBuffer.put(mUVCoords) + mTextureBuffer.position(0) + val dlb = ByteBuffer.allocateDirect(mVertexIndex.size * 2) + dlb.order(ByteOrder.nativeOrder()) + mDrawListBuffer = dlb.asShortBuffer() + mDrawListBuffer.put(mVertexIndex) + mDrawListBuffer.position(0) + } + } + + override fun onFrame(frame: Frame) { + mRenderer.displayFrame(frame) + mView.requestRender() + } + + override fun setStyle(key: String, value: String) { + if (STYLE_VIDEO_SCALE == key) { + if (STYLE_VIDEO_FIT == value) { + mRenderer.enableVideoFit(true) + } else if (STYLE_VIDEO_FILL == value) { + mRenderer.enableVideoFit(false) + } + } + } + + override fun onVideoPropertiesChanged(videoEnabled: Boolean) { + mRenderer.disableVideo(!videoEnabled) + } + + override fun getView(): View { + return mView + } + + override fun onPause() { + mView.onPause() + } + + override fun onResume() { + mView.onResume() + } + + companion object { + private const val THUMBNAIL_SIZE = 90 //in dp + } + + init { + mView.setEGLContextClientVersion(2) + mView.setEGLConfigChooser(8, 8, 8, 8, 16, 0) + mView.holder.setFormat(PixelFormat.TRANSLUCENT) + mRenderer = MyRenderer() + mView.setRenderer(mRenderer) + mView.renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY + } +} 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 a7470da3..a54e57b3 100644 --- a/android/app/src/main/res/layout/activity_video_call.xml +++ b/android/app/src/main/res/layout/activity_video_call.xml @@ -97,8 +97,7 @@ android:layout_alignParentTop="true" android:layout_alignParentEnd="true" android:layout_marginTop="@dimen/local_preview_margin_top" - android:layout_marginEnd="@dimen/local_preview_margin_top" - android:background="@color/localBackground"> + android:layout_marginEnd="@dimen/local_preview_margin_top"> + + Date: Thu, 17 Jun 2021 15:43:49 +0300 Subject: [PATCH 68/72] fix disconected stream --- .../kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) 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 5b98b27d..d89c939c 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 @@ -371,6 +371,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session Log.d(TAG, "onDisconnected: disconnected from session " + session.sessionId) mSession = null cmTimer.stop() + disconnectSession() } override fun onError(session: Session, opentokError: OpentokError) { @@ -477,11 +478,6 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session mSession!!.subscribe(mSubscriber) } - override fun dismiss() { - videoCallResponseListener?.onCallFinished(1000) - super.dismiss() - } - private fun disconnectSession() { if (mSession == null) { videoCallResponseListener?.onCallFinished(Activity.RESULT_CANCELED) @@ -489,6 +485,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session dialog?.dismiss() return } + if (mSubscriber != null) { mSubscriberViewContainer.removeView(mSubscriber!!.view) mSession!!.unsubscribe(mSubscriber) @@ -503,6 +500,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } mSession!!.disconnect() countDownTimer?.cancel() + videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(16, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) dialog?.dismiss() } From 02f43d6e61ed77836baa035df98f108b96d23431 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 17 Jun 2021 16:08:03 +0300 Subject: [PATCH 69/72] fix timer issue --- .../kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt | 4 +++- .../profile/profile_screen/patient_profile_screen.dart | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) 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 d89c939c..be1ed9d4 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 @@ -365,6 +365,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session cmTimer.base = SystemClock.elapsedRealtime() } cmTimer.start() + videoCallResponseListener?.minimizeVideoEvent(true) } override fun onDisconnected(session: Session) { @@ -372,6 +373,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session mSession = null cmTimer.stop() disconnectSession() + videoCallResponseListener?.minimizeVideoEvent(false) } override fun onError(session: Session, opentokError: OpentokError) { @@ -581,7 +583,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session btnMinimize.setImageResource(res) setViewsVisibility() - videoCallResponseListener?.minimizeVideoEvent(!isFullScreen) +// videoCallResponseListener?.minimizeVideoEvent(!isFullScreen) } private fun setViewsVisibility() { 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 ea61359a..0a05b596 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -105,7 +105,7 @@ class _PatientProfileScreenState extends State StreamSubscription callTimer; callConnected(){ - callTimer = CountdownTimer(Duration(minutes: 1), Duration(seconds: 1)).listen(null) + callTimer = CountdownTimer(Duration(minutes: 90), Duration(seconds: 1)).listen(null) ..onDone(() { callTimer.cancel(); }) From c585cbb5be345162bb171e34bcd352f9f4c2c181 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 17 Jun 2021 16:35:43 +0300 Subject: [PATCH 70/72] fix timer issue --- .../hmg/hmgDr/ui/fragment/VideoCallFragment.kt | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) 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 be1ed9d4..35e28b23 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 @@ -546,16 +546,27 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session 400, 600 ) - (mSubscriber!!.renderer as DynamicVideoRenderer).enableThumbnailCircle(false) } else { dialog?.window?.setLayout( 300, 300 ) - (mSubscriber!!.renderer as DynamicVideoRenderer).enableThumbnailCircle(true) } isCircle = !isCircle + if (mSubscriber != null) { + (mSubscriber!!.renderer as DynamicVideoRenderer).enableThumbnailCircle(isCircle) + } else { + if (isCircle) { + videoCallContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) + mSubscriberViewContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) + } else { + videoCallContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_color)) + mSubscriberViewContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_color)) + } + + } + if (isCircle) { controlPanel.visibility = View.GONE layoutMini.visibility = View.GONE From 61c94f85b271affbeb16ba41ec10b3c7ee5a1982 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Thu, 17 Jun 2021 16:47:31 +0300 Subject: [PATCH 71/72] fix the end call --- lib/core/service/VideoCallService.dart | 8 +-- .../viewModel/patient-referral-viewmodel.dart | 2 +- lib/models/patient/patiant_info_model.dart | 11 ++-- lib/screens/live_care/end_call_screen.dart | 11 +++- .../patient_profile_screen.dart | 56 ++---------------- lib/screens/procedures/ProcedureCard.dart | 59 +------------------ 6 files changed, 28 insertions(+), 119 deletions(-) diff --git a/lib/core/service/VideoCallService.dart b/lib/core/service/VideoCallService.dart index 53739c9c..f72544a0 100644 --- a/lib/core/service/VideoCallService.dart +++ b/lib/core/service/VideoCallService.dart @@ -27,9 +27,9 @@ class VideoCallService extends BaseService{ this.patient = patientModel; DoctorProfileModel doctorProfile = await getDoctorProfile(isGetProfile: true); await VideoChannel.openVideoCallScreen( - kToken: "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==",//tartCallRes.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 ? "${patient.firstName} ${patient.lastName}" : "-"), tokenID: await sharedPref.getString(TOKEN), @@ -80,7 +80,7 @@ class VideoCallService extends BaseService{ endCallReq.generalid = 'Cs2020@2016\$2958'; endCallReq.vCID = vCID; endCallReq.isDestroy = isPatient; - // await _liveCarePatientServices.endCall(endCallReq); + await _liveCarePatientServices.endCall(endCallReq); if (_liveCarePatientServices.hasError) { error = _liveCarePatientServices.error; } diff --git a/lib/core/viewModel/patient-referral-viewmodel.dart b/lib/core/viewModel/patient-referral-viewmodel.dart index 9e852978..0351db77 100644 --- a/lib/core/viewModel/patient-referral-viewmodel.dart +++ b/lib/core/viewModel/patient-referral-viewmodel.dart @@ -240,7 +240,7 @@ class PatientReferralViewModel extends BaseViewModel { patientID: patient.patientId, roomID: patient.roomId, referralClinic: clinicID, - admissionNo: patient.appointmentNo, + admissionNo: int.parse(patient.admissionNo), referralDoctor: doctorID, patientTypeID: patient.patientType, referringDoctorRemarks: remarks, diff --git a/lib/models/patient/patiant_info_model.dart b/lib/models/patient/patiant_info_model.dart index 71d46dc9..29dc6198 100644 --- a/lib/models/patient/patiant_info_model.dart +++ b/lib/models/patient/patiant_info_model.dart @@ -224,10 +224,13 @@ class PatiantInformtion { isSigned: json['isSigned'], medicationOrders: json['medicationOrders'], nationality: json['nationality'] ?? json['NationalityNameN'], - patientMRN: json['patientMRN'] ?? json['PatientMRN']?? ( - json["PatientID"] != null ? - int.parse(json["PatientID"].toString()) - : int.parse(json["patientID"].toString())), + patientMRN: json['patientMRN'] ?? + json['PatientMRN'] ?? + (json["PatientID"] != null + ? int?.parse(json["PatientID"].toString()) + : json["patientID"] != null ? int?.parse( + json["patientID"].toString()) : json["patientId"] != null ? int + ?.parse(json["patientId"].toString()) : ''), visitType: json['visitType'] ?? json['visitType'] ?? json['visitType'], nationalityFlagURL: json['NationalityFlagURL'] ?? json['NationalityFlagURL'], diff --git a/lib/screens/live_care/end_call_screen.dart b/lib/screens/live_care/end_call_screen.dart index d355473d..d3db12b6 100644 --- a/lib/screens/live_care/end_call_screen.dart +++ b/lib/screens/live_care/end_call_screen.dart @@ -23,9 +23,9 @@ import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:hexcolor/hexcolor.dart'; class EndCallScreen extends StatefulWidget { + final PatiantInformtion patient; - - const EndCallScreen({Key key,}) : super(key: key); + const EndCallScreen({Key key, this.patient,}) : super(key: key); @override _EndCallScreenState createState() => _EndCallScreenState(); @@ -42,11 +42,18 @@ class _EndCallScreenState extends State { String to; LiveCarePatientViewModel liveCareModel; + @override + void initState() { + super.initState(); + if(widget.patient!=null) + patient = widget.patient; + } @override void didChangeDependencies() { super.didChangeDependencies(); final routeArgs = ModalRoute.of(context).settings.arguments as Map; + if(routeArgs.containsKey('patient')) patient = routeArgs['patient']; } 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 ea61359a..03def2f7 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -339,19 +339,18 @@ class _PatientProfileScreenState extends State if(isCallFinished) { - // Navigator.push(context, MaterialPageRoute( - // builder: (BuildContext context) => EndCallScreen(patient:patient))); - var asd = ""; + Navigator.push(context, MaterialPageRoute( + 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 = model.startCallRes.appointmentNo; + patient.appointmentNo = model.startCallRes.appointmentNo; patient.episodeNo = 0; GifLoaderDialogUtils.hideDialog(context); @@ -360,53 +359,6 @@ class _PatientProfileScreenState extends State }); - // await VideoChannel.openVideoCallScreen( - // kToken: "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==",//model.startCallRes.openTokenID, - // kSessionId:"1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg",// model.startCallRes.openSessionID, - // kApiKey: '47247954',//46209962 - // vcId: patient.vcId, - // patientName: patient.fullName ?? (patient.firstName != null ? "${patient.firstName} ${patient.lastName}" : "-"), - // tokenID: await model.getToken(), - // generalId: GENERAL_ID, - // doctorId: model.doctorProfile.doctorID, - // onFailure: (String error) { - // DrAppToastMsg.showErrorToast(error); - // },onCallConnected: callConnected, - // onCallEnd: () { - // var asd=""; - // WidgetsBinding.instance.addPostFrameCallback((_) { - // GifLoaderDialogUtils.showMyDialog(context); - // model.endCall(patient.vcId, false,).then((value) { - // GifLoaderDialogUtils.hideDialog(context); - // if (model.state == ViewState.ErrorLocal) { - // DrAppToastMsg.showErrorToast(model.error); - // } - // setState(() { - // isCallFinished = true; - // }); - // }); - // }); - // Navigator.push(context, MaterialPageRoute( - // builder: (BuildContext context) => - // EndCallScreen(patient:patient))); - // }, - // onCallNotRespond: (SessionStatusModel sessionStatusModel) { - // var asd=""; - // // WidgetsBinding.instance.addPostFrameCallback((_) { - // // GifLoaderDialogUtils.showMyDialog(context); - // // model.endCall(patient.vcId, sessionStatusModel.sessionStatus == 3,).then((value) { - // // GifLoaderDialogUtils.hideDialog(context); - // // if (model.state == ViewState.ErrorLocal) { - // // DrAppToastMsg.showErrorToast(model.error); - // // } - // // setState(() { - // // isCallFinished = true; - // // }); - // // }); - // // - // // }); - // }); - } } diff --git a/lib/screens/procedures/ProcedureCard.dart b/lib/screens/procedures/ProcedureCard.dart index d998ca58..31611b67 100644 --- a/lib/screens/procedures/ProcedureCard.dart +++ b/lib/screens/procedures/ProcedureCard.dart @@ -18,7 +18,7 @@ class ProcedureCard extends StatelessWidget { final int categoryID; final PatiantInformtion patient; final int doctorID; - + final bool isInpatient; const ProcedureCard({ Key key, this.onTap, @@ -26,7 +26,7 @@ class ProcedureCard extends StatelessWidget { this.categoryID, this.categoryName, this.patient, - this.doctorID, + this.doctorID, this.isInpatient = false, }) : super(key: key); @override @@ -132,36 +132,6 @@ class ProcedureCard extends StatelessWidget { ), ], ), - // Row( - // children: [ - // AppText( - // TranslationBase.of(context).doctorName + ": ", - // //color: Colors.grey, - // fontSize: 12, - // color: Colors.grey, - // ), - // AppText( - // entityList.doctorName.toString(), - // fontSize: 12, - // bold: true, - // ), - // ], - // ), - // Row( - // children: [ - // AppText( - // TranslationBase.of(context).clinic + ": ", - // //color: Colors.grey, - // fontSize: 12, - // color: Colors.grey, - // ), - // AppText( - // entityList.clinicDescription ?? "", - // bold: true, - // fontSize: 12, - // ), - // ], - // ), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -222,27 +192,6 @@ class ProcedureCard extends StatelessWidget { ), ], ), - /*Container( - alignment: Alignment.centerRight, - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: FlowChartPage( - filterName: entityList.procedureName, - patient: patient, - ), - ), - ); - }, - child: AppText( - TranslationBase.of(context).showMoreBtn, - textDecoration: TextDecoration.underline, - color: Colors.blue, - ), - ), - ),*/ Padding( padding: const EdgeInsets.all(8.0), child: Row( @@ -254,9 +203,7 @@ class ProcedureCard extends StatelessWidget { fontSize: 12, ), ), - if ((entityList.categoryID == 2 || - entityList.categoryID == 4) && - doctorID == entityList.doctorID) + if ((entityList.categoryID == 2 || entityList.categoryID == 4) && doctorID == entityList.doctorID && !isInpatient) InkWell( child: Icon(DoctorApp.edit), onTap: onTap, From 6853173d938ac9a66410a2ed0c65a5a9d5b95bdf Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Mon, 21 Jun 2021 11:12:42 +0300 Subject: [PATCH 72/72] Enable iOS AirPlay --- ios/Runner/Info.plist | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 2314a2c8..3966a95c 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -46,6 +46,10 @@ Need to upload image NSSpeechRecognitionUsageDescription This permission is not needed by the app, but it is required by an underlying API. If you see this dialog, contact us. + UIBackgroundModes + + audio + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile