From 2cc685bd680b7c254ec42e106387967604a2a46a Mon Sep 17 00:00:00 2001 From: sssuhha Date: Fri, 23 Jan 2026 00:12:56 +0900 Subject: [PATCH 1/3] =?UTF-8?q?[FIX/#145]=20=EA=B2=80=EC=83=89=20=EC=95=84?= =?UTF-8?q?=EC=9D=B4=EC=BD=98=20=ED=81=B4=EB=A6=AD=20=EC=8B=9C=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=EB=8F=99=EC=9E=91=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../calendar/component/ProcedureSearchTextField.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/cherrish/android/presentation/calendar/component/ProcedureSearchTextField.kt b/app/src/main/java/com/cherrish/android/presentation/calendar/component/ProcedureSearchTextField.kt index 72edebf8..0e362eec 100644 --- a/app/src/main/java/com/cherrish/android/presentation/calendar/component/ProcedureSearchTextField.kt +++ b/app/src/main/java/com/cherrish/android/presentation/calendar/component/ProcedureSearchTextField.kt @@ -25,6 +25,7 @@ import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.cherrish.android.R +import com.cherrish.android.core.common.extension.noRippleClickable import com.cherrish.android.core.designsystem.theme.CherrishTheme @Composable @@ -78,7 +79,12 @@ fun ProcedureTextField( imageVector = ImageVector.vectorResource(id = R.drawable.ic_search), contentDescription = null, tint = CherrishTheme.colors.gray500, - modifier = Modifier.align(Alignment.CenterEnd) + modifier = Modifier + .align(Alignment.CenterEnd) + .noRippleClickable { + onSearchAction() + keyboardController?.hide() + } ) } } From dee1cfe1f2ca09b3efb9b13c8f0ed8bdc6a0c06c Mon Sep 17 00:00:00 2001 From: sssuhha Date: Fri, 23 Jan 2026 00:30:34 +0900 Subject: [PATCH 2/3] =?UTF-8?q?[FIX/#145]=20=EB=AA=A9=ED=91=9C=20=EB=94=94?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=20=EC=9E=85=EB=A0=A5=20=ED=95=84=EB=93=9C=20?= =?UTF-8?q?=EC=99=B8=EB=B6=80=20=ED=84=B0=EC=B9=98=20=EC=8B=9C=20=ED=8F=AC?= =?UTF-8?q?=EC=BB=A4=20=EB=B0=8F=20=ED=82=A4=EB=B3=B4=EB=93=9C=20=ED=95=B4?= =?UTF-8?q?=EC=A0=9C=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/RecoveryScheduleContent.kt | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/content/RecoveryScheduleContent.kt b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/content/RecoveryScheduleContent.kt index ff85a102..0ceecf3f 100644 --- a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/content/RecoveryScheduleContent.kt +++ b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/content/RecoveryScheduleContent.kt @@ -19,7 +19,11 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment.Companion.CenterVertically import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusDirection +import androidx.compose.ui.input.pointer.PointerEventPass +import androidx.compose.ui.input.pointer.changedToUp +import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.style.TextAlign @@ -45,8 +49,23 @@ fun RecoveryScheduleContent( ) { val hasSelection = selectedIndex != null && selectedIndex >= 0 val focusManager = LocalFocusManager.current - - Column(modifier = modifier) { + val keyboardController = LocalSoftwareKeyboardController.current + + Column( + modifier = modifier.pointerInput(focusManager) { + awaitPointerEventScope { + while (true) { + val event = awaitPointerEvent(PointerEventPass.Final) + val isTapUp = event.changes.any { it.changedToUp() } + val isConsumed = event.changes.any { it.isConsumed } + if (isTapUp && !isConsumed) { + focusManager.clearFocus() + keyboardController?.hide() + } + } + } + } + ) { SelectionSection( title = "회복을 계획할 때 고려해야 할\n중요한 일정이 있나요?", items = persistentListOf("아직 없어요", "네, 있어요"), From 4044e44cd516434854474e9b84cb1903e882049f Mon Sep 17 00:00:00 2001 From: sssuhha Date: Fri, 23 Jan 2026 00:42:47 +0900 Subject: [PATCH 3/3] =?UTF-8?q?[FIX/#145]=20=EC=B4=88=EC=84=B1=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=EC=8B=9C=20empty=20view=20=EB=82=98=EC=98=A4?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../calendar/procedure/ProcedureScreen.kt | 1 + .../calendar/procedure/ProcedureUiState.kt | 1 + .../calendar/procedure/ProcedureViewModel.kt | 22 +++++++++++++++++-- .../content/FilteringWithSearchContent.kt | 18 +++++++++++++-- 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureScreen.kt b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureScreen.kt index 506d37d3..2a6911c5 100644 --- a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureScreen.kt +++ b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureScreen.kt @@ -231,6 +231,7 @@ fun ProcedureScreen( onCardClick = onProcedureCardClick, onSearchAction = onSearchAction, query = uiState.searchQuery, + searchedQuery = uiState.searchedQuery, onQueryChange = onSearchableQueryChange, bottomContentPadding = uiState.lazyColumnBottomPadding, modifier = Modifier diff --git a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureUiState.kt b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureUiState.kt index 9c267884..33c4e8df 100644 --- a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureUiState.kt +++ b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureUiState.kt @@ -43,6 +43,7 @@ data class ProcedureUiState( val selectedWorryName: String = "", val searchQuery: String = "", + val searchedQuery: String = "", val showDowntimeBottomSheet: Boolean = false, val selectedProcedureForDowntime: ProcedureCardItemUiModel? = null, diff --git a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureViewModel.kt b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureViewModel.kt index 15c3cc22..65990365 100644 --- a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureViewModel.kt +++ b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureViewModel.kt @@ -121,6 +121,7 @@ class ProcedureViewModel @Inject constructor( fun onSearchAction(query: String) { val current = currentStateOrNull() ?: return val keyword = query.trim().takeIf { it.isNotEmpty() } + _uiState.updateSuccess { it.copy(searchedQuery = query.trim()) } fetchProcedures( keyword = keyword, worryId = current.selectedWorryId, @@ -433,7 +434,22 @@ class ProcedureViewModel @Inject constructor( viewModelScope.launch { procedureRepository.getProcedures(keyword = keyword, worryId = worryId) .onSuccess { response -> - val items = response.procedures + val normalizedKeyword = keyword?.trim().takeIf { !it.isNullOrEmpty() } + val filteredProcedures = if (normalizedKeyword == null) { + response.procedures + } else { + response.procedures.filter { procedure -> + procedure.name.contains(normalizedKeyword, ignoreCase = true) || + ( + procedure.category?.contains( + normalizedKeyword, + ignoreCase = true + ) == true + ) + } + } + + val items = filteredProcedures .map { it.toUiModel() } .toPersistentList() @@ -511,7 +527,9 @@ private fun ProcedureUiState.toEntryState(): ProcedureUiState { selectedDowntime = null, selectedProcedureCardIds = persistentListOf(), selectedProcedureItems = persistentListOf(), - procedureDowntimeMap = emptyMap() + procedureDowntimeMap = emptyMap(), + searchQuery = "", + searchedQuery = "" ) } diff --git a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/content/FilteringWithSearchContent.kt b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/content/FilteringWithSearchContent.kt index 13bb0131..287202cf 100644 --- a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/content/FilteringWithSearchContent.kt +++ b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/content/FilteringWithSearchContent.kt @@ -33,6 +33,7 @@ import com.cherrish.android.presentation.calendar.procedure.model.ProcedureCardD import com.cherrish.android.presentation.calendar.procedure.model.ProcedureCardItemUiModel import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toPersistentList /* TODO: 삭제 예정 */ private val mockProcedureCardItems = persistentListOf( @@ -101,10 +102,21 @@ fun FilteringWithSearchContent( onCardClick: (Long) -> Unit, onSearchAction: (String) -> Unit, query: String, + searchedQuery: String, onQueryChange: (String) -> Unit, bottomContentPadding: Dp, modifier: Modifier = Modifier ) { + val normalizedQuery = searchedQuery.trim() + val filteredItems = if (normalizedQuery.isEmpty()) { + cardItems + } else { + cardItems.filter { item -> + item.name.contains(normalizedQuery, ignoreCase = true) || + item.category.contains(normalizedQuery, ignoreCase = true) + }.toPersistentList() + } + Column( modifier = modifier.fillMaxWidth() ) { @@ -128,7 +140,7 @@ fun FilteringWithSearchContent( Spacer(modifier = Modifier.height(10.dp)) } - if (cardItems.isEmpty()) { + if (filteredItems.isEmpty()) { item { EmptySearchResult( modifier = Modifier.fillParentMaxSize() @@ -136,7 +148,7 @@ fun FilteringWithSearchContent( } } else { items( - items = cardItems, + items = filteredItems, key = { it.id } ) { item -> ProcedureCard( @@ -202,6 +214,7 @@ private fun FilteringWithSearchContentPreview() { }, onSearchAction = {}, query = query, + searchedQuery = "", bottomContentPadding = 20.dp, onQueryChange = { query = it } ) @@ -218,6 +231,7 @@ private fun FilteringWithSearchContentEmptyPreview() { onCardClick = {}, onSearchAction = {}, query = "레이저 토닝", + searchedQuery = "레이저 토닝", bottomContentPadding = 20.dp, onQueryChange = {} )