diff --git a/app/src/main/kotlin/com/tutpro/baresip/AccountActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/AccountActivity.kt index 0ae0784f..573638d6 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/AccountActivity.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/AccountActivity.kt @@ -3,6 +3,7 @@ package com.tutpro.baresip import android.content.Context import android.content.Intent import android.os.Bundle +import android.widget.Toast import androidx.activity.ComponentActivity import androidx.activity.OnBackPressedCallback import androidx.activity.compose.setContent @@ -13,27 +14,35 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.safeDrawingPadding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Check +import androidx.compose.material3.AlertDialogDefaults +import androidx.compose.material3.BasicAlertDialog import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.OutlinedTextFieldDefaults import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.material3.Text +import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable @@ -44,11 +53,16 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.LocalSoftwareKeyboardController +import androidx.compose.ui.platform.SoftwareKeyboardController import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.text.input.KeyboardType @@ -116,6 +130,9 @@ class AccountActivity : ComponentActivity() { private var oldDefaultAccount = false private var newDefaultAccount = false private var arrowTint = Color.Unspecified + private var showPasswordDialog = mutableStateOf(false) + private var keyboardController: SoftwareKeyboardController? = null + private val onBackPressedCallback = object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { @@ -153,6 +170,7 @@ class AccountActivity : ComponentActivity() { setContent { AppTheme { + keyboardController = LocalSoftwareKeyboardController.current Surface( modifier = Modifier.fillMaxSize(), color = LocalCustomColors.current.background @@ -283,6 +301,7 @@ class AccountActivity : ComponentActivity() { CountryCode(ctx) TelProvider(ctx) DefaultAccount() + AskPassword(ctx) } } @@ -298,7 +317,7 @@ class AccountActivity : ComponentActivity() { enabled = false, onValueChange = {}, modifier = Modifier.fillMaxWidth(), - textStyle = androidx.compose.ui.text.TextStyle( + textStyle = TextStyle( fontSize = 18.sp, color = LocalCustomColors.current.itemText ), @@ -327,7 +346,7 @@ class AccountActivity : ComponentActivity() { .clickable { Utils.alertView(ctx, getString(R.string.nickname), getString(R.string.account_nickname_help)) }, - textStyle = androidx.compose.ui.text.TextStyle( + textStyle = TextStyle( fontSize = 18.sp, color = LocalCustomColors.current.itemText), label = { Text(stringResource(R.string.nickname)) }, keyboardOptions = KeyboardOptions( @@ -357,7 +376,7 @@ class AccountActivity : ComponentActivity() { .clickable { Utils.alertView(ctx, getString(R.string.display_name), getString(R.string.display_name_help)) }, - textStyle = androidx.compose.ui.text.TextStyle( + textStyle = TextStyle( fontSize = 18.sp, color = LocalCustomColors.current.itemText), label = { Text(stringResource(R.string.display_name)) }, keyboardOptions = KeyboardOptions( @@ -387,7 +406,7 @@ class AccountActivity : ComponentActivity() { .clickable { Utils.alertView(ctx, getString(R.string.authentication_username), getString(R.string.authentication_username_help)) }, - textStyle = androidx.compose.ui.text.TextStyle( + textStyle = TextStyle( fontSize = 18.sp, color = LocalCustomColors.current.itemText), label = { Text(stringResource(R.string.authentication_username)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) @@ -436,7 +455,7 @@ class AccountActivity : ComponentActivity() { .clickable { Utils.alertView(ctx, getString(R.string.authentication_password), getString(R.string.authentication_password_help)) }, - textStyle = androidx.compose.ui.text.TextStyle( + textStyle = TextStyle( fontSize = 18.sp, color = LocalCustomColors.current.itemText), label = { Text(stringResource(R.string.authentication_password)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) @@ -476,7 +495,7 @@ class AccountActivity : ComponentActivity() { }, modifier = Modifier.fillMaxWidth(), singleLine = true, - textStyle = androidx.compose.ui.text.TextStyle( + textStyle = TextStyle( fontSize = 18.sp, color = LocalCustomColors.current.itemText), label = { Text(stringResource(R.string.sip_uri_of_proxy_server)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) @@ -498,7 +517,7 @@ class AccountActivity : ComponentActivity() { }, modifier = Modifier.fillMaxWidth(), singleLine = true, - textStyle = androidx.compose.ui.text.TextStyle( + textStyle = TextStyle( fontSize = 18.sp, color = LocalCustomColors.current.itemText), label = { Text(stringResource(R.string.sip_uri_of_another_proxy_server)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) @@ -553,7 +572,7 @@ class AccountActivity : ComponentActivity() { .clickable { Utils.alertView(ctx, getString(R.string.reg_int), getString(R.string.reg_int_help)) }, - textStyle = androidx.compose.ui.text.TextStyle( + textStyle = TextStyle( fontSize = 18.sp, color = LocalCustomColors.current.itemText), label = { Text(stringResource(R.string.reg_int)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number) @@ -727,7 +746,7 @@ class AccountActivity : ComponentActivity() { .clickable { Utils.alertView(ctx, getString(R.string.stun_server), getString(R.string.stun_server_help)) }, - textStyle = androidx.compose.ui.text.TextStyle( + textStyle = TextStyle( fontSize = 18.sp, color = LocalCustomColors.current.itemText), label = { Text(stringResource(R.string.stun_server)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) @@ -755,7 +774,7 @@ class AccountActivity : ComponentActivity() { .clickable { Utils.alertView(ctx, getString(R.string.stun_username), getString(R.string.stun_username_help)) }, - textStyle = androidx.compose.ui.text.TextStyle( + textStyle = TextStyle( fontSize = 18.sp, color = LocalCustomColors.current.itemText), label = { Text(stringResource(R.string.stun_username)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) @@ -808,7 +827,7 @@ class AccountActivity : ComponentActivity() { .clickable { Utils.alertView(ctx, getString(R.string.stun_password), getString(R.string.stun_password_help)) }, - textStyle = androidx.compose.ui.text.TextStyle( + textStyle = TextStyle( fontSize = 18.sp, color = LocalCustomColors.current.itemText), label = { Text(stringResource(R.string.stun_password)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) @@ -1058,7 +1077,7 @@ class AccountActivity : ComponentActivity() { .clickable { Utils.alertView(ctx, getString(R.string.voicemail_uri), getString(R.string.voicemain_uri_help)) }, - textStyle = androidx.compose.ui.text.TextStyle( + textStyle = TextStyle( fontSize = 18.sp, color = LocalCustomColors.current.itemText), label = { Text(stringResource(R.string.voicemail_uri)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) @@ -1086,7 +1105,7 @@ class AccountActivity : ComponentActivity() { .clickable { Utils.alertView(ctx, getString(R.string.country_code), getString(R.string.country_code_help)) }, - textStyle = androidx.compose.ui.text.TextStyle( + textStyle = TextStyle( fontSize = 18.sp, color = LocalCustomColors.current.itemText), label = { Text(stringResource(R.string.country_code)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) @@ -1114,7 +1133,7 @@ class AccountActivity : ComponentActivity() { .clickable { Utils.alertView(ctx, getString(R.string.telephony_provider), getString(R.string.telephony_provider_help)) }, - textStyle = androidx.compose.ui.text.TextStyle( + textStyle = TextStyle( fontSize = 18.sp, color = LocalCustomColors.current.itemText), label = { Text(stringResource(R.string.telephony_provider)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) @@ -1144,6 +1163,142 @@ class AccountActivity : ComponentActivity() { } } + @OptIn(ExperimentalMaterial3Api::class) + @Composable + fun AskPassword(ctx: Context) { + if (showPasswordDialog.value) { + val showPassword = remember { mutableStateOf(false) } + BasicAlertDialog( + onDismissRequest = { + keyboardController?.hide() + showPasswordDialog.value = false + } + ) { + Surface( + modifier = Modifier + .wrapContentWidth() + .wrapContentHeight(), + color = LocalCustomColors.current.background, + shape = MaterialTheme.shapes.large, + tonalElevation = AlertDialogDefaults.TonalElevation + ) { + Column(modifier = Modifier.padding(16.dp)) { + CustomElements.Text( + text = getString(R.string.authentication_password), + fontSize = 20.sp, + modifier = Modifier.padding(top = 16.dp, bottom = 16.dp), + color = LocalCustomColors.current.alert, + ) + val message = getString(R.string.account) + " " + Utils.plainAor(acc.aor) + CustomElements.Text( + text = message, + fontSize = 16.sp, + modifier = Modifier.padding(16.dp), + color = LocalCustomColors.current.itemText, + ) + var password by remember { mutableStateOf("") } + val focusRequester = remember { FocusRequester() } + OutlinedTextField( + value = password, + singleLine = true, + colors = OutlinedTextFieldDefaults.colors( + focusedContainerColor = LocalCustomColors.current.textFieldBackground, + unfocusedContainerColor = LocalCustomColors.current.textFieldBackground, + cursorColor = LocalCustomColors.current.primary, + ), + onValueChange = { + password = it + }, + visualTransformation = if (showPassword.value) + VisualTransformation.None + else + PasswordVisualTransformation(), + trailingIcon = { + IconButton(onClick = { + showPassword.value = !showPassword.value + }) { + Icon( + if (showPassword.value) + ImageVector.vectorResource(R.drawable.visibility) + else + ImageVector.vectorResource(R.drawable.visibility_off), + contentDescription = "Visibility", + tint = LocalCustomColors.current.grayDark + + ) + } + }, + modifier = Modifier + .fillMaxWidth() + .padding( + start = 4.dp, + end = 4.dp, + top = 12.dp, + bottom = 2.dp + ) + .focusRequester(focusRequester), + textStyle = TextStyle( + fontSize = 18.sp, + color = LocalCustomColors.current.dark + ), + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) + ) + Row( + horizontalArrangement = Arrangement.Start + ) { + TextButton( + onClick = { + keyboardController?.hide() + showPasswordDialog.value = false + reRegister = true + finishActivity() + }, + modifier = Modifier.padding(8.dp), + ) { + CustomElements.Text( + text = stringResource(R.string.cancel), + color = LocalCustomColors.current.gray + ) + } + Spacer(modifier = Modifier.weight(1f)) + TextButton( + onClick = { + keyboardController?.hide() + showPasswordDialog.value = false + password = password.trim() + if (!Account.checkAuthPass(password)) { + Toast.makeText( + ctx, + String.format( + getString(R.string.invalid_authentication_password), + password + ), + Toast.LENGTH_SHORT + ).show() + password = "" + showPasswordDialog.value = true + } + else { + BaresipService.aorPasswords[acc.aor] = password + Api.account_set_auth_pass(acc.accp, password) + reRegister = true + finishActivity() + } + }, + modifier = Modifier.padding(8.dp), + ) { + CustomElements.Text( + text = stringResource(R.string.ok), + color = LocalCustomColors.current.alert + ) + } + } + } + } + } + } + } + private fun updateAccount() { if (BaresipService.activities.indexOf("account,$aor") == -1) @@ -1218,7 +1373,8 @@ class AccountActivity : ComponentActivity() { String.format(getString(R.string.invalid_authentication_password), ap)) return } - } else { + } + else { BaresipService.aorPasswords.remove(acc.aor) } } else { // ap == "" @@ -1465,6 +1621,13 @@ class AccountActivity : ComponentActivity() { AccountsActivity.saveAccounts() + if (acc.authUser != "" && BaresipService.aorPasswords[aor] == NO_AUTH_PASS) + showPasswordDialog.value = true + else + finishActivity() + } + + private fun finishActivity() { if (reRegister) { ua.status = R.drawable.circle_yellow if (acc.regint == 0) @@ -1472,7 +1635,6 @@ class AccountActivity : ComponentActivity() { else Api.ua_register(ua.uap) } - BaresipService.activities.remove("account,$aor") returnResult(RESULT_OK) } diff --git a/app/src/main/kotlin/com/tutpro/baresip/CustomElements.kt b/app/src/main/kotlin/com/tutpro/baresip/CustomElements.kt index e43cf2f4..94e688ba 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/CustomElements.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/CustomElements.kt @@ -1,6 +1,5 @@ package com.tutpro.baresip -import android.content.Context import android.graphics.Bitmap import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.tween @@ -14,18 +13,11 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row 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.layout.Spacer import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.AlertDialog -import androidx.compose.material3.AlertDialogDefaults -import androidx.compose.material3.BasicAlertDialog import androidx.compose.material3.Button import androidx.compose.material3.Card import androidx.compose.material3.Checkbox @@ -34,8 +26,6 @@ import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface import androidx.compose.material3.TextButton import androidx.compose.material3.pulltorefresh.PullToRefreshDefaults.Indicator import androidx.compose.material3.pulltorefresh.pullToRefresh @@ -65,8 +55,6 @@ import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.compose.ui.window.Dialog -import androidx.core.content.ContextCompat.getString -import com.tutpro.baresip.CustomElements.Text import com.tutpro.baresip.CustomElements.ThreeButtonAlertDialog object CustomElements { diff --git a/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt index 29f46577..84c0d286 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt @@ -314,14 +314,6 @@ class MainActivity : ComponentActivity() { spinToAor(activityAor) val ua = UserAgent.ofAor(viewModel.selectedAor.value)!! updateIcons(ua.account) - if (it.resultCode == RESULT_OK) - if (BaresipService.aorPasswords[activityAor] == NO_AUTH_PASS) { - passwordAccounts = String( - Utils.getFileContents(filesDir.absolutePath + "/accounts")!!, - Charsets.UTF_8 - ).lines().toMutableList() - showPasswordsDialog.value = true - } } contactsRequest = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {