From 5680624cc9a3b15e46b73f7b977722bab31103a5 Mon Sep 17 00:00:00 2001 From: Juha Heinanen Date: Mon, 5 Jan 2026 04:25:30 +0200 Subject: [PATCH] Started to add search to contacts screen --- .../kotlin/com/tutpro/baresip/ChatsScreen.kt | 4 +- .../com/tutpro/baresip/ContactsScreen.kt | 91 +++++++++++++++---- app/src/main/res/values/strings.xml | 1 + 3 files changed, 77 insertions(+), 19 deletions(-) diff --git a/app/src/main/kotlin/com/tutpro/baresip/ChatsScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/ChatsScreen.kt index 3ea151ca..0f0531af 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/ChatsScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/ChatsScreen.kt @@ -566,9 +566,7 @@ private fun NewChatPeer(ctx: Context, navController: NavController, account: Acc } } }, - modifier = Modifier - .padding(end = 6.dp) - .fillMaxWidth(), + modifier = Modifier.padding(end = 6.dp).fillMaxWidth(), singleLine = true, trailingIcon = { if (newPeer.isNotEmpty()) diff --git a/app/src/main/kotlin/com/tutpro/baresip/ContactsScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/ContactsScreen.kt index cafb31f0..25e55202 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/ContactsScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/ContactsScreen.kt @@ -6,40 +6,50 @@ import android.provider.ContactsContract import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Image import androidx.compose.foundation.background +import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.asPaddingValues 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.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.statusBars +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Edit +import androidx.compose.material.icons.filled.Search +import androidx.compose.material.icons.outlined.Clear import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Scaffold import androidx.compose.material3.SmallFloatingActionButton import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -47,14 +57,18 @@ import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable import coil.compose.AsyncImage +import com.tutpro.baresip.BaresipService.Companion.contactNames import com.tutpro.baresip.CustomElements.AlertDialog import com.tutpro.baresip.CustomElements.TextAvatar import com.tutpro.baresip.CustomElements.verticalScrollbar @@ -74,7 +88,10 @@ fun NavGraphBuilder.contactsScreenRoute( @OptIn(ExperimentalMaterial3Api::class) @Composable -private fun ContactsScreen(navController: NavController, viewModel: ViewModel) { +private fun ContactsScreen( + navController: NavController, + viewModel: ViewModel +) { val ctx = LocalContext.current @@ -116,25 +133,67 @@ private fun ContactsScreen(navController: NavController, viewModel: ViewModel) { ) } }, - floatingActionButton = { - SmallFloatingActionButton( - modifier = Modifier.offset(x = 2.dp), - onClick = { navController.navigate("baresip_contact//new") }, - containerColor = MaterialTheme.colorScheme.secondary, - contentColor = MaterialTheme.colorScheme.onSecondary - ) { - Icon(imageVector = Icons.Filled.Add, - modifier = Modifier.size(36.dp), - contentDescription = stringResource(R.string.add) - ) - } - }, + bottomBar = { BottomBar(navController) }, content = { contentPadding -> ContactsContent(ctx, viewModel, navController, contentPadding) } ) } +@Composable +private fun BottomBar(navController: NavController) { + var contactName by remember { mutableStateOf("") } + Row( + modifier = Modifier + .fillMaxWidth() + .navigationBarsPadding() + .padding(start = 16.dp, end = 12.dp, bottom = 16.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(10.dp) + ) { + OutlinedTextField( + value = contactName, + placeholder = { Text(stringResource(R.string.search)) }, + onValueChange = { + contactName = it + if (contactName.isNotEmpty()) { + // Show in ContactsContent LazyColumn contacts whose name starts with contactName + } + }, + modifier = Modifier.weight(1f), + singleLine = true, + trailingIcon = { + if (contactName.isNotEmpty()) + Icon( + Icons.Outlined.Clear, + contentDescription = null, + modifier = Modifier.clickable { + contactName = "" + }, + tint = MaterialTheme.colorScheme.onSurfaceVariant + ) + }, + label = { Icon(Icons.Default.Search, contentDescription = "") }, + textStyle = TextStyle(fontSize = 18.sp), + keyboardOptions = KeyboardOptions( + keyboardType = KeyboardType.Text, + imeAction = ImeAction.Done + ) + ) + SmallFloatingActionButton( + onClick = { navController.navigate("baresip_contact//new") }, + containerColor = MaterialTheme.colorScheme.secondary, + contentColor = MaterialTheme.colorScheme.onSecondary + ) { + Icon( + imageVector = Icons.Filled.Add, + modifier = Modifier.size(36.dp), + contentDescription = stringResource(R.string.add) + ) + } + } +} + @OptIn(ExperimentalFoundationApi::class) @Composable private fun ContactsContent( @@ -169,7 +228,7 @@ private fun ContactsContent( .fillMaxWidth() .background(MaterialTheme.colorScheme.background) .padding(contentPadding) - .padding(start = 16.dp, end = 4.dp, top = 16.dp, bottom = 64.dp) + .padding(start = 16.dp, end = 4.dp, top = 16.dp, bottom = 10.dp) .verticalScrollbar( state = lazyListState, width = 4.dp, @@ -336,4 +395,4 @@ private fun ContactsContent( } } } -} \ No newline at end of file +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 06dec69e..4d13414d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -456,6 +456,7 @@ Do you want to call or send message to \'%1$s\'\? Send Message Do you want to delete contact \'%1$s\'\? + Search Alert Info