diff --git a/app/src/main/kotlin/com/tutpro/baresip/AboutScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/AboutScreen.kt index 99001d39..ce97e751 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/AboutScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/AboutScreen.kt @@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.imePadding -import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.rememberScrollState @@ -56,7 +55,7 @@ fun AboutScreen(onBack: () -> Unit) { } Scaffold( - modifier = Modifier.fillMaxSize().imePadding().navigationBarsPadding(), + modifier = Modifier.fillMaxSize().imePadding(), containerColor = MaterialTheme.colorScheme.background, topBar = { Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) { diff --git a/app/src/main/kotlin/com/tutpro/baresip/AccountScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/AccountScreen.kt index 17d0fa98..e414990e 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/AccountScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/AccountScreen.kt @@ -13,7 +13,6 @@ import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.imePadding -import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.statusBarsPadding @@ -164,7 +163,7 @@ private fun AccountScreen( } Scaffold( - modifier = Modifier.fillMaxSize().imePadding().navigationBarsPadding(), + modifier = Modifier.fillMaxSize().imePadding(), containerColor = MaterialTheme.colorScheme.background, topBar = { Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) { @@ -604,55 +603,17 @@ private fun AccountContent( } @Composable - fun BlockUnknown() { - val blockUnknownTitle = stringResource(R.string.block_unknown) - val blockUnknownHelp = stringResource(R.string.block_unknown_help) - val block by viewModel.blockUnknown.collectAsState() + fun Blocking(navController: NavController, aor: String) { Row( - Modifier.fillMaxWidth().padding(end = 10.dp), + Modifier.fillMaxWidth().padding(top = 8.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { - Text(text = blockUnknownTitle, - modifier = Modifier - .weight(1f) - .clickable { - alertTitle.value = blockUnknownTitle - 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 } + Text( + text = stringResource(R.string.blocking), + modifier = Modifier.weight(1f).clickable { navController.navigate("blocking/$aor") }, + fontSize = 18.sp, + fontWeight = FontWeight.Bold ) } } @@ -660,7 +621,7 @@ private fun AccountContent( @Composable fun AudioCodecs(navController: NavController, aor: String) { Row( - Modifier.fillMaxWidth(), + Modifier.fillMaxWidth().padding(top = 8.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { @@ -1343,8 +1304,7 @@ private fun AccountContent( CheckOrigin() } } - BlockUnknown() - BlockHidden() + Blocking(navController, aor) if (!ua.account.isMobile) { AudioCodecs(navController, aor) MediaEnc() diff --git a/app/src/main/kotlin/com/tutpro/baresip/AccountsScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/AccountsScreen.kt index c7908175..b1ac81a3 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/AccountsScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/AccountsScreen.kt @@ -69,7 +69,7 @@ fun NavGraphBuilder.accountsScreenRoute(navController: NavController) { @Composable fun AccountsScreen(navController: NavController) { Scaffold( - modifier = Modifier.fillMaxSize().imePadding().navigationBarsPadding(), + modifier = Modifier.fillMaxSize().imePadding(), containerColor = MaterialTheme.colorScheme.background, topBar = { Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) { diff --git a/app/src/main/kotlin/com/tutpro/baresip/AudioScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/AudioScreen.kt index 45013d84..db9ccc24 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/AudioScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/AudioScreen.kt @@ -20,7 +20,6 @@ import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.imePadding -import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.statusBarsPadding @@ -101,7 +100,7 @@ private fun AudioScreen( checkOnClick: () -> Unit, ) { Scaffold( - modifier = Modifier.fillMaxSize().imePadding().navigationBarsPadding(), + modifier = Modifier.fillMaxSize().imePadding(), containerColor = MaterialTheme.colorScheme.background, topBar = { Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) { diff --git a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt index f17a377f..7a77772a 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt @@ -553,6 +553,7 @@ class BaresipService: Service() { } Blocked.restore() + BlockRule.restore() val recordings = File(filesDir, "recordings") @@ -988,6 +989,11 @@ class BaresipService: Service() { ) else if (ua.account.blockHidden && peerUri.contains("anonymous")) 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))) getString(R.string.no_calls) else @@ -1452,6 +1458,28 @@ class BaresipService: Service() { 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 val lastMsg = messages.lastOrNull { m -> m.aor == aor } if (lastMsg != null && lastMsg.timeStamp == timeStamp && lastMsg.peerUri == peerUri && @@ -2958,6 +2986,14 @@ class BaresipService: Service() { val calls = ArrayList() var callHistory = ArrayList() var blocked = ArrayList() + var blockRules = mutableListOf() + + fun isBlocked(uri: String): Boolean { + for (rule in blockRules) { + if (rule.matches(uri)) return true + } + return false + } var contactsMode by mutableStateOf("baresip") var addressFamily = "" diff --git a/app/src/main/kotlin/com/tutpro/baresip/BlockedScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/BlockedScreen.kt index 10ba5db9..cf126bbc 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/BlockedScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/BlockedScreen.kt @@ -14,7 +14,6 @@ import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.imePadding -import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.lazy.LazyColumn @@ -108,7 +107,7 @@ private fun BlockedScreen(navController: NavController, request: String, aor: St } Scaffold( - modifier = Modifier.fillMaxSize().imePadding().navigationBarsPadding(), + modifier = Modifier.fillMaxSize().imePadding(), containerColor = MaterialTheme.colorScheme.background, topBar = { Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) { @@ -220,7 +219,7 @@ private fun BlockedContent( verticalArrangement = Arrangement.spacedBy(12.dp) ) { Account(account) - Blocked(ctx, navController, blocked) + Blocked(ctx, navController, account, blocked) } } @@ -237,7 +236,12 @@ private fun Account(account: Account) { @OptIn(ExperimentalFoundationApi::class) @Composable -private fun Blocked(ctx: Context, navController: NavController, blocked: MutableState>) { +private fun Blocked( + ctx: Context, + navController: NavController, + acc: Account, + blocked: MutableState> +) { val showDialog = remember { mutableStateOf(false) } val message = 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), fontSize = 18.sp) Text( - text = peerUri.replace("sip:", ""), + text = Utils.friendlyUri(ctx, peerUri, acc), fontSize = 18.sp, maxLines = 1, overflow = TextOverflow.Ellipsis diff --git a/app/src/main/kotlin/com/tutpro/baresip/CallDetailsScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/CallDetailsScreen.kt index 9dbbe42d..5b766b2e 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/CallDetailsScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/CallDetailsScreen.kt @@ -22,7 +22,6 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.imePadding -import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.layout.width @@ -94,7 +93,7 @@ fun NavGraphBuilder.callDetailsScreenRoute(navController: NavController, viewMod private fun CallDetailsScreen(navController: NavController, callRow: CallRow) { val detailsState = remember { callRow.details.toMutableStateList() } Scaffold( - modifier = Modifier.fillMaxSize().imePadding().navigationBarsPadding(), + modifier = Modifier.fillMaxSize().imePadding(), containerColor = MaterialTheme.colorScheme.background, topBar = { Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) { @@ -294,8 +293,8 @@ private fun startTime(detail: Details, onDelete: (Details) -> Unit): String { Text( text = startTimeText, modifier = Modifier.combinedClickable( - onClick = {}, - onLongClick = { showDialog.value = true } + onClick = { showDialog.value = true }, + onLongClick = { } ) ) diff --git a/app/src/main/kotlin/com/tutpro/baresip/CallsScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/CallsScreen.kt index b49942d1..e881cb47 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/CallsScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/CallsScreen.kt @@ -17,7 +17,6 @@ import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.imePadding -import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.statusBarsPadding @@ -121,7 +120,7 @@ private fun CallsScreen(navController: NavController, viewModel: ViewModel, aor: } Scaffold( - modifier = Modifier.fillMaxSize().imePadding().navigationBarsPadding(), + modifier = Modifier.fillMaxSize().imePadding(), containerColor = MaterialTheme.colorScheme.background, topBar = { Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) { @@ -417,8 +416,7 @@ private fun Calls( peerNameWithLabel, callText ) secondButtonText.value = "" - thirdButtonText.value = ctx.getString(R.string.copy_uri) - thirdAction.value = { Utils.copyToClipboard(ctx, peerUri) } + thirdButtonText.value = "" lastButtonText.value = ctx.getString(R.string.delete) lastAction.value = { removeFromHistory(callHistory, callRow) } } @@ -433,8 +431,12 @@ private fun Calls( val uri = Utils.sipToTel(peerUri) navController.navigate("contact/$uri/new") } - thirdButtonText.value = ctx.getString(R.string.copy_uri) - thirdAction.value = { Utils.copyToClipboard(ctx, peerUri) + thirdButtonText.value = ctx.getString(R.string.block) + thirdAction.value = { + if (!BlockRule.exists(peerUri)) { + BaresipService.blockRules.add(BlockRule(peerUri)) + BlockRule.save() + } } lastButtonText.value = ctx.getString(R.string.delete) lastAction.value = { removeFromHistory(callHistory, callRow) } diff --git a/app/src/main/kotlin/com/tutpro/baresip/ChatScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/ChatScreen.kt index 7203f83b..bb3c9cdf 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/ChatScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/ChatScreen.kt @@ -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.Clear 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.Icon import androidx.compose.material3.IconButton @@ -191,7 +189,6 @@ private fun ChatScreen( if (areMessagesLoaded) ChatContent( ctx, - navController, contentPadding, account, peerUri, chatMessages, @@ -286,7 +283,6 @@ private fun TopAppBar( @Composable private fun ChatContent( ctx: Context, - navController: NavController, contentPadding: PaddingValues, account: Account, peerUri: String, @@ -299,7 +295,7 @@ private fun ChatContent( ) { Account(ctx, account) 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 private fun Messages( ctx: Context, - navController: NavController, account: Account, peerUri: String, messages: List, @@ -389,42 +384,28 @@ private fun Messages( verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(end = 12.dp) ) { - Button( + CustomElements.Button( onClick = { - if (Contact.findContact(peerUri) == null) { - dialogMessage.value = String.format( - ctx.getString(R.string.long_message_question), - peerUri - ) - secondButtonText.value = ctx.getString(R.string.add_contact) - 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() - } + 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 }, + onLongClick = { + }, shape = if (message.direction == MESSAGE_DOWN) RoundedCornerShape(50.dp, 20.dp, 20.dp, 10.dp) else RoundedCornerShape(20.dp, 10.dp, 50.dp, 20.dp), - colors = ButtonDefaults.buttonColors( - containerColor = - if (message.direction == MESSAGE_DOWN) - MaterialTheme.colorScheme.secondaryContainer - else - MaterialTheme.colorScheme.primaryContainer - ), + color = + if (message.direction == MESSAGE_DOWN) + MaterialTheme.colorScheme.secondaryContainer + else + MaterialTheme.colorScheme.primaryContainer, modifier = Modifier .fillMaxWidth() .wrapContentHeight() diff --git a/app/src/main/kotlin/com/tutpro/baresip/ChatsScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/ChatsScreen.kt index 422edba1..e3be9282 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/ChatsScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/ChatsScreen.kt @@ -253,6 +253,8 @@ private fun Chats( val dialogMessage = remember { mutableStateOf("") } val secondButtonText = remember { mutableStateOf("") } val secondAction = remember { mutableStateOf({}) } + val thirdButtonText = remember { mutableStateOf("") } + val thirdAction = remember { mutableStateOf({}) } val lastButtonText = remember { mutableStateOf("") } val lastAction = remember { mutableStateOf({}) } @@ -264,6 +266,8 @@ private fun Chats( firstButtonText = stringResource(R.string.cancel), secondButtonText = secondButtonText.value, onSecondClicked = secondAction.value, + thirdButtonText = thirdButtonText.value, + onThirdClicked = thirdAction.value, lastButtonText = lastButtonText.value, onLastClicked = lastAction.value, ) @@ -344,10 +348,17 @@ private fun Chats( ctx.getString(R.string.long_chat_question), peerName ) - secondButtonText.value = ctx.getString(R.string.delete) - secondAction.value = { deleteMessages(uaMessages, account, message.peerUri) } - lastButtonText.value = ctx.getString(R.string.add_contact) - lastAction.value = { navController.navigate("contact/${message.peerUri}/new") } + secondButtonText.value = ctx.getString(R.string.add_contact) + secondAction.value = { navController.navigate("contact/${message.peerUri}/new") } + thirdButtonText.value = ctx.getString(R.string.block) + 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 }, diff --git a/app/src/main/kotlin/com/tutpro/baresip/CodecsScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/CodecsScreen.kt index ad52eaf3..6ac6ebf6 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/CodecsScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/CodecsScreen.kt @@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.imePadding -import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.lazy.LazyColumn @@ -118,7 +117,7 @@ private fun CodecsScreen( } Scaffold( - modifier = Modifier.fillMaxSize().imePadding().navigationBarsPadding(), + modifier = Modifier.fillMaxSize().imePadding(), containerColor = MaterialTheme.colorScheme.background, topBar = { Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) { diff --git a/app/src/main/kotlin/com/tutpro/baresip/ContactScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/ContactScreen.kt index 0dec9c9c..4b3c2a27 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/ContactScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/ContactScreen.kt @@ -31,7 +31,6 @@ import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.imePadding -import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.statusBarsPadding @@ -275,7 +274,7 @@ private fun ContactScreen( BackHandler(enabled = true) { onBack() } Scaffold( - modifier = Modifier.fillMaxSize().imePadding().navigationBarsPadding(), + modifier = Modifier.fillMaxSize().imePadding(), containerColor = MaterialTheme.colorScheme.background, topBar = { Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) { diff --git a/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt index 9151f5cd..10ab4659 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt @@ -290,6 +290,7 @@ class MainActivity : ComponentActivity() { callsScreenRoute(navController, viewModel) callDetailsScreenRoute(navController, viewModel) blockedScreenRoute(navController) + blockingScreenRoute(navController) chatsScreenRoute(navController) chatScreenRoute(navController, viewModel) } diff --git a/app/src/main/kotlin/com/tutpro/baresip/SettingsScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/SettingsScreen.kt index f2e0f282..047caed8 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/SettingsScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/SettingsScreen.kt @@ -30,7 +30,6 @@ import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.imePadding -import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.statusBarsPadding @@ -156,7 +155,7 @@ private fun SettingsScreen( } Scaffold( - modifier = Modifier.fillMaxSize().imePadding().navigationBarsPadding(), + modifier = Modifier.fillMaxSize().imePadding(), containerColor = MaterialTheme.colorScheme.background, topBar = { Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) { diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 20d0546f..c456b73c 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -279,6 +279,17 @@ Estetty puhelu tuntemattomalta soittajalta Estetty viesti vieraalta lähettäjältä \`%1$s\` Estetty viesti tuntemattomalta lähettäjältä + + Estot + Estolista + Uusi estosääntö + 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. + + Haluatko poistaa estosäännön \'%1$s\'\? + Estetyt Estetyt puhelut @@ -294,11 +305,10 @@ Kumppani Aika Kesto - Haluatko luoda kohteelle \'%1$s\' uuden yhteystiedon, - kopioida sen URI:n tai poistaa %2$s puheluhistoriasta\? + Haluatko lisätä URI:n \'%1$s\' yhteystietoihin tai + estolistaan tai poistaa %2$s puheluhistoriasta\? - Haluatko kopioida yhteystiedon \'%1$s\' URI:n tai poistaa - %2$s puheluhistoriasta\? + Haluatko poistaa %2$s puheluhistoriasta\? Poista käytöstä Ota käyttöön Haluatko tyhjentää tilin \'%1$s\' puheluhistorian\? @@ -326,8 +336,9 @@ Tänään Sinä Uusi viestin kohde - Haluatko poistaa viestiketjun tai - luoda uuden yhteystiedon \'%1$s\'\? + Haluatko lisätä URI:n \'%1$s\' yhteystietoihin tai estolistaan + tai poistaa tämän viestiketjun? + Haluatko poistaa viestiketjun \'%1$s\'\? Haluatko tyhjentää tilin \'%1$s\' viestihistorian\? @@ -403,10 +414,10 @@ nimeltään \'ca_certs.crt\' ladataan Download-kansiosta. Ei ulkoisen muistin lukuoikeutta - Uniikki Contact URI - Jos merkitty, Contact URI:n taataan olevan uniikki. - Merkittävä, jos on useammalla tilillä on same SIP URI:n käyttäjäosa, mutta myös - suojaa tilejä hyökkäyksiltä. + Uniikki kontakti-URI + Jos merkitty, kontakti-URI:n taataan olevan uniikki. + Merkittävä, jos on useammalla tilillä on sama SIP URI:n käyttäjäosa, mutta se myös + parantaa tilien suojaa hyökkäyksiltä. Audio-asetukset Kaiutin @@ -531,6 +542,7 @@ Estä Lisää Poista + Estä Muokkaa Kopioi URI Kopioitu leikepöydälle diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a892bd6a..4989774a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -271,6 +271,15 @@ Auto-rejected call from hidden caller Auto-rejected blocked message from \`%1$s\` Auto-rejected message from hidden sender + + Blocking + Blocking List + New Blocking Rule + 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. + + Do you want to delete blocking rule \'%1$s\'\? Blocked Blocked Calls @@ -287,10 +296,9 @@ Direction Time Duration - Do you want to add \'%1$s\' to contacts, copy its URI, - or delete this %2$s from call history\? - Do you want to copy URI of \'%1$s\' or delete this %2$s - from call history\? + Do you want to add \'%1$s\' to contacts, block it, + or delete %2$s from call history\? + Do you want to delete %2$s from call history\? Disable Enable Do you want to delete call history of account \'%1$s\'\? @@ -308,7 +316,7 @@ Chat with %1$s New message Do you want to delete message or add peer \'%1$s\' to contacts\? - Do you want to delete message\? + Do you want to delete this message\? Add Contact Sending of message failed Failed @@ -317,8 +325,8 @@ Today You New Chat Peer - Do you want to delete chat with peer \'%1$s\' or - add peer to contacts\? + Do you want to add \'%1$s\' to contacts, block it, or + delete this chat? Do you want to delete chat with \'%1$s\'\? Do you want to delete chat history of account \'%1$s\'\? @@ -510,6 +518,7 @@ Deny Add Delete + Block Edit Copy URI Copied to clipboard