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..2e7c32a7 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, 30 * 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..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
@@ -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(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">
'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.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..0a5ed700 100644
--- a/ios/Runner/AppDelegate.swift
+++ b/ios/Runner/AppDelegate.swift
@@ -6,18 +6,30 @@ import OpenTok
// Copyright © 2020 Cloud. All rights reserved.
@UIApplicationMain
-@objc class AppDelegate: FlutterAppDelegate {
+@objc class AppDelegate: FlutterAppDelegate ,ICallProtocol {
+
+ var result: FlutterResult?
+
+
+ func sessionDone(res:Any) {
+ self.result?(res)
+
+ }
+ func sessionNotResponded(res:Any) {
+ self.result?(res)
+ }
+
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
-
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
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 {
@@ -26,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)
@@ -37,9 +53,10 @@ import OpenTok
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
+
- 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"
@@ -48,6 +65,12 @@ 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
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..197be424
--- /dev/null
+++ b/ios/Runner/ICallProtocoll.swift
@@ -0,0 +1,15 @@
+//
+// 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(res:Any)
+ func sessionNotResponded(res: Any)
+}
diff --git a/ios/Runner/ViewControlleraa.swift b/ios/Runner/VideoViewController.swift
similarity index 77%
rename from ios/Runner/ViewControlleraa.swift
rename to ios/Runner/VideoViewController.swift
index 6e7c17f3..3ff2eef5 100644
--- a/ios/Runner/ViewControlleraa.swift
+++ b/ios/Runner/VideoViewController.swift
@@ -8,6 +8,7 @@
import UIKit
import OpenTok
+import Alamofire
class ViewController: UIViewController {
@@ -22,6 +23,16 @@ 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
+ var isUserConnect : Bool = false
+
override func viewDidLoad() {
super.viewDidLoad()
@@ -34,6 +45,46 @@ class ViewController: UIViewController {
// Do any additional setup after loading the view.
}
+
+ private func getSessionStatus() {
+ 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": 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! 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()
+ }
+ //getting json value from the server
+
+ }
+ }
+
func setupButtons() {
perform(#selector(hideControlButtons), with: nil, afterDelay: 3)
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(remoteVideoTapped(_:)))
@@ -102,6 +153,7 @@ class ViewController: UIViewController {
}
@IBAction func hangUp(_ sender: UIButton) {
+ callBack?.sessionDone(res:["callResponse":"CallEnd"])
sessionDisconnect()
}
@@ -204,6 +256,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 {
+ getSessionStatus()
+
+ }
+
+ }
}
@@ -212,11 +273,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
@@ -300,6 +367,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))")
+ }
+ isUserConnect = true
+ timer.invalidate()
+ }
}
diff --git a/lib/config/config.dart b/lib/config/config.dart
index 261fcd46..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 =
@@ -35,23 +37,43 @@ 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';
+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/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/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/models/livecare/session_status_model.dart b/lib/models/livecare/session_status_model.dart
new file mode 100644
index 00000000..7e7a3e43
--- /dev/null
+++ b/lib/models/livecare/session_status_model.dart
@@ -0,0 +1,28 @@
+class SessionStatusModel {
+ bool isAuthenticated;
+ int messageStatus;
+ String result;
+ int sessionStatus;
+
+ SessionStatusModel(
+ {this.isAuthenticated,
+ this.messageStatus,
+ this.result,
+ this.sessionStatus});
+
+ SessionStatusModel.fromJson(Map 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/providers/auth_provider.dart b/lib/providers/auth_provider.dart
index 61a61530..69551b7b 100644
--- a/lib/providers/auth_provider.dart
+++ b/lib/providers/auth_provider.dart
@@ -3,21 +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';
DrAppSharedPreferances sharedPref = new DrAppSharedPreferances();
enum APP_STATUS { LOADING, UNAUTHENTICATED, AUTHENTICATED }
@@ -166,11 +155,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..7548dc2c 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 doctorClinicsList = [];
+ bool isLoading = false;
+ bool isError = false;
+ String error = '';
Locale get appLocal => _appLocale;
bool get isArabic => _isArabic;
StreamSubscription subscription;
- // AuthProvider authProvider = AuthProvider();
ProjectProvider() {
loadSharedPrefLanguage();
@@ -66,17 +72,44 @@ class ProjectProvider with ChangeNotifier {
currentLanguage = 'en';
sharedPref.setString(APP_Language, 'en');
}
- getProfile();
+ callServicesAfterChangeLang();
notifyListeners();
}
+ callServicesAfterChangeLang() {
+ getProfile();
+ getDoctorClinicsList();
+ }
+
@override
void dispose() {
if (subscription != null) subscription.cancel();
super.dispose();
}
- void getProfile()async{
+ Future getDoctorClinicsList() async {
+ try {
+ dynamic localRes;
+
+ await BaseAppClient.post(GET_CLINICS_FOR_DOCTOR,
+ onSuccess: (dynamic response, int statusCode) {
+ doctorClinicsList = [];
+ response['List_DoctorsClinic'].forEach((v) {
+ doctorClinicsList.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 +120,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 ad64d89a..3dce5276 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';
@@ -51,6 +54,17 @@ 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.getDoctorClinicsList();
+ }
+ _isInit = false;
+ }
+
BuildContext myContext;
GlobalKey _one = GlobalKey();
@@ -61,7 +75,6 @@ class _DashboardScreenState extends State {
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();
@@ -92,7 +105,9 @@ class _DashboardScreenState extends State {
fontWeight: FontWeight.bold,
fontSize: SizeConfig.textMultiplier * 2.5,
),
- alignment: Alignment.centerLeft,
+ alignment: projectsProvider.isArabic
+ ? Alignment.topRight
+ : Alignment.topLeft,
),
),
Row(
@@ -101,10 +116,10 @@ class _DashboardScreenState extends State {
crossAxisAlignment: CrossAxisAlignment.end,
children: [
InkWell(
- onTap: () {
- showCupertinoPicker(
- context: context,
- actionList: authProvider.doctorsClinicList);
+ onTap: () async {
+ showCupertinoPicker(
+ decKey: '',context: context,
+ actionList: projectsProvider.doctorClinicsList);
},
child: Container(
margin:
@@ -301,7 +316,9 @@ class _DashboardScreenState extends State {
TranslationBase.of(context).patientServices,
fontWeight: FontWeight.bold,
),
- alignment: Alignment.centerLeft,
+ alignment: projectsProvider.isArabic
+ ? Alignment.topRight
+ : Alignment.topLeft,
),
),
Expanded(
@@ -529,19 +546,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);
@@ -555,14 +570,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,
+ style: TextStyle(
+ fontSize:
+ SizeConfig.textMultiplier *
+ 1.9),
+ )),
+ ),
))
.toList(),
))
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 c5bf278e..bf255b54 100644
--- a/lib/util/VideoChannel.dart
+++ b/lib/util/VideoChannel.dart
@@ -1,28 +1,44 @@
+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';
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,int vcId,String tokenID,String generalId,int doctorId, Function() onCallEnd , Function(SessionStatusModel sessionStatusModel) onCallNotRespond ,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": vcId,
+ "TokenID": tokenID,
+ "generalId": generalId,
+ "DoctorId": doctorId ,
},
);
- } on PlatformException catch (e) {
- result = e.toString();
+ if(result['callResponse'] == 'CallEnd') {
+ onCallEnd();
+ }
+ else {
+ SessionStatusModel sessionStatusModel = SessionStatusModel.fromJson(Platform.isIOS ?result['sessionStatus'] :json.decode(result['sessionStatus']));
+ onCallNotRespond(sessionStatusModel);
+ }
+
+ } catch (e) {
+ onFailure(e.toString());
}
- return result;
+
}
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 {
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.';
}