Improved settings dialog implementations

This commit is contained in:
Juha Heinanen
2025-04-14 17:11:44 +03:00
parent 17ef122f6b
commit 80587ab06f
@@ -63,7 +63,7 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.tutpro.baresip.CustomElements.AlertDialog
import com.tutpro.baresip.CustomElements.Checkbox import com.tutpro.baresip.CustomElements.Checkbox
import com.tutpro.baresip.CustomElements.verticalScrollbar import com.tutpro.baresip.CustomElements.verticalScrollbar
import com.tutpro.baresip.Utils.copyInputStreamToFile import com.tutpro.baresip.Utils.copyInputStreamToFile
@@ -116,6 +116,18 @@ class ConfigActivity : ComponentActivity() {
private var restart = false private var restart = false
private var audioRestart = false private var audioRestart = false
private val alertTitle = mutableStateOf("")
private val alertMessage = mutableStateOf("")
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 showDialog = mutableStateOf(false)
private val onBackPressedCallback = object : OnBackPressedCallback(true) { private val onBackPressedCallback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() { override fun handleOnBackPressed() {
goBack() goBack()
@@ -137,10 +149,9 @@ class ConfigActivity : ComponentActivity() {
save = true save = true
restart = true restart = true
} catch (e: Error) { } catch (e: Error) {
Utils.alertView( alertTitle.value = getString(R.string.error)
this, getString(R.string.error), alertMessage.value = getString(R.string.read_cert_error) + ": " + e.message
getString(R.string.read_cert_error) + ": " + e.message showAlert.value = true
)
newTlsCertificateFile = false newTlsCertificateFile = false
} }
} }
@@ -162,10 +173,9 @@ class ConfigActivity : ComponentActivity() {
inputStream.close() inputStream.close()
restart = true restart = true
} catch (e: Error) { } catch (e: Error) {
Utils.alertView( alertTitle.value = getString(R.string.error)
this, getString(R.string.error), alertMessage.value = getString(R.string.read_ca_certs_error) + ": " + e.message
getString(R.string.read_ca_certs_error) + ": " + e.message showAlert.value = true
)
newCaFile = false newCaFile = false
} }
} }
@@ -330,38 +340,62 @@ class ConfigActivity : ComponentActivity() {
@Composable @Composable
fun ConfigContent(ctx: Context, contentPadding: PaddingValues) { fun ConfigContent(ctx: Context, contentPadding: PaddingValues) {
arrowTint = if (BaresipService.darkTheme.value) arrowTint = if (BaresipService.darkTheme.value)
LocalCustomColors.current.grayLight LocalCustomColors.current.grayLight
else else
LocalCustomColors.current.black LocalCustomColors.current.black
if (showAlert.value) {
AlertDialog(
showDialog = showAlert,
title = alertTitle.value,
message = alertMessage.value,
positiveButtonText = stringResource(R.string.ok),
)
}
if (showDialog.value)
AlertDialog(
showDialog = showDialog,
title = alertTitle.value,
message = alertMessage.value,
positiveButtonText = positiveText.value,
onPositiveClicked = onPositiveClicked.value,
negativeButtonText = negativeText.value,
onNegativeClicked = onNegativeClicked.value,
)
val scrollState = rememberScrollState() val scrollState = rememberScrollState()
Column( Column(
modifier = Modifier modifier = Modifier
.imePadding() .imePadding()
.fillMaxWidth() .fillMaxWidth()
.padding(contentPadding) .padding(contentPadding)
.padding(start = 16.dp, end = 4.dp, top = 8.dp, bottom = 8.dp) .padding(start = 16.dp, end = 4.dp, top = 16.dp, bottom = 8.dp)
.verticalScrollbar(scrollState) .verticalScrollbar(scrollState)
.verticalScroll(state = scrollState), .verticalScroll(state = scrollState),
verticalArrangement = Arrangement.spacedBy(8.dp), verticalArrangement = Arrangement.spacedBy(8.dp),
) { ) {
StartAutomatically(ctx) StartAutomatically(ctx)
ListenAddress(ctx) ListenAddress()
AddressFamily(ctx) AddressFamily()
DnsServers(ctx) DnsServers()
TlsCertificateFile(ctx) TlsCertificateFile(ctx)
VerifyServer(ctx) VerifyServer()
CaFile(ctx) CaFile(ctx)
UserAgent(ctx) UserAgent()
AudioSettings(ctx) AudioSettings(ctx)
BatteryOptimizations(ctx) BatteryOptimizations()
if (Build.VERSION.SDK_INT >= 29) if (Build.VERSION.SDK_INT >= 29)
DefaultDialer(ctx) DefaultDialer()
Contacts(ctx) Contacts(ctx)
DarkTheme(ctx) DarkTheme()
Debug(ctx) Debug()
SipTrace(ctx) SipTrace()
Reset(ctx) Reset()
} }
} }
@@ -376,10 +410,9 @@ class ConfigActivity : ComponentActivity() {
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
.clickable { .clickable {
Utils.alertView( alertTitle.value = getString(R.string.start_automatically)
ctx, getString(R.string.start_automatically), alertMessage.value = getString(R.string.start_automatically_help)
getString(R.string.start_automatically_help) showAlert.value = true
)
}, },
color = LocalCustomColors.current.itemText, color = LocalCustomColors.current.itemText,
fontSize = 18.sp) fontSize = 18.sp)
@@ -390,28 +423,19 @@ class ConfigActivity : ComponentActivity() {
onCheckedChange = { onCheckedChange = {
if (it) { if (it) {
if (!isAppearOnTopPermissionGranted(ctx)) { if (!isAppearOnTopPermissionGranted(ctx)) {
with( dialogTitle.value = getString(R.string.notice)
MaterialAlertDialogBuilder( dialogMessage.value = getString(R.string.appear_on_top_permission)
ctx, positiveText.value = getString(R.string.ok)
R.style.AlertDialogTheme onPositiveClicked.value = {
)
) {
setTitle(getText(R.string.notice))
setMessage(getText(R.string.appear_on_top_permission))
setPositiveButton(getText(R.string.ok)) { dialog, _ ->
dialog.dismiss()
managingOverlayPermission = true managingOverlayPermission = true
val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION) val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
startActivity(intent) startActivity(intent)
} }
setNegativeButton(getText(R.string.cancel)) { dialog, _ -> negativeText.value = getString(R.string.cancel)
dialog.dismiss() onNegativeClicked.value = {
} negativeText.value = ""
val dialog = this.create()
dialog.setCancelable(false)
dialog.setCanceledOnTouchOutside(false)
dialog.show()
} }
showDialog.value = true
startAutomatically = false startAutomatically = false
} }
else else
@@ -426,7 +450,7 @@ class ConfigActivity : ComponentActivity() {
} }
@Composable @Composable
private fun ListenAddress(ctx: Context) { private fun ListenAddress() {
Row( Row(
Modifier Modifier
.fillMaxWidth() .fillMaxWidth()
@@ -446,10 +470,9 @@ class ConfigActivity : ComponentActivity() {
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.clickable { .clickable {
Utils.alertView( alertTitle.value = getString(R.string.listen_address)
ctx, getString(R.string.listen_address), alertMessage.value = getString(R.string.listen_address_help)
getString(R.string.listen_address_help) showAlert.value = true
)
}, },
textStyle = androidx.compose.ui.text.TextStyle( textStyle = androidx.compose.ui.text.TextStyle(
fontSize = 18.sp, color = LocalCustomColors.current.itemText), fontSize = 18.sp, color = LocalCustomColors.current.itemText),
@@ -460,7 +483,7 @@ class ConfigActivity : ComponentActivity() {
} }
@Composable @Composable
private fun AddressFamily(ctx: Context) { private fun AddressFamily() {
Row( Row(
Modifier Modifier
.fillMaxWidth() .fillMaxWidth()
@@ -472,10 +495,9 @@ class ConfigActivity : ComponentActivity() {
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
.clickable { .clickable {
Utils.alertView( alertTitle.value = getString(R.string.address_family)
ctx, getString(R.string.address_family), alertMessage.value = getString(R.string.address_family_help)
getString(R.string.address_family_help) showAlert.value = true
)
}, },
color = LocalCustomColors.current.itemText, color = LocalCustomColors.current.itemText,
fontSize = 18.sp) fontSize = 18.sp)
@@ -526,7 +548,7 @@ class ConfigActivity : ComponentActivity() {
} }
@Composable @Composable
private fun DnsServers(ctx: Context) { private fun DnsServers() {
Row( Row(
Modifier Modifier
.fillMaxWidth() .fillMaxWidth()
@@ -545,10 +567,9 @@ class ConfigActivity : ComponentActivity() {
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.clickable { .clickable {
Utils.alertView( alertTitle.value = getString(R.string.dns_servers)
ctx, getString(R.string.dns_servers), alertMessage.value = getString(R.string.dns_servers_help)
getString(R.string.dns_servers_help) showAlert.value = true
)
}, },
textStyle = androidx.compose.ui.text.TextStyle( textStyle = androidx.compose.ui.text.TextStyle(
fontSize = 18.sp, color = LocalCustomColors.current.itemText), fontSize = 18.sp, color = LocalCustomColors.current.itemText),
@@ -560,6 +581,7 @@ class ConfigActivity : ComponentActivity() {
@Composable @Composable
private fun TlsCertificateFile(ctx: Context) { private fun TlsCertificateFile(ctx: Context) {
val showAlertDialog = remember { mutableStateOf(false) }
Row( Row(
Modifier.fillMaxWidth(), Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
@@ -569,10 +591,9 @@ class ConfigActivity : ComponentActivity() {
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
.clickable { .clickable {
Utils.alertView( alertTitle.value = getString(R.string.tls_certificate_file)
ctx, getString(R.string.tls_certificate_file), alertMessage.value = getString(R.string.tls_certificate_file_help)
getString(R.string.tls_certificate_file_help) showAlert.value = true
)
}, },
color = LocalCustomColors.current.itemText, color = LocalCustomColors.current.itemText,
fontSize = 18.sp) fontSize = 18.sp)
@@ -594,10 +615,9 @@ class ConfigActivity : ComponentActivity() {
val downloadsPath = Utils.downloadsPath("cert.pem") val downloadsPath = Utils.downloadsPath("cert.pem")
val content = Utils.getFileContents(downloadsPath) val content = Utils.getFileContents(downloadsPath)
if (content == null) { if (content == null) {
Utils.alertView( alertTitle.value = getString(R.string.error)
ctx, getString(R.string.error), alertMessage.value = getString(R.string.read_cert_error)
getString(R.string.read_cert_error) showAlert.value = true
)
return@Checkbox return@Checkbox
} }
val certPath = BaresipService.filesPath + "/cert.pem" val certPath = BaresipService.filesPath + "/cert.pem"
@@ -607,9 +627,8 @@ class ConfigActivity : ComponentActivity() {
save = true save = true
restart = true restart = true
} }
shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE) -> shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE) -> {
Utils.alertView(ctx, getString(R.string.notice), getString(R.string.no_android_contacts)) { showAlertDialog.value = true
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
} }
else -> else ->
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
@@ -625,10 +644,20 @@ class ConfigActivity : ComponentActivity() {
} }
) )
} }
if (showAlertDialog.value)
AlertDialog(
showDialog = showAlertDialog,
title = getString(R.string.notice),
message = getString(R.string.no_read_permission),
positiveButtonText = getString(R.string.ok),
onPositiveClicked = { requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) },
negativeButtonText = "",
onNegativeClicked = {},
)
} }
@Composable @Composable
private fun VerifyServer(ctx: Context) { private fun VerifyServer() {
Row( Row(
Modifier.fillMaxWidth(), Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
@@ -638,10 +667,9 @@ class ConfigActivity : ComponentActivity() {
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
.clickable { .clickable {
Utils.alertView( alertTitle.value = getString(R.string.verify_server)
ctx, getString(R.string.verify_server), alertMessage.value = getString(R.string.verify_server_help)
getString(R.string.verify_server_help) showAlert.value = true
)
}, },
color = LocalCustomColors.current.itemText, color = LocalCustomColors.current.itemText,
fontSize = 18.sp) fontSize = 18.sp)
@@ -667,10 +695,9 @@ class ConfigActivity : ComponentActivity() {
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
.clickable { .clickable {
Utils.alertView( alertTitle.value = getString(R.string.tls_ca_file)
ctx, getString(R.string.tls_ca_file), alertMessage.value = getString(R.string.tls_ca_file_help)
getString(R.string.tls_certificate_file_help) showAlert.value = true
)
}, },
color = LocalCustomColors.current.itemText, color = LocalCustomColors.current.itemText,
fontSize = 18.sp) fontSize = 18.sp)
@@ -691,24 +718,33 @@ class ConfigActivity : ComponentActivity() {
val downloadsPath = Utils.downloadsPath("ca_certs.crt") val downloadsPath = Utils.downloadsPath("ca_certs.crt")
val content = Utils.getFileContents(downloadsPath) val content = Utils.getFileContents(downloadsPath)
if (content == null) { if (content == null) {
Utils.alertView(ctx, getString(R.string.error), getString(R.string.read_ca_certs_error)) alertTitle.value = getString(R.string.error)
alertMessage.value = getString(R.string.read_ca_certs_error)
showAlert.value = true
return@Checkbox return@Checkbox
} }
caCertsFile.writeBytes(content) caCertsFile.writeBytes(content)
caFile = true caFile = true
restart = true restart = true
} }
shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE) -> shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE) -> {
Utils.alertView(ctx, getString(R.string.notice), getString(R.string.no_android_contacts)) { dialogTitle.value = getString(R.string.notice)
dialogMessage.value = getString(R.string.no_read_permission)
positiveText.value = getString(R.string.ok)
onPositiveClicked.value = {
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
} }
negativeText.value = ""
showDialog.value = true
}
else -> else ->
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
} }
} else { }
else
Utils.selectInputFile(caCertsRequest) Utils.selectInputFile(caCertsRequest)
} }
} else { else {
if (caCertsFile.exists()) if (caCertsFile.exists())
caCertsFile.delete() caCertsFile.delete()
restart = true restart = true
@@ -719,7 +755,7 @@ class ConfigActivity : ComponentActivity() {
} }
@Composable @Composable
private fun UserAgent(ctx: Context) { private fun UserAgent() {
Row( Row(
Modifier Modifier
.fillMaxWidth() .fillMaxWidth()
@@ -739,10 +775,9 @@ class ConfigActivity : ComponentActivity() {
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.clickable { .clickable {
Utils.alertView( alertTitle.value = getString(R.string.user_agent)
ctx, getString(R.string.user_agent), alertMessage.value = getString(R.string.user_agent_help)
getString(R.string.user_agent_help) showAlert.value = true
)
}, },
textStyle = androidx.compose.ui.text.TextStyle( textStyle = androidx.compose.ui.text.TextStyle(
fontSize = 18.sp, color = LocalCustomColors.current.itemText), fontSize = 18.sp, color = LocalCustomColors.current.itemText),
@@ -776,7 +811,7 @@ class ConfigActivity : ComponentActivity() {
} }
@Composable @Composable
private fun BatteryOptimizations(ctx: Context) { private fun BatteryOptimizations() {
Row( Row(
Modifier.fillMaxWidth(), Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
@@ -786,10 +821,9 @@ class ConfigActivity : ComponentActivity() {
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
.clickable { .clickable {
Utils.alertView( alertTitle.value = getString(R.string.battery_optimizations)
ctx, getString(R.string.battery_optimizations), alertMessage.value = getString(R.string.battery_optimizations_help)
getString(R.string.battery_optimizations_help) showAlert.value = true
)
}, },
color = LocalCustomColors.current.itemText, color = LocalCustomColors.current.itemText,
fontSize = 18.sp) fontSize = 18.sp)
@@ -811,7 +845,7 @@ class ConfigActivity : ComponentActivity() {
@RequiresApi(29) @RequiresApi(29)
@Composable @Composable
private fun DefaultDialer(ctx: Context) { private fun DefaultDialer() {
Row( Row(
Modifier.fillMaxWidth(), Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
@@ -821,10 +855,9 @@ class ConfigActivity : ComponentActivity() {
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
.clickable { .clickable {
Utils.alertView( alertTitle.value = getString(R.string.default_phone_app)
ctx, getString(R.string.default_phone_app), alertMessage.value = getString(R.string.default_phone_app_help)
getString(R.string.default_phone_app_help) showAlert.value = true
)
}, },
color = LocalCustomColors.current.itemText, color = LocalCustomColors.current.itemText,
fontSize = 18.sp) fontSize = 18.sp)
@@ -835,9 +868,11 @@ class ConfigActivity : ComponentActivity() {
defaultDialer = it defaultDialer = it
newDefaultDialer = defaultDialer newDefaultDialer = defaultDialer
if (it) { if (it) {
if (!roleManager.isRoleAvailable(RoleManager.ROLE_DIALER)) if (!roleManager.isRoleAvailable(RoleManager.ROLE_DIALER)) {
Utils.alertView(ctx, getString(R.string.notice), alertTitle.value = getString(R.string.alert)
getString(R.string.dialer_role_not_available)) alertMessage.value = getString(R.string.dialer_role_not_available)
showAlert.value = true
}
else else
if (!roleManager.isRoleHeld(RoleManager.ROLE_DIALER)) if (!roleManager.isRoleHeld(RoleManager.ROLE_DIALER))
dialerRoleRequest.launch(roleManager.createRequestRoleIntent(RoleManager.ROLE_DIALER)) dialerRoleRequest.launch(roleManager.createRequestRoleIntent(RoleManager.ROLE_DIALER))
@@ -855,6 +890,7 @@ class ConfigActivity : ComponentActivity() {
@Composable @Composable
private fun Contacts(ctx: Context) { private fun Contacts(ctx: Context) {
val showAlertDialog = remember { mutableStateOf(false) }
Row( Row(
Modifier Modifier
.fillMaxWidth() .fillMaxWidth()
@@ -866,10 +902,9 @@ class ConfigActivity : ComponentActivity() {
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
.clickable { .clickable {
Utils.alertView( alertTitle.value = getString(R.string.contacts)
ctx, getString(R.string.contacts), alertMessage.value = getString(R.string.contacts_help)
getString(R.string.contacts_help) showAlert.value = true
)
}, },
color = LocalCustomColors.current.itemText, color = LocalCustomColors.current.itemText,
fontSize = 18.sp) fontSize = 18.sp)
@@ -908,23 +943,41 @@ class ConfigActivity : ComponentActivity() {
onClick = { onClick = {
isDropDownExpanded.value = false isDropDownExpanded.value = false
val mode = contactValues[index] val mode = contactValues[index]
if (mode != "baresip" && !Utils.checkPermissions(applicationContext, contactsPermissions)) if (mode != "baresip" && !Utils.checkPermissions(applicationContext, contactsPermissions)) {
with(MaterialAlertDialogBuilder(ctx, R.style.AlertDialogTheme)) { dialogTitle.value = getString(R.string.consent_request)
setTitle(getText(R.string.consent_request)) dialogMessage.value = getString(R.string.contacts_consent)
setMessage(getText(R.string.contacts_consent)) positiveText.value = getString(R.string.accept)
setPositiveButton(getText(R.string.accept)) { dialog, _ -> onPositiveClicked.value = {
dialog.dismiss() showDialog.value = false
newContactsMode = mode newContactsMode = mode
askForContactsPermission(ctx) if (ContextCompat.checkSelfPermission(
ctx,
Manifest.permission.READ_CONTACTS
) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(
ctx,
Manifest.permission.WRITE_CONTACTS
) == PackageManager.PERMISSION_GRANTED
) {
Log.d(TAG, "Contacts permissions already granted")
} else {
if (shouldShowRequestPermissionRationale(Manifest.permission.READ_CONTACTS) ||
shouldShowRequestPermissionRationale(Manifest.permission.WRITE_CONTACTS))
showAlertDialog.value = true
else
requestPermissionsLauncher.launch(
arrayOf(
Manifest.permission.READ_CONTACTS,
Manifest.permission.WRITE_CONTACTS
)
)
} }
setNegativeButton(getText(R.string.deny)) { dialog, _ -> }
negativeText.value = getString(R.string.deny)
onNegativeClicked.value = {
itemPosition.intValue = contactValues.indexOf(oldContactsMode) itemPosition.intValue = contactValues.indexOf(oldContactsMode)
dialog.dismiss() negativeText.value = ""
} }
val dialog = this.create() showDialog.value = true
dialog.setCancelable(false)
dialog.setCanceledOnTouchOutside(false)
dialog.show()
} }
else { else {
itemPosition.intValue = index itemPosition.intValue = index
@@ -939,11 +992,26 @@ class ConfigActivity : ComponentActivity() {
} }
} }
} }
if (showAlertDialog.value)
AlertDialog(
showDialog = showAlertDialog,
title = getString(R.string.notice),
message = getString(R.string.no_android_contacts),
positiveButtonText = getString(R.string.ok),
onPositiveClicked = { requestPermissionsLauncher.launch(
arrayOf(
Manifest.permission.READ_CONTACTS,
Manifest.permission.WRITE_CONTACTS
)
)},
negativeButtonText = "",
onNegativeClicked = {},
)
} }
} }
@Composable @Composable
private fun DarkTheme(ctx: Context) { private fun DarkTheme() {
Row( Row(
Modifier.fillMaxWidth(), Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
@@ -953,10 +1021,9 @@ class ConfigActivity : ComponentActivity() {
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
.clickable { .clickable {
Utils.alertView( alertTitle.value = getString(R.string.dark_theme)
ctx, getString(R.string.dark_theme), alertMessage.value = getString(R.string.dark_theme_help)
getString(R.string.dark_theme_help) showAlert.value = true
)
}, },
color = LocalCustomColors.current.itemText, color = LocalCustomColors.current.itemText,
fontSize = 18.sp) fontSize = 18.sp)
@@ -972,7 +1039,7 @@ class ConfigActivity : ComponentActivity() {
} }
@Composable @Composable
private fun Debug(ctx: Context) { private fun Debug() {
Row( Row(
Modifier.fillMaxWidth(), Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
@@ -982,10 +1049,9 @@ class ConfigActivity : ComponentActivity() {
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
.clickable { .clickable {
Utils.alertView( alertTitle.value = getString(R.string.debug)
ctx, getString(R.string.debug), alertMessage.value = getString(R.string.debug_help)
getString(R.string.debug_help) showAlert.value = true
)
}, },
color = LocalCustomColors.current.itemText, color = LocalCustomColors.current.itemText,
fontSize = 18.sp) fontSize = 18.sp)
@@ -1001,7 +1067,7 @@ class ConfigActivity : ComponentActivity() {
} }
@Composable @Composable
private fun SipTrace(ctx: Context) { private fun SipTrace() {
Row( Row(
Modifier.fillMaxWidth(), Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
@@ -1011,10 +1077,9 @@ class ConfigActivity : ComponentActivity() {
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
.clickable { .clickable {
Utils.alertView( alertTitle.value = getString(R.string.sip_trace)
ctx, getString(R.string.sip_trace), alertMessage.value = getString(R.string.sip_trace_help)
getString(R.string.sip_trace_help) showAlert.value = true
)
}, },
color = LocalCustomColors.current.itemText, color = LocalCustomColors.current.itemText,
fontSize = 18.sp) fontSize = 18.sp)
@@ -1030,7 +1095,7 @@ class ConfigActivity : ComponentActivity() {
} }
@Composable @Composable
private fun Reset(ctx: Context) { private fun Reset() {
Row( Row(
Modifier.fillMaxWidth(), Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
@@ -1040,10 +1105,9 @@ class ConfigActivity : ComponentActivity() {
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
.clickable { .clickable {
Utils.alertView( alertTitle.value = getString(R.string.reset_config)
ctx, getString(R.string.reset_config), alertMessage.value = getString(R.string.reset_config_help)
getString(R.string.reset_config_help) showAlert.value = true
)
}, },
color = LocalCustomColors.current.itemText, color = LocalCustomColors.current.itemText,
fontSize = 18.sp) fontSize = 18.sp)
@@ -1051,23 +1115,21 @@ class ConfigActivity : ComponentActivity() {
Checkbox( Checkbox(
checked = reset, checked = reset,
onCheckedChange = { onCheckedChange = {
with(MaterialAlertDialogBuilder(ctx, dialogTitle.value = getString(R.string.confirmation)
R.style.AlertDialogTheme)) { dialogMessage.value = getString(R.string.reset_config_alert)
setTitle(R.string.confirmation) positiveText.value = getString(R.string.reset)
setMessage(getString(R.string.reset_config_alert)) onPositiveClicked.value = {
setPositiveButton(getText(R.string.reset)) { dialog, _ ->
Config.reset() Config.reset()
save = false save = false
restart = true restart = true
done() done()
dialog.dismiss()
} }
setNeutralButton(getText(R.string.cancel)) { dialog, _ -> negativeText.value = getString(R.string.cancel)
onNegativeClicked.value = {
reset = false reset = false
dialog.dismiss() negativeText.value = ""
}
show()
} }
showDialog.value = true
} }
) )
} }
@@ -1087,8 +1149,9 @@ class ConfigActivity : ComponentActivity() {
val listenAddr = newListenAddr.trim() val listenAddr = newListenAddr.trim()
if (listenAddr != oldListenAddr) { if (listenAddr != oldListenAddr) {
if ((listenAddr != "") && !Utils.checkIpPort(listenAddr)) { if ((listenAddr != "") && !Utils.checkIpPort(listenAddr)) {
Utils.alertView(this, getString(R.string.notice), alertTitle.value = getString(R.string.notice)
"${getString(R.string.invalid_listen_address)}: $listenAddr") alertMessage.value = "${getString(R.string.invalid_listen_address)}: $listenAddr"
showAlert.value = true
return return
} }
Config.replaceVariable("sip_listen", listenAddr) Config.replaceVariable("sip_listen", listenAddr)
@@ -1107,8 +1170,9 @@ class ConfigActivity : ComponentActivity() {
dnsServers = addMissingPorts(dnsServers) dnsServers = addMissingPorts(dnsServers)
if (dnsServers != oldDnsServers.replace(" ", "")) { if (dnsServers != oldDnsServers.replace(" ", "")) {
if (!checkDnsServers(dnsServers)) { if (!checkDnsServers(dnsServers)) {
Utils.alertView(this, getString(R.string.notice), alertTitle.value = getString(R.string.notice)
"${getString(R.string.invalid_dns_servers)}: $dnsServers") alertMessage.value = "${getString(R.string.invalid_dns_servers)}: $dnsServers"
showAlert.value = true
return return
} }
Config.removeVariable("dns_server") Config.removeVariable("dns_server")
@@ -1117,8 +1181,9 @@ class ConfigActivity : ComponentActivity() {
Config.addVariable("dns_server", server) Config.addVariable("dns_server", server)
Config.replaceVariable("dyn_dns", "no") Config.replaceVariable("dyn_dns", "no")
if (Api.net_use_nameserver(dnsServers) != 0) { if (Api.net_use_nameserver(dnsServers) != 0) {
Utils.alertView(this, getString(R.string.error), alertTitle.value = getString(R.string.notice)
"${getString(R.string.failed_to_set_dns_servers)}: $dnsServers") alertMessage.value = "${getString(R.string.failed_to_set_dns_servers)}: $dnsServers"
showAlert.value = true
return return
} }
} else { } else {
@@ -1139,8 +1204,9 @@ class ConfigActivity : ComponentActivity() {
newUserAgent = newUserAgent.trim() newUserAgent = newUserAgent.trim()
if (newUserAgent != oldUserAgent) { if (newUserAgent != oldUserAgent) {
if ((newUserAgent != "") && !Utils.checkServerVal(newUserAgent)) { if ((newUserAgent != "") && !Utils.checkServerVal(newUserAgent)) {
Utils.alertView(this, getString(R.string.notice), alertTitle.value = getString(R.string.notice)
"${getString(R.string.invalid_user_agent)}: $newUserAgent") alertMessage.value = "${getString(R.string.invalid_user_agent)}: $newUserAgent"
showAlert.value = true
return return
} }
if (newUserAgent != "") if (newUserAgent != "")
@@ -1219,38 +1285,6 @@ class ConfigActivity : ComponentActivity() {
registerForActivityResult(ActivityResultContracts.RequestPermission()) {} registerForActivityResult(ActivityResultContracts.RequestPermission()) {}
} }
private fun askForContactsPermission(ctx: Context) {
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.READ_CONTACTS
) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(
this,
Manifest.permission.WRITE_CONTACTS
) == PackageManager.PERMISSION_GRANTED
) {
Log.d(TAG, "Contacts permissions already granted")
} else {
if (shouldShowRequestPermissionRationale(Manifest.permission.READ_CONTACTS) ||
shouldShowRequestPermissionRationale(Manifest.permission.WRITE_CONTACTS)) {
Utils.alertView(ctx, getString(R.string.notice), getString(R.string.no_android_contacts)
) {
requestPermissionsLauncher.launch(
arrayOf(
Manifest.permission.READ_CONTACTS,
Manifest.permission.WRITE_CONTACTS
)
)
}
} else
requestPermissionsLauncher.launch(
arrayOf(
Manifest.permission.READ_CONTACTS,
Manifest.permission.WRITE_CONTACTS
)
)
}
}
private fun isAppearOnTopPermissionGranted(ctx: Context): Boolean { private fun isAppearOnTopPermissionGranted(ctx: Context): Boolean {
return Settings.canDrawOverlays(ctx) return Settings.canDrawOverlays(ctx)
} }