diff --git a/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt index f043c772..db778d46 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt @@ -6,7 +6,7 @@ import android.Manifest.permission.WRITE_EXTERNAL_STORAGE import android.app.Activity.RESULT_OK import android.content.Context import android.content.Intent -import android.content.res.Configuration.ORIENTATION_PORTRAIT +import android.content.res.Configuration import android.media.AudioManager import android.net.Uri import android.os.Build @@ -101,8 +101,9 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.SoftwareKeyboardController +import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.TextStyle @@ -152,8 +153,6 @@ private var password = mutableStateOf("") private val selectItems = mutableStateOf(listOf()) private val selectItemAction = mutableStateOf<(Int) -> Unit>({ _ -> run {} }) private val showSelectItemDialog = mutableStateOf(false) - -private var keyboardController: SoftwareKeyboardController? = null private var callRunnable: Runnable? = null private var callHandler: Handler = Handler(Looper.getMainLooper()) private var audioModeChangedListener: AudioManager.OnModeChangedListener? = null @@ -186,6 +185,21 @@ private fun MainScreen( ) { val ctx = LocalContext.current val lifecycleOwner = LocalLifecycleOwner.current + val configuration = LocalConfiguration.current + val keyboardController = LocalSoftwareKeyboardController.current + + val ua = uas.value.find { it.account.aor == viewModel.selectedAor.value } + val call = ua?.currentCall() + + LaunchedEffect(viewModel.showKeyboard.value) { + if (viewModel.showKeyboard.value > 0) + keyboardController?.show() + } + + LaunchedEffect(viewModel.hideKeyboard.value) { + if (viewModel.hideKeyboard.value > 0) + keyboardController?.hide() + } DisposableEffect(lifecycleOwner) { val observer = LifecycleEventObserver { _, event -> @@ -344,6 +358,18 @@ private fun MainScreen( } } + LaunchedEffect(key1 = call?.status, key2 = configuration.orientation) { + val isConnected = call != null && call.status == "connected" && !call.held + if (isConnected) { + if (configuration.orientation == Configuration.ORIENTATION_PORTRAIT) { + focusDtmf.value = true + keyboardController?.show() + } + else + keyboardController?.hide() + } + } + if (showPasswordDialog.value) PasswordDialog( ctx = ctx, @@ -1429,7 +1455,7 @@ private fun CallRow(ctx: Context, viewModel: ViewModel) { if (showDialog.value) BasicAlertDialog( onDismissRequest = { - keyboardController?.hide() + viewModel.requestHideKeyboard() showDialog.value = false showTransferDialog = false } @@ -1593,7 +1619,7 @@ private fun CallRow(ctx: Context, viewModel: ViewModel) { ) { TextButton( onClick = { - keyboardController?.hide() + viewModel.requestHideKeyboard() showDialog.value = false showTransferDialog = false }, @@ -1635,7 +1661,7 @@ private fun CallRow(ctx: Context, viewModel: ViewModel) { !blindChecked.value ) } - keyboardController?.hide() + viewModel.requestHideKeyboard() showDialog.value = false showTransferDialog = false } @@ -1998,7 +2024,6 @@ private fun showCall(ctx: Context, viewModel: ViewModel, ua: UserAgent?, showCal callUri.value = "" callUriLabel.value = ctx.getString(R.string.outgoing_call_to_dots) callUriEnabled.value = true - keyboardController?.hide() showCallTimer.value = false securityIcon.intValue = -1 showHangupButton.value = false @@ -2019,6 +2044,19 @@ private fun showCall(ctx: Context, viewModel: ViewModel, ua: UserAgent?, showCal } else { pullToRefreshEnabled.value = false callUriEnabled.value = false + val isLandscape = ctx.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE + if (isLandscape || call.held || call.status != "connected") { + focusDtmf.value = false + dtmfEnabled.value = !call.held + Handler(Looper.getMainLooper()).postDelayed({ + viewModel.requestHideKeyboard() + }, 25) + } + else { + dtmfEnabled.value = true + focusDtmf.value = true + viewModel.requestShowKeyboard() + } when (call.status) { "outgoing", "transferring", "answered" -> { callUriLabel.value = if (call.status == "answered") @@ -2090,16 +2128,6 @@ private fun showCall(ctx: Context, viewModel: ViewModel, ua: UserAgent?, showCal Handler(Looper.getMainLooper()).postDelayed({ showOnHoldNotice.value = call.held }, 100) - if (call.held) { - keyboardController?.hide() - dtmfEnabled.value = false - focusDtmf.value = false - } else { - dtmfEnabled.value = true - focusDtmf.value = true - if (ctx.resources.configuration.orientation == ORIENTATION_PORTRAIT) - keyboardController?.show() - } } } } diff --git a/app/src/main/kotlin/com/tutpro/baresip/ViewModel.kt b/app/src/main/kotlin/com/tutpro/baresip/ViewModel.kt index 43e939f2..7ae457a5 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/ViewModel.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/ViewModel.kt @@ -45,6 +45,20 @@ class ViewModel(application: Application) : AndroidViewModel(application) { _aorPeerMessage.value = newMap } + private val _showKeyboard = mutableStateOf(0) + val showKeyboard: State = _showKeyboard + + fun requestShowKeyboard() { + _showKeyboard.value++ + } + + private val _hideKeyboard = mutableStateOf(0) + val hideKeyboard: State = _hideKeyboard + + fun requestHideKeyboard() { + _hideKeyboard.value++ + } + private val _speakerIcon = MutableStateFlow(R.drawable.speaker_off) val speakerIcon: StateFlow = _speakerIcon.asStateFlow()