From 3d13a4cd6d0be7bd73ef9aa217a18d7665450c60 Mon Sep 17 00:00:00 2001 From: roel <ash49901@gmail.com> Date: Wed, 22 Jan 2025 18:56:06 +0900 Subject: [PATCH 1/9] =?UTF-8?q?[FEAT/#101]=20=EB=82=B4=20=EC=A7=80?= =?UTF-8?q?=EB=8F=84=20=EC=B0=9C=20=ED=81=B4=EB=A6=AD=EC=8B=9C=20=ED=85=8D?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=83=89=EC=83=81=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?=EB=B0=91=20=EC=9E=A5=EC=86=8C=20=EC=83=81=EC=84=B8=20=EB=B0=94?= =?UTF-8?q?=ED=85=80=20=EC=9C=84=EC=97=90=EC=84=9C=20=EC=95=84=EB=9E=98?= =?UTF-8?q?=EB=A1=9C=20=EB=82=B4=EB=A0=A4=EC=98=A4=EB=8A=94=20=EB=B6=80?= =?UTF-8?q?=EB=B6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/placeDetail/PlaceDetailRoute.kt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailRoute.kt b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailRoute.kt index e2ffa6cd..ac58f752 100644 --- a/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailRoute.kt +++ b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailRoute.kt @@ -7,6 +7,7 @@ import android.net.Uri import android.os.Build import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.PaddingValues @@ -17,6 +18,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.safeContentPadding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.sizeIn import androidx.compose.foundation.layout.width @@ -265,7 +267,14 @@ private fun PlaceDetailScreen( } Spacer(modifier = Modifier.height(27.dp)) } + } + Box( + modifier = Modifier + .fillMaxSize() + .safeContentPadding() + ) { PlaceDetailBottomBar( + modifier = Modifier.align(Alignment.BottomCenter), addMapCount = addMapCount, isScooped = isScooped, isAddMap = isAddMap, @@ -284,6 +293,7 @@ private fun PlaceDetailScreen( onDeletePinMapButtonClick = onDeletePinMapButtonClick ) } + } private fun searchPlaceNaverMap( @@ -378,7 +388,7 @@ private fun PlaceDetailBottomBar( Text( text = addMapCount.toString(), style = SpoonyAndroidTheme.typography.caption1m, - color = SpoonyAndroidTheme.colors.gray800 + color = if(isAddMap) SpoonyAndroidTheme.colors.main400 else SpoonyAndroidTheme.colors.gray800 ) } } else { From dd56c13032efc77654091317cf4f46c2c5aa6c8e Mon Sep 17 00:00:00 2001 From: roel <ash49901@gmail.com> Date: Wed, 22 Jan 2025 20:19:01 +0900 Subject: [PATCH 2/9] =?UTF-8?q?[FEAT/#101]=20snackbar=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../placeDetail/PlaceDetailRoute.kt | 434 ++++++++---------- .../placeDetail/PlaceDetailViewModel.kt | 12 + .../component/PlaceDetailBottomBar.kt | 113 +++++ .../event/PlaceDetailSnackbarTrigger.kt | 7 + 4 files changed, 314 insertions(+), 252 deletions(-) create mode 100644 app/src/main/java/com/spoony/spoony/presentation/placeDetail/component/PlaceDetailBottomBar.kt create mode 100644 app/src/main/java/com/spoony/spoony/presentation/placeDetail/event/PlaceDetailSnackbarTrigger.kt diff --git a/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailRoute.kt b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailRoute.kt index ac58f752..982ffb73 100644 --- a/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailRoute.kt +++ b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailRoute.kt @@ -5,63 +5,60 @@ import android.content.Intent import android.content.pm.PackageManager import android.net.Uri import android.os.Build -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.IntrinsicSize 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.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.safeContentPadding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.sizeIn -import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.Icon +import androidx.compose.material3.Scaffold +import androidx.compose.material3.SnackbarHost +import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.vectorResource import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.spoony.spoony.R -import com.spoony.spoony.core.designsystem.component.button.SpoonyButton +import androidx.lifecycle.flowWithLifecycle +import com.spoony.spoony.core.designsystem.component.snackbar.TextSnackbar import com.spoony.spoony.core.designsystem.component.tag.IconTag import com.spoony.spoony.core.designsystem.component.topappbar.TagTopAppBar import com.spoony.spoony.core.designsystem.theme.SpoonyAndroidTheme -import com.spoony.spoony.core.designsystem.type.ButtonSize -import com.spoony.spoony.core.designsystem.type.ButtonStyle import com.spoony.spoony.core.state.UiState import com.spoony.spoony.core.util.extension.hexToColor -import com.spoony.spoony.core.util.extension.noRippleClickable import com.spoony.spoony.core.util.extension.toValidHexColor import com.spoony.spoony.domain.entity.CategoryEntity import com.spoony.spoony.domain.entity.PostEntity import com.spoony.spoony.domain.entity.UserEntity +import com.spoony.spoony.presentation.main.SHOW_SNACKBAR_TIMEMILLIS import com.spoony.spoony.presentation.placeDetail.component.IconDropdownMenu +import com.spoony.spoony.presentation.placeDetail.component.PlaceDetailBottomBar import com.spoony.spoony.presentation.placeDetail.component.PlaceDetailImageLazyRow import com.spoony.spoony.presentation.placeDetail.component.ScoopDialog import com.spoony.spoony.presentation.placeDetail.component.StoreInfo import com.spoony.spoony.presentation.placeDetail.component.UserProfileInfo +import com.spoony.spoony.presentation.placeDetail.event.PlaceDetailLocalSnackBarTrigger import com.spoony.spoony.presentation.placeDetail.type.DropdownOption import kotlinx.collections.immutable.ImmutableList +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch @Composable fun PlaceDetailRoute( @@ -74,11 +71,41 @@ fun PlaceDetailRoute( val state by viewModel.state.collectAsStateWithLifecycle(lifecycleOwner = lifecycleOwner) + val coroutineScope = rememberCoroutineScope() + val snackBarHostState = remember { SnackbarHostState() } + var scoopDialogVisibility by remember { mutableStateOf(false) } + + val onShowSnackBar: (String) -> Unit = { message -> + coroutineScope.launch { + snackBarHostState.currentSnackbarData?.dismiss() + val job = launch { + snackBarHostState.showSnackbar(message) + } + delay(SHOW_SNACKBAR_TIMEMILLIS) + job.cancel() + } + } + val spoonAmount = when (state.spoonAmountEntity) { is UiState.Success -> (state.spoonAmountEntity as UiState.Success<Int>).data else -> 99 } + LaunchedEffect(viewModel.sideEffect, lifecycleOwner) { + viewModel.sideEffect.flowWithLifecycle(lifecycleOwner.lifecycle).collect { effect -> + when (effect) { + is PlaceDetailSideEffect.ShowSnackbar -> { + onShowSnackBar(effect.message) + } + } + } + } + + val postId = (state.postId as? UiState.Success)?.data ?: return + val userId = (state.userId as? UiState.Success)?.data ?: return + + val context = LocalContext.current + val userProfile = when (state.userEntity) { is UiState.Success -> (state.userEntity as UiState.Success<UserEntity>).data else -> UserEntity( @@ -89,40 +116,84 @@ fun PlaceDetailRoute( userRegion = "성북구" ) } + + if (scoopDialogVisibility) { + ScoopDialog( + onClickPositive = { + viewModel.useSpoon(postId, userId) + scoopDialogVisibility = false + }, + onClickNegative = { + scoopDialogVisibility = false + } + ) + } + when (state.postEntity) { is UiState.Empty -> {} is UiState.Loading -> {} is UiState.Failure -> {} is UiState.Success -> { with(state.postEntity as UiState.Success<PostEntity>) { - val postId = (state.postId as? UiState.Success)?.data ?: return - val userId = (state.userId as? UiState.Success)?.data ?: return - PlaceDetailScreen( - paddingValues = paddingValues, - menuList = data.menuList, - title = data.title, - description = data.description, - userProfileUrl = userProfile.userProfileUrl, - userName = userProfile.userName, - userRegion = userProfile.userRegion, - photoUrlList = data.photoUrlList, - category = data.category, - date = data.date, - placeAddress = data.placeAddress, - placeName = data.placeName, - spoonAmount = spoonAmount, - addMapCount = data.addMapCount, - isScooped = data.isScooped, - isAddMap = data.isAddMap, - latitude = data.latitude, - longitude = data.longitude, - onScoopButtonClick = { viewModel.useSpoon(postId, userId) }, - onAddMapButtonClick = { viewModel.addMyMap(postId, userId) }, - onDeletePinMapButtonClick = { viewModel.deletePinMap(postId, userId) }, - dropdownMenuList = state.dropDownMenuList, - onBackButtonClick = navigateUp, - onReportButtonClick = navigateToReport - ) + CompositionLocalProvider( + PlaceDetailLocalSnackBarTrigger provides onShowSnackBar + ) { + Scaffold( + snackbarHost = { + SnackbarHost(hostState = snackBarHostState) { snackbarData -> + TextSnackbar(text = snackbarData.visuals.message) + } + }, + topBar = { + TagTopAppBar( + count = spoonAmount, + showBackButton = true, + onBackButtonClick = navigateUp + ) + }, + bottomBar = { + PlaceDetailBottomBar( + modifier = Modifier + .navigationBarsPadding(), + addMapCount = data.addMapCount, + isScooped = data.isScooped, + isAddMap = data.isAddMap, + onScoopButtonClick = { + scoopDialogVisibility = true + }, + onSearchMapClick = { + searchPlaceNaverMap( + latitude = data.latitude, + longitude = data.longitude, + placeName = data.placeName, + context = context + ) + }, + onAddMapButtonClick = { viewModel.addMyMap(postId, userId) }, + onDeletePinMapButtonClick = { viewModel.deletePinMap(postId, userId) } + ) + }, + content = { paddingValues -> + PlaceDetailScreen( + paddingValues = paddingValues, + menuList = data.menuList, + title = data.title, + description = data.description, + userProfileUrl = userProfile.userProfileUrl, + userName = userProfile.userName, + userRegion = userProfile.userRegion, + photoUrlList = data.photoUrlList, + category = data.category, + date = data.date, + placeAddress = data.placeAddress, + placeName = data.placeName, + isScooped = data.isScooped, + dropdownMenuList = state.dropDownMenuList, + onReportButtonClick = navigateToReport + ) + } + ) + } } } } @@ -142,158 +213,100 @@ private fun PlaceDetailScreen( date: String, placeAddress: String, placeName: String, - spoonAmount: Int, - addMapCount: Int, - isAddMap: Boolean, isScooped: Boolean, - latitude: Double, - longitude: Double, - onScoopButtonClick: () -> Unit, - onAddMapButtonClick: () -> Unit, - onDeletePinMapButtonClick: () -> Unit, - onBackButtonClick: () -> Unit, dropdownMenuList: ImmutableList<String>, onReportButtonClick: () -> Unit ) { val scrollState = rememberScrollState() - val context = LocalContext.current - - var scoopDialogVisibility by remember { mutableStateOf(false) } - - if (scoopDialogVisibility) { - ScoopDialog( - onClickPositive = { - onScoopButtonClick() - scoopDialogVisibility = false - }, - onClickNegative = { - scoopDialogVisibility = false - } - ) - } - Column( modifier = Modifier .fillMaxSize() - .padding(bottom = paddingValues.calculateBottomPadding()) + .padding( + top = paddingValues.calculateTopPadding(), + bottom = paddingValues.calculateBottomPadding() + ) + .verticalScroll(scrollState) ) { - TagTopAppBar( - count = spoonAmount, - showBackButton = true, - onBackButtonClick = onBackButtonClick - ) - Column( + Row( modifier = Modifier - .weight(1f) - .verticalScroll(scrollState) + .fillMaxWidth() + .padding( + vertical = 8.dp, + horizontal = 20.dp + ), + verticalAlignment = Alignment.CenterVertically ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding( - vertical = 8.dp, - horizontal = 20.dp - ), - verticalAlignment = Alignment.CenterVertically - ) { - UserProfileInfo( - imageUrl = userProfileUrl, - name = userName, - location = "$userRegion 수저", - modifier = Modifier.weight(1f) - ) + UserProfileInfo( + imageUrl = userProfileUrl, + name = userName, + location = "$userRegion 수저", + modifier = Modifier.weight(1f) + ) - IconDropdownMenu( - menuItems = dropdownMenuList, - onMenuItemClick = { menu -> - when (menu) { - DropdownOption.REPORT.string -> { - onReportButtonClick() - } + IconDropdownMenu( + menuItems = dropdownMenuList, + onMenuItemClick = { menu -> + when (menu) { + DropdownOption.REPORT.string -> { + onReportButtonClick() } } - ) - } + } + ) + } - Spacer(modifier = Modifier.height(24.dp)) + Spacer(modifier = Modifier.height(24.dp)) - PlaceDetailImageLazyRow( - imageList = photoUrlList, - isBlurred = !isScooped - ) + PlaceDetailImageLazyRow( + imageList = photoUrlList, + isBlurred = !isScooped + ) - Spacer(modifier = Modifier.height(32.dp)) + Spacer(modifier = Modifier.height(32.dp)) - Column(modifier = Modifier.padding(horizontal = 20.dp)) { - IconTag( - text = category.categoryName, - backgroundColor = Color.hexToColor(category.backgroundColor.toValidHexColor()), - textColor = Color.hexToColor(category.textColor.toValidHexColor()), - iconUrl = category.iconUrl - ) + Column(modifier = Modifier.padding(horizontal = 20.dp)) { + IconTag( + text = category.categoryName, + backgroundColor = Color.hexToColor(category.backgroundColor.toValidHexColor()), + textColor = Color.hexToColor(category.textColor.toValidHexColor()), + iconUrl = category.iconUrl + ) - Spacer(modifier = Modifier.height(8.dp)) + Spacer(modifier = Modifier.height(8.dp)) - Text( - text = title, - style = SpoonyAndroidTheme.typography.title1, - color = SpoonyAndroidTheme.colors.black - ) + Text( + text = title, + style = SpoonyAndroidTheme.typography.title1, + color = SpoonyAndroidTheme.colors.black + ) - Spacer(modifier = Modifier.height(8.dp)) + Spacer(modifier = Modifier.height(8.dp)) - Text( - text = date, - style = SpoonyAndroidTheme.typography.caption1m, - color = SpoonyAndroidTheme.colors.gray400 - ) + Text( + text = date, + style = SpoonyAndroidTheme.typography.caption1m, + color = SpoonyAndroidTheme.colors.gray400 + ) - Spacer(modifier = Modifier.height(20.dp)) + Spacer(modifier = Modifier.height(20.dp)) - Text( - text = description, - style = SpoonyAndroidTheme.typography.body2m, - color = SpoonyAndroidTheme.colors.gray900 - ) + Text( + text = description, + style = SpoonyAndroidTheme.typography.body2m, + color = SpoonyAndroidTheme.colors.gray900 + ) - Spacer(modifier = Modifier.height(32.dp)) + Spacer(modifier = Modifier.height(32.dp)) - StoreInfo( - isBlurred = !isScooped, - menuList = menuList, - locationSubTitle = placeName, - location = placeAddress - ) - } - Spacer(modifier = Modifier.height(27.dp)) + StoreInfo( + isBlurred = !isScooped, + menuList = menuList, + locationSubTitle = placeName, + location = placeAddress + ) } + Spacer(modifier = Modifier.height(27.dp)) } - Box( - modifier = Modifier - .fillMaxSize() - .safeContentPadding() - ) { - PlaceDetailBottomBar( - modifier = Modifier.align(Alignment.BottomCenter), - addMapCount = addMapCount, - isScooped = isScooped, - isAddMap = isAddMap, - onScoopButtonClick = { - scoopDialogVisibility = true - }, - onSearchMapClick = { - searchPlaceNaverMap( - latitude = latitude, - longitude = longitude, - placeName = placeName, - context = context - ) - }, - onAddMapButtonClick = onAddMapButtonClick, - onDeletePinMapButtonClick = onDeletePinMapButtonClick - ) - } - } private fun searchPlaceNaverMap( @@ -327,86 +340,3 @@ private fun searchPlaceNaverMap( } } } - -@Composable -private fun PlaceDetailBottomBar( - addMapCount: Int, - onScoopButtonClick: () -> Unit, - onSearchMapClick: () -> Unit, - onAddMapButtonClick: () -> Unit, - onDeletePinMapButtonClick: () -> Unit, - modifier: Modifier = Modifier, - isScooped: Boolean = false, - isAddMap: Boolean = false -) { - Row( - modifier = modifier - .fillMaxWidth() - .background(SpoonyAndroidTheme.colors.white) - .padding( - horizontal = 20.dp, - vertical = 10.dp - ) - .height(IntrinsicSize.Max), - verticalAlignment = Alignment.CenterVertically - ) { - if (isScooped) { - SpoonyButton( - text = "길찾기", - onClick = onSearchMapClick, - style = ButtonStyle.Secondary, - size = ButtonSize.Medium, - modifier = Modifier.weight(1f) - ) - - Spacer(modifier = Modifier.width(15.dp)) - - Column( - modifier = Modifier - .fillMaxHeight() - .sizeIn(minWidth = 56.dp) - .noRippleClickable( - if (isAddMap) { - onDeletePinMapButtonClick - } else { - onAddMapButtonClick - } - ), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally - ) { - Icon( - imageVector = if (isAddMap) ImageVector.vectorResource(id = R.drawable.ic_add_map_main400_24) else ImageVector.vectorResource(id = R.drawable.ic_add_map_gray400_24), - modifier = Modifier - .size(32.dp), - contentDescription = null, - tint = Color.Unspecified - ) - - Spacer(modifier = Modifier.height(4.dp)) - - Text( - text = addMapCount.toString(), - style = SpoonyAndroidTheme.typography.caption1m, - color = if(isAddMap) SpoonyAndroidTheme.colors.main400 else SpoonyAndroidTheme.colors.gray800 - ) - } - } else { - SpoonyButton( - text = "떠먹기", - style = ButtonStyle.Secondary, - size = ButtonSize.Medium, - onClick = onScoopButtonClick, - modifier = Modifier.weight(1f), - icon = { - Icon( - imageVector = ImageVector.vectorResource(R.drawable.ic_button_spoon_32), - modifier = Modifier.size(32.dp), - contentDescription = null, - tint = Color.Unspecified - ) - } - ) - } - } -} diff --git a/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailViewModel.kt b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailViewModel.kt index eaad3b81..fc5058ac 100644 --- a/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailViewModel.kt +++ b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailViewModel.kt @@ -9,8 +9,11 @@ import com.spoony.spoony.domain.repository.PostRepository import com.spoony.spoony.presentation.placeDetail.navigation.PlaceDetail import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.launch @HiltViewModel @@ -22,6 +25,9 @@ class PlaceDetailViewModel @Inject constructor( val state: StateFlow<PlaceDetailState> get() = _state + private val _sideEffect = MutableSharedFlow<PlaceDetailSideEffect>() + val sideEffect: SharedFlow<PlaceDetailSideEffect> = _sideEffect.asSharedFlow() + init { val postArgs = savedStateHandle.toRoute<PlaceDetail>() _state.value = _state.value.copy( @@ -69,6 +75,7 @@ class PlaceDetailViewModel @Inject constructor( viewModelScope.launch { postRepository.postAddMap(userId = userId, postId = postId) .onSuccess { response -> + _sideEffect.emit(PlaceDetailSideEffect.ShowSnackbar("내 지도에 추가되었어요.")) (_state.value.postEntity as? UiState.Success)?.data?.let { currentPostEntity -> with(currentPostEntity) { _state.value = _state.value.copy( @@ -92,6 +99,7 @@ class PlaceDetailViewModel @Inject constructor( viewModelScope.launch { postRepository.deletePinMap(userId = userId, postId = postId) .onSuccess { response -> + _sideEffect.emit(PlaceDetailSideEffect.ShowSnackbar("내 지도에서 삭제되었어요.")) (_state.value.postEntity as? UiState.Success)?.data?.let { currentPostEntity -> with(currentPostEntity) { _state.value = _state.value.copy( @@ -111,3 +119,7 @@ class PlaceDetailViewModel @Inject constructor( } } } + +sealed class PlaceDetailSideEffect { + data class ShowSnackbar(val message: String) : PlaceDetailSideEffect() +} diff --git a/app/src/main/java/com/spoony/spoony/presentation/placeDetail/component/PlaceDetailBottomBar.kt b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/component/PlaceDetailBottomBar.kt new file mode 100644 index 00000000..3a83bd1d --- /dev/null +++ b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/component/PlaceDetailBottomBar.kt @@ -0,0 +1,113 @@ +package com.spoony.spoony.presentation.placeDetail.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.IntrinsicSize +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.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.sizeIn +import androidx.compose.foundation.layout.width +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.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.unit.dp +import com.spoony.spoony.R +import com.spoony.spoony.core.designsystem.component.button.SpoonyButton +import com.spoony.spoony.core.designsystem.theme.SpoonyAndroidTheme +import com.spoony.spoony.core.designsystem.type.ButtonSize +import com.spoony.spoony.core.designsystem.type.ButtonStyle +import com.spoony.spoony.core.util.extension.noRippleClickable + +@Composable +fun PlaceDetailBottomBar( + addMapCount: Int, + onScoopButtonClick: () -> Unit, + onSearchMapClick: () -> Unit, + onAddMapButtonClick: () -> Unit, + onDeletePinMapButtonClick: () -> Unit, + modifier: Modifier = Modifier, + isScooped: Boolean = false, + isAddMap: Boolean = false +) { + Row( + modifier = modifier + .fillMaxWidth() + .background(SpoonyAndroidTheme.colors.white) + .padding( + horizontal = 20.dp, + vertical = 10.dp + ) + .height(IntrinsicSize.Max), + verticalAlignment = Alignment.CenterVertically + ) { + if (isScooped) { + SpoonyButton( + text = "길찾기", + onClick = onSearchMapClick, + style = ButtonStyle.Secondary, + size = ButtonSize.Medium, + modifier = Modifier.weight(1f) + ) + + Spacer(modifier = Modifier.width(15.dp)) + + Column( + modifier = Modifier + .fillMaxHeight() + .sizeIn(minWidth = 56.dp) + .noRippleClickable( + if (isAddMap) { + onDeletePinMapButtonClick + } else { + onAddMapButtonClick + } + ), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Icon( + imageVector = if (isAddMap) ImageVector.vectorResource(id = R.drawable.ic_add_map_main400_24) else ImageVector.vectorResource(id = R.drawable.ic_add_map_gray400_24), + modifier = Modifier + .size(32.dp), + contentDescription = null, + tint = Color.Unspecified + ) + + Spacer(modifier = Modifier.height(4.dp)) + + Text( + text = addMapCount.toString(), + style = SpoonyAndroidTheme.typography.caption1m, + color = if (isAddMap) SpoonyAndroidTheme.colors.main400 else SpoonyAndroidTheme.colors.gray800 + ) + } + } else { + SpoonyButton( + text = "떠먹기", + style = ButtonStyle.Secondary, + size = ButtonSize.Medium, + onClick = onScoopButtonClick, + modifier = Modifier.weight(1f), + icon = { + Icon( + imageVector = ImageVector.vectorResource(R.drawable.ic_button_spoon_32), + modifier = Modifier.size(32.dp), + contentDescription = null, + tint = Color.Unspecified + ) + } + ) + } + } +} diff --git a/app/src/main/java/com/spoony/spoony/presentation/placeDetail/event/PlaceDetailSnackbarTrigger.kt b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/event/PlaceDetailSnackbarTrigger.kt new file mode 100644 index 00000000..c52990be --- /dev/null +++ b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/event/PlaceDetailSnackbarTrigger.kt @@ -0,0 +1,7 @@ +package com.spoony.spoony.presentation.placeDetail.event + +import androidx.compose.runtime.staticCompositionLocalOf + +val PlaceDetailLocalSnackBarTrigger = staticCompositionLocalOf<(String) -> Unit> { + error("No SnackBar provided") +} From 5fe19a47af6dd6283850e28140d3de0e77f47f0c Mon Sep 17 00:00:00 2001 From: roel <ash49901@gmail.com> Date: Wed, 22 Jan 2025 20:22:50 +0900 Subject: [PATCH 3/9] =?UTF-8?q?[FEAT/#101]=20ReportRadioButton=20text=20st?= =?UTF-8?q?yle=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spoony/presentation/report/component/ReportRadioButton.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/com/spoony/spoony/presentation/report/component/ReportRadioButton.kt b/app/src/main/java/com/spoony/spoony/presentation/report/component/ReportRadioButton.kt index 96851d57..b97d457a 100644 --- a/app/src/main/java/com/spoony/spoony/presentation/report/component/ReportRadioButton.kt +++ b/app/src/main/java/com/spoony/spoony/presentation/report/component/ReportRadioButton.kt @@ -53,6 +53,8 @@ fun ReportRadioButton( Text( text = option.text, modifier = Modifier.noRippleClickable { onOptionSelected(option) }, + style = SpoonyAndroidTheme.typography.body1m, + color = SpoonyAndroidTheme.colors.gray900, maxLines = 1, overflow = TextOverflow.Ellipsis ) From dbfa68a2e6246e9a75da935884e44c08cf526d7a Mon Sep 17 00:00:00 2001 From: roel <ash49901@gmail.com> Date: Wed, 22 Jan 2025 21:12:33 +0900 Subject: [PATCH 4/9] =?UTF-8?q?[FEAT/#101]=20=EC=8B=A0=EA=B3=A0=ED=95=98?= =?UTF-8?q?=EA=B8=B0=20QA=20=EC=88=98=EC=A0=95=EC=82=AC=ED=95=AD=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 1 + .../spoony/presentation/report/ReportRoute.kt | 25 ++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ee4d9395..9bb2802c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -20,6 +20,7 @@ android:name=".presentation.MainActivity" android:exported="true" android:label="@string/app_name" + android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.SpoonyAndroid"> <intent-filter> <action android:name="android.intent.action.MAIN" /> diff --git a/app/src/main/java/com/spoony/spoony/presentation/report/ReportRoute.kt b/app/src/main/java/com/spoony/spoony/presentation/report/ReportRoute.kt index d884578b..02db413a 100644 --- a/app/src/main/java/com/spoony/spoony/presentation/report/ReportRoute.kt +++ b/app/src/main/java/com/spoony/spoony/presentation/report/ReportRoute.kt @@ -5,8 +5,13 @@ 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.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.ime +import androidx.compose.foundation.layout.imePadding +import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState @@ -16,12 +21,14 @@ import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.vectorResource import androidx.compose.ui.tooling.preview.Preview @@ -91,11 +98,20 @@ private fun ReportScreen( onOpenDialogClick: () -> Unit ) { val focusManager = LocalFocusManager.current + val scrollState = rememberScrollState() + val imeInsets = WindowInsets.ime // 키보드 상태를 관찰 + val imeHeight = imeInsets.getBottom(LocalDensity.current) + + LaunchedEffect(imeHeight) { + if (imeHeight > 0) { + scrollState.scrollTo(scrollState.maxValue) + } + } Column( modifier = Modifier .addFocusCleaner(focusManager) - .padding(bottom = paddingValues.calculateBottomPadding()) + .navigationBarsPadding() ) { TitleTopAppBar( title = "신고하기", @@ -109,10 +125,11 @@ private fun ReportScreen( Column( modifier = Modifier - .fillMaxWidth() + .fillMaxSize() .background(color = SpoonyAndroidTheme.colors.white) .padding(horizontal = 20.dp) - .verticalScroll(rememberScrollState()) + .verticalScroll(scrollState) + .imePadding() ) { Spacer(modifier = Modifier.height(31.dp)) @@ -177,6 +194,8 @@ private fun ReportScreen( Spacer(modifier = Modifier.height(20.dp)) + Spacer(modifier = Modifier.weight(1f)) + SpoonyButton( text = "신고하기", onClick = onOpenDialogClick, From f4b87e22b913ae90823d7eebf7c1d951d158221b Mon Sep 17 00:00:00 2001 From: roel <ash49901@gmail.com> Date: Wed, 22 Jan 2025 22:35:15 +0900 Subject: [PATCH 5/9] =?UTF-8?q?[FEAT/#101]=20=5FsideEffect=20=EC=84=A0?= =?UTF-8?q?=EC=96=B8=20=EB=B0=A9=EC=8B=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spoony/presentation/placeDetail/PlaceDetailViewModel.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailViewModel.kt b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailViewModel.kt index fc5058ac..beb54a57 100644 --- a/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailViewModel.kt +++ b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailViewModel.kt @@ -26,7 +26,8 @@ class PlaceDetailViewModel @Inject constructor( get() = _state private val _sideEffect = MutableSharedFlow<PlaceDetailSideEffect>() - val sideEffect: SharedFlow<PlaceDetailSideEffect> = _sideEffect.asSharedFlow() + val sideEffect: SharedFlow<PlaceDetailSideEffect> + get() = _sideEffect init { val postArgs = savedStateHandle.toRoute<PlaceDetail>() From 0de5ca8470d45dd4478624299126d72d0c8f469d Mon Sep 17 00:00:00 2001 From: roel <ash49901@gmail.com> Date: Wed, 22 Jan 2025 22:38:58 +0900 Subject: [PATCH 6/9] =?UTF-8?q?[FEAT/#101]=20PlaceDetailSideEffect=20?= =?UTF-8?q?=EB=94=B0=EB=A1=9C=20=ED=8C=8C=EC=9D=BC=EB=A1=9C=20=EC=98=AE?= =?UTF-8?q?=EA=B9=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spoony/presentation/placeDetail/PlaceDetailSideEffect.kt | 5 +++++ .../spoony/presentation/placeDetail/PlaceDetailViewModel.kt | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailSideEffect.kt diff --git a/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailSideEffect.kt b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailSideEffect.kt new file mode 100644 index 00000000..584e24fe --- /dev/null +++ b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailSideEffect.kt @@ -0,0 +1,5 @@ +package com.spoony.spoony.presentation.placeDetail + +sealed class PlaceDetailSideEffect { + data class ShowSnackbar(val message: String) : PlaceDetailSideEffect() +} diff --git a/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailViewModel.kt b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailViewModel.kt index beb54a57..645fa81d 100644 --- a/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailViewModel.kt +++ b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailViewModel.kt @@ -13,7 +13,6 @@ import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.launch @HiltViewModel @@ -120,7 +119,3 @@ class PlaceDetailViewModel @Inject constructor( } } } - -sealed class PlaceDetailSideEffect { - data class ShowSnackbar(val message: String) : PlaceDetailSideEffect() -} From d99aa38370118e5254d6759130858f3409b4e65c Mon Sep 17 00:00:00 2001 From: roel <ash49901@gmail.com> Date: Wed, 22 Jan 2025 22:41:49 +0900 Subject: [PATCH 7/9] =?UTF-8?q?[FEAT/#101]=20=EC=BD=94=EB=93=9C=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EC=88=98=EC=A0=95=EC=82=AC=ED=95=AD=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 --- .../spoony/presentation/placeDetail/PlaceDetailRoute.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailRoute.kt b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailRoute.kt index 982ffb73..37f63459 100644 --- a/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailRoute.kt +++ b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailRoute.kt @@ -221,10 +221,7 @@ private fun PlaceDetailScreen( Column( modifier = Modifier .fillMaxSize() - .padding( - top = paddingValues.calculateTopPadding(), - bottom = paddingValues.calculateBottomPadding() - ) + .padding(paddingValues) .verticalScroll(scrollState) ) { Row( From bea047be978c7901f08a1069a69e28f81f759694 Mon Sep 17 00:00:00 2001 From: roel <ash49901@gmail.com> Date: Wed, 22 Jan 2025 22:44:02 +0900 Subject: [PATCH 8/9] =?UTF-8?q?[FEAT/#101]=20=ED=95=84=EC=9A=94=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../placeDetail/PlaceDetailRoute.kt | 114 +++++++++--------- .../event/PlaceDetailSnackbarTrigger.kt | 7 -- 2 files changed, 54 insertions(+), 67 deletions(-) delete mode 100644 app/src/main/java/com/spoony/spoony/presentation/placeDetail/event/PlaceDetailSnackbarTrigger.kt diff --git a/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailRoute.kt b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailRoute.kt index 37f63459..c3852122 100644 --- a/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailRoute.kt +++ b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/PlaceDetailRoute.kt @@ -21,7 +21,6 @@ import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -54,7 +53,6 @@ import com.spoony.spoony.presentation.placeDetail.component.PlaceDetailImageLazy import com.spoony.spoony.presentation.placeDetail.component.ScoopDialog import com.spoony.spoony.presentation.placeDetail.component.StoreInfo import com.spoony.spoony.presentation.placeDetail.component.UserProfileInfo -import com.spoony.spoony.presentation.placeDetail.event.PlaceDetailLocalSnackBarTrigger import com.spoony.spoony.presentation.placeDetail.type.DropdownOption import kotlinx.collections.immutable.ImmutableList import kotlinx.coroutines.delay @@ -135,65 +133,61 @@ fun PlaceDetailRoute( is UiState.Failure -> {} is UiState.Success -> { with(state.postEntity as UiState.Success<PostEntity>) { - CompositionLocalProvider( - PlaceDetailLocalSnackBarTrigger provides onShowSnackBar - ) { - Scaffold( - snackbarHost = { - SnackbarHost(hostState = snackBarHostState) { snackbarData -> - TextSnackbar(text = snackbarData.visuals.message) - } - }, - topBar = { - TagTopAppBar( - count = spoonAmount, - showBackButton = true, - onBackButtonClick = navigateUp - ) - }, - bottomBar = { - PlaceDetailBottomBar( - modifier = Modifier - .navigationBarsPadding(), - addMapCount = data.addMapCount, - isScooped = data.isScooped, - isAddMap = data.isAddMap, - onScoopButtonClick = { - scoopDialogVisibility = true - }, - onSearchMapClick = { - searchPlaceNaverMap( - latitude = data.latitude, - longitude = data.longitude, - placeName = data.placeName, - context = context - ) - }, - onAddMapButtonClick = { viewModel.addMyMap(postId, userId) }, - onDeletePinMapButtonClick = { viewModel.deletePinMap(postId, userId) } - ) - }, - content = { paddingValues -> - PlaceDetailScreen( - paddingValues = paddingValues, - menuList = data.menuList, - title = data.title, - description = data.description, - userProfileUrl = userProfile.userProfileUrl, - userName = userProfile.userName, - userRegion = userProfile.userRegion, - photoUrlList = data.photoUrlList, - category = data.category, - date = data.date, - placeAddress = data.placeAddress, - placeName = data.placeName, - isScooped = data.isScooped, - dropdownMenuList = state.dropDownMenuList, - onReportButtonClick = navigateToReport - ) + Scaffold( + snackbarHost = { + SnackbarHost(hostState = snackBarHostState) { snackbarData -> + TextSnackbar(text = snackbarData.visuals.message) } - ) - } + }, + topBar = { + TagTopAppBar( + count = spoonAmount, + showBackButton = true, + onBackButtonClick = navigateUp + ) + }, + bottomBar = { + PlaceDetailBottomBar( + modifier = Modifier + .navigationBarsPadding(), + addMapCount = data.addMapCount, + isScooped = data.isScooped, + isAddMap = data.isAddMap, + onScoopButtonClick = { + scoopDialogVisibility = true + }, + onSearchMapClick = { + searchPlaceNaverMap( + latitude = data.latitude, + longitude = data.longitude, + placeName = data.placeName, + context = context + ) + }, + onAddMapButtonClick = { viewModel.addMyMap(postId, userId) }, + onDeletePinMapButtonClick = { viewModel.deletePinMap(postId, userId) } + ) + }, + content = { paddingValues -> + PlaceDetailScreen( + paddingValues = paddingValues, + menuList = data.menuList, + title = data.title, + description = data.description, + userProfileUrl = userProfile.userProfileUrl, + userName = userProfile.userName, + userRegion = userProfile.userRegion, + photoUrlList = data.photoUrlList, + category = data.category, + date = data.date, + placeAddress = data.placeAddress, + placeName = data.placeName, + isScooped = data.isScooped, + dropdownMenuList = state.dropDownMenuList, + onReportButtonClick = navigateToReport + ) + } + ) } } } diff --git a/app/src/main/java/com/spoony/spoony/presentation/placeDetail/event/PlaceDetailSnackbarTrigger.kt b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/event/PlaceDetailSnackbarTrigger.kt deleted file mode 100644 index c52990be..00000000 --- a/app/src/main/java/com/spoony/spoony/presentation/placeDetail/event/PlaceDetailSnackbarTrigger.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.spoony.spoony.presentation.placeDetail.event - -import androidx.compose.runtime.staticCompositionLocalOf - -val PlaceDetailLocalSnackBarTrigger = staticCompositionLocalOf<(String) -> Unit> { - error("No SnackBar provided") -} From 271268cdc257209815836717a6f47aa5027082b4 Mon Sep 17 00:00:00 2001 From: roel <ash49901@gmail.com> Date: Wed, 22 Jan 2025 22:45:50 +0900 Subject: [PATCH 9/9] =?UTF-8?q?[FEAT/#101]=20=EC=BD=94=EB=93=9C=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EC=88=98=EC=A0=95=EC=82=AC=ED=95=AD=20=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/placeDetail/component/PlaceDetailBottomBar.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/spoony/spoony/presentation/placeDetail/component/PlaceDetailBottomBar.kt b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/component/PlaceDetailBottomBar.kt index 3a83bd1d..f1528946 100644 --- a/app/src/main/java/com/spoony/spoony/presentation/placeDetail/component/PlaceDetailBottomBar.kt +++ b/app/src/main/java/com/spoony/spoony/presentation/placeDetail/component/PlaceDetailBottomBar.kt @@ -77,7 +77,7 @@ fun PlaceDetailBottomBar( horizontalAlignment = Alignment.CenterHorizontally ) { Icon( - imageVector = if (isAddMap) ImageVector.vectorResource(id = R.drawable.ic_add_map_main400_24) else ImageVector.vectorResource(id = R.drawable.ic_add_map_gray400_24), + imageVector = ImageVector.vectorResource(id = if (isAddMap) R.drawable.ic_add_map_main400_24 else R.drawable.ic_add_map_gray400_24), modifier = Modifier .size(32.dp), contentDescription = null,