diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt index f013d281..d595be97 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -7,6 +7,7 @@ import androidx.annotation.NonNull import com.google.gson.GsonBuilder import com.hmg.hmgDr.Model.GetSessionStatusModel import com.hmg.hmgDr.Model.SessionStatusModel +import com.hmg.hmgDr.ui.VideoCallResponseListener import com.hmg.hmgDr.ui.fragment.VideoCallFragment import io.flutter.embedding.android.FlutterFragmentActivity import io.flutter.embedding.engine.FlutterEngine @@ -15,7 +16,7 @@ import io.flutter.plugin.common.MethodChannel import io.flutter.plugins.GeneratedPluginRegistrant -class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler { +class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, VideoCallResponseListener { private val CHANNEL = "Dr.cloudSolution/videoCall" private var result: MethodChannel.Result? = null @@ -67,7 +68,6 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler private fun openVideoCall(apiKey: String?, sessionId: String?, token: String?, appLang: String?, baseUrl: String?, sessionStatusModel: GetSessionStatusModel) { // val videoCallActivity = VideoCallActivity() - // val intent = Intent(this, VideoCallActivity::class.java) // intent.putExtra("apiKey", apiKey) // intent.putExtra("sessionId", sessionId) @@ -77,14 +77,23 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler // intent.putExtra("sessionStatusModel", sessionStatusModel) // startActivityForResult(intent, LAUNCH_VIDEO) + val arguments = Bundle() + arguments.putString("apiKey", apiKey) + arguments.putString("sessionId", sessionId) + arguments.putString("token", token) + arguments.putString("appLang", appLang) + arguments.putString("baseUrl", baseUrl) + arguments.putParcelable("sessionStatusModel", sessionStatusModel) + val transaction = supportFragmentManager.beginTransaction() - dialogFragment = VideoCallFragment.newInstance(Bundle()) - dialogFragment.isCancelable = false + dialogFragment = VideoCallFragment.newInstance(arguments) + dialogFragment.setCallListener(this) + dialogFragment.isCancelable = true dialogFragment.show(transaction, "dialog") } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + /* override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) var asd = ""; if (requestCode == LAUNCH_VIDEO) { @@ -108,6 +117,28 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler result?.success(callResponse) } } + }*/ + + override fun onCallFinished(resultCode: Int, intent: Intent?) { + if (resultCode == Activity.RESULT_OK) { + val result : SessionStatusModel? = intent?.getParcelableExtra("sessionStatusNotRespond") + val callResponse : HashMap = HashMap() + + val sessionStatus : HashMap = HashMap() + val gson = GsonBuilder().serializeNulls().create() + + callResponse["callResponse"] = "CallNotRespond" + val jsonRes = gson.toJson(result) + callResponse["sessionStatus"] = jsonRes + + this.result?.success(callResponse) + } + if (resultCode == Activity.RESULT_CANCELED) { + val callResponse : HashMap = HashMap() + callResponse["callResponse"] = "CallEnd" + + result?.success(callResponse) + } } diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt new file mode 100644 index 00000000..e32630b4 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt @@ -0,0 +1,8 @@ +package com.hmg.hmgDr.ui + +import android.content.Intent + +interface VideoCallResponseListener { + + fun onCallFinished(resultCode : Int, intent: Intent? = null) +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt index d5a5d5da..dd4613bd 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -10,39 +10,38 @@ import android.graphics.Color import android.graphics.Point import android.graphics.drawable.ColorDrawable import android.opengl.GLSurfaceView -import android.os.Bundle -import android.os.CountDownTimer -import android.os.Handler -import android.os.Looper +import android.os.* import android.util.Log import android.view.* import android.widget.* import androidx.annotation.Nullable +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.constraintlayout.widget.ConstraintSet import androidx.fragment.app.DialogFragment -import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel import com.hmg.hmgDr.Model.GetSessionStatusModel import com.hmg.hmgDr.Model.SessionStatusModel import com.hmg.hmgDr.R import com.hmg.hmgDr.ui.VideoCallContract.VideoCallPresenter import com.hmg.hmgDr.ui.VideoCallContract.VideoCallView import com.hmg.hmgDr.ui.VideoCallPresenterImpl +import com.hmg.hmgDr.ui.VideoCallResponseListener import com.opentok.android.* import com.opentok.android.PublisherKit.PublisherListener import pub.devrel.easypermissions.AfterPermissionGranted import pub.devrel.easypermissions.AppSettingsDialog import pub.devrel.easypermissions.EasyPermissions import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks -import java.util.* import kotlin.math.ceil + class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.SessionListener, PublisherListener, SubscriberKit.VideoListener, VideoCallView { var isFullScreen: Boolean = true private var x_init_cord = 0 - private var y_init_cord:Int = 0 - private var x_init_margin:Int = 0 - private var y_init_margin:Int = 0 + private var y_init_cord: Int = 0 + private var x_init_margin: Int = 0 + private var y_init_margin: Int = 0 private val szWindow: Point = Point() private lateinit var mWindowManager: WindowManager private var isLeft = true @@ -58,9 +57,11 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private var mVolRunnable: Runnable? = null private var mConnectedRunnable: Runnable? = null - private var mPublisherViewContainer: FrameLayout? = null - private var mSubscriberViewContainer: RelativeLayout? = null - private var controlPanel: RelativeLayout? = null + private lateinit var mPublisherViewContainer: FrameLayout + private lateinit var mPublisherViewIcon: View + private lateinit var mSubscriberViewContainer: FrameLayout + private lateinit var mSubscriberViewIcon: ImageView + private var controlPanel: ConstraintLayout? = null private var apiKey: String? = null private var sessionId: String? = null @@ -73,7 +74,9 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private var isSpeckerClicked = false private var isMicClicked = false - private lateinit var videoCallContainer: LinearLayout + private lateinit var parentView: View + private lateinit var videoCallContainer: ConstraintLayout + private lateinit var layoutName: RelativeLayout private lateinit var mCallBtn: ImageView private lateinit var btnMinimize: ImageView private lateinit var mCameraBtn: ImageView @@ -81,6 +84,11 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private lateinit var mspeckerBtn: ImageView private lateinit var mMicBtn: ImageView + private lateinit var patientName: TextView + private lateinit var cmTimer: Chronometer + var elapsedTime: Long = 0 + var resume = false + private val progressBar: ProgressBar? = null private val countDownTimer: CountDownTimer? = null private val progressBarTextView: TextView? = null @@ -89,6 +97,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private var isConnected = false private var sessionStatusModel: GetSessionStatusModel? = null + private var videoCallResponseListener: VideoCallResponseListener? =null override fun onCreate(savedInstanceState: Bundle?) { @@ -137,16 +146,20 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } } + fun setCallListener(videoCallResponseListener: VideoCallResponseListener){ + this.videoCallResponseListener = videoCallResponseListener + } + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - val view = inflater.inflate(R.layout.activity_video_call, container, false) + parentView = inflater.inflate(R.layout.activity_video_call, container, false) - Objects.requireNonNull(requireActivity().actionBar)!!.hide() - initUI(view) +// Objects.requireNonNull(requireActivity().actionBar)!!.hide() + initUI(parentView) handleDragDialog() - return view + return parentView } override fun onPause() { @@ -170,14 +183,18 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onDestroy() { disconnectSession() + cmTimer.stop() super.onDestroy() } @SuppressLint("ClickableViewAccessibility") private fun initUI(view: View) { - videoCallContainer = view.findViewById(R.id.video_call_ll) - mPublisherViewContainer = view.findViewById(R.id.local_video_view_container) - mSubscriberViewContainer = view.findViewById(R.id.remote_video_view_container) + videoCallContainer = view.findViewById(R.id.video_call_ll) + layoutName = view.findViewById(R.id.layout_name) + mPublisherViewContainer = view.findViewById(R.id.local_video_view_container) + mPublisherViewIcon = view.findViewById(R.id.local_video_view_icon) + mSubscriberViewIcon = view.findViewById(R.id.remote_video_view_icon) + mSubscriberViewContainer = view.findViewById(R.id.remote_video_view_container) arguments?.run { apiKey = getString("apiKey") @@ -188,7 +205,27 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session sessionStatusModel = getParcelable("sessionStatusModel") } - controlPanel = view.findViewById(R.id.control_panel) + patientName = view.findViewById(R.id.patient_name) + patientName.text = sessionStatusModel!!.patientName + + cmTimer = view.findViewById(R.id.cmTimer) + cmTimer.format = "mm:ss" + cmTimer.onChronometerTickListener = Chronometer.OnChronometerTickListener { arg0: Chronometer? -> + val minutes: Long + val seconds: Long + if (!resume) { + minutes = (SystemClock.elapsedRealtime() - cmTimer.base) / 1000 / 60 + seconds = (SystemClock.elapsedRealtime() - cmTimer.base) / 1000 % 60 + elapsedTime = SystemClock.elapsedRealtime() + } else { + minutes = (elapsedTime - cmTimer.base) / 1000 / 60 + seconds = (elapsedTime - cmTimer.base) / 1000 % 60 + elapsedTime = elapsedTime + 1000 + } + Log.d(VideoCallFragment.TAG, "onChronometerTick: $minutes : $seconds") + } + + controlPanel = view.findViewById(R.id.control_panel) videoCallPresenter = VideoCallPresenterImpl(this, baseUrl) mCallBtn = view.findViewById(R.id.btn_call) mCallBtn.setOnClickListener { @@ -295,17 +332,23 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session (mPublisher!!.getView() as GLSurfaceView).setZOrderOnTop(true) } mSession!!.publish(mPublisher) + + if (!resume) { + cmTimer.base = SystemClock.elapsedRealtime() + } + cmTimer.start() } override fun onDisconnected(session: Session) { Log.d(TAG, "onDisconnected: disconnected from session " + session.sessionId) mSession = null + cmTimer.stop() } override fun onError(session: Session, opentokError: OpentokError) { Log.d(TAG, "onError: Error (" + opentokError.message + ") in session " + session.sessionId) - Toast.makeText(requireContext(), "Session error. See the logcat please.", Toast.LENGTH_LONG).show() - requireActivity().finish() +// Toast.makeText(requireContext(), "Session error. See the logcat please.", Toast.LENGTH_LONG).show() +// requireActivity().finish() } override fun onStreamReceived(session: Session, stream: Stream) { @@ -316,7 +359,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } isConnected = true subscribeToStream(stream) - videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(3, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) +// videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(3, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) } override fun onStreamDropped(session: Session, stream: Stream) { @@ -342,8 +385,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onError(publisherKit: PublisherKit?, opentokError: OpentokError) { Log.d(VideoCallFragment.TAG, "onError: Error (" + opentokError.message + ") in publisher") - Toast.makeText(requireContext(), "Session error. See the logcat please.", Toast.LENGTH_LONG).show() - requireActivity().finish() +// Toast.makeText(requireContext(), "Session error. See the logcat please.", Toast.LENGTH_LONG).show() +// requireActivity().finish() } override fun onVideoDataReceived(subscriberKit: SubscriberKit?) { @@ -367,8 +410,9 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private fun disconnectSession() { if (mSession == null) { - requireActivity().setResult(Activity.RESULT_CANCELED) - requireActivity().finish() + videoCallResponseListener?.onCallFinished(Activity.RESULT_CANCELED) +// requireActivity().setResult(Activity.RESULT_CANCELED) + dialog?.dismiss() return } if (mSubscriber != null) { @@ -385,8 +429,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } mSession!!.disconnect() countDownTimer?.cancel() - videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(16, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) - requireActivity().finish() +// videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(16, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) + dialog?.dismiss() } @@ -394,8 +438,9 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session if (sessionStatusModel.sessionStatus == 2 || sessionStatusModel.sessionStatus == 3) { val returnIntent = Intent() returnIntent.putExtra("sessionStatusNotRespond", sessionStatusModel) - requireActivity().setResult(Activity.RESULT_OK, returnIntent) - requireActivity().finish() + videoCallResponseListener?.onCallFinished(Activity.RESULT_OK, returnIntent) +// requireActivity().setResult(Activity.RESULT_OK, returnIntent) + dialog?.dismiss() } } @@ -403,7 +448,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onFailure() {} - fun onSwitchCameraClicked(view: View?) { + private fun onSwitchCameraClicked(view: View?) { if (mPublisher != null) { isSwitchCameraClicked = !isSwitchCameraClicked mPublisher!!.cycleCamera() @@ -412,11 +457,11 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } } - fun onCallClicked(view: View?) { + private fun onCallClicked(view: View?) { disconnectSession() } - fun onMinimizedClicked(view: View?) { + private fun onMinimizedClicked(view: View?) { if (isFullScreen) { dialog?.window?.setLayout( 400, @@ -429,9 +474,89 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session ) } isFullScreen = !isFullScreen + setViewsVisibility() + } + + private fun setViewsVisibility() { + initUI(parentView) + val iconSize : Int = context!!.resources.getDimension(R.dimen.video_icon_size).toInt() + val iconSizeSmall : Int = context!!.resources.getDimension(R.dimen.video_icon_size_small).toInt() + val btnMinimizeLayoutParam : ConstraintLayout.LayoutParams = btnMinimize.layoutParams as ConstraintLayout.LayoutParams + val mCallBtnLayoutParam : ConstraintLayout.LayoutParams = mCallBtn.layoutParams as ConstraintLayout.LayoutParams + +// val localPreviewMargin : Int = context!!.resources.getDimension(R.dimen.local_preview_margin_top).toInt() +// val localPreviewWidth : Int = context!!.resources.getDimension(R.dimen.local_preview_width).toInt() +// val localPreviewHeight : Int = context!!.resources.getDimension(R.dimen.local_preview_height).toInt() +// val localPreviewIconSize: Int = context!!.resources.getDimension(R.dimen.local_back_icon_size).toInt() +// val localPreviewMarginSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_margin_small).toInt() +// val localPreviewWidthSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_width_small).toInt() +// val localPreviewHeightSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_height_small).toInt() +// val localPreviewIconSmall: Int = context!!.resources.getDimension(R.dimen.local_back_icon_size_small).toInt() +// val localPreviewLayoutIconParam : FrameLayout.LayoutParams +// val localPreviewLayoutParam : RelativeLayout.LayoutParams = mPublisherViewContainer.layoutParams as RelativeLayout.LayoutParams + + val remotePreviewIconSize: Int = context!!.resources.getDimension(R.dimen.remote_back_icon_size).toInt() + val remotePreviewIconSizeSmall: Int = context!!.resources.getDimension(R.dimen.remote_back_icon_size_small).toInt() + val remotePreviewLayoutParam : FrameLayout.LayoutParams = mSubscriberViewIcon.layoutParams as FrameLayout.LayoutParams + + val constraintSet = ConstraintSet() + //layoutParam.constrain +// constraintSet. + if (isFullScreen) { + layoutName.visibility = View.VISIBLE + mCameraBtn.visibility = View.VISIBLE + mSwitchCameraBtn.visibility = View.VISIBLE + mspeckerBtn.visibility = View.VISIBLE + mMicBtn.visibility = View.VISIBLE + mPublisherViewContainer.visibility = View.VISIBLE + +// layoutParam = ConstraintLayout.LayoutParams(iconSize, iconSize) + btnMinimizeLayoutParam.width = iconSize + btnMinimizeLayoutParam.height = iconSize + mCallBtnLayoutParam.width = iconSize + mCallBtnLayoutParam.height = iconSize +// localPreviewLayoutIconParam = FrameLayout.LayoutParams(localPreviewIconSize, localPreviewIconSize) +//// localPreviewLayoutParam = RelativeLayout.LayoutParams(localPreviewWidth, localPreviewHeight) +// localPreviewLayoutParam.width = localPreviewIconSize +// localPreviewLayoutParam.height = localPreviewIconSize +// localPreviewLayoutParam.setMargins(0,localPreviewMargin, localPreviewMargin, 0) +// remotePreviewLayoutParam = FrameLayout.LayoutParams(remotePreviewIconSize, remotePreviewIconSize) + remotePreviewLayoutParam.width = remotePreviewIconSize + remotePreviewLayoutParam.height = remotePreviewIconSize + } else { + layoutName.visibility = View.GONE + mCameraBtn.visibility = View.GONE + mSwitchCameraBtn.visibility = View.GONE + mspeckerBtn.visibility = View.GONE + mMicBtn.visibility = View.GONE + mPublisherViewContainer.visibility = View.GONE + +// layoutParam = ConstraintLayout.LayoutParams(iconSizeSmall, iconSizeSmall) + btnMinimizeLayoutParam.width = iconSizeSmall + btnMinimizeLayoutParam.height = iconSizeSmall + mCallBtnLayoutParam.width = iconSizeSmall + mCallBtnLayoutParam.height = iconSizeSmall + +// localPreviewLayoutIconParam = FrameLayout.LayoutParams(localPreviewIconSmall, localPreviewIconSmall) +//// localPreviewLayoutParam = RelativeLayout.LayoutParams(localPreviewWidthSmall, localPreviewHeightSmall) +// localPreviewLayoutParam.width = localPreviewWidthSmall +// localPreviewLayoutParam.height = localPreviewWidthSmall +// localPreviewLayoutParam.setMargins(0,localPreviewMarginSmall, localPreviewMarginSmall, 0) +// remotePreviewLayoutParam = FrameLayout.LayoutParams(remotePreviewIconSizeSmall, remotePreviewIconSizeSmall) + remotePreviewLayoutParam.width = remotePreviewIconSizeSmall + remotePreviewLayoutParam.height = remotePreviewIconSizeSmall + } + +// mPublisherViewContainer.layoutParams = localPreviewLayoutParam +// mPublisherViewIcon.layoutParams = localPreviewLayoutIconParam + mSubscriberViewIcon.layoutParams = remotePreviewLayoutParam + + btnMinimize.layoutParams = btnMinimizeLayoutParam + mCallBtn.layoutParams = mCallBtnLayoutParam + } - fun onCameraClicked(view: View?) { + private fun onCameraClicked(view: View?) { if (mPublisher != null) { isCameraClicked = !isCameraClicked mPublisher!!.publishVideo = !isCameraClicked @@ -440,7 +565,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } } - fun onMicClicked(view: View?) { + private fun onMicClicked(view: View?) { if (mPublisher != null) { isMicClicked = !isMicClicked mPublisher!!.publishAudio = !isMicClicked @@ -449,7 +574,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } } - fun onSpeckerClicked(view: View?) { + private fun onSpeckerClicked(view: View?) { if (mSubscriber != null) { isSpeckerClicked = !isSpeckerClicked mSubscriber!!.subscribeToAudio = !isSpeckerClicked @@ -458,64 +583,69 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } } + @SuppressLint("ClickableViewAccessibility") - fun handleDragDialog(){ + fun handleDragDialog() { mWindowManager = requireActivity().getSystemService(Context.WINDOW_SERVICE) as WindowManager getWindowManagerDefaultDisplay() - videoCallContainer.setOnTouchListener { _, event -> - //Get Floating widget view params - //Get Floating widget view params - val layoutParams : WindowManager.LayoutParams = dialog!!.window!!.attributes - //get the touch location coordinates - val x_cord = event.rawX.toInt() - val y_cord = event.rawY.toInt() - val x_cord_Destination: Int - var y_cord_Destination: Int - - when (event.action) { - MotionEvent.ACTION_DOWN -> { - x_init_cord = x_cord - y_init_cord = y_cord - - //remember the initial position. - x_init_margin = layoutParams.x - y_init_margin = layoutParams.y - } - MotionEvent.ACTION_UP -> { - //Get the difference between initial coordinate and current coordinate - val x_diff: Int = x_cord - x_init_cord - val y_diff: Int = y_cord - y_init_cord - - y_cord_Destination = y_init_margin + y_diff - val barHeight: Int = getStatusBarHeight() - if (y_cord_Destination < 0) { + videoCallContainer.setOnTouchListener(dragListener) +// mSubscriberViewContainer.setOnTouchListener(dragListener) + } + + @SuppressLint("ClickableViewAccessibility") + val dragListener : View.OnTouchListener = View.OnTouchListener{ _, event -> + //Get Floating widget view params + //Get Floating widget view params + val layoutParams: WindowManager.LayoutParams = dialog!!.window!!.attributes + //get the touch location coordinates + val x_cord = event.rawX.toInt() + val y_cord = event.rawY.toInt() + val x_cord_Destination: Int + var y_cord_Destination: Int + + when (event.action) { + MotionEvent.ACTION_DOWN -> { + x_init_cord = x_cord + y_init_cord = y_cord + + //remember the initial position. + x_init_margin = layoutParams.x + y_init_margin = layoutParams.y + } + MotionEvent.ACTION_UP -> { + //Get the difference between initial coordinate and current coordinate + val x_diff: Int = x_cord - x_init_cord + val y_diff: Int = y_cord - y_init_cord + + y_cord_Destination = y_init_margin + y_diff + val barHeight: Int = getStatusBarHeight() + if (y_cord_Destination < 0) { // y_cord_Destination = 0 - y_cord_Destination = - -(szWindow.y - (videoCallContainer.height /*+ barHeight*/)) - } else if (y_cord_Destination + (videoCallContainer.height + barHeight) > szWindow.y) { - y_cord_Destination = - szWindow.y - (videoCallContainer.height + barHeight) - } - layoutParams.y = y_cord_Destination - - //reset position if user drags the floating view - resetPosition(x_cord) + y_cord_Destination = + -(szWindow.y - (videoCallContainer.height /*+ barHeight*/)) + } else if (y_cord_Destination + (videoCallContainer.height + barHeight) > szWindow.y) { + y_cord_Destination = + szWindow.y - (videoCallContainer.height + barHeight) } - MotionEvent.ACTION_MOVE -> { - val x_diff_move: Int = x_cord - x_init_cord - val y_diff_move: Int = y_cord - y_init_cord - x_cord_Destination = x_init_margin + x_diff_move - y_cord_Destination = y_init_margin + y_diff_move + layoutParams.y = y_cord_Destination + + //reset position if user drags the floating view + resetPosition(x_cord) + } + MotionEvent.ACTION_MOVE -> { + val x_diff_move: Int = x_cord - x_init_cord + val y_diff_move: Int = y_cord - y_init_cord + x_cord_Destination = x_init_margin + x_diff_move + y_cord_Destination = y_init_margin + y_diff_move - layoutParams.x = x_cord_Destination - layoutParams.y = y_cord_Destination + layoutParams.x = x_cord_Destination + layoutParams.y = y_cord_Destination - dialog!!.window!!.attributes = layoutParams - } + dialog!!.window!!.attributes = layoutParams } - true } + true } /* Reset position of Floating Widget view on dragging */ @@ -532,16 +662,16 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session /* Method to move the Floating widget view to Left */ private fun moveToLeft(current_x_cord: Int) { - var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes + var mParams: WindowManager.LayoutParams = dialog!!.window!!.attributes mParams.x = - (szWindow.x - current_x_cord * current_x_cord - videoCallContainer.width).toInt() + (szWindow.x - current_x_cord * current_x_cord - videoCallContainer.width).toInt() dialog!!.window!!.attributes = mParams val x = szWindow.x - current_x_cord object : CountDownTimer(500, 5) { //get params of Floating Widget view - var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes + var mParams: WindowManager.LayoutParams = dialog!!.window!!.attributes override fun onTick(t: Long) { val step = (500 - t) / 5 // mParams.x = 0 - (current_x_cord * current_x_cord * step).toInt() @@ -568,7 +698,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session // dialog!!.window!!.attributes = mParams object : CountDownTimer(500, 5) { //get params of Floating Widget view - var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes + var mParams: WindowManager.LayoutParams = dialog!!.window!!.attributes override fun onTick(t: Long) { val step = (500 - t) / 5 mParams.x = diff --git a/android/app/src/main/res/drawable/layout_rounded_bg.xml b/android/app/src/main/res/drawable/layout_rounded_bg.xml new file mode 100644 index 00000000..0c46f49b --- /dev/null +++ b/android/app/src/main/res/drawable/layout_rounded_bg.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/android/app/src/main/res/layout/activity_video_call.xml b/android/app/src/main/res/layout/activity_video_call.xml index b7ca8d8d..0b3baff7 100644 --- a/android/app/src/main/res/layout/activity_video_call.xml +++ b/android/app/src/main/res/layout/activity_video_call.xml @@ -1,5 +1,6 @@ - + android:padding="@dimen/padding_space_medium" + app:layout_constraintTop_toTopOf="parent"> + tools:text="25:45" /> @@ -47,7 +50,8 @@ android:id="@+id/activity_clingo_video_call" android:layout_width="match_parent" android:layout_height="0dp" - android:layout_weight="1" + app:layout_constraintBottom_toTopOf="@id/control_panel" + app:layout_constraintTop_toBottomOf="@+id/layout_name" tools:context=".ui.VideoCallActivity"> - - + - + - + android:padding="@dimen/padding_space_big" + app:layout_constraintBottom_toBottomOf="parent"> + android:src="@drawable/call" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + android:src="@drawable/ic_mini" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + android:scaleType="centerCrop" + android:src="@drawable/video_enabled" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/btn_minimize" + app:layout_constraintTop_toTopOf="parent" + /> + android:src="@drawable/mic_enabled" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/btn_camera" + app:layout_constraintTop_toTopOf="parent" + /> - - - + android:scaleType="centerCrop" + android:src="@drawable/audio_enabled" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/btn_mic" + app:layout_constraintTop_toTopOf="parent" + /> + + + diff --git a/android/app/src/main/res/values/dimens.xml b/android/app/src/main/res/values/dimens.xml index 2d53d554..2a4d695f 100644 --- a/android/app/src/main/res/values/dimens.xml +++ b/android/app/src/main/res/values/dimens.xml @@ -3,21 +3,27 @@ 16dp 16dp 28dp + 12dp 24dp 60dp 54dp - 64dp + 52dp + 24dp 24dp 25dp 88dp + 40dp 117dp + 50dp 50dp + 25dp 100dp + 40dp 90dp diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index 58df9331..189dea42 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -254,8 +254,8 @@ class AuthenticationViewModel extends BaseViewModel { /// add  token to shared preferences in case of send activation code is success setDataAfterSendActivationSuccess(SendActivationCodeForDoctorAppResponseModel sendActivationCodeForDoctorAppResponseModel) { - print("VerificationCode : " + - sendActivationCodeForDoctorAppResponseModel.verificationCode); + print("VerificationCode : " + sendActivationCodeForDoctorAppResponseModel.verificationCode); + DrAppToastMsg.showSuccesToast("VerificationCode : " + sendActivationCodeForDoctorAppResponseModel.verificationCode); sharedPref.setString(VIDA_AUTH_TOKEN_ID, sendActivationCodeForDoctorAppResponseModel.vidaAuthTokenID); sharedPref.setString(VIDA_REFRESH_TOKEN_ID, diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index e0053b81..d755af4a 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -17,6 +17,7 @@ import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; diff --git a/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart b/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart index 995ac57a..f2a32e63 100644 --- a/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart @@ -21,8 +21,10 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget final bool isDischargedPatient; final bool isFromLiveCare; + final Stream videoCallDurationStream; + PatientProfileHeaderNewDesignAppBar( - this.patient, this.patientType, this.arrivalType, {this.height = 0.0, this.isInpatient=false, this.isDischargedPatient=false, this.isFromLiveCare = false}); + this.patient, this.patientType, this.arrivalType, {this.height = 0.0, this.isInpatient=false, this.isDischargedPatient=false, this.isFromLiveCare = false, this.videoCallDurationStream}); @override Widget build(BuildContext context) { @@ -88,6 +90,23 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget ), ), ), + StreamBuilder( + stream: videoCallDurationStream, + builder: (BuildContext context, AsyncSnapshot snapshot) { + if(snapshot.hasData && snapshot.data != null) + return InkWell( + onTap: (){ + }, + child: Container( + decoration: BoxDecoration(color: Colors.red, borderRadius: BorderRadius.circular(20)), + padding: EdgeInsets.symmetric(vertical: 2, horizontal: 10), + child: Text(snapshot.data, style: TextStyle(color: Colors.white),), + ), + ); + else + return Container(); + }, + ), ]), ), Row(children: [