From 8db2f059baeb0d58d534361262c03ca16d417a03 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Thu, 2 Jul 2020 11:14:28 +0300 Subject: [PATCH 01/10] add call back fun for end call --- ios/Runner.xcodeproj/project.pbxproj | 12 ++++++++---- ios/Runner/AppDelegate.swift | 15 +++++++++++++-- ios/Runner/ICallProtocoll.swift | 14 ++++++++++++++ ...rolleraa.swift => VideoViewController.swift} | 6 +++++- lib/screens/dashboard_screen.dart | 17 +++++++++++++---- 5 files changed, 53 insertions(+), 11 deletions(-) create mode 100644 ios/Runner/ICallProtocoll.swift rename ios/Runner/{ViewControlleraa.swift => VideoViewController.swift} (99%) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 0550eac7..dcd750d8 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -13,7 +13,8 @@ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; - 9CE61EBD24AB366E008D68DD /* ViewControlleraa.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CE61EBC24AB366E008D68DD /* ViewControlleraa.swift */; }; + 9CE61EBD24AB366E008D68DD /* VideoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CE61EBC24AB366E008D68DD /* VideoViewController.swift */; }; + 9CE61ECD24ADBB4C008D68DD /* ICallProtocoll.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CE61ECC24ADBB4C008D68DD /* ICallProtocoll.swift */; }; B650DC3076E9D70CB188286A /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93A5F83B23AB032D1E096663 /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ @@ -46,7 +47,8 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 9CE61EBC24AB366E008D68DD /* ViewControlleraa.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewControlleraa.swift; sourceTree = ""; }; + 9CE61EBC24AB366E008D68DD /* VideoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoViewController.swift; sourceTree = ""; }; + 9CE61ECC24ADBB4C008D68DD /* ICallProtocoll.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ICallProtocoll.swift; sourceTree = ""; }; 9D4B7DB43C6A6C849D2387CE /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; E698D7B14B12DF768FE47A1A /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -115,7 +117,8 @@ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, - 9CE61EBC24AB366E008D68DD /* ViewControlleraa.swift */, + 9CE61EBC24AB366E008D68DD /* VideoViewController.swift */, + 9CE61ECC24ADBB4C008D68DD /* ICallProtocoll.swift */, ); path = Runner; sourceTree = ""; @@ -282,8 +285,9 @@ buildActionMask = 2147483647; files = ( 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, - 9CE61EBD24AB366E008D68DD /* ViewControlleraa.swift in Sources */, + 9CE61EBD24AB366E008D68DD /* VideoViewController.swift in Sources */, 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + 9CE61ECD24ADBB4C008D68DD /* ICallProtocoll.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 5e32b165..e763b11d 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -6,7 +6,15 @@ import OpenTok // Copyright © 2020 Cloud. All rights reserved. @UIApplicationMain -@objc class AppDelegate: FlutterAppDelegate { +@objc class AppDelegate: FlutterAppDelegate ,ICallProtocol { + + var result: FlutterResult? + + + func sessionDone() { + self.result?("Session Done") + } + override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? @@ -17,7 +25,8 @@ import OpenTok let videoCallChannel = FlutterMethodChannel(name: "Dr.cloudSolution/videoCall", binaryMessenger: controller.binaryMessenger) videoCallChannel.setMethodCallHandler({ - (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in + (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in + self.result = result switch call.method { case "openVideoCall": do { @@ -37,6 +46,7 @@ import OpenTok return super.application(application, didFinishLaunchingWithOptions: launchOptions) } + private func openVideoChat(result: FlutterResult,kApiKey: String, kSessionId: String,kToken: String,appLang:String) { @@ -48,6 +58,7 @@ import OpenTok videoVC.kApiKey=kApiKey videoVC.kSessionId=kSessionId videoVC.kToken=kToken + videoVC.callBack = self videoVC.navigationController?.setNavigationBarHidden(true, animated: false) navVC.modalPresentationStyle = .fullScreen window.rootViewController?.present(navVC, animated: true, completion: nil) diff --git a/ios/Runner/ICallProtocoll.swift b/ios/Runner/ICallProtocoll.swift new file mode 100644 index 00000000..1e267a17 --- /dev/null +++ b/ios/Runner/ICallProtocoll.swift @@ -0,0 +1,14 @@ +// +// ICallProtocol.swift +// Runner +// +// Created by Elham Rababah && Mohammad Aljammal on 7/2/20. +// Copyright © 2020 The Chromium Authors. All rights reserved. +// + +import Foundation + +protocol ICallProtocol { + + func sessionDone() +} diff --git a/ios/Runner/ViewControlleraa.swift b/ios/Runner/VideoViewController.swift similarity index 99% rename from ios/Runner/ViewControlleraa.swift rename to ios/Runner/VideoViewController.swift index 6e7c17f3..507e3d87 100644 --- a/ios/Runner/ViewControlleraa.swift +++ b/ios/Runner/VideoViewController.swift @@ -22,6 +22,8 @@ class ViewController: UIViewController { var kToken:String = "" + var callBack: ICallProtocol? + override func viewDidLoad() { super.viewDidLoad() @@ -33,7 +35,7 @@ class ViewController: UIViewController { setupSession() // Do any additional setup after loading the view. } - + func setupButtons() { perform(#selector(hideControlButtons), with: nil, afterDelay: 3) let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(remoteVideoTapped(_:))) @@ -102,6 +104,7 @@ class ViewController: UIViewController { } @IBAction func hangUp(_ sender: UIButton) { + sessionDisconnect() } @@ -110,6 +113,7 @@ class ViewController: UIViewController { if (session != nil) { print("disconnecting....") session!.disconnect(nil) + callBack?.sessionDone() dismiss(animated: true) return } diff --git a/lib/screens/dashboard_screen.dart b/lib/screens/dashboard_screen.dart index ad64d89a..f972e5d3 100644 --- a/lib/screens/dashboard_screen.dart +++ b/lib/screens/dashboard_screen.dart @@ -101,10 +101,19 @@ class _DashboardScreenState extends State { crossAxisAlignment: CrossAxisAlignment.end, children: [ InkWell( - onTap: () { - showCupertinoPicker( - context: context, - actionList: authProvider.doctorsClinicList); + onTap: () async { + + var asd = await VideoChannel.openVideoCallScreen( + kToken: "T1==cGFydG5lcl9pZD00NjgwMzIyNCZzaWc9ZTUxZGI0NGJiNjhjOGY2YzZkZGVjNTQ0M2Q5ZDJkODY2MjBlYjJjYTpzZXNzaW9uX2lkPTJfTVg0ME5qZ3dNekl5Tkg1LU1UVTVNekEzTkRrMk1qUXhOSDVRZWt3clkxb3lhSGRuYmpWU2FFTmtlbWx2TkZWcWVFSi1mZyZjcmVhdGVfdGltZT0xNTkzMDc1MDA3Jm5vbmNlPTAuNjQ2OTA2MTAwMTU0ODY3NSZyb2xlPXB1Ymxpc2hlciZleHBpcmVfdGltZT0xNTkzNjc5ODA2JmluaXRpYWxfbGF5b3V0X2NsYXNzX2xpc3Q9", + kSessionId: '2_MX40NjgwMzIyNH5-MTU5MzA3NDk2MjQxNH5QekwrY1oyaHdnbjVSaENkemlvNFVqeEJ-fg', + kApiKey: '46803224' + ); + + print(asd); + + // showCupertinoPicker( + // context: context, + // actionList: authProvider.doctorsClinicList); }, child: Container( margin: From d866d8b9de2cd8023add689e284433d041b24a27 Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Thu, 2 Jul 2020 12:30:53 +0300 Subject: [PATCH 02/10] get clinic list --- lib/config/config.dart | 24 +++++++++++------ lib/providers/auth_provider.dart | 9 +++++-- lib/providers/project_provider.dart | 41 ++++++++++++++++++++++++----- lib/screens/dashboard_screen.dart | 15 ++++++++--- lib/widgets/auth/login_form.dart | 2 +- 5 files changed, 70 insertions(+), 21 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 261fcd46..153e5d3a 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -35,23 +35,31 @@ const START_LIVECARE_CALL = 'LiveCareApi/DoctorApp/CallPatient'; const LIVE_CARE_STATISTICS_FOR_CERTAIN_DOCTOR_URL = "Lists.svc/REST/DashBoard_GetLiveCareDoctorsStatsticsForCertainDoctor"; -const GET_PRESCRIPTION_REPORT = 'Services/Patients.svc/REST/GetPrescriptionReport'; +const GET_PRESCRIPTION_REPORT = + 'Services/Patients.svc/REST/GetPrescriptionReport'; -const GT_MY_PATIENT_QUESTION = 'Services/DoctorApplication.svc/REST/GtMyPatientsQuestions'; +const GT_MY_PATIENT_QUESTION = + 'Services/DoctorApplication.svc/REST/GtMyPatientsQuestions'; const GET_PATIENT = 'Services/DoctorApplication.svc/REST/'; -const GET_PRESCRIPTION_REPORT_FOR_IN_PATIENT= 'Services/DoctorApplication.svc/REST/GetPrescriptionReportForInPatient'; +const GET_PRESCRIPTION_REPORT_FOR_IN_PATIENT = + 'Services/DoctorApplication.svc/REST/GetPrescriptionReportForInPatient'; -const GET_MY_REFERRAL_PATIENT = 'Services/DoctorApplication.svc/REST/GtMyReferralPatient'; +const GET_MY_REFERRAL_PATIENT = + 'Services/DoctorApplication.svc/REST/GtMyReferralPatient'; -const ADD_REFERRED_DOCTOR_REMARKS= 'Services/DoctorApplication.svc/REST/AddReferredDoctorRemarks'; +const ADD_REFERRED_DOCTOR_REMARKS = + 'Services/DoctorApplication.svc/REST/AddReferredDoctorRemarks'; -const GET_MY_REFERRED_PATIENT = 'Services/DoctorApplication.svc/REST/GtMyReferredPatient'; +const GET_MY_REFERRED_PATIENT = + 'Services/DoctorApplication.svc/REST/GtMyReferredPatient'; -const GET_DOCTOR_WORKING_HOURS_TABLE = 'Services/Doctors.svc/REST/GetDoctorWorkingHoursTable'; +const GET_DOCTOR_WORKING_HOURS_TABLE = + 'Services/Doctors.svc/REST/GetDoctorWorkingHoursTable'; -const GET_PATIENT_LAB_RESULTS= 'Services/DoctorApplication.svc/REST/GetPatientLabResults'; +const GET_PATIENT_LAB_RESULTS = + 'Services/DoctorApplication.svc/REST/GetPatientLabResults'; var selectedPatientType = 1; diff --git a/lib/providers/auth_provider.dart b/lib/providers/auth_provider.dart index 61a61530..a66c6192 100644 --- a/lib/providers/auth_provider.dart +++ b/lib/providers/auth_provider.dart @@ -18,6 +18,10 @@ const SEND_ACTIVATION_CODE_BY_OTP_NOTIFICATION_TYPE = const MEMBER_CHECK_ACTIVATION_CODE_NEW = 'Services/Sentry.svc/REST/MemberCheckActivationCode_New'; const GET_DOC_PROFILES = 'Services/Doctors.svc/REST/GetDocProfiles'; + +const GET_CLINICS_FOR_DOCTOR = + 'Services/DoctorApplication.svc/REST/GetClinicsForDoctor'; + DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); enum APP_STATUS { LOADING, UNAUTHENTICATED, AUTHENTICATED } @@ -166,11 +170,12 @@ class AuthProvider with ChangeNotifier { onSuccess: (dynamic response, int statusCode) { localRes = response; //ClinicDescription - selectedClinicName = response['DoctorProfileList'][0]['ClinicDescription']; + selectedClinicName = + response['DoctorProfileList'][0]['ClinicDescription']; }, onFailure: (String error, int statusCode) { throw error; }, body: docInfo); - notifyListeners(); + notifyListeners(); return Future.value(localRes); } catch (error) { print(error); diff --git a/lib/providers/project_provider.dart b/lib/providers/project_provider.dart index 4de2251f..f3abc26c 100644 --- a/lib/providers/project_provider.dart +++ b/lib/providers/project_provider.dart @@ -1,8 +1,10 @@ import 'dart:async'; import 'package:connectivity/connectivity.dart'; +import 'package:doctor_app_flutter/client/base_app_client.dart'; import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; +import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; import 'package:doctor_app_flutter/providers/auth_provider.dart'; @@ -10,6 +12,7 @@ import 'package:doctor_app_flutter/util/dr_app_shared_pref.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:flutter/cupertino.dart'; import 'package:provider/provider.dart'; + Helpers helpers = Helpers(); class ProjectProvider with ChangeNotifier { @@ -18,12 +21,15 @@ class ProjectProvider with ChangeNotifier { String currentLanguage = 'ar'; bool _isArabic = false; bool isInternetConnection = true; + List clinicList = []; + bool isLoading = false; + bool isError = false; + String error = ''; Locale get appLocal => _appLocale; bool get isArabic => _isArabic; StreamSubscription subscription; - // AuthProvider authProvider = AuthProvider(); ProjectProvider() { loadSharedPrefLanguage(); @@ -66,7 +72,7 @@ class ProjectProvider with ChangeNotifier { currentLanguage = 'en'; sharedPref.setString(APP_Language, 'en'); } - getProfile(); + getProfile(); notifyListeners(); } @@ -76,7 +82,29 @@ class ProjectProvider with ChangeNotifier { super.dispose(); } - void getProfile()async{ + Future getClinicNames() async { + try { + dynamic localRes; + + await BaseAppClient.post(GET_CLINICS_FOR_DOCTOR, + onSuccess: (dynamic response, int statusCode) { + clinicList = []; + response['List_DoctorsClinic'].forEach((v) { + clinicList.add(new ClinicModel.fromJson(v)); + }); + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: {}); + + return Future.value(localRes); + } catch (error) { + print(error); + throw error; + } + } + + void getProfile() async { Map profile = await sharedPref.getObj(DOCTOR_PROFILE); DoctorProfileModel doctorProfile = new DoctorProfileModel.fromJson(profile); ProfileReqModel docInfo = new ProfileReqModel( @@ -87,13 +115,12 @@ class ProjectProvider with ChangeNotifier { tokenID: '', languageID: 2); - Provider.of(AppGlobal.CONTEX,listen: false) - .getDocProfiles(docInfo.toJson()).then((res) async { + Provider.of(AppGlobal.CONTEX, listen: false) + .getDocProfiles(docInfo.toJson()) + .then((res) async { sharedPref.setObj(DOCTOR_PROFILE, res['DoctorProfileList'][0]); }).catchError((err) { print(err); }); } - - } diff --git a/lib/screens/dashboard_screen.dart b/lib/screens/dashboard_screen.dart index 037b344d..3542f624 100644 --- a/lib/screens/dashboard_screen.dart +++ b/lib/screens/dashboard_screen.dart @@ -49,13 +49,22 @@ class _DashboardScreenState extends State { AuthProvider authProvider; bool isLoading = false; ProjectProvider projectsProvider; + var _isInit = true; + + void didChangeDependencies() { + super.didChangeDependencies(); + if (_isInit) { + projectsProvider = Provider.of(context); + projectsProvider.getClinicNames(); + } + _isInit = false; + } @override Widget build(BuildContext context) { hospitalProvider = Provider.of(context); authProvider = Provider.of(context); projectsProvider = Provider.of(context); - print(authProvider.doctorsClinicList); FocusScopeNode currentFocus = FocusScope.of(context); if (!currentFocus.hasPrimaryFocus) { currentFocus.unfocus(); @@ -90,7 +99,7 @@ class _DashboardScreenState extends State { onTap: () { showCupertinoPicker( context: context, - actionList: authProvider.doctorsClinicList); + actionList: projectsProvider.clinicList); }, child: Container( margin: @@ -542,6 +551,7 @@ class _DashboardScreenState extends State { changeIsLoading(true); Map profile = await sharedPref.getObj(DOCTOR_PROFILE); DoctorProfileModel doctorProfile = new DoctorProfileModel.fromJson(profile); + ProfileReqModel docInfo = new ProfileReqModel( doctorID: doctorProfile.doctorID, clinicID: clinicId, @@ -549,7 +559,6 @@ class _DashboardScreenState extends State { projectID: doctorProfile.projectID, tokenID: '', languageID: 2); - // authProvider.getDocProfiles(docInfo) authProvider.getDocProfiles(docInfo.toJson()).then((res) async { changeIsLoading(false); diff --git a/lib/widgets/auth/login_form.dart b/lib/widgets/auth/login_form.dart index 033f445c..078cf503 100644 --- a/lib/widgets/auth/login_form.dart +++ b/lib/widgets/auth/login_form.dart @@ -301,7 +301,7 @@ class _LoginFormState extends State { platformImei = await ImeiPlugin.getImei(shouldShowRequestPermissionRationale: false); idunique = await ImeiPlugin.getImei(); - } catch(e) { + } catch (e) { platformImei = 'Failed to get platform version.'; } From 1e27edf09f9a6d3370045f96712d630e6b378569 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Thu, 2 Jul 2020 17:38:12 +0300 Subject: [PATCH 03/10] kill the session after 30 second --- ios/Runner/VideoViewController.swift | 31 +++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/ios/Runner/VideoViewController.swift b/ios/Runner/VideoViewController.swift index 507e3d87..357c696f 100644 --- a/ios/Runner/VideoViewController.swift +++ b/ios/Runner/VideoViewController.swift @@ -23,6 +23,8 @@ class ViewController: UIViewController { var kToken:String = "" var callBack: ICallProtocol? + var timer = Timer() + var seconds = 30 override func viewDidLoad() { @@ -208,6 +210,15 @@ class ViewController: UIViewController { @IBOutlet weak var localVideoMutedIndicator: UIImageView! + @objc func updateTimer(){ + seconds -= 1 //This will decrement(count down)the seconds. + print(seconds) + if seconds == 0 { + sessionDisconnect(); + timer.invalidate() + + } + } } @@ -216,11 +227,17 @@ extension ViewController: OTSessionDelegate { func sessionDidConnect(_ session: OTSession) { print("The client connected to the OpenTok session.") + + + + + timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(ViewController.updateTimer)), userInfo: nil, repeats: true) + setupPublisher() } - + func setupPublisher() { let settings = OTPublisherSettings() settings.name = UIDevice.current.name @@ -304,6 +321,18 @@ extension ViewController: OTSessionDelegate { subscriber?.view!.removeFromSuperview() subscriber = nil } + + func session( + _ session: OTSession?, + connectionCreated connection: OTConnection? + ) { +// startTimer(callDuration, warningDuration) + if let connectionId = connection?.connectionId { + print("session connectionCreated (\(connectionId))") + } + + timer.invalidate() + } } From aa57f4c4d7a644a2a8f801aa4a8316d3c350dbd7 Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Sun, 5 Jul 2020 12:04:50 +0300 Subject: [PATCH 04/10] get clinic list after changing the language --- lib/config/localized_values.dart | 4 ++- lib/providers/project_provider.dart | 7 +++- lib/screens/dashboard_screen.dart | 45 ++++++++++++++---------- lib/util/helpers.dart | 5 +-- lib/util/translations_delegate_base.dart | 2 ++ 5 files changed, 41 insertions(+), 22 deletions(-) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 892d54fe..c5332425 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -213,5 +213,7 @@ const Map> localizedValues = { }, 'livecare': {'en': 'Live Care', 'ar': 'Live Care'}, 'beingBad': {'en': 'being bad', 'ar': 'سيء'}, - 'beingGreat': {'en': 'being great', 'ar': 'راثع'}, + 'beingGreat': {'en': 'being great', 'ar': 'رائع'}, + 'cancel': {'en': 'CANCEL', 'ar': 'الغاء'}, + 'done': {'en': 'DONE', 'ar': 'تأكيد'}, }; diff --git a/lib/providers/project_provider.dart b/lib/providers/project_provider.dart index f3abc26c..81f50c42 100644 --- a/lib/providers/project_provider.dart +++ b/lib/providers/project_provider.dart @@ -72,10 +72,15 @@ class ProjectProvider with ChangeNotifier { currentLanguage = 'en'; sharedPref.setString(APP_Language, 'en'); } - getProfile(); + callServicesAfterChangeLang(); notifyListeners(); } + callServicesAfterChangeLang() { + getProfile(); + getClinicNames(); + } + @override void dispose() { if (subscription != null) subscription.cancel(); diff --git a/lib/screens/dashboard_screen.dart b/lib/screens/dashboard_screen.dart index 3fda04d0..4a1a2f46 100644 --- a/lib/screens/dashboard_screen.dart +++ b/lib/screens/dashboard_screen.dart @@ -61,6 +61,7 @@ class _DashboardScreenState extends State { } _isInit = false; } + BuildContext myContext; GlobalKey _one = GlobalKey(); @@ -101,7 +102,9 @@ class _DashboardScreenState extends State { fontWeight: FontWeight.bold, fontSize: SizeConfig.textMultiplier * 2.5, ), - alignment: Alignment.centerLeft, + alignment: projectsProvider.isArabic + ? Alignment.topRight + : Alignment.topLeft, ), ), Row( @@ -112,6 +115,7 @@ class _DashboardScreenState extends State { InkWell( onTap: () { showCupertinoPicker( + decKey: '', context: context, actionList: projectsProvider.clinicList); }, @@ -310,7 +314,9 @@ class _DashboardScreenState extends State { TranslationBase.of(context).patientServices, fontWeight: FontWeight.bold, ), - alignment: Alignment.centerLeft, + alignment: projectsProvider.isArabic + ? Alignment.topRight + : Alignment.topLeft, ), ), Expanded( @@ -538,19 +544,17 @@ class _DashboardScreenState extends State { mainAxisAlignment: MainAxisAlignment.end, children: [ CupertinoButton( - child: Text( - 'Cancel'.toUpperCase(), - // style: TextStyle(context) - ), + child: Text(TranslationBase.of(context).cancel + // style: TextStyle(context) + ), onPressed: () { Navigator.pop(context); }, ), CupertinoButton( - child: Text( - 'Done'.toUpperCase(), - // style: textStyle(context), - ), + child: Text(TranslationBase.of(context).done + // style: textStyle(context), + ), onPressed: () { Navigator.pop(context); // onSelectFun(cupertinoPickerIndex); @@ -564,14 +568,19 @@ class _DashboardScreenState extends State { color: Color(0xfff7f7f7), child: Column( children: actionList - .map((e) => Container( - child: InkWell( - onTap: () => - changeClinic(e.clinicID, context), - child: Text( - e.clinicName, - style: TextStyle(fontSize: 15), - )), + .map((e) => Flexible( + child: Container( + child: InkWell( + onTap: () => + changeClinic(e.clinicID, context), + child: Text( + e.clinicName ?? 'asd', + style: TextStyle( + fontSize: + SizeConfig.textMultiplier * + 1.9), + )), + ), )) .toList(), )) diff --git a/lib/util/helpers.dart b/lib/util/helpers.dart index 6807edf3..41c0b4f7 100644 --- a/lib/util/helpers.dart +++ b/lib/util/helpers.dart @@ -11,6 +11,7 @@ import '../util/dr_app_toast_msg.dart'; import 'package:connectivity/connectivity.dart'; import 'dr_app_shared_pref.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); @@ -51,7 +52,7 @@ class Helpers { mainAxisAlignment: MainAxisAlignment.end, children: [ CupertinoButton( - child: Text('Cancel'.toUpperCase(), + child: Text(TranslationBase.of(context).cancel, style: textStyle(context)), onPressed: () { Navigator.pop(context); @@ -59,7 +60,7 @@ class Helpers { ), CupertinoButton( child: Text( - 'Done'.toUpperCase(), + TranslationBase.of(context).done, style: textStyle(context), ), onPressed: () { diff --git a/lib/util/translations_delegate_base.dart b/lib/util/translations_delegate_base.dart index ca49936e..ad52edd8 100644 --- a/lib/util/translations_delegate_base.dart +++ b/lib/util/translations_delegate_base.dart @@ -233,6 +233,8 @@ class TranslationBase { String get livecare => localizedValues['livecare'][locale.languageCode]; String get beingBad => localizedValues['beingBad'][locale.languageCode]; String get beingGreat => localizedValues['beingGreat'][locale.languageCode]; + String get cancel => localizedValues['cancel'][locale.languageCode]; + String get done => localizedValues['done'][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { From acaaca314e57228bd2b82e2bba5293c6f2c962d4 Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Sun, 5 Jul 2020 12:43:27 +0300 Subject: [PATCH 05/10] get clinic list after changing the language --- lib/config/config.dart | 14 ++++++++ lib/interceptor/http_interceptor.dart | 48 +++++++++++++-------------- lib/providers/auth_provider.dart | 17 +--------- lib/providers/project_provider.dart | 10 +++--- lib/screens/dashboard_screen.dart | 7 ++-- 5 files changed, 48 insertions(+), 48 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 153e5d3a..1054b1d0 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -16,6 +16,8 @@ const PATIENT_REFER_TO_DOCTOR_URL = "Services/DoctorApplication.svc/REST/ReferToDoctor"; const PATIENT_GET_DOCTOR_BY_CLINIC_URL = "Services/DoctorApplication.svc/REST/GetDoctorsByClinicID"; +const GET_CLINICS_FOR_DOCTOR = + 'Services/DoctorApplication.svc/REST/GetClinicsForDoctor'; const PATIENT_GET_LIST_REFERAL_URL = "Services/Lists.svc/REST/GetList_STPReferralFrequency"; const PATIENT_GET_CLINIC_BY_PROJECT_URL = @@ -60,6 +62,18 @@ const GET_DOCTOR_WORKING_HOURS_TABLE = const GET_PATIENT_LAB_RESULTS = 'Services/DoctorApplication.svc/REST/GetPatientLabResults'; +const LOGIN_URL = 'Services/Sentry.svc/REST/MemberLogIN_New'; +const INSERT_DEVICE_IMEI = + 'Services/Sentry.svc/REST/DoctorApplication_INSERTDeviceIMEI'; +const SELECT_DEVICE_IMEI = + 'Services/Sentry.svc/REST/DoctorApplication_SELECTDeviceIMEIbyIMEI'; + +const SEND_ACTIVATION_CODE_BY_OTP_NOTIFICATION_TYPE = + 'Services/Sentry.svc/REST/DoctorApplication_SendActivationCodebyOTPNotificationType'; + +const MEMBER_CHECK_ACTIVATION_CODE_NEW = + 'Services/Sentry.svc/REST/MemberCheckActivationCode_New'; +const GET_DOC_PROFILES = 'Services/Doctors.svc/REST/GetDocProfiles'; var selectedPatientType = 1; diff --git a/lib/interceptor/http_interceptor.dart b/lib/interceptor/http_interceptor.dart index 4d0f9c33..7f5488b0 100644 --- a/lib/interceptor/http_interceptor.dart +++ b/lib/interceptor/http_interceptor.dart @@ -8,6 +8,7 @@ import 'package:http_interceptor/http_interceptor.dart'; import '../providers/auth_provider.dart'; import '../util/dr_app_shared_pref.dart'; +import 'package:doctor_app_flutter/config/config.dart'; DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); List publicUrls = [ @@ -18,10 +19,9 @@ List publicUrls = [ ]; class HttpInterceptor extends InterceptorContract { - - Client getClient(){ - return HttpClientWithInterceptor.build(interceptors: [this]); -} + Client getClient() { + return HttpClientWithInterceptor.build(interceptors: [this]); + } Future interceptRequest({RequestData data}) async { print('RequestData ${data.body}'); @@ -29,26 +29,26 @@ class HttpInterceptor extends InterceptorContract { try { data.headers["Content-Type"] = "application/json"; data.headers["Accept"] = "application/json"; - // if (publicUrls.contains(data.url)) { - // var loggedUserInfo = await sharedPref.getObj('loggedUser'); - // var token = await sharedPref.getString(TOKEN); - // // print("token"+token); - // // print('loggedUserInfo${loggedUserInfo["LogInTokenID"]}'); - // // // the sevices handel the token in differat name so I ask to be change - // // // we must change the imple - // var body = json.decode(data.body); - // body['LogInTokenID']=token; - // data.body = json.encode(body); - - // // data.body['LogInTokenID'] = ''; - // } else { - // if (data.body['LogInTokenID']) { - // data.body['LogInTokenID'] = ''; - // } - // if (data.body['TokenID']) { - // data.body['TokenID'] = ''; - // } - // } + // if (publicUrls.contains(data.url)) { + // var loggedUserInfo = await sharedPref.getObj('loggedUser'); + // var token = await sharedPref.getString(TOKEN); + // // print("token"+token); + // // print('loggedUserInfo${loggedUserInfo["LogInTokenID"]}'); + // // // the sevices handel the token in differat name so I ask to be change + // // // we must change the imple + // var body = json.decode(data.body); + // body['LogInTokenID']=token; + // data.body = json.encode(body); + + // // data.body['LogInTokenID'] = ''; + // } else { + // if (data.body['LogInTokenID']) { + // data.body['LogInTokenID'] = ''; + // } + // if (data.body['TokenID']) { + // data.body['TokenID'] = ''; + // } + // } } catch (e) { print(e); } diff --git a/lib/providers/auth_provider.dart b/lib/providers/auth_provider.dart index a66c6192..69551b7b 100644 --- a/lib/providers/auth_provider.dart +++ b/lib/providers/auth_provider.dart @@ -3,25 +3,10 @@ import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/util/dr_app_shared_pref.dart'; import 'package:flutter/cupertino.dart'; +import 'package:doctor_app_flutter/config/config.dart'; import '../models/doctor/user_model.dart'; -const LOGIN_URL = 'Services/Sentry.svc/REST/MemberLogIN_New'; -const INSERT_DEVICE_IMEI = - 'Services/Sentry.svc/REST/DoctorApplication_INSERTDeviceIMEI'; -const SELECT_DEVICE_IMEI = - 'Services/Sentry.svc/REST/DoctorApplication_SELECTDeviceIMEIbyIMEI'; - -const SEND_ACTIVATION_CODE_BY_OTP_NOTIFICATION_TYPE = - 'Services/Sentry.svc/REST/DoctorApplication_SendActivationCodebyOTPNotificationType'; - -const MEMBER_CHECK_ACTIVATION_CODE_NEW = - 'Services/Sentry.svc/REST/MemberCheckActivationCode_New'; -const GET_DOC_PROFILES = 'Services/Doctors.svc/REST/GetDocProfiles'; - -const GET_CLINICS_FOR_DOCTOR = - 'Services/DoctorApplication.svc/REST/GetClinicsForDoctor'; - DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); enum APP_STATUS { LOADING, UNAUTHENTICATED, AUTHENTICATED } diff --git a/lib/providers/project_provider.dart b/lib/providers/project_provider.dart index 81f50c42..7548dc2c 100644 --- a/lib/providers/project_provider.dart +++ b/lib/providers/project_provider.dart @@ -21,7 +21,7 @@ class ProjectProvider with ChangeNotifier { String currentLanguage = 'ar'; bool _isArabic = false; bool isInternetConnection = true; - List clinicList = []; + List doctorClinicsList = []; bool isLoading = false; bool isError = false; String error = ''; @@ -78,7 +78,7 @@ class ProjectProvider with ChangeNotifier { callServicesAfterChangeLang() { getProfile(); - getClinicNames(); + getDoctorClinicsList(); } @override @@ -87,15 +87,15 @@ class ProjectProvider with ChangeNotifier { super.dispose(); } - Future getClinicNames() async { + Future getDoctorClinicsList() async { try { dynamic localRes; await BaseAppClient.post(GET_CLINICS_FOR_DOCTOR, onSuccess: (dynamic response, int statusCode) { - clinicList = []; + doctorClinicsList = []; response['List_DoctorsClinic'].forEach((v) { - clinicList.add(new ClinicModel.fromJson(v)); + doctorClinicsList.add(new ClinicModel.fromJson(v)); }); localRes = response; }, onFailure: (String error, int statusCode) { diff --git a/lib/screens/dashboard_screen.dart b/lib/screens/dashboard_screen.dart index 4a1a2f46..cab257e0 100644 --- a/lib/screens/dashboard_screen.dart +++ b/lib/screens/dashboard_screen.dart @@ -57,7 +57,7 @@ class _DashboardScreenState extends State { super.didChangeDependencies(); if (_isInit) { projectsProvider = Provider.of(context); - projectsProvider.getClinicNames(); + projectsProvider.getDoctorClinicsList(); } _isInit = false; } @@ -117,7 +117,8 @@ class _DashboardScreenState extends State { showCupertinoPicker( decKey: '', context: context, - actionList: projectsProvider.clinicList); + actionList: + projectsProvider.doctorClinicsList); }, child: Container( margin: @@ -574,7 +575,7 @@ class _DashboardScreenState extends State { onTap: () => changeClinic(e.clinicID, context), child: Text( - e.clinicName ?? 'asd', + e.clinicName, style: TextStyle( fontSize: SizeConfig.textMultiplier * From d22ce32cdb79ba3ea93877ff63eb8e1ac78090c1 Mon Sep 17 00:00:00 2001 From: Mohammad ALjammal Date: Sun, 5 Jul 2020 14:09:16 +0300 Subject: [PATCH 06/10] add call back android --- android/app/build.gradle | 5 + android/app/src/main/AndroidManifest.xml | 2 +- .../Model/GetSessionStatusModel.java | 115 ++++++++++++++++++ .../Model/SessionStatusModel.java | 106 ++++++++++++++++ .../Service/AppRetrofit.java | 69 +++++++++++ .../Service/SessionStatusAPI.java | 15 +++ .../{ => ui}/VideoCallActivity.java | 92 ++++++++++---- .../ui/VideoCallContract.java | 18 +++ .../ui/VideoCallPresenterImpl.java | 49 ++++++++ .../doctor_app_flutter/MainActivity.kt | 102 ++++++++++++---- .../main/res/layout/activity_video_call.xml | 2 +- lib/models/livecare/session_status_model.dart | 28 +++++ lib/screens/dashboard_screen.dart | 20 ++- lib/util/VideoChannel.dart | 31 +++-- 14 files changed, 592 insertions(+), 62 deletions(-) create mode 100644 android/app/src/main/java/com/example/doctor_app_flutter/Model/GetSessionStatusModel.java create mode 100644 android/app/src/main/java/com/example/doctor_app_flutter/Model/SessionStatusModel.java create mode 100644 android/app/src/main/java/com/example/doctor_app_flutter/Service/AppRetrofit.java create mode 100644 android/app/src/main/java/com/example/doctor_app_flutter/Service/SessionStatusAPI.java rename android/app/src/main/java/com/example/doctor_app_flutter/{ => ui}/VideoCallActivity.java (82%) create mode 100644 android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallContract.java create mode 100644 android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallPresenterImpl.java create mode 100644 lib/models/livecare/session_status_model.dart diff --git a/android/app/build.gradle b/android/app/build.gradle index 048dea59..ae87782e 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -72,4 +72,9 @@ dependencies { implementation 'com.opentok.android:opentok-android-sdk:2.16.5' //permissions implementation 'pub.devrel:easypermissions:0.4.0' + + //retrofit + implementation 'com.squareup.retrofit2:retrofit:2.6.2' + implementation 'com.squareup.retrofit2:converter-gson:2.6.2' + implementation 'com.squareup.okhttp3:logging-interceptor:3.14.1' } diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index fda3b312..51b33a46 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -15,7 +15,7 @@ android:name="io.flutter.app.FlutterApplication" android:icon="@mipmap/ic_launcher" android:label="doctor_app_flutter"> - + CREATOR = new Creator() { + @Override + public GetSessionStatusModel createFromParcel(Parcel in) { + return new GetSessionStatusModel(in); + } + + @Override + public GetSessionStatusModel[] newArray(int size) { + return new GetSessionStatusModel[size]; + } + }; + + public Integer getVCID() { + return vCID; + } + + public void setVCID(Integer vCID) { + this.vCID = vCID; + } + + public String getTokenID() { + return tokenID; + } + + public void setTokenID(String tokenID) { + this.tokenID = tokenID; + } + + public String getGeneralid() { + return generalid; + } + + public void setGeneralid(String generalid) { + this.generalid = generalid; + } + + public Integer getDoctorId() { + return doctorId; + } + + public void setDoctorId(Integer doctorId) { + this.doctorId = doctorId; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + if (vCID == null) { + dest.writeByte((byte) 0); + } else { + dest.writeByte((byte) 1); + dest.writeInt(vCID); + } + dest.writeString(tokenID); + dest.writeString(generalid); + if (doctorId == null) { + dest.writeByte((byte) 0); + } else { + dest.writeByte((byte) 1); + dest.writeInt(doctorId); + } + } +} diff --git a/android/app/src/main/java/com/example/doctor_app_flutter/Model/SessionStatusModel.java b/android/app/src/main/java/com/example/doctor_app_flutter/Model/SessionStatusModel.java new file mode 100644 index 00000000..da6bba1d --- /dev/null +++ b/android/app/src/main/java/com/example/doctor_app_flutter/Model/SessionStatusModel.java @@ -0,0 +1,106 @@ +package com.example.doctor_app_flutter.Model; + +import android.os.Parcel; +import android.os.Parcelable; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class SessionStatusModel implements Parcelable { + + @SerializedName("Result") + @Expose + private String result; + @SerializedName("SessionStatus") + @Expose + private Integer sessionStatus; + @SerializedName("IsAuthenticated") + @Expose + private Boolean isAuthenticated; + @SerializedName("MessageStatus") + @Expose + private Integer messageStatus; + + protected SessionStatusModel(Parcel in) { + result = in.readString(); + if (in.readByte() == 0) { + sessionStatus = null; + } else { + sessionStatus = in.readInt(); + } + byte tmpIsAuthenticated = in.readByte(); + isAuthenticated = tmpIsAuthenticated == 0 ? null : tmpIsAuthenticated == 1; + if (in.readByte() == 0) { + messageStatus = null; + } else { + messageStatus = in.readInt(); + } + } + + public static final Creator CREATOR = new Creator() { + @Override + public SessionStatusModel createFromParcel(Parcel in) { + return new SessionStatusModel(in); + } + + @Override + public SessionStatusModel[] newArray(int size) { + return new SessionStatusModel[size]; + } + }; + + public String getResult() { + return result; + } + + public void setResult(String result) { + this.result = result; + } + + public Integer getSessionStatus() { + return sessionStatus; + } + + public void setSessionStatus(Integer sessionStatus) { + this.sessionStatus = sessionStatus; + } + + public Boolean getIsAuthenticated() { + return isAuthenticated; + } + + public void setIsAuthenticated(Boolean isAuthenticated) { + this.isAuthenticated = isAuthenticated; + } + + public Integer getMessageStatus() { + return messageStatus; + } + + public void setMessageStatus(Integer messageStatus) { + this.messageStatus = messageStatus; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(result); + if (sessionStatus == null) { + dest.writeByte((byte) 0); + } else { + dest.writeByte((byte) 1); + dest.writeInt(sessionStatus); + } + dest.writeByte((byte) (isAuthenticated == null ? 0 : isAuthenticated ? 1 : 2)); + if (messageStatus == null) { + dest.writeByte((byte) 0); + } else { + dest.writeByte((byte) 1); + dest.writeInt(messageStatus); + } + } +} \ No newline at end of file diff --git a/android/app/src/main/java/com/example/doctor_app_flutter/Service/AppRetrofit.java b/android/app/src/main/java/com/example/doctor_app_flutter/Service/AppRetrofit.java new file mode 100644 index 00000000..6646bd6f --- /dev/null +++ b/android/app/src/main/java/com/example/doctor_app_flutter/Service/AppRetrofit.java @@ -0,0 +1,69 @@ +package com.example.doctor_app_flutter.Service; + +import android.app.Activity; +import android.app.Application; + +import androidx.annotation.CallSuper; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.util.concurrent.TimeUnit; + +import io.flutter.view.FlutterMain; +import okhttp3.ConnectionPool; +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + +public class AppRetrofit extends Application { + private static final int MY_SOCKET_TIMEOUT_MS = 20000; + + @Override + @CallSuper + public void onCreate() { + super.onCreate(); + FlutterMain.startInitialization(this); + } + + private Activity mCurrentActivity = null; + + public Activity getCurrentActivity() { + return mCurrentActivity; + } + + public void setCurrentActivity(Activity mCurrentActivity) { + this.mCurrentActivity = mCurrentActivity; + } + + public static Retrofit getRetrofit( String baseUrl) { + + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + Gson gson = new GsonBuilder().serializeNulls().create(); + OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(chain -> { + okhttp3.Request originalRequest = chain.request(); + okhttp3.Request newRequest = originalRequest.newBuilder() + .addHeader("Content-Type","application/json") + .addHeader("Accept","application/json") + .build(); + + return chain.proceed(newRequest); + }) + .addInterceptor(interceptor) + .callTimeout(MY_SOCKET_TIMEOUT_MS, TimeUnit.SECONDS) + .connectTimeout(MY_SOCKET_TIMEOUT_MS, TimeUnit.SECONDS) + .readTimeout(MY_SOCKET_TIMEOUT_MS, TimeUnit.SECONDS) + .connectionPool(new ConnectionPool(0, 5 * 60 * 1000, TimeUnit.SECONDS)) + .retryOnConnectionFailure(false) + .build(); + + + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create(gson)) + .client(okHttpClient) + .build(); + } +} diff --git a/android/app/src/main/java/com/example/doctor_app_flutter/Service/SessionStatusAPI.java b/android/app/src/main/java/com/example/doctor_app_flutter/Service/SessionStatusAPI.java new file mode 100644 index 00000000..fbc8d1d3 --- /dev/null +++ b/android/app/src/main/java/com/example/doctor_app_flutter/Service/SessionStatusAPI.java @@ -0,0 +1,15 @@ +package com.example.doctor_app_flutter.Service; + +import com.example.doctor_app_flutter.Model.GetSessionStatusModel; +import com.example.doctor_app_flutter.Model.SessionStatusModel; + + +import retrofit2.Call; +import retrofit2.http.Body; +import retrofit2.http.POST; + +public interface SessionStatusAPI { + + @POST("LiveCareApi/DoctorApp/GetSessionStatus") + Call getSessionStatusModelData(@Body GetSessionStatusModel getSessionStatusModel); +} diff --git a/android/app/src/main/java/com/example/doctor_app_flutter/VideoCallActivity.java b/android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallActivity.java similarity index 82% rename from android/app/src/main/java/com/example/doctor_app_flutter/VideoCallActivity.java rename to android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallActivity.java index 146a3d54..adc32d38 100644 --- a/android/app/src/main/java/com/example/doctor_app_flutter/VideoCallActivity.java +++ b/android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallActivity.java @@ -1,18 +1,17 @@ -package com.example.doctor_app_flutter; +package com.example.doctor_app_flutter.ui; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import android.Manifest; import android.annotation.SuppressLint; -import android.content.res.ColorStateList; -import android.graphics.Color; +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.util.Log; -import android.view.MotionEvent; import android.view.View; import android.widget.FrameLayout; import android.widget.ImageView; @@ -21,6 +20,9 @@ import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; +import com.example.doctor_app_flutter.Model.GetSessionStatusModel; +import com.example.doctor_app_flutter.Model.SessionStatusModel; +import com.example.doctor_app_flutter.R; import com.opentok.android.Session; import com.opentok.android.Stream; import com.opentok.android.Publisher; @@ -40,31 +42,32 @@ import pub.devrel.easypermissions.EasyPermissions; public class VideoCallActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks, Session.SessionListener, Publisher.PublisherListener, - Subscriber.VideoListener { - + 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; - private Runnable mVolRunnable; + private Handler mVolHandler, mConnectedHandler; + private Runnable mVolRunnable, mConnectedRunnable; private FrameLayout mPublisherViewContainer; private RelativeLayout mSubscriberViewContainer; private RelativeLayout controlPanel; - private String apiKey; - private String sessionId; - private String token; - private String callDuration; - private String warningDuration; - private String appLang; + private String apiKey; + private String sessionId; + private String token; + private String appLang; + private String baseUrl; private boolean isSwitchCameraClicked; private boolean isCameraClicked; @@ -82,6 +85,10 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi private TextView progressBarTextView; private RelativeLayout progressBarLayout; + private boolean isConnected = false; + + private GetSessionStatusModel sessionStatusModel; + @Override protected void onCreate(Bundle savedInstanceState) { @@ -132,11 +139,14 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi apiKey = getIntent().getStringExtra("apiKey"); sessionId = getIntent().getStringExtra("sessionId"); token = getIntent().getStringExtra("token"); - // callDuration = getIntent().getStringExtra("callDuration"); - // warningDuration = getIntent().getStringExtra("warningDuration"); - appLang=getIntent().getStringExtra("appLang"); + appLang = getIntent().getStringExtra("appLang"); + baseUrl = getIntent().getStringExtra("baseUrl"); + sessionStatusModel = getIntent().getParcelableExtra("sessionStatusModel"); + + controlPanel = findViewById(R.id.control_panel); + + videoCallPresenter = new VideoCallPresenterImpl(this, baseUrl); - controlPanel=findViewById(R.id.control_panel); mCallBtn = findViewById(R.id.btn_call); mCameraBtn = findViewById(R.id.btn_camera); @@ -144,17 +154,19 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi mspeckerBtn = findViewById(R.id.btn_specker); mMicBtn = findViewById(R.id.btn_mic); - // progressBarLayout=findViewById(R.id.progressBar); - // progressBar=findViewById(R.id.progress_bar); + // 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); + mVolHandler.postDelayed(mVolRunnable, 5 * 1000); return true; }); @@ -164,16 +176,25 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi } + private void checkClientConnected() { + mConnectedHandler = new Handler(); + mConnectedRunnable = () -> { + if (!isConnected) { + videoCallPresenter.callClintConnected(sessionStatusModel); + } + }; + mConnectedHandler.postDelayed(mConnectedRunnable, 7 * 1000); + } - private void hiddenButtons(){ + private void hiddenButtons() { mVolHandler = new Handler(); mVolRunnable = new Runnable() { public void run() { controlPanel.setVisibility(View.GONE); } }; - mVolHandler.postDelayed(mVolRunnable,5*1000); + mVolHandler.postDelayed(mVolRunnable, 5 * 1000); } @Override @@ -225,7 +246,7 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi mPublisherViewContainer.addView(mPublisher.getView()); - if (mPublisher.getView() instanceof GLSurfaceView){ + if (mPublisher.getView() instanceof GLSurfaceView) { ((GLSurfaceView) mPublisher.getView()).setZOrderOnTop(true); } @@ -250,10 +271,11 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi @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); } @@ -325,6 +347,7 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi private void disconnectSession() { if (mSession == null) { + setResult(Activity.RESULT_CANCELED); finish(); return; } @@ -343,7 +366,7 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi mPublisher = null; } mSession.disconnect(); - if(countDownTimer!=null) { + if (countDownTimer != null) { countDownTimer.cancel(); } finish(); @@ -375,7 +398,9 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi mspeckerBtn.setImageResource(res); } } + public void onMicClicked(View view) { + if (mPublisher != null) { isMicClicked = !isMicClicked; mPublisher.setPublishAudio(!isMicClicked); @@ -387,4 +412,19 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi public void onCallClicked(View view) { disconnectSession(); } + + @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(); + } + } + + @Override + public void onFailure() { + + } } \ No newline at end of file diff --git a/android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallContract.java b/android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallContract.java new file mode 100644 index 00000000..21122239 --- /dev/null +++ b/android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallContract.java @@ -0,0 +1,18 @@ +package com.example.doctor_app_flutter.ui; + +import com.example.doctor_app_flutter.Model.GetSessionStatusModel; +import com.example.doctor_app_flutter.Model.SessionStatusModel; + +public interface VideoCallContract { + + interface VideoCallView{ + + void onCallSuccessful(SessionStatusModel sessionStatusModel); + void onFailure(); + } + + interface VideoCallPresenter { + + void callClintConnected(GetSessionStatusModel statusModel); + } +} diff --git a/android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallPresenterImpl.java b/android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallPresenterImpl.java new file mode 100644 index 00000000..363d1ca8 --- /dev/null +++ b/android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallPresenterImpl.java @@ -0,0 +1,49 @@ +package com.example.doctor_app_flutter.ui; + +import com.example.doctor_app_flutter.Model.GetSessionStatusModel; +import com.example.doctor_app_flutter.Model.SessionStatusModel; +import com.example.doctor_app_flutter.Service.AppRetrofit; +import com.example.doctor_app_flutter.Service.SessionStatusAPI; + +import org.jetbrains.annotations.NotNull; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class VideoCallPresenterImpl implements VideoCallContract.VideoCallPresenter { + + private VideoCallContract.VideoCallView view; + private SessionStatusAPI sessionStatusAPI; + private String baseUrl; + + public VideoCallPresenterImpl(VideoCallContract.VideoCallView view, String baseUrl) { + this.view = view; + this.baseUrl = baseUrl; + } + + @Override + public void callClintConnected(GetSessionStatusModel statusModel) { + + + sessionStatusAPI = AppRetrofit.getRetrofit(baseUrl).create(SessionStatusAPI.class); + + Call call = sessionStatusAPI.getSessionStatusModelData(statusModel); + + call.enqueue(new Callback() { + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + if (response.isSuccessful()) { + view.onCallSuccessful(response.body()); + } else + view.onFailure(); + } + + @Override + public void onFailure(@NotNull Call call, @NotNull Throwable t) { + view.onFailure(); + } + }); + + } +} diff --git a/android/app/src/main/kotlin/com/example/doctor_app_flutter/MainActivity.kt b/android/app/src/main/kotlin/com/example/doctor_app_flutter/MainActivity.kt index d1d710ad..1a203368 100644 --- a/android/app/src/main/kotlin/com/example/doctor_app_flutter/MainActivity.kt +++ b/android/app/src/main/kotlin/com/example/doctor_app_flutter/MainActivity.kt @@ -1,45 +1,101 @@ package com.example.doctor_app_flutter +import android.app.Activity import android.content.Intent -import androidx.annotation.NonNull; -import io.flutter.embedding.android.FlutterActivity -import io.flutter.embedding.engine.FlutterEngine -import io.flutter.plugins.GeneratedPluginRegistrant +import androidx.annotation.NonNull +import com.example.doctor_app_flutter.Model.GetSessionStatusModel +import com.example.doctor_app_flutter.Model.SessionStatusModel +import com.example.doctor_app_flutter.ui.VideoCallActivity +import com.google.gson.GsonBuilder 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() { +class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler { private val CHANNEL = "Dr.cloudSolution/videoCall" + private var result: MethodChannel.Result? = null + private var call: MethodCall? = null + private val LAUNCH_VIDEO: Int = 1 override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { GeneratedPluginRegistrant.registerWith(flutterEngine) - MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { - call, result -> - if (call.method == "openVideoCall") { - val apiKey = call.argument("kApiKey") - val sessionId = call.argument("kSessionId") - val token = call.argument("kToken") - // val callDuration = call.argument("callDuration") - // val warningDuration = call.argument("warningDuration") - val appLang = call.argument("appLang") - openVideoCall(apiKey,sessionId,token/*,callDuration,warningDuration*/,appLang) - } else { - result.notImplemented() - } - } + MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler(this) } - private fun openVideoCall(apiKey: String?, sessionId: String?, token: String?/*, callDuration: String?, warningDuration: String?*/, appLang: String?) { + + override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { + + 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") + + // 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 sessionStatusModel = GetSessionStatusModel(VC_ID, tokenID, generalId, doctorId) + + + openVideoCall(apiKey, sessionId, token, appLang, baseUrl, sessionStatusModel) + + } else { + result.notImplemented() + } + } + + 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("callDuration", callDuration) - //intent.putExtra("warningDuration", warningDuration) intent.putExtra("appLang", appLang) - startActivity(intent) + intent.putExtra("baseUrl", baseUrl) + intent.putExtra("sessionStatusModel", sessionStatusModel) + startActivityForResult(intent, LAUNCH_VIDEO) + + } + + + 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() + + callResponse["callResponse"] = "CallNotRespond" + val jsonRes = gson.toJson(result) + callResponse["sessionStatus"] = jsonRes + + this.result?.success(gson.toJson(callResponse)) + } + if (resultCode == Activity.RESULT_CANCELED) { + val callResponse : HashMap = HashMap() + callResponse["callResponse"] = "CallEnd" + + result?.success(callResponse) + } + } } + + } 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 c7500b6c..2dcf2ba4 100644 --- a/android/app/src/main/res/layout/activity_video_call.xml +++ b/android/app/src/main/res/layout/activity_video_call.xml @@ -4,7 +4,7 @@ android:id="@+id/activity_clingo_video_call" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".VideoCallActivity"> + tools:context=".ui.VideoCallActivity"> json) { + isAuthenticated = json['IsAuthenticated']; + messageStatus = json['MessageStatus']; + result = json['Result']; + sessionStatus = json['SessionStatus']; + } + + Map toJson() { + final Map data = new Map(); + data['IsAuthenticated'] = this.isAuthenticated; + data['MessageStatus'] = this.messageStatus; + data['Result'] = this.result; + data['SessionStatus'] = this.sessionStatus; + return data; + } +} diff --git a/lib/screens/dashboard_screen.dart b/lib/screens/dashboard_screen.dart index ad64d89a..52ecf34f 100644 --- a/lib/screens/dashboard_screen.dart +++ b/lib/screens/dashboard_screen.dart @@ -1,9 +1,12 @@ +import 'dart:convert'; + import 'package:doctor_app_flutter/config/shared_pref_kay.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/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; +import 'package:doctor_app_flutter/models/livecare/session_status_model.dart'; import 'package:doctor_app_flutter/providers/auth_provider.dart'; import 'package:doctor_app_flutter/providers/doctor_reply_provider.dart'; import 'package:doctor_app_flutter/providers/hospital_provider.dart'; @@ -101,10 +104,19 @@ class _DashboardScreenState extends State { crossAxisAlignment: CrossAxisAlignment.end, children: [ InkWell( - onTap: () { - showCupertinoPicker( - context: context, - actionList: authProvider.doctorsClinicList); + onTap: () async { + await VideoChannel.openVideoCallScreen( + kToken: 'T1==cGFydG5lcl9pZD00NjgwMzIyNCZzaWc9NWRhNmExMzU4ZDViZGU3OTA5NDY4ODRhNzI4ZGUxZTRmMjZmNzcwMjpzZXNzaW9uX2lkPTFfTVg0ME5qZ3dNekl5Tkg1LU1UVTVNelk0TXpZek9EWXdNMzV1Y0V4V1lWUlZTbTVIY3k5dVdHWm1NMWxPYTNjelpIVi1mZyZjcmVhdGVfdGltZT0xNTkzNjgzNjYyJm5vbmNlPTAuODAxMzMzMzUxMDQwNzE5NSZyb2xlPXB1Ymxpc2hlciZleHBpcmVfdGltZT0xNTk2Mjc1NjYyJmluaXRpYWxfbGF5b3V0X2NsYXNzX2xpc3Q9', + kSessionId: '1_MX40NjgwMzIyNH5-MTU5MzY4MzYzODYwM35ucExWYVRVSm5Hcy9uWGZmM1lOa3czZHV-fg', + kApiKey: '46803224', + onFailure: (String error) {}, + onCallEnd: () {}, + callNotRespond: (SessionStatusModel sessionStatusModel) {}); + + +// showCupertinoPicker( +// context: context, +// actionList: authProvider.doctorsClinicList); }, child: Container( margin: diff --git a/lib/util/VideoChannel.dart b/lib/util/VideoChannel.dart index c5bf278e..73b17930 100644 --- a/lib/util/VideoChannel.dart +++ b/lib/util/VideoChannel.dart @@ -1,28 +1,45 @@ +import 'dart:convert'; + +import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/models/livecare/session_status_model.dart'; import 'package:flutter/services.dart'; class VideoChannel{ /// channel name static const _channel = const MethodChannel("Dr.cloudSolution/videoCall"); - static Future openVideoCallScreen( - {kApiKey, kSessionId, kToken, callDuration, warningDuration}) { + static openVideoCallScreen( + {kApiKey, kSessionId, kToken, callDuration, warningDuration, Function() onCallEnd , Function(SessionStatusModel sessionStatusModel) callNotRespond ,Function(String error) onFailure}) async { var result; try { - result = _channel.invokeMethod( + result = await _channel.invokeMethod( 'openVideoCall', { "kApiKey": kApiKey, "kSessionId": kSessionId, "kToken": kToken, - /* "callDuration": callDuration, - "warningDuration": warningDuration,*/ "appLang": "en", + "baseUrl": BASE_URL, + "VC_ID": 3245, + "TokenID": "hfkjshdf347r8743", + "generalId": 'Cs2020@2016\$2958', + "DoctorId": 1485 , }, ); + if(result['callResponse'] == 'CallEnd') { + onCallEnd(); + } + else { + var asd = result['sessionStatus']; + var parsed = json.decode(result['sessionStatus']); + SessionStatusModel sessionStatusModel = SessionStatusModel.fromJson(parsed); + callNotRespond(sessionStatusModel); + } + } on PlatformException catch (e) { - result = e.toString(); + onFailure(e.toString()); } - return result; + } From 693effd6b7953ea1faf90f5a8109583920620b5a Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Sun, 5 Jul 2020 14:10:18 +0300 Subject: [PATCH 07/10] first step form calling API --- ios/Podfile | 2 +- ios/Podfile.lock | 6 +++- ios/Runner/AppDelegate.swift | 9 ++++-- ios/Runner/ICallProtocoll.swift | 3 +- ios/Runner/VideoViewController.swift | 42 +++++++++++++++++++++++++--- 5 files changed, 52 insertions(+), 10 deletions(-) diff --git a/ios/Podfile b/ios/Podfile index 3b20de57..bebf8f5b 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -64,7 +64,7 @@ target 'Runner' do # Keep pod path relative so it can be checked into Podfile.lock. pod 'Flutter', :path => 'Flutter' pod 'OpenTok' - + pod 'Alamofire' # Plugin Pods # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock diff --git a/ios/Podfile.lock b/ios/Podfile.lock index ab95eb7c..70b9d103 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,4 +1,5 @@ PODS: + - Alamofire (4.9.1) - barcode_scan (0.0.1): - Flutter - MTBBarcodeScanner @@ -41,6 +42,7 @@ PODS: - Flutter DEPENDENCIES: + - Alamofire - barcode_scan (from `.symlinks/plugins/barcode_scan/ios`) - connectivity (from `.symlinks/plugins/connectivity/ios`) - connectivity_macos (from `.symlinks/plugins/connectivity_macos/ios`) @@ -62,6 +64,7 @@ DEPENDENCIES: SPEC REPOS: trunk: + - Alamofire - MTBBarcodeScanner - OpenTok - Reachability @@ -104,6 +107,7 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/url_launcher_web/ios" SPEC CHECKSUMS: + Alamofire: 85e8a02c69d6020a0d734f6054870d7ecb75cf18 barcode_scan: a5c27959edfafaa0c771905bad0b29d6d39e4479 connectivity: 6e94255659cc86dcbef1d452ad3e0491bb1b3e75 connectivity_macos: e2e9731b6b22dda39eb1b128f6969d574460e191 @@ -126,6 +130,6 @@ SPEC CHECKSUMS: url_launcher_macos: fd7894421cd39320dce5f292fc99ea9270b2a313 url_launcher_web: e5527357f037c87560776e36436bf2b0288b965c -PODFILE CHECKSUM: ad71cae222b2dc22820a69b80873417b35fef79e +PODFILE CHECKSUM: 649616dc336b3659ac6b2b25159d8e488e042b69 COCOAPODS: 1.9.3 diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index e763b11d..e4992e16 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -11,8 +11,12 @@ import OpenTok var result: FlutterResult? - func sessionDone() { - self.result?("Session Done") + func sessionDone(res:Any) { + self.result?(res) + + } + func sessionNotResponded(res:Any) { + self.result?(res) } override func application( @@ -20,7 +24,6 @@ import OpenTok didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { - let controller : FlutterViewController = window?.rootViewController as! FlutterViewController let videoCallChannel = FlutterMethodChannel(name: "Dr.cloudSolution/videoCall", binaryMessenger: controller.binaryMessenger) diff --git a/ios/Runner/ICallProtocoll.swift b/ios/Runner/ICallProtocoll.swift index 1e267a17..197be424 100644 --- a/ios/Runner/ICallProtocoll.swift +++ b/ios/Runner/ICallProtocoll.swift @@ -10,5 +10,6 @@ import Foundation protocol ICallProtocol { - func sessionDone() + func sessionDone(res:Any) + func sessionNotResponded(res: Any) } diff --git a/ios/Runner/VideoViewController.swift b/ios/Runner/VideoViewController.swift index 357c696f..d9834fea 100644 --- a/ios/Runner/VideoViewController.swift +++ b/ios/Runner/VideoViewController.swift @@ -8,6 +8,7 @@ import UIKit import OpenTok +import Alamofire class ViewController: UIViewController { @@ -25,6 +26,7 @@ class ViewController: UIViewController { var callBack: ICallProtocol? var timer = Timer() var seconds = 30 + var isUserConnect : Bool = false override func viewDidLoad() { @@ -37,6 +39,38 @@ class ViewController: UIViewController { setupSession() // Do any additional setup after loading the view. } + + + private func callApi() { + let URL_USER_REGISTER = "https://uat.hmgwebservices.com/LiveCareApi/DoctorApp/GetSessionStatus" + let headers: HTTPHeaders = [ + "Content-Type":"application/json", + "Accept":"application/json", + + ] + + let parameters = [ + "VC_ID": 3245, + "TokenID": "hfkjshdf347r8743", + "generalid": "Cs2020@2016$2958", + "DoctorId" : 1485 , + ] as [String : Any] + Alamofire.request(URL_USER_REGISTER, method: .post,parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseJSON{ + response in + if self.isUserConnect { + } else { + if let result = response.result.value { + let jsonData = result as! NSDictionary + self.callBack?.sessionNotResponded(res: ["sessionStatus":jsonData, "callResponse":"CallNotRespond"]) + + } + self.sessionDisconnect(); + self.timer.invalidate() + } + //getting json value from the server + + } + } func setupButtons() { perform(#selector(hideControlButtons), with: nil, afterDelay: 3) @@ -115,7 +149,7 @@ class ViewController: UIViewController { if (session != nil) { print("disconnecting....") session!.disconnect(nil) - callBack?.sessionDone() + callBack?.sessionDone(res:["callResponse":"CallEnd"]) dismiss(animated: true) return } @@ -214,10 +248,10 @@ class ViewController: UIViewController { seconds -= 1 //This will decrement(count down)the seconds. print(seconds) if seconds == 0 { - sessionDisconnect(); - timer.invalidate() + callApi() } + } } @@ -330,7 +364,7 @@ extension ViewController: OTSessionDelegate { if let connectionId = connection?.connectionId { print("session connectionCreated (\(connectionId))") } - + isUserConnect = true timer.invalidate() } From d5825ccb85cfab99510687dc45bf9d7b0ff97948 Mon Sep 17 00:00:00 2001 From: Mohammad ALjammal Date: Sun, 5 Jul 2020 16:54:07 +0300 Subject: [PATCH 08/10] fix issues --- .../kotlin/com/example/doctor_app_flutter/MainActivity.kt | 2 +- lib/models/livecare/session_status_model.dart | 2 +- lib/screens/dashboard_screen.dart | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/android/app/src/main/kotlin/com/example/doctor_app_flutter/MainActivity.kt b/android/app/src/main/kotlin/com/example/doctor_app_flutter/MainActivity.kt index 1a203368..4aada798 100644 --- a/android/app/src/main/kotlin/com/example/doctor_app_flutter/MainActivity.kt +++ b/android/app/src/main/kotlin/com/example/doctor_app_flutter/MainActivity.kt @@ -86,7 +86,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler val jsonRes = gson.toJson(result) callResponse["sessionStatus"] = jsonRes - this.result?.success(gson.toJson(callResponse)) + this.result?.success(callResponse) } if (resultCode == Activity.RESULT_CANCELED) { val callResponse : HashMap = HashMap() diff --git a/lib/models/livecare/session_status_model.dart b/lib/models/livecare/session_status_model.dart index ad9a1142..7e7a3e43 100644 --- a/lib/models/livecare/session_status_model.dart +++ b/lib/models/livecare/session_status_model.dart @@ -10,7 +10,7 @@ class SessionStatusModel { this.result, this.sessionStatus}); - SessionStatusModel.fromJson(Map json) { + SessionStatusModel.fromJson(Map json) { isAuthenticated = json['IsAuthenticated']; messageStatus = json['MessageStatus']; result = json['Result']; diff --git a/lib/screens/dashboard_screen.dart b/lib/screens/dashboard_screen.dart index 52ecf34f..5ce0973d 100644 --- a/lib/screens/dashboard_screen.dart +++ b/lib/screens/dashboard_screen.dart @@ -111,7 +111,9 @@ class _DashboardScreenState extends State { kApiKey: '46803224', onFailure: (String error) {}, onCallEnd: () {}, - callNotRespond: (SessionStatusModel sessionStatusModel) {}); + callNotRespond: (SessionStatusModel sessionStatusModel) { + var asd =""; + }); // showCupertinoPicker( From 6ea72f5ffaf1f38b9e7301c9bb6cb2a57c77d15c Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Sun, 5 Jul 2020 16:54:41 +0300 Subject: [PATCH 09/10] make things daynamic --- ios/Runner/AppDelegate.swift | 13 +++++-- ios/Runner/VideoViewController.swift | 34 +++++++++++++------ lib/models/livecare/session_status_model.dart | 2 +- lib/util/VideoChannel.dart | 6 ++-- 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index e4992e16..0a5ed700 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -38,7 +38,11 @@ import OpenTok let kSessionId = arguments!["kSessionId"] as? String let kToken = arguments!["kToken"] as? String let appLang = arguments!["appLang"] as? String - self.openVideoChat(result: result,kApiKey: kApiKey!,kSessionId:kSessionId!,kToken: kToken!, appLang: appLang!) + let vC_ID = arguments!["VC_ID"] as? Int + let tokenID = arguments!["TokenID"] as? String + let generalId = arguments!["generalId"] as? String + let doctorId = arguments!["DoctorId"] as? Int + self.openVideoChat(result: result,kApiKey: kApiKey!,kSessionId:kSessionId!,kToken: kToken!, appLang: appLang!, vC_ID: vC_ID!,tokenID: tokenID!,generalId: generalId!,doctorId: doctorId!) } default: result(FlutterMethodNotImplemented) @@ -52,7 +56,7 @@ import OpenTok - private func openVideoChat(result: FlutterResult,kApiKey: String, kSessionId: String,kToken: String,appLang:String) { + private func openVideoChat(result: FlutterResult,kApiKey: String, kSessionId: String,kToken: String,appLang:String, vC_ID: Int,tokenID:String,generalId:String,doctorId:Int) { let storyboard = UIStoryboard(name: "Main", bundle: nil) let identifier = "ViewControllerNav" @@ -61,6 +65,11 @@ import OpenTok videoVC.kApiKey=kApiKey videoVC.kSessionId=kSessionId videoVC.kToken=kToken + videoVC.VC_ID = vC_ID + videoVC.generalid = generalId + videoVC.TokenID = tokenID + videoVC.DoctorId = doctorId + videoVC.callBack = self videoVC.navigationController?.setNavigationBarHidden(true, animated: false) navVC.modalPresentationStyle = .fullScreen diff --git a/ios/Runner/VideoViewController.swift b/ios/Runner/VideoViewController.swift index d9834fea..3ff2eef5 100644 --- a/ios/Runner/VideoViewController.swift +++ b/ios/Runner/VideoViewController.swift @@ -23,6 +23,11 @@ class ViewController: UIViewController { var kToken:String = "" + var VC_ID: Int = 0 + var TokenID: String = "" + var generalid : String = "" + var DoctorId: Int = 0 + var callBack: ICallProtocol? var timer = Timer() var seconds = 30 @@ -41,7 +46,7 @@ class ViewController: UIViewController { } - private func callApi() { + private func getSessionStatus() { let URL_USER_REGISTER = "https://uat.hmgwebservices.com/LiveCareApi/DoctorApp/GetSessionStatus" let headers: HTTPHeaders = [ "Content-Type":"application/json", @@ -50,19 +55,27 @@ class ViewController: UIViewController { ] let parameters = [ - "VC_ID": 3245, - "TokenID": "hfkjshdf347r8743", - "generalid": "Cs2020@2016$2958", - "DoctorId" : 1485 , + "VC_ID": VC_ID, + "TokenID": TokenID, + "generalid": generalid, + "DoctorId" : DoctorId , ] as [String : Any] Alamofire.request(URL_USER_REGISTER, method: .post,parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseJSON{ response in if self.isUserConnect { } else { if let result = response.result.value { - let jsonData = result as! NSDictionary - self.callBack?.sessionNotResponded(res: ["sessionStatus":jsonData, "callResponse":"CallNotRespond"]) - + let jsonData = result as! NSObject + if((jsonData.value(forKey: "SessionStatus")) as! Int == 2 || (jsonData.value(forKey: "SessionStatus")) as! Int == 3) { + //jsonData + let jsonObject: [String: Any] = [ + "sessionStatus": result , + "callResponse": "CallNotRespond", + ] + self.callBack?.sessionNotResponded(res: jsonObject) + + } + } self.sessionDisconnect(); self.timer.invalidate() @@ -140,7 +153,7 @@ class ViewController: UIViewController { } @IBAction func hangUp(_ sender: UIButton) { - + callBack?.sessionDone(res:["callResponse":"CallEnd"]) sessionDisconnect() } @@ -149,7 +162,6 @@ class ViewController: UIViewController { if (session != nil) { print("disconnecting....") session!.disconnect(nil) - callBack?.sessionDone(res:["callResponse":"CallEnd"]) dismiss(animated: true) return } @@ -248,7 +260,7 @@ class ViewController: UIViewController { seconds -= 1 //This will decrement(count down)the seconds. print(seconds) if seconds == 0 { - callApi() + getSessionStatus() } diff --git a/lib/models/livecare/session_status_model.dart b/lib/models/livecare/session_status_model.dart index ad9a1142..7e7a3e43 100644 --- a/lib/models/livecare/session_status_model.dart +++ b/lib/models/livecare/session_status_model.dart @@ -10,7 +10,7 @@ class SessionStatusModel { this.result, this.sessionStatus}); - SessionStatusModel.fromJson(Map json) { + SessionStatusModel.fromJson(Map json) { isAuthenticated = json['IsAuthenticated']; messageStatus = json['MessageStatus']; result = json['Result']; diff --git a/lib/util/VideoChannel.dart b/lib/util/VideoChannel.dart index 73b17930..9f4195af 100644 --- a/lib/util/VideoChannel.dart +++ b/lib/util/VideoChannel.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'dart:io' show Platform; import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/models/livecare/session_status_model.dart'; @@ -30,9 +31,8 @@ class VideoChannel{ onCallEnd(); } else { - var asd = result['sessionStatus']; - var parsed = json.decode(result['sessionStatus']); - SessionStatusModel sessionStatusModel = SessionStatusModel.fromJson(parsed); + + SessionStatusModel sessionStatusModel = SessionStatusModel.fromJson(Platform.isIOS ?result['sessionStatus'] :json.decode(result['sessionStatus'])); callNotRespond(sessionStatusModel); } From 287bb20d12acda4877215f8e117161109984ca48 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Sun, 5 Jul 2020 17:10:56 +0300 Subject: [PATCH 10/10] fix issues ios --- .../ui/VideoCallActivity.java | 2 +- lib/screens/dashboard_screen.dart | 17 ++--------- lib/screens/live_care/video_call.dart | 28 ++++++++++++++----- lib/util/VideoChannel.dart | 15 +++++----- 4 files changed, 32 insertions(+), 30 deletions(-) diff --git a/android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallActivity.java b/android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallActivity.java index adc32d38..2e7c32a7 100644 --- a/android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallActivity.java +++ b/android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallActivity.java @@ -183,7 +183,7 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi videoCallPresenter.callClintConnected(sessionStatusModel); } }; - mConnectedHandler.postDelayed(mConnectedRunnable, 7 * 1000); + mConnectedHandler.postDelayed(mConnectedRunnable, 30 * 1000); } diff --git a/lib/screens/dashboard_screen.dart b/lib/screens/dashboard_screen.dart index 5ce0973d..fe41913b 100644 --- a/lib/screens/dashboard_screen.dart +++ b/lib/screens/dashboard_screen.dart @@ -105,20 +105,9 @@ class _DashboardScreenState extends State { children: [ InkWell( onTap: () async { - await VideoChannel.openVideoCallScreen( - kToken: 'T1==cGFydG5lcl9pZD00NjgwMzIyNCZzaWc9NWRhNmExMzU4ZDViZGU3OTA5NDY4ODRhNzI4ZGUxZTRmMjZmNzcwMjpzZXNzaW9uX2lkPTFfTVg0ME5qZ3dNekl5Tkg1LU1UVTVNelk0TXpZek9EWXdNMzV1Y0V4V1lWUlZTbTVIY3k5dVdHWm1NMWxPYTNjelpIVi1mZyZjcmVhdGVfdGltZT0xNTkzNjgzNjYyJm5vbmNlPTAuODAxMzMzMzUxMDQwNzE5NSZyb2xlPXB1Ymxpc2hlciZleHBpcmVfdGltZT0xNTk2Mjc1NjYyJmluaXRpYWxfbGF5b3V0X2NsYXNzX2xpc3Q9', - kSessionId: '1_MX40NjgwMzIyNH5-MTU5MzY4MzYzODYwM35ucExWYVRVSm5Hcy9uWGZmM1lOa3czZHV-fg', - kApiKey: '46803224', - onFailure: (String error) {}, - onCallEnd: () {}, - callNotRespond: (SessionStatusModel sessionStatusModel) { - var asd =""; - }); - - -// showCupertinoPicker( -// context: context, -// actionList: authProvider.doctorsClinicList); + showCupertinoPicker( + context: context, + actionList: authProvider.doctorsClinicList); }, child: Container( margin: diff --git a/lib/screens/live_care/video_call.dart b/lib/screens/live_care/video_call.dart index 02abdc5b..4d7d4170 100644 --- a/lib/screens/live_care/video_call.dart +++ b/lib/screens/live_care/video_call.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:doctor_app_flutter/models/livecare/session_status_model.dart'; import 'package:doctor_app_flutter/providers/livecare_provider.dart'; import 'package:doctor_app_flutter/util/VideoChannel.dart'; import 'package:doctor_app_flutter/util/dr_app_shared_pref.dart'; @@ -37,15 +38,28 @@ class _VideoCallPageState extends State { _isInit = false; } - void connectOpenTok(tokenData) { + void connectOpenTok(tokenData) async { _tokenData = tokenData; /* opentok functionalites need to be written */ - - VideoChannel.openVideoCallScreen( - kApiKey: '46209962', - kSessionId: _tokenData["OpenSessionID"], - kToken: _tokenData["OpenTokenID"], - ); + await VideoChannel.openVideoCallScreen( + kToken: + 'T1==cGFydG5lcl9pZD00NjgwMzIyNCZzaWc9NWRhNmExMzU4ZDViZGU3OTA5NDY4ODRhNzI4ZGUxZTRmMjZmNzcwMjpzZXNzaW9uX2lkPTFfTVg0ME5qZ3dNekl5Tkg1LU1UVTVNelk0TXpZek9EWXdNMzV1Y0V4V1lWUlZTbTVIY3k5dVdHWm1NMWxPYTNjelpIVi1mZyZjcmVhdGVfdGltZT0xNTkzNjgzNjYyJm5vbmNlPTAuODAxMzMzMzUxMDQwNzE5NSZyb2xlPXB1Ymxpc2hlciZleHBpcmVfdGltZT0xNTk2Mjc1NjYyJmluaXRpYWxfbGF5b3V0X2NsYXNzX2xpc3Q9', + kSessionId: + '1_MX40NjgwMzIyNH5-MTU5MzY4MzYzODYwM35ucExWYVRVSm5Hcy9uWGZmM1lOa3czZHV-fg', + kApiKey: '46803224', + vcId: 3245, + tokenID: "hfkjshdf347r8743", + generalId: "Cs2020@2016\$2958", + doctorId: 1485, + onFailure: (String error) { + //TODO handling Failure + }, + onCallEnd: () { + //TODO handling onCallEnd + }, + onCallNotRespond: (SessionStatusModel sessionStatusModel) { + //TODO handling onCalcallNotRespondlEnd + }); } String getTimerTime(int start) { diff --git a/lib/util/VideoChannel.dart b/lib/util/VideoChannel.dart index 9f4195af..bf255b54 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, Function() onCallEnd , Function(SessionStatusModel sessionStatusModel) callNotRespond ,Function(String error) onFailure}) async { + {kApiKey, kSessionId, kToken, callDuration, warningDuration,int vcId,String tokenID,String generalId,int doctorId, Function() onCallEnd , Function(SessionStatusModel sessionStatusModel) onCallNotRespond ,Function(String error) onFailure}) async { var result; try { result = await _channel.invokeMethod( @@ -21,22 +21,21 @@ class VideoChannel{ "kToken": kToken, "appLang": "en", "baseUrl": BASE_URL, - "VC_ID": 3245, - "TokenID": "hfkjshdf347r8743", - "generalId": 'Cs2020@2016\$2958', - "DoctorId": 1485 , + "VC_ID": vcId, + "TokenID": tokenID, + "generalId": generalId, + "DoctorId": doctorId , }, ); if(result['callResponse'] == 'CallEnd') { onCallEnd(); } else { - SessionStatusModel sessionStatusModel = SessionStatusModel.fromJson(Platform.isIOS ?result['sessionStatus'] :json.decode(result['sessionStatus'])); - callNotRespond(sessionStatusModel); + onCallNotRespond(sessionStatusModel); } - } on PlatformException catch (e) { + } catch (e) { onFailure(e.toString()); }