From 07b4f03f8bf1ca35842f45c3eb90195b955afdc9 Mon Sep 17 00:00:00 2001 From: Juha Heinanen Date: Thu, 5 Feb 2026 21:40:43 +0200 Subject: [PATCH] Migrated alert dialogs to Material desing style --- .../com/tutpro/baresip/AccountScreen.kt | 2 +- .../com/tutpro/baresip/AccountsScreen.kt | 12 +- .../kotlin/com/tutpro/baresip/AudioScreen.kt | 2 +- .../tutpro/baresip/BaresipContactScreen.kt | 2 +- .../com/tutpro/baresip/BlockedScreen.kt | 28 ++--- .../com/tutpro/baresip/CallDetailsScreen.kt | 24 ++-- .../kotlin/com/tutpro/baresip/CallsScreen.kt | 50 ++++---- .../kotlin/com/tutpro/baresip/ChatScreen.kt | 34 +++--- .../kotlin/com/tutpro/baresip/ChatsScreen.kt | 48 ++++---- .../kotlin/com/tutpro/baresip/CodecsScreen.kt | 15 --- .../com/tutpro/baresip/ContactsScreen.kt | 38 +++--- .../com/tutpro/baresip/CustomElements.kt | 108 ++++++++++-------- .../kotlin/com/tutpro/baresip/MainScreen.kt | 104 +++++++++-------- .../com/tutpro/baresip/SettingsScreen.kt | 93 ++++++++------- 14 files changed, 277 insertions(+), 283 deletions(-) diff --git a/app/src/main/kotlin/com/tutpro/baresip/AccountScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/AccountScreen.kt index 3b3707de..87ebfd07 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/AccountScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/AccountScreen.kt @@ -1198,7 +1198,7 @@ private fun AccountContent( showDialog = showAlert, title = alertTitle.value, message = alertMessage.value, - positiveButtonText = stringResource(R.string.ok), + lastButtonText = stringResource(R.string.ok), ) } diff --git a/app/src/main/kotlin/com/tutpro/baresip/AccountsScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/AccountsScreen.kt index 0a41601c..b97dabac 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/AccountsScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/AccountsScreen.kt @@ -116,15 +116,15 @@ fun AccountsContent(contentPadding: PaddingValues, navController: NavController) val showDialog = remember { mutableStateOf(false) } val message = remember { mutableStateOf("") } - val positiveAction = remember { mutableStateOf({}) } + val lastAction = remember { mutableStateOf({}) } AlertDialog( showDialog = showDialog, title = stringResource(R.string.confirmation), message = message.value, - positiveButtonText = stringResource(R.string.delete), - onPositiveClicked = positiveAction.value, - negativeButtonText = stringResource(R.string.cancel), + firstButtonText = stringResource(R.string.cancel), + lastButtonText = stringResource(R.string.delete), + onLastClicked = lastAction.value, ) val showAccounts = remember { mutableStateOf(true) } @@ -169,7 +169,7 @@ fun AccountsContent(contentPadding: PaddingValues, navController: NavController) modifier = Modifier.padding(end = 8.dp), onClick = { message.value = String.format(deleteAccountMessage, text) - positiveAction.value = { + lastAction.value = { CallHistoryNew.clear(aor) Message.clearMessagesOfAor(aor) ua.remove() @@ -206,7 +206,7 @@ fun NewAccount(navController: NavController) { showDialog = showAlert, title = alertTitle.value, message = alertMessage.value, - positiveButtonText = stringResource(R.string.ok), + lastButtonText = stringResource(R.string.ok), ) fun createNew(ctx: Context, newAor: String): Account? { diff --git a/app/src/main/kotlin/com/tutpro/baresip/AudioScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/AudioScreen.kt index 458e1235..7d4f6ebc 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/AudioScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/AudioScreen.kt @@ -176,7 +176,7 @@ private fun AudioContent(contentPadding: PaddingValues) { showDialog = showAlert, title = alertTitle.value, message = alertMessage.value, - positiveButtonText = stringResource(R.string.ok), + lastButtonText = stringResource(R.string.ok), ) } diff --git a/app/src/main/kotlin/com/tutpro/baresip/BaresipContactScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/BaresipContactScreen.kt index 00a62ce5..9d78e62e 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/BaresipContactScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/BaresipContactScreen.kt @@ -273,7 +273,7 @@ private fun ContactContent( showDialog = showAlert, title = alertTitle.value, message = alertMessage.value, - positiveButtonText = stringResource(R.string.ok), + lastButtonText = stringResource(R.string.ok), ) } diff --git a/app/src/main/kotlin/com/tutpro/baresip/BlockedScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/BlockedScreen.kt index bc8d976b..6b876297 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/BlockedScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/BlockedScreen.kt @@ -145,15 +145,15 @@ private fun TopAppBar( var expanded by remember { mutableStateOf(false) } val delete = stringResource(R.string.delete) val showDialog = remember { mutableStateOf(false) } - val positiveAction = remember { mutableStateOf({}) } + val lastAction = remember { mutableStateOf({}) } AlertDialog( showDialog = showDialog, title = stringResource(R.string.confirmation), message = String.format(stringResource(R.string.blocked_delete_alert), account.text()), - positiveButtonText = stringResource(R.string.delete), - negativeButtonText = stringResource(R.string.cancel), - onPositiveClicked = positiveAction.value, + firstButtonText = stringResource(R.string.cancel), + lastButtonText = stringResource(R.string.delete), + onLastClicked = lastAction.value, ) TopAppBar( @@ -200,7 +200,7 @@ private fun TopAppBar( expanded = false when (selectedItem) { delete -> { - positiveAction.value = { + lastAction.value = { Blocked.clear(account.aor) blocked.value = emptyList() } @@ -251,20 +251,16 @@ private fun Account(account: Account) { private fun Blocked(ctx: Context, navController: NavController, blocked: MutableState>) { val showDialog = remember { mutableStateOf(false) } val message = remember { mutableStateOf("") } - val positiveButtonText = remember { mutableStateOf("") } - val positiveAction = remember { mutableStateOf({}) } - val neutralButtonText = remember { mutableStateOf("") } - val neutralAction = remember { mutableStateOf({}) } + val lastButtonText = remember { mutableStateOf("") } + val lastAction = remember { mutableStateOf({}) } AlertDialog( showDialog = showDialog, title = stringResource(R.string.confirmation), message = message.value, - positiveButtonText = positiveButtonText.value, - onPositiveClicked = positiveAction.value, - neutralButtonText = neutralButtonText.value, - onNeutralClicked = neutralAction.value, - negativeButtonText = stringResource(R.string.cancel) + firstButtonText = stringResource(R.string.cancel), + lastButtonText = lastButtonText.value, + onLastClicked = lastAction.value, ) val lazyListState = rememberLazyListState() @@ -289,8 +285,8 @@ private fun Blocked(ctx: Context, navController: NavController, blocked: Mutable .clickable(onClick = { message.value = String.format(ctx.getString(R.string.blocked_contact_question), peerUri) - positiveButtonText.value = ctx.getString(R.string.add_contact) - positiveAction.value = { + lastButtonText.value = ctx.getString(R.string.add_contact) + lastAction.value = { navController.navigate("baresip_contact/$peerUri/new") } showDialog.value = true diff --git a/app/src/main/kotlin/com/tutpro/baresip/CallDetailsScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/CallDetailsScreen.kt index 61b25f24..14eab463 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/CallDetailsScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/CallDetailsScreen.kt @@ -70,6 +70,7 @@ import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable import com.tutpro.baresip.CallRow.Details +import com.tutpro.baresip.CustomElements.AlertDialog import com.tutpro.baresip.CustomElements.verticalScrollbar import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay @@ -280,18 +281,17 @@ private fun startTime(detail: Details, onDelete: (Details) -> Unit): String { } } val showDialog = remember { mutableStateOf(false) } - val positiveAction = remember { mutableStateOf({}) } - CustomElements.AlertDialog( + AlertDialog( showDialog = showDialog, title = stringResource(R.string.confirmation), message = stringResource(R.string.delete_call_alert), - positiveButtonText = stringResource(R.string.delete), - onPositiveClicked = { + firstButtonText = stringResource(R.string.cancel), + lastButtonText = stringResource(R.string.delete), + onLastClicked = { CallHistoryNew.remove(detail.startTime, detail.stopTime) onDelete(detail) }, - negativeButtonText = stringResource(R.string.cancel) ) Text( @@ -299,9 +299,6 @@ private fun startTime(detail: Details, onDelete: (Details) -> Unit): String { modifier = Modifier.combinedClickable( onClick = {}, onLongClick = { - positiveAction.value = { - CallHistoryNew.remove(startTime, stopTime) - } showDialog.value = true } ) @@ -371,22 +368,21 @@ private fun Duration(ctx: Context, detail: Details, durationText: String) { ) // 2. Download Confirmation Dialog - if (showDownloadDialog.value) { - CustomElements.AlertDialog( + if (showDownloadDialog.value) + AlertDialog( showDialog = showDownloadDialog, title = stringResource(R.string.save_recording), message = stringResource(R.string.save_recording_question), - positiveButtonText = stringResource(R.string.save), - onPositiveClicked = { + firstButtonText = stringResource(R.string.cancel), + lastButtonText = stringResource(R.string.save), + onLastClicked = { showDownloadDialog.value = false detail.recording.firstOrNull { it.isNotEmpty() }?.let { val suggestedName = File(it).name saveLauncher.launch(suggestedName) } }, - negativeButtonText = stringResource(R.string.cancel) ) - } val hasRecording = detail.recording.isNotEmpty() && detail.recording[0].isNotEmpty() if (hasRecording) { diff --git a/app/src/main/kotlin/com/tutpro/baresip/CallsScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/CallsScreen.kt index 9749144f..1aafe3f4 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/CallsScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/CallsScreen.kt @@ -156,15 +156,15 @@ private fun TopAppBar(navController: NavController, account: Account, callHistor val blocked = stringResource(R.string.blocked) val showDialog = remember { mutableStateOf(false) } - val positiveAction = remember { mutableStateOf({}) } + val lastAction = remember { mutableStateOf({}) } AlertDialog( showDialog = showDialog, title = stringResource(R.string.confirmation), message = String.format(stringResource(R.string.delete_history_alert), account.text()), - positiveButtonText = stringResource(R.string.delete), - negativeButtonText = stringResource(R.string.cancel), - onPositiveClicked = positiveAction.value, + firstButtonText = stringResource(R.string.cancel), + lastButtonText = stringResource(R.string.delete), + onLastClicked = lastAction.value, ) TopAppBar( @@ -211,7 +211,7 @@ private fun TopAppBar(navController: NavController, account: Account, callHistor expanded = false when (selectedItem) { delete -> { - positiveAction.value = { + lastAction.value = { CallHistoryNew.clear(account.aor) callHistory.value = emptyList() Blocked.clear(account.aor) @@ -276,20 +276,20 @@ private fun Calls( val showDialog = remember { mutableStateOf(false) } val message = remember { mutableStateOf("") } - val positiveButtonText = remember { mutableStateOf("") } - val positiveAction = remember { mutableStateOf({}) } - val neutralButtonText = remember { mutableStateOf("") } - val neutralAction = remember { mutableStateOf({}) } + val secondButtonText = remember { mutableStateOf("") } + val secondAction = remember { mutableStateOf({}) } + val lastButtonText = remember { mutableStateOf("") } + val lastAction = remember { mutableStateOf({}) } AlertDialog( showDialog = showDialog, title = stringResource(R.string.confirmation), message = message.value, - positiveButtonText = positiveButtonText.value, - onPositiveClicked = positiveAction.value, - neutralButtonText = neutralButtonText.value, - onNeutralClicked = neutralAction.value, - negativeButtonText = stringResource(R.string.cancel) + firstButtonText = stringResource(R.string.cancel), + secondButtonText = secondButtonText.value, + onSecondClicked = secondAction.value, + lastButtonText = lastButtonText.value, + onLastClicked = lastAction.value, ) val lazyListState = rememberLazyListState() @@ -329,8 +329,8 @@ private fun Calls( Log.w(TAG, "onClickListener did not find UA for $aor") 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 = { + secondButtonText.value = ctx.getString(R.string.call) + secondAction.value = { if (ua != null) { handleIntent(ctx, viewModel, intent, "call") navController.navigate("main") { @@ -339,8 +339,8 @@ private fun Calls( } } } - neutralButtonText.value = ctx.getString(R.string.send_message) - neutralAction.value = { + lastButtonText.value = ctx.getString(R.string.send_message) + lastAction.value = { if (ua != null) { handleIntent(ctx, viewModel, intent, "message") navController.navigateUp() @@ -360,23 +360,23 @@ private fun Calls( ctx.getString(R.string.calls_delete_question), peerName, callText ) - positiveButtonText.value = ctx.getString(R.string.delete) - positiveAction.value = { + secondButtonText.value = "" + lastButtonText.value = ctx.getString(R.string.delete) + lastAction.value = { removeFromHistory(callHistory, callRow) } - neutralButtonText.value = "" } else { message.value = String.format( ctx.getString(R.string.calls_add_delete_question), peerName, callText ) - positiveButtonText.value = ctx.getString(R.string.add_contact) - positiveAction.value = { + secondButtonText.value = ctx.getString(R.string.add_contact) + secondAction.value = { navController.navigate("baresip_contact/$peerUri/new") } - neutralButtonText.value = ctx.getString(R.string.delete) - neutralAction.value = { + lastButtonText.value = ctx.getString(R.string.delete) + lastAction.value = { removeFromHistory(callHistory, callRow) } } diff --git a/app/src/main/kotlin/com/tutpro/baresip/ChatScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/ChatScreen.kt index 3eca91a8..71d1b318 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/ChatScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/ChatScreen.kt @@ -315,20 +315,20 @@ private fun Messages( val showDialog = remember { mutableStateOf(false) } val dialogMessage = remember { mutableStateOf("") } - val positiveButtonText = remember { mutableStateOf("") } - val positiveAction = remember { mutableStateOf({}) } - val neutralButtonText = remember { mutableStateOf("") } - val neutralAction = remember { mutableStateOf({}) } + val secondButtonText = remember { mutableStateOf("") } + val secondAction = remember { mutableStateOf({}) } + val lastButtonText = remember { mutableStateOf("") } + val lastAction = remember { mutableStateOf({}) } AlertDialog( showDialog = showDialog, title = stringResource(R.string.confirmation), message = dialogMessage.value, - positiveButtonText = positiveButtonText.value, - onPositiveClicked = positiveAction.value, - neutralButtonText = neutralButtonText.value, - onNeutralClicked = neutralAction.value, - negativeButtonText = stringResource(R.string.cancel) + firstButtonText = stringResource(R.string.cancel), + secondButtonText = secondButtonText.value, + onSecondClicked = secondAction.value, + lastButtonText = lastButtonText.value, + onLastClicked = lastAction.value, ) val lazyListState = rememberLazyListState() @@ -391,23 +391,23 @@ private fun Messages( ctx.getString(R.string.long_message_question), peerUri ) - positiveButtonText.value = ctx.getString(R.string.add_contact) - positiveAction.value = { + secondButtonText.value = ctx.getString(R.string.add_contact) + secondAction.value = { navController.navigate("baresip_contact/$peerUri/new") } - neutralButtonText.value = ctx.getString(R.string.delete) - neutralAction.value = { + lastButtonText.value = ctx.getString(R.string.delete) + lastAction.value = { message.delete() onMessageDeleted() } } else { dialogMessage.value = ctx.getString(R.string.short_message_question) - positiveButtonText.value = ctx.getString(R.string.delete) - positiveAction.value = { + secondButtonText.value = "" + lastButtonText.value = ctx.getString(R.string.delete) + lastAction.value = { message.delete() onMessageDeleted() } - neutralButtonText.value = "" } showDialog.value = true }, @@ -484,7 +484,7 @@ private fun NewMessage( showDialog = showDialog, title = stringResource(R.string.notice), message = dialogMessage.value, - positiveButtonText = stringResource(R.string.ok), + lastButtonText = stringResource(R.string.ok), ) Row(modifier = Modifier diff --git a/app/src/main/kotlin/com/tutpro/baresip/ChatsScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/ChatsScreen.kt index f900aed6..f29724e9 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/ChatsScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/ChatsScreen.kt @@ -167,15 +167,15 @@ private fun TopAppBar( val delete = stringResource(R.string.delete) val blocked = stringResource(R.string.blocked) val showDialog = remember { mutableStateOf(false) } - val positiveAction = remember { mutableStateOf({}) } + val lastAction = remember { mutableStateOf({}) } AlertDialog( showDialog = showDialog, title = stringResource(R.string.confirmation), message = String.format(stringResource(R.string.delete_chats_alert), account.text()), - positiveButtonText = stringResource(R.string.delete), - onPositiveClicked = positiveAction.value, - negativeButtonText = stringResource(R.string.cancel), + firstButtonText = stringResource(R.string.cancel), + lastButtonText = stringResource(R.string.delete), + onLastClicked = lastAction.value, ) TopAppBar( @@ -212,7 +212,7 @@ private fun TopAppBar( menuExpanded = false when (selectedItem) { delete -> { - positiveAction.value = { + lastAction.value = { deleteMessages(uaMessages, account, "") account.unreadMessages = false } @@ -269,21 +269,21 @@ private fun Chats( val showDialog = remember { mutableStateOf(false) } val dialogMessage = remember { mutableStateOf("") } - val positiveButtonText = remember { mutableStateOf("") } - val positiveAction = remember { mutableStateOf({}) } - val neutralButtonText = remember { mutableStateOf("") } - val neutralAction = remember { mutableStateOf({}) } + val secondButtonText = remember { mutableStateOf("") } + val secondAction = remember { mutableStateOf({}) } + val lastButtonText = remember { mutableStateOf("") } + val lastAction = remember { mutableStateOf({}) } if (showDialog.value) AlertDialog( showDialog = showDialog, title = stringResource(R.string.confirmation), message = dialogMessage.value, - positiveButtonText = positiveButtonText.value, - onPositiveClicked = positiveAction.value, - neutralButtonText = neutralButtonText.value, - onNeutralClicked = neutralAction.value, - negativeButtonText = stringResource(R.string.cancel) + firstButtonText = stringResource(R.string.cancel), + secondButtonText = secondButtonText.value, + onSecondClicked = secondAction.value, + lastButtonText = lastButtonText.value, + onLastClicked = lastAction.value, ) val lazyListState = rememberLazyListState() @@ -359,22 +359,22 @@ private fun Chats( ctx.getString(R.string.short_chat_question), peer ) - positiveButtonText.value = ctx.getString(R.string.delete) - positiveAction.value = { + secondButtonText.value = "" + lastButtonText.value = ctx.getString(R.string.delete) + lastAction.value = { deleteMessages(uaMessages, account, message.peerUri) } - neutralButtonText.value = "" } else { dialogMessage.value = String.format(ctx.getString(R.string.long_chat_question), peer) - positiveButtonText.value = ctx.getString(R.string.add_contact) - positiveAction.value = { - navController.navigate("baresip_contact/${message.peerUri}/new") - } - neutralButtonText.value = ctx.getString(R.string.delete) - neutralAction.value = { + secondButtonText.value = ctx.getString(R.string.delete) + secondAction.value = { deleteMessages(uaMessages, account, message.peerUri) } + lastButtonText.value = ctx.getString(R.string.add_contact) + lastAction.value = { + navController.navigate("baresip_contact/${message.peerUri}/new") + } } showDialog.value = true }, @@ -463,7 +463,7 @@ private fun NewChatPeer(ctx: Context, navController: NavController, account: Acc showDialog = showAlert, title = alertTitle.value, message = alertMessage.value, - positiveButtonText = stringResource(R.string.ok), + lastButtonText = stringResource(R.string.ok), ) } diff --git a/app/src/main/kotlin/com/tutpro/baresip/CodecsScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/CodecsScreen.kt index 697d8f21..552bcf73 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/CodecsScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/CodecsScreen.kt @@ -47,7 +47,6 @@ import androidx.navigation.NavGraphBuilder import androidx.navigation.NavType import androidx.navigation.compose.composable import androidx.navigation.navArgument -import com.tutpro.baresip.CustomElements.AlertDialog import com.tutpro.baresip.CustomElements.verticalScrollbar fun NavGraphBuilder.codecsScreenRoute(navController: NavController) { @@ -161,11 +160,6 @@ private fun CodecsScreen( ) } -private val alertTitle = mutableStateOf("") -private val alertMessage = mutableStateOf("") -private val showAlert = mutableStateOf(false) - - @Composable private fun CodecsContent( contentPadding: PaddingValues, @@ -196,15 +190,6 @@ private fun CodecsContent( codecs.addAll(currentCodecs) } - if (showAlert.value) { - AlertDialog( - showDialog = showAlert, - title = alertTitle.value, - message = alertMessage.value, - positiveButtonText = stringResource(R.string.ok), - ) - } - Column( modifier = Modifier .fillMaxWidth() diff --git a/app/src/main/kotlin/com/tutpro/baresip/ContactsScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/ContactsScreen.kt index a8383db8..ed09cce7 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/ContactsScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/ContactsScreen.kt @@ -215,21 +215,21 @@ private fun ContactsContent( ) { val showDialog = remember { mutableStateOf(false) } val dialogMessage = remember { mutableStateOf("") } - val positiveText = remember { mutableStateOf("") } - val positiveAction = remember { mutableStateOf({}) } - val neutralText = remember { mutableStateOf("") } - val neutralAction = remember { mutableStateOf({}) } + val secondText = remember { mutableStateOf("") } + val secondAction = remember { mutableStateOf({}) } + val lastText = remember { mutableStateOf("") } + val lastAction = remember { mutableStateOf({}) } if (showDialog.value) AlertDialog( showDialog = showDialog, title = stringResource(R.string.confirmation), message = dialogMessage.value, - positiveButtonText = positiveText.value, - onPositiveClicked = positiveAction.value, - neutralButtonText = neutralText.value, - onNeutralClicked = neutralAction.value, - negativeButtonText = stringResource(R.string.cancel) + firstButtonText = stringResource(R.string.cancel), + secondButtonText = secondText.value, + onSecondClicked = secondAction.value, + lastButtonText = lastText.value, + onLastClicked = lastAction.value, ) val lazyListState = rememberLazyListState() @@ -334,8 +334,8 @@ private fun ContactsContent( ctx.getString(R.string.contact_action_question), contact.name() ) - positiveText.value = ctx.getString(R.string.call) - positiveAction.value = { + secondText.value = ctx.getString(R.string.call) + secondAction.value = { if (ua != null) { handleIntent(ctx, viewModel, intent, "call") navController.navigate("main") { @@ -344,8 +344,8 @@ private fun ContactsContent( } } } - neutralText.value = ctx.getString(R.string.send_message) - neutralAction.value = { + lastText.value = ctx.getString(R.string.send_message) + lastAction.value = { if (ua != null) { handleIntent(ctx, viewModel, intent, "message") navController.navigateUp() @@ -358,8 +358,9 @@ private fun ContactsContent( ctx.getString(R.string.contact_delete_question), contact.name() ) - positiveText.value = ctx.getString(R.string.delete) - positiveAction.value = { + secondText.value = "" + lastText.value = ctx.getString(R.string.delete) + lastAction.value = { val id = contact.id val avatarFile = File( BaresipService.filesPath, @@ -377,7 +378,6 @@ private fun ContactsContent( } Contact.removeBaresipContact(contact) } - neutralText.value = "" showDialog.value = true } ) @@ -410,15 +410,15 @@ private fun ContactsContent( ctx.getString(R.string.contact_delete_question), contact.name() ) - positiveText.value = ctx.getString(R.string.delete) - positiveAction.value = { + secondText.value = "" + lastText.value = ctx.getString(R.string.delete) + lastAction.value = { ctx.contentResolver.delete( ContactsContract.RawContacts.CONTENT_URI, ContactsContract.Contacts.DISPLAY_NAME + "='" + contact.name() + "'", null ) } - neutralText.value = "" showDialog.value = true } ) diff --git a/app/src/main/kotlin/com/tutpro/baresip/CustomElements.kt b/app/src/main/kotlin/com/tutpro/baresip/CustomElements.kt index 3968f21d..b1ca2be3 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/CustomElements.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/CustomElements.kt @@ -228,18 +228,21 @@ object CustomElements { } } } + @OptIn(ExperimentalMaterial3Api::class) @Composable fun AlertDialog( showDialog: MutableState, title: String, message: String, - positiveButtonText: String = "", - onPositiveClicked: () -> Unit = {}, - negativeButtonText: String = "", - onNegativeClicked: () -> Unit = {}, - neutralButtonText: String = "", - onNeutralClicked: () -> Unit = {} + firstButtonText: String = "", + onFirstClicked: () -> Unit = {}, + secondButtonText: String = "", + onSecondClicked: () -> Unit = {}, + thirdButtonText: String = "", + onThirdClicked: () -> Unit = {}, + lastButtonText: String = "", + onLastClicked: () -> Unit = {} ) { if (showDialog.value) { BasicAlertDialog( @@ -272,52 +275,59 @@ object CustomElements { ) Spacer(modifier = Modifier.height(16.dp)) - // New logic starts here - if (positiveButtonText.isNotEmpty()) { - val buttonCount = listOf(positiveButtonText, negativeButtonText, neutralButtonText) - .count { it.isNotEmpty() } + if (lastButtonText.isNotEmpty()) { + + val buttonCount = listOf( + firstButtonText, secondButtonText, thirdButtonText, lastButtonText + ).count { it.isNotEmpty() } if (buttonCount >= 3) { - // Use a Column for 3 buttons, aligned to the end (right) + // Use a Column for 3-4 buttons, aligned to the end (right) Column( modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.End ) { - // The positive button is usually last for emphasis - if (negativeButtonText.isNotEmpty()) { - TextButton(onClick = { - onNegativeClicked() - showDialog.value = false - }) { - Text( - text = negativeButtonText.uppercase(), - fontSize = 14.sp, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - if (neutralButtonText.isNotEmpty()) { - TextButton(onClick = { - onNeutralClicked() - showDialog.value = false - }) { - Text( - text = neutralButtonText.uppercase(), - fontSize = 14.sp, - color = MaterialTheme.colorScheme.primary - ) - } - } TextButton(onClick = { - onPositiveClicked() + onFirstClicked() showDialog.value = false }) { Text( - text = positiveButtonText.uppercase(), + text = firstButtonText.uppercase(), + fontSize = 14.sp, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + TextButton(onClick = { + onSecondClicked() + showDialog.value = false + }) { + Text( + text = secondButtonText.uppercase(), fontSize = 14.sp, color = MaterialTheme.colorScheme.primary, ) } + if (thirdButtonText.isNotEmpty()) + TextButton(onClick = { + onThirdClicked() + showDialog.value = false + }) { + Text( + text = thirdButtonText.uppercase(), + fontSize = 14.sp, + color = MaterialTheme.colorScheme.primary, + ) + } + TextButton(onClick = { + onLastClicked() + showDialog.value = false + }) { + Text( + text = lastButtonText.uppercase(), + fontSize = 14.sp, + color = MaterialTheme.colorScheme.primary + ) + } } } else { // Use the existing Row for 1 or 2 buttons @@ -325,38 +335,36 @@ object CustomElements { modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End ) { - if (negativeButtonText.isNotEmpty()) { + if (firstButtonText.isNotEmpty()) TextButton(onClick = { - onNegativeClicked() + onFirstClicked() showDialog.value = false }) { Text( - text = negativeButtonText.uppercase(), + text = firstButtonText.uppercase(), fontSize = 14.sp, color = MaterialTheme.colorScheme.onSurfaceVariant ) } - } - if (neutralButtonText.isNotEmpty()) { + if (secondButtonText.isNotEmpty()) TextButton(onClick = { - onNeutralClicked() + onSecondClicked() showDialog.value = false }) { Text( - text = neutralButtonText.uppercase(), + text = secondButtonText.uppercase(), fontSize = 14.sp, color = MaterialTheme.colorScheme.primary ) } - } TextButton(onClick = { - onPositiveClicked() + onLastClicked() showDialog.value = false }) { Text( - text = positiveButtonText.uppercase(), + text = lastButtonText.uppercase(), fontSize = 14.sp, - color = MaterialTheme.colorScheme.primary, + color = MaterialTheme.colorScheme.primary ) } } @@ -481,7 +489,7 @@ object CustomElements { .padding(top = 16.dp, start = 16.dp, end = 16.dp, bottom = 0.dp), shape = RoundedCornerShape(16.dp), colors = CardDefaults.cardColors( - containerColor = MaterialTheme.colorScheme.surfaceContainer + containerColor = MaterialTheme.colorScheme.surfaceVariant ) ) { Column(modifier = Modifier.padding(16.dp)) { diff --git a/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt index c5ef9f6c..27daf443 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt @@ -754,15 +754,16 @@ private fun BottomBar(ctx: Context, viewModel: ViewModel, navController: NavCont if (acc.vmUri.isNotEmpty()) { dialogTitle.value = ctx.getString(R.string.voicemail_messages) dialogMessage.value = acc.vmMessages(ctx) - positiveText.value = ctx.getString(R.string.listen) - onPositiveClicked.value = { + firstText.value = ctx.getString(R.string.cancel) + onFirstClicked.value = {} + secondText.value = "" + lastText.value = ctx.getString(R.string.listen) + onLastClicked.value = { val intent = Intent(ctx, MainActivity::class.java) intent.putExtra("uap", ua.uap) intent.putExtra("peer", acc.vmUri) handleIntent(ctx, viewModel, intent, "call") } - negativeText.value = ctx.getString(R.string.cancel) - onNegativeClicked.value = {} showDialog.value = true } }, @@ -852,10 +853,13 @@ private val showAlert = mutableStateOf(false) private val dialogTitle = mutableStateOf("") private val dialogMessage = mutableStateOf("") -private val positiveText = mutableStateOf("") -private val onPositiveClicked = mutableStateOf({}) -private val negativeText = mutableStateOf("") -private val onNegativeClicked = mutableStateOf({}) +private val firstText = mutableStateOf("") +private val onFirstClicked = mutableStateOf({}) + +private val secondText = mutableStateOf("") +private val onSecondClicked = mutableStateOf({}) +private val lastText = mutableStateOf("") +private val onLastClicked = mutableStateOf({}) private val showDialog = mutableStateOf(false) @Composable @@ -902,7 +906,7 @@ private fun MainContent(navController: NavController, viewModel: ViewModel, cont showDialog = showAlert, title = alertTitle.value, message = alertMessage.value, - positiveButtonText = stringResource(R.string.ok), + lastButtonText = stringResource(R.string.ok), ) if (showDialog.value) @@ -910,10 +914,12 @@ private fun MainContent(navController: NavController, viewModel: ViewModel, cont showDialog = showDialog, title = stringResource(R.string.confirmation), message = dialogMessage.value, - positiveButtonText = positiveText.value, - onPositiveClicked = onPositiveClicked.value, - negativeButtonText = negativeText.value, - onNegativeClicked = onNegativeClicked.value + firstButtonText = firstText.value, + onFirstClicked = onFirstClicked.value, + secondButtonText = secondText.value, + onSecondClicked = onSecondClicked.value, + lastButtonText = lastText.value, + onLastClicked = onLastClicked.value, ) SelectableAlertDialog( @@ -1347,8 +1353,11 @@ private fun CallUriRow( R.color.colorTrafficGreen -> { dialogTitle.value = ctx.getString(R.string.info) dialogMessage.value = ctx.getString(R.string.call_is_secure) - positiveText.value = ctx.getString(R.string.unverify) - onPositiveClicked.value = { + firstText.value = ctx.getString(R.string.cancel) + onFirstClicked.value = {} + secondText.value = "" + lastText.value = ctx.getString(R.string.unverify) + onLastClicked.value = { if (Api.cmd_exec("zrtp_unverify " + call.zid) != 0) Log.e( TAG, @@ -1357,7 +1366,6 @@ private fun CallUriRow( else call.securityIconTint.value = R.color.colorTrafficYellow } - negativeText.value = ctx.getString(R.string.cancel) showDialog.value = true } } @@ -2339,12 +2347,13 @@ fun handleServiceEvent(ctx: Context, viewModel: ViewModel, event: String, params else { dialogTitle.value = ctx.getString(R.string.redirect_request) dialogMessage.value = String.format(ctx.getString(R.string.redirect_request_query), target) - positiveText.value = ctx.getString(R.string.yes) - onPositiveClicked.value = { + firstText.value = "" + secondText.value = ctx.getString(R.string.no) + onSecondClicked.value = { } + lastText.value = ctx.getString(R.string.yes) + onLastClicked.value = { redirect(ctx, viewModel, ua, target) } - negativeText.value = ctx.getString(R.string.no) - onNegativeClicked.value = {} showDialog.value = true } showCall(ctx, viewModel, ua) @@ -2374,8 +2383,17 @@ fun handleServiceEvent(ctx: Context, viewModel: ViewModel, event: String, params } dialogTitle.value = ctx.getString(R.string.verify) dialogMessage.value = String.format(ctx.getString(R.string.verify_sas), ev[1]) - positiveText.value = ctx.getString(R.string.yes) - onPositiveClicked.value = { + firstText.value = "" + secondText.value = ctx.getString(R.string.no) + onSecondClicked.value = { + call.security = R.color.colorTrafficYellow + call.zid = ev[2] + if (aor == viewModel.selectedAor.value) + call.securityIconTint.value = R.color.colorTrafficYellow + secondText.value = "" + } + lastText.value = ctx.getString(R.string.yes) + onLastClicked.value = { call.security = if (Api.cmd_exec("zrtp_verify ${ev[2]}") != 0) { Log.e(TAG, "Command 'zrtp_verify ${ev[2]}' failed") R.color.colorTrafficYellow @@ -2386,14 +2404,6 @@ fun handleServiceEvent(ctx: Context, viewModel: ViewModel, event: String, params if (aor == viewModel.selectedAor.value) call.securityIconTint.value = call.security } - negativeText.value = ctx.getString(R.string.no) - onNegativeClicked.value = { - call.security = R.color.colorTrafficYellow - call.zid = ev[2] - if (aor == viewModel.selectedAor.value) - call.securityIconTint.value = R.color.colorTrafficYellow - onNegativeClicked.value = {} - } showDialog.value = true } "call verified", "call secure" -> { @@ -2420,19 +2430,19 @@ fun handleServiceEvent(ctx: Context, viewModel: ViewModel, event: String, params String.format(ctx.getString(R.string.transfer_request_query), target) else String.format(ctx.getString(R.string.call_request_query), target) - positiveText.value = ctx.getString(R.string.yes) - onPositiveClicked.value = { + firstText.value = "" + secondText.value = ctx.getString(R.string.no) + onSecondClicked.value = { + if (call in Call.calls()) + call!!.notifySipfrag(603, "Decline") + } + lastText.value = ctx.getString(R.string.yes) + onLastClicked.value = { if (call in Call.calls()) acceptTransfer(ctx, viewModel, ua, call!!, ev[1]) else makeCall(ctx, viewModel, ev[1], false) } - negativeText.value = ctx.getString(R.string.no) - onNegativeClicked.value = { - if (call in Call.calls()) - call!!.notifySipfrag(603, "Decline") - onNegativeClicked.value = {} - } showDialog.value = true } "transfer accept" -> { @@ -2569,9 +2579,10 @@ fun handleIntent(ctx: Context, viewModel: ViewModel, intent: Intent, action: Str fun handleDialog(ctx: Context, title: String, message: String, action: () -> Unit = {}) { dialogTitle.value = title dialogMessage.value = message - positiveText.value = ctx.getString(R.string.ok) - onPositiveClicked.value = { action() } - negativeText.value = "" + firstText.value = "" + secondText.value = "" + lastText.value = ctx.getString(R.string.ok) + onLastClicked.value = { action() } showDialog.value = true } @@ -2736,13 +2747,14 @@ private fun restore(ctx: Context, password: String, onRestartApp: () -> Unit) { dialogTitle.value = ctx.getString(R.string.info) dialogMessage.value = ctx.getString(R.string.restored) - positiveText.value = ctx.getString(R.string.restart) - onPositiveClicked.value = { - onRestartApp() + firstText.value = ctx.getString(R.string.cancel) + onFirstClicked.value = { showDialog.value = false } - negativeText.value = ctx.getString(R.string.cancel) - onNegativeClicked.value = { + secondText.value = "" + lastText.value = ctx.getString(R.string.restart) + onLastClicked.value = { + onRestartApp() showDialog.value = false } showDialog.value = true diff --git a/app/src/main/kotlin/com/tutpro/baresip/SettingsScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/SettingsScreen.kt index f4e14439..e789f9d7 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/SettingsScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/SettingsScreen.kt @@ -200,14 +200,14 @@ private fun SettingsScreen( showDialog = showRestartDialog, title = stringResource(R.string.restart_request), message = stringResource(R.string.config_restart), - positiveButtonText = stringResource(R.string.restart), - onPositiveClicked = { + firstButtonText = stringResource(R.string.cancel), + onFirstClicked = { + navController.navigateUp() + }, + lastButtonText = stringResource(R.string.restart), + onLastClicked = { onRestartApp() }, - negativeButtonText = stringResource(R.string.cancel), - onNegativeClicked = { - navController.navigateUp() - } ) } @@ -218,10 +218,10 @@ private fun SettingsScreen( private val dialogTitle = mutableStateOf("") private val dialogMessage = mutableStateOf("") -private val positiveText = mutableStateOf("") -private val onPositiveClicked = mutableStateOf({}) -private val negativeText = mutableStateOf("") -private val onNegativeClicked = mutableStateOf({}) +private val firstButtonText = mutableStateOf("") +private val onFirstClicked = mutableStateOf({}) +private val lastButtonText = mutableStateOf("") +private val onLastClicked = mutableStateOf({}) private val showDialog = mutableStateOf(false) private val alertTitle = mutableStateOf("") @@ -249,7 +249,8 @@ private fun SettingsContent( showDialog = showAlert, title = alertTitle.value, message = alertMessage.value, - positiveButtonText = okButtonText, + firstButtonText = "", + lastButtonText = okButtonText, ) } @@ -258,10 +259,10 @@ private fun SettingsContent( showDialog = showDialog, title = dialogTitle.value, message = dialogMessage.value, - positiveButtonText = positiveText.value, - onPositiveClicked = onPositiveClicked.value, - negativeButtonText = negativeText.value, - onNegativeClicked = onNegativeClicked.value, + firstButtonText = firstButtonText.value, + onFirstClicked = onFirstClicked.value, + lastButtonText = lastButtonText.value, + onLastClicked = onLastClicked.value, ) @Composable @@ -293,15 +294,13 @@ private fun SettingsContent( if (!isAppearOnTopPermissionGranted(ctx)) { dialogTitle.value = noticeTitleText dialogMessage.value = appearOnTopPermissionMessage - positiveText.value = okButtonText - onPositiveClicked.value = { + firstButtonText.value = cancelButtonText + onFirstClicked.value = {} + lastButtonText.value = okButtonText + onLastClicked.value = { val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION) ctx.startActivity(intent) } - negativeText.value = cancelButtonText - onNegativeClicked.value = { - negativeText.value = "" - } showDialog.value = true viewModel.autoStart.value = false } @@ -578,10 +577,10 @@ private fun SettingsContent( showDialog = showAlertDialog, title = stringResource(R.string.notice), message = stringResource(R.string.no_read_permission), - positiveButtonText = stringResource(R.string.ok), - onPositiveClicked = { requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) }, - negativeButtonText = "", - onNegativeClicked = {}, + firstButtonText = "", + onFirstClicked = {}, + lastButtonText = stringResource(R.string.ok), + onLastClicked = { requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) }, ) } @@ -690,11 +689,11 @@ private fun SettingsContent( shouldShowRequestPermissionRationale(activity, permission) -> { dialogTitle.value = noticeTitleText dialogMessage.value = noReadPermissionMessage - positiveText.value = okButtonText - onPositiveClicked.value = { + firstButtonText.value = "" + lastButtonText.value = okButtonText + onLastClicked.value = { requestPermissionLauncher.launch(permission) } - negativeText.value = "" showDialog.value = true } else -> @@ -764,8 +763,8 @@ private fun SettingsContent( val contactsHelp = stringResource(R.string.contacts_help) val consentRequestTitle = stringResource(R.string.consent_request) val contactsConsentMessage = stringResource(R.string.contacts_consent) - val positiveButtonText = stringResource(R.string.accept) - val negativeButtonText = stringResource(R.string.deny) + val denyText = stringResource(R.string.deny) + val acceptText = stringResource(R.string.accept) val both = stringResource(R.string.both) val noAndroidContactsMessage = stringResource(R.string.no_android_contacts) val showAlertDialog = remember { mutableStateOf(false) } @@ -832,8 +831,12 @@ private fun SettingsContent( if (mode != "baresip" && !Utils.checkPermissions(ctx, contactsPermissions)) { dialogTitle.value = consentRequestTitle dialogMessage.value = contactsConsentMessage - positiveText.value = positiveButtonText - onPositiveClicked.value = { + firstButtonText.value = denyText + onFirstClicked.value = { + itemPosition.intValue = contactValues.indexOf(contactsMode) + } + lastButtonText.value = acceptText + onLastClicked.value = { showDialog.value = false viewModel.contactsMode.value = mode if (ContextCompat.checkSelfPermission( @@ -864,11 +867,6 @@ private fun SettingsContent( ) } } - negativeText.value = negativeButtonText - onNegativeClicked.value = { - itemPosition.intValue = contactValues.indexOf(contactsMode) - negativeText.value = "" - } showDialog.value = true } else { @@ -886,15 +884,15 @@ private fun SettingsContent( showDialog = showAlertDialog, title = noticeTitleText, message = noAndroidContactsMessage, - positiveButtonText = okButtonText, - onPositiveClicked = { requestPermissionsLauncher.launch( + firstButtonText = "", + onFirstClicked = {}, + lastButtonText = okButtonText, + onLastClicked = { requestPermissionsLauncher.launch( arrayOf( Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS ) )}, - negativeButtonText = "", - onNegativeClicked = {}, ) } } @@ -1229,16 +1227,15 @@ private fun SettingsContent( onCheckedChange = { dialogTitle.value = confirmationText dialogMessage.value = resetConfigAlert - positiveText.value = resetButtonText - onPositiveClicked.value = { + firstButtonText.value = cancelButtonText + onFirstClicked.value = { + reset = false + } + lastButtonText.value = resetButtonText + onLastClicked.value = { Config.reset() onRestartApp() } - negativeText.value = cancelButtonText - onNegativeClicked.value = { - reset = false - negativeText.value = "" - } showDialog.value = true } )