Merge branch 'video-stream-background' into 'development'

Video stream background

See merge request Cloud_Solution/doctor_app_flutter!759
merge-requests/760/merge
Mohammad Aljammal 5 years ago
commit ec3ac18a15

@ -40,6 +40,9 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name = ".Service.VideoStreamContainerService"/>
<!--
Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java

@ -1,14 +1,20 @@
package com.hmg.hmgDr
import android.app.Activity
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Bundle
import android.os.IBinder
import android.util.Log
import android.widget.Toast
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
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.Service.VideoStreamContainerService
import com.hmg.hmgDr.ui.VideoCallResponseListener
import com.hmg.hmgDr.ui.fragment.VideoCallFragment
import io.flutter.embedding.android.FlutterFragmentActivity
@ -18,7 +24,8 @@ import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, VideoCallResponseListener {
class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler,
VideoCallResponseListener {
private val CHANNEL = "Dr.cloudSolution/videoCall"
private lateinit var methodChannel: MethodChannel
@ -27,6 +34,9 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler,
private val LAUNCH_VIDEO: Int = 1
private var dialogFragment: VideoCallFragment? = null
private var serviceIntent: Intent? = null
private var videoStreamService: VideoStreamContainerService? = null
private var bound = false
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine)
@ -56,7 +66,8 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler,
val patientName = call.argument<String>("patientName")
val isRecording = call.argument<Boolean>("isRecording")
val sessionStatusModel = GetSessionStatusModel(VC_ID, tokenID, generalId, doctorId, patientName, isRecording!!)
val sessionStatusModel =
GetSessionStatusModel(VC_ID, tokenID, generalId, doctorId, patientName, isRecording!!)
openVideoCall(apiKey, sessionId, token, appLang, baseUrl, sessionStatusModel)
@ -64,6 +75,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler,
}
"closeVideoCall" -> {
dialogFragment?.onCallClicked()
// videoStreamService?.closeVideoCall()
}
"onCallConnected" -> {
@ -103,6 +115,32 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler,
}
}
// private fun openVideoCall(
// apiKey: String?,
// sessionId: String?,
// token: String?,
// appLang: String?,
// baseUrl: String?,
// sessionStatusModel: GetSessionStatusModel
// ) {
//
// 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)
//
//// showSoftKeyBoard(null)
// // start service
// serviceIntent = Intent(this@MainActivity, VideoStreamContainerService::class.java)
// serviceIntent?.run {
// putExtras(arguments)
// startService(this)
// }
//// bindService()
// }
/* override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
@ -146,7 +184,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler,
try {
this.result?.success(callResponse)
} catch (e : Exception){
} catch (e: Exception) {
Log.e("onVideoCallFinished", "${e.message}.")
}
} else if (resultCode == Activity.RESULT_CANCELED) {
@ -154,10 +192,14 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler,
callResponse["callResponse"] = "CallEnd"
try {
result?.success(callResponse)
} catch (e : Exception){
} catch (e: Exception) {
Log.e("onVideoCallFinished", "${e.message}.")
}
}
// stopService(serviceIntent)
// unbindService()
// videoStreamService!!.serviceRunning = false
}
override fun errorHandle(message: String) {
@ -176,4 +218,63 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler,
super.onBackPressed()
}
// override fun onStart() {
// super.onStart()
// bindService()
// }
//
// override fun onStop() {
// super.onStop()
// unbindService()
// }
// private fun bindService() {
// serviceIntent?.run {
// if (videoStreamService != null && !videoStreamService!!.serviceRunning){
// startService(this)
// }
// bindService(this, serviceConnection, Context.BIND_AUTO_CREATE)
// videoStreamService?.serviceRunning = true
// }
// }
//
// private fun unbindService() {
// if (bound) {
// videoStreamService!!.videoCallResponseListener = null // unregister
// videoStreamService!!.mActivity = null
// unbindService(serviceConnection)
// bound = false
// }
// }
//
// private val serviceConnection: ServiceConnection = object : ServiceConnection {
// override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
// val binder: VideoStreamContainerService.VideoStreamBinder =
// service as VideoStreamContainerService.VideoStreamBinder
// videoStreamService = binder.service
// bound = true
// videoStreamService!!.videoCallResponseListener = this@MainActivity // register
// videoStreamService!!.mActivity = this@MainActivity // register
// }
//
// override fun onServiceDisconnected(name: ComponentName?) {
// bound = false
// }
//
// }
// code to hide soft keyboard
fun hideSoftKeyBoard(editBox: EditText?) {
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(editBox?.windowToken, 0)
}
// code to show soft keyboard
private fun showSoftKeyBoard(editBox: EditText?) {
val inputMethodManager = this.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
editBox?.requestFocus()
inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0)
}
}

@ -0,0 +1,91 @@
package com.hmg.hmgDr.Service
import android.app.Service
import android.content.Intent
import android.os.Binder
import android.os.Bundle
import android.os.IBinder
import com.hmg.hmgDr.MainActivity
import com.hmg.hmgDr.ui.VideoCallResponseListener
import com.hmg.hmgDr.ui.fragment.VideoCallFragment
class VideoStreamContainerService : Service(), VideoCallResponseListener {
var videoCallResponseListener: VideoCallResponseListener? = null
var mActivity: MainActivity? = null
set(value) {
field = value
if (field != null) {
setDialogFragment()
}
}
var arguments: Bundle? = null
var serviceRunning: Boolean = false
private val serviceBinder: IBinder = VideoStreamBinder()
private var dialogFragment: VideoCallFragment? = null
override fun onBind(intent: Intent?): IBinder {
return serviceBinder
}
private fun setDialogFragment() {
mActivity?.run {
if (dialogFragment == null) {
val transaction = supportFragmentManager.beginTransaction()
dialogFragment = VideoCallFragment.newInstance(arguments!!)
dialogFragment?.let {
it.setCallListener(this@VideoStreamContainerService)
it.isCancelable = true
if (it.isAdded) {
it.dismiss()
} else {
it.show(transaction, "dialog")
}
}
} else if (!dialogFragment!!.isVisible) {
val transaction = supportFragmentManager.beginTransaction()
dialogFragment!!.show(transaction, "dialog")
} else {
// don't do anything
}
}
}
fun closeVideoCall(){
dialogFragment?.onCallClicked()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (intent != null && intent.extras != null) {
arguments = intent.extras
}
// Toast.makeText(this, "Service started by user.", Toast.LENGTH_LONG).show()
return START_STICKY
}
override fun onDestroy() {
super.onDestroy()
// Toast.makeText(this, "Service destroyed by user.", Toast.LENGTH_LONG).show()
}
inner class VideoStreamBinder : Binder() {
val service: VideoStreamContainerService
get() = this@VideoStreamContainerService
}
override fun onCallFinished(resultCode: Int, intent: Intent?) {
dialogFragment = null
videoCallResponseListener?.onCallFinished(resultCode, intent)
}
override fun errorHandle(message: String) {
dialogFragment = null
// Toast.makeText(this, message, Toast.LENGTH_LONG).show()
}
override fun minimizeVideoEvent(isMinimize: Boolean) {
videoCallResponseListener?.minimizeVideoEvent(isMinimize)
}
}

@ -6,7 +6,7 @@ interface VideoCallResponseListener {
fun onCallFinished(resultCode : Int, intent: Intent? = null)
fun errorHandle(message: String)
fun errorHandle(message: String){}
fun minimizeVideoEvent(isMinimize : Boolean)

@ -11,10 +11,12 @@ import android.graphics.Point
import android.graphics.drawable.ColorDrawable
import android.opengl.GLSurfaceView
import android.os.*
import android.util.DisplayMetrics
import android.util.Log
import android.view.*
import android.widget.*
import androidx.annotation.Nullable
import androidx.appcompat.app.AlertDialog
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.core.view.GestureDetectorCompat
@ -28,7 +30,7 @@ import com.hmg.hmgDr.ui.VideoCallContract.VideoCallView
import com.hmg.hmgDr.ui.VideoCallPresenterImpl
import com.hmg.hmgDr.ui.VideoCallResponseListener
import com.hmg.hmgDr.util.DynamicVideoRenderer
import com.hmg.hmgDr.util.ThumbnailCircleVideoRenderer
import com.hmg.hmgDr.util.ViewsUtil
import com.opentok.android.*
import com.opentok.android.PublisherKit.PublisherListener
import pub.devrel.easypermissions.AfterPermissionGranted
@ -37,7 +39,8 @@ import pub.devrel.easypermissions.EasyPermissions
import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks
import kotlin.math.ceil
// check this if it works to solve keyboard not work when dialog is opened
// https://stackoverflow.com/questions/55066977/how-to-prevent-custom-dialogfragment-from-hiding-keyboard-when-being-shown
class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.SessionListener,
PublisherListener,
SubscriberKit.VideoListener, VideoCallView {
@ -65,6 +68,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session
private lateinit var recordContainer: FrameLayout
private lateinit var thumbnail_container: FrameLayout
private lateinit var activity_clingo_video_call: RelativeLayout
private lateinit var mPublisherViewContainer: FrameLayout
private lateinit var mPublisherViewIcon: View
private lateinit var mSubscriberViewContainer: FrameLayout
@ -119,20 +123,47 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session
override fun onStart() {
super.onStart()
// val params: ViewGroup.LayoutParams = dialog!!.window!!.attributes
// params.width = WindowManager.LayoutParams.MATCH_PARENT
// params.height = WindowManager.LayoutParams.MATCH_PARENT
// dialog!!.window!!.attributes = params as WindowManager.LayoutParams
dialog?.window?.setLayout(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT
)
// val parentLayoutParam: FrameLayout.LayoutParams = /*parentView.layoutParams as*/ FrameLayout.LayoutParams(
// LinearLayout.LayoutParams.MATCH_PARENT,
// LinearLayout.LayoutParams.MATCH_PARENT
// )
// parentView.layoutParams = parentLayoutParam
}
override fun getTheme(): Int {
return R.style.dialogTheme
}
override fun onCreateDialog(@Nullable savedInstanceState: Bundle?): Dialog {
val dialog: Dialog = super.onCreateDialog(savedInstanceState)
override fun onCreateDialog(@Nullable savedInstanceState: Bundle?): Dialog {// FullScreenVideoTheme
val layoutInflater = activity!!.layoutInflater
this.parentView = onCreateView(layoutInflater, null)
// Add back button listener
val alertDialogBuilder: AlertDialog.Builder =
AlertDialog.Builder(requireContext(), R.style.dialogTheme)
// .setTitle(android.R.string.select_a_color)
.setView(this.parentView)
// .setPositiveButton(android.R.string.ok, { dialogInterface, i -> })
alertDialogBuilder.setOnKeyListener { _, keyCode, keyEvent ->
// getAction to make sure this doesn't double fire
if (keyCode == KeyEvent.KEYCODE_BACK && keyEvent.action == KeyEvent.ACTION_UP) {
videoCallResponseListener?.onBackHandle()
false // Capture onKey
} else true
// Don't capture
}
return alertDialogBuilder.create()
/*
val dialog: Dialog = super.onCreateDialog(savedInstanceState)
// Add back button listener
dialog.setOnKeyListener { _, keyCode, keyEvent ->
// getAction to make sure this doesn't double fire
@ -144,6 +175,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session
}
return dialog
*/
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -171,13 +203,16 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session
this.videoCallResponseListener = videoCallResponseListener
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
private fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?
): View {
val view = inflater.inflate(R.layout.activity_video_call, container, false)
parentView = inflater.inflate(R.layout.activity_video_call, container, false)
// val parentViewLayoutParam: ConstraintLayout.LayoutParams = ConstraintLayout.LayoutParams(
// ConstraintLayout.LayoutParams.MATCH_PARENT,
// ConstraintLayout.LayoutParams.MATCH_PARENT
// )
// parentView.layoutParams = parentViewLayoutParam
// Objects.requireNonNull(requireActivity().actionBar)!!.hide()
arguments?.run {
apiKey = getString("apiKey")
@ -189,7 +224,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session
if (sessionStatusModel != null)
isRecording = sessionStatusModel!!.isRecording
}
initUI(parentView)
initUI(view)
requestPermissions()
handleDragDialog()
@ -198,9 +233,15 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session
MyGestureListener({ showControlPanelTemporarily() }, { miniCircleDoubleTap() })
)
return parentView
return view
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return this.parentView
}
override fun onPause() {
super.onPause()
@ -230,10 +271,13 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session
@SuppressLint("ClickableViewAccessibility")
private fun initUI(view: View) {
videoCallContainer = view.findViewById(R.id.video_call_ll)
layoutName = view.findViewById(R.id.layout_name)
layoutMini = view.findViewById(R.id.layout_mini)
icMini = view.findViewById(R.id.ic_mini)
recordContainer = view.findViewById(R.id.record_container)
activity_clingo_video_call = view.findViewById(R.id.activity_clingo_video_call)
thumbnail_container = view.findViewById(R.id.thumbnail_container)
mPublisherViewContainer = view.findViewById(R.id.local_video_view_container)
mPublisherViewIcon = view.findViewById(R.id.local_video_view_icon)
@ -249,10 +293,12 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session
recordContainer.visibility = View.GONE
}
cmTimer = view.findViewById<Chronometer>(R.id.cmTimer)
cmTimer = view.findViewById(R.id.cmTimer)
cmTimer.format = "mm:ss"
cmTimer.onChronometerTickListener =
Chronometer.OnChronometerTickListener { arg0: Chronometer? ->
// val f: NumberFormat = DecimalFormat("00")
// f.format(minutes)
val minutes: Long
val seconds: Long
if (!resume) {
@ -264,8 +310,10 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session
seconds = (elapsedTime - cmTimer.base) / 1000 % 60
elapsedTime += 1000
}
arg0?.text = "$minutes:$seconds"
Log.d(VideoCallFragment.TAG, "onChronometerTick: $minutes : $seconds")
val format = "%1$02d:%2$02d" // two digits
arg0?.text = String.format(format, minutes, seconds)
Log.d(TAG, "onChronometerTick: $minutes : $seconds")
}
icMini.setOnClickListener {
@ -302,10 +350,9 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session
// progressBar=findViewById(R.id.progress_bar);
// progressBarTextView=findViewById(R.id.progress_bar_text);
// progressBar.setVisibility(View.GONE);
// hiddenButtons()
checkClientConnected()
handleVideoViewHeight(true)
if (appLang == "ar") {
progressBarLayout!!.layoutDirection = View.LAYOUT_DIRECTION_RTL
@ -517,9 +564,25 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session
}, 4000)
}
override fun onVideoDisabled(subscriberKit: SubscriberKit?, s: String?) {}
override fun onVideoDisabled(subscriberKit: SubscriberKit?, s: String?) {
Log.d(VideoCallFragment.TAG, "onVideoDisabled: Error ($s)")
// if (isCircle) {
// videoCallContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape)
// mSubscriberViewContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape)
// } else {
// videoCallContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_color))
// mSubscriberViewContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.remoteBackground))
// }
}
override fun onVideoEnabled(subscriberKit: SubscriberKit?, s: String?) {}
override fun onVideoEnabled(subscriberKit: SubscriberKit?, s: String?) {
Log.d(VideoCallFragment.TAG, "onVideoEnabled: Error ($s)")
// if (mSubscriber != null) {
// (mSubscriber!!.renderer as DynamicVideoRenderer).enableThumbnailCircle(isCircle)
// }
}
override fun onVideoDisableWarning(subscriberKit: SubscriberKit?) {}
@ -607,13 +670,12 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session
400,
600
)
recordContainer.visibility = View.VISIBLE
} else {
dialog?.window?.setLayout(
300,
300
)
recordContainer.visibility = View.GONE
}
isCircle = !isCircle
@ -640,7 +702,6 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session
)
)
}
}
if (isCircle) {
@ -650,6 +711,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session
controlPanel.visibility = View.VISIBLE
layoutMini.visibility = View.VISIBLE
}
handleVideoViewHeight(isFullScreen)
}
private fun onMinimizedClicked(view: View?) {
@ -658,11 +721,17 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session
400,
600
)
recordContainer.visibility = View.GONE
} else {
dialog?.window?.setLayout(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT
)
if (isRecording) {
recordContainer.visibility = View.VISIBLE
} else {
recordContainer.visibility = View.GONE
}
}
isFullScreen = !isFullScreen
@ -674,14 +743,15 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session
}
private fun setViewsVisibility() {
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 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 localPreviewMargin: Int =
context!!.resources.getDimension(R.dimen.local_preview_margin_top).toInt()
val localPreviewWidth: Int =
@ -777,6 +847,87 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session
btnMinimize.layoutParams = btnMinimizeLayoutParam
mCallBtn.layoutParams = mCallBtnLayoutParam
handleVideoViewHeight(isFullScreen)
}
private fun handleVideoViewHeight(isFullScreen: Boolean) {
val layoutNameParam: ConstraintLayout.LayoutParams =
layoutName.layoutParams as ConstraintLayout.LayoutParams
val layoutMiniParam: ConstraintLayout.LayoutParams =
layoutMini.layoutParams as ConstraintLayout.LayoutParams
val controlPanelParam: ConstraintLayout.LayoutParams =
controlPanel.layoutParams as ConstraintLayout.LayoutParams
val layoutNameHeight: Int =
context!!.resources.getDimension(R.dimen.layout_name_height).toInt()
val layoutMiniHeight: Int =
context!!.resources.getDimension(R.dimen.layout_mini_height).toInt()
val panelHeight: Int = context!!.resources.getDimension(R.dimen.layout_panel_height).toInt()
val panelHeightSmall: Int =
context!!.resources.getDimension(R.dimen.layout_panel_height_small).toInt()
val panelPadding: Int =
context!!.resources.getDimension(R.dimen.padding_space_big).toInt()
val panelPaddingMedium: Int =
context!!.resources.getDimension(R.dimen.padding_space_medium).toInt()
val temp = getStatusBarHeight() / 2
val screenWidth: Float
val screenHeight: Float
if (isFullScreen) {
screenWidth = ViewsUtil.getWidthDp(requireContext())
screenHeight = ViewsUtil.getHeightDp(requireContext())
layoutNameParam.height = layoutNameHeight + temp
layoutMiniParam.height = 0
controlPanelParam.height = panelHeight + temp
controlPanel.setPadding(panelPadding, panelPadding, panelPadding, panelPadding)
} else {
if (isCircle) {
screenWidth = 300F
screenHeight = 300F
layoutNameParam.height = 0
layoutMiniParam.height = 0
controlPanelParam.height = 0
} else {
screenWidth = 400F
screenHeight = 600F
layoutNameParam.height = 0
layoutMiniParam.height = layoutMiniHeight
controlPanelParam.height = panelHeightSmall
}
controlPanel.setPadding(
panelPaddingMedium,
panelPaddingMedium,
panelPaddingMedium,
panelPaddingMedium
)
}
layoutName.layoutParams = layoutNameParam
layoutMini.layoutParams = layoutMiniParam
controlPanel.layoutParams = controlPanelParam
var videoStreamHeight =
screenHeight - controlPanelParam.height - layoutNameParam.height - layoutMiniParam.height
if (isFullScreen) {
// videoStreamHeight -= getStatusBarHeight() / 2
}
val callLayoutParam: ConstraintLayout.LayoutParams =
activity_clingo_video_call.layoutParams as ConstraintLayout.LayoutParams
callLayoutParam.height = videoStreamHeight.toInt()
callLayoutParam.width = screenWidth.toInt()
}
private fun onCameraClicked(view: View?) {
@ -784,7 +935,15 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session
isCameraClicked = !isCameraClicked
mPublisher!!.publishVideo = !isCameraClicked
val res = if (isCameraClicked) R.drawable.video_disabled else R.drawable.video_enabled
mCameraBtn!!.setImageResource(res)
mCameraBtn.setImageResource(res)
// if (!isCameraClicked) {
// videoCallContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape)
// mSubscriberViewContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape)
// } else {
// videoCallContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_color))
// mSubscriberViewContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.remoteBackground))
// }
}
}
@ -910,7 +1069,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session
mParams.x =
(szWindow.x - current_x_cord * current_x_cord * step - videoCallContainer.width).toInt()
dialog!!.window!!.attributes = mParams
dialog?.window?.attributes = mParams
}
override fun onFinish() {

@ -0,0 +1,33 @@
package com.hmg.hmgDr.util
import android.content.Context
import android.util.DisplayMetrics
object ViewsUtil {
/**
* @param context
* @return the Screen height in DP
*/
fun getHeightDp(context: Context, isInDp: Boolean = false): Float {
val displayMetrics: DisplayMetrics = context.resources.displayMetrics
return if (isInDp) {
displayMetrics.heightPixels / displayMetrics.density
} else {
displayMetrics.heightPixels.toFloat()
}
}
/**
* @param context
* @return the screnn width in dp
*/
fun getWidthDp(context: Context, isInDp: Boolean = false): Float {
val displayMetrics: DisplayMetrics = context.resources.displayMetrics
return if (isInDp) {
displayMetrics.widthPixels / displayMetrics.density
} else {
displayMetrics.widthPixels.toFloat()
}
}
}

@ -11,7 +11,7 @@
<RelativeLayout
android:id="@+id/layout_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="@dimen/layout_name_height"
android:padding="@dimen/padding_space_medium"
app:layout_constraintTop_toTopOf="parent">
@ -47,38 +47,39 @@
</RelativeLayout>
<RelativeLayout
android:id="@+id/layout_mini"
android:layout_width="match_parent"
android:layout_height="@dimen/layout_mini_height"
android:background="@color/remoteBackground"
app:layout_constraintTop_toBottomOf="@+id/layout_name"
android:alpha="0.5"
android:visibility="gone"
tools:visibility="visible">
<ImageButton
android:id="@+id/ic_mini"
style="@style/Widget.MaterialComponents.Button.Icon"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_margin="@dimen/padding_space_medium"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:background="@null"
android:src="@drawable/ic_mini" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/activity_clingo_video_call"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/control_panel"
app:layout_constraintTop_toBottomOf="@+id/layout_name">
<RelativeLayout
android:id="@+id/layout_mini"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/remoteBackground"
android:alpha="0.5"
android:visibility="gone">
<ImageButton
android:id="@+id/ic_mini"
style="@style/Widget.MaterialComponents.Button.Icon"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_margin="@dimen/padding_space_medium"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:background="@null"
android:src="@drawable/ic_mini" />
</RelativeLayout>
app:layout_constraintTop_toBottomOf="@+id/layout_mini">
<FrameLayout
android:id="@+id/remote_video_view_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/layout_mini"
android:background="@color/remoteBackground">
<ImageView
@ -140,7 +141,7 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/control_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="@dimen/layout_panel_height"
android:padding="@dimen/padding_space_big"
app:layout_constraintBottom_toBottomOf="parent">
@ -148,7 +149,7 @@
android:id="@+id/btn_call"
android:layout_width="@dimen/video_icon_size"
android:layout_height="@dimen/video_icon_size"
android:scaleType="centerCrop"
android:scaleType="centerInside"
android:src="@drawable/call"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
@ -158,7 +159,7 @@
android:id="@+id/btn_minimize"
android:layout_width="@dimen/video_icon_size"
android:layout_height="@dimen/video_icon_size"
android:scaleType="centerCrop"
android:scaleType="centerInside"
android:src="@drawable/reducing"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
@ -169,7 +170,7 @@
android:layout_width="@dimen/video_icon_size"
android:layout_height="@dimen/video_icon_size"
android:layout_marginStart="@dimen/padding_space_medium"
android:scaleType="centerCrop"
android:scaleType="centerInside"
android:src="@drawable/video_enabled"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/btn_minimize"
@ -180,7 +181,7 @@
android:layout_width="@dimen/video_icon_size"
android:layout_height="@dimen/video_icon_size"
android:layout_marginStart="@dimen/padding_space_medium"
android:scaleType="centerCrop"
android:scaleType="centerInside"
android:src="@drawable/mic_enabled"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/btn_camera"
@ -191,7 +192,7 @@
android:layout_width="@dimen/video_icon_size"
android:layout_height="@dimen/video_icon_size"
android:layout_marginStart="@dimen/padding_space_medium"
android:scaleType="centerCrop"
android:scaleType="centerInside"
android:src="@drawable/camera_back"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/btn_mic"
@ -202,7 +203,7 @@
android:layout_width="@dimen/video_icon_size"
android:layout_height="@dimen/video_icon_size"
android:layout_marginStart="@dimen/padding_space_medium"
android:scaleType="centerCrop"
android:scaleType="centerInside"
android:src="@drawable/audio_enabled"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"

@ -9,7 +9,7 @@
<!-- buttons -->
<dimen name="call_button_size">60dp</dimen>
<dimen name="other_button_size">54dp</dimen>
<dimen name="video_icon_size">52dp</dimen>
<dimen name="video_icon_size">48dp</dimen>
<dimen name="video_icon_size_small">24dp</dimen>
<!-- buttons -->
@ -33,9 +33,15 @@
<!-- padding/margin-->
<dimen name="padding_space_small">4dp</dimen>
<dimen name="padding_space_medium">8sp</dimen>
<dimen name="padding_space_medium">8dp</dimen>
<dimen name="padding_space_big">16dp</dimen>
<dimen name="padding_space_big_2">24dp</dimen>
<dimen name="layout_mini_height">36dp</dimen>
<dimen name="layout_name_height">60dp</dimen>
<dimen name="layout_panel_height">80dp</dimen>
<dimen name="layout_panel_height_small">40dp</dimen>
</resources>

@ -1,10 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<style name="AppTheme" parent="Theme.AppCompat">
</style>
@ -25,12 +27,17 @@
<!-- turn off any drawable used to draw a frame on the window -->
<item name="android:windowIsFloating">true</item>
<!-- float the window so it does not fill the screen -->
<item name="android:windowNoTitle">true</item>
<item name="windowNoTitle">true</item>
<item name="windowActionBar">true</item>
<item name="android:windowFullscreen">false</item>
<!-- remove the title bar we make our own-->
<item name="android:windowContentOverlay">@null</item>
<!-- remove the shadow from under the title bar -->
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">match_parent</item>
<!-- smooth animation-->
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
</style>
</resources>

@ -22,20 +22,19 @@ class VideoCallService extends BaseService {
LiveCarePatientServices _liveCarePatientServices =
locator<LiveCarePatientServices>();
openVideo(
StartCallRes startModel,
PatiantInformtion patientModel,
bool isRecording,
VoidCallback onCallConnected,
VoidCallback onCallDisconnected) async {
openVideo(StartCallRes startModel, PatiantInformtion patientModel,
bool isRecording,VoidCallback onCallConnected, VoidCallback onCallDisconnected) async {
this.startCallRes = startModel;
this.patient = patientModel;
DoctorProfileModel doctorProfile =
await getDoctorProfile(isGetProfile: true);
await VideoChannel.openVideoCallScreen(
kToken: startCallRes.openTokenID,//"T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==",
kSessionId: startCallRes.openSessionID,// "1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg",
kApiKey: '46209962' ,// '47247954'
kToken: startCallRes.openTokenID,
kSessionId: startCallRes.openSessionID,
kApiKey:'46209962',
// kToken: "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==",
// kSessionId: "1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg",
// kApiKey:'47247954',
vcId: patient.vcId,
isRecording: isRecording,
patientName: patient.fullName ??

@ -255,7 +255,7 @@ class AuthenticationViewModel extends BaseViewModel {
/// add  token to shared preferences in case of send activation code is success
setDataAfterSendActivationSuccess(SendActivationCodeForDoctorAppResponseModel sendActivationCodeForDoctorAppResponseModel) {
print("VerificationCode : " + sendActivationCodeForDoctorAppResponseModel.verificationCode);
// DrAppToastMsg.showSuccesToast("VerificationCode : " + sendActivationCodeForDoctorAppResponseModel.verificationCode);
// DrAppToastMsg.showSuccesToast("_VerificationCode_ : " + sendActivationCodeForDoctorAppResponseModel.verificationCode);
sharedPref.setString(VIDA_AUTH_TOKEN_ID,
sendActivationCodeForDoctorAppResponseModel.vidaAuthTokenID);
sharedPref.setString(VIDA_REFRESH_TOKEN_ID,

@ -2,19 +2,23 @@ import 'dart:async';
import 'package:doctor_app_flutter/config/size_config.dart';
import 'package:doctor_app_flutter/core/enum/viewstate.dart';
import 'package:doctor_app_flutter/core/service/VideoCallService.dart';
import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart';
import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart';
import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart';
import 'package:doctor_app_flutter/screens/base/base_view.dart';
import 'package:doctor_app_flutter/util/NotificationPermissionUtils.dart';
import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
import 'package:doctor_app_flutter/widgets/patients/patient_card/PatientCard.dart';
import 'package:doctor_app_flutter/widgets/shared/app_loader_widget.dart';
import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart';
import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart';
import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart';
import 'package:doctor_app_flutter/widgets/shared/errors/error_message.dart';
import 'package:doctor_app_flutter/widgets/shared/text_fields/app_text_form_field.dart';
import 'package:flutter/material.dart';
import '../../locator.dart';
import '../../routes.dart';
class LiveCarePatientScreen extends StatefulWidget {
@ -169,9 +173,31 @@ class _LiveCarePatientScreenState extends State<LiveCarePatientScreen> {
child: AppLoaderWidget(
containerColor: Colors.transparent,
)),
// AppButton(
// fontWeight: FontWeight.w700,
// color:Colors.green[600],
// title: TranslationBase.of(context).initiateCall,
// disabled: model.state == ViewState.BusyLocal,
// onPressed: () async {
// AppPermissionsUtils.requestVideoCallPermission(context: context,onTapGrant: (){
// locator<VideoCallService>().openVideo(model.startCallRes, PatiantInformtion(
// vcId: 454353,
// fullName: "test mosa"
// ), callConnected, callDisconnected);
// });
//
// },
// ),
],
),
),
);
}
callConnected(){
}
callDisconnected(){
}
}

@ -301,6 +301,17 @@ class _PatientProfileScreenState extends State<PatientProfileScreen> with Single
: TranslationBase.of(context).initiateCall,
disabled: isCallStarted || model.state == ViewState.BusyLocal,
onPressed: () async {
// AppPermissionsUtils
// .requestVideoCallPermission(
// context: context,
// onTapGrant: () {
// locator<VideoCallService>()
// .openVideo(
// model.startCallRes,
// patient,
// false, callConnected, // model.startCallRes.isRecording
// callDisconnected);
// });
if (isCallFinished) {
Navigator.push(
context,
@ -338,7 +349,8 @@ class _PatientProfileScreenState extends State<PatientProfileScreen> with Single
.openVideo(
model.startCallRes,
patient,
model.startCallRes.isRecording, callConnected,
/*model.startCallRes != null ? model.startCallRes.isRecording : */ true
, callConnected,
callDisconnected);
});
}

Loading…
Cancel
Save