From 4baa0b3cd1d8b1bbaf2563b88d9f05cad8c26355 Mon Sep 17 00:00:00 2001 From: somin Date: Thu, 15 Feb 2024 23:03:57 +0900 Subject: [PATCH 01/10] =?UTF-8?q?layout=20:=20=ED=98=84=EC=9E=AC=20?= =?UTF-8?q?=ED=82=A4=EC=9B=8C=EB=93=9C=EB=A1=9C=20=EC=9E=AC=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=EB=B2=84=ED=8A=BC=20layout=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/presentation/ui/MainScreen.kt | 65 +++++++-- .../presentation/ui/map/NaverMapScreen.kt | 14 +- .../ui/search/ReSearchComponent.kt | 127 ++++++++++++++++++ presentation/src/main/res/values/strings.xml | 1 + 4 files changed, 193 insertions(+), 14 deletions(-) create mode 100644 presentation/src/main/java/com/example/presentation/ui/search/ReSearchComponent.kt diff --git a/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt b/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt index 4e1c14a..0220074 100644 --- a/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt +++ b/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt @@ -1,6 +1,7 @@ package com.example.presentation.ui import android.app.Activity +import android.util.Log import android.widget.Toast import androidx.activity.compose.BackHandler import androidx.compose.runtime.Composable @@ -26,8 +27,10 @@ import com.example.presentation.ui.map.list.StoreListBottomSheet import com.example.presentation.ui.map.reload.ReloadOrShowMoreButton import com.example.presentation.ui.map.summary.DimScreen import com.example.presentation.ui.map.summary.StoreSummaryBottomSheet +import com.example.presentation.ui.search.ReSearchComponent import com.example.presentation.ui.search.StoreSearchComponent import com.example.presentation.util.MainConstants +import com.example.presentation.util.MainConstants.SEARCH_KEY import com.example.presentation.util.MainConstants.UN_MARKER import com.example.presentation.util.MapScreenType import com.naver.maps.map.compose.ExperimentalNaverMapApi @@ -109,6 +112,8 @@ fun MainScreen( val (isLoading, onLoadingChanged) = remember { mutableStateOf(false) } + val (isFilteredMarker, onFilteredMarkerChanged) = remember { mutableStateOf(false) } + val (errorToastMsg, onErrorToastChanged) = remember { mutableStateOf("") } val (isListItemClicked, onListItemChanged) = remember { mutableStateOf(false) } @@ -117,6 +122,8 @@ fun MainScreen( val (isReloadOrShowMoreShowAble, onReloadOrShowMoreChanged) = remember { mutableStateOf(false) } + val (isReSearchButtonClicked, onReSearchButtonChanged) = remember { mutableStateOf(false) } + val (isScreenCoordinateChanged, onGetNewScreenCoordinateChanged) = remember { mutableStateOf( false @@ -161,22 +168,40 @@ fun MainScreen( isBackPressed, onBackPressedChanged, mapViewModel, - navController + navController, + isFilteredMarker, + onFilteredMarkerChanged, + isReSearchButtonClicked ) if (isReloadOrShowMoreShowAble) { - ReloadOrShowMoreButton( - isMarkerClicked, - currentSummaryInfoHeight, - isMapGestured, - onShowMoreCountChanged, - onReloadButtonChanged, - onMarkerChanged, - onBottomSheetChanged, - isLoading, - showMoreCount, - mapViewModel - ) + val searchText = navController.previousBackStackEntry?.savedStateHandle?.contains( + SEARCH_KEY + ) ?: false + if (searchText) { + ReSearchComponent( + isMarkerClicked, + currentSummaryInfoHeight, + isMapGestured, + onReSearchButtonChanged, + onMarkerChanged, + onBottomSheetChanged, + isLoading, + ) + } else { + ReloadOrShowMoreButton( + isMarkerClicked, + currentSummaryInfoHeight, + isMapGestured, + onShowMoreCountChanged, + onReloadButtonChanged, + onMarkerChanged, + onBottomSheetChanged, + isLoading, + showMoreCount, + mapViewModel + ) + } } StoreSearchComponent( @@ -238,9 +263,23 @@ fun MainScreen( onCallDialogChanged(false) } + val mapCenterCoordinate by mapViewModel.mapCenterCoordinate.collectAsStateWithLifecycle() + if (isReSearchButtonClicked && isScreenCoordinateChanged) { + Log.d("테스트", "키워드 재검색 눌리고있음?") + mapViewModel.updateIsFilteredMarker(false) + mapViewModel.searchStore( + mapCenterCoordinate.longitude, + mapCenterCoordinate.latitude, + searchText ?: "" + ) + onReSearchButtonChanged(false) + onGetNewScreenCoordinateChanged(false) + } + if ((isReloadButtonClicked && isScreenCoordinateChanged)) { mapViewModel.updateIsFilteredMarker(false) onErrorToastChanged("") + onFilteredMarkerChanged(false) mapViewModel.getStoreDetail( nwLong = screenCoordinate.northWest.longitude, nwLat = screenCoordinate.northWest.latitude, diff --git a/presentation/src/main/java/com/example/presentation/ui/map/NaverMapScreen.kt b/presentation/src/main/java/com/example/presentation/ui/map/NaverMapScreen.kt index c409a2b..5ccbac9 100644 --- a/presentation/src/main/java/com/example/presentation/ui/map/NaverMapScreen.kt +++ b/presentation/src/main/java/com/example/presentation/ui/map/NaverMapScreen.kt @@ -91,7 +91,10 @@ fun NaverMapScreen( isBackPressed: Boolean, onBackPressedChanged: (Boolean) -> Unit, mapViewModel: MapViewModel, - navController: NavHostController + navController: NavHostController, + isFilteredMarker: Boolean, + onFilteredMarkerChanged: (Boolean) -> Unit, + isReSearchButtonClicked: Boolean ) { val cameraPositionState = rememberCameraPositionState {} @@ -248,6 +251,15 @@ fun NaverMapScreen( onLocationButtonChanged(LocationTrackingButton.NO_FOLLOW) } } + if (isReSearchButtonClicked) { + mapViewModel.updateMapCenterCoordinate( + Coordinate( + cameraPositionState.position.target.latitude, + cameraPositionState.position.target.longitude + ) + ) + onGetNewScreenCoordinateChanged(true) + } if (isReloadButtonClicked) { GetScreenCoordinate(cameraPositionState, onScreenChanged) onGetNewScreenCoordinateChanged(true) diff --git a/presentation/src/main/java/com/example/presentation/ui/search/ReSearchComponent.kt b/presentation/src/main/java/com/example/presentation/ui/search/ReSearchComponent.kt new file mode 100644 index 0000000..4a1c5ea --- /dev/null +++ b/presentation/src/main/java/com/example/presentation/ui/search/ReSearchComponent.kt @@ -0,0 +1,127 @@ +package com.example.presentation.ui.search + +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.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.hilt.navigation.compose.hiltViewModel +import com.example.presentation.R +import com.example.presentation.ui.map.MapViewModel +import com.example.presentation.ui.map.reload.LoadingAnimation +import com.example.presentation.ui.map.reload.setReloadButtonBottomPadding +import com.example.presentation.ui.theme.Black +import com.example.presentation.ui.theme.Blue +import com.example.presentation.ui.theme.White +import com.example.presentation.util.MainConstants.UN_MARKER + +@Composable +fun ReSearchComponent( + isMarkerClicked: Boolean, + currentSummaryInfoHeight: Dp, + isMapGestured: Boolean, + onReSearchButtonChanged: (Boolean) -> Unit, + onMarkerChanged: (Long) -> Unit, + onBottomSheetChanged: (Boolean) -> Unit, + isLoading: Boolean, +) { + Column( + modifier = Modifier + .fillMaxHeight() + .fillMaxWidth() + .padding( + bottom = setReloadButtonBottomPadding( + isMarkerClicked, + currentSummaryInfoHeight + ) + ), + verticalArrangement = Arrangement.Bottom, + horizontalAlignment = Alignment.CenterHorizontally + ) { + if (isMapGestured) { + ReSearchButton( + onReSearchButtonChanged, + onMarkerChanged, + onBottomSheetChanged, + isLoading, + ) + } + } +} + + +@Composable +fun ReSearchButton( + onReSearchButtonChanged: (Boolean) -> Unit, + onMarkerChanged: (Long) -> Unit, + onBottomSheetChanged: (Boolean) -> Unit, + isLoading: Boolean, + viewModel: MapViewModel = hiltViewModel() +) { + Button( + onClick = { + onMarkerChanged(UN_MARKER) + onBottomSheetChanged(false) + onReSearchButtonChanged(true) + }, + modifier = Modifier + .size(width = 145.dp, height = 35.dp), + contentPadding = PaddingValues(horizontal = 0.dp, vertical = 0.dp), + colors = ButtonDefaults.buttonColors( + containerColor = White, + contentColor = Black + ), + shape = RoundedCornerShape(30.dp), + elevation = ButtonDefaults.buttonElevation(defaultElevation = 4.dp) + ) { + Row( + modifier = Modifier.align(Alignment.CenterVertically) + ) { + if (isLoading) { + LoadingAnimation() + } else { + ReSearchByKeyword() + } + } + } +} + +@Composable +private fun ReSearchByKeyword() { + Row( + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + imageVector = ImageVector.vectorResource(id = R.drawable.reload), + tint = Blue, + contentDescription = "ReSearch", + modifier = Modifier.size(13.dp) + ) + Spacer(modifier = Modifier.width(6.dp)) + Text( + text = stringResource(R.string.search_by_keyword_on_current_map), + fontSize = 11.sp, + fontWeight = FontWeight.Medium + ) + } +} \ No newline at end of file diff --git a/presentation/src/main/res/values/strings.xml b/presentation/src/main/res/values/strings.xml index 7cd01fc..1476884 100644 --- a/presentation/src/main/res/values/strings.xml +++ b/presentation/src/main/res/values/strings.xml @@ -11,6 +11,7 @@ 클립보드에 복사되었어요. tel:%s 현 지도에서 검색 + 현재 키워드로 재검색 영업 중 영업 종료 휴무일 From abd585860af2b585a25542b1bcc41d8b56740950 Mon Sep 17 00:00:00 2001 From: somin Date: Fri, 16 Feb 2024 00:14:03 +0900 Subject: [PATCH 02/10] =?UTF-8?q?chore=20:=20searchText=20=EC=9C=84?= =?UTF-8?q?=EC=B9=98=20MainScreen=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/presentation/ui/MainScreen.kt | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt b/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt index 0220074..de50679 100644 --- a/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt +++ b/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt @@ -139,6 +139,14 @@ fun MainScreen( } val (isBackPressed, onBackPressedChanged) = remember { mutableStateOf(false) } + val isSearchTextExist = navController.previousBackStackEntry?.savedStateHandle?.contains( + SEARCH_KEY + ) ?: false + + val searchText = navController.previousBackStackEntry?.savedStateHandle?.get( + SEARCH_KEY + ) + NaverMapScreen( isMarkerClicked, onBottomSheetChanged, @@ -175,10 +183,7 @@ fun MainScreen( ) if (isReloadOrShowMoreShowAble) { - val searchText = navController.previousBackStackEntry?.savedStateHandle?.contains( - SEARCH_KEY - ) ?: false - if (searchText) { + if (isSearchTextExist) { ReSearchComponent( isMarkerClicked, currentSummaryInfoHeight, From 60c8d53552e2f3bbd4c76dfd32c91ab3750bcb3e Mon Sep 17 00:00:00 2001 From: somin Date: Mon, 19 Feb 2024 10:10:09 +0900 Subject: [PATCH 03/10] =?UTF-8?q?feat=20:=20=EA=B2=80=EC=83=89=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A6=B0,=20=EB=A7=B5=20=EC=8A=A4=ED=81=AC=EB=A6=B0?= =?UTF-8?q?=20=EA=B0=84=20=EC=9D=B4=EB=8F=99=20=EC=8B=9C=20Filter=20?= =?UTF-8?q?=EC=B4=88=EA=B8=B0=ED=99=94=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/presentation/ui/MainScreen.kt | 20 +-------- .../presentation/ui/map/MapViewModel.kt | 4 ++ .../presentation/ui/map/NaverMapScreen.kt | 15 +++++-- .../ui/map/filter/FilterComponent.kt | 38 +++++++++-------- .../ui/map/filter/FilterViewModel.kt | 41 +++++++++++++++++++ .../presentation/ui/search/SearchScreen.kt | 5 +++ 6 files changed, 85 insertions(+), 38 deletions(-) create mode 100644 presentation/src/main/java/com/example/presentation/ui/map/filter/FilterViewModel.kt diff --git a/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt b/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt index de50679..1539576 100644 --- a/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt +++ b/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt @@ -1,7 +1,6 @@ package com.example.presentation.ui import android.app.Activity -import android.util.Log import android.widget.Toast import androidx.activity.compose.BackHandler import androidx.compose.runtime.Composable @@ -72,10 +71,6 @@ fun MainScreen( mutableStateOf(false) } - val (isKindFilterClicked, onKindFilterChanged) = remember { mutableStateOf(false) } - val (isGreatFilterClicked, onGreatFilterChanged) = remember { mutableStateOf(false) } - val (isSafeFilterClicked, onSafeFilterChanged) = remember { mutableStateOf(false) } - val (screenCoordinate, onScreenChanged) = remember { mutableStateOf( ScreenCoordinate( @@ -112,8 +107,6 @@ fun MainScreen( val (isLoading, onLoadingChanged) = remember { mutableStateOf(false) } - val (isFilteredMarker, onFilteredMarkerChanged) = remember { mutableStateOf(false) } - val (errorToastMsg, onErrorToastChanged) = remember { mutableStateOf("") } val (isListItemClicked, onListItemChanged) = remember { mutableStateOf(false) } @@ -177,8 +170,6 @@ fun MainScreen( onBackPressedChanged, mapViewModel, navController, - isFilteredMarker, - onFilteredMarkerChanged, isReSearchButtonClicked ) @@ -216,12 +207,6 @@ fun MainScreen( ) FilterComponent( - isKindFilterClicked, - onKindFilterChanged, - isGreatFilterClicked, - onGreatFilterChanged, - isSafeFilterClicked, - onSafeFilterChanged, mapViewModel, onFilterStateChanged ) @@ -270,7 +255,6 @@ fun MainScreen( val mapCenterCoordinate by mapViewModel.mapCenterCoordinate.collectAsStateWithLifecycle() if (isReSearchButtonClicked && isScreenCoordinateChanged) { - Log.d("테스트", "키워드 재검색 눌리고있음?") mapViewModel.updateIsFilteredMarker(false) mapViewModel.searchStore( mapCenterCoordinate.longitude, @@ -284,7 +268,6 @@ fun MainScreen( if ((isReloadButtonClicked && isScreenCoordinateChanged)) { mapViewModel.updateIsFilteredMarker(false) onErrorToastChanged("") - onFilteredMarkerChanged(false) mapViewModel.getStoreDetail( nwLong = screenCoordinate.northWest.longitude, nwLat = screenCoordinate.northWest.latitude, @@ -321,7 +304,7 @@ fun MainScreen( @Composable fun PressBack( mapViewModel: MapViewModel, - onBackPressedChanged: (Boolean) -> Unit + onBackPressedChanged: (Boolean) -> Unit, ) { val mapScreenType by mapViewModel.mapScreenType.collectAsStateWithLifecycle() val context = LocalContext.current @@ -329,6 +312,7 @@ fun PressBack( BackHandler { if (mapScreenType == MapScreenType.SEARCH) { + mapViewModel.updateIsSearchTerminated(true) onBackPressedChanged(true) mapViewModel.updateMapScreenType(MapScreenType.MAIN) } else { diff --git a/presentation/src/main/java/com/example/presentation/ui/map/MapViewModel.kt b/presentation/src/main/java/com/example/presentation/ui/map/MapViewModel.kt index 01a827d..e569731 100644 --- a/presentation/src/main/java/com/example/presentation/ui/map/MapViewModel.kt +++ b/presentation/src/main/java/com/example/presentation/ui/map/MapViewModel.kt @@ -110,6 +110,10 @@ class MapViewModel @Inject constructor( } } + fun initializeFilterSet() { + filterSet.clear() + } + fun setLocationTrackingMode(): LocationTrackingButton { return if (isLocationPermissionGranted.value) { LocationTrackingButton.FOLLOW diff --git a/presentation/src/main/java/com/example/presentation/ui/map/NaverMapScreen.kt b/presentation/src/main/java/com/example/presentation/ui/map/NaverMapScreen.kt index 5ccbac9..5dde879 100644 --- a/presentation/src/main/java/com/example/presentation/ui/map/NaverMapScreen.kt +++ b/presentation/src/main/java/com/example/presentation/ui/map/NaverMapScreen.kt @@ -18,6 +18,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavHostController import com.example.domain.model.map.ShowMoreCount @@ -28,6 +29,7 @@ import com.example.presentation.model.LocationTrackingButton import com.example.presentation.model.ScreenCoordinate import com.example.presentation.model.StoreDetail import com.example.presentation.model.StoreType +import com.example.presentation.ui.map.filter.FilterViewModel import com.example.presentation.ui.map.location.CurrentLocationComponent import com.example.presentation.ui.map.marker.StoreMarker import com.example.presentation.ui.map.reload.setReloadButtonBottomPadding @@ -92,9 +94,8 @@ fun NaverMapScreen( onBackPressedChanged: (Boolean) -> Unit, mapViewModel: MapViewModel, navController: NavHostController, - isFilteredMarker: Boolean, - onFilteredMarkerChanged: (Boolean) -> Unit, - isReSearchButtonClicked: Boolean + isReSearchButtonClicked: Boolean, + filterViewModel:FilterViewModel = hiltViewModel() ) { val cameraPositionState = rememberCameraPositionState {} @@ -225,6 +226,7 @@ fun NaverMapScreen( } val isFilteredMarker by mapViewModel.isFilteredMarker.collectAsStateWithLifecycle() + if (isFilteredMarker) { FilteredMarkers( mapViewModel, @@ -273,6 +275,8 @@ fun NaverMapScreen( ) mapViewModel.updateMapZoomLevel(cameraPositionState.position.zoom) navController.navigate(Screen.Search.route) + filterViewModel.updateAllFilterUnClicked() + mapViewModel.initializeFilterSet() onSearchComponentChanged(false) } if (isBackPressed) { @@ -508,7 +512,8 @@ private fun CheckSearchTerminationButtonClicked( onSearchTerminationButtonChanged: (Boolean) -> Unit, onReloadButtonChanged: (Boolean) -> Unit, mapCenterCoordinate: Coordinate, - mapZoomLevel: Double + mapZoomLevel: Double, + filterViewModel: FilterViewModel = hiltViewModel() ) { if (isSearchTerminationButtonClicked) { mapViewModel.updateMapCenterCoordinate( @@ -532,6 +537,8 @@ private fun CheckSearchTerminationButtonClicked( LaunchedEffect(key1 = isSearchTerminated) { if (isSearchTerminated) { + filterViewModel.updateAllFilterUnClicked() + mapViewModel.initializeFilterSet() movePrevCamera(cameraPositionState, mapCenterCoordinate, mapZoomLevel) onReloadButtonChanged(true) mapViewModel.updateIsSearchTerminated(false) diff --git a/presentation/src/main/java/com/example/presentation/ui/map/filter/FilterComponent.kt b/presentation/src/main/java/com/example/presentation/ui/map/filter/FilterComponent.kt index 3d813f1..32772e0 100644 --- a/presentation/src/main/java/com/example/presentation/ui/map/filter/FilterComponent.kt +++ b/presentation/src/main/java/com/example/presentation/ui/map/filter/FilterComponent.kt @@ -1,5 +1,6 @@ package com.example.presentation.ui.map.filter +import android.annotation.SuppressLint import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.PaddingValues @@ -27,6 +28,8 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.example.presentation.model.StoreType import com.example.presentation.ui.map.MapViewModel import com.example.presentation.ui.theme.Black @@ -36,43 +39,42 @@ import com.example.presentation.util.MainConstants.DEFAULT_MARGIN import com.example.presentation.util.MainConstants.SEARCH_TEXT_FIELD_HEIGHT import com.example.presentation.util.MainConstants.SEARCH_TEXT_FIELD_TOP_PADDING +@SuppressLint("StateFlowValueCalledInComposition") @Composable fun FilterComponent( - isKindFilterClicked: Boolean, - onKindFilterChanged: (Boolean) -> Unit, - isGreatFilterClicked: Boolean, - onGreatFilterChanged: (Boolean) -> Unit, - isSafeFilterClicked: Boolean, - onSafeFilterChanged: (Boolean) -> Unit, mapViewModel: MapViewModel, onFilterStateChanged: (Boolean) -> Unit, + filterViewModel: FilterViewModel = hiltViewModel() ) { Row( modifier = Modifier .fillMaxHeight() .fillMaxWidth() - .padding(top = (SEARCH_TEXT_FIELD_HEIGHT + SEARCH_TEXT_FIELD_TOP_PADDING + 8).dp, start = DEFAULT_MARGIN.dp), + .padding( + top = (SEARCH_TEXT_FIELD_HEIGHT + SEARCH_TEXT_FIELD_TOP_PADDING + 8).dp, + start = DEFAULT_MARGIN.dp + ), verticalAlignment = Alignment.Top ) { + val isKindClicked = filterViewModel.isKindFilterClicked.collectAsStateWithLifecycle() + val isGreatClicked = filterViewModel.isGreatFilterClicked.collectAsStateWithLifecycle() + val isSafeClicked = filterViewModel.isSafeFilterClicked.collectAsStateWithLifecycle() FilterButton( storeType = StoreType.KIND, - isKindFilterClicked, - onKindFilterChanged, + isKindClicked.value, mapViewModel, onFilterStateChanged ) FilterButton( storeType = StoreType.GREAT, - isGreatFilterClicked, - onGreatFilterChanged, + isGreatClicked.value, mapViewModel, onFilterStateChanged ) FilterButton( storeType = StoreType.SAFE, - isSafeFilterClicked, - onSafeFilterChanged, + isSafeClicked.value, mapViewModel, onFilterStateChanged ) @@ -84,16 +86,20 @@ fun FilterComponent( fun FilterButton( storeType: StoreType, isFilterClicked: Boolean, - onFilterChanged: (Boolean) -> Unit, mapViewModel: MapViewModel, - onFilterStateChanged: (Boolean) -> Unit + onFilterStateChanged: (Boolean) -> Unit, + filterViewModel: FilterViewModel = hiltViewModel(), ) { val certificationName = stringResource(id = storeType.storeTypeName).replace(" ", "") CompositionLocalProvider(LocalMinimumInteractiveComponentEnforcement provides false) { Button( onClick = { mapViewModel.updateFilterSet(certificationName, isFilterClicked.not()) - onFilterChanged(isFilterClicked.not()) + when (storeType) { + StoreType.KIND -> filterViewModel.updateKindFilterClicked() + StoreType.SAFE -> filterViewModel.updateSafeFilterClicked() + StoreType.GREAT -> filterViewModel.updateGreatFilterClicked() + } onFilterStateChanged(true) }, modifier = Modifier diff --git a/presentation/src/main/java/com/example/presentation/ui/map/filter/FilterViewModel.kt b/presentation/src/main/java/com/example/presentation/ui/map/filter/FilterViewModel.kt new file mode 100644 index 0000000..cbee111 --- /dev/null +++ b/presentation/src/main/java/com/example/presentation/ui/map/filter/FilterViewModel.kt @@ -0,0 +1,41 @@ +package com.example.presentation.ui.map.filter + +import android.util.Log +import androidx.lifecycle.ViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import javax.inject.Inject + + +@HiltViewModel +class FilterViewModel @Inject constructor() : ViewModel() { + + private val _isKindFilterClicked = MutableStateFlow(false) + val isKindFilterClicked: StateFlow get() = _isKindFilterClicked + + private val _isGreatFilterClicked = MutableStateFlow(false) + val isGreatFilterClicked: StateFlow get() = _isGreatFilterClicked + + private val _isSafeFilterClicked = MutableStateFlow(false) + val isSafeFilterClicked: StateFlow get() = _isSafeFilterClicked + + fun updateKindFilterClicked() { + _isKindFilterClicked.value = _isKindFilterClicked.value.not() + } + + fun updateGreatFilterClicked() { + _isGreatFilterClicked.value = _isGreatFilterClicked.value.not() + } + + fun updateSafeFilterClicked() { + _isSafeFilterClicked.value = _isSafeFilterClicked.value.not() + } + + fun updateAllFilterUnClicked() { + _isKindFilterClicked.value = false + _isGreatFilterClicked.value = false + _isSafeFilterClicked.value = false + Log.d("테스트","${_isKindFilterClicked.value}") + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/example/presentation/ui/search/SearchScreen.kt b/presentation/src/main/java/com/example/presentation/ui/search/SearchScreen.kt index 6202a54..c1db364 100644 --- a/presentation/src/main/java/com/example/presentation/ui/search/SearchScreen.kt +++ b/presentation/src/main/java/com/example/presentation/ui/search/SearchScreen.kt @@ -54,6 +54,7 @@ import com.example.domain.model.search.SearchWord import com.example.presentation.R import com.example.presentation.ui.component.EmptyScreen import com.example.presentation.ui.map.MapViewModel +import com.example.presentation.ui.map.filter.FilterViewModel import com.example.presentation.ui.navigation.Screen import com.example.presentation.ui.theme.Black import com.example.presentation.ui.theme.DarkGray @@ -132,6 +133,7 @@ fun SearchTextField( navController: NavHostController, mapViewModel: MapViewModel, searchViewModel: SearchViewModel = hiltViewModel(), + filterViewModel: FilterViewModel = hiltViewModel() ) { var searchText by remember { mutableStateOf("") } @@ -195,6 +197,9 @@ fun SearchTextField( textStyle = TextStyle(color = Black, fontSize = 14.sp, fontWeight = Medium), modifier = Modifier.focusRequester(focusRequester), keyboardActions = KeyboardActions(onDone = { + filterViewModel.updateAllFilterUnClicked() + mapViewModel.initializeFilterSet() + if (searchText.isNotBlank()) { insertSearchWord(searchText, searchViewModel) From 56a6ffec2631bdad781e77f12ac0cf6be2df66ee Mon Sep 17 00:00:00 2001 From: somin Date: Mon, 19 Feb 2024 10:32:58 +0900 Subject: [PATCH 04/10] =?UTF-8?q?refactor=20:=20filter=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EB=B3=80=EC=88=98=20=EB=B0=8F=20=EB=A9=94=EC=86=8C?= =?UTF-8?q?=EB=93=9C=EB=A5=BC=20FilterViewModel=EB=A1=9C=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/presentation/ui/MainScreen.kt | 10 +++-- .../presentation/ui/map/MapViewModel.kt | 29 -------------- .../presentation/ui/map/NaverMapScreen.kt | 15 ++++---- .../ui/map/filter/FilterComponent.kt | 8 +--- .../ui/map/filter/FilterViewModel.kt | 38 ++++++++++++++++--- .../ui/map/list/StoreListBottomSheet.kt | 7 +++- .../presentation/ui/search/SearchScreen.kt | 3 +- 7 files changed, 52 insertions(+), 58 deletions(-) diff --git a/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt b/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt index 1539576..d608b17 100644 --- a/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt +++ b/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt @@ -10,6 +10,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavHostController import com.example.domain.model.map.ShowMoreCount @@ -22,6 +23,7 @@ import com.example.presentation.ui.map.MapViewModel import com.example.presentation.ui.map.NaverMapScreen import com.example.presentation.ui.map.call.StoreCallDialog import com.example.presentation.ui.map.filter.FilterComponent +import com.example.presentation.ui.map.filter.FilterViewModel import com.example.presentation.ui.map.list.StoreListBottomSheet import com.example.presentation.ui.map.reload.ReloadOrShowMoreButton import com.example.presentation.ui.map.summary.DimScreen @@ -41,7 +43,8 @@ fun MainScreen( onSplashScreenShowAble: (Boolean) -> Unit, navController: NavHostController, searchText: String?, - mapViewModel: MapViewModel + mapViewModel: MapViewModel, + filterViewModel : FilterViewModel = hiltViewModel() ) { val (clickedStoreInfo, onStoreInfoChanged) = remember { mutableStateOf( @@ -207,7 +210,6 @@ fun MainScreen( ) FilterComponent( - mapViewModel, onFilterStateChanged ) @@ -255,7 +257,7 @@ fun MainScreen( val mapCenterCoordinate by mapViewModel.mapCenterCoordinate.collectAsStateWithLifecycle() if (isReSearchButtonClicked && isScreenCoordinateChanged) { - mapViewModel.updateIsFilteredMarker(false) + filterViewModel.updateIsFilteredMarker(false) mapViewModel.searchStore( mapCenterCoordinate.longitude, mapCenterCoordinate.latitude, @@ -266,7 +268,7 @@ fun MainScreen( } if ((isReloadButtonClicked && isScreenCoordinateChanged)) { - mapViewModel.updateIsFilteredMarker(false) + filterViewModel.updateIsFilteredMarker(false) onErrorToastChanged("") mapViewModel.getStoreDetail( nwLong = screenCoordinate.northWest.longitude, diff --git a/presentation/src/main/java/com/example/presentation/ui/map/MapViewModel.kt b/presentation/src/main/java/com/example/presentation/ui/map/MapViewModel.kt index e569731..f2f4cd2 100644 --- a/presentation/src/main/java/com/example/presentation/ui/map/MapViewModel.kt +++ b/presentation/src/main/java/com/example/presentation/ui/map/MapViewModel.kt @@ -13,10 +13,7 @@ import com.example.domain.util.Resource import com.example.presentation.model.Coordinate import com.example.presentation.model.LocationTrackingButton import com.example.presentation.util.MainConstants.FAIL_TO_LOAD_DATA -import com.example.presentation.util.MainConstants.GREAT_STORE import com.example.presentation.util.MainConstants.INITIALIZE_ABLE -import com.example.presentation.util.MainConstants.KIND_STORE -import com.example.presentation.util.MainConstants.SAFE_STORE import com.example.presentation.util.MapScreenType import com.example.presentation.util.UiState import com.naver.maps.geometry.LatLng @@ -38,8 +35,6 @@ class MapViewModel @Inject constructor( private val _ableToShowSplashScreen = MutableStateFlow(true) val ableToShowSplashScreen: StateFlow = _ableToShowSplashScreen - private val filterSet = mutableSetOf() - private val _storeDetailModelData = MutableStateFlow>>>(UiState.Loading) val storeDetailModelData: StateFlow>>> = @@ -80,9 +75,6 @@ class MapViewModel @Inject constructor( private val _isSearchTerminated = MutableStateFlow(false) val isSearchTerminated: StateFlow = _isSearchTerminated - private val _isFilteredMarker = MutableStateFlow(false) - val isFilteredMarker: StateFlow = _isFilteredMarker - fun showMoreStore(count: Int) { val newItem: List = when (val uiState = _storeDetailModelData.value) { is UiState.Success -> uiState.data.getOrNull(count) ?: emptyList() @@ -97,23 +89,6 @@ class MapViewModel @Inject constructor( _ableToShowSplashScreen.value = false } - fun getFilterSet(): Set { - return if (filterSet.isEmpty()) setOf(SAFE_STORE, GREAT_STORE, KIND_STORE) - else filterSet.toSet() - } - - fun updateFilterSet(certificationName: String, isClicked: Boolean) { - if (isClicked) { - filterSet.add(certificationName) - } else { - filterSet.remove(certificationName) - } - } - - fun initializeFilterSet() { - filterSet.clear() - } - fun setLocationTrackingMode(): LocationTrackingButton { return if (isLocationPermissionGranted.value) { LocationTrackingButton.FOLLOW @@ -247,8 +222,4 @@ class MapViewModel @Inject constructor( fun updateIsSearchTerminated(isTerminated: Boolean) { _isSearchTerminated.value = isTerminated } - - fun updateIsFilteredMarker(isFilteredMarker: Boolean) { - _isFilteredMarker.value = isFilteredMarker - } } \ No newline at end of file diff --git a/presentation/src/main/java/com/example/presentation/ui/map/NaverMapScreen.kt b/presentation/src/main/java/com/example/presentation/ui/map/NaverMapScreen.kt index 5dde879..702b1e0 100644 --- a/presentation/src/main/java/com/example/presentation/ui/map/NaverMapScreen.kt +++ b/presentation/src/main/java/com/example/presentation/ui/map/NaverMapScreen.kt @@ -95,7 +95,7 @@ fun NaverMapScreen( mapViewModel: MapViewModel, navController: NavHostController, isReSearchButtonClicked: Boolean, - filterViewModel:FilterViewModel = hiltViewModel() + filterViewModel: FilterViewModel = hiltViewModel() ) { val cameraPositionState = rememberCameraPositionState {} @@ -161,7 +161,7 @@ fun NaverMapScreen( if (isInitializationLocation && mapViewModel.ableToShowSplashScreen.value) { onSplashScreenShowAble(false) } - mapViewModel.updateIsFilteredMarker(true) + filterViewModel.updateIsFilteredMarker(true) onLoadingChanged(false) onCurrentMapChanged(false) onShowMoreCountChanged(ShowMoreCount(0, state.data.size)) @@ -195,7 +195,7 @@ fun NaverMapScreen( } is UiState.Success -> { - mapViewModel.updateIsFilteredMarker(true) + filterViewModel.updateIsFilteredMarker(true) onCurrentMapChanged(false) onReloadOrShowMoreChanged(false) @@ -225,7 +225,7 @@ fun NaverMapScreen( } } - val isFilteredMarker by mapViewModel.isFilteredMarker.collectAsStateWithLifecycle() + val isFilteredMarker by filterViewModel.isFilteredMarker.collectAsStateWithLifecycle() if (isFilteredMarker) { FilteredMarkers( @@ -276,7 +276,6 @@ fun NaverMapScreen( mapViewModel.updateMapZoomLevel(cameraPositionState.position.zoom) navController.navigate(Screen.Search.route) filterViewModel.updateAllFilterUnClicked() - mapViewModel.initializeFilterSet() onSearchComponentChanged(false) } if (isBackPressed) { @@ -336,13 +335,14 @@ fun FilteredMarkers( onStoreInfoChanged: (StoreDetail) -> Unit, clickedMarkerId: Long, onMarkerChanged: (Long) -> Unit, + filterViewModel: FilterViewModel = hiltViewModel() ) { val storeDetailData by mapViewModel.flattenedStoreDetailList.collectAsStateWithLifecycle() storeDetailData.filter { info -> - mapViewModel.getFilterSet().intersect(info.certificationName.toSet()).isNotEmpty() + filterViewModel.getFilterSet().intersect(info.certificationName.toSet()).isNotEmpty() }.forEach { info -> val storeType = - when (mapViewModel.getFilterSet().intersect(info.certificationName.toSet()) + when (filterViewModel.getFilterSet().intersect(info.certificationName.toSet()) .last()) { KIND_STORE -> StoreType.KIND GREAT_STORE -> StoreType.GREAT @@ -538,7 +538,6 @@ private fun CheckSearchTerminationButtonClicked( LaunchedEffect(key1 = isSearchTerminated) { if (isSearchTerminated) { filterViewModel.updateAllFilterUnClicked() - mapViewModel.initializeFilterSet() movePrevCamera(cameraPositionState, mapCenterCoordinate, mapZoomLevel) onReloadButtonChanged(true) mapViewModel.updateIsSearchTerminated(false) diff --git a/presentation/src/main/java/com/example/presentation/ui/map/filter/FilterComponent.kt b/presentation/src/main/java/com/example/presentation/ui/map/filter/FilterComponent.kt index 32772e0..7e44de2 100644 --- a/presentation/src/main/java/com/example/presentation/ui/map/filter/FilterComponent.kt +++ b/presentation/src/main/java/com/example/presentation/ui/map/filter/FilterComponent.kt @@ -31,7 +31,6 @@ import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.example.presentation.model.StoreType -import com.example.presentation.ui.map.MapViewModel import com.example.presentation.ui.theme.Black import com.example.presentation.ui.theme.Blue import com.example.presentation.ui.theme.White @@ -42,7 +41,6 @@ import com.example.presentation.util.MainConstants.SEARCH_TEXT_FIELD_TOP_PADDING @SuppressLint("StateFlowValueCalledInComposition") @Composable fun FilterComponent( - mapViewModel: MapViewModel, onFilterStateChanged: (Boolean) -> Unit, filterViewModel: FilterViewModel = hiltViewModel() ) { @@ -63,19 +61,16 @@ fun FilterComponent( FilterButton( storeType = StoreType.KIND, isKindClicked.value, - mapViewModel, onFilterStateChanged ) FilterButton( storeType = StoreType.GREAT, isGreatClicked.value, - mapViewModel, onFilterStateChanged ) FilterButton( storeType = StoreType.SAFE, isSafeClicked.value, - mapViewModel, onFilterStateChanged ) } @@ -86,7 +81,6 @@ fun FilterComponent( fun FilterButton( storeType: StoreType, isFilterClicked: Boolean, - mapViewModel: MapViewModel, onFilterStateChanged: (Boolean) -> Unit, filterViewModel: FilterViewModel = hiltViewModel(), ) { @@ -94,7 +88,7 @@ fun FilterButton( CompositionLocalProvider(LocalMinimumInteractiveComponentEnforcement provides false) { Button( onClick = { - mapViewModel.updateFilterSet(certificationName, isFilterClicked.not()) + filterViewModel.updateFilterSet(certificationName, isFilterClicked.not()) when (storeType) { StoreType.KIND -> filterViewModel.updateKindFilterClicked() StoreType.SAFE -> filterViewModel.updateSafeFilterClicked() diff --git a/presentation/src/main/java/com/example/presentation/ui/map/filter/FilterViewModel.kt b/presentation/src/main/java/com/example/presentation/ui/map/filter/FilterViewModel.kt index cbee111..4c1403c 100644 --- a/presentation/src/main/java/com/example/presentation/ui/map/filter/FilterViewModel.kt +++ b/presentation/src/main/java/com/example/presentation/ui/map/filter/FilterViewModel.kt @@ -1,7 +1,7 @@ package com.example.presentation.ui.map.filter -import android.util.Log import androidx.lifecycle.ViewModel +import com.example.presentation.util.MainConstants import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -11,6 +11,11 @@ import javax.inject.Inject @HiltViewModel class FilterViewModel @Inject constructor() : ViewModel() { + private val _isFilteredMarker = MutableStateFlow(false) + val isFilteredMarker: StateFlow = _isFilteredMarker + + private val filterSet = mutableSetOf() + private val _isKindFilterClicked = MutableStateFlow(false) val isKindFilterClicked: StateFlow get() = _isKindFilterClicked @@ -20,6 +25,30 @@ class FilterViewModel @Inject constructor() : ViewModel() { private val _isSafeFilterClicked = MutableStateFlow(false) val isSafeFilterClicked: StateFlow get() = _isSafeFilterClicked + fun getFilterSet(): Set { + return if (filterSet.isEmpty()) setOf( + MainConstants.SAFE_STORE, + MainConstants.GREAT_STORE, + MainConstants.KIND_STORE + ) + else filterSet.toSet() + } + + fun updateFilterSet(certificationName: String, isClicked: Boolean) { + if (isClicked) { + filterSet.add(certificationName) + } else { + filterSet.remove(certificationName) + } + } + + fun updateAllFilterUnClicked() { + filterSet.clear() + _isKindFilterClicked.value = false + _isGreatFilterClicked.value = false + _isSafeFilterClicked.value = false + } + fun updateKindFilterClicked() { _isKindFilterClicked.value = _isKindFilterClicked.value.not() } @@ -32,10 +61,7 @@ class FilterViewModel @Inject constructor() : ViewModel() { _isSafeFilterClicked.value = _isSafeFilterClicked.value.not() } - fun updateAllFilterUnClicked() { - _isKindFilterClicked.value = false - _isGreatFilterClicked.value = false - _isSafeFilterClicked.value = false - Log.d("테스트","${_isKindFilterClicked.value}") + fun updateIsFilteredMarker(isFilteredMarker: Boolean) { + _isFilteredMarker.value = isFilteredMarker } } \ No newline at end of file diff --git a/presentation/src/main/java/com/example/presentation/ui/map/list/StoreListBottomSheet.kt b/presentation/src/main/java/com/example/presentation/ui/map/list/StoreListBottomSheet.kt index 008dae5..f7abd6f 100644 --- a/presentation/src/main/java/com/example/presentation/ui/map/list/StoreListBottomSheet.kt +++ b/presentation/src/main/java/com/example/presentation/ui/map/list/StoreListBottomSheet.kt @@ -25,6 +25,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.example.presentation.R import com.example.presentation.mapper.toUiModel @@ -33,6 +34,7 @@ import com.example.presentation.model.StoreDetail import com.example.presentation.ui.component.BottomSheetDragHandle import com.example.presentation.ui.component.EmptyScreen import com.example.presentation.ui.map.MapViewModel +import com.example.presentation.ui.map.filter.FilterViewModel import com.example.presentation.ui.theme.Black import com.example.presentation.ui.theme.DarkGray import com.example.presentation.ui.theme.SemiLightGray @@ -145,7 +147,8 @@ fun StoreListContent( onStoreInfoChanged: (StoreDetail) -> Unit, onMarkerChanged: (Long) -> Unit, onListItemChanged: (Boolean) -> Unit, - viewModel: MapViewModel + viewModel: MapViewModel, + filterViewModel: FilterViewModel = hiltViewModel() ) { val storeDetailData by viewModel.flattenedStoreDetailList.collectAsStateWithLifecycle() @@ -160,7 +163,7 @@ fun StoreListContent( LazyColumn { itemsIndexed( storeDetailData.filter { - viewModel.getFilterSet().intersect(it.certificationName.toSet()) + filterViewModel.getFilterSet().intersect(it.certificationName.toSet()) .isNotEmpty() } ) { _, item -> diff --git a/presentation/src/main/java/com/example/presentation/ui/search/SearchScreen.kt b/presentation/src/main/java/com/example/presentation/ui/search/SearchScreen.kt index c1db364..6eda4da 100644 --- a/presentation/src/main/java/com/example/presentation/ui/search/SearchScreen.kt +++ b/presentation/src/main/java/com/example/presentation/ui/search/SearchScreen.kt @@ -198,12 +198,11 @@ fun SearchTextField( modifier = Modifier.focusRequester(focusRequester), keyboardActions = KeyboardActions(onDone = { filterViewModel.updateAllFilterUnClicked() - mapViewModel.initializeFilterSet() if (searchText.isNotBlank()) { insertSearchWord(searchText, searchViewModel) - mapViewModel.updateIsFilteredMarker(false) + filterViewModel.updateIsFilteredMarker(false) mapViewModel.searchStore( mapCenterCoordinate.longitude, mapCenterCoordinate.latitude, From 0cccf07dca0dc875a6e4d181ecae3effff41d0cb Mon Sep 17 00:00:00 2001 From: jeeminimini Date: Mon, 19 Feb 2024 17:38:40 +0900 Subject: [PATCH 05/10] =?UTF-8?q?fix=20:=20SearchScreen=20=EB=92=A4?= =?UTF-8?q?=EB=A1=9C=EA=B0=80=EA=B8=B0=20=EC=97=90=EB=9F=AC=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/presentation/ui/search/SearchScreen.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/presentation/src/main/java/com/example/presentation/ui/search/SearchScreen.kt b/presentation/src/main/java/com/example/presentation/ui/search/SearchScreen.kt index 6eda4da..aa844f4 100644 --- a/presentation/src/main/java/com/example/presentation/ui/search/SearchScreen.kt +++ b/presentation/src/main/java/com/example/presentation/ui/search/SearchScreen.kt @@ -239,13 +239,16 @@ fun insertSearchWord(keyword: String, viewModel: SearchViewModel) { @Composable private fun BackArrow(navController: NavHostController, mapViewModel: MapViewModel) { + val mapScreenType by mapViewModel.mapScreenType.collectAsStateWithLifecycle() Image( imageVector = ImageVector.vectorResource(id = R.drawable.arrow), contentDescription = "Arrow", modifier = Modifier .size(18.dp) .clickable { - mapViewModel.updateIsSearchTerminated(true) + if (mapScreenType == MapScreenType.MAIN) { + mapViewModel.updateIsSearchTerminated(true) + } navController.popBackStack() } ) From 3e8258c366ebd99e970be8717ffc4c68ae36f254 Mon Sep 17 00:00:00 2001 From: jeeminimini Date: Mon, 19 Feb 2024 17:56:02 +0900 Subject: [PATCH 06/10] =?UTF-8?q?fix=20:=20SearchScreen=20=EB=92=A4?= =?UTF-8?q?=EB=A1=9C=EA=B0=80=EA=B8=B0=20=EC=82=AC=EC=9A=A9=EC=8B=9C=20Mai?= =?UTF-8?q?n=20=ED=99=94=EB=A9=B4=20SearchComponent=20=EC=B4=88=EA=B8=B0?= =?UTF-8?q?=ED=99=94=20=EC=95=88=EB=90=98=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/presentation/ui/MainScreen.kt | 3 ++- .../presentation/ui/search/StoreSearchComponent.kt | 13 ++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt b/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt index d608b17..7e2b05a 100644 --- a/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt +++ b/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt @@ -206,7 +206,8 @@ fun MainScreen( StoreSearchComponent( searchText, onSearchComponentChanged, - onSearchTerminationButtonChanged + onSearchTerminationButtonChanged, + mapViewModel ) FilterComponent( diff --git a/presentation/src/main/java/com/example/presentation/ui/search/StoreSearchComponent.kt b/presentation/src/main/java/com/example/presentation/ui/search/StoreSearchComponent.kt index 322edfb..3642742 100644 --- a/presentation/src/main/java/com/example/presentation/ui/search/StoreSearchComponent.kt +++ b/presentation/src/main/java/com/example/presentation/ui/search/StoreSearchComponent.kt @@ -15,6 +15,7 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.shadow @@ -26,19 +27,25 @@ import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.example.presentation.R +import com.example.presentation.ui.map.MapViewModel import com.example.presentation.ui.theme.MediumGray import com.example.presentation.ui.theme.White import com.example.presentation.util.MainConstants.DEFAULT_MARGIN import com.example.presentation.util.MainConstants.SEARCH_TEXT_FIELD_HEIGHT import com.example.presentation.util.MainConstants.SEARCH_TEXT_FIELD_TOP_PADDING +import com.example.presentation.util.MapScreenType @Composable fun StoreSearchComponent( searchText: String?, onSearchComponentChanged: (Boolean) -> Unit, - onSearchTerminationButtonChanged: (Boolean) -> Unit + onSearchTerminationButtonChanged: (Boolean) -> Unit, + mapViewModel: MapViewModel ) { + val mapScreenType by mapViewModel.mapScreenType.collectAsStateWithLifecycle() + Row( modifier = Modifier .padding( @@ -61,11 +68,11 @@ fun StoreSearchComponent( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween ) { - if (searchText.isNullOrBlank()) { + if (mapScreenType == MapScreenType.MAIN) { SearchPlaceHolderText(stringResource(R.string.search_placeholder_text), MediumGray) SearchSuffixImage(R.drawable.search) } else { - SearchPlaceHolderText(searchText, Black) + SearchPlaceHolderText(searchText ?: "", Black) SearchSuffixImage( R.drawable.delete, onSearchTerminationButtonChanged From ceec413c984acbe77e340ce3315a41988a37fdbe Mon Sep 17 00:00:00 2001 From: somin Date: Mon, 19 Feb 2024 22:22:36 +0900 Subject: [PATCH 07/10] =?UTF-8?q?refactor=20:=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81=20-=20=EB=B6=88?= =?UTF-8?q?=ED=95=84=EC=9A=94=ED=95=9C=20SearchText=20=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=20-=20ReSearchButtonComponent=EB=A1=9C=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/example/presentation/ui/InitScreen.kt | 2 -- .../main/java/com/example/presentation/ui/MainActivity.kt | 7 ------- .../main/java/com/example/presentation/ui/MainScreen.kt | 5 ++--- .../example/presentation/ui/search/ReSearchComponent.kt | 5 +---- 4 files changed, 3 insertions(+), 16 deletions(-) diff --git a/presentation/src/main/java/com/example/presentation/ui/InitScreen.kt b/presentation/src/main/java/com/example/presentation/ui/InitScreen.kt index 3a4dd1e..342b1b5 100644 --- a/presentation/src/main/java/com/example/presentation/ui/InitScreen.kt +++ b/presentation/src/main/java/com/example/presentation/ui/InitScreen.kt @@ -16,7 +16,6 @@ fun InitScreen( onCallStoreChanged: (String) -> Unit, onSplashScreenShowAble: (Boolean) -> Unit, navController: NavHostController, - searchText: String?, isFirstRun: Boolean, isOnboardingScreenShowAble: Boolean, onOnboardingScreenShowAble: (Boolean) -> Unit, @@ -29,7 +28,6 @@ fun InitScreen( onCallStoreChanged, onSplashScreenShowAble, navController, - searchText, mapViewModel ) diff --git a/presentation/src/main/java/com/example/presentation/ui/MainActivity.kt b/presentation/src/main/java/com/example/presentation/ui/MainActivity.kt index fa0c11c..d86de5d 100644 --- a/presentation/src/main/java/com/example/presentation/ui/MainActivity.kt +++ b/presentation/src/main/java/com/example/presentation/ui/MainActivity.kt @@ -24,7 +24,6 @@ import com.example.presentation.ui.map.MapViewModel import com.example.presentation.ui.navigation.Screen import com.example.presentation.ui.search.SearchScreen import com.example.presentation.ui.theme.Android_KCSTheme -import com.example.presentation.util.MainConstants.SEARCH_KEY import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch @@ -64,16 +63,10 @@ class MainActivity : ComponentActivity() { composable( route = Screen.Main.route ) { - val searchText = remember { - navController.previousBackStackEntry?.savedStateHandle?.get( - SEARCH_KEY - ) - } InitScreen( onCallStoreChanged, onSplashScreenShowAble, navController, - searchText, isFirstRun, isOnboardingScreenShowAble, onOnboardingScreenShowAble, diff --git a/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt b/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt index 7e2b05a..f76e486 100644 --- a/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt +++ b/presentation/src/main/java/com/example/presentation/ui/MainScreen.kt @@ -28,7 +28,7 @@ import com.example.presentation.ui.map.list.StoreListBottomSheet import com.example.presentation.ui.map.reload.ReloadOrShowMoreButton import com.example.presentation.ui.map.summary.DimScreen import com.example.presentation.ui.map.summary.StoreSummaryBottomSheet -import com.example.presentation.ui.search.ReSearchComponent +import com.example.presentation.ui.search.ReSearchButtonComponent import com.example.presentation.ui.search.StoreSearchComponent import com.example.presentation.util.MainConstants import com.example.presentation.util.MainConstants.SEARCH_KEY @@ -42,7 +42,6 @@ fun MainScreen( onCallStoreChanged: (String) -> Unit, onSplashScreenShowAble: (Boolean) -> Unit, navController: NavHostController, - searchText: String?, mapViewModel: MapViewModel, filterViewModel : FilterViewModel = hiltViewModel() ) { @@ -178,7 +177,7 @@ fun MainScreen( if (isReloadOrShowMoreShowAble) { if (isSearchTextExist) { - ReSearchComponent( + ReSearchButtonComponent( isMarkerClicked, currentSummaryInfoHeight, isMapGestured, diff --git a/presentation/src/main/java/com/example/presentation/ui/search/ReSearchComponent.kt b/presentation/src/main/java/com/example/presentation/ui/search/ReSearchComponent.kt index 4a1c5ea..f2efd94 100644 --- a/presentation/src/main/java/com/example/presentation/ui/search/ReSearchComponent.kt +++ b/presentation/src/main/java/com/example/presentation/ui/search/ReSearchComponent.kt @@ -25,9 +25,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import androidx.hilt.navigation.compose.hiltViewModel import com.example.presentation.R -import com.example.presentation.ui.map.MapViewModel import com.example.presentation.ui.map.reload.LoadingAnimation import com.example.presentation.ui.map.reload.setReloadButtonBottomPadding import com.example.presentation.ui.theme.Black @@ -36,7 +34,7 @@ import com.example.presentation.ui.theme.White import com.example.presentation.util.MainConstants.UN_MARKER @Composable -fun ReSearchComponent( +fun ReSearchButtonComponent( isMarkerClicked: Boolean, currentSummaryInfoHeight: Dp, isMapGestured: Boolean, @@ -76,7 +74,6 @@ fun ReSearchButton( onMarkerChanged: (Long) -> Unit, onBottomSheetChanged: (Boolean) -> Unit, isLoading: Boolean, - viewModel: MapViewModel = hiltViewModel() ) { Button( onClick = { From 7bec4d677f1cb1c389aec3ffa108090958ba6709 Mon Sep 17 00:00:00 2001 From: somin Date: Mon, 19 Feb 2024 22:48:34 +0900 Subject: [PATCH 08/10] =?UTF-8?q?layout=20:=20ReSearchButton=20=EB=A1=9C?= =?UTF-8?q?=EB=94=A9=EC=8B=9C=20=EC=95=A0=EB=8B=88=EB=A9=94=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/presentation/ui/map/NaverMapScreen.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/presentation/src/main/java/com/example/presentation/ui/map/NaverMapScreen.kt b/presentation/src/main/java/com/example/presentation/ui/map/NaverMapScreen.kt index 702b1e0..bd66641 100644 --- a/presentation/src/main/java/com/example/presentation/ui/map/NaverMapScreen.kt +++ b/presentation/src/main/java/com/example/presentation/ui/map/NaverMapScreen.kt @@ -191,10 +191,11 @@ fun NaverMapScreen( when (val state = searchStore) { is UiState.Loading -> { - // Todo : 검색 시 로딩 뷰 구현 + onLoadingChanged(true) } is UiState.Success -> { + onLoadingChanged(false) filterViewModel.updateIsFilteredMarker(true) onCurrentMapChanged(false) onReloadOrShowMoreChanged(false) From f3c83d4f0ba6fc8a14bc2276c77bf9da56744884 Mon Sep 17 00:00:00 2001 From: somin Date: Mon, 19 Feb 2024 23:59:35 +0900 Subject: [PATCH 09/10] =?UTF-8?q?fix=20:=20SearchComponent=20=ED=81=B4?= =?UTF-8?q?=EB=A6=AD=20=EC=8B=9C=20=ED=82=A4=EC=9B=8C=EB=93=9C=20=EC=97=85?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EC=95=88=20=EB=90=98=EB=8A=94=20?= =?UTF-8?q?=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/example/presentation/ui/map/NaverMapScreen.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/presentation/src/main/java/com/example/presentation/ui/map/NaverMapScreen.kt b/presentation/src/main/java/com/example/presentation/ui/map/NaverMapScreen.kt index bd66641..654b1e3 100644 --- a/presentation/src/main/java/com/example/presentation/ui/map/NaverMapScreen.kt +++ b/presentation/src/main/java/com/example/presentation/ui/map/NaverMapScreen.kt @@ -275,6 +275,7 @@ fun NaverMapScreen( ) ) mapViewModel.updateMapZoomLevel(cameraPositionState.position.zoom) + mapViewModel.updateMapScreenType(MapScreenType.MAIN) navController.navigate(Screen.Search.route) filterViewModel.updateAllFilterUnClicked() onSearchComponentChanged(false) From a3bb0dbc525bfb64ff3c0422fb91f4ff6237b49b Mon Sep 17 00:00:00 2001 From: somin Date: Tue, 20 Feb 2024 03:14:43 +0900 Subject: [PATCH 10/10] =?UTF-8?q?feat=20:=20SearchScreen=EC=9D=98=20?= =?UTF-8?q?=EC=B5=9C=EA=B7=BC=20=EA=B2=80=EC=83=89=EC=96=B4=20=ED=81=B4?= =?UTF-8?q?=EB=A6=AD=20=EC=8B=9C=20=ED=95=B4=EB=8B=B9=20=EA=B2=80=EC=83=89?= =?UTF-8?q?=EC=96=B4=EB=A1=9C=20Api=20=ED=86=B5=EC=8B=A0=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/ui/search/SearchScreen.kt | 42 +++++++++++++++---- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/presentation/src/main/java/com/example/presentation/ui/search/SearchScreen.kt b/presentation/src/main/java/com/example/presentation/ui/search/SearchScreen.kt index aa844f4..b9609a8 100644 --- a/presentation/src/main/java/com/example/presentation/ui/search/SearchScreen.kt +++ b/presentation/src/main/java/com/example/presentation/ui/search/SearchScreen.kt @@ -84,7 +84,7 @@ fun SearchScreen( ) { SearchAppBar(navController, mapViewModel) SearchDivider(6) - RecentSearchList(onDeleteAllDialogVisibleChanged) + RecentSearchList(onDeleteAllDialogVisibleChanged, navController) if (isDeleteAllDialogVisible) { DeleteAllDialog(onDeleteAllDialogVisibleChanged) @@ -257,10 +257,11 @@ private fun BackArrow(navController: NavHostController, mapViewModel: MapViewMod @Composable fun RecentSearchList( onDeleteAllDialogVisibleChanged: (Boolean) -> Unit, - viewModel: SearchViewModel = hiltViewModel() + navController: NavHostController, + searchViewModel: SearchViewModel = hiltViewModel() ) { - viewModel.getRecentSearchWord() - val recentSearchWords by viewModel.recentSearchWords.collectAsStateWithLifecycle() + searchViewModel.getRecentSearchWord() + val recentSearchWords by searchViewModel.recentSearchWords.collectAsStateWithLifecycle() TitleText(recentSearchWords, onDeleteAllDialogVisibleChanged) @@ -270,7 +271,7 @@ fun RecentSearchList( } else { LazyColumn { itemsIndexed(recentSearchWords) { idx, item -> - RecentSearchItem(item) + RecentSearchItem(item, navController) SearchDivider(1) } } @@ -307,12 +308,37 @@ fun TitleText(exampleItems: List, onDeleteAllDialogVisibleChanged: ( } @Composable -fun RecentSearchItem(searchWord: SearchWord, viewModel: SearchViewModel = hiltViewModel()) { +fun RecentSearchItem( + searchWord: SearchWord, + navController: NavHostController, + mapViewModel: MapViewModel = hiltViewModel(), + searchViewModel: SearchViewModel = hiltViewModel(), + filterViewModel: FilterViewModel = hiltViewModel() +) { + val mapCenterCoordinate by mapViewModel.mapCenterCoordinate.collectAsStateWithLifecycle() + val mapScreenType by mapViewModel.mapScreenType.collectAsStateWithLifecycle() Row( modifier = Modifier .fillMaxWidth() .height(53.dp) - .padding(horizontal = DEFAULT_MARGIN.dp), + .padding(horizontal = DEFAULT_MARGIN.dp) + .clickable { + // TODO : 최근 검색어 클릭 시 검색 구현 + filterViewModel.updateAllFilterUnClicked() + insertSearchWord(searchWord.keyword, searchViewModel) + + filterViewModel.updateIsFilteredMarker(false) + mapViewModel.searchStore( + mapCenterCoordinate.longitude, + mapCenterCoordinate.latitude, + searchWord.keyword + ) + navController.currentBackStackEntry?.savedStateHandle?.set( + key = SEARCH_KEY, + value = searchWord.keyword + ) + mapViewModel.updateMapScreenType(MapScreenType.SEARCH) + }, verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween ) { @@ -343,7 +369,7 @@ fun RecentSearchItem(searchWord: SearchWord, viewModel: SearchViewModel = hiltVi modifier = Modifier .size(16.dp) .clickable { - viewModel.deleteSearchWordById(searchWord.id) + searchViewModel.deleteSearchWordById(searchWord.id) } ) }