Merge branch 'development' into 'master'

Development

See merge request Cloud_Solution/doctor_app_flutter!142
merge-requests/145/merge
Mohammad Aljammal 6 years ago
commit 4fe69599fb

@ -61,7 +61,15 @@ flutter {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.appcompat:appcompat:1.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
//openTok
implementation 'com.opentok.android:opentok-android-sdk:2.16.5'
//permissions
implementation 'pub.devrel:easypermissions:0.4.0'
}

@ -1,32 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.doctor_app_flutter">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
<!--
io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<uses-permission android:name="android.permission.INTERNET"/>
FlutterApplication and put your custom class here.
-->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<application
android:name="io.flutter.app.FlutterApplication"
android:label="doctor_app_flutter"
android:icon="@mipmap/ic_launcher">
android:icon="@mipmap/ic_launcher"
android:label="doctor_app_flutter">
<activity android:name=".VideoCallActivity"></activity>
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<!--
Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java
-->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
</manifest>

@ -0,0 +1,390 @@
package com.example.doctor_app_flutter;
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.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;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.opentok.android.Session;
import com.opentok.android.Stream;
import com.opentok.android.Publisher;
import com.opentok.android.PublisherKit;
import com.opentok.android.Subscriber;
import com.opentok.android.BaseVideoRenderer;
import com.opentok.android.OpentokError;
import com.opentok.android.SubscriberKit;
import java.util.List;
import java.util.Objects;
import pub.devrel.easypermissions.AfterPermissionGranted;
import pub.devrel.easypermissions.AppSettingsDialog;
import pub.devrel.easypermissions.EasyPermissions;
public class VideoCallActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks,
Session.SessionListener,
Publisher.PublisherListener,
Subscriber.VideoListener {
private static final String TAG = VideoCallActivity.class.getSimpleName();
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 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 boolean isSwitchCameraClicked;
private boolean isCameraClicked;
private boolean isSpeckerClicked;
private boolean isMicClicked;
private ImageView mCallBtn;
private ImageView mCameraBtn;
private ImageView mSwitchCameraBtn;
private ImageView mspeckerBtn;
private ImageView mMicBtn;
private ProgressBar progressBar;
private CountDownTimer countDownTimer;
private TextView progressBarTextView;
private RelativeLayout progressBarLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_call);
Objects.requireNonNull(getSupportActionBar()).hide();
initUI();
requestPermissions();
}
@Override
protected void onPause() {
super.onPause();
if (mSession == null) {
return;
}
mSession.onPause();
if (isFinishing()) {
disconnectSession();
}
}
@Override
protected void onResume() {
super.onResume();
if (mSession == null) {
return;
}
mSession.onResume();
}
@Override
protected void onDestroy() {
disconnectSession();
super.onDestroy();
}
@SuppressLint("ClickableViewAccessibility")
private void initUI() {
mPublisherViewContainer = (FrameLayout) findViewById(R.id.local_video_view_container);
mSubscriberViewContainer = (RelativeLayout) findViewById(R.id.remote_video_view_container);
apiKey = getIntent().getStringExtra("apiKey");
sessionId = getIntent().getStringExtra("sessionId");
token = getIntent().getStringExtra("token");
// callDuration = getIntent().getStringExtra("callDuration");
// warningDuration = getIntent().getStringExtra("warningDuration");
appLang=getIntent().getStringExtra("appLang");
controlPanel=findViewById(R.id.control_panel);
mCallBtn = findViewById(R.id.btn_call);
mCameraBtn = findViewById(R.id.btn_camera);
mSwitchCameraBtn = findViewById(R.id.btn_switch_camera);
mspeckerBtn = findViewById(R.id.btn_specker);
mMicBtn = findViewById(R.id.btn_mic);
// progressBarLayout=findViewById(R.id.progressBar);
// progressBar=findViewById(R.id.progress_bar);
// progressBarTextView=findViewById(R.id.progress_bar_text);
// progressBar.setVisibility(View.GONE);
hiddenButtons();
mSubscriberViewContainer.setOnTouchListener((v, event) -> {
controlPanel.setVisibility(View.VISIBLE);
mVolHandler.removeCallbacks(mVolRunnable);
mVolHandler.postDelayed(mVolRunnable, 5*1000);
return true;
});
if (appLang.equals("ar")) {
progressBarLayout.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
}
}
private void hiddenButtons(){
mVolHandler = new Handler();
mVolRunnable = new Runnable() {
public void run() {
controlPanel.setVisibility(View.GONE);
}
};
mVolHandler.postDelayed(mVolRunnable,5*1000);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
@Override
public void onPermissionsGranted(int requestCode, List<String> perms) {
Log.d(TAG, "onPermissionsGranted:" + requestCode + ":" + perms.size());
}
@Override
public void onPermissionsDenied(int requestCode, List<String> perms) {
Log.d(TAG, "onPermissionsDenied:" + requestCode + ":" + perms.size());
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
new AppSettingsDialog.Builder(this)
.setTitle(getString(R.string.title_settings_dialog))
.setRationale(getString(R.string.rationale_ask_again))
.setPositiveButton(getString(R.string.setting))
.setNegativeButton(getString(R.string.cancel))
.setRequestCode(RC_SETTINGS_SCREEN_PERM)
.build()
.show();
}
}
@AfterPermissionGranted(RC_VIDEO_APP_PERM)
private void requestPermissions() {
String[] perms = {Manifest.permission.INTERNET, Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO};
if (EasyPermissions.hasPermissions(this, perms)) {
mSession = new Session.Builder(VideoCallActivity.this, apiKey, sessionId).build();
mSession.setSessionListener(this);
mSession.connect(token);
} else {
EasyPermissions.requestPermissions(this, getString(R.string.remaining_ar), RC_VIDEO_APP_PERM, perms);
}
}
@Override
public void onConnected(Session session) {
Log.i(TAG, "Session Connected");
mPublisher = new Publisher.Builder(this).build();
mPublisher.setPublisherListener(this);
mPublisherViewContainer.addView(mPublisher.getView());
if (mPublisher.getView() instanceof GLSurfaceView){
((GLSurfaceView) mPublisher.getView()).setZOrderOnTop(true);
}
mSession.publish(mPublisher);
}
@Override
public void onDisconnected(Session session) {
Log.d(TAG, "onDisconnected: disconnected from session " + session.getSessionId());
mSession = null;
}
@Override
public void onError(Session session, OpentokError opentokError) {
Log.d(TAG, "onError: Error (" + opentokError.getMessage() + ") in session " + session.getSessionId());
Toast.makeText(this, "Session error. See the logcat please.", Toast.LENGTH_LONG).show();
finish();
}
@Override
public void onStreamReceived(Session session, Stream stream) {
Log.d(TAG, "onStreamReceived: New stream " + stream.getStreamId() + " in session " + session.getSessionId());
if (mSubscriber != null) {
return;
}
subscribeToStream(stream);
}
@Override
public void onStreamDropped(Session session, Stream stream) {
Log.d(TAG, "onStreamDropped: Stream " + stream.getStreamId() + " dropped from session " + session.getSessionId());
if (mSubscriber == null) {
return;
}
if (mSubscriber.getStream().equals(stream)) {
mSubscriberViewContainer.removeView(mSubscriber.getView());
mSubscriber.destroy();
mSubscriber = null;
}
disconnectSession();
}
@Override
public void onStreamCreated(PublisherKit publisherKit, Stream stream) {
Log.d(TAG, "onStreamCreated: Own stream " + stream.getStreamId() + " created");
}
@Override
public void onStreamDestroyed(PublisherKit publisherKit, Stream stream) {
Log.d(TAG, "onStreamDestroyed: Own stream " + stream.getStreamId() + " destroyed");
}
@Override
public void onError(PublisherKit publisherKit, OpentokError opentokError) {
Log.d(TAG, "onError: Error (" + opentokError.getMessage() + ") in publisher");
Toast.makeText(this, "Session error. See the logcat please.", Toast.LENGTH_LONG).show();
finish();
}
@Override
public void onVideoDataReceived(SubscriberKit subscriberKit) {
mSubscriber.setStyle(BaseVideoRenderer.STYLE_VIDEO_SCALE, BaseVideoRenderer.STYLE_VIDEO_FILL);
mSubscriberViewContainer.addView(mSubscriber.getView());
}
@Override
public void onVideoDisabled(SubscriberKit subscriberKit, String s) {
}
@Override
public void onVideoEnabled(SubscriberKit subscriberKit, String s) {
}
@Override
public void onVideoDisableWarning(SubscriberKit subscriberKit) {
}
@Override
public void onVideoDisableWarningLifted(SubscriberKit subscriberKit) {
}
private void subscribeToStream(Stream stream) {
mSubscriber = new Subscriber.Builder(VideoCallActivity.this, stream).build();
mSubscriber.setVideoListener(this);
mSession.subscribe(mSubscriber);
}
private void disconnectSession() {
if (mSession == null) {
finish();
return;
}
if (mSubscriber != null) {
mSubscriberViewContainer.removeView(mSubscriber.getView());
mSession.unsubscribe(mSubscriber);
mSubscriber.destroy();
mSubscriber = null;
}
if (mPublisher != null) {
mPublisherViewContainer.removeView(mPublisher.getView());
mSession.unpublish(mPublisher);
mPublisher.destroy();
mPublisher = null;
}
mSession.disconnect();
if(countDownTimer!=null) {
countDownTimer.cancel();
}
finish();
}
public void onSwitchCameraClicked(View view) {
if (mPublisher != null) {
isSwitchCameraClicked = !isSwitchCameraClicked;
mPublisher.cycleCamera();
int res = isSwitchCameraClicked ? R.drawable.flip_disapled : R.drawable.flip_enabled;
mSwitchCameraBtn.setImageResource(res);
}
}
public void onCameraClicked(View view) {
if (mPublisher != null) {
isCameraClicked = !isCameraClicked;
mPublisher.setPublishVideo(!isCameraClicked);
int res = isCameraClicked ? R.drawable.video_disanabled : R.drawable.video_enabled;
mCameraBtn.setImageResource(res);
}
}
public void onSpeckerClicked(View view) {
if (mSubscriber != null) {
isSpeckerClicked = !isSpeckerClicked;
mSubscriber.setSubscribeToAudio(!isSpeckerClicked);
int res = isSpeckerClicked ? R.drawable.audio_disabled : R.drawable.audio_enabled;
mspeckerBtn.setImageResource(res);
}
}
public void onMicClicked(View view) {
if (mPublisher != null) {
isMicClicked = !isMicClicked;
mPublisher.setPublishAudio(!isMicClicked);
int res = isMicClicked ? R.drawable.mic_disabled : R.drawable.mic_enabled;
mMicBtn.setImageResource(res);
}
}
public void onCallClicked(View view) {
disconnectSession();
}
}

@ -1,13 +1,45 @@
package com.example.doctor_app_flutter
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 io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.plugin.common.MethodChannel
class MainActivity: FlutterFragmentActivity() {
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
private val CHANNEL = "Dr.cloudSolution/videoCall"
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<String>("kApiKey")
val sessionId = call.argument<String>("kSessionId")
val token = call.argument<String>("kToken")
// val callDuration = call.argument<String>("callDuration")
// val warningDuration = call.argument<String>("warningDuration")
val appLang = call.argument<String>("appLang")
openVideoCall(apiKey,sessionId,token/*,callDuration,warningDuration*/,appLang)
} else {
result.notImplemented()
}
}
}
private fun openVideoCall(apiKey: String?, sessionId: String?, token: String?/*, callDuration: String?, warningDuration: String?*/, appLang: String?) {
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)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

@ -0,0 +1,169 @@
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_clingo_video_call"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".VideoCallActivity">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal"
android:keepScreenOn="true"
android:clickable="true">
<LinearLayout
android:id="@+id/subscriberview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:orientation="horizontal"/>
<RelativeLayout
android:id="@+id/publisherview"
android:layout_height="200dp"
android:layout_width="150dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/remote_video_view_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/remoteBackground">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/icon_padding">
<ImageView
android:layout_width="@dimen/remote_back_icon_size"
android:layout_height="@dimen/remote_back_icon_size"
android:layout_centerInParent="true"
android:src="@drawable/video_off_fill" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/icon_padding"
android:layout_width="match_parent"
android:layout_height="@dimen/remote_back_icon_margin_bottom"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
<FrameLayout
android:id="@+id/local_video_view_container"
android:layout_width="@dimen/local_preview_width"
android:layout_height="@dimen/local_preview_height"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginEnd="@dimen/local_preview_margin_right"
android:layout_marginRight="@dimen/local_preview_margin_right"
android:layout_marginTop="@dimen/local_preview_margin_top"
android:background="@color/localBackground">
<ImageView
android:layout_width="@dimen/local_back_icon_size"
android:layout_height="@dimen/local_back_icon_size"
android:layout_gravity="center"
android:scaleType="centerCrop"
android:src="@drawable/video_off_fill" />
</FrameLayout>
<RelativeLayout
android:id="@+id/control_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="60dp">
<ImageView
android:id="@+id/btn_call"
android:layout_width="71dp"
android:layout_height="71dp"
android:layout_centerInParent="true"
android:onClick="onCallClicked"
android:scaleType="centerCrop"
android:src="@drawable/call" />
<ImageView
android:id="@+id/btn_switch_camera"
android:layout_width="39dp"
android:layout_height="39dp"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/control_bottom_horizontal_margin"
android:layout_toEndOf="@id/btn_camera"
android:layout_toRightOf="@id/btn_camera"
android:onClick="onSwitchCameraClicked"
android:scaleType="centerCrop"
android:src="@drawable/flip_enabled" />
<ImageView
android:id="@+id/btn_camera"
android:layout_width="39dp"
android:layout_height="39dp"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/control_bottom_horizontal_margin"
android:layout_toEndOf="@id/btn_call"
android:layout_toRightOf="@id/btn_call"
android:onClick="onCameraClicked"
android:scaleType="centerCrop"
android:src="@drawable/video_enabled" />
<ImageView
android:id="@+id/btn_mic"
android:layout_width="39dp"
android:layout_height="39dp"
android:layout_centerVertical="true"
android:layout_marginRight="@dimen/control_bottom_horizontal_margin"
android:layout_toStartOf="@id/btn_call"
android:layout_toLeftOf="@id/btn_call"
android:onClick="onMicClicked"
android:scaleType="centerCrop"
android:src="@drawable/mic_enabled" />
<ImageView
android:id="@+id/btn_specker"
android:layout_width="39dp"
android:layout_height="39dp"
android:layout_centerVertical="true"
android:layout_marginRight="@dimen/control_bottom_horizontal_margin"
android:layout_toStartOf="@id/btn_mic"
android:layout_toLeftOf="@id/btn_mic"
android:onClick="onSpeckerClicked"
android:scaleType="centerCrop"
android:src="@drawable/audio_enabled" />
</RelativeLayout>
<!-- <RelativeLayout-->
<!-- android:id="@+id/progressBar"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="40dp"-->
<!-- android:layout_alignParentBottom="true">-->
<!-- <ProgressBar-->
<!-- android:id="@+id/progress_bar"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="31dp"-->
<!-- android:layout_alignParentEnd="true"-->
<!-- android:layout_alignParentBottom="true"-->
<!-- android:layout_marginEnd="0dp"-->
<!-- android:layout_marginBottom="0dp"-->
<!-- android:progressBackgroundTint="@color/colorProgressBarBackground"-->
<!-- style="@android:style/Widget.ProgressBar.Horizontal" />-->
<!-- <TextView-->
<!-- android:id="@+id/progress_bar_text"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginLeft="9dp"-->
<!-- android:gravity="center_vertical"-->
<!-- android:textColor="@color/colorPrimary"-->
<!-- android:layout_centerInParent="true"/>-->
<!-- </RelativeLayout>-->
</RelativeLayout>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#ffffff</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#fc3850</color>
<color name="colorProgressBarBackground">#e4e9f2</color>
<!-- Chat Activity -->
<color name="localBackground">#827b92</color>
<color name="remoteBackground">#484258</color>
</resources>

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="local_preview_margin_top">28dp</dimen>
<dimen name="local_preview_margin_right">24dp</dimen>
<!-- buttons -->
<dimen name="call_button_size">60dp</dimen>
<dimen name="other_button_size">54dp</dimen>
<dimen name="local_preview_width">88dp</dimen>
<dimen name="local_preview_height">117dp</dimen>
<dimen name="local_back_icon_size">50dp</dimen>
<dimen name="remote_back_icon_size">100dp</dimen>
<dimen name="remote_back_icon_margin_bottom">90dp</dimen>
<!-- buttons -->
<dimen name="control_bottom_margin">24dp</dimen>
<dimen name="control_bottom_horizontal_margin">25dp</dimen>
</resources>

@ -0,0 +1,8 @@
<resources>
<string name="remaining_en">Remaining Time In Seconds: </string>
<string name="remaining_ar">الوقت المتبقي بالثانيه: </string>
<string name="setting">Settings</string>
<string name="cancel">Cancel</string>
</resources>

@ -5,4 +5,15 @@
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<style name="AppTheme" parent="Theme.AppCompat">
</style>
<style name="FullScreenVideoTheme" parent="AppTheme">
<item name="windowNoTitle">true</item>
<item name="windowActionBar">true</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
</resources>

@ -15,6 +15,7 @@ allprojects {
repositories {
google()
jcenter()
maven { url 'https://tokbox.bintray.com/maven' }
}
}

@ -63,6 +63,7 @@ target 'Runner' do
# Keep pod path relative so it can be checked into Podfile.lock.
pod 'Flutter', :path => 'Flutter'
pod 'OpenTok'
# Plugin Pods

@ -22,6 +22,7 @@ PODS:
- local_auth (0.0.1):
- Flutter
- MTBBarcodeScanner (5.0.11)
- OpenTok (2.15.3)
- "permission_handler (5.0.0+hotfix.5)":
- Flutter
- Reachability (3.2)
@ -50,6 +51,7 @@ DEPENDENCIES:
- hexcolor (from `.symlinks/plugins/hexcolor/ios`)
- imei_plugin (from `.symlinks/plugins/imei_plugin/ios`)
- local_auth (from `.symlinks/plugins/local_auth/ios`)
- OpenTok
- permission_handler (from `.symlinks/plugins/permission_handler/ios`)
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
- shared_preferences_macos (from `.symlinks/plugins/shared_preferences_macos/ios`)
@ -59,8 +61,9 @@ DEPENDENCIES:
- url_launcher_web (from `.symlinks/plugins/url_launcher_web/ios`)
SPEC REPOS:
https://cdn.cocoapods.org/:
trunk:
- MTBBarcodeScanner
- OpenTok
- Reachability
- SwiftProtobuf
@ -112,6 +115,7 @@ SPEC CHECKSUMS:
imei_plugin: cb1af7c223ac2d82dcd1457a7137d93d65d2a3cd
local_auth: 25938960984c3a7f6e3253e3f8d962fdd16852bd
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
OpenTok: fde03ecc5ea31fe0a453242847c4ee1f47e1d735
permission_handler: 6226fcb78b97c7c7458a95c7346a11d5184fec12
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
@ -122,6 +126,6 @@ SPEC CHECKSUMS:
url_launcher_macos: fd7894421cd39320dce5f292fc99ea9270b2a313
url_launcher_web: e5527357f037c87560776e36436bf2b0288b965c
PODFILE CHECKSUM: 1b66dae606f75376c5f2135a8290850eeb09ae83
PODFILE CHECKSUM: ad71cae222b2dc22820a69b80873417b35fef79e
COCOAPODS: 1.9.3

@ -13,6 +13,7 @@
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 */; };
AF260AD724A4922F006461D3 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF260AD624A4922F006461D3 /* ViewController.swift */; };
B650DC3076E9D70CB188286A /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93A5F83B23AB032D1E096663 /* Pods_Runner.framework */; };
/* End PBXBuildFile section */
@ -46,6 +47,7 @@
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
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 = "<group>"; };
AF260AD624A4922F006461D3 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ViewController.swift; path = ../../../../AndroidStudioProjects/open_tok_app/ios/Runner/ViewController.swift; sourceTree = "<group>"; };
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 = "<group>"; };
/* End PBXFileReference section */
@ -104,6 +106,7 @@
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
AF260AD624A4922F006461D3 /* ViewController.swift */,
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
@ -278,6 +281,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
AF260AD724A4922F006461D3 /* ViewController.swift in Sources */,
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
@ -307,7 +311,6 @@
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
@ -385,7 +388,6 @@
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
@ -441,7 +443,6 @@
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;

@ -1,5 +1,9 @@
import UIKit
import Flutter
import OpenTok
// Created by Mohammad Aljammal & Elham Rababah on 24/06/20.
// Copyright © 2020 Cloud. All rights reserved.
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
@ -7,7 +11,47 @@ import Flutter
_ 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
switch call.method {
case "openVideoCall":
do {
let arguments = call.arguments as? NSDictionary
let kApiKey = arguments!["kApiKey"] as? String
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!)
}
default:
result(FlutterMethodNotImplemented)
}
})
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
private func openVideoChat(result: FlutterResult,kApiKey: String, kSessionId: String,kToken: String,appLang:String) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let identifier = "ViewControllerNav"
let navVC = storyboard.instantiateViewController(withIdentifier: identifier) as! UINavigationController
let videoVC = navVC.viewControllers.first as! ViewController
videoVC.kApiKey=kApiKey
videoVC.kSessionId=kSessionId
videoVC.kToken=kToken
videoVC.navigationController?.setNavigationBarHidden(true, animated: false)
navVC.modalPresentationStyle = .fullScreen
window.rootViewController?.present(navVC, animated: true, completion: nil)
}
}

@ -0,0 +1,98 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "call.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "call-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "call-2.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "cameramute.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "mic_enabled.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "mic_enabled-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "mic_enabled-2.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "mic_disabled.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "mic_disabled-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "mic_disabled-2.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "audio_enabled.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "audio_enabled-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "audio_enabled-2.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "audio_disabled.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "audio_disabled-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "audio_disabled-2.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "flip_enabled-2.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "flip_enabled.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "flip_enabled-1.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "flip_disapled.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "flip_disapled-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "flip_disapled-2.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "video_enabled-2.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "video_enabled-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "video_enabled.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "video_disanabled.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "video_disanabled-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "video_disanabled-2.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "cameraoff_mainVideo.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
@ -14,13 +16,281 @@
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-45" y="1436"/>
</scene>
<!--View Controller-->
<scene sceneID="L7v-n1-KvF">
<objects>
<viewController id="t2c-G5-7AE" customClass="ViewController" customModule="Runner" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="BIa-yr-ZMY"/>
<viewControllerLayoutGuide type="bottom" id="VIH-1T-Ife"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="PoR-7r-yNe">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="6C5-o5-R1n" userLabel="controlButtonSpacer">
<rect key="frame" x="14" y="844" width="139" height="30"/>
<constraints>
<constraint firstAttribute="height" constant="30" id="0mU-Ko-Up3"/>
<constraint firstAttribute="width" constant="139" id="DNz-Ig-XOS"/>
</constraints>
</view>
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="yS9-HT-vp8" userLabel="controlButtonSpacer">
<rect key="frame" x="265" y="844" width="140" height="30"/>
<constraints>
<constraint firstAttribute="width" constant="140" id="Alm-7E-yeU"/>
<constraint firstAttribute="height" constant="30" id="amS-in-0UH"/>
</constraints>
</view>
<view contentMode="scaleToFill" restorationIdentifier="VideoCallNavigationViewController" translatesAutoresizingMaskIntoConstraints="NO" id="eOT-Jr-GUl" userLabel="remoteVideo">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
</view>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="videoMutedIndicator" translatesAutoresizingMaskIntoConstraints="NO" id="CL1-2v-m1L" userLabel="remoteVideoMutedIndicator">
<rect key="frame" x="147" y="398" width="120" height="100"/>
<constraints>
<constraint firstAttribute="width" constant="120" id="eon-3Z-74P"/>
<constraint firstAttribute="height" constant="100" id="iyK-hL-H3m"/>
</constraints>
</imageView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0ZP-s2-kM5" userLabel="localVideo">
<rect key="frame" x="270.5" y="138" width="103.5" height="224"/>
</view>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="localVideoMutedBg" translatesAutoresizingMaskIntoConstraints="NO" id="A0G-cT-yji" userLabel="localVideoMutedBg">
<rect key="frame" x="215" y="138" width="159" height="224"/>
</imageView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="sK0-tB-H9u" userLabel="controlButtons">
<rect key="frame" x="0.0" y="740" width="414" height="80"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="NUO-2p-pzL" userLabel="videoMuteButton">
<rect key="frame" x="29" y="20.5" width="39" height="39"/>
<constraints>
<constraint firstAttribute="width" constant="39" id="CWU-fT-9gx"/>
<constraint firstAttribute="height" constant="39" id="nsM-Xv-O2N"/>
</constraints>
<state key="normal" title="Button" image="speakerOff"/>
<state key="selected" image="speakerOffSelected"/>
<connections>
<action selector="didClickSpeakerButton:" destination="t2c-G5-7AE" eventType="touchUpInside" id="XHg-oo-TWD"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="N2h-FX-kF5" userLabel="muteButton">
<rect key="frame" x="98" y="20.5" width="39" height="39"/>
<constraints>
<constraint firstAttribute="width" constant="39" id="Nv9-dR-SYL"/>
<constraint firstAttribute="height" constant="39" id="lFc-rS-c6B"/>
</constraints>
<state key="normal" title="Button" image="muteButton"/>
<state key="selected" image="muteButtonSelected"/>
<connections>
<action selector="didClickMuteButton:" destination="t2c-G5-7AE" eventType="touchUpInside" id="xYM-PE-Zzq"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ygd-al-G4F" userLabel="switchCameraButton">
<rect key="frame" x="352" y="20.5" width="39" height="39"/>
<constraints>
<constraint firstAttribute="width" constant="39" id="EHa-e5-BfD"/>
<constraint firstAttribute="height" constant="39" id="KEK-0n-HJw"/>
</constraints>
<state key="normal" title="Button" image="switchCameraButton"/>
<state key="selected" image="switchCameraButtonSelected"/>
<connections>
<action selector="didClickSwitchCameraButton:" destination="t2c-G5-7AE" eventType="touchUpInside" id="TBa-Av-IXy"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="AoF-Up-Yu5" userLabel="hangUpButton">
<rect key="frame" x="174" y="4.5" width="71" height="71"/>
<constraints>
<constraint firstAttribute="width" constant="71" id="ACP-i0-gK8"/>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="71" id="DS1-a1-ep3"/>
<constraint firstAttribute="height" constant="71" id="ltx-rR-am0"/>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="71" id="s7u-Zs-z2Q"/>
</constraints>
<state key="normal" image="hangUpButton"/>
<connections>
<action selector="hangUp:" destination="t2c-G5-7AE" eventType="touchUpInside" id="SUH-Gd-OXj"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="7vf-kV-eQ5" userLabel="videoMuteButton">
<rect key="frame" x="283" y="20.5" width="39" height="39"/>
<constraints>
<constraint firstAttribute="height" constant="39" id="7Rd-r8-zJP"/>
<constraint firstAttribute="width" constant="39" id="mwK-hd-jIy"/>
</constraints>
<state key="normal" title="Button" image="videoMuteButton"/>
<state key="selected" image="videoMuteButtonSelected"/>
<connections>
<action selector="didClickVideoMuteButton:" destination="t2c-G5-7AE" eventType="touchUpInside" id="Hza-Ft-NNB"/>
</connections>
</button>
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9g2-IH-l8e" userLabel="controlButtonSpacer">
<rect key="frame" x="396" y="0.0" width="18" height="80"/>
<constraints>
<constraint firstAttribute="width" priority="750" constant="18" id="7f6-zT-RoW"/>
<constraint firstAttribute="height" constant="80" id="cmy-aX-hM0"/>
</constraints>
</view>
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="a4N-1U-1Yt" userLabel="controlButtonSpacer">
<rect key="frame" x="328" y="0.0" width="18" height="80"/>
<constraints>
<constraint firstAttribute="width" priority="750" constant="18" id="X8j-wu-KrQ"/>
<constraint firstAttribute="height" constant="80" id="vkd-63-bmN"/>
</constraints>
</view>
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="GbA-j6-191" userLabel="controlButtonSpacer">
<rect key="frame" x="259" y="0.0" width="18" height="80"/>
<constraints>
<constraint firstAttribute="width" priority="750" constant="18" id="Bz0-tD-Q4d"/>
<constraint firstAttribute="height" constant="80" id="Ovg-ap-S7E"/>
</constraints>
</view>
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="h0g-z5-Y95" userLabel="controlButtonSpacer">
<rect key="frame" x="143" y="0.0" width="18" height="80"/>
<constraints>
<constraint firstAttribute="height" constant="80" id="Vaj-Va-jZn"/>
<constraint firstAttribute="width" priority="750" constant="18" id="Wv5-ys-Ho4"/>
</constraints>
</view>
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gop-Yl-2fm" userLabel="controlButtonSpacer">
<rect key="frame" x="73" y="0.0" width="18" height="80"/>
<constraints>
<constraint firstAttribute="width" priority="750" constant="18" id="iqX-Wz-fb1"/>
<constraint firstAttribute="height" constant="80" id="j0P-xC-zSP"/>
</constraints>
</view>
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="JCG-W9-5ko" userLabel="controlButtonSpacer">
<rect key="frame" x="6" y="0.0" width="18" height="80"/>
<constraints>
<constraint firstAttribute="width" priority="750" constant="18" id="La6-ZY-Qs8"/>
<constraint firstAttribute="height" constant="80" id="mf9-Qg-gVZ"/>
</constraints>
</view>
</subviews>
<constraints>
<constraint firstItem="9g2-IH-l8e" firstAttribute="leading" secondItem="ygd-al-G4F" secondAttribute="trailing" constant="5" id="0Bv-9b-HQh"/>
<constraint firstItem="a4N-1U-1Yt" firstAttribute="leading" secondItem="7vf-kV-eQ5" secondAttribute="trailing" constant="6" id="4vp-mw-gRE"/>
<constraint firstAttribute="height" constant="80" id="5QG-54-ulG"/>
<constraint firstItem="GbA-j6-191" firstAttribute="width" secondItem="h0g-z5-Y95" secondAttribute="width" id="5cw-b2-SPx"/>
<constraint firstItem="h0g-z5-Y95" firstAttribute="width" secondItem="gop-Yl-2fm" secondAttribute="width" id="7oE-3V-2Gc"/>
<constraint firstItem="7vf-kV-eQ5" firstAttribute="centerY" secondItem="sK0-tB-H9u" secondAttribute="centerY" id="8zH-6k-6Wz"/>
<constraint firstItem="gop-Yl-2fm" firstAttribute="leading" secondItem="NUO-2p-pzL" secondAttribute="trailing" constant="5" id="Bbh-OY-I9f"/>
<constraint firstItem="NUO-2p-pzL" firstAttribute="leading" secondItem="JCG-W9-5ko" secondAttribute="trailing" constant="5" id="Ccz-Qq-RXf"/>
<constraint firstItem="gop-Yl-2fm" firstAttribute="centerY" secondItem="sK0-tB-H9u" secondAttribute="centerY" id="DE6-nZ-rEI"/>
<constraint firstItem="GbA-j6-191" firstAttribute="centerY" secondItem="sK0-tB-H9u" secondAttribute="centerY" id="EVH-xy-wpT"/>
<constraint firstItem="ygd-al-G4F" firstAttribute="leading" secondItem="a4N-1U-1Yt" secondAttribute="trailing" constant="6" id="FNy-Br-FIj"/>
<constraint firstItem="NUO-2p-pzL" firstAttribute="centerY" secondItem="sK0-tB-H9u" secondAttribute="centerY" id="Fme-oB-F7i"/>
<constraint firstItem="GbA-j6-191" firstAttribute="leading" secondItem="AoF-Up-Yu5" secondAttribute="trailing" constant="14" id="GxO-Fe-iqR"/>
<constraint firstItem="JCG-W9-5ko" firstAttribute="centerY" secondItem="sK0-tB-H9u" secondAttribute="centerY" id="HPP-q4-IDT"/>
<constraint firstItem="h0g-z5-Y95" firstAttribute="leading" secondItem="N2h-FX-kF5" secondAttribute="trailing" constant="6" id="I2J-pE-7yx"/>
<constraint firstItem="7vf-kV-eQ5" firstAttribute="leading" secondItem="GbA-j6-191" secondAttribute="trailing" constant="6" id="MVo-If-UVQ"/>
<constraint firstItem="a4N-1U-1Yt" firstAttribute="width" secondItem="GbA-j6-191" secondAttribute="width" id="Me9-IC-YE2"/>
<constraint firstItem="N2h-FX-kF5" firstAttribute="leading" secondItem="gop-Yl-2fm" secondAttribute="trailing" constant="7" id="RHr-s8-sAg"/>
<constraint firstItem="h0g-z5-Y95" firstAttribute="centerY" secondItem="sK0-tB-H9u" secondAttribute="centerY" id="RJj-Uh-H2E"/>
<constraint firstItem="a4N-1U-1Yt" firstAttribute="centerY" secondItem="sK0-tB-H9u" secondAttribute="centerY" id="Tb2-6o-Wqh"/>
<constraint firstItem="AoF-Up-Yu5" firstAttribute="leading" secondItem="h0g-z5-Y95" secondAttribute="trailing" constant="13" id="VZS-xZ-nbe"/>
<constraint firstItem="NUO-2p-pzL" firstAttribute="leading" secondItem="JCG-W9-5ko" secondAttribute="trailing" constant="5" id="Z1j-5z-34E"/>
<constraint firstItem="7vf-kV-eQ5" firstAttribute="leading" secondItem="GbA-j6-191" secondAttribute="trailing" constant="6" id="ZjD-GK-SkY"/>
<constraint firstItem="ygd-al-G4F" firstAttribute="centerY" secondItem="sK0-tB-H9u" secondAttribute="centerY" id="bJA-GM-b2E"/>
<constraint firstItem="ygd-al-G4F" firstAttribute="leading" secondItem="a4N-1U-1Yt" secondAttribute="trailing" constant="6" id="eFd-3F-A5f"/>
<constraint firstItem="JCG-W9-5ko" firstAttribute="leading" secondItem="sK0-tB-H9u" secondAttribute="leading" constant="6" id="f0s-gb-347"/>
<constraint firstItem="gop-Yl-2fm" firstAttribute="leading" secondItem="NUO-2p-pzL" secondAttribute="trailing" constant="5" id="frf-I5-Rs9"/>
<constraint firstItem="gop-Yl-2fm" firstAttribute="width" secondItem="JCG-W9-5ko" secondAttribute="width" id="i84-jd-Hwr"/>
<constraint firstItem="N2h-FX-kF5" firstAttribute="leading" secondItem="gop-Yl-2fm" secondAttribute="trailing" constant="7" id="jlv-lR-Nlf"/>
<constraint firstItem="N2h-FX-kF5" firstAttribute="centerY" secondItem="sK0-tB-H9u" secondAttribute="centerY" id="nU8-Hw-s0U"/>
<constraint firstItem="9g2-IH-l8e" firstAttribute="centerY" secondItem="sK0-tB-H9u" secondAttribute="centerY" id="pxq-U1-zP5"/>
<constraint firstItem="AoF-Up-Yu5" firstAttribute="centerY" secondItem="sK0-tB-H9u" secondAttribute="centerY" id="ql2-fm-OeZ"/>
<constraint firstItem="9g2-IH-l8e" firstAttribute="width" secondItem="a4N-1U-1Yt" secondAttribute="width" id="uXs-zM-gyf"/>
<constraint firstItem="h0g-z5-Y95" firstAttribute="leading" secondItem="N2h-FX-kF5" secondAttribute="trailing" constant="6" id="uia-9X-UrW"/>
<constraint firstItem="a4N-1U-1Yt" firstAttribute="leading" secondItem="7vf-kV-eQ5" secondAttribute="trailing" constant="6" id="vgH-Oj-HJc"/>
<constraint firstAttribute="trailing" secondItem="9g2-IH-l8e" secondAttribute="trailing" id="vng-6I-eYj"/>
</constraints>
</view>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="videoMutedIndicator" translatesAutoresizingMaskIntoConstraints="NO" id="FEH-bC-Hnh" userLabel="localVideoMutedIndicator">
<rect key="frame" x="276" y="235" width="36" height="30"/>
<constraints>
<constraint firstAttribute="height" constant="30" id="1iv-w5-GDT"/>
<constraint firstAttribute="width" constant="36" id="AwX-vQ-Ynn"/>
</constraints>
</imageView>
</subviews>
<constraints>
<constraint firstItem="VIH-1T-Ife" firstAttribute="top" secondItem="sK0-tB-H9u" secondAttribute="bottom" constant="42" id="1tT-KH-NEk"/>
<constraint firstAttribute="trailing" secondItem="sK0-tB-H9u" secondAttribute="trailing" id="6K9-n9-ceJ"/>
<constraint firstAttribute="bottom" secondItem="6C5-o5-R1n" secondAttribute="bottom" constant="22" id="76x-6M-xOb"/>
<constraint firstItem="yS9-HT-vp8" firstAttribute="top" secondItem="sK0-tB-H9u" secondAttribute="bottom" constant="24" id="9zS-Fw-oaT"/>
<constraint firstItem="eOT-Jr-GUl" firstAttribute="centerX" secondItem="PoR-7r-yNe" secondAttribute="centerX" id="HMH-Hc-ofZ"/>
<constraint firstItem="FEH-bC-Hnh" firstAttribute="centerY" secondItem="0ZP-s2-kM5" secondAttribute="centerY" id="K8x-bd-bS9"/>
<constraint firstItem="eOT-Jr-GUl" firstAttribute="width" secondItem="PoR-7r-yNe" secondAttribute="width" id="PH6-qw-V6p"/>
<constraint firstItem="eOT-Jr-GUl" firstAttribute="centerY" secondItem="PoR-7r-yNe" secondAttribute="centerY" id="Prz-4m-LHB"/>
<constraint firstItem="0ZP-s2-kM5" firstAttribute="width" secondItem="PoR-7r-yNe" secondAttribute="width" multiplier="0.25" id="QCm-L0-oF7"/>
<constraint firstItem="sK0-tB-H9u" firstAttribute="leading" secondItem="PoR-7r-yNe" secondAttribute="leading" id="TPj-1d-lx6"/>
<constraint firstItem="CL1-2v-m1L" firstAttribute="centerY" secondItem="PoR-7r-yNe" secondAttribute="centerY" id="UGv-46-ri8"/>
<constraint firstAttribute="trailingMargin" secondItem="0ZP-s2-kM5" secondAttribute="trailing" constant="20" id="UZX-Yj-Efk"/>
<constraint firstItem="A0G-cT-yji" firstAttribute="width" secondItem="0ZP-s2-kM5" secondAttribute="width" constant="55.5" id="WMH-vd-rQe"/>
<constraint firstItem="CL1-2v-m1L" firstAttribute="centerX" secondItem="PoR-7r-yNe" secondAttribute="centerX" id="Xt8-k3-fDj"/>
<constraint firstItem="FEH-bC-Hnh" firstAttribute="centerX" secondItem="0ZP-s2-kM5" secondAttribute="centerX" constant="-28.25" id="Yvq-7p-bjS"/>
<constraint firstAttribute="bottom" secondItem="yS9-HT-vp8" secondAttribute="bottom" constant="22" id="bVF-wg-lH8"/>
<constraint firstItem="6C5-o5-R1n" firstAttribute="leading" secondItem="PoR-7r-yNe" secondAttribute="leading" constant="14" id="der-54-SZ4"/>
<constraint firstItem="A0G-cT-yji" firstAttribute="centerX" secondItem="0ZP-s2-kM5" secondAttribute="centerX" constant="-27.75" id="ga5-7D-8CU"/>
<constraint firstItem="A0G-cT-yji" firstAttribute="height" secondItem="0ZP-s2-kM5" secondAttribute="height" id="hMV-RD-NwE"/>
<constraint firstItem="A0G-cT-yji" firstAttribute="centerY" secondItem="0ZP-s2-kM5" secondAttribute="centerY" id="nBC-L0-5Pe"/>
<constraint firstItem="0ZP-s2-kM5" firstAttribute="height" secondItem="PoR-7r-yNe" secondAttribute="height" multiplier="0.25" id="pq3-Iv-N4l"/>
<constraint firstItem="0ZP-s2-kM5" firstAttribute="top" secondItem="BIa-yr-ZMY" secondAttribute="bottom" constant="50" id="qrs-H2-Rw4"/>
<constraint firstItem="eOT-Jr-GUl" firstAttribute="height" secondItem="PoR-7r-yNe" secondAttribute="height" id="rbk-Lc-qip"/>
<constraint firstAttribute="trailing" secondItem="yS9-HT-vp8" secondAttribute="trailing" constant="9" id="vEv-GY-lDH"/>
<constraint firstItem="6C5-o5-R1n" firstAttribute="top" secondItem="sK0-tB-H9u" secondAttribute="bottom" constant="24" id="xhd-lu-lFH"/>
</constraints>
</view>
<navigationItem key="navigationItem" id="s5b-6P-Hwj"/>
<connections>
<outlet property="controlButtons" destination="sK0-tB-H9u" id="mDK-cq-oQz"/>
<outlet property="localVideo" destination="0ZP-s2-kM5" id="C68-k7-h5j"/>
<outlet property="localVideoMutedBg" destination="A0G-cT-yji" id="5Ia-9g-7CT"/>
<outlet property="localVideoMutedIndicator" destination="FEH-bC-Hnh" id="PKd-gQ-Jct"/>
<outlet property="remoteVideo" destination="eOT-Jr-GUl" id="VKE-el-YGR"/>
<outlet property="remoteVideoMutedIndicator" destination="CL1-2v-m1L" id="aJ0-QC-m9Y"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="x33-EE-6Ak" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1685.5072463768117" y="1435.7142857142856"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="GvA-TT-FAo">
<objects>
<navigationController restorationIdentifier="ViewControllerNav" storyboardIdentifier="ViewControllerNav" id="0WJ-RG-MEh" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" id="S7n-df-cyC">
<rect key="frame" x="0.0" y="44" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<connections>
<segue destination="t2c-G5-7AE" kind="relationship" relationship="rootViewController" id="L74-If-nYJ"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="vSx-dK-kQe" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="880" y="1436"/>
</scene>
</scenes>
<resources>
<image name="hangUpButton" width="71" height="71"/>
<image name="localVideoMutedBg" width="90" height="120"/>
<image name="muteButton" width="39" height="39"/>
<image name="muteButtonSelected" width="39" height="39"/>
<image name="speakerOff" width="39" height="39"/>
<image name="speakerOffSelected" width="39" height="39"/>
<image name="switchCameraButton" width="39" height="39"/>
<image name="switchCameraButtonSelected" width="39" height="39"/>
<image name="videoMuteButton" width="39" height="39"/>
<image name="videoMuteButtonSelected" width="39" height="39"/>
<image name="videoMutedIndicator" width="153.5" height="129"/>
</resources>
</document>

@ -45,5 +45,12 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>NSCameraUsageDescription</key>
<string>${PRODUCT_NAME} always camera use</string>
<key>NSMicrophoneUsageDescription</key>
<string>${PRODUCT_NAME} always Microphone use</string>
</dict>
</plist>

@ -4,15 +4,14 @@ import 'package:http/http.dart';
// OWNER : Ibrahim albitar
// DATE : 22-04-2020
// DESCRIPTION : Custom App client to pin base url for all srvices
// DESCRIPTION : Custom App client to pin base url for all srvices
class AppClient {
static Client client = HttpInterceptor().getClient();
static Future<Response> post(dynamic path, {dynamic body}) async {
static Future<Response> post(dynamic path, {dynamic body}) async {
String _fullUrl = BASE_URL + path;
final response = await client.post(_fullUrl, body: body);
return response;
}
}
}

@ -59,10 +59,10 @@ class BaseAppClient {
body['stamp'] = STAMP;
body['IPAdress'] = IP_ADDRESS;
body['VersionID'] = VERSION_ID;
body['Channel'] = CHANNEL;
if (body['Channel'] == null) body['Channel'] = CHANNEL;
body['SessionID'] = SESSION_ID;
body['IsLoginForDoctorApp'] = IS_LOGIN_FOR_DOCTOR_APP;
body['PatientOutSA'] = PATIENT_OUT_SA;
body['PatientOutSA'] = 0; // PATIENT_OUT_SA;
print("URL : $url");
print("Body : ${json.encode(body)}");

@ -2,32 +2,56 @@ const MAX_SMALL_SCREEN = 660;
const ONLY_NUMBERS = "[0-9]";
const ONLY_LETTERS = "[a-zA-Z &'\"]";
const ONLY_DATE = "[0-9/]";
const BASE_URL = 'https://hmgwebservices.com/Services/';
//const BASE_URL = 'https://uat.hmgwebservices.com/Services/';
const PHARMACY_ITEMS_URL = "Lists.svc/REST/GetPharmcyItems_Region";
const PHARMACY_LIST_URL = "Patients.svc/REST/GetPharmcyList";
//const BASE_URL = 'https://hmgwebservices.com/Services/';
const BASE_URL = 'https://uat.hmgwebservices.com/';
const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region";
const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList";
const PATIENT_PROGRESS_NOTE_URL =
"DoctorApplication.svc/REST/GetProgressNoteForInPatient";
"Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient";
const PATIENT_INSURANCE_APPROVALS_URL =
"DoctorApplication.svc/REST/GetApprovalStatusForInpatient";
"Services/DoctorApplication.svc/REST/GetApprovalStatusForInpatient";
const PATIENT_ORDERS_URL =
"DoctorApplication.svc/REST/GetProgressNoteForInPatient";
const PATIENT_REFER_TO_DOCTOR_URL = "DoctorApplication.svc/REST/ReferToDoctor";
"Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient";
const PATIENT_REFER_TO_DOCTOR_URL =
"Services/DoctorApplication.svc/REST/ReferToDoctor";
const PATIENT_GET_DOCTOR_BY_CLINIC_URL =
"DoctorApplication.svc/REST/GetDoctorsByClinicID";
"Services/DoctorApplication.svc/REST/GetDoctorsByClinicID";
const PATIENT_GET_LIST_REFERAL_URL =
"Lists.svc/REST/GetList_STPReferralFrequency";
"Services/Lists.svc/REST/GetList_STPReferralFrequency";
const PATIENT_GET_CLINIC_BY_PROJECT_URL =
"DoctorApplication.svc/REST/GetClinicsByProjectID";
"Services/DoctorApplication.svc/REST/GetClinicsByProjectID";
const GET_PROJECTS = 'Lists.svc/REST/GetProjectForDoctorAPP';
const GET_PATIENT_VITAL_SIGN = 'Doctors.svc/REST/Doctor_GetPatientVitalSign';
const GET_PROJECTS = 'Services/Lists.svc/REST/GetProjectForDoctorAPP';
const GET_PATIENT_VITAL_SIGN =
'Services/Doctors.svc/REST/Doctor_GetPatientVitalSign';
const GET_PATIENT_LAB_OREDERS =
'DoctorApplication.svc/REST/GetPatientLabOreders';
const GET_PRESCRIPTION = 'Patients.svc/REST/GetPrescriptionApptList';
const GET_RADIOLOGY = 'DoctorApplication.svc/REST/GetPatientRadResult';
'Services/DoctorApplication.svc/REST/GetPatientLabOreders';
const GET_PRESCRIPTION = 'Services/Patients.svc/REST/GetPrescriptionApptList';
const GET_RADIOLOGY = 'Services/DoctorApplication.svc/REST/GetPatientRadResult';
const LIVE_CARE_STATISTICS_FOR_CERTAIN_DOCTOR_URL = "Lists.svc/REST/DashBoard_GetLiveCareDoctorsStatsticsForCertainDoctor";
const GET_LIVECARE_PENDINGLIST =
'Services/DoctorApplication.svc/REST/GetPendingPatientER';
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 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_MY_REFERRAL_PATIENT = 'Services/DoctorApplication.svc/REST/GtMyReferralPatient';
const ADD_REFERRED_DOCTOR_REMARKS= 'Services/DoctorApplication.svc/REST/AddReferredDoctorRemarks';
const GET_MY_REFERRED_PATIENT = 'Services/DoctorApplication.svc/REST/GtMyReferredPatient';
const GET_DOCTOR_WORKING_HOURS_TABLE = 'Services/Doctors.svc/REST/GetDoctorWorkingHoursTable';
const GET_PATIENT_LAB_RESULTS= 'Services/DoctorApplication.svc/REST/GetPatientLabResults';
var selectedPatientType = 1;

@ -211,6 +211,7 @@ const Map<String, Map<String, String>> localizedValues = {
'en': 'You don\'t have any Orders',
'ar': 'لا يوجد لديك اي طلبات'
},
'livecare': {'en': 'Live Care', 'ar': 'Live Care'},
'beingBad': {'en': 'being bad', 'ar': 'سيء'},
'beingGreat': {'en': 'being great', 'ar': 'راثع'},
};

@ -1,8 +1,9 @@
final TOKEN = 'token';
final PROJECT_ID='projectID';
final PROJECT_ID = 'projectID';
//===========amjad============
final DOCTOR_ID='doctorID';
final DOCTOR_ID = 'doctorID';
//=======================
final SLECTED_PATIENT_TYPE='slectedPatientType';
final SLECTED_PATIENT_TYPE = 'slectedPatientType';
final APP_Language = 'language';
final DOCTOR_PROFILE = 'doctorProfile';
final DOCTOR_PROFILE = 'doctorProfile';
final LIVE_CARE_PATIENT = 'livecare-patient-profile';

@ -1,3 +1,5 @@
import 'package:doctor_app_flutter/providers/livecare_provider.dart';
import 'package:doctor_app_flutter/providers/medicine_provider.dart';
import 'package:doctor_app_flutter/providers/project_provider.dart';
import 'package:doctor_app_flutter/providers/schedule_provider.dart';
import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
@ -26,11 +28,22 @@ class MyApp extends StatelessWidget {
SizeConfig().init(constraints, orientation);
return MultiProvider(
providers: [
ChangeNotifierProvider<PatientsProvider>(create: (context) => PatientsProvider()),
ChangeNotifierProvider<AuthProvider>(create: (context) => AuthProvider()),
ChangeNotifierProvider<HospitalProvider>(create: (context) => HospitalProvider()),
ChangeNotifierProvider<ProjectProvider>(create: (context) => ProjectProvider(),),
ChangeNotifierProvider<ScheduleProvider>(create: (context) => ScheduleProvider(),)
ChangeNotifierProvider<PatientsProvider>(
create: (context) => PatientsProvider()),
ChangeNotifierProvider<AuthProvider>(
create: (context) => AuthProvider()),
ChangeNotifierProvider<HospitalProvider>(
create: (context) => HospitalProvider()),
ChangeNotifierProvider<ProjectProvider>(
create: (context) => ProjectProvider(),
),
ChangeNotifierProvider<ScheduleProvider>(
create: (context) => ScheduleProvider(),
),
ChangeNotifierProvider<LiveCareProvider>(
create: (context) => LiveCareProvider(),
),
ChangeNotifierProvider<MedicineProvider>(create: (context) => MedicineProvider(),),
],
child: Consumer<ProjectProvider>(
builder: (context,projectProvider,child) => MaterialApp(

@ -0,0 +1,49 @@
class LiveCarePendingListRequest {
PatientData patientData;
int doctorID;
String sErServiceID;
int projectID;
int sourceID;
LiveCarePendingListRequest(
{this.patientData,
this.doctorID,
this.sErServiceID,
this.projectID,
this.sourceID});
LiveCarePendingListRequest.fromJson(Map<String, dynamic> json) {
patientData = new PatientData.fromJson(json['PatientData']);
doctorID = json['DoctorID'];
sErServiceID = json['SErServiceID'];
projectID = json['ProjectID'];
sourceID = json['SourceID'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['PatientData'] = this.patientData.toJson();
data['DoctorID'] = this.doctorID;
data['SErServiceID'] = this.sErServiceID;
data['ProjectID'] = this.projectID;
data['SourceID'] = this.sourceID;
return data;
}
}
class PatientData {
bool isOutKSA;
PatientData({this.isOutKSA});
PatientData.fromJson(Map<String, dynamic> json) {
isOutKSA = json['IsOutKSA'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['IsOutKSA'] = this.isOutKSA;
return data;
}
}

@ -0,0 +1,168 @@
class LiveCarePendingListResponse {
Null acceptedBy;
Null acceptedOn;
int age;
Null appointmentNo;
String arrivalTime;
String arrivalTimeD;
int callStatus;
String clientRequestID;
String clinicName;
Null consoltationEnd;
Null consultationNotes;
Null createdOn;
String dateOfBirth;
String deviceToken;
String deviceType;
Null doctorName;
String editOn;
String gender;
bool isFollowUP;
Null isFromVida;
int isLoginB;
bool isOutKSA;
int isRejected;
String language;
double latitude;
double longitude;
String mobileNumber;
Null openSession;
Null openTokenID;
String patientID;
String patientName;
int patientStatus;
String preferredLanguage;
int projectID;
int scoring;
int serviceID;
Null tokenID;
int vCID;
String voipToken;
LiveCarePendingListResponse(
{this.acceptedBy,
this.acceptedOn,
this.age,
this.appointmentNo,
this.arrivalTime,
this.arrivalTimeD,
this.callStatus,
this.clientRequestID,
this.clinicName,
this.consoltationEnd,
this.consultationNotes,
this.createdOn,
this.dateOfBirth,
this.deviceToken,
this.deviceType,
this.doctorName,
this.editOn,
this.gender,
this.isFollowUP,
this.isFromVida,
this.isLoginB,
this.isOutKSA,
this.isRejected,
this.language,
this.latitude,
this.longitude,
this.mobileNumber,
this.openSession,
this.openTokenID,
this.patientID,
this.patientName,
this.patientStatus,
this.preferredLanguage,
this.projectID,
this.scoring,
this.serviceID,
this.tokenID,
this.vCID,
this.voipToken});
LiveCarePendingListResponse.fromJson(Map<String, dynamic> json) {
acceptedBy = json['AcceptedBy'];
acceptedOn = json['AcceptedOn'];
age = json['Age'];
appointmentNo = json['AppointmentNo'];
arrivalTime = json['ArrivalTime'];
arrivalTimeD = json['ArrivalTimeD'];
callStatus = json['CallStatus'];
clientRequestID = json['ClientRequestID'];
clinicName = json['ClinicName'];
consoltationEnd = json['ConsoltationEnd'];
consultationNotes = json['ConsultationNotes'];
createdOn = json['CreatedOn'];
dateOfBirth = json['DateOfBirth'];
deviceToken = json['DeviceToken'];
deviceType = json['DeviceType'];
doctorName = json['DoctorName'];
editOn = json['EditOn'];
gender = json['Gender'];
isFollowUP = json['IsFollowUP'];
isFromVida = json['IsFromVida'];
isLoginB = json['IsLoginB'];
isOutKSA = json['IsOutKSA'];
isRejected = json['IsRejected'];
language = json['Language'];
latitude = json['Latitude'];
longitude = json['Longitude'];
mobileNumber = json['MobileNumber'];
openSession = json['OpenSession'];
openTokenID = json['OpenTokenID'];
patientID = json['PatientID'];
patientName = json['PatientName'];
patientStatus = json['PatientStatus'];
preferredLanguage = json['PreferredLanguage'];
projectID = json['ProjectID'];
scoring = json['Scoring'];
serviceID = json['ServiceID'];
tokenID = json['TokenID'];
vCID = json['VC_ID'];
voipToken = json['VoipToken'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['AcceptedBy'] = this.acceptedBy;
data['AcceptedOn'] = this.acceptedOn;
data['Age'] = this.age;
data['AppointmentNo'] = this.appointmentNo;
data['ArrivalTime'] = this.arrivalTime;
data['ArrivalTimeD'] = this.arrivalTimeD;
data['CallStatus'] = this.callStatus;
data['ClientRequestID'] = this.clientRequestID;
data['ClinicName'] = this.clinicName;
data['ConsoltationEnd'] = this.consoltationEnd;
data['ConsultationNotes'] = this.consultationNotes;
data['CreatedOn'] = this.createdOn;
data['DateOfBirth'] = this.dateOfBirth;
data['DeviceToken'] = this.deviceToken;
data['DeviceType'] = this.deviceType;
data['DoctorName'] = this.doctorName;
data['EditOn'] = this.editOn;
data['Gender'] = this.gender;
data['IsFollowUP'] = this.isFollowUP;
data['IsFromVida'] = this.isFromVida;
data['IsLoginB'] = this.isLoginB;
data['IsOutKSA'] = this.isOutKSA;
data['IsRejected'] = this.isRejected;
data['Language'] = this.language;
data['Latitude'] = this.latitude;
data['Longitude'] = this.longitude;
data['MobileNumber'] = this.mobileNumber;
data['OpenSession'] = this.openSession;
data['OpenTokenID'] = this.openTokenID;
data['PatientID'] = this.patientID;
data['PatientName'] = this.patientName;
data['PatientStatus'] = this.patientStatus;
data['PreferredLanguage'] = this.preferredLanguage;
data['ProjectID'] = this.projectID;
data['Scoring'] = this.scoring;
data['ServiceID'] = this.serviceID;
data['TokenID'] = this.tokenID;
data['VC_ID'] = this.vCID;
data['VoipToken'] = this.voipToken;
return data;
}
}

@ -0,0 +1,56 @@
class StartCallReq {
int vCID;
bool isrecall;
String tokenID;
String generalid;
int doctorId;
bool isOutKsa;
String projectName;
String docotrName;
String clincName;
String docSpec;
int clinicId;
StartCallReq(
{this.vCID,
this.isrecall,
this.tokenID,
this.generalid,
this.doctorId,
this.isOutKsa,
this.projectName,
this.docotrName,
this.clincName,
this.docSpec,
this.clinicId});
StartCallReq.fromJson(Map<String, dynamic> json) {
vCID = json['VC_ID'];
isrecall = json['isrecall'];
tokenID = json['TokenID'];
generalid = json['generalid'];
doctorId = json['DoctorId'];
isOutKsa = json['IsOutKsa'];
projectName = json['projectName'];
docotrName = json['DocotrName'];
clincName = json['clincName'];
docSpec = json['Doc_Spec'];
clinicId = json['ClinicId'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['VC_ID'] = this.vCID;
data['isrecall'] = this.isrecall;
data['TokenID'] = this.tokenID;
data['generalid'] = this.generalid;
data['DoctorId'] = this.doctorId;
data['IsOutKsa'] = this.isOutKsa;
data['projectName'] = this.projectName;
data['DocotrName'] = this.docotrName;
data['clincName'] = this.clincName;
data['Doc_Spec'] = this.docSpec;
data['ClinicId'] = this.clinicId;
return data;
}
}

@ -6,17 +6,18 @@ import 'package:flutter/cupertino.dart';
import '../models/doctor/user_model.dart';
const LOGIN_URL = 'Sentry.svc/REST/MemberLogIN_New';
const INSERT_DEVICE_IMEI = 'Sentry.svc/REST/DoctorApplication_INSERTDeviceIMEI';
const LOGIN_URL = 'Services/Sentry.svc/REST/MemberLogIN_New';
const INSERT_DEVICE_IMEI =
'Services/Sentry.svc/REST/DoctorApplication_INSERTDeviceIMEI';
const SELECT_DEVICE_IMEI =
'Sentry.svc/REST/DoctorApplication_SELECTDeviceIMEIbyIMEI';
'Services/Sentry.svc/REST/DoctorApplication_SELECTDeviceIMEIbyIMEI';
const SEND_ACTIVATION_CODE_BY_OTP_NOTIFICATION_TYPE =
'Sentry.svc/REST/DoctorApplication_SendActivationCodebyOTPNotificationType';
'Services/Sentry.svc/REST/DoctorApplication_SendActivationCodebyOTPNotificationType';
const MEMBER_CHECK_ACTIVATION_CODE_NEW =
'Sentry.svc/REST/MemberCheckActivationCode_New';
const GET_DOC_PROFILES = 'Doctors.svc/REST/GetDocProfiles';
'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 }
@ -137,7 +138,7 @@ class AuthProvider with ChangeNotifier {
localRes = response;
selectedClinicName =
ClinicModel.fromJson(response['List_DoctorsClinic'][0]).clinicName;
notifyListeners();
notifyListeners();
response['List_DoctorsClinic'].forEach((v) {
doctorsClinicList.add(new ClinicModel.fromJson(v));
});
@ -166,10 +167,10 @@ class AuthProvider with ChangeNotifier {
localRes = response;
//ClinicDescription
selectedClinicName = response['DoctorProfileList'][0]['ClinicDescription'];
notifyListeners();
}, onFailure: (String error, int statusCode) {
throw error;
}, body: docInfo);
notifyListeners();
return Future.value(localRes);
} catch (error) {
print(error);

@ -1,4 +1,5 @@
import 'package:doctor_app_flutter/client/base_app_client.dart';
import 'package:doctor_app_flutter/config/config.dart';
import 'package:doctor_app_flutter/models/doctor/request_doctor_reply.dart';
import 'package:doctor_app_flutter/models/doctor/list_gt_my_patients_question_model.dart';
import 'package:flutter/cupertino.dart';
@ -17,8 +18,7 @@ class DoctorReplyProvider with ChangeNotifier {
getDoctorReply() async {
try {
await BaseAppClient.post(
'DoctorApplication.svc/REST/GtMyPatientsQuestions',
await BaseAppClient.post(GT_MY_PATIENT_QUESTION,
body: _requestDoctorReply.toJson(),
onSuccess: (dynamic response, int statusCode) {
response['List_GtMyPatientsQuestions'].forEach((v) {

@ -0,0 +1,78 @@
import 'dart:convert';
import 'package:doctor_app_flutter/client/base_app_client.dart';
import 'package:doctor_app_flutter/config/config.dart';
import 'package:doctor_app_flutter/models/livecare/get_panding_req_list.dart';
import 'package:doctor_app_flutter/models/livecare/start_call_req.dart';
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:doctor_app_flutter/config/shared_pref_kay.dart';
class LiveCareProvider with ChangeNotifier {
DrAppSharedPreferances sharedPref = new DrAppSharedPreferances();
var liveCarePendingList = [];
var inCallResponse = {};
bool isFinished = true;
bool hasError = false;
String errorMsg = '';
LiveCarePendingListRequest _pendingRequestModel =
LiveCarePendingListRequest();
Future<List> getpendingList() async {
var profile = await sharedPref.getObj(DOCTOR_PROFILE);
_pendingRequestModel.projectID = await sharedPref.getInt(PROJECT_ID);
_pendingRequestModel.doctorID = profile['DoctorID'];
_pendingRequestModel.sErServiceID = "1,3";
_pendingRequestModel.sourceID = 1;
_pendingRequestModel.patientData = PatientData(isOutKSA: false);
resetDefaultValues();
// dynamic localRes;
await BaseAppClient.post(GET_LIVECARE_PENDINGLIST,
onSuccess: (response, statusCode) async {
isFinished = true;
liveCarePendingList = response["List_PendingPatientList"];
}, onFailure: (String error, int statusCode) {
isFinished = true;
throw error;
}, body: _pendingRequestModel.toJson());
return Future.value(liveCarePendingList);
}
Future<Map> startCall(request, bool isReCall) async {
var profile = await sharedPref.getObj(DOCTOR_PROFILE);
resetDefaultValues();
/* the request model is not same hence added manually */
var newRequest = new StartCallReq();
newRequest.clinicId = profile["ClinicID"];
newRequest.vCID = request["VC_ID"];
newRequest.isrecall = isReCall;
newRequest.doctorId = profile["DoctorID"];
newRequest.isOutKsa = request["IsOutKSA"];
newRequest.projectName = profile["ProjectName"];
newRequest.docotrName = profile["DoctorName"];
newRequest.clincName = profile["ClinicDescription"];
newRequest.clincName = profile["ClinicDescription"];
newRequest.docSpec = profile["DoctorTitleForProfile"];
newRequest.generalid = 'Cs2020@2016\$2958';
isFinished = false;
await BaseAppClient.post(START_LIVECARE_CALL,
onSuccess: (response, statusCode) async {
isFinished = true;
inCallResponse = response;
}, onFailure: (String error, int statusCode) {
isFinished = true;
throw error;
}, body: newRequest.toJson());
return Future.value(inCallResponse);
}
resetDefaultValues() {
isFinished = false;
hasError = false;
errorMsg = '';
notifyListeners();
}
}

@ -1,103 +1,72 @@
import 'dart:convert';
import 'package:doctor_app_flutter/client/app_client.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/pharmacies/pharmacies_List_request_model.dart';
import 'package:doctor_app_flutter/models/pharmacies/pharmacies_items_request_model.dart';
import 'package:doctor_app_flutter/util/dr_app_shared_pref.dart';
import 'package:doctor_app_flutter/util/helpers.dart';
import 'package:flutter/cupertino.dart';
class MedicineProvider with ChangeNotifier {
DrAppSharedPreferances sharedPref = new DrAppSharedPreferances();
var pharmacyItemsList = [];
var pharmaciesList = [];
bool isFinished = true;
bool hasError = false;
String errorMsg = '';
PharmaciesItemsRequestModel _itemsRequestModel =PharmaciesItemsRequestModel();
PharmaciesItemsRequestModel _itemsRequestModel =
PharmaciesItemsRequestModel();
PharmaciesListRequestModel _listRequestModel = PharmaciesListRequestModel();
Future<String> getMedicineItem(String itemName) async {
clearPharmacyItemsList(){
pharmacyItemsList.clear();
notifyListeners();
}
getMedicineItem(String itemName) async {
_itemsRequestModel.pHRItemName = itemName;
resetDefaultValues();
pharmacyItemsList.clear();
notifyListeners();
try {
if (await Helpers.checkConnection()) {
_itemsRequestModel.pHRItemName = itemName;
final response = await AppClient.post(PHARMACY_ITEMS_URL,
body: json.encode(_itemsRequestModel.toJson()));
final int statusCode = response.statusCode;
isFinished = true;
if (statusCode < 200 || statusCode >= 400 || json == null) {
isFinished = true;
hasError = true;
errorMsg = 'Error While Fetching data';
} else {
var parsed = json.decode(response.body.toString());
if (parsed['MessageStatus'] == 1) {
pharmacyItemsList = parsed['ListPharmcy_Region'];
await BaseAppClient.post(PHARMACY_ITEMS_URL,
onSuccess: (dynamic response, int statusCode) {
pharmacyItemsList = response['ListPharmcy_Region'];
hasError = false;
isFinished = true;
errorMsg = "Done";
} else {
}, onFailure: (String error, int statusCode) {
isFinished = true;
hasError = true;
errorMsg = parsed['ErrorMessage'] ?? parsed['ErrorEndUserMessage'];
}
}
} else {
isFinished = true;
hasError = true;
errorMsg = 'Please Check The Internet Connection';
}
errorMsg = error;
}, body: _itemsRequestModel.toJson());
notifyListeners();
} catch (error) {
throw error;
}
return errorMsg;
}
Future<String> getPharmaciesList(int itemId) async {
String token = await sharedPref.getString(TOKEN);
getPharmaciesList(int itemId) async {
resetDefaultValues();
try {
if (await Helpers.checkConnection()) {
_listRequestModel.itemID = itemId;
_listRequestModel.tokenID = token;
final response = await AppClient.post(PHARMACY_LIST_URL,
body: json.encode(_listRequestModel.toJson()));
final int statusCode = response.statusCode;
isFinished = true;
if (statusCode < 200 || statusCode >= 400 || json == null) {
isFinished = true;
hasError = true;
errorMsg = 'Error While Fetching data';
} else {
var parsed = json.decode(response.body.toString());
if (parsed['MessageStatus'] == 1) {
pharmaciesList = parsed['PharmList'];
_listRequestModel.itemID = itemId;
isFinished = true;
await BaseAppClient.post(PHARMACY_LIST_URL,
onSuccess: (dynamic response, int statusCode) {
pharmaciesList = response['PharmList'];
hasError = false;
isFinished = true;
errorMsg = "Done";
} else {
}, onFailure: (String error, int statusCode) {
isFinished = true;
hasError = true;
errorMsg = parsed['ErrorMessage'] ?? parsed['ErrorEndUserMessage'];
}
}
} else {
isFinished = true;
hasError = true;
errorMsg = 'Please Check The Internet Connection';
}
errorMsg = error;
}, body: _listRequestModel.toJson());
notifyListeners();
} catch (error) {
throw error;
}
return errorMsg;
}
resetDefaultValues() {

@ -72,7 +72,7 @@ class PatientsProvider with ChangeNotifier {
try {
dynamic localRes;
await BaseAppClient.post('DoctorApplication.svc/REST/' + SERVICES_PATIANT[val],
await BaseAppClient.post(GET_PATIENT + SERVICES_PATIANT[val],
onSuccess: (dynamic response, int statusCode) {
localRes = response;
}, onFailure: (String error, int statusCode) {
@ -235,8 +235,7 @@ class PatientsProvider with ChangeNotifier {
try {
prescriptionReportForInPatientList = [];
notifyListeners();
await BaseAppClient.post(
'DoctorApplication.svc/REST/GetPrescriptionReportForInPatient',
await BaseAppClient.post(GET_PRESCRIPTION_REPORT_FOR_IN_PATIENT,
onSuccess: (dynamic response, int statusCode) {
response['List_PrescriptionReportForInPatient'].forEach((v) {
prescriptionReportForInPatientList
@ -261,7 +260,7 @@ class PatientsProvider with ChangeNotifier {
isError = false;
error = "";
notifyListeners();
await BaseAppClient.post('Patients.svc/REST/GetPrescriptionReport',
await BaseAppClient.post(GET_PRESCRIPTION_REPORT,
onSuccess: (dynamic response, int statusCode) {
response['ListPRM'].forEach((v) {
prescriptionReport.add(PrescriptionReport.fromJson(v));
@ -330,7 +329,7 @@ class PatientsProvider with ChangeNotifier {
requestLabResult.orderNo = labOrdersResModel.orderNo;
requestLabResult.invoiceNo = labOrdersResModel.invoiceNo;
requestLabResult.patientTypeID = labOrdersResModel.patientType;
await BaseAppClient.post('DoctorApplication.svc/REST/GetPatientLabResults',
await BaseAppClient.post(GET_PATIENT_LAB_RESULTS,
onSuccess: (dynamic response, int statusCode) {
isError = false;
isLoading = false;

@ -1,23 +1,29 @@
import 'dart:async';
import 'package:connectivity/connectivity.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/doctor_profile_model.dart';
import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart';
import 'package:doctor_app_flutter/providers/auth_provider.dart';
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 {
DrAppSharedPreferances sharedPref = DrAppSharedPreferances();
Locale _appLocale;
String currentLanguage = 'ar';
bool _isArabic = false;
bool isInternetConnection=true;
bool isInternetConnection = true;
Locale get appLocal => _appLocale;
bool get isArabic => _isArabic;
StreamSubscription subscription;
// AuthProvider authProvider = AuthProvider();
ProjectProvider() {
loadSharedPrefLanguage();
@ -60,6 +66,7 @@ class ProjectProvider with ChangeNotifier {
currentLanguage = 'en';
sharedPref.setString(APP_Language, 'en');
}
getProfile();
notifyListeners();
}
@ -68,4 +75,25 @@ class ProjectProvider with ChangeNotifier {
if (subscription != null) subscription.cancel();
super.dispose();
}
void getProfile()async{
Map profile = await sharedPref.getObj(DOCTOR_PROFILE);
DoctorProfileModel doctorProfile = new DoctorProfileModel.fromJson(profile);
ProfileReqModel docInfo = new ProfileReqModel(
doctorID: doctorProfile.doctorID,
clinicID: doctorProfile.clinicID,
license: true,
projectID: doctorProfile.projectID,
tokenID: '',
languageID: 2);
Provider.of<AuthProvider>(AppGlobal.CONTEX,listen: false)
.getDocProfiles(docInfo.toJson()).then((res) async {
sharedPref.setObj(DOCTOR_PROFILE, res['DoctorProfileList'][0]);
}).catchError((err) {
print(err);
});
}
}

@ -1,4 +1,5 @@
import 'package:doctor_app_flutter/client/base_app_client.dart';
import 'package:doctor_app_flutter/config/config.dart';
import 'package:doctor_app_flutter/models/patient/my_referral/my_referral_patient_model.dart';
import 'package:doctor_app_flutter/models/doctor/request_add_referred_doctor_remarks.dart';
import 'package:doctor_app_flutter/models/patient/request_my_referral_patient_model.dart';
@ -24,8 +25,7 @@ class MyReferralPatientProvider with ChangeNotifier {
getMyReferralPatient() async {
try {
await BaseAppClient.post(
'DoctorApplication.svc/REST/GtMyReferralPatient',
await BaseAppClient.post(GET_MY_REFERRAL_PATIENT,
body: _requestMyReferralPatient.toJson(),
onSuccess: (dynamic response, int statusCode) {
response['List_MyReferralPatient'].forEach((v) {
@ -57,8 +57,7 @@ class MyReferralPatientProvider with ChangeNotifier {
_requestAddReferredDoctorRemarks.referredDoctorRemarks = referredDoctorRemarks;
_requestAddReferredDoctorRemarks.lineItemNo = model.lineItemNo;
_requestAddReferredDoctorRemarks.referringDoctor = model.referringDoctor;
await BaseAppClient.post(
'DoctorApplication.svc/REST/AddReferredDoctorRemarks',
await BaseAppClient.post(ADD_REFERRED_DOCTOR_REMARKS,
body: _requestAddReferredDoctorRemarks.toJson(),
onSuccess: (dynamic body, int statusCode) {
model.referredDoctorRemarks = referredDoctorRemarks;

@ -1,4 +1,5 @@
import 'package:doctor_app_flutter/client/base_app_client.dart';
import 'package:doctor_app_flutter/config/config.dart';
import 'package:doctor_app_flutter/models/patient/my_referral/my_referred_patient_model.dart';
import 'package:doctor_app_flutter/models/patient/request_my_referral_patient_model.dart';
import 'package:doctor_app_flutter/models/doctor/verify_referral_doctor_remarks.dart';
@ -22,8 +23,7 @@ class MyReferredPatientProvider with ChangeNotifier {
getMyReferralPatient() async {
try {
await BaseAppClient.post(
'DoctorApplication.svc/REST/GtMyReferredPatient',
await BaseAppClient.post(GET_MY_REFERRED_PATIENT,
body: _requestMyReferralPatient.toJson(),
onSuccess: (dynamic response, int statusCode) {
response['List_MyReferredPatient'].forEach((v) {
@ -62,8 +62,7 @@ class MyReferredPatientProvider with ChangeNotifier {
_verifyreferraldoctorremarks.patientMobileNumber=model.mobileNumber;
_verifyreferraldoctorremarks.patientIdentificationID=model.patientIdentificationNo;
await BaseAppClient.post(
'DoctorApplication.svc/REST/GtMyReferredPatient',
await BaseAppClient.post(GET_MY_REFERRED_PATIENT,
body: _verifyreferraldoctorremarks.toJson(),
onSuccess: (dynamic body, int statusCode) {

@ -1,4 +1,5 @@
import 'package:doctor_app_flutter/client/base_app_client.dart';
import 'package:doctor_app_flutter/config/config.dart';
import 'package:flutter/cupertino.dart';
import '../models/doctor/list_doctor_working_hours_table_model.dart';
import '../models/doctor/request_schedule.dart';
@ -16,7 +17,7 @@ class ScheduleProvider with ChangeNotifier {
getDoctorSchedule() async {
try {
await BaseAppClient.post('Doctors.svc/REST/GetDoctorWorkingHoursTable',
await BaseAppClient.post(GET_DOCTOR_WORKING_HOURS_TABLE,
body: requestSchedule.toJson(),
onSuccess: (dynamic response, int statusCode) {
response['List_DoctorWorkingHoursTable'].forEach((v) {

@ -1,4 +1,3 @@
import 'package:doctor_app_flutter/config/config.dart';
import 'package:doctor_app_flutter/root_page.dart';
import 'package:doctor_app_flutter/screens/patients/profile/insurance_approvals_screen.dart';
@ -6,8 +5,8 @@ import 'package:doctor_app_flutter/screens/patients/profile/patient_orders_scree
import 'package:doctor_app_flutter/screens/patients/profile/progress_note_screen.dart';
import 'package:doctor_app_flutter/screens/patients/profile/refer_patient_screen.dart';
import 'package:doctor_app_flutter/screens/patients/profile/prescriptions/in_patient_prescription_details_screen.dart';
import 'package:doctor_app_flutter/screens/live_care/video_call.dart';
import './screens/QR_reader_screen.dart';
import './screens/auth/change_password_screen.dart';
@ -38,6 +37,7 @@ import './screens/profile_screen.dart';
import './screens/settings/settings_screen.dart';
import 'landing_page.dart';
import 'screens/doctor/doctor_reply_screen.dart';
import 'screens/live_care/panding_list.dart';
const String INIT_ROUTE = ROOT;
const String ROOT = 'root';
@ -67,11 +67,13 @@ const String RADIOLOGY = 'patients/radiology';
const String PROGRESS_NOTE = 'patients/progress-note';
const String REFER_PATIENT = 'patients/refer-patient';
const String PATIENT_ORDERS = 'patients/patient_orders';
const String PATIENT_INSURANCE_APPROVALS = 'patients/patient_insurance_approvals';
const String PATIENT_INSURANCE_APPROVALS =
'patients/patient_insurance_approvals';
const String VITAL_SIGN_DETAILS = 'patients/vital-sign-details';
const String BODY_MEASUREMENTS = 'patients/body-measurements';
const String IN_PATIENT_PRESCRIPTIONS_DETAILS = 'patients/prescription-details';
const String VIDEO_CALL = 'video-call';
const String LIVECARE_PENDING_LIST = 'livecare-pendinglist';
var routes = {
ROOT: (_) => RootPage(),
HOME: (_) => LandingPage(),
@ -79,7 +81,7 @@ var routes = {
PROFILE: (_) => ProfileScreen(),
MY_SCHEDULE: (_) => MyScheduleScreen(),
PATIENT_SEARCH: (_) => PatientSearchScreen(),
PATIENTS_REFERRED:(_)=>PatientReferredScreen(),
PATIENTS_REFERRED: (_) => PatientReferredScreen(),
PATIENTS: (_) => PatientsScreen(),
QR_READER: (_) => QrReaderScreen(),
BLOOD_BANK: (_) => BloodBankScreen(),
@ -100,10 +102,12 @@ var routes = {
PRESCRIPTIONS: (_) => PrescriptionScreen(),
RADIOLOGY: (_) => RadiologyScreen(),
PROGRESS_NOTE: (_) => ProgressNoteScreen(),
REFER_PATIENT: (_)=> ReferPatientScreen(),
REFER_PATIENT: (_) => ReferPatientScreen(),
PATIENT_ORDERS: (_) => PatientsOrdersScreen(),
PATIENT_INSURANCE_APPROVALS: (_) => InsuranceApprovalsScreen(),
VITAL_SIGN_DETAILS: (_) => VitalSignDetailsScreen(),
BODY_MEASUREMENTS: (_) => VitalSignItemDetailsScreen(),
IN_PATIENT_PRESCRIPTIONS_DETAILS:(_)=> InpatientPrescriptionDetailsScreen()
IN_PATIENT_PRESCRIPTIONS_DETAILS: (_) => InpatientPrescriptionDetailsScreen(),
VIDEO_CALL: (_) => VideoCallPage(),
LIVECARE_PENDING_LIST: (_) => LiveCarePandingListScreen()
};

@ -12,6 +12,7 @@ import 'package:doctor_app_flutter/providers/project_provider.dart';
import 'package:doctor_app_flutter/providers/referral_patient_provider.dart';
import 'package:doctor_app_flutter/providers/referred_patient_provider.dart';
import 'package:doctor_app_flutter/screens/medicine/medicine_search_screen.dart';
import 'package:doctor_app_flutter/util/VideoChannel.dart';
import 'package:doctor_app_flutter/util/dr_app_shared_pref.dart';
import 'package:doctor_app_flutter/util/helpers.dart';
import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
@ -66,7 +67,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
isLoading: isLoading,
body: SingleChildScrollView(
child: SizedBox(
height: MediaQuery.of(context).size.height * 1.09,
height: MediaQuery.of(context).size.height * 1.3,
child: Column(
children: <Widget>[
Row(
@ -77,7 +78,9 @@ class _DashboardScreenState extends State<DashboardScreen> {
Container(
margin: EdgeInsets.only(left: 10, top: 10),
child: AppText(
authProvider.selectedClinicName != null?authProvider.selectedClinicName:'',
authProvider.selectedClinicName != null
? authProvider.selectedClinicName
: '',
fontWeight: FontWeight.bold,
fontSize: SizeConfig.textMultiplier * 2.5,
),
@ -231,15 +234,17 @@ class _DashboardScreenState extends State<DashboardScreen> {
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
flex: 2,
child: new DashboardItemIconText(
DoctorApp.in_patient_white,
"23",
TranslationBase.of(context).outPatients,
showBorder: true,
backgroundColor: Colors.red[900],
iconColor: Colors.white),
),
flex: 2,
child: InkWell(
onTap: () {},
child: new DashboardItemIconText(
DoctorApp.in_patient_white,
"23",
TranslationBase.of(context).outPatients,
showBorder: true,
backgroundColor: Colors.red[900],
iconColor: Colors.white),
)),
Expanded(
flex: 2,
child: new DashboardItemIconText(
@ -432,6 +437,35 @@ class _DashboardScreenState extends State<DashboardScreen> {
),
],
)),
Expanded(
flex: 2,
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
flex: 1,
child: InkWell(
onTap: () {
// Navigator.of(context).pushNamed(VIDEO_CALL);
Navigator.of(context)
.pushNamed(LIVECARE_PENDING_LIST);
},
child: DashboardItemIconText(
DoctorApp.referral,
"",
TranslationBase.of(context).livecare,
showBorder: true,
backgroundColor: Colors.white,
valueFontColor: Colors.black,
titleFontColor: Colors.black,
iconColor: Colors.black,
titleFontSize: SizeConfig.textMultiplier * 2,
),
),
),
Expanded(flex: 1, child: Container())
],
))
],
),
),

@ -0,0 +1,305 @@
import 'package:doctor_app_flutter/config/size_config.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';
import 'package:doctor_app_flutter/util/helpers.dart';
import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart';
import 'package:doctor_app_flutter/widgets/shared/dr_app_circular_progress_Indeicator.dart';
import 'package:doctor_app_flutter/widgets/shared/rounded_container_widget.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
import 'package:doctor_app_flutter/models/livecare/get_pending_res_list.dart';
import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart';
import 'package:doctor_app_flutter/widgets/shared/card_with_bgNew_widget.dart';
import '../../config/size_config.dart';
import '../../config/size_config.dart';
import '../../widgets/shared/app_scaffold_widget.dart';
import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart';
import '../../routes.dart';
import 'package:doctor_app_flutter/config/shared_pref_kay.dart';
DrAppSharedPreferances sharedPref = DrAppSharedPreferances();
class LiveCarePandingListScreen extends StatefulWidget {
// In the constructor, require a item id.
LiveCarePandingListScreen({Key key}) : super(key: key);
@override
_LiveCarePandingListState createState() => _LiveCarePandingListState();
}
class _LiveCarePandingListState extends State<LiveCarePandingListScreen> {
var _data = [];
Helpers helpers = new Helpers();
LiveCareProvider _liveCareProvider;
@override
void didChangeDependencies() {
super.didChangeDependencies();
_liveCareProvider = Provider.of<LiveCareProvider>(context);
if (_data.isEmpty) pendingList();
}
@override
Widget build(BuildContext context) {
return AppScaffold(
appBarTitle: TranslationBase.of(context).livecare,
body: Container(
child: ListView(scrollDirection: Axis.vertical,
// physics: const AlwaysScrollableScrollPhysics(),
children: <Widget>[
RoundedContainer(
child: !_liveCareProvider.isFinished
? Container(
height: SizeConfig.screenHeight,
width: SizeConfig.screenWidth,
child: DrAppCircularProgressIndeicator())
: _liveCareProvider.hasError
? Center(
child: Text(
_liveCareProvider.errorMsg,
style: TextStyle(
color: Theme.of(context).errorColor),
),
)
: Column(
children: _data.map<Widget>((item) {
return Container(
decoration: myBoxDecoration(),
child: InkWell(
child: CardWithBgWidgetNew(
//CardWithBgWidget(
widget: Column(
children: <Widget>[
Container(
// decoration: myBoxDecoration(),
child: Row(
children: <Widget>[
Column(
children: <Widget>[
Container(
decoration:
BoxDecoration(
gradient:
LinearGradient(
begin:
Alignment(
-1,
-1),
end:
Alignment(
1,
1),
colors: [
Colors.grey[
100],
Colors.grey[
200],
]),
boxShadow: [
BoxShadow(
color: Color
.fromRGBO(
0,
0,
0,
0.08),
offset:
Offset(
0.0,
5.0),
blurRadius:
16.0)
],
borderRadius:
BorderRadius.all(
Radius.circular(
50.0)),
),
width: 80,
height: 80,
child: Icon(
item["Gender"] ==
"1"
? DoctorApp.male
: DoctorApp
.femaleicon,
size: 80,
)),
],
),
SizedBox(
width: 20,
),
Column(
crossAxisAlignment:
CrossAxisAlignment
.start,
children: <Widget>[
AppText(
item["PatientName"],
fontSize: 2.0 *
SizeConfig
.textMultiplier,
fontWeight:
FontWeight.bold,
backGroundcolor:
Colors.white,
),
SizedBox(
height: 8,
),
AppText(
TranslationBase.of(
context)
.fileNo +
item["PatientID"]
.toString(),
fontSize: 2.0 *
SizeConfig
.textMultiplier,
fontWeight:
FontWeight.bold,
backGroundcolor:
Colors.white,
),
// SizedBox(
// height: 8,
// ),
AppText(
TranslationBase.of(
context)
.age +
' ' +
item["Age"]
.toString(),
fontSize: 2.0 *
SizeConfig
.textMultiplier,
fontWeight:
FontWeight.bold,
backGroundcolor:
Colors.white,
),
SizedBox(
height: 8,
),
],
),
SizedBox(
width: 80,
),
// Divider(color: Colors.grey
Expanded(
flex: 3,
child: IconButton(
icon: Icon(
Icons.video_call,
size: 40,
),
color: Colors
.green, //Colors.black,
onPressed: () => {
sharedPref.setObj(
LIVE_CARE_PATIENT,
item),
Navigator.of(context)
.pushNamed(
VIDEO_CALL)
},
),
)
],
),
),
// Divider(color: Colors.grey)
],
),
),
onTap: () {
sharedPref.setObj(
LIVE_CARE_PATIENT,
item);
Navigator.of(context)
.pushNamed(
VIDEO_CALL);
},
),
);
}).toList(),
))
]),
));
}
Future<bool> pendingList() async {
_liveCareProvider.getpendingList().then((result) {
this.setState(() {
_data = _liveCareProvider.liveCarePendingList;
// _data = [
// {
// "AcceptedBy": null,
// "AcceptedOn": null,
// "Age": 33,
// "AppointmentNo": null,
// "ArrivalTime": "2020-06-14 09:34",
// "ArrivalTimeD": "/Date(1592116471237+0300)/",
// "CallStatus": 1,
// "ClientRequestID": "2344670985-1231755-1584378710",
// "ClinicName": "ER Clinic",
// "ConsoltationEnd": null,
// "ConsultationNotes": null,
// "CreatedOn": null,
// "DateOfBirth": "1987-01-04",
// "DeviceToken":
// "fbxt2XpseU_DpO8Msqa1V6:APA91bHUxsfKpAewTt0DzGg_mSTN0T7KIQM92VpubUTobgTm0-DGcJMgcc3DmERbEiWbyTup3zGttU3_9RBaRBxZUKj9ju5wnTGSrIelEE-qxOK30YnIaDhbhs8fJixACbyzgr72HU8Y",
// "DeviceType": "iOS",
// "DoctorName": null,
// "EditOn": "/Date(1592116471237+0300)/",
// "Gender": "1",
// "IsFollowUP": false,
// "IsFromVida": null,
// "IsLoginB": 0,
// "IsOutKSA": false,
// "IsRejected": 0,
// "Language": "AR",
// "Latitude": 24.708879,
// "Longitude": 46.665827,
// "MobileNumber": "0537503378",
// "OpenSession": null,
// "OpenTokenID": null,
// "PatientID": "1231755",
// "PatientName": "TAMER FANASHEH",
// "PatientStatus": 1,
// "PreferredLanguage": "Ar",
// "ProjectID": 0,
// "Scoring": 0.00,
// "ServiceID": 1,
// "TokenID": null,
// "VC_ID": 2240,
// "VoipToken":
// "8dcc17e2365d4f3c4afadc6b5d625a88407398ee517f0e9beda7f663007e88b9"
// }
// ];
});
});
return true;
}
myBoxDecoration() {
return BoxDecoration(
border: Border(
bottom: BorderSide(
// <--- top side
color: Colors.grey,
width: 1.0,
),
),
);
}
}

@ -0,0 +1,254 @@
import 'dart:async';
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';
import 'package:flutter/material.dart';
import 'package:doctor_app_flutter/config/shared_pref_kay.dart';
import 'package:provider/provider.dart';
import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart';
import 'package:doctor_app_flutter/util/helpers.dart';
class VideoCallPage extends StatefulWidget {
@override
_VideoCallPageState createState() => _VideoCallPageState();
}
DrAppSharedPreferances sharedPref = DrAppSharedPreferances();
class _VideoCallPageState extends State<VideoCallPage> {
Timer _timmerInstance;
int _start = 0;
String _timmer = '';
LiveCareProvider _liveCareProvider;
bool _isInit = true;
var _tokenData;
var patientData = {};
String image_url = 'https://hmgwebservices.com/Images/MobileImages/DUBAI/';
//bool _isOutOfStuck = false;
Helpers helpers = new Helpers();
@override
void didChangeDependencies() {
super.didChangeDependencies();
if (_isInit) {
_liveCareProvider = Provider.of<LiveCareProvider>(context);
startCall();
}
_isInit = false;
}
void connectOpenTok(tokenData) {
_tokenData = tokenData;
/* opentok functionalites need to be written */
VideoChannel.openVideoCallScreen(kApiKey: '46209962',
kSessionId: _tokenData["OpenSessionID"],
kToken: _tokenData["OpenTokenID"],
);
}
String getTimerTime(int start) {
int minutes = (start ~/ 60);
String sMinute = '';
if (minutes.toString().length == 1) {
sMinute = '0' + minutes.toString();
} else
sMinute = minutes.toString();
int seconds = (start % 60);
String sSeconds = '';
if (seconds.toString().length == 1) {
sSeconds = '0' + seconds.toString();
} else
sSeconds = seconds.toString();
return sMinute + ':' + sSeconds;
}
startCall() async {
patientData = await sharedPref.getObj(LIVE_CARE_PATIENT);
_liveCareProvider.startCall(patientData, false).then((result) {
connectOpenTok(result);
}).catchError((error) =>
{helpers.showErrorToast(error), Navigator.of(context).pop()});
}
// @override
// void initState() {
// super.initState();
// }
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
height: MediaQuery.of(context).size.height * 1.09,
// width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: Colors.white,
),
padding: EdgeInsets.all(50.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 10.0,
),
Text(
'Calling',
style: TextStyle(
color: Colors.deepPurpleAccent,
fontWeight: FontWeight.w300,
fontSize: 15),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.02,
),
Text(
patientData["PatientName"],
style: TextStyle(
color: Colors.deepPurpleAccent,
fontWeight: FontWeight.w900,
fontSize: 20),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.02,
),
Container(
child: Text(
_timmer == '' ? 'Connecting' : 'Connected',
style: TextStyle(
color: Colors.deepPurpleAccent,
fontWeight: FontWeight.w300,
fontSize: 15),
)),
SizedBox(
height: MediaQuery.of(context).size.height * 0.02,
),
ClipRRect(
borderRadius: BorderRadius.circular(200.0),
child: Image.network(
patientData["Gender"] == "1"
? image_url + 'unkown.png'
: image_url + 'unkowwn_female.png',
height: 200.0,
width: 200.0,
),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.02,
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
FunctionalButton(
title: 'Speaker',
icon: Icons.phone_in_talk,
onPressed: () {
print(_tokenData["OpenSessionID"]);
print(_tokenData["OpenTokenID"]);
VideoChannel.openVideoCallScreen(kApiKey: '46209962',
kSessionId: _tokenData["OpenSessionID"],
kToken: _tokenData["OpenTokenID"],
);
},
),
FunctionalButton(
title: 'Flip',
icon: Icons.flip_to_back,
onPressed: () {},
),
FunctionalButton(
title: 'Mute',
icon: Icons.mic_off,
onPressed: () {},
),
],
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.1,
),
FloatingActionButton(
onPressed: () {
Navigator.of(context).pop();
},
elevation: 20.0,
shape: CircleBorder(side: BorderSide(color: Colors.red)),
mini: false,
child: Icon(
Icons.call_end,
color: Colors.red,
),
backgroundColor: Colors.red[100],
)
],
),
),
),
);
}
}
class FunctionalButton extends StatefulWidget {
final title;
final icon;
final Function() onPressed;
const FunctionalButton({Key key, this.title, this.icon, this.onPressed})
: super(key: key);
@override
_FunctionalButtonState createState() => _FunctionalButtonState();
}
class _FunctionalButtonState extends State<FunctionalButton> {
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
RawMaterialButton(
onPressed: widget.onPressed,
splashColor: Colors.deepPurpleAccent,
fillColor: Colors.white,
elevation: 10.0,
shape: CircleBorder(),
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Icon(
widget.icon,
size: 30.0,
color: Colors.deepPurpleAccent,
),
),
),
Container(
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0),
child: Text(
widget.title,
style: TextStyle(fontSize: 15.0, color: Colors.deepPurpleAccent),
),
)
],
);
}
}

@ -92,7 +92,7 @@ class _MedicineSearchState extends State<MedicineSearchScreen> {
children: <Widget>[
AppText(
TranslationBase.of(context).youCanFind +
(data == null ? "0" : data.length.toString()) +
(_medicineProvider.pharmacyItemsList == null ? "0" : _medicineProvider.pharmacyItemsList.length.toString()) +
TranslationBase.of(context).itemsInSearch,
fontWeight: FontWeight.bold,
margin: 5,
@ -116,25 +116,22 @@ class _MedicineSearchState extends State<MedicineSearchScreen> {
: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: data == null ? 0 : data.length,
itemCount: _medicineProvider.pharmacyItemsList == null ? 0 : _medicineProvider.pharmacyItemsList.length,
itemBuilder: (BuildContext context, int index) {
return InkWell(
child: MedicineItemWidget(
label: data[index]["ItemDescription"],
url: data[index]["ProductImageBase64"],
label: _medicineProvider.pharmacyItemsList[index]["ItemDescription"],
url: _medicineProvider.pharmacyItemsList[index]["ProductImageBase64"],
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ChangeNotifierProvider(
create: (_) => MedicineProvider(),
child: PharmaciesListScreen(
itemID: data[index]["ItemID"],
url: data[index]
["ProductImageBase64"]),
),
PharmaciesListScreen(
itemID: _medicineProvider.pharmacyItemsList[index]["ItemID"],
url: _medicineProvider.pharmacyItemsList[index]
["ProductImageBase64"]),
),
);
},
@ -150,16 +147,10 @@ class _MedicineSearchState extends State<MedicineSearchScreen> {
searchMedicine(context) {
FocusScope.of(context).unfocus();
if (myController.text.isNullOrEmpty()) {
this.setState(() {
data = null;
});
_medicineProvider.clearPharmacyItemsList();
helpers.showErrorToast("Type Medicine Name");
return;
}
_medicineProvider.getMedicineItem(myController.text).then((str) {
this.setState(() {
data = _medicineProvider.pharmacyItemsList;
});
});
_medicineProvider.getMedicineItem(myController.text);
}
}

@ -55,7 +55,17 @@ class _PharmaciesListState extends State<PharmaciesListScreen> {
projectsProvider = Provider.of(context);
return AppScaffold(
appBarTitle: TranslationBase.of(context).pharmaciesList,
body: Container(
body: !_medicineProvider.isFinished
? DrAppCircularProgressIndeicator()
: _medicineProvider.hasError
? Center(
child: Text(
_medicineProvider.errorMsg,
style: TextStyle(
color: Theme.of(context).errorColor),
),
)
:Container(
height: SizeConfig.screenHeight,
child: ListView(
shrinkWrap: true,
@ -63,84 +73,70 @@ class _PharmaciesListState extends State<PharmaciesListScreen> {
physics: const AlwaysScrollableScrollPhysics(),
children: <Widget>[
RoundedContainer(
child: !_medicineProvider.isFinished
? DrAppCircularProgressIndeicator()
: _medicineProvider.hasError
? Center(
child: Text(
_medicineProvider.errorMsg,
style: TextStyle(
color: Theme.of(context).errorColor),
),
)
: StreamBuilder<Object>(
stream: null,
builder: (context, snapshot) {
return Row(
children: <Widget>[
Expanded(
flex: 1,
child: ClipRRect(
borderRadius: BorderRadius.all(
Radius.circular(7)),
child: Image.memory(
dataFromBase64String(widget.url),
height:
SizeConfig.imageSizeMultiplier *
21,
width:
SizeConfig.imageSizeMultiplier *
20,
fit: BoxFit.cover,
),
),
),
Expanded(
flex: 3,
child: Column(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.stretch,
children: <Widget>[
AppText(
TranslationBase.of(context)
.description,
marginLeft: 10,
marginTop: 0,
marginRight: 10,
marginBottom: 2,
fontWeight: FontWeight.bold,
),
AppText(
_data[0]["ItemDescription"],
marginLeft: 10,
marginTop: 0,
marginRight: 10,
marginBottom: 10,
),
AppText(
TranslationBase.of(context).price,
marginLeft: 10,
marginTop: 0,
marginRight: 10,
marginBottom: 2,
fontWeight: FontWeight.bold,
),
AppText(
_data[0]["SellingPrice"]
.toString(),
marginLeft: 10,
marginTop: 0,
marginRight: 10,
marginBottom: 10,
),
],
),
)
],
);
})),
child: Row(
children: <Widget>[
Expanded(
flex: 1,
child: ClipRRect(
borderRadius: BorderRadius.all(
Radius.circular(7)),
child: Image.memory(
dataFromBase64String(widget.url),
height:
SizeConfig.imageSizeMultiplier *
21,
width:
SizeConfig.imageSizeMultiplier *
20,
fit: BoxFit.cover,
),
),
),
Expanded(
flex: 3,
child: Column(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.stretch,
children: <Widget>[
AppText(
TranslationBase.of(context)
.description,
marginLeft: 10,
marginTop: 0,
marginRight: 10,
marginBottom: 2,
fontWeight: FontWeight.bold,
),
AppText(
_medicineProvider.pharmaciesList[0]["ItemDescription"],
marginLeft: 10,
marginTop: 0,
marginRight: 10,
marginBottom: 10,
),
AppText(
TranslationBase.of(context).price,
marginLeft: 10,
marginTop: 0,
marginRight: 10,
marginBottom: 2,
fontWeight: FontWeight.bold,
),
AppText(
_medicineProvider.pharmaciesList[0]["SellingPrice"]
.toString(),
marginLeft: 10,
marginTop: 0,
marginRight: 10,
marginBottom: 10,
),
],
),
)
],
)),
Container(
margin: EdgeInsets.only(
top: SizeConfig.widthMultiplier * 2,
@ -165,7 +161,7 @@ class _PharmaciesListState extends State<PharmaciesListScreen> {
child: ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: _data == null ? 0 : _data.length,
itemCount: _medicineProvider.pharmaciesList == null ? 0 : _medicineProvider.pharmaciesList.length,
itemBuilder: (BuildContext context, int index) {
return RoundedContainer(
child: Row(
@ -176,7 +172,7 @@ class _PharmaciesListState extends State<PharmaciesListScreen> {
borderRadius:
BorderRadius.all(Radius.circular(7)),
child: Image.network(
_data[index]["ProjectImageURL"],
_medicineProvider.pharmaciesList[index]["ProjectImageURL"],
height:
SizeConfig.imageSizeMultiplier * 15,
width:
@ -188,7 +184,7 @@ class _PharmaciesListState extends State<PharmaciesListScreen> {
Expanded(
flex: 4,
child: AppText(
_data[index]["LocationDescription"],
_medicineProvider.pharmaciesList[index]["LocationDescription"],
margin: 10,
),
),
@ -207,7 +203,7 @@ class _PharmaciesListState extends State<PharmaciesListScreen> {
color: Colors.red,
),
onTap: () => launch("tel://" +
_data[index]["PhoneNumber"]),
_medicineProvider.pharmaciesList[index]["PhoneNumber"]),
),
),
Padding(
@ -220,10 +216,10 @@ class _PharmaciesListState extends State<PharmaciesListScreen> {
onTap: () {
MapsLauncher.launchCoordinates(
double.parse(
_data[index]["Latitude"]),
_medicineProvider.pharmaciesList[index]["Latitude"]),
double.parse(
_data[index]["Longitude"]),
_data[index]
_medicineProvider.pharmaciesList[index]["Longitude"]),
_medicineProvider.pharmaciesList[index]
["LocationDescription"]);
},
),
@ -241,19 +237,15 @@ class _PharmaciesListState extends State<PharmaciesListScreen> {
));
}
Future<bool> pharmaciesList() async {
_medicineProvider.getPharmaciesList(widget.itemID).then((result) {
this.setState(() {
_data = _medicineProvider.pharmaciesList;
});
});
return true;
pharmaciesList() async {
_medicineProvider.getPharmaciesList(widget.itemID);
}
Image imageFromBase64String(String base64String) {
return Image.memory(base64Decode(base64String));
}
//TODO CHECK THE URL IS NULL OR NOT
Uint8List dataFromBase64String(String base64String) {
return base64Decode(base64String);
}

@ -0,0 +1,29 @@
import 'package:flutter/services.dart';
class VideoChannel{
/// channel name
static const _channel = const MethodChannel("Dr.cloudSolution/videoCall");
static Future<dynamic> openVideoCallScreen(
{kApiKey, kSessionId, kToken, callDuration, warningDuration}) {
var result;
try {
result = _channel.invokeMethod(
'openVideoCall',
{
"kApiKey": kApiKey,
"kSessionId": kSessionId,
"kToken": kToken,
/* "callDuration": callDuration,
"warningDuration": warningDuration,*/
"appLang": "en",
},
);
} on PlatformException catch (e) {
result = e.toString();
}
return result;
}
}

@ -1,3 +1,4 @@
import 'package:doctor_app_flutter/config/shared_pref_kay.dart';
import 'package:doctor_app_flutter/models/doctor/list_doctor_working_hours_table_model.dart';
import 'package:doctor_app_flutter/routes.dart';
import 'package:doctor_app_flutter/util/dr_app_shared_pref.dart';
@ -9,6 +10,7 @@ import '../config/size_config.dart';
import '../util/dr_app_toast_msg.dart';
import 'package:connectivity/connectivity.dart';
import 'dr_app_shared_pref.dart';
DrAppSharedPreferances sharedPref = new DrAppSharedPreferances();
@ -22,6 +24,8 @@ DrAppSharedPreferances sharedPref = new DrAppSharedPreferances();
class Helpers {
int cupertinoPickerIndex = 0;
get currentLanguage => null;
/*
*@author: Elham Rababah
*@Date:12/4/2020
@ -340,7 +344,9 @@ class Helpers {
}
logout() async {
String lang = await sharedPref.getString(APP_Language);
await clearSharedPref();
sharedPref.setString(APP_Language, lang);
Navigator.of(AppGlobal.CONTEX).pushReplacementNamed(LOGIN);
}
}

@ -230,6 +230,7 @@ class TranslationBase {
localizedValues['prescriptionInfo'][locale.languageCode];
String get errorNoOrders =>
localizedValues['errorNoOrders'][locale.languageCode];
String get livecare => localizedValues['livecare'][locale.languageCode];
String get beingBad => localizedValues['beingBad'][locale.languageCode];
String get beingGreat => localizedValues['beingGreat'][locale.languageCode];
}

@ -29,6 +29,7 @@ class AppDrawer extends StatefulWidget {
class _AppDrawerState extends State<AppDrawer> {
bool _isInit = true;
DoctorProfileModel doctorProfile;
Helpers helpers = new Helpers();
@override
void didChangeDependencies() {
super.didChangeDependencies();
@ -105,9 +106,8 @@ class _AppDrawerState extends State<AppDrawer> {
color: Colors.white,
),
onPressed: () async {
await Helpers.clearSharedPref();
Navigator.pop(context);
Navigator.of(context).pushNamed(LOGIN);
await helpers.logout();
},
),
],

@ -127,6 +127,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "7.1.0"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
charcode:
dependency: transitive
description:
@ -155,6 +162,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
code_builder:
dependency: transitive
description:
@ -246,6 +260,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "4.1.4"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
fixnum:
dependency: transitive
description:
@ -350,13 +371,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.4"
image:
dependency: transitive
description:
name: image
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.12"
imei_plugin:
dependency: "direct main"
description:
@ -468,7 +482,7 @@ packages:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.4"
version: "1.7.0"
pedantic:
dependency: transitive
description:
@ -497,13 +511,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
petitparser:
dependency: transitive
description:
name: petitparser
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.0"
platform:
dependency: transitive
description:
@ -676,7 +683,7 @@ packages:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.15"
version: "0.2.16"
timing:
dependency: transitive
description:
@ -740,13 +747,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
xml:
dependency: transitive
description:
name: xml
url: "https://pub.dartlang.org"
source: hosted
version: "3.6.1"
yaml:
dependency: transitive
description:
@ -755,5 +755,5 @@ packages:
source: hosted
version: "2.2.1"
sdks:
dart: ">=2.7.0 <3.0.0"
dart: ">=2.9.0-14.0.dev <3.0.0"
flutter: ">=1.12.13+hotfix.5 <2.0.0"

Loading…
Cancel
Save