diff --git a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt index ceaf0fc4..811122f7 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt @@ -853,9 +853,12 @@ class BaresipService: Service() { val peerUri = ev[1] val bevent = ev[2].toLong() val blockUnknown = ua.account.blockUnknown && Contact.contactName(peerUri) == peerUri - val toastMsg = if (Call.inCall() || blockUnknown) + val toastMsg = if (Call.inCall()) String.format(getString(R.string.call_auto_rejected), Utils.friendlyUri(this, peerUri, ua.account)) + else if (blockUnknown) + 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 if (!requestAudioFocus(applicationContext)) @@ -868,13 +871,15 @@ class BaresipService: Service() { Api.sip_treply(callp, 486, "Busy Here") Api.bevent_stop(bevent) toast(toastMsg) - if (blockUnknown) - Blocked( - ua.account.aor, - peerUri, - "invite", - GregorianCalendar().timeInMillis - ).add() + if (blockUnknown) { + if (ua.account.callHistory) + Blocked( + ua.account.aor, + peerUri, + "invite", + GregorianCalendar().timeInMillis + ).add() + } else { val name = "callwaiting_$toneCountry" val resourceId = applicationContext.resources.getIdentifier( @@ -1222,8 +1227,14 @@ class BaresipService: Service() { if (ua.account.blockUnknown && Contact.contactName(peerUri) == peerUri) { Log.d(TAG, "Auto-rejecting incoming message by $uap from $peerUri") + Blocked( + ua.account.aor, + peerUri, + "message", + GregorianCalendar().timeInMillis + ).add() toast(String.format( - getString(R.string.message_auto_rejected), + getString(R.string.message_blocked), Utils.friendlyUri(this, peerUri, ua.account) ) ) diff --git a/app/src/main/kotlin/com/tutpro/baresip/Blocked.kt b/app/src/main/kotlin/com/tutpro/baresip/Blocked.kt index 1d3ddc80..1f5b3e56 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Blocked.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Blocked.kt @@ -12,11 +12,13 @@ class Blocked ( val request: String, val timeStamp: Long ) { - private val blockedSize = 3 + private val blockedSize = 128 fun add() { BaresipService.blocked.add(this) - val aorBlocked = BaresipService.blocked.filter { it.aor == this.aor } + val aorBlocked = BaresipService.blocked.filter { + it.aor == this.aor && it.request == this.request + } if (aorBlocked.size > blockedSize) { val oldestToRemove = aorBlocked.first() BaresipService.blocked.remove(oldestToRemove) @@ -53,7 +55,7 @@ class Blocked ( BaresipService.blocked = ArrayList(blockedList) Log.d(TAG, "Restored ${BaresipService.blocked.size} blocked calls and messages") } catch (e: Exception) { - Log.e(TAG, "Deserialization exception: - $e") + Log.e(TAG, "Deserialization exception: $e") } } } diff --git a/app/src/main/kotlin/com/tutpro/baresip/BlockedScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/BlockedScreen.kt index 89c803bf..c691d768 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/BlockedScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/BlockedScreen.kt @@ -63,17 +63,21 @@ import java.util.GregorianCalendar fun NavGraphBuilder.blockedScreenRoute(navController: NavController) { composable( - route = "blocked/{aor}", - arguments = listOf(navArgument("aor") { type = NavType.StringType }) + route = "blocked/{request}/{aor}", + arguments = listOf( + navArgument("aor") { type = NavType.StringType }, + navArgument("request") { type = NavType.StringType } + ) ) { backStackEntry -> val aor = backStackEntry.arguments?.getString("aor")!! - BlockedScreen(navController, aor) + val request = backStackEntry.arguments?.getString("request")!! + BlockedScreen(navController, request, aor) } } @OptIn(ExperimentalMaterial3Api::class) @Composable -private fun BlockedScreen(navController: NavController, aor: String) { +private fun BlockedScreen(navController: NavController, request: String, aor: String) { val account = Account.ofAor(aor)!! @@ -84,7 +88,7 @@ private fun BlockedScreen(navController: NavController, aor: String) { val lifecycleOwner = LocalLifecycleOwner.current LaunchedEffect(aor, refreshTrigger) { - blocked.value = loadBlocked(aor) + blocked.value = loadBlocked(request, aor) isBlockedLoaded = true } @@ -100,7 +104,7 @@ private fun BlockedScreen(navController: NavController, aor: String) { } BackHandler(enabled = true) { - navController.popBackStack() + navController.navigateUp() } Scaffold( @@ -115,7 +119,7 @@ private fun BlockedScreen(navController: NavController, aor: String) { .background(MaterialTheme.colorScheme.background) .padding(top = WindowInsets.statusBars.asPaddingValues().calculateTopPadding()) ) { - TopAppBar(navController, account) + TopAppBar(navController, account, request, blocked) } }, content = { contentPadding -> @@ -124,8 +128,7 @@ private fun BlockedScreen(navController: NavController, aor: String) { LocalContext.current, navController, contentPadding, - account, - blocked + account, blocked ) }, ) @@ -133,12 +136,14 @@ private fun BlockedScreen(navController: NavController, aor: String) { @OptIn(ExperimentalMaterial3Api::class) @Composable -private fun TopAppBar(navController: NavController, account: Account) { - +private fun TopAppBar( + navController: NavController, + account: Account, + request: String, + blocked: MutableState> +) { var expanded by remember { mutableStateOf(false) } - val delete = stringResource(R.string.delete) - val showDialog = remember { mutableStateOf(false) } val positiveAction = remember { mutableStateOf({}) } @@ -154,7 +159,10 @@ private fun TopAppBar(navController: NavController, account: Account) { TopAppBar( title = { Text( - text = stringResource(R.string.blocked_calls), + text = if (request == "invite") + stringResource(R.string.blocked_calls) + else + stringResource(R.string.blocked_messages), fontWeight = FontWeight.Bold ) }, @@ -196,6 +204,7 @@ private fun TopAppBar(navController: NavController, account: Account) { delete -> { positiveAction.value = { Blocked.clear(account.aor) + blocked.value = emptyList() } showDialog.value = true } @@ -241,8 +250,7 @@ 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, blocked: MutableState>) { val showDialog = remember { mutableStateOf(false) } val message = remember { mutableStateOf("") } val positiveButtonText = remember { mutableStateOf("") } @@ -290,8 +298,11 @@ private fun Blocked(ctx: Context, navController: NavController, blocked: Mutable showDialog.value = true }) ) { - Text(text = peerUri, - modifier = Modifier.padding(start = 8.dp), + Text(text = "\u2022", + modifier = Modifier.padding(start = 8.dp, end = 4.dp), + fontSize = 18.sp) + + Text(text = peerUri.replace("sip:", ""), fontSize = 18.sp, maxLines = 1, overflow = TextOverflow.Ellipsis @@ -315,14 +326,14 @@ private fun Blocked(ctx: Context, navController: NavController, blocked: Mutable } } -private fun loadBlocked(aor: String): MutableList { +private fun loadBlocked(request: String, aor: String): MutableList { val res = mutableListOf() for (i in BaresipService.blocked.indices.reversed()) { val b = BaresipService.blocked[i] - if (b.aor == aor && b.request == "invite") { + if (b.aor == aor && b.request == request) { res.add(Blocked("", b.peerUri, "", b.timeStamp)) } } - Log.d(TAG, "Loaded ${res.size} blocked calls") + Log.d(TAG, "Loaded ${res.size} blocked $request requests") return res } diff --git a/app/src/main/kotlin/com/tutpro/baresip/CallsScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/CallsScreen.kt index e535dcc3..81ca6ac2 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/CallsScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/CallsScreen.kt @@ -208,7 +208,7 @@ private fun TopAppBar(navController: NavController, account: Account, callHistor CustomElements.DropdownMenu( expanded, { expanded = false }, - if (account.callHistory) listOf(delete, disable, blocked) else listOf(enable), + if (account.callHistory) listOf(disable, delete, blocked) else listOf(enable), onItemClick = { selectedItem -> expanded = false when (selectedItem) { @@ -216,6 +216,7 @@ private fun TopAppBar(navController: NavController, account: Account, callHistor positiveAction.value = { CallHistoryNew.clear(account.aor) callHistory.value = emptyList() + Blocked.clear(account.aor) } showDialog.value = true } @@ -224,7 +225,7 @@ private fun TopAppBar(navController: NavController, account: Account, callHistor Account.saveAccounts() } blocked -> { - navController.navigate("blocked/${account.aor}") + navController.navigate("blocked/invite/${account.aor}") } } } diff --git a/app/src/main/kotlin/com/tutpro/baresip/ChatsScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/ChatsScreen.kt index a1f425fa..3ea151ca 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/ChatsScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/ChatsScreen.kt @@ -163,6 +163,7 @@ private fun TopAppBar( var menuExpanded by remember { mutableStateOf(false) } val delete = stringResource(R.string.delete) + val blocked = stringResource(R.string.blocked) val showDialog = remember { mutableStateOf(false) } val positiveAction = remember { mutableStateOf({}) } @@ -176,12 +177,7 @@ private fun TopAppBar( ) TopAppBar( - title = { - Text( - text = stringResource(R.string.chats), - fontWeight = FontWeight.Bold - ) - }, + title = { Text(text = stringResource(R.string.chats), fontWeight = FontWeight.Bold) }, colors = TopAppBarDefaults.topAppBarColors( containerColor = MaterialTheme.colorScheme.primary, navigationIconContentColor = MaterialTheme.colorScheme.onPrimary, @@ -189,7 +185,7 @@ private fun TopAppBar( actionIconContentColor = MaterialTheme.colorScheme.onPrimary ), navigationIcon = { - IconButton(onClick = { navController.popBackStack() }) { + IconButton(onClick = { navController.navigateUp() }) { Icon( imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null, @@ -209,7 +205,7 @@ private fun TopAppBar( DropdownMenu ( expanded = menuExpanded, onDismissRequest = { menuExpanded = false }, - items = listOf(delete), + items = listOf(delete, blocked), onItemClick = { selectedItem -> menuExpanded = false when (selectedItem) { @@ -222,6 +218,9 @@ private fun TopAppBar( } showDialog.value = true } + blocked -> { + navController.navigate("blocked/message/${account.aor}") + } } } ) diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 67d43156..6bd2f06f 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -266,6 +266,14 @@ %1$d vastaamatonta puhelua Puhelun siirtopyyntö kohteeseen Automaattisesti hylätty puhelu soittajalta \`%1$s\` + Estetty puhelu hylätty soittajalta \`%1$s\` + Estetty viesti hylätty lähettäjältä \`%1$s\` + + Estetyt + Estetyt puhelut + Estetyt viestit + Haluatko poistaa tilin \'%1$s\' estetyt pyynnöt\? + Haluatko lisätä osoitteen \'%1$s\' yhteystietoihin\? Puheluhistoria Soita diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8c20db73..06dec69e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -254,7 +254,14 @@ %1$d missed calls Call transfer request to Auto-rejected call from \`%1$s\` - Auto-rejected message from \`%1$s\` + Auto-rejected blocked call from \`%1$s\` + Auto-rejected blocked message from \`%1$s\` + + Blocked + Blocked Calls + Blocked Messages + Do you want to delete blocked requests of \'%1$s\'\? + Do you want to add peer \'%1$s\' to contacts\? Call History Call Details @@ -281,11 +288,6 @@ Do you want to save this recording? Recording saved Do you want to delete this call from history? - - Blocked - Blocked Calls - Do you want to delete blocked calls of \'%1$s\'\? - Do you want to add peer \'%1$s\' to contacts\? Chat with %1$s New message