merge-requests/143/head
Sultan Khan 4 years ago
commit b66eebfd10

@ -61,7 +61,15 @@ flutter {
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 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' testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1' androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.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" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.doctor_app_flutter"> 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. calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide 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 additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. --> FlutterApplication and put your custom class here.
<uses-permission android:name="android.permission.INTERNET"/> -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" />
<application <application
android:name="io.flutter.app.FlutterApplication" 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 <activity
android:name=".MainActivity" android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </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 <meta-data
android:name="flutterEmbedding" android:name="flutterEmbedding"
android:value="2" /> android:value="2" />
</application> </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 package com.example.doctor_app_flutter
import android.content.Intent
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant import io.flutter.plugins.GeneratedPluginRegistrant
import io.flutter.embedding.android.FlutterFragmentActivity import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.plugin.common.MethodChannel
class MainActivity: FlutterFragmentActivity() { 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 --> Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item> <item name="android:windowBackground">@drawable/launch_background</item>
</style> </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> </resources>

@ -15,6 +15,7 @@ allprojects {
repositories { repositories {
google() google()
jcenter() 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. # Keep pod path relative so it can be checked into Podfile.lock.
pod 'Flutter', :path => 'Flutter' pod 'Flutter', :path => 'Flutter'
pod 'OpenTok'
# Plugin Pods # Plugin Pods

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

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

@ -1,5 +1,9 @@
import UIKit import UIKit
import Flutter import Flutter
import OpenTok
// Created by Mohammad Aljammal & Elham Rababah on 24/06/20.
// Copyright © 2020 Cloud. All rights reserved.
@UIApplicationMain @UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate { @objc class AppDelegate: FlutterAppDelegate {
@ -7,7 +11,47 @@ import Flutter
_ application: UIApplication, _ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool { ) -> 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) GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions) 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"?> <?xml version="1.0" encoding="UTF-8"?>
<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"> <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> <dependencies>
<deployment identifier="iOS"/> <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> </dependencies>
<scenes> <scenes>
<!--Flutter View Controller--> <!--Flutter View Controller-->
@ -14,13 +16,281 @@
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/> <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides> </layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC"> <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"/> <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> </view>
</viewController> </viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects> </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> </scene>
</scenes> </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> </document>

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

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

@ -35,6 +35,24 @@ const START_LIVECARE_CALL = 'LiveCareApi/DoctorApp/CallPatient';
const LIVE_CARE_STATISTICS_FOR_CERTAIN_DOCTOR_URL = const LIVE_CARE_STATISTICS_FOR_CERTAIN_DOCTOR_URL =
"Lists.svc/REST/DashBoard_GetLiveCareDoctorsStatsticsForCertainDoctor"; "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; var selectedPatientType = 1;
//*********change value to decode json from Dropdown ************ //*********change value to decode json from Dropdown ************

@ -1,4 +1,5 @@
import 'package:doctor_app_flutter/providers/livecare_provider.dart'; 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/project_provider.dart';
import 'package:doctor_app_flutter/providers/schedule_provider.dart'; import 'package:doctor_app_flutter/providers/schedule_provider.dart';
import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
@ -41,33 +42,36 @@ class MyApp extends StatelessWidget {
), ),
ChangeNotifierProvider<LiveCareProvider>( ChangeNotifierProvider<LiveCareProvider>(
create: (context) => LiveCareProvider(), create: (context) => LiveCareProvider(),
) ),
ChangeNotifierProvider<MedicineProvider>(create: (context) => MedicineProvider(),),
], ],
child: Consumer<ProjectProvider>( child: Consumer<ProjectProvider>(
builder: (context, projectProvider, child) => MaterialApp( builder: (context,projectProvider,child) => MaterialApp(
showSemanticsDebugger: false, showSemanticsDebugger: false,
title: 'Flutter Demo', title: 'Flutter Demo',
locale: projectProvider.appLocal, locale: projectProvider.appLocal,
localizationsDelegates: [ localizationsDelegates: [
TranslationBaseDelegate(), TranslationBaseDelegate(),
GlobalMaterialLocalizations.delegate, GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate, GlobalWidgetsLocalizations.delegate,
], ],
supportedLocales: [ supportedLocales: [
const Locale('ar', ''), // Arabic const Locale('ar', ''), // Arabic
const Locale('en', ''), // English const Locale('en', ''), // English
], ],
theme: ThemeData( theme: ThemeData(
primarySwatch: Colors.grey, primarySwatch: Colors.grey,
primaryColor: Colors.grey, primaryColor: Colors.grey,
buttonColor: Hexcolor('#B8382C'), buttonColor: Hexcolor('#B8382C'),
fontFamily: 'WorkSans', fontFamily: 'WorkSans',
dividerColor: Colors.grey[350], dividerColor: Colors.grey[350],
backgroundColor: Color.fromRGBO(255, 255, 255, 1)), backgroundColor: Color.fromRGBO(255,255,255, 1)
initialRoute: INIT_ROUTE, ),
routes: routes, initialRoute: INIT_ROUTE,
debugShowCheckedModeBanner: false, routes: routes,
)), debugShowCheckedModeBanner: false,
)
),
); );
}); });
}, },

@ -166,12 +166,11 @@ class AuthProvider with ChangeNotifier {
onSuccess: (dynamic response, int statusCode) { onSuccess: (dynamic response, int statusCode) {
localRes = response; localRes = response;
//ClinicDescription //ClinicDescription
selectedClinicName = selectedClinicName = response['DoctorProfileList'][0]['ClinicDescription'];
response['DoctorProfileList'][0]['ClinicDescription'];
notifyListeners();
}, onFailure: (String error, int statusCode) { }, onFailure: (String error, int statusCode) {
throw error; throw error;
}, body: docInfo); }, body: docInfo);
notifyListeners();
return Future.value(localRes); return Future.value(localRes);
} catch (error) { } catch (error) {
print(error); print(error);

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

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

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

@ -1,9 +1,16 @@
import 'dart:async'; import 'dart:async';
import 'package:connectivity/connectivity.dart'; 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/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/dr_app_shared_pref.dart';
import 'package:doctor_app_flutter/util/helpers.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';
Helpers helpers = Helpers();
class ProjectProvider with ChangeNotifier { class ProjectProvider with ChangeNotifier {
DrAppSharedPreferances sharedPref = DrAppSharedPreferances(); DrAppSharedPreferances sharedPref = DrAppSharedPreferances();
@ -16,7 +23,7 @@ class ProjectProvider with ChangeNotifier {
bool get isArabic => _isArabic; bool get isArabic => _isArabic;
StreamSubscription subscription; StreamSubscription subscription;
// AuthProvider authProvider = AuthProvider();
ProjectProvider() { ProjectProvider() {
loadSharedPrefLanguage(); loadSharedPrefLanguage();
@ -59,6 +66,7 @@ class ProjectProvider with ChangeNotifier {
currentLanguage = 'en'; currentLanguage = 'en';
sharedPref.setString(APP_Language, 'en'); sharedPref.setString(APP_Language, 'en');
} }
getProfile();
notifyListeners(); notifyListeners();
} }
@ -67,4 +75,25 @@ class ProjectProvider with ChangeNotifier {
if (subscription != null) subscription.cancel(); if (subscription != null) subscription.cancel();
super.dispose(); 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/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/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/doctor/request_add_referred_doctor_remarks.dart';
import 'package:doctor_app_flutter/models/patient/request_my_referral_patient_model.dart'; import 'package:doctor_app_flutter/models/patient/request_my_referral_patient_model.dart';
@ -24,8 +25,7 @@ class MyReferralPatientProvider with ChangeNotifier {
getMyReferralPatient() async { getMyReferralPatient() async {
try { try {
await BaseAppClient.post( await BaseAppClient.post(GET_MY_REFERRAL_PATIENT,
'DoctorApplication.svc/REST/GtMyReferralPatient',
body: _requestMyReferralPatient.toJson(), body: _requestMyReferralPatient.toJson(),
onSuccess: (dynamic response, int statusCode) { onSuccess: (dynamic response, int statusCode) {
response['List_MyReferralPatient'].forEach((v) { response['List_MyReferralPatient'].forEach((v) {
@ -57,8 +57,7 @@ class MyReferralPatientProvider with ChangeNotifier {
_requestAddReferredDoctorRemarks.referredDoctorRemarks = referredDoctorRemarks; _requestAddReferredDoctorRemarks.referredDoctorRemarks = referredDoctorRemarks;
_requestAddReferredDoctorRemarks.lineItemNo = model.lineItemNo; _requestAddReferredDoctorRemarks.lineItemNo = model.lineItemNo;
_requestAddReferredDoctorRemarks.referringDoctor = model.referringDoctor; _requestAddReferredDoctorRemarks.referringDoctor = model.referringDoctor;
await BaseAppClient.post( await BaseAppClient.post(ADD_REFERRED_DOCTOR_REMARKS,
'DoctorApplication.svc/REST/AddReferredDoctorRemarks',
body: _requestAddReferredDoctorRemarks.toJson(), body: _requestAddReferredDoctorRemarks.toJson(),
onSuccess: (dynamic body, int statusCode) { onSuccess: (dynamic body, int statusCode) {
model.referredDoctorRemarks = referredDoctorRemarks; model.referredDoctorRemarks = referredDoctorRemarks;

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

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

@ -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/referral_patient_provider.dart';
import 'package:doctor_app_flutter/providers/referred_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/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/dr_app_shared_pref.dart';
import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/helpers.dart';
import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart';

@ -1,5 +1,6 @@
import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/config/size_config.dart';
import 'package:doctor_app_flutter/providers/livecare_provider.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/dr_app_shared_pref.dart';
import 'package:doctor_app_flutter/util/helpers.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/app_scaffold_widget.dart';
@ -207,6 +208,8 @@ class _LiveCarePandingListState extends State<LiveCarePandingListScreen> {
color: Colors color: Colors
.green, //Colors.black, .green, //Colors.black,
onPressed: () => { onPressed: () => {
sharedPref.setObj( sharedPref.setObj(
LIVE_CARE_PATIENT, LIVE_CARE_PATIENT,
item), item),
@ -223,7 +226,15 @@ class _LiveCarePandingListState extends State<LiveCarePandingListScreen> {
], ],
), ),
), ),
onTap: () {}, onTap: () {
sharedPref.setObj(
LIVE_CARE_PATIENT,
item);
Navigator.of(context)
.pushNamed(
VIDEO_CALL);
},
), ),
); );
}).toList(), }).toList(),

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:doctor_app_flutter/providers/livecare_provider.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/dr_app_shared_pref.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart';
@ -21,6 +22,7 @@ class _VideoCallPageState extends State<VideoCallPage> {
String _timmer = ''; String _timmer = '';
LiveCareProvider _liveCareProvider; LiveCareProvider _liveCareProvider;
bool _isInit = true; bool _isInit = true;
var _tokenData;
var patientData = {}; var patientData = {};
String image_url = 'https://hmgwebservices.com/Images/MobileImages/DUBAI/'; String image_url = 'https://hmgwebservices.com/Images/MobileImages/DUBAI/';
//bool _isOutOfStuck = false; //bool _isOutOfStuck = false;
@ -36,9 +38,14 @@ class _VideoCallPageState extends State<VideoCallPage> {
} }
void connectOpenTok(tokenData) { void connectOpenTok(tokenData) {
_tokenData = tokenData;
/* opentok functionalites need to be written */ /* opentok functionalites need to be written */
print(tokenData["OpenSessionID"]);
print(tokenData["OpenTokenID"]); VideoChannel.openVideoCallScreen(kApiKey: '46209962',
kSessionId: _tokenData["OpenSessionID"],
kToken: _tokenData["OpenTokenID"],
);
} }
String getTimerTime(int start) { String getTimerTime(int start) {
@ -149,7 +156,19 @@ class _VideoCallPageState extends State<VideoCallPage> {
FunctionalButton( FunctionalButton(
title: 'Speaker', title: 'Speaker',
icon: Icons.phone_in_talk, icon: Icons.phone_in_talk,
onPressed: () {}, onPressed: () {
print(_tokenData["OpenSessionID"]);
print(_tokenData["OpenTokenID"]);
VideoChannel.openVideoCallScreen(kApiKey: '46209962',
kSessionId: _tokenData["OpenSessionID"],
kToken: _tokenData["OpenTokenID"],
);
},
), ),
FunctionalButton( FunctionalButton(
title: 'Flip', title: 'Flip',

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

@ -55,7 +55,17 @@ class _PharmaciesListState extends State<PharmaciesListScreen> {
projectsProvider = Provider.of(context); projectsProvider = Provider.of(context);
return AppScaffold( return AppScaffold(
appBarTitle: TranslationBase.of(context).pharmaciesList, 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, height: SizeConfig.screenHeight,
child: ListView( child: ListView(
shrinkWrap: true, shrinkWrap: true,
@ -63,84 +73,70 @@ class _PharmaciesListState extends State<PharmaciesListScreen> {
physics: const AlwaysScrollableScrollPhysics(), physics: const AlwaysScrollableScrollPhysics(),
children: <Widget>[ children: <Widget>[
RoundedContainer( RoundedContainer(
child: !_medicineProvider.isFinished child: Row(
? DrAppCircularProgressIndeicator() children: <Widget>[
: _medicineProvider.hasError Expanded(
? Center( flex: 1,
child: Text( child: ClipRRect(
_medicineProvider.errorMsg, borderRadius: BorderRadius.all(
style: TextStyle( Radius.circular(7)),
color: Theme.of(context).errorColor), child: Image.memory(
), dataFromBase64String(widget.url),
) height:
: StreamBuilder<Object>( SizeConfig.imageSizeMultiplier *
stream: null, 21,
builder: (context, snapshot) { width:
return Row( SizeConfig.imageSizeMultiplier *
children: <Widget>[ 20,
Expanded( fit: BoxFit.cover,
flex: 1, ),
child: ClipRRect( ),
borderRadius: BorderRadius.all( ),
Radius.circular(7)), Expanded(
child: Image.memory( flex: 3,
dataFromBase64String(widget.url), child: Column(
height: mainAxisAlignment:
SizeConfig.imageSizeMultiplier * MainAxisAlignment.start,
21, crossAxisAlignment:
width: CrossAxisAlignment.stretch,
SizeConfig.imageSizeMultiplier * children: <Widget>[
20, AppText(
fit: BoxFit.cover, TranslationBase.of(context)
), .description,
), marginLeft: 10,
), marginTop: 0,
Expanded( marginRight: 10,
flex: 3, marginBottom: 2,
child: Column( fontWeight: FontWeight.bold,
mainAxisAlignment: ),
MainAxisAlignment.start, AppText(
crossAxisAlignment: _medicineProvider.pharmaciesList[0]["ItemDescription"],
CrossAxisAlignment.stretch, marginLeft: 10,
children: <Widget>[ marginTop: 0,
AppText( marginRight: 10,
TranslationBase.of(context) marginBottom: 10,
.description, ),
marginLeft: 10, AppText(
marginTop: 0, TranslationBase.of(context).price,
marginRight: 10, marginLeft: 10,
marginBottom: 2, marginTop: 0,
fontWeight: FontWeight.bold, marginRight: 10,
), marginBottom: 2,
AppText( fontWeight: FontWeight.bold,
_data[0]["ItemDescription"], ),
marginLeft: 10, AppText(
marginTop: 0, _medicineProvider.pharmaciesList[0]["SellingPrice"]
marginRight: 10, .toString(),
marginBottom: 10, marginLeft: 10,
), marginTop: 0,
AppText( marginRight: 10,
TranslationBase.of(context).price, marginBottom: 10,
marginLeft: 10, ),
marginTop: 0, ],
marginRight: 10, ),
marginBottom: 2, )
fontWeight: FontWeight.bold, ],
), )),
AppText(
_data[0]["SellingPrice"]
.toString(),
marginLeft: 10,
marginTop: 0,
marginRight: 10,
marginBottom: 10,
),
],
),
)
],
);
})),
Container( Container(
margin: EdgeInsets.only( margin: EdgeInsets.only(
top: SizeConfig.widthMultiplier * 2, top: SizeConfig.widthMultiplier * 2,
@ -165,7 +161,7 @@ class _PharmaciesListState extends State<PharmaciesListScreen> {
child: ListView.builder( child: ListView.builder(
shrinkWrap: true, shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
itemCount: _data == null ? 0 : _data.length, itemCount: _medicineProvider.pharmaciesList == null ? 0 : _medicineProvider.pharmaciesList.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return RoundedContainer( return RoundedContainer(
child: Row( child: Row(
@ -176,7 +172,7 @@ class _PharmaciesListState extends State<PharmaciesListScreen> {
borderRadius: borderRadius:
BorderRadius.all(Radius.circular(7)), BorderRadius.all(Radius.circular(7)),
child: Image.network( child: Image.network(
_data[index]["ProjectImageURL"], _medicineProvider.pharmaciesList[index]["ProjectImageURL"],
height: height:
SizeConfig.imageSizeMultiplier * 15, SizeConfig.imageSizeMultiplier * 15,
width: width:
@ -188,7 +184,7 @@ class _PharmaciesListState extends State<PharmaciesListScreen> {
Expanded( Expanded(
flex: 4, flex: 4,
child: AppText( child: AppText(
_data[index]["LocationDescription"], _medicineProvider.pharmaciesList[index]["LocationDescription"],
margin: 10, margin: 10,
), ),
), ),
@ -207,7 +203,7 @@ class _PharmaciesListState extends State<PharmaciesListScreen> {
color: Colors.red, color: Colors.red,
), ),
onTap: () => launch("tel://" + onTap: () => launch("tel://" +
_data[index]["PhoneNumber"]), _medicineProvider.pharmaciesList[index]["PhoneNumber"]),
), ),
), ),
Padding( Padding(
@ -220,10 +216,10 @@ class _PharmaciesListState extends State<PharmaciesListScreen> {
onTap: () { onTap: () {
MapsLauncher.launchCoordinates( MapsLauncher.launchCoordinates(
double.parse( double.parse(
_data[index]["Latitude"]), _medicineProvider.pharmaciesList[index]["Latitude"]),
double.parse( double.parse(
_data[index]["Longitude"]), _medicineProvider.pharmaciesList[index]["Longitude"]),
_data[index] _medicineProvider.pharmaciesList[index]
["LocationDescription"]); ["LocationDescription"]);
}, },
), ),
@ -241,19 +237,15 @@ class _PharmaciesListState extends State<PharmaciesListScreen> {
)); ));
} }
Future<bool> pharmaciesList() async { pharmaciesList() async {
_medicineProvider.getPharmaciesList(widget.itemID).then((result) { _medicineProvider.getPharmaciesList(widget.itemID);
this.setState(() {
_data = _medicineProvider.pharmaciesList;
});
});
return true;
} }
Image imageFromBase64String(String base64String) { Image imageFromBase64String(String base64String) {
return Image.memory(base64Decode(base64String)); return Image.memory(base64Decode(base64String));
} }
//TODO CHECK THE URL IS NULL OR NOT
Uint8List dataFromBase64String(String base64String) { Uint8List dataFromBase64String(String base64String) {
return base64Decode(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/models/doctor/list_doctor_working_hours_table_model.dart';
import 'package:doctor_app_flutter/routes.dart'; import 'package:doctor_app_flutter/routes.dart';
import 'package:doctor_app_flutter/util/dr_app_shared_pref.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 '../util/dr_app_toast_msg.dart';
import 'package:connectivity/connectivity.dart'; import 'package:connectivity/connectivity.dart';
import 'dr_app_shared_pref.dart';
DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); DrAppSharedPreferances sharedPref = new DrAppSharedPreferances();
@ -22,6 +24,8 @@ DrAppSharedPreferances sharedPref = new DrAppSharedPreferances();
class Helpers { class Helpers {
int cupertinoPickerIndex = 0; int cupertinoPickerIndex = 0;
get currentLanguage => null;
/* /*
*@author: Elham Rababah *@author: Elham Rababah
*@Date:12/4/2020 *@Date:12/4/2020
@ -340,7 +344,9 @@ class Helpers {
} }
logout() async { logout() async {
String lang = await sharedPref.getString(APP_Language);
await clearSharedPref(); await clearSharedPref();
sharedPref.setString(APP_Language, lang);
Navigator.of(AppGlobal.CONTEX).pushReplacementNamed(LOGIN); Navigator.of(AppGlobal.CONTEX).pushReplacementNamed(LOGIN);
} }
} }

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

Loading…
Cancel
Save