Created AlertDialog composable and used it in calls activity

This commit is contained in:
Juha Heinanen
2025-04-11 14:49:55 +03:00
parent ce3039ea83
commit e7823ffab1
2 changed files with 244 additions and 159 deletions

View File

@ -2,11 +2,9 @@ package com.tutpro.baresip
import android.annotation.SuppressLint
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.graphics.BitmapFactory
import android.os.Bundle
import android.os.SystemClock
import androidx.activity.ComponentActivity
import androidx.activity.OnBackPressedCallback
import androidx.activity.compose.setContent
@ -61,7 +59,7 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import coil.compose.AsyncImage
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.tutpro.baresip.CustomElements.AlertDialog
import com.tutpro.baresip.CustomElements.ImageAvatar
import com.tutpro.baresip.CustomElements.TextAvatar
import com.tutpro.baresip.CustomElements.verticalScrollbar
@ -71,7 +69,6 @@ class CallsActivity : ComponentActivity() {
private lateinit var account: Account
private var aor = ""
private var lastClick: Long = 0
private val onBackPressedCallback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
@ -136,6 +133,18 @@ class CallsActivity : ComponentActivity() {
val disable = String.format(getString(R.string.disable_history))
val enable = String.format(getString(R.string.enable_history))
val openDialog = remember { mutableStateOf(false) }
val positiveAction = remember { mutableStateOf({}) }
AlertDialog(
openDialog = openDialog,
title = getString(R.string.confirmation),
message = String.format(getString(R.string.delete_history_alert), aor.substringAfter(":")),
positiveButtonText = getString(R.string.delete),
negativeButtonText = getString(R.string.cancel),
onPositiveClicked = positiveAction.value,
)
TopAppBar(
title = {
Text(
@ -172,29 +181,14 @@ class CallsActivity : ComponentActivity() {
onItemClick = { selectedItem ->
expanded = false
when (selectedItem) {
delete ->
with(
MaterialAlertDialogBuilder(this@CallsActivity, R.style.AlertDialogTheme)
) {
setTitle(R.string.confirmation)
setMessage(
String.format(
getString(R.string.delete_history_alert),
aor.substringAfter(":")
)
)
setPositiveButton(delete) { dialog, _ ->
CallHistoryNew.clear(aor)
CallHistoryNew.save()
uaHistory.value = emptyList()
dialog.dismiss()
}
setNeutralButton(getText(R.string.cancel)) { dialog, _ ->
dialog.dismiss()
}
show()
delete -> {
positiveAction.value = {
CallHistoryNew.clear(aor)
CallHistoryNew.save()
uaHistory.value = emptyList()
}
openDialog.value = true
}
disable, enable -> {
account.callHistory = !account.callHistory
AccountsActivity.saveAccounts()
@ -242,6 +236,25 @@ class CallsActivity : ComponentActivity() {
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun Calls(ctx: Context, account: Account) {
val openDialog = remember { mutableStateOf(false) }
val message = remember { mutableStateOf("") }
val positiveButtonText = remember { mutableStateOf("") }
val positiveAction = remember { mutableStateOf({}) }
val neutralButtonText = remember { mutableStateOf("") }
val neutralAction = remember { mutableStateOf({}) }
AlertDialog(
openDialog = openDialog,
title = getString(R.string.confirmation),
message = message.value,
positiveButtonText = positiveButtonText.value,
onPositiveClicked = positiveAction.value,
neutralButtonText = neutralButtonText.value,
onNeutralClicked = neutralAction.value,
negativeButtonText = getString(R.string.cancel)
)
val lazyListState = rememberLazyListState()
LazyColumn(
modifier = Modifier
@ -268,10 +281,76 @@ class CallsActivity : ComponentActivity() {
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.combinedClickable(
onClick = {
callMessageClick(ctx, callRow)
val peerUri = callRow.peerUri
val peerName = Utils.friendlyUri(ctx, peerUri, account)
message.value = String.format(ctx.getString(R.string.contact_action_question), peerName)
positiveButtonText.value = ctx.getString(R.string.call)
positiveAction.value = {
BaresipService.activities.remove("calls,$aor")
MainActivity.activityAor = aor
returnResult()
val i = Intent(this@CallsActivity, MainActivity::class.java)
i.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP
i.putExtra("action", "call")
i.putExtra("uap", UserAgent.ofAor(aor)!!.uap)
i.putExtra("peer", peerUri)
startActivity(i)
}
neutralButtonText.value = ctx.getString(R.string.send_message)
neutralAction.value = {
BaresipService.activities.remove("calls,$aor")
MainActivity.activityAor = aor
returnResult()
val i = Intent(this@CallsActivity, MainActivity::class.java)
i.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP
i.putExtra("action", "message")
i.putExtra("uap", UserAgent.ofAor(aor)!!.uap)
i.putExtra("peer", peerUri)
startActivity(i)
}
openDialog.value = true
},
onLongClick = {
callMessageLongClick(ctx, callRow)
val peerUri = callRow.peerUri
val peerName = Utils.friendlyUri(ctx, peerUri, account)
val callText: String = if (callRow.details.size > 1)
getString(R.string.calls_calls)
else
getString(R.string.calls_call)
val contactExists = Contact.nameExists(peerName, BaresipService.contacts, false)
if (contactExists) {
message.value = String.format(
getString(R.string.calls_delete_question),
peerName, callText
)
positiveButtonText.value = getString(R.string.delete)
positiveAction.value = {
removeFromHistory(callRow)
CallHistoryNew.save()
}
neutralButtonText.value = ""
}
else {
message.value = String.format(
getString(R.string.calls_add_delete_question),
peerName, callText
)
positiveButtonText.value = getString(R.string.add_contact)
positiveAction.value = {
val i = Intent(ctx, BaresipContactActivity::class.java)
val b = Bundle()
b.putBoolean("new", true)
b.putString("uri", callRow.peerUri)
i.putExtras(b)
ctx.startActivity(i)
}
neutralButtonText.value = getString(R.string.delete)
neutralAction.value = {
removeFromHistory(callRow)
CallHistoryNew.save()
}
}
openDialog.value = true
}
)
) {
@ -291,7 +370,9 @@ class CallsActivity : ComponentActivity() {
model = thumbNailUri,
contentDescription = "Avatar",
contentScale = ContentScale.Crop,
modifier = Modifier.size(36.dp).clip(CircleShape),
modifier = Modifier
.size(36.dp)
.clip(CircleShape),
)
else
TextAvatar(contact.name, contact.color)
@ -334,7 +415,9 @@ class CallsActivity : ComponentActivity() {
LocalCustomColors.current.accent
else
LocalCustomColors.current.itemText,
modifier = Modifier.padding(end = 16.dp).width(64.dp)
modifier = Modifier
.padding(end = 16.dp)
.width(64.dp)
.clickable(onClick = {
val i = Intent(ctx, CallDetailsActivity::class.java)
val b = Bundle()
@ -351,130 +434,6 @@ class CallsActivity : ComponentActivity() {
}
}
private fun callMessageClick(ctx: Context, callRow: CallRow) {
val peerUri = callRow.peerUri
val peerName = Utils.friendlyUri(ctx, peerUri, account)
val dialogClickListener = DialogInterface.OnClickListener { _, which ->
when (which) {
DialogInterface.BUTTON_POSITIVE, DialogInterface.BUTTON_NEGATIVE -> {
BaresipService.activities.remove("calls,$aor")
MainActivity.activityAor = aor
returnResult()
val i = Intent(this@CallsActivity, MainActivity::class.java)
i.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP
if (which == DialogInterface.BUTTON_NEGATIVE)
i.putExtra("action", "call")
else
i.putExtra("action", "message")
i.putExtra("uap", UserAgent.ofAor(aor)!!.uap)
i.putExtra("peer", peerUri)
startActivity(i)
}
DialogInterface.BUTTON_NEUTRAL -> {
}
}
}
if (SystemClock.elapsedRealtime() - lastClick > 1000) {
lastClick = SystemClock.elapsedRealtime()
with(
MaterialAlertDialogBuilder(ctx, R.style.AlertDialogTheme)
) {
setTitle(R.string.confirmation)
setMessage(
String.format(ctx.getString(R.string.contact_action_question), peerName)
)
setNeutralButton(
ctx.getText(R.string.cancel),
dialogClickListener
)
setNegativeButton(
ctx.getText(R.string.call),
dialogClickListener
)
setPositiveButton(
ctx.getText(R.string.send_message),
dialogClickListener
)
show()
}
}
}
private fun callMessageLongClick(ctx: Context, callRow: CallRow) {
val peerUri = callRow.peerUri
val peerName = Utils.friendlyUri(ctx, peerUri, account)
val dialogClickListener =
DialogInterface.OnClickListener { _, which ->
when (which) {
DialogInterface.BUTTON_NEGATIVE -> {
val i = Intent(ctx, BaresipContactActivity::class.java)
val b = Bundle()
b.putBoolean("new", true)
b.putString("uri", peerUri)
i.putExtras(b)
ctx.startActivity(i)
}
DialogInterface.BUTTON_POSITIVE -> {
removeFromHistory(callRow)
CallHistoryNew.save()
}
DialogInterface.BUTTON_NEUTRAL -> {
}
}
}
val callText: String = if (callRow.details.size > 1)
getString(R.string.calls_calls)
else
getString(R.string.calls_call)
val builder = MaterialAlertDialogBuilder(
this@CallsActivity,
R.style.AlertDialogTheme
)
if (!Contact.nameExists(peerName, BaresipService.contacts, false))
with(builder) {
setTitle(R.string.confirmation)
setMessage(
String.format(
getString(R.string.calls_add_delete_question),
peerName, callText
)
)
setNeutralButton(
getString(R.string.cancel),
dialogClickListener
)
setPositiveButton(
getString(R.string.delete),
dialogClickListener
)
setNegativeButton(
getString(R.string.add_contact),
dialogClickListener
)
show()
}
else
with(builder) {
setTitle(R.string.confirmation)
setMessage(
String.format(
getString(R.string.calls_delete_question),
peerName, callText
)
)
setNeutralButton(
getString(R.string.cancel),
dialogClickListener
)
setPositiveButton(
getString(R.string.delete),
dialogClickListener
)
show()
}
}
private fun goBack() {
BaresipService.activities.remove("calls,$aor")
returnResult()

View File

@ -19,16 +19,19 @@ import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.AlertDialogDefaults
import androidx.compose.material3.BasicAlertDialog
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Card
import androidx.compose.material3.Checkbox
import androidx.compose.material3.CheckboxDefaults
import androidx.compose.material3.DropdownMenu
@ -120,11 +123,13 @@ object CustomElements {
Surface(
shape = shape,
color = color,
modifier = modifier.pointerInput(Unit) {
detectTapGestures(
onTap = { onClick() },
onLongPress = { onLongClick() },
) }
modifier = modifier
.pointerInput(Unit) {
detectTapGestures(
onTap = { onClick() },
onLongPress = { onLongClick() },
)
}
.then(modifier),
) {
Row(
@ -310,6 +315,126 @@ object CustomElements {
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AlertDialog(
openDialog: MutableState<Boolean>,
title: String,
message: String,
positiveButtonText: String,
onPositiveClicked: () -> Unit,
negativeButtonText: String = "",
onNegativeClicked: () -> Unit = {},
neutralButtonText: String = "",
onNeutralClicked: () -> Unit = {}
) {
if (openDialog.value) {
BasicAlertDialog(
onDismissRequest = {
openDialog.value = false
},
content = {
Card(
modifier = Modifier.fillMaxWidth()
.padding(top = 16.dp, start = 16.dp, end = 16.dp, bottom = 0.dp),
shape = RoundedCornerShape(16.dp),
) {
Column(modifier = Modifier.padding(16.dp)) {
androidx.compose.material3.Text(
text = title,
fontSize = 20.sp,
color = LocalCustomColors.current.alert,
)
Spacer(modifier = Modifier.height(16.dp))
androidx.compose.material3.Text(
text = message,
fontSize = 16.sp,
color = LocalCustomColors.current.itemText,
)
Spacer(modifier = Modifier.height(16.dp))
if (negativeButtonText.isNotEmpty() && neutralButtonText.isNotEmpty()) {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.End
) {
TextButton(onClick = {
onPositiveClicked()
openDialog.value = false
}) {
androidx.compose.material3.Text(
text = positiveButtonText.uppercase(),
fontSize = 14.sp,
color = LocalCustomColors.current.alert,
)
}
TextButton(onClick = {
onNeutralClicked()
openDialog.value = false
}) {
androidx.compose.material3.Text(
text = neutralButtonText.uppercase(),
fontSize = 14.sp,
color = LocalCustomColors.current.alert
)
}
TextButton(onClick = {
onNegativeClicked()
openDialog.value = false
}) {
androidx.compose.material3.Text(
text = negativeButtonText.uppercase(),
fontSize = 14.sp,
color = LocalCustomColors.current.gray
)
}
}
}
else {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.End
) {
if (negativeButtonText.isNotEmpty())
TextButton(onClick = {
onNegativeClicked()
openDialog.value = false
}) {
androidx.compose.material3.Text(
text = negativeButtonText.uppercase(),
fontSize = 14.sp,
color = LocalCustomColors.current.gray
)
}
if (neutralButtonText.isNotEmpty())
TextButton(onClick = {
onNeutralClicked()
openDialog.value = false
}) {
androidx.compose.material3.Text(
text = neutralButtonText.uppercase(),
fontSize = 14.sp,
color = LocalCustomColors.current.alert
)
}
TextButton(onClick = {
onPositiveClicked()
openDialog.value = false
}) {
androidx.compose.material3.Text(
text = positiveButtonText.uppercase(),
fontSize = 14.sp,
color = LocalCustomColors.current.alert,
)
}
}
}
}
}
}
)
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PasswordDialog(
@ -448,4 +573,5 @@ object CustomElements {
}
}
}
}