From ed8a7f573c8e177d73b02548b2dae947ee119b0d Mon Sep 17 00:00:00 2001 From: Asim Mughal Date: Tue, 16 Jul 2024 14:36:40 +0100 Subject: [PATCH] Version 12.1 - Version updater, search members by name --- app/src/main/AndroidManifest.xml | 1 - .../gym/ui/screens/members/MembersScreen.kt | 11 ++++- .../screens/members/MembersScreenViewModel.kt | 21 ++++++++- .../garden/gym/ui/widgets/EditTextWidget.kt | 47 +++++++++++++++++++ app/src/main/res/values/strings.xml | 3 +- 5 files changed, 78 insertions(+), 5 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a06e598..0b531b1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,7 +9,6 @@ diff --git a/app/src/main/kotlin/com/ndemi/garden/gym/ui/screens/members/MembersScreen.kt b/app/src/main/kotlin/com/ndemi/garden/gym/ui/screens/members/MembersScreen.kt index 86683fa..af4bbe1 100644 --- a/app/src/main/kotlin/com/ndemi/garden/gym/ui/screens/members/MembersScreen.kt +++ b/app/src/main/kotlin/com/ndemi/garden/gym/ui/screens/members/MembersScreen.kt @@ -20,7 +20,7 @@ import androidx.compose.ui.text.style.TextAlign import com.ndemi.garden.gym.R import com.ndemi.garden.gym.ui.screens.members.MembersScreenViewModel.UiState import com.ndemi.garden.gym.ui.theme.padding_screen -import com.ndemi.garden.gym.ui.theme.padding_screen_tiny +import com.ndemi.garden.gym.ui.widgets.SearchTextWidget import com.ndemi.garden.gym.ui.widgets.TextRegular import com.ndemi.garden.gym.ui.widgets.ToolBarWidget import com.ndemi.garden.gym.ui.widgets.WarningWidget @@ -54,12 +54,19 @@ fun MembersScreen( onRefresh = { viewModel.getMembers() } ) { LazyColumn { + item { + SearchTextWidget( + textInput = viewModel.searchTerm, + hint = stringResource(R.string.txt_search_members), + onValueChanged = viewModel::onSearchTextChanged + ) + } item { if (members.value.isEmpty() && uiState.value !is UiState.Loading) { TextRegular( modifier = Modifier .fillMaxWidth() - .padding(padding_screen_tiny), + .padding(padding_screen), textAlign = TextAlign.Center, text = stringResource(R.string.txt_no_members) ) diff --git a/app/src/main/kotlin/com/ndemi/garden/gym/ui/screens/members/MembersScreenViewModel.kt b/app/src/main/kotlin/com/ndemi/garden/gym/ui/screens/members/MembersScreenViewModel.kt index ca71f50..272132d 100644 --- a/app/src/main/kotlin/com/ndemi/garden/gym/ui/screens/members/MembersScreenViewModel.kt +++ b/app/src/main/kotlin/com/ndemi/garden/gym/ui/screens/members/MembersScreenViewModel.kt @@ -28,8 +28,10 @@ class MembersScreenViewModel ( private val navigationService: NavigationService, ) : BaseViewModel(UiState.Loading) { + private val _membersUnfiltered: MutableList = mutableListOf() private val _members = MutableLiveData>(listOf()) val members: LiveData> = _members + var searchTerm: String = "" fun getMembers() { sendAction(Action.SetLoading) @@ -39,7 +41,9 @@ class MembersScreenViewModel ( is DomainResult.Error -> sendAction(Action.ShowDomainError(result.error, errorCodeConverter)) is DomainResult.Success -> { - _members.value = result.data + _membersUnfiltered.clear() + _membersUnfiltered.addAll(result.data) + filterResults() sendAction(Action.Success) } } @@ -89,6 +93,21 @@ class MembersScreenViewModel ( } } + fun onSearchTextChanged(searchTerm: String) { + this.searchTerm = searchTerm + filterResults() + } + + private fun filterResults() { + if (searchTerm.isNotEmpty()){ + _members.value = _membersUnfiltered.filter { + it.getFullName().lowercase().contains(searchTerm.lowercase()) + } + } else { + _members.value = _membersUnfiltered + } + } + @Immutable sealed interface UiState : BaseState { data object Loading : UiState diff --git a/app/src/main/kotlin/com/ndemi/garden/gym/ui/widgets/EditTextWidget.kt b/app/src/main/kotlin/com/ndemi/garden/gym/ui/widgets/EditTextWidget.kt index 50eef3a..ab2afb5 100644 --- a/app/src/main/kotlin/com/ndemi/garden/gym/ui/widgets/EditTextWidget.kt +++ b/app/src/main/kotlin/com/ndemi/garden/gym/ui/widgets/EditTextWidget.kt @@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Clear @@ -25,6 +26,7 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.VisualTransformation @@ -123,6 +125,49 @@ fun EditPasswordTextWidget( ) } +@Composable +fun SearchTextWidget( + textInput: String = "", + hint: String = "", + onValueChanged: (String) -> Unit = {}, +){ + val kc = LocalSoftwareKeyboardController.current + var text by remember { mutableStateOf(textInput) } + OutlinedTextField( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = padding_screen_small), + value = text, + singleLine = true, + onValueChange = { + text = it + onValueChanged(text) + }, + textStyle = AppTheme.textStyles.regular, + label = {Text(text = hint, style = AppTheme.textStyles.small) }, + trailingIcon = { + if (text.isNotEmpty()){ + Icon( + Icons.Default.Clear, + contentDescription = "Clear text", + modifier = Modifier.clickable { + text = "" + onValueChanged("") + kc?.hide() + } + ) + } + }, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text), + keyboardActions = KeyboardActions { + onValueChanged.invoke(text) + kc?.hide() + }, + colors = getAppTextColors(), + shape = RoundedCornerShape(border_radius) + ) +} + @Composable private fun getAppTextColors() = OutlinedTextFieldDefaults.colors( focusedTextColor = AppTheme.colors.textPrimary, @@ -165,6 +210,8 @@ fun EditTextPreviewsNight(){ EditTextWidget(textInput = "Normal") EditTextWidget(textInput = "Error", isError = true) EditTextWidget(textInput = "Disabled", isEnabled = false) + + SearchTextWidget(textInput = "Disabled") } } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 95ca42f..24ee8f6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -25,6 +25,7 @@ Amount entered is invalid, set any number above 0 The month duration is invalid, set any number above 0 The phone number is invalid, leave blank if not present + Failed to open link, please try again later OK @@ -113,7 +114,7 @@ App update required Looks like you are using an outdated version of the app, please tap the download button below to get redirected to the latest version Download - Failed to open link, please try again later + Search members