Added Blocking screen to account settings
Added capability to add call and message peers to blocked list Fixed background color of bottom navigation bar on some screens
This commit is contained in:
@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.Spacer
|
|||||||
import androidx.compose.foundation.layout.WindowInsets
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.imePadding
|
import androidx.compose.foundation.layout.imePadding
|
||||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.statusBarsPadding
|
import androidx.compose.foundation.layout.statusBarsPadding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
@ -56,7 +55,7 @@ fun AboutScreen(onBack: () -> Unit) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = Modifier.fillMaxSize().imePadding().navigationBarsPadding(),
|
modifier = Modifier.fillMaxSize().imePadding(),
|
||||||
containerColor = MaterialTheme.colorScheme.background,
|
containerColor = MaterialTheme.colorScheme.background,
|
||||||
topBar = {
|
topBar = {
|
||||||
Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
|
Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
|
||||||
|
|||||||
@ -13,7 +13,6 @@ import androidx.compose.foundation.layout.WindowInsets
|
|||||||
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.imePadding
|
import androidx.compose.foundation.layout.imePadding
|
||||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.statusBarsPadding
|
import androidx.compose.foundation.layout.statusBarsPadding
|
||||||
@ -164,7 +163,7 @@ private fun AccountScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = Modifier.fillMaxSize().imePadding().navigationBarsPadding(),
|
modifier = Modifier.fillMaxSize().imePadding(),
|
||||||
containerColor = MaterialTheme.colorScheme.background,
|
containerColor = MaterialTheme.colorScheme.background,
|
||||||
topBar = {
|
topBar = {
|
||||||
Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
|
Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
|
||||||
@ -604,55 +603,17 @@ private fun AccountContent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BlockUnknown() {
|
fun Blocking(navController: NavController, aor: String) {
|
||||||
val blockUnknownTitle = stringResource(R.string.block_unknown)
|
|
||||||
val blockUnknownHelp = stringResource(R.string.block_unknown_help)
|
|
||||||
val block by viewModel.blockUnknown.collectAsState()
|
|
||||||
Row(
|
Row(
|
||||||
Modifier.fillMaxWidth().padding(end = 10.dp),
|
Modifier.fillMaxWidth().padding(top = 8.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.Start
|
horizontalArrangement = Arrangement.Start
|
||||||
) {
|
) {
|
||||||
Text(text = blockUnknownTitle,
|
Text(
|
||||||
modifier = Modifier
|
text = stringResource(R.string.blocking),
|
||||||
.weight(1f)
|
modifier = Modifier.weight(1f).clickable { navController.navigate("blocking/$aor") },
|
||||||
.clickable {
|
fontSize = 18.sp,
|
||||||
alertTitle.value = blockUnknownTitle
|
fontWeight = FontWeight.Bold
|
||||||
alertMessage.value = blockUnknownHelp
|
|
||||||
showAlert.value = true
|
|
||||||
},
|
|
||||||
fontSize = 18.sp
|
|
||||||
)
|
|
||||||
Switch(
|
|
||||||
checked = block,
|
|
||||||
onCheckedChange = { viewModel.blockUnknown.value = it }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun BlockHidden() {
|
|
||||||
val blockHiddenTitle = stringResource(R.string.block_hidden)
|
|
||||||
val blockHiddenHelp = stringResource(R.string.block_hidden_help)
|
|
||||||
val block by viewModel.blockHidden.collectAsState()
|
|
||||||
Row(
|
|
||||||
Modifier.fillMaxWidth().padding(end = 10.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = Arrangement.Start
|
|
||||||
) {
|
|
||||||
Text(text = blockHiddenTitle,
|
|
||||||
modifier = Modifier
|
|
||||||
.weight(1f)
|
|
||||||
.clickable {
|
|
||||||
alertTitle.value = blockHiddenTitle
|
|
||||||
alertMessage.value = blockHiddenHelp
|
|
||||||
showAlert.value = true
|
|
||||||
},
|
|
||||||
fontSize = 18.sp
|
|
||||||
)
|
|
||||||
Switch(
|
|
||||||
checked = block,
|
|
||||||
onCheckedChange = { viewModel.blockHidden.value = it }
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -660,7 +621,7 @@ private fun AccountContent(
|
|||||||
@Composable
|
@Composable
|
||||||
fun AudioCodecs(navController: NavController, aor: String) {
|
fun AudioCodecs(navController: NavController, aor: String) {
|
||||||
Row(
|
Row(
|
||||||
Modifier.fillMaxWidth(),
|
Modifier.fillMaxWidth().padding(top = 8.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.Start
|
horizontalArrangement = Arrangement.Start
|
||||||
) {
|
) {
|
||||||
@ -1343,8 +1304,7 @@ private fun AccountContent(
|
|||||||
CheckOrigin()
|
CheckOrigin()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BlockUnknown()
|
Blocking(navController, aor)
|
||||||
BlockHidden()
|
|
||||||
if (!ua.account.isMobile) {
|
if (!ua.account.isMobile) {
|
||||||
AudioCodecs(navController, aor)
|
AudioCodecs(navController, aor)
|
||||||
MediaEnc()
|
MediaEnc()
|
||||||
|
|||||||
@ -69,7 +69,7 @@ fun NavGraphBuilder.accountsScreenRoute(navController: NavController) {
|
|||||||
@Composable
|
@Composable
|
||||||
fun AccountsScreen(navController: NavController) {
|
fun AccountsScreen(navController: NavController) {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = Modifier.fillMaxSize().imePadding().navigationBarsPadding(),
|
modifier = Modifier.fillMaxSize().imePadding(),
|
||||||
containerColor = MaterialTheme.colorScheme.background,
|
containerColor = MaterialTheme.colorScheme.background,
|
||||||
topBar = {
|
topBar = {
|
||||||
Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
|
Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
|
||||||
|
|||||||
@ -20,7 +20,6 @@ import androidx.compose.foundation.layout.WindowInsets
|
|||||||
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.imePadding
|
import androidx.compose.foundation.layout.imePadding
|
||||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.statusBarsPadding
|
import androidx.compose.foundation.layout.statusBarsPadding
|
||||||
@ -101,7 +100,7 @@ private fun AudioScreen(
|
|||||||
checkOnClick: () -> Unit,
|
checkOnClick: () -> Unit,
|
||||||
) {
|
) {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = Modifier.fillMaxSize().imePadding().navigationBarsPadding(),
|
modifier = Modifier.fillMaxSize().imePadding(),
|
||||||
containerColor = MaterialTheme.colorScheme.background,
|
containerColor = MaterialTheme.colorScheme.background,
|
||||||
topBar = {
|
topBar = {
|
||||||
Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
|
Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
|
||||||
|
|||||||
@ -553,6 +553,7 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Blocked.restore()
|
Blocked.restore()
|
||||||
|
BlockRule.restore()
|
||||||
|
|
||||||
val recordings = File(filesDir, "recordings")
|
val recordings = File(filesDir, "recordings")
|
||||||
|
|
||||||
@ -988,6 +989,11 @@ class BaresipService: Service() {
|
|||||||
)
|
)
|
||||||
else if (ua.account.blockHidden && peerUri.contains("anonymous"))
|
else if (ua.account.blockHidden && peerUri.contains("anonymous"))
|
||||||
getString(R.string.hidden_call_blocked)
|
getString(R.string.hidden_call_blocked)
|
||||||
|
else if (isBlocked(peerUri))
|
||||||
|
String.format(
|
||||||
|
getString(R.string.call_blocked),
|
||||||
|
Utils.friendlyUri(this, peerUri, ua.account)
|
||||||
|
)
|
||||||
else if (!Utils.checkPermissions(this, arrayOf(RECORD_AUDIO)))
|
else if (!Utils.checkPermissions(this, arrayOf(RECORD_AUDIO)))
|
||||||
getString(R.string.no_calls)
|
getString(R.string.no_calls)
|
||||||
else
|
else
|
||||||
@ -1452,6 +1458,28 @@ class BaresipService: Service() {
|
|||||||
|
|
||||||
val aor = ua.account.aor
|
val aor = ua.account.aor
|
||||||
|
|
||||||
|
if ((ua.account.blockUnknown && Contact.contactName(peerUri) == peerUri) ||
|
||||||
|
(ua.account.blockHidden && peerUri.contains("anonymous")) ||
|
||||||
|
isBlocked(peerUri)) {
|
||||||
|
Log.d(TAG, "Auto-rejecting blocked message from $peerUri")
|
||||||
|
toast(
|
||||||
|
if (ua.account.blockHidden && peerUri.contains("anonymous"))
|
||||||
|
getString(R.string.hidden_message_blocked)
|
||||||
|
else
|
||||||
|
String.format(
|
||||||
|
getString(R.string.message_blocked),
|
||||||
|
Utils.friendlyUri(this, peerUri, ua.account)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
Blocked(
|
||||||
|
ua.account.aor,
|
||||||
|
peerUri,
|
||||||
|
"message",
|
||||||
|
GregorianCalendar().timeInMillis
|
||||||
|
).add()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Check for duplicates
|
// Check for duplicates
|
||||||
val lastMsg = messages.lastOrNull { m -> m.aor == aor }
|
val lastMsg = messages.lastOrNull { m -> m.aor == aor }
|
||||||
if (lastMsg != null && lastMsg.timeStamp == timeStamp && lastMsg.peerUri == peerUri &&
|
if (lastMsg != null && lastMsg.timeStamp == timeStamp && lastMsg.peerUri == peerUri &&
|
||||||
@ -2958,6 +2986,14 @@ class BaresipService: Service() {
|
|||||||
val calls = ArrayList<Call>()
|
val calls = ArrayList<Call>()
|
||||||
var callHistory = ArrayList<CallHistoryNew>()
|
var callHistory = ArrayList<CallHistoryNew>()
|
||||||
var blocked = ArrayList<Blocked>()
|
var blocked = ArrayList<Blocked>()
|
||||||
|
var blockRules = mutableListOf<BlockRule>()
|
||||||
|
|
||||||
|
fun isBlocked(uri: String): Boolean {
|
||||||
|
for (rule in blockRules) {
|
||||||
|
if (rule.matches(uri)) return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
var contactsMode by mutableStateOf("baresip")
|
var contactsMode by mutableStateOf("baresip")
|
||||||
var addressFamily = ""
|
var addressFamily = ""
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import androidx.compose.foundation.layout.WindowInsets
|
|||||||
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.imePadding
|
import androidx.compose.foundation.layout.imePadding
|
||||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.statusBarsPadding
|
import androidx.compose.foundation.layout.statusBarsPadding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
@ -108,7 +107,7 @@ private fun BlockedScreen(navController: NavController, request: String, aor: St
|
|||||||
}
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = Modifier.fillMaxSize().imePadding().navigationBarsPadding(),
|
modifier = Modifier.fillMaxSize().imePadding(),
|
||||||
containerColor = MaterialTheme.colorScheme.background,
|
containerColor = MaterialTheme.colorScheme.background,
|
||||||
topBar = {
|
topBar = {
|
||||||
Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
|
Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
|
||||||
@ -220,7 +219,7 @@ private fun BlockedContent(
|
|||||||
verticalArrangement = Arrangement.spacedBy(12.dp)
|
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||||
) {
|
) {
|
||||||
Account(account)
|
Account(account)
|
||||||
Blocked(ctx, navController, blocked)
|
Blocked(ctx, navController, account, blocked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,7 +236,12 @@ private fun Account(account: Account) {
|
|||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun Blocked(ctx: Context, navController: NavController, blocked: MutableState<List<Blocked>>) {
|
private fun Blocked(
|
||||||
|
ctx: Context,
|
||||||
|
navController: NavController,
|
||||||
|
acc: Account,
|
||||||
|
blocked: MutableState<List<Blocked>>
|
||||||
|
) {
|
||||||
val showDialog = remember { mutableStateOf(false) }
|
val showDialog = remember { mutableStateOf(false) }
|
||||||
val message = remember { mutableStateOf("") }
|
val message = remember { mutableStateOf("") }
|
||||||
val lastButtonText = remember { mutableStateOf("") }
|
val lastButtonText = remember { mutableStateOf("") }
|
||||||
@ -286,7 +290,7 @@ private fun Blocked(ctx: Context, navController: NavController, blocked: Mutable
|
|||||||
modifier = Modifier.padding(start = 8.dp, end = 4.dp),
|
modifier = Modifier.padding(start = 8.dp, end = 4.dp),
|
||||||
fontSize = 18.sp)
|
fontSize = 18.sp)
|
||||||
Text(
|
Text(
|
||||||
text = peerUri.replace("sip:", ""),
|
text = Utils.friendlyUri(ctx, peerUri, acc),
|
||||||
fontSize = 18.sp,
|
fontSize = 18.sp,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis
|
overflow = TextOverflow.Ellipsis
|
||||||
|
|||||||
@ -22,7 +22,6 @@ 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.imePadding
|
import androidx.compose.foundation.layout.imePadding
|
||||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.statusBarsPadding
|
import androidx.compose.foundation.layout.statusBarsPadding
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
@ -94,7 +93,7 @@ fun NavGraphBuilder.callDetailsScreenRoute(navController: NavController, viewMod
|
|||||||
private fun CallDetailsScreen(navController: NavController, callRow: CallRow) {
|
private fun CallDetailsScreen(navController: NavController, callRow: CallRow) {
|
||||||
val detailsState = remember { callRow.details.toMutableStateList() }
|
val detailsState = remember { callRow.details.toMutableStateList() }
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = Modifier.fillMaxSize().imePadding().navigationBarsPadding(),
|
modifier = Modifier.fillMaxSize().imePadding(),
|
||||||
containerColor = MaterialTheme.colorScheme.background,
|
containerColor = MaterialTheme.colorScheme.background,
|
||||||
topBar = {
|
topBar = {
|
||||||
Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
|
Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
|
||||||
@ -294,8 +293,8 @@ private fun startTime(detail: Details, onDelete: (Details) -> Unit): String {
|
|||||||
Text(
|
Text(
|
||||||
text = startTimeText,
|
text = startTimeText,
|
||||||
modifier = Modifier.combinedClickable(
|
modifier = Modifier.combinedClickable(
|
||||||
onClick = {},
|
onClick = { showDialog.value = true },
|
||||||
onLongClick = { showDialog.value = true }
|
onLongClick = { }
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,6 @@ import androidx.compose.foundation.layout.WindowInsets
|
|||||||
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.imePadding
|
import androidx.compose.foundation.layout.imePadding
|
||||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.statusBarsPadding
|
import androidx.compose.foundation.layout.statusBarsPadding
|
||||||
@ -121,7 +120,7 @@ private fun CallsScreen(navController: NavController, viewModel: ViewModel, aor:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = Modifier.fillMaxSize().imePadding().navigationBarsPadding(),
|
modifier = Modifier.fillMaxSize().imePadding(),
|
||||||
containerColor = MaterialTheme.colorScheme.background,
|
containerColor = MaterialTheme.colorScheme.background,
|
||||||
topBar = {
|
topBar = {
|
||||||
Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
|
Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
|
||||||
@ -417,8 +416,7 @@ private fun Calls(
|
|||||||
peerNameWithLabel, callText
|
peerNameWithLabel, callText
|
||||||
)
|
)
|
||||||
secondButtonText.value = ""
|
secondButtonText.value = ""
|
||||||
thirdButtonText.value = ctx.getString(R.string.copy_uri)
|
thirdButtonText.value = ""
|
||||||
thirdAction.value = { Utils.copyToClipboard(ctx, peerUri) }
|
|
||||||
lastButtonText.value = ctx.getString(R.string.delete)
|
lastButtonText.value = ctx.getString(R.string.delete)
|
||||||
lastAction.value = { removeFromHistory(callHistory, callRow) }
|
lastAction.value = { removeFromHistory(callHistory, callRow) }
|
||||||
}
|
}
|
||||||
@ -433,8 +431,12 @@ private fun Calls(
|
|||||||
val uri = Utils.sipToTel(peerUri)
|
val uri = Utils.sipToTel(peerUri)
|
||||||
navController.navigate("contact/$uri/new")
|
navController.navigate("contact/$uri/new")
|
||||||
}
|
}
|
||||||
thirdButtonText.value = ctx.getString(R.string.copy_uri)
|
thirdButtonText.value = ctx.getString(R.string.block)
|
||||||
thirdAction.value = { Utils.copyToClipboard(ctx, peerUri)
|
thirdAction.value = {
|
||||||
|
if (!BlockRule.exists(peerUri)) {
|
||||||
|
BaresipService.blockRules.add(BlockRule(peerUri))
|
||||||
|
BlockRule.save()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lastButtonText.value = ctx.getString(R.string.delete)
|
lastButtonText.value = ctx.getString(R.string.delete)
|
||||||
lastAction.value = { removeFromHistory(callHistory, callRow) }
|
lastAction.value = { removeFromHistory(callHistory, callRow) }
|
||||||
|
|||||||
@ -37,8 +37,6 @@ import androidx.compose.material.icons.automirrored.filled.Send
|
|||||||
import androidx.compose.material.icons.outlined.Call
|
import androidx.compose.material.icons.outlined.Call
|
||||||
import androidx.compose.material.icons.outlined.Clear
|
import androidx.compose.material.icons.outlined.Clear
|
||||||
import androidx.compose.material.icons.outlined.Email
|
import androidx.compose.material.icons.outlined.Email
|
||||||
import androidx.compose.material3.Button
|
|
||||||
import androidx.compose.material3.ButtonDefaults
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
@ -191,7 +189,6 @@ private fun ChatScreen(
|
|||||||
if (areMessagesLoaded)
|
if (areMessagesLoaded)
|
||||||
ChatContent(
|
ChatContent(
|
||||||
ctx,
|
ctx,
|
||||||
navController,
|
|
||||||
contentPadding,
|
contentPadding,
|
||||||
account, peerUri,
|
account, peerUri,
|
||||||
chatMessages,
|
chatMessages,
|
||||||
@ -286,7 +283,6 @@ private fun TopAppBar(
|
|||||||
@Composable
|
@Composable
|
||||||
private fun ChatContent(
|
private fun ChatContent(
|
||||||
ctx: Context,
|
ctx: Context,
|
||||||
navController: NavController,
|
|
||||||
contentPadding: PaddingValues,
|
contentPadding: PaddingValues,
|
||||||
account: Account,
|
account: Account,
|
||||||
peerUri: String,
|
peerUri: String,
|
||||||
@ -299,7 +295,7 @@ private fun ChatContent(
|
|||||||
) {
|
) {
|
||||||
Account(ctx, account)
|
Account(ctx, account)
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
Messages(ctx, navController, account, peerUri, messages, onMessageDeleted)
|
Messages(ctx, account, peerUri, messages, onMessageDeleted)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,7 +313,6 @@ private fun Account(ctx: Context, account: Account) {
|
|||||||
@Composable
|
@Composable
|
||||||
private fun Messages(
|
private fun Messages(
|
||||||
ctx: Context,
|
ctx: Context,
|
||||||
navController: NavController,
|
|
||||||
account: Account,
|
account: Account,
|
||||||
peerUri: String,
|
peerUri: String,
|
||||||
messages: List<Message>,
|
messages: List<Message>,
|
||||||
@ -389,42 +384,28 @@ private fun Messages(
|
|||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
modifier = Modifier.padding(end = 12.dp)
|
modifier = Modifier.padding(end = 12.dp)
|
||||||
) {
|
) {
|
||||||
Button(
|
CustomElements.Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
if (Contact.findContact(peerUri) == null) {
|
dialogMessage.value = ctx.getString(R.string.short_message_question)
|
||||||
dialogMessage.value = String.format(
|
secondButtonText.value = ""
|
||||||
ctx.getString(R.string.long_message_question),
|
lastButtonText.value = ctx.getString(R.string.delete)
|
||||||
peerUri
|
lastAction.value = {
|
||||||
)
|
message.delete()
|
||||||
secondButtonText.value = ctx.getString(R.string.add_contact)
|
onMessageDeleted()
|
||||||
secondAction.value = { navController.navigate("contact/$peerUri/new") }
|
|
||||||
lastButtonText.value = ctx.getString(R.string.delete)
|
|
||||||
lastAction.value = {
|
|
||||||
message.delete()
|
|
||||||
onMessageDeleted()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dialogMessage.value = ctx.getString(R.string.short_message_question)
|
|
||||||
secondButtonText.value = ""
|
|
||||||
lastButtonText.value = ctx.getString(R.string.delete)
|
|
||||||
lastAction.value = {
|
|
||||||
message.delete()
|
|
||||||
onMessageDeleted()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
showDialog.value = true
|
showDialog.value = true
|
||||||
},
|
},
|
||||||
|
onLongClick = {
|
||||||
|
},
|
||||||
shape = if (message.direction == MESSAGE_DOWN)
|
shape = if (message.direction == MESSAGE_DOWN)
|
||||||
RoundedCornerShape(50.dp, 20.dp, 20.dp, 10.dp)
|
RoundedCornerShape(50.dp, 20.dp, 20.dp, 10.dp)
|
||||||
else
|
else
|
||||||
RoundedCornerShape(20.dp, 10.dp, 50.dp, 20.dp),
|
RoundedCornerShape(20.dp, 10.dp, 50.dp, 20.dp),
|
||||||
colors = ButtonDefaults.buttonColors(
|
color =
|
||||||
containerColor =
|
if (message.direction == MESSAGE_DOWN)
|
||||||
if (message.direction == MESSAGE_DOWN)
|
MaterialTheme.colorScheme.secondaryContainer
|
||||||
MaterialTheme.colorScheme.secondaryContainer
|
else
|
||||||
else
|
MaterialTheme.colorScheme.primaryContainer,
|
||||||
MaterialTheme.colorScheme.primaryContainer
|
|
||||||
),
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.wrapContentHeight()
|
.wrapContentHeight()
|
||||||
|
|||||||
@ -253,6 +253,8 @@ private fun Chats(
|
|||||||
val dialogMessage = remember { mutableStateOf("") }
|
val dialogMessage = remember { mutableStateOf("") }
|
||||||
val secondButtonText = remember { mutableStateOf("") }
|
val secondButtonText = remember { mutableStateOf("") }
|
||||||
val secondAction = remember { mutableStateOf({}) }
|
val secondAction = remember { mutableStateOf({}) }
|
||||||
|
val thirdButtonText = remember { mutableStateOf("") }
|
||||||
|
val thirdAction = remember { mutableStateOf({}) }
|
||||||
val lastButtonText = remember { mutableStateOf("") }
|
val lastButtonText = remember { mutableStateOf("") }
|
||||||
val lastAction = remember { mutableStateOf({}) }
|
val lastAction = remember { mutableStateOf({}) }
|
||||||
|
|
||||||
@ -264,6 +266,8 @@ private fun Chats(
|
|||||||
firstButtonText = stringResource(R.string.cancel),
|
firstButtonText = stringResource(R.string.cancel),
|
||||||
secondButtonText = secondButtonText.value,
|
secondButtonText = secondButtonText.value,
|
||||||
onSecondClicked = secondAction.value,
|
onSecondClicked = secondAction.value,
|
||||||
|
thirdButtonText = thirdButtonText.value,
|
||||||
|
onThirdClicked = thirdAction.value,
|
||||||
lastButtonText = lastButtonText.value,
|
lastButtonText = lastButtonText.value,
|
||||||
onLastClicked = lastAction.value,
|
onLastClicked = lastAction.value,
|
||||||
)
|
)
|
||||||
@ -344,10 +348,17 @@ private fun Chats(
|
|||||||
ctx.getString(R.string.long_chat_question),
|
ctx.getString(R.string.long_chat_question),
|
||||||
peerName
|
peerName
|
||||||
)
|
)
|
||||||
secondButtonText.value = ctx.getString(R.string.delete)
|
secondButtonText.value = ctx.getString(R.string.add_contact)
|
||||||
secondAction.value = { deleteMessages(uaMessages, account, message.peerUri) }
|
secondAction.value = { navController.navigate("contact/${message.peerUri}/new") }
|
||||||
lastButtonText.value = ctx.getString(R.string.add_contact)
|
thirdButtonText.value = ctx.getString(R.string.block)
|
||||||
lastAction.value = { navController.navigate("contact/${message.peerUri}/new") }
|
thirdAction.value = {
|
||||||
|
if (!BlockRule.exists(message.peerUri)) {
|
||||||
|
BaresipService.blockRules.add(BlockRule(message.peerUri))
|
||||||
|
BlockRule.save()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastButtonText.value = ctx.getString(R.string.delete)
|
||||||
|
lastAction.value = { deleteMessages(uaMessages, account, message.peerUri) }
|
||||||
}
|
}
|
||||||
showDialog.value = true
|
showDialog.value = true
|
||||||
},
|
},
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.WindowInsets
|
|||||||
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.imePadding
|
import androidx.compose.foundation.layout.imePadding
|
||||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.statusBarsPadding
|
import androidx.compose.foundation.layout.statusBarsPadding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
@ -118,7 +117,7 @@ private fun CodecsScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = Modifier.fillMaxSize().imePadding().navigationBarsPadding(),
|
modifier = Modifier.fillMaxSize().imePadding(),
|
||||||
containerColor = MaterialTheme.colorScheme.background,
|
containerColor = MaterialTheme.colorScheme.background,
|
||||||
topBar = {
|
topBar = {
|
||||||
Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
|
Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
|
||||||
|
|||||||
@ -31,7 +31,6 @@ import androidx.compose.foundation.layout.WindowInsets
|
|||||||
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.imePadding
|
import androidx.compose.foundation.layout.imePadding
|
||||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.statusBarsPadding
|
import androidx.compose.foundation.layout.statusBarsPadding
|
||||||
@ -275,7 +274,7 @@ private fun ContactScreen(
|
|||||||
BackHandler(enabled = true) { onBack() }
|
BackHandler(enabled = true) { onBack() }
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = Modifier.fillMaxSize().imePadding().navigationBarsPadding(),
|
modifier = Modifier.fillMaxSize().imePadding(),
|
||||||
containerColor = MaterialTheme.colorScheme.background,
|
containerColor = MaterialTheme.colorScheme.background,
|
||||||
topBar = {
|
topBar = {
|
||||||
Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
|
Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
|
||||||
|
|||||||
@ -290,6 +290,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
callsScreenRoute(navController, viewModel)
|
callsScreenRoute(navController, viewModel)
|
||||||
callDetailsScreenRoute(navController, viewModel)
|
callDetailsScreenRoute(navController, viewModel)
|
||||||
blockedScreenRoute(navController)
|
blockedScreenRoute(navController)
|
||||||
|
blockingScreenRoute(navController)
|
||||||
chatsScreenRoute(navController)
|
chatsScreenRoute(navController)
|
||||||
chatScreenRoute(navController, viewModel)
|
chatScreenRoute(navController, viewModel)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,7 +30,6 @@ import androidx.compose.foundation.layout.WindowInsets
|
|||||||
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.imePadding
|
import androidx.compose.foundation.layout.imePadding
|
||||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.statusBarsPadding
|
import androidx.compose.foundation.layout.statusBarsPadding
|
||||||
@ -156,7 +155,7 @@ private fun SettingsScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = Modifier.fillMaxSize().imePadding().navigationBarsPadding(),
|
modifier = Modifier.fillMaxSize().imePadding(),
|
||||||
containerColor = MaterialTheme.colorScheme.background,
|
containerColor = MaterialTheme.colorScheme.background,
|
||||||
topBar = {
|
topBar = {
|
||||||
Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
|
Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
|
||||||
|
|||||||
@ -279,6 +279,17 @@
|
|||||||
<string name="hidden_call_blocked">Estetty puhelu tuntemattomalta soittajalta</string>
|
<string name="hidden_call_blocked">Estetty puhelu tuntemattomalta soittajalta</string>
|
||||||
<string name="message_blocked">Estetty viesti vieraalta lähettäjältä \`%1$s\`</string>
|
<string name="message_blocked">Estetty viesti vieraalta lähettäjältä \`%1$s\`</string>
|
||||||
<string name="hidden_message_blocked">Estetty viesti tuntemattomalta lähettäjältä</string>
|
<string name="hidden_message_blocked">Estetty viesti tuntemattomalta lähettäjältä</string>
|
||||||
|
<!-- Blocking Activity -->
|
||||||
|
<string name="blocking">Estot</string>
|
||||||
|
<string name="blocking_list">Estolista</string>
|
||||||
|
<string name="new_blocking_rule">Uusi estosääntö</string>
|
||||||
|
<string name="blocking_rule_help">Estosääntö voi olla joko merkkijono tai
|
||||||
|
säännöllinen lauseke. Jos merkkijono löytyy soittajan tai viestin
|
||||||
|
lähettäjän URI:sta tai jos säännöllinen lauseke sopii siihen, niin
|
||||||
|
puhelu tai viesti estetään.
|
||||||
|
</string>
|
||||||
|
<string name="blocking_delete_alert">Haluatko poistaa estosäännön \'%1$s\'\?</string>
|
||||||
|
|
||||||
<!-- Blocked Activity -->
|
<!-- Blocked Activity -->
|
||||||
<string name="blocked">Estetyt</string>
|
<string name="blocked">Estetyt</string>
|
||||||
<string name="blocked_calls">Estetyt puhelut</string>
|
<string name="blocked_calls">Estetyt puhelut</string>
|
||||||
@ -294,11 +305,10 @@
|
|||||||
<string name="peer">Kumppani</string>
|
<string name="peer">Kumppani</string>
|
||||||
<string name="time">Aika</string>
|
<string name="time">Aika</string>
|
||||||
<string name="calls_duration">Kesto</string>
|
<string name="calls_duration">Kesto</string>
|
||||||
<string name="calls_add_delete_question">Haluatko luoda kohteelle \'%1$s\' uuden yhteystiedon,
|
<string name="calls_add_delete_question">Haluatko lisätä URI:n \'%1$s\' yhteystietoihin tai
|
||||||
kopioida sen URI:n tai poistaa %2$s puheluhistoriasta\?
|
estolistaan tai poistaa %2$s puheluhistoriasta\?
|
||||||
</string>
|
</string>
|
||||||
<string name="calls_delete_question">Haluatko kopioida yhteystiedon \'%1$s\' URI:n tai poistaa
|
<string name="calls_delete_question">Haluatko poistaa %2$s puheluhistoriasta\?</string>
|
||||||
%2$s puheluhistoriasta\?</string>
|
|
||||||
<string name="disable_history">Poista käytöstä</string>
|
<string name="disable_history">Poista käytöstä</string>
|
||||||
<string name="enable_history">Ota käyttöön</string>
|
<string name="enable_history">Ota käyttöön</string>
|
||||||
<string name="delete_history_alert">Haluatko tyhjentää tilin \'%1$s\' puheluhistorian\?</string>
|
<string name="delete_history_alert">Haluatko tyhjentää tilin \'%1$s\' puheluhistorian\?</string>
|
||||||
@ -326,8 +336,9 @@
|
|||||||
<string name="today">Tänään</string>
|
<string name="today">Tänään</string>
|
||||||
<string name="you">Sinä</string>
|
<string name="you">Sinä</string>
|
||||||
<string name="new_chat_peer">Uusi viestin kohde</string>
|
<string name="new_chat_peer">Uusi viestin kohde</string>
|
||||||
<string name="long_chat_question">Haluatko poistaa viestiketjun tai
|
<string name="long_chat_question">Haluatko lisätä URI:n \'%1$s\' yhteystietoihin tai estolistaan
|
||||||
luoda uuden yhteystiedon \'%1$s\'\?</string>
|
tai poistaa tämän viestiketjun?
|
||||||
|
</string>
|
||||||
<string name="short_chat_question">Haluatko poistaa viestiketjun \'%1$s\'\?</string>
|
<string name="short_chat_question">Haluatko poistaa viestiketjun \'%1$s\'\?</string>
|
||||||
<string name="delete_chats_alert">Haluatko tyhjentää tilin \'%1$s\' viestihistorian\?</string>
|
<string name="delete_chats_alert">Haluatko tyhjentää tilin \'%1$s\' viestihistorian\?</string>
|
||||||
<!-- Codecs Activity -->
|
<!-- Codecs Activity -->
|
||||||
@ -403,10 +414,10 @@
|
|||||||
nimeltään \'ca_certs.crt\' ladataan Download-kansiosta.
|
nimeltään \'ca_certs.crt\' ladataan Download-kansiosta.
|
||||||
</string>
|
</string>
|
||||||
<string name="no_read_permission">Ei ulkoisen muistin lukuoikeutta</string>
|
<string name="no_read_permission">Ei ulkoisen muistin lukuoikeutta</string>
|
||||||
<string name="unique_contact_uri">Uniikki Contact URI</string>
|
<string name="unique_contact_uri">Uniikki kontakti-URI</string>
|
||||||
<string name="unique_contact_uri_help">Jos merkitty, Contact URI:n taataan olevan uniikki.
|
<string name="unique_contact_uri_help">Jos merkitty, kontakti-URI:n taataan olevan uniikki.
|
||||||
Merkittävä, jos on useammalla tilillä on same SIP URI:n käyttäjäosa, mutta myös
|
Merkittävä, jos on useammalla tilillä on sama SIP URI:n käyttäjäosa, mutta se myös
|
||||||
suojaa tilejä hyökkäyksiltä.
|
parantaa tilien suojaa hyökkäyksiltä.
|
||||||
</string>
|
</string>
|
||||||
<string name="audio_settings">Audio-asetukset</string>
|
<string name="audio_settings">Audio-asetukset</string>
|
||||||
<string name="speaker_phone">Kaiutin</string>
|
<string name="speaker_phone">Kaiutin</string>
|
||||||
@ -531,6 +542,7 @@
|
|||||||
<string name="deny">Estä</string>
|
<string name="deny">Estä</string>
|
||||||
<string name="add">Lisää</string>
|
<string name="add">Lisää</string>
|
||||||
<string name="delete">Poista</string>
|
<string name="delete">Poista</string>
|
||||||
|
<string name="block">Estä</string>
|
||||||
<string name="edit">Muokkaa</string>
|
<string name="edit">Muokkaa</string>
|
||||||
<string name="copy_uri">Kopioi URI</string>
|
<string name="copy_uri">Kopioi URI</string>
|
||||||
<string name="copied_to_clipboard">Kopioitu leikepöydälle</string>
|
<string name="copied_to_clipboard">Kopioitu leikepöydälle</string>
|
||||||
|
|||||||
@ -271,6 +271,15 @@
|
|||||||
<string name="hidden_call_blocked">Auto-rejected call from hidden caller</string>
|
<string name="hidden_call_blocked">Auto-rejected call from hidden caller</string>
|
||||||
<string name="message_blocked">Auto-rejected blocked message from \`%1$s\`</string>
|
<string name="message_blocked">Auto-rejected blocked message from \`%1$s\`</string>
|
||||||
<string name="hidden_message_blocked">Auto-rejected message from hidden sender</string>
|
<string name="hidden_message_blocked">Auto-rejected message from hidden sender</string>
|
||||||
|
<!-- Blocking Activity -->
|
||||||
|
<string name="blocking">Blocking</string>
|
||||||
|
<string name="blocking_list">Blocking List</string>
|
||||||
|
<string name="new_blocking_rule">New Blocking Rule</string>
|
||||||
|
<string name="blocking_rule_help">Blocking rule can be either a string or a regular expression.
|
||||||
|
If the string is included in the peer URI or regular expression matches,
|
||||||
|
the call or message will be blocked.
|
||||||
|
</string>
|
||||||
|
<string name="blocking_delete_alert">Do you want to delete blocking rule \'%1$s\'\?</string>
|
||||||
<!-- Blocked Activity -->
|
<!-- Blocked Activity -->
|
||||||
<string name="blocked">Blocked</string>
|
<string name="blocked">Blocked</string>
|
||||||
<string name="blocked_calls">Blocked Calls</string>
|
<string name="blocked_calls">Blocked Calls</string>
|
||||||
@ -287,10 +296,9 @@
|
|||||||
<string name="direction">Direction</string>
|
<string name="direction">Direction</string>
|
||||||
<string name="time">Time</string>
|
<string name="time">Time</string>
|
||||||
<string name="calls_duration">Duration</string>
|
<string name="calls_duration">Duration</string>
|
||||||
<string name="calls_add_delete_question">Do you want to add \'%1$s\' to contacts, copy its URI,
|
<string name="calls_add_delete_question">Do you want to add \'%1$s\' to contacts, block it,
|
||||||
or delete this %2$s from call history\?</string>
|
or delete %2$s from call history\?</string>
|
||||||
<string name="calls_delete_question">Do you want to copy URI of \'%1$s\' or delete this %2$s
|
<string name="calls_delete_question">Do you want to delete %2$s from call history\?</string>
|
||||||
from call history\?</string>
|
|
||||||
<string name="disable_history">Disable</string>
|
<string name="disable_history">Disable</string>
|
||||||
<string name="enable_history">Enable</string>
|
<string name="enable_history">Enable</string>
|
||||||
<string name="delete_history_alert">Do you want to delete call history of account \'%1$s\'\?</string>
|
<string name="delete_history_alert">Do you want to delete call history of account \'%1$s\'\?</string>
|
||||||
@ -308,7 +316,7 @@
|
|||||||
<string name="chat_with">Chat with %1$s</string>
|
<string name="chat_with">Chat with %1$s</string>
|
||||||
<string name="new_message">New message</string>
|
<string name="new_message">New message</string>
|
||||||
<string name="long_message_question">Do you want to delete message or add peer \'%1$s\' to contacts\?</string>
|
<string name="long_message_question">Do you want to delete message or add peer \'%1$s\' to contacts\?</string>
|
||||||
<string name="short_message_question">Do you want to delete message\?</string>
|
<string name="short_message_question">Do you want to delete this message\?</string>
|
||||||
<string name="add_contact">Add Contact</string>
|
<string name="add_contact">Add Contact</string>
|
||||||
<string name="sending_failed">Sending of message failed</string>
|
<string name="sending_failed">Sending of message failed</string>
|
||||||
<string name="message_failed">Failed</string>
|
<string name="message_failed">Failed</string>
|
||||||
@ -317,8 +325,8 @@
|
|||||||
<string name="today">Today</string>
|
<string name="today">Today</string>
|
||||||
<string name="you">You</string>
|
<string name="you">You</string>
|
||||||
<string name="new_chat_peer">New Chat Peer</string>
|
<string name="new_chat_peer">New Chat Peer</string>
|
||||||
<string name="long_chat_question">Do you want to delete chat with peer \'%1$s\' or
|
<string name="long_chat_question">Do you want to add \'%1$s\' to contacts, block it, or
|
||||||
add peer to contacts\?</string>
|
delete this chat?</string>
|
||||||
<string name="short_chat_question">Do you want to delete chat with \'%1$s\'\?</string>
|
<string name="short_chat_question">Do you want to delete chat with \'%1$s\'\?</string>
|
||||||
<string name="delete_chats_alert">Do you want to delete chat history of account \'%1$s\'\?</string>
|
<string name="delete_chats_alert">Do you want to delete chat history of account \'%1$s\'\?</string>
|
||||||
<!-- Codecs Activity -->
|
<!-- Codecs Activity -->
|
||||||
@ -510,6 +518,7 @@
|
|||||||
<string name="deny">Deny</string>
|
<string name="deny">Deny</string>
|
||||||
<string name="add">Add</string>
|
<string name="add">Add</string>
|
||||||
<string name="delete">Delete</string>
|
<string name="delete">Delete</string>
|
||||||
|
<string name="block">Block</string>
|
||||||
<string name="edit">Edit</string>
|
<string name="edit">Edit</string>
|
||||||
<string name="copy_uri">Copy URI</string>
|
<string name="copy_uri">Copy URI</string>
|
||||||
<string name="copied_to_clipboard">Copied to clipboard</string>
|
<string name="copied_to_clipboard">Copied to clipboard</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user