Completed composting alert of dialogs (testing still needed)
UI improvements
This commit is contained in:
@@ -63,6 +63,7 @@ import androidx.compose.ui.unit.sp
|
|||||||
import com.tutpro.baresip.BaresipService.Companion.uas
|
import com.tutpro.baresip.BaresipService.Companion.uas
|
||||||
import com.tutpro.baresip.CustomElements.AlertDialog
|
import com.tutpro.baresip.CustomElements.AlertDialog
|
||||||
import com.tutpro.baresip.CustomElements.Checkbox
|
import com.tutpro.baresip.CustomElements.Checkbox
|
||||||
|
import com.tutpro.baresip.CustomElements.LabelText
|
||||||
import com.tutpro.baresip.CustomElements.verticalScrollbar
|
import com.tutpro.baresip.CustomElements.verticalScrollbar
|
||||||
|
|
||||||
class AccountActivity : ComponentActivity() {
|
class AccountActivity : ComponentActivity() {
|
||||||
@@ -334,7 +335,10 @@ class AccountActivity : ComponentActivity() {
|
|||||||
fontSize = 18.sp,
|
fontSize = 18.sp,
|
||||||
color = LocalCustomColors.current.itemText
|
color = LocalCustomColors.current.itemText
|
||||||
),
|
),
|
||||||
label = { Text(stringResource(R.string.sip_uri)) }
|
label = {
|
||||||
|
LabelText(text = stringResource(R.string.sip_uri),
|
||||||
|
fontWeight = FontWeight.Bold)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -362,7 +366,7 @@ class AccountActivity : ComponentActivity() {
|
|||||||
showAlert.value = true },
|
showAlert.value = true },
|
||||||
textStyle = TextStyle(
|
textStyle = TextStyle(
|
||||||
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
||||||
label = { Text(stringResource(R.string.nickname)) },
|
label = { LabelText(stringResource(R.string.nickname)) },
|
||||||
keyboardOptions = KeyboardOptions(
|
keyboardOptions = KeyboardOptions(
|
||||||
capitalization = KeyboardCapitalization.Sentences,
|
capitalization = KeyboardCapitalization.Sentences,
|
||||||
keyboardType = KeyboardType.Text),
|
keyboardType = KeyboardType.Text),
|
||||||
@@ -393,7 +397,7 @@ class AccountActivity : ComponentActivity() {
|
|||||||
showAlert.value = true },
|
showAlert.value = true },
|
||||||
textStyle = TextStyle(
|
textStyle = TextStyle(
|
||||||
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
||||||
label = { Text(stringResource(R.string.display_name)) },
|
label = { LabelText(stringResource(R.string.display_name)) },
|
||||||
keyboardOptions = KeyboardOptions(
|
keyboardOptions = KeyboardOptions(
|
||||||
capitalization = KeyboardCapitalization.Sentences,
|
capitalization = KeyboardCapitalization.Sentences,
|
||||||
keyboardType = KeyboardType.Text),
|
keyboardType = KeyboardType.Text),
|
||||||
@@ -424,7 +428,7 @@ class AccountActivity : ComponentActivity() {
|
|||||||
showAlert.value = true },
|
showAlert.value = true },
|
||||||
textStyle = TextStyle(
|
textStyle = TextStyle(
|
||||||
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
||||||
label = { Text(stringResource(R.string.authentication_username)) },
|
label = { LabelText(stringResource(R.string.authentication_username)) },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -474,7 +478,7 @@ class AccountActivity : ComponentActivity() {
|
|||||||
showAlert.value = true },
|
showAlert.value = true },
|
||||||
textStyle = TextStyle(
|
textStyle = TextStyle(
|
||||||
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
||||||
label = { Text(stringResource(R.string.authentication_password)) },
|
label = { LabelText(stringResource(R.string.authentication_password)) },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -509,7 +513,7 @@ class AccountActivity : ComponentActivity() {
|
|||||||
singleLine = true,
|
singleLine = true,
|
||||||
textStyle = TextStyle(
|
textStyle = TextStyle(
|
||||||
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
||||||
label = { Text(stringResource(R.string.sip_uri_of_proxy_server)) },
|
label = { LabelText(stringResource(R.string.sip_uri_of_proxy_server)) },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -531,7 +535,7 @@ class AccountActivity : ComponentActivity() {
|
|||||||
singleLine = true,
|
singleLine = true,
|
||||||
textStyle = TextStyle(
|
textStyle = TextStyle(
|
||||||
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
||||||
label = { Text(stringResource(R.string.sip_uri_of_another_proxy_server)) },
|
label = { LabelText(stringResource(R.string.sip_uri_of_another_proxy_server)) },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -587,7 +591,7 @@ class AccountActivity : ComponentActivity() {
|
|||||||
showAlert.value = true },
|
showAlert.value = true },
|
||||||
textStyle = TextStyle(
|
textStyle = TextStyle(
|
||||||
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
||||||
label = { Text(stringResource(R.string.reg_int)) },
|
label = { LabelText(stringResource(R.string.reg_int)) },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -764,7 +768,7 @@ class AccountActivity : ComponentActivity() {
|
|||||||
showAlert.value = true },
|
showAlert.value = true },
|
||||||
textStyle = TextStyle(
|
textStyle = TextStyle(
|
||||||
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
||||||
label = { Text(stringResource(R.string.stun_server)) },
|
label = { LabelText(stringResource(R.string.stun_server)) },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -793,7 +797,7 @@ class AccountActivity : ComponentActivity() {
|
|||||||
showAlert.value = true },
|
showAlert.value = true },
|
||||||
textStyle = TextStyle(
|
textStyle = TextStyle(
|
||||||
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
||||||
label = { Text(stringResource(R.string.stun_username)) },
|
label = { LabelText(stringResource(R.string.stun_username)) },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -847,7 +851,7 @@ class AccountActivity : ComponentActivity() {
|
|||||||
showAlert.value = true },
|
showAlert.value = true },
|
||||||
textStyle = TextStyle(
|
textStyle = TextStyle(
|
||||||
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
||||||
label = { Text(stringResource(R.string.stun_password)) },
|
label = { LabelText(stringResource(R.string.stun_password)) },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1111,7 +1115,7 @@ class AccountActivity : ComponentActivity() {
|
|||||||
showAlert.value = true },
|
showAlert.value = true },
|
||||||
textStyle = TextStyle(
|
textStyle = TextStyle(
|
||||||
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
||||||
label = { Text(stringResource(R.string.voicemail_uri)) },
|
label = { LabelText(stringResource(R.string.voicemail_uri)) },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1140,7 +1144,7 @@ class AccountActivity : ComponentActivity() {
|
|||||||
showAlert.value = true },
|
showAlert.value = true },
|
||||||
textStyle = TextStyle(
|
textStyle = TextStyle(
|
||||||
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
||||||
label = { Text(stringResource(R.string.country_code)) },
|
label = { LabelText(stringResource(R.string.country_code)) },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1169,7 +1173,7 @@ class AccountActivity : ComponentActivity() {
|
|||||||
showAlert.value = true },
|
showAlert.value = true },
|
||||||
textStyle = TextStyle(
|
textStyle = TextStyle(
|
||||||
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
||||||
label = { Text(stringResource(R.string.telephony_provider)) },
|
label = { LabelText(stringResource(R.string.telephony_provider)) },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,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 com.tutpro.baresip.CustomElements.AlertDialog
|
import com.tutpro.baresip.CustomElements.AlertDialog
|
||||||
|
import com.tutpro.baresip.CustomElements.LabelText
|
||||||
import com.tutpro.baresip.CustomElements.verticalScrollbar
|
import com.tutpro.baresip.CustomElements.verticalScrollbar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -283,12 +284,7 @@ class AccountsActivity : ComponentActivity() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
label = {
|
label = { LabelText(stringResource(R.string.new_account)) },
|
||||||
CustomElements.Text(
|
|
||||||
text = getString(R.string.new_account),
|
|
||||||
fontSize = 18.sp
|
|
||||||
)
|
|
||||||
},
|
|
||||||
textStyle = TextStyle(fontSize = 18.sp),
|
textStyle = TextStyle(fontSize = 18.sp),
|
||||||
keyboardOptions = KeyboardOptions(
|
keyboardOptions = KeyboardOptions(
|
||||||
keyboardType = KeyboardType.Text,
|
keyboardType = KeyboardType.Text,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.tutpro.baresip
|
package com.tutpro.baresip
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.activity.OnBackPressedCallback
|
||||||
@@ -103,7 +102,7 @@ class AudioActivity : ComponentActivity() {
|
|||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
color = LocalCustomColors.current.background
|
color = LocalCustomColors.current.background
|
||||||
) {
|
) {
|
||||||
AudioScreen(this, title) { goBack() }
|
AudioScreen(title) { goBack() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,7 +111,7 @@ class AudioActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AudioScreen(ctx: Context, title: String, navigateBack: () -> Unit) {
|
fun AudioScreen(title: String, navigateBack: () -> Unit) {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
@@ -448,7 +447,7 @@ class AudioActivity : ComponentActivity() {
|
|||||||
},
|
},
|
||||||
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),
|
||||||
label = { LabelText(getString(R.string.audio_delay)) },
|
label = { LabelText(stringResource(R.string.audio_delay)) },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ import androidx.compose.ui.unit.sp
|
|||||||
import androidx.core.graphics.scale
|
import androidx.core.graphics.scale
|
||||||
import androidx.exifinterface.media.ExifInterface
|
import androidx.exifinterface.media.ExifInterface
|
||||||
import coil.compose.rememberAsyncImagePainter
|
import coil.compose.rememberAsyncImagePainter
|
||||||
|
import com.tutpro.baresip.CustomElements.AlertDialog
|
||||||
import com.tutpro.baresip.CustomElements.Checkbox
|
import com.tutpro.baresip.CustomElements.Checkbox
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -86,7 +87,6 @@ class BaresipContactActivity : ComponentActivity() {
|
|||||||
private var new = false
|
private var new = false
|
||||||
private var favorite = false
|
private var favorite = false
|
||||||
private var android = false
|
private var android = false
|
||||||
private var avatarImage: Bitmap? = null
|
|
||||||
private var newName = ""
|
private var newName = ""
|
||||||
private var newUri = ""
|
private var newUri = ""
|
||||||
private var newFavorite = false
|
private var newFavorite = false
|
||||||
@@ -94,9 +94,17 @@ class BaresipContactActivity : ComponentActivity() {
|
|||||||
private var uriOrName = ""
|
private var uriOrName = ""
|
||||||
private var color = 0
|
private var color = 0
|
||||||
private var id: Long = 0
|
private var id: Long = 0
|
||||||
private var newAvatar = ""
|
private var newId: Long = 0
|
||||||
private var tmpFile: File? = null
|
private var tmpFile: File? = null
|
||||||
|
|
||||||
|
private val alertTitle = mutableStateOf("")
|
||||||
|
private val alertMessage = mutableStateOf("")
|
||||||
|
private val showAlert = mutableStateOf(false)
|
||||||
|
|
||||||
|
private val textAvatarText = mutableStateOf("")
|
||||||
|
private val textAvatarColor = mutableIntStateOf(0)
|
||||||
|
private val imageAvatarUri = mutableStateOf("")
|
||||||
|
|
||||||
private val onBackPressedCallback = object : OnBackPressedCallback(true) {
|
private val onBackPressedCallback = object : OnBackPressedCallback(true) {
|
||||||
override fun handleOnBackPressed() {
|
override fun handleOnBackPressed() {
|
||||||
goBack()
|
goBack()
|
||||||
@@ -117,23 +125,29 @@ class BaresipContactActivity : ComponentActivity() {
|
|||||||
name = ""
|
name = ""
|
||||||
uri = intent.getStringExtra("uri")!!
|
uri = intent.getStringExtra("uri")!!
|
||||||
favorite = false
|
favorite = false
|
||||||
avatarImage = null
|
|
||||||
android = BaresipService.contactsMode == "android"
|
android = BaresipService.contactsMode == "android"
|
||||||
title = getString(R.string.new_contact)
|
title = getString(R.string.new_contact)
|
||||||
uriOrName = uri
|
uriOrName = uri
|
||||||
color = Utils.randomColor()
|
color = Utils.randomColor()
|
||||||
id = System.currentTimeMillis()
|
id = System.currentTimeMillis()
|
||||||
} else {
|
newId = id
|
||||||
|
}
|
||||||
|
else {
|
||||||
name = intent.getStringExtra("name")!!
|
name = intent.getStringExtra("name")!!
|
||||||
val contact = Contact.baresipContact(name)!!
|
val contact = Contact.baresipContact(name)!!
|
||||||
uri = contact.uri
|
uri = contact.uri
|
||||||
favorite = contact.favorite
|
favorite = contact.favorite
|
||||||
avatarImage = contact.avatarImage
|
|
||||||
android = false
|
android = false
|
||||||
title = name
|
title = name
|
||||||
uriOrName = name
|
uriOrName = name
|
||||||
color = contact.color
|
color = contact.color
|
||||||
id = contact.id
|
id = contact.id
|
||||||
|
newId = id
|
||||||
|
if (contact.avatarImage != null) {
|
||||||
|
val avatarFile = File(BaresipService.filesPath, "${newId}.png")
|
||||||
|
if (avatarFile.exists())
|
||||||
|
imageAvatarUri.value = Uri.fromFile(avatarFile).toString()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setContent {
|
setContent {
|
||||||
@@ -159,7 +173,7 @@ class BaresipContactActivity : ComponentActivity() {
|
|||||||
containerColor = LocalCustomColors.current.background,
|
containerColor = LocalCustomColors.current.background,
|
||||||
topBar = { TopAppBar(ctx, title, navigateBack) },
|
topBar = { TopAppBar(ctx, title, navigateBack) },
|
||||||
content = { contentPadding ->
|
content = { contentPadding ->
|
||||||
ContactContent(ctx, contentPadding)
|
ContactContent(contentPadding)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -203,13 +217,60 @@ class BaresipContactActivity : ComponentActivity() {
|
|||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun ContactContent(ctx: Context, contentPadding: PaddingValues) {
|
fun ContactContent(contentPadding: PaddingValues) {
|
||||||
|
|
||||||
var avatarType by remember { mutableStateOf(if (avatarImage != null) "image" else "text") }
|
if (showAlert.value) {
|
||||||
var textAvatarText by remember { mutableStateOf("") }
|
AlertDialog(
|
||||||
var textAvatarColor by remember { mutableIntStateOf(0) }
|
showDialog = showAlert,
|
||||||
var imageAvatarUri by remember { mutableStateOf("") }
|
title = alertTitle.value,
|
||||||
|
message = alertMessage.value,
|
||||||
|
positiveButtonText = stringResource(R.string.ok),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.background(LocalCustomColors.current.background)
|
||||||
|
.padding(contentPadding)
|
||||||
|
.padding(start = 16.dp, end = 16.dp, top = 16.dp, bottom = 52.dp),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||||
|
) {
|
||||||
|
Avatar()
|
||||||
|
ContactName()
|
||||||
|
ContactUri()
|
||||||
|
Favorite()
|
||||||
|
Android()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TextAvatar(size: Int) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.size(size.dp),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Canvas(modifier = Modifier.fillMaxSize()) {
|
||||||
|
drawCircle(SolidColor(Color(textAvatarColor.intValue)))
|
||||||
|
}
|
||||||
|
Text(textAvatarText.value, fontSize = 72.sp, color = Color.White)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ImageAvatar(size: Int) {
|
||||||
|
Image(
|
||||||
|
painter = rememberAsyncImagePainter(model = imageAvatarUri.value),
|
||||||
|
contentDescription = stringResource(R.string.avatar_image),
|
||||||
|
contentScale = ContentScale.Crop,
|
||||||
|
modifier = Modifier.size(size.dp).clip(CircleShape)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
|
@Composable
|
||||||
|
fun Avatar() {
|
||||||
val avatarRequest =
|
val avatarRequest =
|
||||||
rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) {
|
rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) {
|
||||||
if (it != null)
|
if (it != null)
|
||||||
@@ -224,67 +285,22 @@ class BaresipContactActivity : ComponentActivity() {
|
|||||||
ExifInterface.ORIENTATION_NORMAL
|
ExifInterface.ORIENTATION_NORMAL
|
||||||
)
|
)
|
||||||
val rotatedBitmap = rotateBitmap(scaledBitmap, orientation)
|
val rotatedBitmap = rotateBitmap(scaledBitmap, orientation)
|
||||||
tmpFile = File(
|
if (tmpFile != null && tmpFile!!.exists())
|
||||||
BaresipService.filesPath + "/tmp",
|
Utils.deleteFile(tmpFile!!)
|
||||||
"${System.currentTimeMillis()}.png"
|
newId = System.currentTimeMillis()
|
||||||
)
|
tmpFile = File(BaresipService.filesPath, "${newId}.png")
|
||||||
if (Utils.saveBitmap(rotatedBitmap, tmpFile!!)) {
|
if (Utils.saveBitmap(rotatedBitmap, tmpFile!!)) {
|
||||||
newAvatar = "image"
|
imageAvatarUri.value = Uri.fromFile(tmpFile).toString()
|
||||||
avatarType = newAvatar
|
|
||||||
imageAvatarUri = Uri.fromFile(tmpFile).toString()
|
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Could not read avatar image: ${e.message}")
|
Log.e(TAG, "Could not read avatar image: ${e.message}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun TextAvatar(size: Int) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier.size(size.dp),
|
|
||||||
contentAlignment = Alignment.Center
|
|
||||||
) {
|
|
||||||
Canvas(modifier = Modifier.fillMaxSize()) {
|
|
||||||
drawCircle(SolidColor(Color(textAvatarColor)))
|
|
||||||
}
|
|
||||||
textAvatarText = if (name == "") "?" else name[0].toString()
|
|
||||||
Text(textAvatarText, fontSize = 72.sp, color = Color.White)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ImageAvatar(size: Int) {
|
|
||||||
Image(
|
|
||||||
painter = rememberAsyncImagePainter(model = imageAvatarUri),
|
|
||||||
contentDescription = stringResource(R.string.avatar_image),
|
|
||||||
contentScale = ContentScale.Crop,
|
|
||||||
modifier = Modifier.size(size.dp).clip(CircleShape)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun avatar() {
|
|
||||||
Row(
|
Row(
|
||||||
Modifier.fillMaxWidth(),
|
Modifier.fillMaxWidth(),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.Center
|
horizontalArrangement = Arrangement.Center
|
||||||
) {
|
) {
|
||||||
if (new)
|
|
||||||
textAvatarColor = color
|
|
||||||
else {
|
|
||||||
val avatarImage = avatarImage
|
|
||||||
val avatarFile = File(BaresipService.filesPath, "${id}.png")
|
|
||||||
if (avatarImage != null && (newAvatar == "" || newAvatar == "image")) {
|
|
||||||
imageAvatarUri = if (tmpFile != null && tmpFile!!.exists())
|
|
||||||
Uri.fromFile(tmpFile).toString()
|
|
||||||
else
|
|
||||||
Uri.fromFile(avatarFile).toString()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
textAvatarText = "${name[0]}"
|
|
||||||
textAvatarColor = color
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Box(
|
Box(
|
||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
modifier = Modifier.size(96.dp)
|
modifier = Modifier.size(96.dp)
|
||||||
@@ -293,23 +309,27 @@ class BaresipContactActivity : ComponentActivity() {
|
|||||||
avatarRequest.launch("image/*")
|
avatarRequest.launch("image/*")
|
||||||
},
|
},
|
||||||
onLongClick = {
|
onLongClick = {
|
||||||
textAvatarColor = Utils.randomColor()
|
textAvatarColor.intValue = Utils.randomColor()
|
||||||
color = textAvatarColor
|
color = textAvatarColor.intValue
|
||||||
newAvatar = "text"
|
imageAvatarUri.value = ""
|
||||||
avatarType = newAvatar
|
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
if (avatarType == "text")
|
if (imageAvatarUri.value == "") {
|
||||||
TextAvatar(96)
|
textAvatarText.value = if (new)
|
||||||
|
"?"
|
||||||
else
|
else
|
||||||
|
"${name[0]}"
|
||||||
|
textAvatarColor.intValue = color
|
||||||
|
TextAvatar(96)
|
||||||
|
} else
|
||||||
ImageAvatar(96)
|
ImageAvatar(96)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun contactName() {
|
fun ContactName() {
|
||||||
val focusRequester = FocusRequester()
|
val focusRequester = FocusRequester()
|
||||||
var contactName by remember { mutableStateOf(name) }
|
var contactName by remember { mutableStateOf(name) }
|
||||||
newName = contactName
|
newName = contactName
|
||||||
@@ -337,7 +357,7 @@ class BaresipContactActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun contactUri() {
|
fun ContactUri() {
|
||||||
var contactUri by remember { mutableStateOf(uri) }
|
var contactUri by remember { mutableStateOf(uri) }
|
||||||
newUri = contactUri
|
newUri = contactUri
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
@@ -357,7 +377,7 @@ class BaresipContactActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun favorite(ctx: Context) {
|
fun Favorite() {
|
||||||
Row(
|
Row(
|
||||||
Modifier.fillMaxWidth(),
|
Modifier.fillMaxWidth(),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
@@ -367,9 +387,9 @@ class BaresipContactActivity : ComponentActivity() {
|
|||||||
text = stringResource(R.string.favorite),
|
text = stringResource(R.string.favorite),
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
.clickable {
|
.clickable {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.favorite)
|
||||||
ctx, getString(R.string.favorite), getString(R.string.favorite_help)
|
alertMessage.value = getString(R.string.favorite_help)
|
||||||
)
|
showAlert.value = true
|
||||||
},
|
},
|
||||||
color = LocalCustomColors.current.itemText,
|
color = LocalCustomColors.current.itemText,
|
||||||
)
|
)
|
||||||
@@ -386,7 +406,7 @@ class BaresipContactActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun android() {
|
fun Android() {
|
||||||
if (new && BaresipService.contactsMode != "baresip")
|
if (new && BaresipService.contactsMode != "baresip")
|
||||||
Row(
|
Row(
|
||||||
Modifier.fillMaxWidth(),
|
Modifier.fillMaxWidth(),
|
||||||
@@ -412,22 +432,6 @@ class BaresipContactActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.background(LocalCustomColors.current.background)
|
|
||||||
.padding(contentPadding)
|
|
||||||
.padding(start = 16.dp, end = 16.dp, top = 16.dp, bottom = 52.dp),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
|
||||||
) {
|
|
||||||
avatar()
|
|
||||||
contactName()
|
|
||||||
contactUri()
|
|
||||||
favorite(ctx)
|
|
||||||
android()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkOnClick(ctx: Context) {
|
private fun checkOnClick(ctx: Context) {
|
||||||
if (BaresipService.activities.indexOf("baresip contact,$new,$uriOrName") == -1)
|
if (BaresipService.activities.indexOf("baresip contact,$new,$uriOrName") == -1)
|
||||||
return
|
return
|
||||||
@@ -439,20 +443,18 @@ class BaresipContactActivity : ComponentActivity() {
|
|||||||
else
|
else
|
||||||
"sip:$newUri"
|
"sip:$newUri"
|
||||||
if (!Utils.checkUri(newUri)) {
|
if (!Utils.checkUri(newUri)) {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.notice)
|
||||||
ctx, getString(R.string.notice),
|
alertMessage.value = String.format(getString(R.string.invalid_sip_or_tel_uri), newUri)
|
||||||
String.format(getString(R.string.invalid_sip_or_tel_uri), newUri)
|
showAlert.value = true
|
||||||
)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
newName = newName.trim()
|
newName = newName.trim()
|
||||||
if (newName == "") newName = newUri.substringAfter(":")
|
if (newName == "") newName = newUri.substringAfter(":")
|
||||||
if (!Utils.checkName(newName)) {
|
if (!Utils.checkName(newName)) {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.notice)
|
||||||
ctx, getString(R.string.notice),
|
alertMessage.value = String.format(getString(R.string.invalid_contact), newName)
|
||||||
String.format(getString(R.string.invalid_contact), newName)
|
showAlert.value = true
|
||||||
)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,39 +464,25 @@ class BaresipContactActivity : ComponentActivity() {
|
|||||||
(uriOrName != newName) && Contact.nameExists(newName, BaresipService.contacts, false)
|
(uriOrName != newName) && Contact.nameExists(newName, BaresipService.contacts, false)
|
||||||
}
|
}
|
||||||
if (alert) {
|
if (alert) {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.notice)
|
||||||
ctx, getString(R.string.notice),
|
alertMessage.value = String.format(getString(R.string.contact_already_exists), newName)
|
||||||
String.format(getString(R.string.contact_already_exists), newName))
|
showAlert.value = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val contact: Contact.BaresipContact
|
val contact: Contact.BaresipContact =
|
||||||
|
Contact.BaresipContact(newName, newUri, color, newId, newFavorite)
|
||||||
|
|
||||||
if (new) {
|
if (imageAvatarUri.value == "") {
|
||||||
contact = Contact.BaresipContact(newName, newUri, color, id, newFavorite)
|
|
||||||
} else {
|
|
||||||
contact = Contact.baresipContact(name)!!
|
|
||||||
contact.uri = newUri
|
|
||||||
contact.name = newName
|
|
||||||
contact.color = color
|
|
||||||
contact.favorite = newFavorite
|
|
||||||
}
|
|
||||||
|
|
||||||
when (newAvatar) {
|
|
||||||
"text" -> {
|
|
||||||
if (contact.avatarImage != null) {
|
if (contact.avatarImage != null) {
|
||||||
contact.avatarImage = null
|
contact.avatarImage = null
|
||||||
Utils.deleteFile(File(BaresipService.filesPath, "${contact.id}.png"))
|
Utils.deleteFile(File(BaresipService.filesPath, "${newId}.png"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"image" -> {
|
else {
|
||||||
val imageFilePath = BaresipService.filesPath + "/${contact.id}.png"
|
val imageFilePath = BaresipService.filesPath + "/${newId}.png"
|
||||||
val imageFile = File(imageFilePath)
|
|
||||||
tmpFile!!.copyTo(target = imageFile, overwrite = true)
|
|
||||||
contact.avatarImage = BitmapFactory.decodeFile(imageFilePath)
|
contact.avatarImage = BitmapFactory.decodeFile(imageFilePath)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (newAndroid)
|
if (newAndroid)
|
||||||
addOrUpdateAndroidContact(ctx, contact)
|
addOrUpdateAndroidContact(ctx, contact)
|
||||||
@@ -502,7 +490,7 @@ class BaresipContactActivity : ComponentActivity() {
|
|||||||
if (new)
|
if (new)
|
||||||
Contact.addBaresipContact(contact)
|
Contact.addBaresipContact(contact)
|
||||||
else
|
else
|
||||||
Contact.updateBaresipContact(contact)
|
Contact.updateBaresipContact(id, contact)
|
||||||
}
|
}
|
||||||
|
|
||||||
BaresipService.activities.remove("baresip contact,$new,$uriOrName")
|
BaresipService.activities.remove("baresip contact,$new,$uriOrName")
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ import androidx.compose.ui.layout.ContentScale
|
|||||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||||
import androidx.compose.ui.platform.SoftwareKeyboardController
|
import androidx.compose.ui.platform.SoftwareKeyboardController
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.res.vectorResource
|
import androidx.compose.ui.res.vectorResource
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
@@ -74,6 +75,7 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import com.tutpro.baresip.CustomElements.AlertDialog
|
import com.tutpro.baresip.CustomElements.AlertDialog
|
||||||
|
import com.tutpro.baresip.CustomElements.LabelText
|
||||||
import com.tutpro.baresip.CustomElements.Text
|
import com.tutpro.baresip.CustomElements.Text
|
||||||
import com.tutpro.baresip.CustomElements.verticalScrollbar
|
import com.tutpro.baresip.CustomElements.verticalScrollbar
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -530,7 +532,7 @@ class ChatActivity : ComponentActivity() {
|
|||||||
modifier = Modifier.clickable { newMessage = "" }
|
modifier = Modifier.clickable { newMessage = "" }
|
||||||
)
|
)
|
||||||
} },
|
} },
|
||||||
label = { Text(text = getString(R.string.new_message), fontSize = 18.sp) },
|
label = { LabelText(text = stringResource(R.string.new_message), fontSize = 16.sp) },
|
||||||
textStyle = TextStyle(fontSize = 18.sp),
|
textStyle = TextStyle(fontSize = 18.sp),
|
||||||
keyboardOptions = KeyboardOptions(
|
keyboardOptions = KeyboardOptions(
|
||||||
capitalization = KeyboardCapitalization.Sentences,
|
capitalization = KeyboardCapitalization.Sentences,
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ import coil.compose.AsyncImage
|
|||||||
import com.tutpro.baresip.BaresipService.Companion.contactNames
|
import com.tutpro.baresip.BaresipService.Companion.contactNames
|
||||||
import com.tutpro.baresip.CustomElements.AlertDialog
|
import com.tutpro.baresip.CustomElements.AlertDialog
|
||||||
import com.tutpro.baresip.CustomElements.ImageAvatar
|
import com.tutpro.baresip.CustomElements.ImageAvatar
|
||||||
|
import com.tutpro.baresip.CustomElements.LabelText
|
||||||
import com.tutpro.baresip.CustomElements.Text
|
import com.tutpro.baresip.CustomElements.Text
|
||||||
import com.tutpro.baresip.CustomElements.TextAvatar
|
import com.tutpro.baresip.CustomElements.TextAvatar
|
||||||
import com.tutpro.baresip.CustomElements.verticalScrollbar
|
import com.tutpro.baresip.CustomElements.verticalScrollbar
|
||||||
@@ -574,9 +575,9 @@ class ChatsActivity: ComponentActivity() {
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
label = {
|
label = {
|
||||||
Text(
|
LabelText(
|
||||||
text = getString(R.string.new_chat_peer),
|
text = stringResource(R.string.new_chat_peer),
|
||||||
fontSize = 18.sp
|
fontSize = 16.sp
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
textStyle = TextStyle(
|
textStyle = TextStyle(
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ import androidx.compose.ui.unit.sp
|
|||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.tutpro.baresip.CustomElements.AlertDialog
|
import com.tutpro.baresip.CustomElements.AlertDialog
|
||||||
import com.tutpro.baresip.CustomElements.Checkbox
|
import com.tutpro.baresip.CustomElements.Checkbox
|
||||||
|
import com.tutpro.baresip.CustomElements.LabelText
|
||||||
import com.tutpro.baresip.CustomElements.verticalScrollbar
|
import com.tutpro.baresip.CustomElements.verticalScrollbar
|
||||||
import com.tutpro.baresip.Utils.copyInputStreamToFile
|
import com.tutpro.baresip.Utils.copyInputStreamToFile
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -476,7 +477,7 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
},
|
},
|
||||||
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),
|
||||||
label = { Text(stringResource(R.string.listen_address)) },
|
label = { LabelText(stringResource(R.string.listen_address)) },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -573,7 +574,7 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
},
|
},
|
||||||
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),
|
||||||
label = { Text(stringResource(R.string.dns_servers)) },
|
label = { LabelText(stringResource(R.string.dns_servers)) },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -781,7 +782,7 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
},
|
},
|
||||||
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),
|
||||||
label = { Text(stringResource(R.string.user_agent)) },
|
label = { LabelText(stringResource(R.string.user_agent)) },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -272,13 +272,11 @@ sealed class Contact {
|
|||||||
contactsUpdate()
|
contactsUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateBaresipContact(contact: BaresipContact) {
|
fun updateBaresipContact(id: Long, contact: BaresipContact) {
|
||||||
val updatedContacts = BaresipService.baresipContacts.value.toMutableList()
|
val updatedContacts = BaresipService.baresipContacts.value.toMutableList()
|
||||||
val updatedContact = contact.copy() as BaresipContact
|
updatedContacts.removeIf { it.id == id }
|
||||||
updatedContact.id = System.currentTimeMillis()
|
updatedContacts.add(contact)
|
||||||
updatedContacts.removeIf { it.id == contact.id }
|
BaresipService.baresipContacts.value = updatedContacts.toList()
|
||||||
updatedContacts.add(updatedContact)
|
|
||||||
BaresipService.baresipContacts.value = updatedContacts
|
|
||||||
saveBaresipContacts()
|
saveBaresipContacts()
|
||||||
contactsUpdate()
|
contactsUpdate()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -369,7 +369,7 @@ class ContactsActivity : ComponentActivity() {
|
|||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Filled.Edit,
|
imageVector = Icons.Filled.Edit,
|
||||||
modifier = Modifier.size(28.dp),
|
modifier = Modifier.size(28.dp),
|
||||||
contentDescription = stringResource(R.string.add)
|
contentDescription = stringResource(R.string.edit)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import android.app.KeyguardManager
|
|||||||
import android.app.NotificationManager
|
import android.app.NotificationManager
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.DialogInterface
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.Intent.ACTION_CALL
|
import android.content.Intent.ACTION_CALL
|
||||||
import android.content.Intent.ACTION_DIAL
|
import android.content.Intent.ACTION_DIAL
|
||||||
@@ -58,11 +57,11 @@ import androidx.compose.foundation.layout.Column
|
|||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.consumeWindowInsets
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.heightIn
|
import androidx.compose.foundation.layout.heightIn
|
||||||
|
import androidx.compose.foundation.layout.imePadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.safeDrawingPadding
|
import androidx.compose.foundation.layout.safeDrawingPadding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
@@ -130,13 +129,15 @@ import androidx.compose.ui.viewinterop.AndroidView
|
|||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import com.tutpro.baresip.BaresipService.Companion.contactNames
|
import com.tutpro.baresip.BaresipService.Companion.contactNames
|
||||||
import com.tutpro.baresip.BaresipService.Companion.uas
|
import com.tutpro.baresip.BaresipService.Companion.uas
|
||||||
import com.tutpro.baresip.BaresipService.Companion.uasStatus
|
import com.tutpro.baresip.BaresipService.Companion.uasStatus
|
||||||
|
import com.tutpro.baresip.CustomElements.AlertDialog
|
||||||
import com.tutpro.baresip.CustomElements.Checkbox
|
import com.tutpro.baresip.CustomElements.Checkbox
|
||||||
import com.tutpro.baresip.CustomElements.DropdownMenu
|
import com.tutpro.baresip.CustomElements.DropdownMenu
|
||||||
|
import com.tutpro.baresip.CustomElements.LabelText
|
||||||
import com.tutpro.baresip.CustomElements.PullToRefreshBox
|
import com.tutpro.baresip.CustomElements.PullToRefreshBox
|
||||||
|
import com.tutpro.baresip.CustomElements.SelectableAlertDialog
|
||||||
import com.tutpro.baresip.CustomElements.Text
|
import com.tutpro.baresip.CustomElements.Text
|
||||||
import com.tutpro.baresip.CustomElements.verticalScrollbar
|
import com.tutpro.baresip.CustomElements.verticalScrollbar
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
@@ -220,6 +221,22 @@ class MainActivity : ComponentActivity() {
|
|||||||
private var passwordAccounts = mutableListOf<String>()
|
private var passwordAccounts = mutableListOf<String>()
|
||||||
private var passwordTitle by mutableStateOf("")
|
private var passwordTitle by mutableStateOf("")
|
||||||
|
|
||||||
|
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 showSelectItemDialog = mutableStateOf(false)
|
||||||
|
val items = mutableStateOf(listOf<String>())
|
||||||
|
val itemAction = mutableStateOf<(Int) -> Unit>({ index -> {} })
|
||||||
|
|
||||||
private val onBackPressedCallback = object : OnBackPressedCallback(true) {
|
private val onBackPressedCallback = object : OnBackPressedCallback(true) {
|
||||||
override fun handleOnBackPressed() {
|
override fun handleOnBackPressed() {
|
||||||
moveTaskToBack(true)
|
moveTaskToBack(true)
|
||||||
@@ -330,18 +347,14 @@ class MainActivity : ComponentActivity() {
|
|||||||
|
|
||||||
configRequest = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
configRequest = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||||
if ((it.data != null) && it.data!!.hasExtra("restart")) {
|
if ((it.data != null) && it.data!!.hasExtra("restart")) {
|
||||||
with(MaterialAlertDialogBuilder(this, R.style.AlertDialogTheme)) {
|
dialogTitle.value = getString(R.string.restart_request)
|
||||||
setTitle(R.string.restart_request)
|
dialogMessage.value = getString(R.string.config_restart)
|
||||||
setMessage(getString(R.string.config_restart))
|
positiveText.value = getString(R.string.restart)
|
||||||
setPositiveButton(getText(R.string.restart)) { dialog, _ ->
|
onPositiveClicked.value = {
|
||||||
dialog.dismiss()
|
|
||||||
quitRestart(true)
|
quitRestart(true)
|
||||||
}
|
}
|
||||||
setNeutralButton(getText(R.string.cancel)) { dialog, _ ->
|
negativeText.value = getString(R.string.cancel)
|
||||||
dialog.dismiss()
|
showDialog.value = true
|
||||||
}
|
|
||||||
show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
val displayTheme = Preferences(applicationContext).displayTheme
|
val displayTheme = Preferences(applicationContext).displayTheme
|
||||||
if (displayTheme != AppCompatDelegate.getDefaultNightMode()) {
|
if (displayTheme != AppCompatDelegate.getDefaultNightMode()) {
|
||||||
@@ -436,21 +449,26 @@ class MainActivity : ComponentActivity() {
|
|||||||
shouldShow.add(permission.key)
|
shouldShow.add(permission.key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (denied.contains(POST_NOTIFICATIONS) &&
|
if (denied.contains(POST_NOTIFICATIONS) && !shouldShow.contains(POST_NOTIFICATIONS)) {
|
||||||
!shouldShow.contains(POST_NOTIFICATIONS)) {
|
dialogTitle.value = getString(R.string.notice)
|
||||||
with(MaterialAlertDialogBuilder(this, R.style.AlertDialogTheme)) {
|
dialogMessage.value = getString(R.string.no_notifications)
|
||||||
setTitle(getString(R.string.notice))
|
positiveText.value = getString(R.string.ok)
|
||||||
setMessage(getString(R.string.no_notifications))
|
onPositiveClicked.value = {
|
||||||
setPositiveButton(getString(R.string.ok)) { _, _ ->
|
|
||||||
quitRestart(false)
|
quitRestart(false)
|
||||||
}
|
}
|
||||||
show()
|
negativeText.value = ""
|
||||||
}
|
showDialog.value = true
|
||||||
} else {
|
} else {
|
||||||
if (shouldShow.isNotEmpty())
|
if (shouldShow.isNotEmpty()) {
|
||||||
Utils.alertView(this, getString(R.string.permissions_rationale),
|
dialogTitle.value = getString(R.string.permissions_rationale)
|
||||||
getString(R.string.audio_permissions)
|
dialogMessage.value = getString(R.string.audio_permissions)
|
||||||
) { requestPermissionsLauncher.launch(permissions) }
|
positiveText.value = getString(R.string.ok)
|
||||||
|
onPositiveClicked.value = {
|
||||||
|
requestPermissionsLauncher.launch(permissions)
|
||||||
|
}
|
||||||
|
negativeText.value = ""
|
||||||
|
showDialog.value = true
|
||||||
|
}
|
||||||
else
|
else
|
||||||
startBaresip()
|
startBaresip()
|
||||||
}
|
}
|
||||||
@@ -486,6 +504,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MainContent(ctx: Context, contentPadding: PaddingValues) {
|
fun MainContent(ctx: Context, contentPadding: PaddingValues) {
|
||||||
|
|
||||||
var isRefreshing by remember { mutableStateOf(false) }
|
var isRefreshing by remember { mutableStateOf(false) }
|
||||||
LaunchedEffect(isRefreshing) {
|
LaunchedEffect(isRefreshing) {
|
||||||
if (isRefreshing) {
|
if (isRefreshing) {
|
||||||
@@ -493,6 +512,18 @@ class MainActivity : ComponentActivity() {
|
|||||||
isRefreshing = false
|
isRefreshing = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (showDialog.value)
|
||||||
|
AlertDialog(
|
||||||
|
showDialog = showDialog,
|
||||||
|
title = getString(R.string.confirmation),
|
||||||
|
message = dialogMessage.value,
|
||||||
|
positiveButtonText = positiveText.value,
|
||||||
|
onPositiveClicked = onPositiveClicked.value,
|
||||||
|
negativeButtonText = getString(R.string.cancel),
|
||||||
|
onNegativeClicked = onNegativeClicked.value
|
||||||
|
)
|
||||||
|
|
||||||
PullToRefreshBox(
|
PullToRefreshBox(
|
||||||
isRefreshing = isRefreshing,
|
isRefreshing = isRefreshing,
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
@@ -508,21 +539,27 @@ class MainActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
SelectableAlertDialog(
|
||||||
|
openDialog = showSelectItemDialog,
|
||||||
|
title = getString(R.string.choose_destination_uri),
|
||||||
|
items = items.value,
|
||||||
|
onItemClicked = itemAction.value,
|
||||||
|
neutralButtonText = getString(R.string.cancel),
|
||||||
|
onNeutralClicked = {}
|
||||||
|
)
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.consumeWindowInsets(contentPadding)
|
.imePadding()
|
||||||
.padding(
|
.fillMaxWidth()
|
||||||
PaddingValues(
|
.padding(contentPadding)
|
||||||
top = 76.dp, bottom = 6.dp,
|
.padding(top = 18.dp, bottom = 6.dp, start = 16.dp, end = 16.dp)
|
||||||
start = 16.dp, end = 16.dp
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.verticalScroll(rememberScrollState()),
|
.verticalScroll(rememberScrollState()),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
) {
|
) {
|
||||||
AccountSpinner(ctx)
|
AccountSpinner(ctx)
|
||||||
CallUriRow(ctx)
|
CallUriRow()
|
||||||
CallRow(ctx)
|
CallRow(ctx)
|
||||||
OnHoldNotice()
|
OnHoldNotice()
|
||||||
AskPasswords(ctx)
|
AskPasswords(ctx)
|
||||||
@@ -668,10 +705,16 @@ class MainActivity : ComponentActivity() {
|
|||||||
passwordTitle = getString(R.string.encrypt_password)
|
passwordTitle = getString(R.string.encrypt_password)
|
||||||
showPasswordDialog.value = true
|
showPasswordDialog.value = true
|
||||||
}
|
}
|
||||||
shouldShowRequestPermissionRationale(WRITE_EXTERNAL_STORAGE) ->
|
shouldShowRequestPermissionRationale(WRITE_EXTERNAL_STORAGE) -> {
|
||||||
Utils.alertView(ctx, getString(R.string.notice), getString(R.string.no_backup)) {
|
dialogTitle.value = getString(R.string.notice)
|
||||||
|
dialogMessage.value = getString(R.string.no_backup)
|
||||||
|
positiveText.value = getString(R.string.ok)
|
||||||
|
onPositiveClicked.value = {
|
||||||
requestPermissionLauncher.launch(WRITE_EXTERNAL_STORAGE)
|
requestPermissionLauncher.launch(WRITE_EXTERNAL_STORAGE)
|
||||||
}
|
}
|
||||||
|
negativeText.value = ""
|
||||||
|
showDialog.value = true
|
||||||
|
}
|
||||||
else ->
|
else ->
|
||||||
requestPermissionLauncher.launch(WRITE_EXTERNAL_STORAGE)
|
requestPermissionLauncher.launch(WRITE_EXTERNAL_STORAGE)
|
||||||
}
|
}
|
||||||
@@ -688,10 +731,16 @@ class MainActivity : ComponentActivity() {
|
|||||||
passwordTitle = getString(R.string.decrypt_password)
|
passwordTitle = getString(R.string.decrypt_password)
|
||||||
showPasswordDialog.value = true
|
showPasswordDialog.value = true
|
||||||
}
|
}
|
||||||
shouldShowRequestPermissionRationale(READ_EXTERNAL_STORAGE) ->
|
shouldShowRequestPermissionRationale(READ_EXTERNAL_STORAGE) -> {
|
||||||
Utils.alertView(ctx, getString(R.string.notice), getString(R.string.no_restore)) {
|
dialogTitle.value = getString(R.string.notice)
|
||||||
|
dialogMessage.value = getString(R.string.no_restore)
|
||||||
|
positiveText.value = getString(R.string.ok)
|
||||||
|
onPositiveClicked.value = {
|
||||||
requestPermissionLauncher.launch(READ_EXTERNAL_STORAGE)
|
requestPermissionLauncher.launch(READ_EXTERNAL_STORAGE)
|
||||||
}
|
}
|
||||||
|
negativeText.value = ""
|
||||||
|
showDialog.value = true
|
||||||
|
}
|
||||||
else ->
|
else ->
|
||||||
requestPermissionLauncher.launch(READ_EXTERNAL_STORAGE)
|
requestPermissionLauncher.launch(READ_EXTERNAL_STORAGE)
|
||||||
}
|
}
|
||||||
@@ -885,7 +934,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CallUriRow(ctx: Context) {
|
fun CallUriRow() {
|
||||||
val suggestions by remember { contactNames }
|
val suggestions by remember { contactNames }
|
||||||
var filteredSuggestions by remember { mutableStateOf(suggestions) }
|
var filteredSuggestions by remember { mutableStateOf(suggestions) }
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
@@ -929,7 +978,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
.padding(start = 4.dp, end = 4.dp, top = 12.dp, bottom = 2.dp)
|
.padding(start = 4.dp, end = 4.dp, top = 12.dp, bottom = 2.dp)
|
||||||
.focusRequester(focusRequester),
|
.focusRequester(focusRequester),
|
||||||
label = {
|
label = {
|
||||||
Text(
|
LabelText(
|
||||||
text = callUriLabel.value,
|
text = callUriLabel.value,
|
||||||
fontSize = 18.sp,
|
fontSize = 18.sp,
|
||||||
)
|
)
|
||||||
@@ -1018,29 +1067,20 @@ class MainActivity : ComponentActivity() {
|
|||||||
.clickable {
|
.clickable {
|
||||||
when (securityIcon.intValue) {
|
when (securityIcon.intValue) {
|
||||||
R.drawable.unlocked -> {
|
R.drawable.unlocked -> {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.alert)
|
||||||
ctx, getString(R.string.alert),
|
alertMessage.value = getString(R.string.call_not_secure)
|
||||||
getString(R.string.call_not_secure)
|
showAlert.value = true
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
R.drawable.locked_yellow -> {
|
R.drawable.locked_yellow -> {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.alert)
|
||||||
ctx, getString(R.string.alert),
|
alertMessage.value = getString(R.string.peer_not_verified)
|
||||||
getString(R.string.peer_not_verified)
|
showAlert.value = true
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
R.drawable.locked_green -> {
|
R.drawable.locked_green -> {
|
||||||
with(
|
dialogTitle.value = getString(R.string.info)
|
||||||
MaterialAlertDialogBuilder(
|
dialogMessage.value = getString(R.string.call_is_secure)
|
||||||
ctx,
|
positiveText.value = getString(R.string.unverify)
|
||||||
R.style.AlertDialogTheme
|
onPositiveClicked.value = {
|
||||||
)
|
|
||||||
) {
|
|
||||||
setTitle(R.string.info)
|
|
||||||
setMessage(getString(R.string.call_is_secure))
|
|
||||||
setPositiveButton(getString(R.string.unverify)) { dialog, _ ->
|
|
||||||
val ua = UserAgent.ofAor(viewModel.selectedAor.value)!!
|
val ua = UserAgent.ofAor(viewModel.selectedAor.value)!!
|
||||||
val call = ua.currentCall()
|
val call = ua.currentCall()
|
||||||
if (call != null) {
|
if (call != null) {
|
||||||
@@ -1052,13 +1092,9 @@ class MainActivity : ComponentActivity() {
|
|||||||
else
|
else
|
||||||
securityIcon.intValue = R.drawable.locked_yellow
|
securityIcon.intValue = R.drawable.locked_yellow
|
||||||
}
|
}
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
setNeutralButton(getString(R.string.cancel)) { dialog, _ ->
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
show()
|
|
||||||
}
|
}
|
||||||
|
negativeText.value = getString(R.string.cancel)
|
||||||
|
showDialog.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1168,11 +1204,11 @@ class MainActivity : ComponentActivity() {
|
|||||||
val call = ua.currentCall()
|
val call = ua.currentCall()
|
||||||
if (call != null) {
|
if (call != null) {
|
||||||
if (call.onHoldCall != null) {
|
if (call.onHoldCall != null) {
|
||||||
if (!call.executeTransfer())
|
if (!call.executeTransfer()) {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.notice)
|
||||||
ctx, getString(R.string.notice),
|
alertMessage.value = getString(R.string.transfer_failed)
|
||||||
String.format(getString(R.string.transfer_failed))
|
showAlert.value = true
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
showTransferDialog = true
|
showTransferDialog = true
|
||||||
@@ -1254,13 +1290,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
bottom = 2.dp
|
bottom = 2.dp
|
||||||
)
|
)
|
||||||
.focusRequester(focusRequester),
|
.focusRequester(focusRequester),
|
||||||
label = {
|
label = { LabelText(stringResource(R.string.transfer_destination)) },
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.transfer_destination),
|
|
||||||
fontSize = 18.sp,
|
|
||||||
color = LocalCustomColors.current.dark
|
|
||||||
)
|
|
||||||
},
|
|
||||||
textStyle = TextStyle(
|
textStyle = TextStyle(
|
||||||
fontSize = 18.sp,
|
fontSize = 18.sp,
|
||||||
color = LocalCustomColors.current.dark
|
color = LocalCustomColors.current.dark
|
||||||
@@ -1365,30 +1395,24 @@ class MainActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
TextButton(
|
TextButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
|
showSuggestions = false
|
||||||
var uriText = transferUri.trim()
|
var uriText = transferUri.trim()
|
||||||
if (uriText.isNotEmpty()) {
|
if (uriText.isNotEmpty()) {
|
||||||
val uris = Contact.contactUris(uriText)
|
val uris = Contact.contactUris(uriText)
|
||||||
if (uris.size > 1) {
|
if (uris.size > 1) {
|
||||||
val destinationBuilder =
|
items.value = uris
|
||||||
MaterialAlertDialogBuilder(
|
itemAction.value = { index ->
|
||||||
ctx,
|
val uriText = uris[index]
|
||||||
R.style.AlertDialogTheme
|
|
||||||
)
|
|
||||||
with(destinationBuilder) {
|
|
||||||
setTitle(R.string.choose_destination_uri)
|
|
||||||
setItems(uris.toTypedArray()) { _, which ->
|
|
||||||
uriText = uris[which]
|
|
||||||
transfer(
|
transfer(
|
||||||
ua,
|
ua,
|
||||||
if (Utils.isTelNumber(uriText))
|
if (Utils.isTelNumber(uriText)) "tel:$uriText" else uriText,
|
||||||
"tel:$uriText"
|
|
||||||
else
|
|
||||||
uriText,
|
|
||||||
!blindChecked.value
|
!blindChecked.value
|
||||||
)
|
)
|
||||||
|
showSelectItemDialog.value = false
|
||||||
}
|
}
|
||||||
|
showSelectItemDialog.value = true
|
||||||
}
|
}
|
||||||
} else {
|
else {
|
||||||
if (uris.size == 1)
|
if (uris.size == 1)
|
||||||
uriText = uris[0]
|
uriText = uris[0]
|
||||||
}
|
}
|
||||||
@@ -1441,7 +1465,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
.focusRequester(focusRequester),
|
.focusRequester(focusRequester),
|
||||||
enabled = dtmfEnabled.value,
|
enabled = dtmfEnabled.value,
|
||||||
textStyle = TextStyle(fontSize = 16.sp),
|
textStyle = TextStyle(fontSize = 16.sp),
|
||||||
label = { Text(getString(R.string.dtmf), fontSize = 16.sp) },
|
label = { LabelText(stringResource(R.string.dtmf)) },
|
||||||
singleLine = true
|
singleLine = true
|
||||||
)
|
)
|
||||||
LaunchedEffect(shouldRequestFocus) {
|
LaunchedEffect(shouldRequestFocus) {
|
||||||
@@ -1468,8 +1492,8 @@ class MainActivity : ComponentActivity() {
|
|||||||
val duration = call.duration()
|
val duration = call.duration()
|
||||||
val txCodec = codecs.split(',')[0].split("/")
|
val txCodec = codecs.split(',')[0].split("/")
|
||||||
val rxCodec = codecs.split(',')[1].split("/")
|
val rxCodec = codecs.split(',')[1].split("/")
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.call_info)
|
||||||
ctx, getString(R.string.call_info),
|
alertMessage.value =
|
||||||
"${String.format(getString(R.string.duration), duration)}\n" +
|
"${String.format(getString(R.string.duration), duration)}\n" +
|
||||||
"${getString(R.string.codecs)}: ${txCodec[0]} ch ${txCodec[2]}/" +
|
"${getString(R.string.codecs)}: ${txCodec[0]} ch ${txCodec[2]}/" +
|
||||||
"${rxCodec[0]} ch ${rxCodec[2]}\n" +
|
"${rxCodec[0]} ch ${rxCodec[2]}\n" +
|
||||||
@@ -1483,12 +1507,11 @@ class MainActivity : ComponentActivity() {
|
|||||||
"${getString(R.string.packets)}: ${parts[2]}\n" +
|
"${getString(R.string.packets)}: ${parts[2]}\n" +
|
||||||
"${getString(R.string.lost)}: ${parts[3]}\n" +
|
"${getString(R.string.lost)}: ${parts[3]}\n" +
|
||||||
String.format(getString(R.string.jitter), parts[4])
|
String.format(getString(R.string.jitter), parts[4])
|
||||||
)
|
showAlert.value = true
|
||||||
} else {
|
} else {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.call_info)
|
||||||
ctx, getString(R.string.call_info),
|
alertMessage.value = getString(R.string.call_info_not_available)
|
||||||
getString(R.string.call_info_not_available)
|
showAlert.value = true
|
||||||
)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
@@ -1539,43 +1562,48 @@ class MainActivity : ComponentActivity() {
|
|||||||
|
|
||||||
private fun callClick(ctx: Context) {
|
private fun callClick(ctx: Context) {
|
||||||
if (viewModel.selectedAor.value != "") {
|
if (viewModel.selectedAor.value != "") {
|
||||||
if (Utils.checkPermissions(ctx, arrayOf(RECORD_AUDIO)))
|
if (Utils.checkPermissions(ctx, arrayOf(RECORD_AUDIO))) {
|
||||||
makeCall()
|
if (Call.inCall())
|
||||||
|
return
|
||||||
|
var uriText = callUri.value.trim()
|
||||||
|
if (uriText.isNotEmpty()) {
|
||||||
|
val uris = Contact.contactUris(uriText)
|
||||||
|
if (uris.isEmpty())
|
||||||
|
makeCall(uriText)
|
||||||
|
else if (uris.size == 1)
|
||||||
|
makeCall(uris[0])
|
||||||
|
else {
|
||||||
|
items.value = uris
|
||||||
|
itemAction.value = { index ->
|
||||||
|
makeCall(uris[index])
|
||||||
|
}
|
||||||
|
showSelectItemDialog.value = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val ua = UserAgent.ofAor(viewModel.selectedAor.value)!!
|
||||||
|
val latestPeerUri = CallHistoryNew.aorLatestPeerUri(ua.account.aor)
|
||||||
|
if (latestPeerUri != null)
|
||||||
|
callUri.value = Utils.friendlyUri(this, latestPeerUri, ua.account)
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
Toast.makeText(applicationContext, R.string.no_calls, Toast.LENGTH_SHORT).show()
|
Toast.makeText(applicationContext, R.string.no_calls, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun makeCall(lookForContact: Boolean = true) {
|
private fun makeCall(uriText: String) {
|
||||||
val ua = UserAgent.ofAor(viewModel.selectedAor.value)
|
val ua = UserAgent.ofAor(viewModel.selectedAor.value)!!
|
||||||
val aor = ua!!.account.aor
|
val aor = ua.account.aor
|
||||||
if (!Call.inCall()) {
|
val peerUri = if (Utils.isTelNumber(uriText))
|
||||||
var uriText = callUri.value.trim()
|
"tel:$uriText"
|
||||||
if (uriText.isNotEmpty()) {
|
else
|
||||||
if (lookForContact) {
|
uriText
|
||||||
val uris = Contact.contactUris(uriText)
|
val uri = if (Utils.isTelUri(peerUri)) {
|
||||||
if (uris.size == 1)
|
|
||||||
uriText = uris[0]
|
|
||||||
else if (uris.size > 1) {
|
|
||||||
val builder = MaterialAlertDialogBuilder(this, R.style.AlertDialogTheme)
|
|
||||||
with(builder) {
|
|
||||||
setTitle(R.string.choose_destination_uri)
|
|
||||||
setItems(uris.toTypedArray()) { _, which ->
|
|
||||||
callUri.value = uris[which]
|
|
||||||
makeCall(false)
|
|
||||||
}
|
|
||||||
setNeutralButton(getString(R.string.cancel)) { _: DialogInterface, _: Int -> }
|
|
||||||
show()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Utils.isTelNumber(uriText))
|
|
||||||
uriText = "tel:$uriText"
|
|
||||||
val uri = if (Utils.isTelUri(uriText)) {
|
|
||||||
if (ua.account.telProvider == "") {
|
if (ua.account.telProvider == "") {
|
||||||
Utils.alertView(this, getString(R.string.notice),
|
alertTitle.value = getString(R.string.notice)
|
||||||
String.format(getString(R.string.no_telephony_provider), aor))
|
alertMessage.value = String.format(getString(R.string.no_telephony_provider), aor)
|
||||||
|
showAlert.value = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Utils.telToSip(uriText, ua.account)
|
Utils.telToSip(uriText, ua.account)
|
||||||
@@ -1583,8 +1611,9 @@ class MainActivity : ComponentActivity() {
|
|||||||
Utils.uriComplete(uriText, aor)
|
Utils.uriComplete(uriText, aor)
|
||||||
}
|
}
|
||||||
if (!Utils.checkUri(uri)) {
|
if (!Utils.checkUri(uri)) {
|
||||||
Utils.alertView(this, getString(R.string.notice),
|
alertTitle.value = getString(R.string.notice)
|
||||||
String.format(getString(R.string.invalid_sip_or_tel_uri), uri))
|
alertMessage.value = String.format(getString(R.string.invalid_sip_or_tel_uri), uri)
|
||||||
|
showAlert.value = true
|
||||||
} else if (!BaresipService.requestAudioFocus(applicationContext)) {
|
} else if (!BaresipService.requestAudioFocus(applicationContext)) {
|
||||||
Toast.makeText(applicationContext, R.string.audio_focus_denied,
|
Toast.makeText(applicationContext, R.string.audio_focus_denied,
|
||||||
Toast.LENGTH_SHORT).show()
|
Toast.LENGTH_SHORT).show()
|
||||||
@@ -1620,12 +1649,6 @@ class MainActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
val latestPeerUri = CallHistoryNew.aorLatestPeerUri(aor)
|
|
||||||
if (latestPeerUri != null)
|
|
||||||
callUri.value = Utils.friendlyUri(this, latestPeerUri, ua.account)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun answer(ctx: Context) {
|
private fun answer(ctx: Context) {
|
||||||
@@ -1668,9 +1691,10 @@ class MainActivity : ComponentActivity() {
|
|||||||
val ua = UserAgent.ofAor(viewModel.selectedAor.value)!!
|
val ua = UserAgent.ofAor(viewModel.selectedAor.value)!!
|
||||||
val acc = ua.account
|
val acc = ua.account
|
||||||
if (acc.vmUri != "") {
|
if (acc.vmUri != "") {
|
||||||
val dialogClickListener = DialogInterface.OnClickListener { _, which ->
|
dialogTitle.value = getString(R.string.voicemail_messages)
|
||||||
when (which) {
|
dialogMessage.value = acc.vmMessages(ctx)
|
||||||
DialogInterface.BUTTON_POSITIVE -> {
|
positiveText.value = getString(R.string.listen)
|
||||||
|
onPositiveClicked.value = {
|
||||||
val i = Intent(ctx, MainActivity::class.java)
|
val i = Intent(ctx, MainActivity::class.java)
|
||||||
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK or
|
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK or
|
||||||
Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP
|
Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||||
@@ -1679,17 +1703,9 @@ class MainActivity : ComponentActivity() {
|
|||||||
i.putExtra("peer", acc.vmUri)
|
i.putExtra("peer", acc.vmUri)
|
||||||
startActivity(i)
|
startActivity(i)
|
||||||
}
|
}
|
||||||
DialogInterface.BUTTON_NEGATIVE -> {
|
negativeText.value = getString(R.string.cancel)
|
||||||
}
|
onNegativeClicked.value = {}
|
||||||
}
|
showDialog.value = true
|
||||||
}
|
|
||||||
with(MaterialAlertDialogBuilder(ctx, R.style.AlertDialogTheme)) {
|
|
||||||
setTitle(R.string.voicemail_messages)
|
|
||||||
setMessage(acc.vmMessages(ctx))
|
|
||||||
setPositiveButton(getString(R.string.listen), dialogClickListener)
|
|
||||||
setNeutralButton(getString(R.string.cancel), dialogClickListener)
|
|
||||||
show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -2074,8 +2090,9 @@ class MainActivity : ComponentActivity() {
|
|||||||
val ev = action.split(",")
|
val ev = action.split(",")
|
||||||
when (ev[0]) {
|
when (ev[0]) {
|
||||||
"no network" -> {
|
"no network" -> {
|
||||||
Utils.alertView(this, getString(R.string.notice),
|
alertTitle.value = getString(R.string.notice)
|
||||||
getString(R.string.no_network))
|
alertMessage.value = getString(R.string.no_network)
|
||||||
|
showAlert.value = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
"call", "dial" -> {
|
"call", "dial" -> {
|
||||||
@@ -2205,8 +2222,11 @@ class MainActivity : ComponentActivity() {
|
|||||||
if (event == "stopped") {
|
if (event == "stopped") {
|
||||||
Log.d(TAG, "Handling service event 'stopped' with start error '${params[0]}'")
|
Log.d(TAG, "Handling service event 'stopped' with start error '${params[0]}'")
|
||||||
if (params[0] != "") {
|
if (params[0] != "") {
|
||||||
Utils.alertView(this, getString(R.string.notice), getString(R.string.start_failed))
|
alertTitle.value = getString(R.string.notice)
|
||||||
} else {
|
alertMessage.value = getString(R.string.start_failed)
|
||||||
|
showAlert.value = true
|
||||||
|
}
|
||||||
|
else {
|
||||||
finishAndRemoveTask()
|
finishAndRemoveTask()
|
||||||
if (restart)
|
if (restart)
|
||||||
reStart()
|
reStart()
|
||||||
@@ -2262,19 +2282,17 @@ class MainActivity : ComponentActivity() {
|
|||||||
String.format(getString(R.string.redirect_notice), target),
|
String.format(getString(R.string.redirect_notice), target),
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
} else {
|
}
|
||||||
with(MaterialAlertDialogBuilder(this, R.style.AlertDialogTheme)) {
|
else {
|
||||||
setTitle(R.string.redirect_request)
|
dialogTitle.value = getString(R.string.redirect_request)
|
||||||
setMessage(String.format(getString(R.string.redirect_request_query), target))
|
dialogMessage.value = String.format(getString(R.string.redirect_request_query), target)
|
||||||
setPositiveButton(getString(R.string.yes)) { dialog, _ ->
|
positiveText.value = getString(R.string.yes)
|
||||||
|
onPositiveClicked.value = {
|
||||||
redirect(ua, target)
|
redirect(ua, target)
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
setNeutralButton(getString(R.string.no)) { dialog, _ ->
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
show()
|
|
||||||
}
|
}
|
||||||
|
negativeText.value = getString(R.string.no)
|
||||||
|
onNegativeClicked.value = {}
|
||||||
|
showDialog.value = true
|
||||||
}
|
}
|
||||||
showCall(ua)
|
showCall(ua)
|
||||||
}
|
}
|
||||||
@@ -2294,10 +2312,10 @@ class MainActivity : ComponentActivity() {
|
|||||||
handleNextEvent("Call $callp to be verified is not found")
|
handleNextEvent("Call $callp to be verified is not found")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
with(MaterialAlertDialogBuilder(this, R.style.AlertDialogTheme)) {
|
dialogTitle.value = getString(R.string.verify)
|
||||||
setTitle(R.string.verify)
|
dialogMessage.value = String.format(getString(R.string.verify_sas), call.zid)
|
||||||
setMessage(String.format(getString(R.string.verify_sas), ev[1]))
|
positiveText.value = getString(R.string.yes)
|
||||||
setPositiveButton(getString(R.string.yes)) { dialog, _ ->
|
onPositiveClicked.value = {
|
||||||
call.security = if (Api.cmd_exec("zrtp_verify ${ev[2]}") != 0) {
|
call.security = if (Api.cmd_exec("zrtp_verify ${ev[2]}") != 0) {
|
||||||
Log.e(TAG, "Command 'zrtp_verify ${ev[2]}' failed")
|
Log.e(TAG, "Command 'zrtp_verify ${ev[2]}' failed")
|
||||||
R.drawable.locked_yellow
|
R.drawable.locked_yellow
|
||||||
@@ -2307,16 +2325,14 @@ class MainActivity : ComponentActivity() {
|
|||||||
call.zid = ev[2]
|
call.zid = ev[2]
|
||||||
if (aor == viewModel.selectedAor.value)
|
if (aor == viewModel.selectedAor.value)
|
||||||
securityIcon.intValue = call.security
|
securityIcon.intValue = call.security
|
||||||
dialog.dismiss()
|
|
||||||
}
|
}
|
||||||
setNeutralButton(getString(R.string.no)) { dialog, _ ->
|
negativeText.value = getString(R.string.no)
|
||||||
|
onNegativeClicked.value = {
|
||||||
call.security = R.drawable.locked_yellow
|
call.security = R.drawable.locked_yellow
|
||||||
call.zid = ev[2]
|
call.zid = ev[2]
|
||||||
if (aor == viewModel.selectedAor.value)
|
if (aor == viewModel.selectedAor.value)
|
||||||
securityIcon.intValue = R.drawable.locked_yellow
|
securityIcon.intValue = R.drawable.locked_yellow
|
||||||
dialog.dismiss()
|
onNegativeClicked.value = {}
|
||||||
}
|
|
||||||
show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"call verified", "call secure" -> {
|
"call verified", "call secure" -> {
|
||||||
@@ -2344,40 +2360,28 @@ class MainActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
val call = Call.ofCallp(callp)
|
val call = Call.ofCallp(callp)
|
||||||
val target = Utils.friendlyUri(this, ev[1], acc)
|
val target = Utils.friendlyUri(this, ev[1], acc)
|
||||||
with(MaterialAlertDialogBuilder(this, R.style.AlertDialogTheme)) {
|
dialogTitle.value = if (call != null)
|
||||||
if (call != null) {
|
getString(R.string.transfer_request)
|
||||||
setTitle(R.string.transfer_request)
|
else
|
||||||
setMessage(
|
getString(R.string.call_request)
|
||||||
String.format(
|
dialogMessage.value = if (call != null)
|
||||||
getString(R.string.transfer_request_query),
|
String.format(getString(R.string.transfer_request_query), target)
|
||||||
target
|
else
|
||||||
)
|
String.format(getString(R.string.call_request_query), target)
|
||||||
)
|
positiveText.value = getString(R.string.yes)
|
||||||
} else {
|
onPositiveClicked.value = {
|
||||||
setTitle(R.string.call_request)
|
|
||||||
setMessage(
|
|
||||||
String.format(
|
|
||||||
getString(R.string.call_request_query),
|
|
||||||
target
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
setPositiveButton(getString(R.string.yes)) { dialog, _ ->
|
|
||||||
if (call in Call.calls())
|
if (call in Call.calls())
|
||||||
acceptTransfer(ua, call!!, ev[1])
|
acceptTransfer(ua, call!!, ev[1])
|
||||||
else {
|
else
|
||||||
callUri.value = ev[1]
|
makeCall(ev[1])
|
||||||
makeCall()
|
|
||||||
}
|
}
|
||||||
dialog.dismiss()
|
negativeText.value = getString(R.string.no)
|
||||||
}
|
onNegativeClicked.value = {
|
||||||
setNeutralButton(getString(R.string.no)) { dialog, _ ->
|
|
||||||
if (call in Call.calls())
|
if (call in Call.calls())
|
||||||
call!!.notifySipfrag(603, "Decline")
|
call!!.notifySipfrag(603, "Decline")
|
||||||
dialog.dismiss()
|
onNegativeClicked.value = {}
|
||||||
}
|
|
||||||
show()
|
|
||||||
}
|
}
|
||||||
|
showDialog.value = true
|
||||||
}
|
}
|
||||||
"transfer accept" -> {
|
"transfer accept" -> {
|
||||||
val callp = params[1] as Long
|
val callp = params[1] as Long
|
||||||
@@ -2509,9 +2513,11 @@ class MainActivity : ComponentActivity() {
|
|||||||
else
|
else
|
||||||
Utils.uriComplete(uriText, ua.account.aor)
|
Utils.uriComplete(uriText, ua.account.aor)
|
||||||
if (!Utils.checkUri(uri)) {
|
if (!Utils.checkUri(uri)) {
|
||||||
Utils.alertView(this@MainActivity, getString(R.string.notice),
|
alertTitle.value = getString(R.string.notice)
|
||||||
String.format(getString(R.string.invalid_sip_or_tel_uri), uri))
|
alertMessage.value = String.format(getString(R.string.invalid_sip_or_tel_uri), uri)
|
||||||
} else {
|
showAlert.value = true
|
||||||
|
}
|
||||||
|
else {
|
||||||
val call = ua.currentCall()
|
val call = ua.currentCall()
|
||||||
if (call != null) {
|
if (call != null) {
|
||||||
if (attended) {
|
if (attended) {
|
||||||
@@ -2519,10 +2525,12 @@ class MainActivity : ComponentActivity() {
|
|||||||
call.referTo = uri
|
call.referTo = uri
|
||||||
call(ua, uri, call)
|
call(ua, uri, call)
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (!call.transfer(uri)) {
|
if (!call.transfer(uri)) {
|
||||||
Utils.alertView(this@MainActivity, getString(R.string.notice),
|
alertTitle.value = getString(R.string.notice)
|
||||||
String.format(getString(R.string.transfer_failed)))
|
alertMessage.value = getString(R.string.transfer_failed)
|
||||||
|
showAlert.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
showCall(ua)
|
showCall(ua)
|
||||||
@@ -2550,31 +2558,35 @@ class MainActivity : ComponentActivity() {
|
|||||||
val zipFilePath = BaresipService.filesPath + "/$zipFile"
|
val zipFilePath = BaresipService.filesPath + "/$zipFile"
|
||||||
if (!Utils.zip(files, zipFile)) {
|
if (!Utils.zip(files, zipFile)) {
|
||||||
Log.w(TAG, "Failed to write zip file '$zipFile'")
|
Log.w(TAG, "Failed to write zip file '$zipFile'")
|
||||||
Utils.alertView(this, getString(R.string.error),
|
alertTitle.value = getString(R.string.error)
|
||||||
String.format(getString(R.string.backup_failed),
|
alertMessage.value = String.format(getString(R.string.backup_failed),
|
||||||
Utils.fileNameOfUri(applicationContext, downloadsOutputUri!!)))
|
Utils.fileNameOfUri(applicationContext, downloadsOutputUri!!))
|
||||||
|
showAlert.value = true
|
||||||
downloadsOutputUri = null
|
downloadsOutputUri = null
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val content = Utils.getFileContents(zipFilePath)
|
val content = Utils.getFileContents(zipFilePath)
|
||||||
if (content == null) {
|
if (content == null) {
|
||||||
Log.w(TAG, "Failed to read zip file '$zipFile'")
|
Log.w(TAG, "Failed to read zip file '$zipFile'")
|
||||||
Utils.alertView(this, getString(R.string.error),
|
alertTitle.value = getString(R.string.error)
|
||||||
String.format(getString(R.string.backup_failed),
|
alertMessage.value = String.format(getString(R.string.backup_failed),
|
||||||
Utils.fileNameOfUri(applicationContext, downloadsOutputUri!!)))
|
Utils.fileNameOfUri(applicationContext, downloadsOutputUri!!))
|
||||||
|
showAlert.value = true
|
||||||
downloadsOutputUri = null
|
downloadsOutputUri = null
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!Utils.encryptToUri(applicationContext, downloadsOutputUri!!, content, password)) {
|
if (!Utils.encryptToUri(applicationContext, downloadsOutputUri!!, content, password)) {
|
||||||
Utils.alertView(this, getString(R.string.error),
|
alertTitle.value = getString(R.string.error)
|
||||||
String.format(getString(R.string.backup_failed),
|
alertMessage.value = String.format(getString(R.string.backup_failed),
|
||||||
Utils.fileNameOfUri(applicationContext, downloadsOutputUri!!)))
|
Utils.fileNameOfUri(applicationContext, downloadsOutputUri!!))
|
||||||
|
showAlert.value = true
|
||||||
downloadsOutputUri = null
|
downloadsOutputUri = null
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Utils.alertView(this, getString(R.string.info),
|
alertTitle.value = getString(R.string.info)
|
||||||
String.format(getString(R.string.backed_up),
|
alertMessage.value = String.format(getString(R.string.backed_up),
|
||||||
Utils.fileNameOfUri(applicationContext, downloadsOutputUri!!)))
|
Utils.fileNameOfUri(applicationContext, downloadsOutputUri!!))
|
||||||
|
showAlert.value = true
|
||||||
Utils.deleteFile(File(zipFilePath))
|
Utils.deleteFile(File(zipFilePath))
|
||||||
downloadsOutputUri = null
|
downloadsOutputUri = null
|
||||||
}
|
}
|
||||||
@@ -2584,34 +2596,27 @@ class MainActivity : ComponentActivity() {
|
|||||||
val zipFilePath = BaresipService.filesPath + "/$zipFile"
|
val zipFilePath = BaresipService.filesPath + "/$zipFile"
|
||||||
val zipData = Utils.decryptFromUri(applicationContext, downloadsInputUri!!, password)
|
val zipData = Utils.decryptFromUri(applicationContext, downloadsInputUri!!, password)
|
||||||
if (zipData == null) {
|
if (zipData == null) {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.error)
|
||||||
this, getString(R.string.error),
|
alertMessage.value = String.format(getString(R.string.restore_failed),
|
||||||
String.format(
|
Utils.fileNameOfUri(applicationContext, downloadsOutputUri!!))
|
||||||
getString(R.string.restore_failed),
|
showAlert.value = true
|
||||||
Utils.fileNameOfUri(applicationContext, downloadsInputUri!!)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
downloadsOutputUri = null
|
downloadsOutputUri = null
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!Utils.putFileContents(zipFilePath, zipData)) {
|
if (!Utils.putFileContents(zipFilePath, zipData)) {
|
||||||
Log.w(TAG, "Failed to write zip file '$zipFile'")
|
Log.w(TAG, "Failed to write zip file '$zipFile'")
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.error)
|
||||||
this, getString(R.string.error),
|
alertMessage.value = String.format(getString(R.string.restore_failed),
|
||||||
String.format(
|
Utils.fileNameOfUri(applicationContext, downloadsOutputUri!!))
|
||||||
getString(R.string.restore_failed),
|
showAlert.value = true
|
||||||
Utils.fileNameOfUri(applicationContext, downloadsInputUri!!)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
downloadsOutputUri = null
|
downloadsOutputUri = null
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!Utils.unZip(zipFilePath)) {
|
if (!Utils.unZip(zipFilePath)) {
|
||||||
Log.w(TAG, "Failed to unzip file '$zipFile'")
|
Log.w(TAG, "Failed to unzip file '$zipFile'")
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.error)
|
||||||
this, getString(R.string.error),
|
alertMessage.value = String.format(getString(R.string.restore_unzip_failed), "baresip", BuildConfig.VERSION_NAME)
|
||||||
String.format(getString(R.string.restore_unzip_failed), "baresip", "60.0.0")
|
showAlert.value = true
|
||||||
)
|
|
||||||
downloadsOutputUri = null
|
downloadsOutputUri = null
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -2627,18 +2632,16 @@ class MainActivity : ComponentActivity() {
|
|||||||
h.recording = arrayOf("", "")
|
h.recording = arrayOf("", "")
|
||||||
CallHistoryNew.save()
|
CallHistoryNew.save()
|
||||||
|
|
||||||
with(MaterialAlertDialogBuilder(this, R.style.AlertDialogTheme)) {
|
dialogTitle.value = getString(R.string.info)
|
||||||
setTitle(getString(R.string.info))
|
dialogMessage.value = getString(R.string.restored)
|
||||||
setMessage(getString(R.string.restored))
|
positiveText.value = getString(R.string.restart)
|
||||||
setPositiveButton(getText(R.string.restart)) { dialog, _ ->
|
onPositiveClicked.value = {
|
||||||
quitRestart(true)
|
quitRestart(true)
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
setNeutralButton(getText(R.string.cancel)) { dialog, _ ->
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
show()
|
|
||||||
}
|
}
|
||||||
|
negativeText.value = getString(R.string.cancel)
|
||||||
|
onNegativeClicked.value = {}
|
||||||
|
showDialog.value = true
|
||||||
|
|
||||||
downloadsOutputUri = null
|
downloadsOutputUri = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ import android.content.Intent
|
|||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
|
||||||
import android.graphics.Canvas
|
|
||||||
import android.media.AudioAttributes
|
import android.media.AudioAttributes
|
||||||
import android.media.AudioDeviceInfo
|
import android.media.AudioDeviceInfo
|
||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
@@ -25,21 +23,14 @@ import android.provider.DocumentsContract
|
|||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import android.provider.OpenableColumns
|
import android.provider.OpenableColumns
|
||||||
import android.text.format.DateUtils
|
import android.text.format.DateUtils
|
||||||
import android.view.View
|
|
||||||
import android.widget.ImageView
|
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.compose.foundation.isSystemInDarkTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.graphics.createBitmap
|
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.core.text.isDigitsOnly
|
import androidx.core.text.isDigitsOnly
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.ProcessLifecycleOwner
|
import androidx.lifecycle.ProcessLifecycleOwner
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import java.io.BufferedInputStream
|
import java.io.BufferedInputStream
|
||||||
import java.io.BufferedOutputStream
|
import java.io.BufferedOutputStream
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -92,18 +83,6 @@ object Utils {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
fun alertView(context: Context, title: String, message: String, action: () -> (Unit) = {}) {
|
|
||||||
with(MaterialAlertDialogBuilder(context, R.style.AlertDialogTheme)) {
|
|
||||||
setTitle(title)
|
|
||||||
setMessage(message)
|
|
||||||
setPositiveButton(R.string.ok) { dialog, _ ->
|
|
||||||
dialog.dismiss()
|
|
||||||
action()
|
|
||||||
}
|
|
||||||
show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun uriHostPart(uri: String): String {
|
fun uriHostPart(uri: String): String {
|
||||||
return if (uri.contains("@")) {
|
return if (uri.contains("@")) {
|
||||||
uri.substringAfter("@")
|
uri.substringAfter("@")
|
||||||
@@ -407,46 +386,6 @@ object Utils {
|
|||||||
return Regex("^[-a-zA-Z0-9.!%*_+`'~]+\$").matches(token)
|
return Regex("^[-a-zA-Z0-9.!%*_+`'~]+\$").matches(token)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setAvatar(ctx: Context, imageView: ImageView, textView: TextView, uri: String) {
|
|
||||||
|
|
||||||
when (val contact = Contact.findContact(uri)) {
|
|
||||||
|
|
||||||
is Contact.BaresipContact -> {
|
|
||||||
val avatarImage = contact.avatarImage
|
|
||||||
if (avatarImage != null) {
|
|
||||||
imageView.setImageBitmap(avatarImage)
|
|
||||||
} else {
|
|
||||||
textView.background.setTint(contact.color)
|
|
||||||
if (contact.name.isNotEmpty())
|
|
||||||
textView.text = "${contact.name[0]}"
|
|
||||||
else
|
|
||||||
textView.text = ""
|
|
||||||
imageView.setImageBitmap(bitmapFromView(textView))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
is Contact.AndroidContact -> {
|
|
||||||
val thumbnailUri = contact.thumbnailUri
|
|
||||||
if (thumbnailUri != null) {
|
|
||||||
imageView.setImageURI(thumbnailUri)
|
|
||||||
} else {
|
|
||||||
textView.background.setTint(contact.color)
|
|
||||||
if (contact.name.isNotEmpty())
|
|
||||||
textView.text = "${contact.name[0]}"
|
|
||||||
else
|
|
||||||
textView.text = ""
|
|
||||||
imageView.setImageBitmap(bitmapFromView(textView))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
null -> {
|
|
||||||
val bitmap = BitmapFactory.decodeResource(ctx.resources, R.drawable.person_image)
|
|
||||||
imageView.setImageBitmap(bitmap)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun checkIfName(name: String): Boolean {
|
fun checkIfName(name: String): Boolean {
|
||||||
if ((name.length < 2) || !name.first().isLetter()) return false
|
if ((name.length < 2) || !name.first().isLetter()) return false
|
||||||
@@ -883,13 +822,6 @@ object Utils {
|
|||||||
Configuration.UI_MODE_NIGHT_YES
|
Configuration.UI_MODE_NIGHT_YES
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun isNightMode() = when (AppCompatDelegate.getDefaultNightMode()) {
|
|
||||||
AppCompatDelegate.MODE_NIGHT_NO -> false
|
|
||||||
AppCompatDelegate.MODE_NIGHT_YES -> true
|
|
||||||
else -> isSystemInDarkTheme()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun relativeTime(ctx: Context, time: GregorianCalendar): String {
|
fun relativeTime(ctx: Context, time: GregorianCalendar): String {
|
||||||
return if (DateUtils.isToday(time.timeInMillis)) {
|
return if (DateUtils.isToday(time.timeInMillis)) {
|
||||||
val fmt = DateFormat.getTimeInstance(DateFormat.SHORT)
|
val fmt = DateFormat.getTimeInstance(DateFormat.SHORT)
|
||||||
@@ -907,14 +839,6 @@ object Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun bitmapFromView(view: View): Bitmap {
|
|
||||||
val bitmap = createBitmap(view.layoutParams.width, view.layoutParams.height)
|
|
||||||
val canvas = Canvas(bitmap)
|
|
||||||
view.layout(0, 0, view.layoutParams.width, view.layoutParams.height)
|
|
||||||
view.draw(canvas)
|
|
||||||
return bitmap
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isSpeakerPhoneOn(am: AudioManager): Boolean {
|
fun isSpeakerPhoneOn(am: AudioManager): Boolean {
|
||||||
return if (Build.VERSION.SDK_INT >= 31)
|
return if (Build.VERSION.SDK_INT >= 31)
|
||||||
am.communicationDevice!!.type == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER
|
am.communicationDevice!!.type == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
<resources>
|
|
||||||
|
|
||||||
<style name="AlertDialogTheme" parent="@style/ThemeOverlay.MaterialComponents.MaterialAlertDialog">
|
|
||||||
<item name="materialAlertDialogTitleTextStyle">@style/Alert.Title</item>
|
|
||||||
<item name="materialAlertDialogBodyTextStyle">@style/Alert.Message</item>
|
|
||||||
<item name="buttonBarPositiveButtonStyle">@style/Alert.Button.Positive</item>
|
|
||||||
<item name="buttonBarNegativeButtonStyle">@style/Alert.Button.Positive</item>
|
|
||||||
<item name="buttonBarNeutralButtonStyle">@style/Alert.Button.Neutral</item>
|
|
||||||
<item name="android:windowBackground">@color/colorCardBackground</item>
|
|
||||||
<item name="android:background">@color/colorCardBackground</item>
|
|
||||||
<item name="android:textSize">14sp</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style name="Alert.Title" parent="@style/MaterialAlertDialog.Material3.Title.Text">
|
|
||||||
<item name="android:textColor">@color/colorAlert</item>
|
|
||||||
<item name="android:textSize">20sp</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style name="Alert.Message" parent="@style/MaterialAlertDialog.Material3.Body.Text">
|
|
||||||
<item name="android:textColor">@color/colorItemText</item>
|
|
||||||
<item name="android:textSize">16sp</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style name="Alert.Button.Positive" parent="Widget.Material3.Button.TextButton">
|
|
||||||
<item name="android:textColor">@color/colorAlert</item>
|
|
||||||
<item name="rippleColor">@color/colorAccent</item>
|
|
||||||
<item name="android:textSize">14sp</item>
|
|
||||||
<item name="android:textAllCaps">true</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style name="Alert.Button.Neutral" parent="Widget.Material3.Button.TextButton">
|
|
||||||
<item name="rippleColor">@color/colorAccent</item>
|
|
||||||
<item name="android:textColor">@color/colorGray</item>
|
|
||||||
<item name="android:textSize">14sp</item>
|
|
||||||
<item name="android:textAllCaps">true</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
</resources>
|
|
||||||
Reference in New Issue
Block a user