From 5caa3ac37d26020cf32b41ddf9f09172370f9771 Mon Sep 17 00:00:00 2001 From: JI HUN LEE <51016231+easyhooon@users.noreply.github.com> Date: Thu, 11 Apr 2024 15:57:58 +0900 Subject: [PATCH 01/16] =?UTF-8?q?[fix]=20[#55]=20TextField=20=ED=82=A4?= =?UTF-8?q?=EB=B3=B4=EB=93=9C=EA=B0=80=20=ED=95=9C=EB=B2=88=20=EB=82=B4?= =?UTF-8?q?=EB=A0=A4=EA=B0=94=EC=9D=84=20=EB=95=8C,=20=EB=8B=A4=EC=8B=9C?= =?UTF-8?q?=20=ED=82=A4=EB=B3=B4=EB=93=9C=EA=B0=80=20=EC=98=AC=EB=9D=BC?= =?UTF-8?q?=EC=98=A4=EC=A7=80=20=EC=95=8A=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 --- .../kotlin/AndroidFeatureConventionPlugin.kt | 1 + .../kotlin/com/unifest/android/Compose.kt | 1 - .../designsystem/component/SearchTextField.kt | 39 +++++++++++-------- .../ui/component/FestivalSearchBottomSheet.kt | 9 +++-- .../android/feature/intro/IntroScreen.kt | 6 ++- .../feature/intro/viewmodel/IntroUiState.kt | 6 +-- .../feature/intro/viewmodel/IntroViewModel.kt | 12 ++++-- .../unifest/android/feature/map/MapScreen.kt | 19 +++++++-- .../feature/map/viewmodel/MapUiState.kt | 8 ++-- .../feature/map/viewmodel/MapViewModel.kt | 18 +++++++-- gradle/libs.versions.toml | 4 +- 11 files changed, 78 insertions(+), 45 deletions(-) diff --git a/build-logic/src/main/kotlin/AndroidFeatureConventionPlugin.kt b/build-logic/src/main/kotlin/AndroidFeatureConventionPlugin.kt index e3a626b4..c6bf2385 100644 --- a/build-logic/src/main/kotlin/AndroidFeatureConventionPlugin.kt +++ b/build-logic/src/main/kotlin/AndroidFeatureConventionPlugin.kt @@ -19,6 +19,7 @@ internal class AndroidFeatureConventionPlugin : BuildLogicConventionPlugin( implementation(project(path = ":core:ui")) implementation(project(path = ":feature:navigator")) + implementation(libs.androidx.navigation.compose) implementation(libs.androidx.hilt.navigation.compose) implementation(libs.bundles.androidx.lifecycle) } diff --git a/build-logic/src/main/kotlin/com/unifest/android/Compose.kt b/build-logic/src/main/kotlin/com/unifest/android/Compose.kt index 5758c83b..33e26d02 100644 --- a/build-logic/src/main/kotlin/com/unifest/android/Compose.kt +++ b/build-logic/src/main/kotlin/com/unifest/android/Compose.kt @@ -24,7 +24,6 @@ internal fun Project.configureCompose(extension: CommonExtension<*, *, *, *, *>) implementation(libs.androidx.compose.ui) implementation(libs.androidx.compose.ui.tooling.preview) debugImplementation(libs.androidx.compose.ui.tooling) - implementation(libs.androidx.navigation.compose) } } diff --git a/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/SearchTextField.kt b/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/SearchTextField.kt index ac28a1d8..2122319b 100644 --- a/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/SearchTextField.kt +++ b/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/SearchTextField.kt @@ -14,9 +14,8 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.foundation.text2.BasicTextField2 -import androidx.compose.foundation.text2.input.TextFieldState import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -29,16 +28,17 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.unit.dp import com.unifest.android.core.designsystem.ComponentPreview import com.unifest.android.core.designsystem.R import com.unifest.android.core.designsystem.theme.BoothLocation import com.unifest.android.core.designsystem.theme.UnifestTheme -@OptIn(ExperimentalFoundationApi::class) @Composable fun SearchTextField( - searchText: TextFieldState, + searchText: TextFieldValue, + updateSearchText: (TextFieldValue) -> Unit, @StringRes searchTextHintRes: Int, onSearch: (String) -> Unit, initSearchText: () -> Unit, @@ -47,12 +47,13 @@ fun SearchTextField( cornerShape: RoundedCornerShape = RoundedCornerShape(67.dp), borderStroke: BorderStroke = BorderStroke(width = 1.dp, color = Color(0xFFBABABA)), ) { - BasicTextField2( - state = searchText, + BasicTextField( + value = searchText, + onValueChange = updateSearchText, modifier = Modifier.fillMaxWidth(), - keyboardOptions = KeyboardOptions.Default.copy(imeAction = ImeAction.Search), + keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search), textStyle = TextStyle(color = Color.Black), - decorator = { innerTextField -> + decorationBox = { innerTextField -> Row( modifier = modifier .background(color = backgroundColor, shape = cornerShape) @@ -79,7 +80,7 @@ fun SearchTextField( imageVector = ImageVector.vectorResource(R.drawable.ic_search), contentDescription = "Search Icon", modifier = Modifier.clickable { - onSearch(searchText.text.toString()) + onSearch(searchText.text) }, ) } else { @@ -102,7 +103,8 @@ fun SearchTextField( @OptIn(ExperimentalFoundationApi::class) @Composable fun FestivalSearchTextField( - searchText: TextFieldState, + searchText: TextFieldValue, + updateSearchText: (TextFieldValue) -> Unit, @StringRes searchTextHintRes: Int, onSearch: (String) -> Unit, initSearchText: () -> Unit, @@ -117,12 +119,13 @@ fun FestivalSearchTextField( setEnableSearchMode(searchText.text.isNotEmpty()) } - BasicTextField2( - state = searchText, + BasicTextField( + value = searchText, + onValueChange = updateSearchText, modifier = Modifier.fillMaxWidth(), - keyboardOptions = KeyboardOptions.Default.copy(imeAction = ImeAction.Search), + keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search), textStyle = TextStyle(color = Color.Black), - decorator = { innerTextField -> + decorationBox = { innerTextField -> Row( modifier = modifier .background(color = backgroundColor, shape = cornerShape) @@ -160,7 +163,7 @@ fun FestivalSearchTextField( imageVector = ImageVector.vectorResource(R.drawable.ic_search), contentDescription = "Search Icon", modifier = Modifier.clickable { - onSearch(searchText.text.toString()) + onSearch(searchText.text) }, ) } else { @@ -185,7 +188,8 @@ fun FestivalSearchTextField( fun SearchTextFieldPreview() { UnifestTheme { SearchTextField( - searchText = TextFieldState(""), + searchText = TextFieldValue(), + updateSearchText = {}, searchTextHintRes = R.string.intro_search_text_hint, onSearch = {}, initSearchText = {}, @@ -203,7 +207,8 @@ fun SearchTextFieldPreview() { fun FestivalSearchTextFieldPreview() { UnifestTheme { FestivalSearchTextField( - searchText = TextFieldState("건국대학교"), + searchText = TextFieldValue("건국대학교"), + updateSearchText = {}, searchTextHintRes = R.string.intro_search_text_hint, onSearch = {}, initSearchText = {}, diff --git a/core/ui/src/main/kotlin/com/unifest/android/core/ui/component/FestivalSearchBottomSheet.kt b/core/ui/src/main/kotlin/com/unifest/android/core/ui/component/FestivalSearchBottomSheet.kt index 737c4581..aae7c46c 100644 --- a/core/ui/src/main/kotlin/com/unifest/android/core/ui/component/FestivalSearchBottomSheet.kt +++ b/core/ui/src/main/kotlin/com/unifest/android/core/ui/component/FestivalSearchBottomSheet.kt @@ -12,7 +12,6 @@ import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.text2.input.TextFieldState import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.VerticalDivider @@ -24,6 +23,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.unit.dp import com.skydoves.flexible.bottomsheet.material3.FlexibleBottomSheet import com.skydoves.flexible.core.FlexibleSheetSize @@ -43,7 +43,8 @@ import kotlinx.collections.immutable.persistentListOf fun FestivalSearchBottomSheet( @StringRes searchTextHintRes: Int, setFestivalSearchBottomSheetVisible: (Boolean) -> Unit, - searchText: TextFieldState, + searchText: TextFieldValue, + updateSearchText: (TextFieldValue) -> Unit, interestedFestivals: MutableList, festivalSearchResults: ImmutableList, initSearchText: () -> Unit, @@ -105,6 +106,7 @@ fun FestivalSearchBottomSheet( Spacer(modifier = Modifier.height(24.dp)) FestivalSearchTextField( searchText = searchText, + updateSearchText = updateSearchText, searchTextHintRes = searchTextHintRes, onSearch = {}, initSearchText = initSearchText, @@ -169,7 +171,8 @@ fun SchoolSearchBottomSheetPreview() { FestivalSearchBottomSheet( searchTextHintRes = R.string.festival_search_text_field_hint, setFestivalSearchBottomSheetVisible = {}, - searchText = TextFieldState(), + searchText = TextFieldValue(), + updateSearchText = {}, interestedFestivals = mutableListOf( Festival("https://picsum.photos/36", "서울대학교", "설대축제", "05.06-05.08"), Festival("https://picsum.photos/36", "연세대학교", "연대축제", "05.06-05.08"), diff --git a/feature/intro/src/main/kotlin/com/unifest/android/feature/intro/IntroScreen.kt b/feature/intro/src/main/kotlin/com/unifest/android/feature/intro/IntroScreen.kt index 475646ea..a75e31a7 100644 --- a/feature/intro/src/main/kotlin/com/unifest/android/feature/intro/IntroScreen.kt +++ b/feature/intro/src/main/kotlin/com/unifest/android/feature/intro/IntroScreen.kt @@ -31,6 +31,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -65,15 +66,16 @@ internal fun IntroRoute( IntroScreen( uiState = uiState, navigateToMain = navigateToMain, + updateSearchText = viewModel::updateSearchText, initSearchText = viewModel::initSearchText, ) } -@OptIn(ExperimentalFoundationApi::class) @Composable fun IntroScreen( uiState: IntroUiState, navigateToMain: () -> Unit, + updateSearchText: (TextFieldValue) -> Unit, initSearchText: () -> Unit, ) { val selectedFestivals = remember { mutableStateListOf() } @@ -92,6 +94,7 @@ fun IntroScreen( InformationText() SearchTextField( searchText = uiState.searchText, + updateSearchText = updateSearchText, searchTextHintRes = R.string.intro_search_text_hint, onSearch = { query -> Timber.d("검색: $query") }, initSearchText = initSearchText, @@ -253,6 +256,7 @@ fun PreviewIntroScreen() { ), ), navigateToMain = {}, + updateSearchText = {}, initSearchText = {}, ) } diff --git a/feature/intro/src/main/kotlin/com/unifest/android/feature/intro/viewmodel/IntroUiState.kt b/feature/intro/src/main/kotlin/com/unifest/android/feature/intro/viewmodel/IntroUiState.kt index ed349e39..3466140d 100644 --- a/feature/intro/src/main/kotlin/com/unifest/android/feature/intro/viewmodel/IntroUiState.kt +++ b/feature/intro/src/main/kotlin/com/unifest/android/feature/intro/viewmodel/IntroUiState.kt @@ -1,13 +1,11 @@ package com.unifest.android.feature.intro.viewmodel -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.text2.input.TextFieldState +import androidx.compose.ui.text.input.TextFieldValue import com.unifest.android.core.domain.entity.Festival import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf -@OptIn(ExperimentalFoundationApi::class) data class IntroUiState( - val searchText: TextFieldState = TextFieldState(""), + val searchText: TextFieldValue = TextFieldValue(), val schools: ImmutableList = persistentListOf(), ) diff --git a/feature/intro/src/main/kotlin/com/unifest/android/feature/intro/viewmodel/IntroViewModel.kt b/feature/intro/src/main/kotlin/com/unifest/android/feature/intro/viewmodel/IntroViewModel.kt index e252caf7..6ed60d1a 100644 --- a/feature/intro/src/main/kotlin/com/unifest/android/feature/intro/viewmodel/IntroViewModel.kt +++ b/feature/intro/src/main/kotlin/com/unifest/android/feature/intro/viewmodel/IntroViewModel.kt @@ -1,7 +1,6 @@ package com.unifest.android.feature.intro.viewmodel -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.text2.input.TextFieldState +import androidx.compose.ui.text.input.TextFieldValue import androidx.lifecycle.ViewModel import com.unifest.android.core.domain.entity.Festival import dagger.hilt.android.lifecycle.HiltViewModel @@ -12,7 +11,6 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import javax.inject.Inject -@OptIn(ExperimentalFoundationApi::class) @HiltViewModel class IntroViewModel @Inject constructor() : ViewModel() { private val _uiState = MutableStateFlow(IntroUiState()) @@ -32,9 +30,15 @@ class IntroViewModel @Inject constructor() : ViewModel() { } } + fun updateSearchText(text: TextFieldValue) { + _uiState.update { + it.copy(searchText = text) + } + } + fun initSearchText() { _uiState.update { - it.copy(searchText = TextFieldState("")) + it.copy(searchText = TextFieldValue()) } } } diff --git a/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt b/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt index aef1c5b0..b9b2e3a8 100644 --- a/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt +++ b/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt @@ -16,13 +16,13 @@ import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.PagerState import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.text2.input.TextFieldState import androidx.compose.material3.Card import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -63,6 +63,8 @@ internal fun MapRoute( uiState = uiState, onNavigateToBooth = onNavigateToBooth, setFestivalSearchBottomSheetVisible = viewModel::setFestivalSearchBottomSheetVisible, + updateBoothSearchText = viewModel::updateBoothSearchText, + updateFestivalSearchText = viewModel::updateFestivalSearchText, initSearchText = viewModel::initSearchText, setEnableSearchMode = viewModel::setEnableSearchMode, setEnableEditMode = viewModel::setEnableEditMode, @@ -79,6 +81,8 @@ internal fun MapScreen( uiState: MapUiState, onNavigateToBooth: (Long) -> Unit, setFestivalSearchBottomSheetVisible: (Boolean) -> Unit, + updateBoothSearchText: (TextFieldValue) -> Unit, + updateFestivalSearchText: (TextFieldValue) -> Unit, initSearchText: () -> Unit, setEnableSearchMode: (Boolean) -> Unit, setEnableEditMode: () -> Unit, @@ -112,6 +116,7 @@ internal fun MapScreen( MapTopAppBar( title = uiState.selectedSchoolName, searchText = uiState.boothSearchText, + updateSearchText = updateBoothSearchText, onTitleClick = setFestivalSearchBottomSheetVisible, initSearchText = initSearchText, modifier = Modifier @@ -128,11 +133,12 @@ internal fun MapScreen( ) if (uiState.isFestivalSearchBottomSheetVisible) { FestivalSearchBottomSheet( + searchText = uiState.festivalSearchText, + updateSearchText = updateFestivalSearchText, searchTextHintRes = R.string.festival_search_text_field_hint, setFestivalSearchBottomSheetVisible = setFestivalSearchBottomSheetVisible, interestedFestivals = uiState.interestedFestivals, festivalSearchResults = uiState.festivalSearchResults, - searchText = uiState.festivalSearchText, initSearchText = initSearchText, setEnableSearchMode = setEnableSearchMode, isSearchMode = uiState.isSearchMode, @@ -150,7 +156,8 @@ internal fun MapScreen( @Composable fun MapTopAppBar( title: String, - searchText: TextFieldState, + searchText: TextFieldValue, + updateSearchText: (TextFieldValue) -> Unit, onTitleClick: (Boolean) -> Unit, initSearchText: () -> Unit, modifier: Modifier = Modifier, @@ -172,6 +179,7 @@ fun MapTopAppBar( ) SearchTextField( searchText = searchText, + updateSearchText = updateSearchText, searchTextHintRes = R.string.map_booth_search_text_field_hint, onSearch = {}, initSearchText = initSearchText, @@ -246,6 +254,8 @@ fun MapScreenPreview() { ), onNavigateToBooth = {}, setFestivalSearchBottomSheetVisible = {}, + updateBoothSearchText = {}, + updateFestivalSearchText = {}, initSearchText = {}, setEnableSearchMode = {}, setEnableEditMode = {}, @@ -261,7 +271,8 @@ fun MapTopAppBarPreview() { UnifestTheme { MapTopAppBar( title = "건국대학교", - searchText = TextFieldState(), + searchText = TextFieldValue(), + updateSearchText = {}, initSearchText = {}, onTitleClick = {}, ) diff --git a/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapUiState.kt b/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapUiState.kt index ca44a533..28bfd673 100644 --- a/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapUiState.kt +++ b/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapUiState.kt @@ -1,18 +1,16 @@ package com.unifest.android.feature.map.viewmodel -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.text2.input.TextFieldState +import androidx.compose.ui.text.input.TextFieldValue import com.unifest.android.core.domain.entity.BoothDetailEntity import com.unifest.android.core.domain.entity.BoothSpot import com.unifest.android.core.domain.entity.Festival import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf -@OptIn(ExperimentalFoundationApi::class) data class MapUiState( val selectedSchoolName: String = "", - val boothSearchText: TextFieldState = TextFieldState(""), - val festivalSearchText: TextFieldState = TextFieldState(""), + val boothSearchText: TextFieldValue = TextFieldValue(), + val festivalSearchText: TextFieldValue = TextFieldValue(), val boothSpots: ImmutableList = persistentListOf(), val boothList: ImmutableList = persistentListOf(), val isFestivalSearchBottomSheetVisible: Boolean = false, diff --git a/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt b/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt index 5849b373..d70523ed 100644 --- a/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt +++ b/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt @@ -1,7 +1,6 @@ package com.unifest.android.feature.map.viewmodel -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.text2.input.TextFieldState +import androidx.compose.ui.text.input.TextFieldValue import androidx.lifecycle.ViewModel import com.unifest.android.core.domain.entity.BoothDetailEntity import com.unifest.android.core.domain.entity.BoothSpot @@ -15,7 +14,6 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import javax.inject.Inject -@OptIn(ExperimentalFoundationApi::class) @HiltViewModel class MapViewModel @Inject constructor() : ViewModel() { private val _uiState = MutableStateFlow(MapUiState()) @@ -71,9 +69,21 @@ class MapViewModel @Inject constructor() : ViewModel() { } } + fun updateBoothSearchText(text: TextFieldValue) { + _uiState.update { + it.copy(boothSearchText = text) + } + } + + fun updateFestivalSearchText(text: TextFieldValue) { + _uiState.update { + it.copy(festivalSearchText = text) + } + } + fun initSearchText() { _uiState.update { - it.copy(festivalSearchText = TextFieldState("")) + it.copy(festivalSearchText = TextFieldValue()) } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1a112b8d..e732fcb8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -20,7 +20,7 @@ kotlinx-serialization-converter = "1.0.0" kotlinx-collections-immutable = "0.3.7" androidx-core = "1.12.0" -androidx-lifecycle = "2.8.0-alpha04" +androidx-lifecycle = "2.8.0-alpha02" androidx-splash = "1.0.1" androidx-startup = "1.1.1" androidx-navigation = "2.7.7" @@ -28,6 +28,7 @@ androidx-datastore = "1.0.0" androidx-activity-compose = "1.8.2" androidx-compose-compiler = "1.5.11" androidx-compose-bom = "2024.04.00" +#androidx-compose-foundation = "1.7.0-alpha06" androidx-compose-material3 = "1.2.1" androidx-hilt-navigation-compose = "1.2.0" @@ -83,7 +84,6 @@ androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "l androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "androidx-compose-bom" } androidx-compose-foundation = { group = "androidx.compose.foundation", name = "foundation" } -androidx-compose-foundation-layout = { group = "androidx.compose.foundation", name = "foundation-layout" } androidx-compose-material-iconsExtended = { group = "androidx.compose.material", name = "material-icons-extended" } androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3", version.ref = "androidx-compose-material3" } androidx-compose-material3-windowSizeClass = { group = "androidx.compose.material3", name = "material3-window-size-class" } From 3d985e2cdcb2152e8838b3a6828688ec20da3c3a Mon Sep 17 00:00:00 2001 From: JI HUN LEE <51016231+easyhooon@users.noreply.github.com> Date: Thu, 11 Apr 2024 16:09:33 +0900 Subject: [PATCH 02/16] =?UTF-8?q?[style]=20TextFieldSelectionColor=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 기본 Material3 색상에서 앱에서 사용하는 색상으로 변경 --- .../designsystem/component/SearchTextField.kt | 224 +++++++++--------- 1 file changed, 116 insertions(+), 108 deletions(-) diff --git a/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/SearchTextField.kt b/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/SearchTextField.kt index 2122319b..56de2c9a 100644 --- a/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/SearchTextField.kt +++ b/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/SearchTextField.kt @@ -2,7 +2,6 @@ package com.unifest.android.core.designsystem.component import androidx.annotation.StringRes import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable @@ -16,9 +15,12 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.text.selection.LocalTextSelectionColors +import androidx.compose.foundation.text.selection.TextSelectionColors import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -35,6 +37,11 @@ import com.unifest.android.core.designsystem.R import com.unifest.android.core.designsystem.theme.BoothLocation import com.unifest.android.core.designsystem.theme.UnifestTheme +val unifestTextSelectionColors = TextSelectionColors( + handleColor = Color(0xFFF5687E), + backgroundColor = Color(0xFFFAB3BE) +) + @Composable fun SearchTextField( searchText: TextFieldValue, @@ -47,60 +54,61 @@ fun SearchTextField( cornerShape: RoundedCornerShape = RoundedCornerShape(67.dp), borderStroke: BorderStroke = BorderStroke(width = 1.dp, color = Color(0xFFBABABA)), ) { - BasicTextField( - value = searchText, - onValueChange = updateSearchText, - modifier = Modifier.fillMaxWidth(), - keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search), - textStyle = TextStyle(color = Color.Black), - decorationBox = { innerTextField -> - Row( - modifier = modifier - .background(color = backgroundColor, shape = cornerShape) - .border( - border = borderStroke, - shape = cornerShape, - ), - verticalAlignment = Alignment.CenterVertically, - ) { - Spacer(modifier = Modifier.width(17.dp)) - Box { + CompositionLocalProvider(LocalTextSelectionColors provides unifestTextSelectionColors) { + BasicTextField( + value = searchText, + onValueChange = updateSearchText, + modifier = Modifier.fillMaxWidth(), + keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search), + textStyle = TextStyle(color = Color.Black), + decorationBox = { innerTextField -> + Row( + modifier = modifier + .background(color = backgroundColor, shape = cornerShape) + .border( + border = borderStroke, + shape = cornerShape, + ), + verticalAlignment = Alignment.CenterVertically, + ) { + Spacer(modifier = Modifier.width(17.dp)) + Box { + if (searchText.text.isEmpty()) { + Text( + text = stringResource(id = searchTextHintRes), + color = Color(0xFF848484), + style = BoothLocation, + ) + } + innerTextField() + } + Spacer(modifier = Modifier.weight(1f)) if (searchText.text.isEmpty()) { - Text( - text = stringResource(id = searchTextHintRes), - color = Color(0xFF848484), - style = BoothLocation, + Icon( + imageVector = ImageVector.vectorResource(R.drawable.ic_search), + contentDescription = "Search Icon", + modifier = Modifier.clickable { + onSearch(searchText.text) + }, + ) + } else { + Icon( + imageVector = ImageVector.vectorResource(R.drawable.ic_delete_gray), + contentDescription = "Delete Icon", + tint = Color.Unspecified, + modifier = Modifier + .clickable { + initSearchText() + }, ) } - innerTextField() + Spacer(modifier = Modifier.width(width = 15.dp)) } - Spacer(modifier = Modifier.weight(1f)) - if (searchText.text.isEmpty()) { - Icon( - imageVector = ImageVector.vectorResource(R.drawable.ic_search), - contentDescription = "Search Icon", - modifier = Modifier.clickable { - onSearch(searchText.text) - }, - ) - } else { - Icon( - imageVector = ImageVector.vectorResource(R.drawable.ic_delete_gray), - contentDescription = "Delete Icon", - tint = Color.Unspecified, - modifier = Modifier - .clickable { - initSearchText() - }, - ) - } - Spacer(modifier = Modifier.width(width = 15.dp)) - } - }, - ) + }, + ) + } } -@OptIn(ExperimentalFoundationApi::class) @Composable fun FestivalSearchTextField( searchText: TextFieldValue, @@ -119,70 +127,71 @@ fun FestivalSearchTextField( setEnableSearchMode(searchText.text.isNotEmpty()) } - BasicTextField( - value = searchText, - onValueChange = updateSearchText, - modifier = Modifier.fillMaxWidth(), - keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search), - textStyle = TextStyle(color = Color.Black), - decorationBox = { innerTextField -> - Row( - modifier = modifier - .background(color = backgroundColor, shape = cornerShape) - .border( - border = borderStroke, - shape = cornerShape, - ), - verticalAlignment = Alignment.CenterVertically, - ) { - Spacer(modifier = Modifier.width(14.dp)) - if (isSearchMode) { - Icon( - imageVector = ImageVector.vectorResource(R.drawable.ic_arrow_back_dark_gray), - contentDescription = "Search Icon", - tint = Color(0xFF767676), - modifier = Modifier.clickable { - initSearchText() - }, - ) - } - Spacer(modifier = Modifier.width(12.dp)) - Box { + CompositionLocalProvider(LocalTextSelectionColors provides unifestTextSelectionColors) { + BasicTextField( + value = searchText, + onValueChange = updateSearchText, + modifier = Modifier.fillMaxWidth(), + keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search), + textStyle = TextStyle(color = Color.Black), + decorationBox = { innerTextField -> + Row( + modifier = modifier + .background(color = backgroundColor, shape = cornerShape) + .border( + border = borderStroke, + shape = cornerShape, + ), + verticalAlignment = Alignment.CenterVertically, + ) { + Spacer(modifier = Modifier.width(14.dp)) + if (isSearchMode) { + Icon( + imageVector = ImageVector.vectorResource(R.drawable.ic_arrow_back_dark_gray), + contentDescription = "Search Icon", + tint = Color(0xFF767676), + modifier = Modifier.clickable { + initSearchText() + }, + ) + } + Spacer(modifier = Modifier.width(12.dp)) + Box { + if (searchText.text.isEmpty()) { + Text( + text = stringResource(id = searchTextHintRes), + color = Color(0xFF848484), + style = BoothLocation, + ) + } + innerTextField() + } + Spacer(modifier = Modifier.weight(1f)) if (searchText.text.isEmpty()) { - Text( - text = stringResource(id = searchTextHintRes), - color = Color(0xFF848484), - style = BoothLocation, + Icon( + imageVector = ImageVector.vectorResource(R.drawable.ic_search), + contentDescription = "Search Icon", + modifier = Modifier.clickable { + onSearch(searchText.text) + }, + ) + } else { + Icon( + imageVector = ImageVector.vectorResource(R.drawable.ic_delete_gray), + contentDescription = "Delete Icon", + tint = Color.Unspecified, + modifier = Modifier.clickable { + initSearchText() + }, ) } - innerTextField() - } - Spacer(modifier = Modifier.weight(1f)) - if (searchText.text.isEmpty()) { - Icon( - imageVector = ImageVector.vectorResource(R.drawable.ic_search), - contentDescription = "Search Icon", - modifier = Modifier.clickable { - onSearch(searchText.text) - }, - ) - } else { - Icon( - imageVector = ImageVector.vectorResource(R.drawable.ic_delete_gray), - contentDescription = "Delete Icon", - tint = Color.Unspecified, - modifier = Modifier.clickable { - initSearchText() - }, - ) + Spacer(modifier = Modifier.width(width = 15.dp)) } - Spacer(modifier = Modifier.width(width = 15.dp)) - } - }, - ) + }, + ) + } } -@OptIn(ExperimentalFoundationApi::class) @ComponentPreview @Composable fun SearchTextFieldPreview() { @@ -201,7 +210,6 @@ fun SearchTextFieldPreview() { } } -@OptIn(ExperimentalFoundationApi::class) @ComponentPreview @Composable fun FestivalSearchTextFieldPreview() { From 9554eb0e2595ca9a3df55d9445eb11144a50f0cb Mon Sep 17 00:00:00 2001 From: JI HUN LEE <51016231+easyhooon@users.noreply.github.com> Date: Thu, 11 Apr 2024 16:47:10 +0900 Subject: [PATCH 03/16] =?UTF-8?q?[fix]=20=EB=B6=80=EC=8A=A4=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=ED=99=94=EB=A9=B4=EC=97=90=20=EC=A7=84=EC=9E=85=20?= =?UTF-8?q?=ED=9B=84=20=EB=AA=A8=EB=93=A0=20=ED=99=94=EB=A9=B4=EC=97=90=20?= =?UTF-8?q?status=20bar=20=EC=98=81=EC=97=AD=EC=9D=98=20icon=20=EC=9D=B4?= =?UTF-8?q?=20=EB=B3=B4=EC=9D=B4=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=9D=B4?= =?UTF-8?q?=EC=8A=88=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- feature/map/build.gradle.kts | 1 + .../com/unifest/android/feature/map/MapScreen.kt | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/feature/map/build.gradle.kts b/feature/map/build.gradle.kts index e8f60bef..497bfc96 100644 --- a/feature/map/build.gradle.kts +++ b/feature/map/build.gradle.kts @@ -14,6 +14,7 @@ dependencies { libs.kotlinx.collections.immutable, libs.androidx.core, libs.timber, + libs.compose.system.ui.controller, libs.bundles.naver.map.compose, ) diff --git a/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt b/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt index b9b2e3a8..df9ddf3f 100644 --- a/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt +++ b/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt @@ -18,6 +18,7 @@ import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Card import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -51,6 +52,7 @@ import com.unifest.android.feature.map.viewmodel.MapViewModel import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList +import tech.thdev.compose.exteions.system.ui.controller.rememberExSystemUiController @Composable internal fun MapRoute( @@ -58,6 +60,16 @@ internal fun MapRoute( viewModel: MapViewModel = hiltViewModel(), ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() + val systemUiController = rememberExSystemUiController() + + DisposableEffect(systemUiController) { + systemUiController.setSystemBarsColor( + color = Color.White, + darkIcons = true, + isNavigationBarContrastEnforced = false, + ) + onDispose {} + } MapScreen( uiState = uiState, From a22bc99bb734743c858029977fb10fc3ef2ddcc1 Mon Sep 17 00:00:00 2001 From: JI HUN LEE <51016231+easyhooon@users.noreply.github.com> Date: Thu, 11 Apr 2024 17:17:02 +0900 Subject: [PATCH 04/16] =?UTF-8?q?[fix]=20[#57]=20=EB=B6=80=EC=8A=A4=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20=ED=99=94=EB=A9=B4=20system=20bar=20?= =?UTF-8?q?=EC=98=81=EC=97=AD=EC=97=90=20padding=20=EC=9D=B4=20=EC=83=9D?= =?UTF-8?q?=EA=B8=B0=EB=8A=94=20=EC=9D=B4=EC=8A=88=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/designsystem/component/Scaffold.kt | 11 +++-------- .../unifest/android/feature/home/HomeScreen.kt | 9 ++++++++- .../feature/home/navigation/HomeNavigation.kt | 7 ++++++- .../unifest/android/feature/main/MainScreen.kt | 12 +++++++++--- .../unifest/android/feature/map/MapScreen.kt | 8 +++++++- .../feature/map/navigation/MapNavigation.kt | 3 +++ .../unifest/android/feature/menu/MenuScreen.kt | 17 ++++++++++++----- .../feature/menu/navigation/MenuNavigation.kt | 7 +++++-- .../android/feature/waiting/WaitingScreen.kt | 17 ++++++++++++----- .../waiting/navigation/WaitingNavigation.kt | 7 +++++-- 10 files changed, 70 insertions(+), 28 deletions(-) diff --git a/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/Scaffold.kt b/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/Scaffold.kt index bb0d5cc9..7920f2ea 100644 --- a/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/Scaffold.kt +++ b/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/Scaffold.kt @@ -1,8 +1,7 @@ package com.unifest.android.core.designsystem.component -import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.padding import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.ScaffoldDefaults @@ -25,7 +24,7 @@ fun UnifestScaffold( containerColor: Color = MaterialTheme.colorScheme.background, contentColor: Color = contentColorFor(containerColor), contentWindowInsets: WindowInsets = ScaffoldDefaults.contentWindowInsets, - content: @Composable () -> Unit, + content: @Composable (PaddingValues) -> Unit, ) { CompositionLocalProvider( LocalMutableExKeyboardStateSourceOwner provides MutableExKeyboardStateSource(), @@ -40,11 +39,7 @@ fun UnifestScaffold( contentWindowInsets = contentWindowInsets, modifier = modifier.removeFocusWhenKeyboardIsHidden(), ) { innerPadding -> - Box( - modifier = Modifier.padding(innerPadding), - ) { - content() - } + content(innerPadding) } } } diff --git a/feature/home/src/main/kotlin/com/unifest/android/feature/home/HomeScreen.kt b/feature/home/src/main/kotlin/com/unifest/android/feature/home/HomeScreen.kt index 23725347..3297d899 100644 --- a/feature/home/src/main/kotlin/com/unifest/android/feature/home/HomeScreen.kt +++ b/feature/home/src/main/kotlin/com/unifest/android/feature/home/HomeScreen.kt @@ -7,6 +7,7 @@ import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box 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.fillMaxSize @@ -60,11 +61,13 @@ import kotlinx.collections.immutable.persistentListOf @Composable internal fun HomeRoute( + padding: PaddingValues, onNavigateToIntro: () -> Unit, viewModel: HomeViewModel = hiltViewModel(), ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() HomeScreen( + padding = padding, uiState = uiState, onNavigateToIntro = onNavigateToIntro, ) @@ -72,13 +75,16 @@ internal fun HomeRoute( @Composable internal fun HomeScreen( + padding: PaddingValues, uiState: HomeUiState, @Suppress("unused") onNavigateToIntro: () -> Unit, ) { var selectedEventId by remember { mutableIntStateOf(-1) } Column( - modifier = Modifier.fillMaxSize(), + modifier = Modifier + .fillMaxSize() + .padding(padding), ) { LazyColumn( modifier = Modifier.weight(1f), @@ -323,6 +329,7 @@ fun IncomingFestivalCard(event: IncomingFestivalEventEntity) { fun HomeScreenPreview() { UnifestTheme { HomeScreen( + padding = PaddingValues(0.dp), uiState = HomeUiState( festivalEvents = persistentListOf( FestivalEventEntity( diff --git a/feature/home/src/main/kotlin/com/unifest/android/feature/home/navigation/HomeNavigation.kt b/feature/home/src/main/kotlin/com/unifest/android/feature/home/navigation/HomeNavigation.kt index e069a554..ea28ac1c 100644 --- a/feature/home/src/main/kotlin/com/unifest/android/feature/home/navigation/HomeNavigation.kt +++ b/feature/home/src/main/kotlin/com/unifest/android/feature/home/navigation/HomeNavigation.kt @@ -1,5 +1,6 @@ package com.unifest.android.feature.home.navigation +import androidx.compose.foundation.layout.PaddingValues import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions @@ -13,9 +14,13 @@ fun NavController.navigateToHome(navOptions: NavOptions) { } fun NavGraphBuilder.homeNavGraph( + padding: PaddingValues, onNavigateToIntro: () -> Unit, ) { composable(route = HOME_ROUTE) { - HomeRoute(onNavigateToIntro = onNavigateToIntro) + HomeRoute( + padding = padding, + onNavigateToIntro = onNavigateToIntro, + ) } } diff --git a/feature/main/src/main/kotlin/com/unifest/android/feature/main/MainScreen.kt b/feature/main/src/main/kotlin/com/unifest/android/feature/main/MainScreen.kt index 386bb5f3..92824365 100644 --- a/feature/main/src/main/kotlin/com/unifest/android/feature/main/MainScreen.kt +++ b/feature/main/src/main/kotlin/com/unifest/android/feature/main/MainScreen.kt @@ -63,16 +63,18 @@ internal fun MainScreen( } UnifestScaffold( - content = { + content = { innerPadding -> NavHost( navController = navigator.navController, startDestination = navigator.startDestination, modifier = Modifier.fillMaxSize(), ) { homeNavGraph( + padding = innerPadding, onNavigateToIntro = onNavigateToIntro, ) mapNavGraph( + padding = innerPadding, onNavigateToBooth = navigator::navigateToBoothDetail, ) boothNavGraph( @@ -81,8 +83,12 @@ internal fun MainScreen( onNavigateToBoothLocation = navigator::navigateToBoothLocation, onShowSnackBar = onShowSnackBar, ) - waitingNavGraph() - menuNavGraph() + waitingNavGraph( + padding = innerPadding, + ) + menuNavGraph( + padding = innerPadding, + ) } }, bottomBar = { diff --git a/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt b/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt index df9ddf3f..8b35b8e6 100644 --- a/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt +++ b/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt @@ -56,6 +56,7 @@ import tech.thdev.compose.exteions.system.ui.controller.rememberExSystemUiContro @Composable internal fun MapRoute( + padding: PaddingValues, onNavigateToBooth: (Long) -> Unit, viewModel: MapViewModel = hiltViewModel(), ) { @@ -72,6 +73,7 @@ internal fun MapRoute( } MapScreen( + padding = padding, uiState = uiState, onNavigateToBooth = onNavigateToBooth, setFestivalSearchBottomSheetVisible = viewModel::setFestivalSearchBottomSheetVisible, @@ -90,6 +92,7 @@ internal fun MapRoute( ) @Composable internal fun MapScreen( + padding: PaddingValues, uiState: MapUiState, onNavigateToBooth: (Long) -> Unit, setFestivalSearchBottomSheetVisible: (Boolean) -> Unit, @@ -101,7 +104,9 @@ internal fun MapScreen( setInterestedFestivalDeleteDialogVisible: (Boolean) -> Unit, ) { Column( - modifier = Modifier.fillMaxSize(), + modifier = Modifier + .fillMaxSize() + .padding(padding), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center, ) { @@ -253,6 +258,7 @@ fun MapScreenPreview() { } UnifestTheme { MapScreen( + padding = PaddingValues(0.dp), uiState = MapUiState( selectedSchoolName = "건국대학교", boothList = boothList.toImmutableList(), diff --git a/feature/map/src/main/kotlin/com/unifest/android/feature/map/navigation/MapNavigation.kt b/feature/map/src/main/kotlin/com/unifest/android/feature/map/navigation/MapNavigation.kt index 6f343a0f..2ac3483c 100644 --- a/feature/map/src/main/kotlin/com/unifest/android/feature/map/navigation/MapNavigation.kt +++ b/feature/map/src/main/kotlin/com/unifest/android/feature/map/navigation/MapNavigation.kt @@ -1,5 +1,6 @@ package com.unifest.android.feature.map.navigation +import androidx.compose.foundation.layout.PaddingValues import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions @@ -13,10 +14,12 @@ fun NavController.navigateToMap(navOptions: NavOptions) { } fun NavGraphBuilder.mapNavGraph( + padding: PaddingValues, onNavigateToBooth: (Long) -> Unit, ) { composable(route = MAP_ROUTE) { MapRoute( + padding = padding, onNavigateToBooth = onNavigateToBooth, ) } diff --git a/feature/menu/src/main/kotlin/com/unifest/android/feature/menu/MenuScreen.kt b/feature/menu/src/main/kotlin/com/unifest/android/feature/menu/MenuScreen.kt index b2374626..4636c45f 100644 --- a/feature/menu/src/main/kotlin/com/unifest/android/feature/menu/MenuScreen.kt +++ b/feature/menu/src/main/kotlin/com/unifest/android/feature/menu/MenuScreen.kt @@ -2,23 +2,30 @@ package com.unifest.android.feature.menu import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp import com.unifest.android.core.designsystem.theme.UnifestTheme import com.unifest.android.core.ui.DevicePreview @Composable -internal fun MenuRoute() { - MenuScreen() +internal fun MenuRoute(padding: PaddingValues) { + MenuScreen(padding = padding) } @Composable -fun MenuScreen() { +fun MenuScreen( + padding: PaddingValues, +) { Column( - modifier = Modifier.fillMaxSize(), + modifier = Modifier + .fillMaxSize() + .padding(padding), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center, ) { @@ -30,6 +37,6 @@ fun MenuScreen() { @Composable fun MenuScreenPreview() { UnifestTheme { - MenuScreen() + MenuScreen(padding = PaddingValues(0.dp)) } } diff --git a/feature/menu/src/main/kotlin/com/unifest/android/feature/menu/navigation/MenuNavigation.kt b/feature/menu/src/main/kotlin/com/unifest/android/feature/menu/navigation/MenuNavigation.kt index 1f9ef1fa..1cd2e85e 100644 --- a/feature/menu/src/main/kotlin/com/unifest/android/feature/menu/navigation/MenuNavigation.kt +++ b/feature/menu/src/main/kotlin/com/unifest/android/feature/menu/navigation/MenuNavigation.kt @@ -1,5 +1,6 @@ package com.unifest.android.feature.menu.navigation +import androidx.compose.foundation.layout.PaddingValues import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions @@ -12,8 +13,10 @@ fun NavController.navigateToMenu(navOptions: NavOptions) { navigate(MENU_ROUTE, navOptions) } -fun NavGraphBuilder.menuNavGraph() { +fun NavGraphBuilder.menuNavGraph( + padding: PaddingValues, +) { composable(route = MENU_ROUTE) { - MenuRoute() + MenuRoute(padding = padding) } } diff --git a/feature/waiting/src/main/kotlin/com/unifest/android/feature/waiting/WaitingScreen.kt b/feature/waiting/src/main/kotlin/com/unifest/android/feature/waiting/WaitingScreen.kt index c7d703c3..22270e8d 100644 --- a/feature/waiting/src/main/kotlin/com/unifest/android/feature/waiting/WaitingScreen.kt +++ b/feature/waiting/src/main/kotlin/com/unifest/android/feature/waiting/WaitingScreen.kt @@ -2,23 +2,30 @@ package com.unifest.android.feature.waiting import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp import com.unifest.android.core.designsystem.theme.UnifestTheme import com.unifest.android.core.ui.DevicePreview @Composable -internal fun WaitingRoute() { - WaitingScreen() +internal fun WaitingRoute(padding: PaddingValues) { + WaitingScreen(padding = padding) } @Composable -internal fun WaitingScreen() { +internal fun WaitingScreen( + padding: PaddingValues, +) { Column( - modifier = Modifier.fillMaxSize(), + modifier = Modifier + .fillMaxSize() + .padding(padding), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center, ) { @@ -30,6 +37,6 @@ internal fun WaitingScreen() { @Composable fun WaitingScreenPreview() { UnifestTheme { - WaitingScreen() + WaitingScreen(padding = PaddingValues(0.dp)) } } diff --git a/feature/waiting/src/main/kotlin/com/unifest/android/feature/waiting/navigation/WaitingNavigation.kt b/feature/waiting/src/main/kotlin/com/unifest/android/feature/waiting/navigation/WaitingNavigation.kt index 0c80b034..10f5c808 100644 --- a/feature/waiting/src/main/kotlin/com/unifest/android/feature/waiting/navigation/WaitingNavigation.kt +++ b/feature/waiting/src/main/kotlin/com/unifest/android/feature/waiting/navigation/WaitingNavigation.kt @@ -1,5 +1,6 @@ package com.unifest.android.feature.waiting.navigation +import androidx.compose.foundation.layout.PaddingValues import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions @@ -12,8 +13,10 @@ fun NavController.navigateToWaiting(navOptions: NavOptions) { navigate(WAITING_ROUTE, navOptions) } -fun NavGraphBuilder.waitingNavGraph() { +fun NavGraphBuilder.waitingNavGraph( + padding: PaddingValues, +) { composable(route = WAITING_ROUTE) { - WaitingRoute() + WaitingRoute(padding = padding) } } From ee5466b79e7063fa4e2c03834f07c9ee00b3e16b Mon Sep 17 00:00:00 2001 From: JI HUN LEE <51016231+easyhooon@users.noreply.github.com> Date: Thu, 11 Apr 2024 17:28:42 +0900 Subject: [PATCH 05/16] =?UTF-8?q?[fix]=20=EB=B6=80=EC=8A=A4=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=ED=99=94=EB=A9=B4=20TopAppBar=20=EC=83=81=EB=8B=A8?= =?UTF-8?q?=EC=97=90=20=EA=B3=A0=EC=A0=95=20=EB=B0=8F=20padding=20?= =?UTF-8?q?=EA=B0=92=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/booth/BoothDetailScreen.kt | 25 +++++++++++-------- .../booth/navigation/BoothNavigation.kt | 3 +++ .../android/feature/main/MainScreen.kt | 1 + 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/feature/booth/src/main/kotlin/com/unifest/android/feature/booth/BoothDetailScreen.kt b/feature/booth/src/main/kotlin/com/unifest/android/feature/booth/BoothDetailScreen.kt index c5644bf3..2e334dbb 100644 --- a/feature/booth/src/main/kotlin/com/unifest/android/feature/booth/BoothDetailScreen.kt +++ b/feature/booth/src/main/kotlin/com/unifest/android/feature/booth/BoothDetailScreen.kt @@ -58,6 +58,7 @@ import tech.thdev.compose.exteions.system.ui.controller.rememberExSystemUiContro @Composable internal fun BoothDetailRoute( + padding: PaddingValues, onBackClick: () -> Unit, onShowSnackBar: (message: Int) -> Unit, onNavigateToBoothLocation: () -> Unit, @@ -76,6 +77,7 @@ internal fun BoothDetailRoute( } BoothDetailScreen( + padding = padding, uiState = uiState, onBackClick = onBackClick, onNavigateToBoothLocation = onNavigateToBoothLocation, @@ -88,6 +90,7 @@ internal fun BoothDetailRoute( @Composable fun BoothDetailScreen( + padding: PaddingValues, uiState: BoothUiState, onBackClick: () -> Unit, onNavigateToBoothLocation: () -> Unit, @@ -100,9 +103,17 @@ fun BoothDetailScreen( BoothDetailContent( uiState = uiState, onNavigateToBoothLocation = onNavigateToBoothLocation, - onBackClick = onBackClick, bottomPadding = 116.dp, ) + UnifestTopAppBar( + navigationType = TopAppBarNavigationType.Back, + navigationIconRes = R.drawable.ic_arrow_back_gray, + containerColor = Color.Transparent, + onNavigationClick = onBackClick, + modifier = Modifier + .align(Alignment.TopCenter) + .padding(padding), + ) BottomBar( isBookmarked = isBookmarked, bookmarkCount = bookmarkCount, @@ -120,7 +131,6 @@ fun BoothDetailScreen( fun BoothDetailContent( uiState: BoothUiState, onNavigateToBoothLocation: () -> Unit, - onBackClick: () -> Unit = {}, bottomPadding: Dp, ) { LazyColumn( @@ -129,15 +139,7 @@ fun BoothDetailContent( .padding(bottom = bottomPadding), ) { item { - Box { - BoothImage() - UnifestTopAppBar( - navigationType = TopAppBarNavigationType.Back, - navigationIconRes = R.drawable.ic_arrow_back_gray, - containerColor = Color.Transparent, - onNavigationClick = onBackClick, - ) - } + BoothImage() } item { Spacer(modifier = Modifier.height(30.dp)) } item { @@ -328,6 +330,7 @@ fun MenuItem(menu: MenuEntity) { fun BoothScreenPreview() { UnifestTheme { BoothDetailScreen( + padding = PaddingValues(0.dp), uiState = BoothUiState( boothDetailInfo = BoothDetailEntity( id = 0L, diff --git a/feature/booth/src/main/kotlin/com/unifest/android/feature/booth/navigation/BoothNavigation.kt b/feature/booth/src/main/kotlin/com/unifest/android/feature/booth/navigation/BoothNavigation.kt index 9ec566ee..4547c787 100644 --- a/feature/booth/src/main/kotlin/com/unifest/android/feature/booth/navigation/BoothNavigation.kt +++ b/feature/booth/src/main/kotlin/com/unifest/android/feature/booth/navigation/BoothNavigation.kt @@ -1,5 +1,6 @@ package com.unifest.android.feature.booth.navigation +import androidx.compose.foundation.layout.PaddingValues import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController @@ -29,6 +30,7 @@ fun NavController.navigateToBoothLocation() { } fun NavGraphBuilder.boothNavGraph( + padding: PaddingValues, navController: NavHostController, onBackClick: () -> Unit, onNavigateToBoothLocation: () -> Unit, @@ -46,6 +48,7 @@ fun NavGraphBuilder.boothNavGraph( composable(route = BOOTH_DETAIL_ROUTE) { entry -> val viewModel = entry.sharedViewModel(navController) BoothDetailRoute( + padding = padding, onBackClick = onBackClick, onNavigateToBoothLocation = onNavigateToBoothLocation, onShowSnackBar = onShowSnackBar, diff --git a/feature/main/src/main/kotlin/com/unifest/android/feature/main/MainScreen.kt b/feature/main/src/main/kotlin/com/unifest/android/feature/main/MainScreen.kt index 92824365..01740be1 100644 --- a/feature/main/src/main/kotlin/com/unifest/android/feature/main/MainScreen.kt +++ b/feature/main/src/main/kotlin/com/unifest/android/feature/main/MainScreen.kt @@ -78,6 +78,7 @@ internal fun MainScreen( onNavigateToBooth = navigator::navigateToBoothDetail, ) boothNavGraph( + padding = innerPadding, navController = navigator.navController, onBackClick = navigator::popBackStackIfNotHome, onNavigateToBoothLocation = navigator::navigateToBoothLocation, From d60a1a9aa93523cedd65f18319bed2cc42214876 Mon Sep 17 00:00:00 2001 From: JI HUN LEE <51016231+easyhooon@users.noreply.github.com> Date: Thu, 11 Apr 2024 17:47:42 +0900 Subject: [PATCH 06/16] =?UTF-8?q?[fix]=20[#57]=20=EC=8A=A4=EB=82=B5?= =?UTF-8?q?=EB=B0=94=20=EC=9C=84=EC=B9=98=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/feature/main/MainScreen.kt | 73 ++++++++++--------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/feature/main/src/main/kotlin/com/unifest/android/feature/main/MainScreen.kt b/feature/main/src/main/kotlin/com/unifest/android/feature/main/MainScreen.kt index 01740be1..df44cb9f 100644 --- a/feature/main/src/main/kotlin/com/unifest/android/feature/main/MainScreen.kt +++ b/feature/main/src/main/kotlin/com/unifest/android/feature/main/MainScreen.kt @@ -12,6 +12,7 @@ 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.selection.selectable import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon @@ -25,6 +26,7 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Color.Companion.White import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.vectorResource @@ -63,35 +65,6 @@ internal fun MainScreen( } UnifestScaffold( - content = { innerPadding -> - NavHost( - navController = navigator.navController, - startDestination = navigator.startDestination, - modifier = Modifier.fillMaxSize(), - ) { - homeNavGraph( - padding = innerPadding, - onNavigateToIntro = onNavigateToIntro, - ) - mapNavGraph( - padding = innerPadding, - onNavigateToBooth = navigator::navigateToBoothDetail, - ) - boothNavGraph( - padding = innerPadding, - navController = navigator.navController, - onBackClick = navigator::popBackStackIfNotHome, - onNavigateToBoothLocation = navigator::navigateToBoothLocation, - onShowSnackBar = onShowSnackBar, - ) - waitingNavGraph( - padding = innerPadding, - ) - menuNavGraph( - padding = innerPadding, - ) - } - }, bottomBar = { MainBottomBar( visible = navigator.shouldShowBottomBar(), @@ -100,11 +73,45 @@ internal fun MainScreen( onTabSelected = { navigator.navigate(it) }, ) }, - snackbarHost = { SnackbarHost(snackBarHostState) }, - containerColor = Color.White, - ) + snackbarHost = { + SnackbarHost( + hostState = snackBarHostState, + modifier = Modifier.padding(bottom = 64.dp), + ) + }, + containerColor = White, + ) { innerPadding -> + NavHost( + navController = navigator.navController, + startDestination = navigator.startDestination, + modifier = Modifier.fillMaxSize(), + ) { + homeNavGraph( + padding = innerPadding, + onNavigateToIntro = onNavigateToIntro, + ) + mapNavGraph( + padding = innerPadding, + onNavigateToBooth = navigator::navigateToBoothDetail, + ) + boothNavGraph( + padding = innerPadding, + navController = navigator.navController, + onBackClick = navigator::popBackStackIfNotHome, + onNavigateToBoothLocation = navigator::navigateToBoothLocation, + onShowSnackBar = onShowSnackBar, + ) + waitingNavGraph( + padding = innerPadding, + ) + menuNavGraph( + padding = innerPadding, + ) + } + } } + @Composable private fun MainBottomBar( visible: Boolean, @@ -113,7 +120,7 @@ private fun MainBottomBar( onTabSelected: (MainTab) -> Unit, ) { if (visible) { - Box(modifier = Modifier.background(Color.White)) { + Box(modifier = Modifier.background(White)) { Column { HorizontalDivider(color = Color(0xFFEBEBEB)) Row( From 2d4e4a02264e6ff76ca05d782b3a33a6a113aac6 Mon Sep 17 00:00:00 2001 From: JI HUN LEE <51016231+easyhooon@users.noreply.github.com> Date: Thu, 11 Apr 2024 21:20:41 +0900 Subject: [PATCH 07/16] =?UTF-8?q?[style]=20BoothDetail=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EB=92=A4=EB=A1=9C=EA=B0=80=EA=B8=B0=20=EC=95=84?= =?UTF-8?q?=EC=9D=B4=EC=BD=98=20=EA=B5=90=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit stroke 추가 --- .../android/core/designsystem/component/TopAppBar.kt | 1 + .../src/main/res/drawable/ic_arrow_back_gray.xml | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/TopAppBar.kt b/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/TopAppBar.kt index b5cb3f6c..547fd205 100644 --- a/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/TopAppBar.kt +++ b/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/TopAppBar.kt @@ -66,6 +66,7 @@ fun UnifestTopAppBar( Icon( imageVector = imageVector, contentDescription = navigationIconContentDescription, + tint = Color.Unspecified ) } } diff --git a/core/designsystem/src/main/res/drawable/ic_arrow_back_gray.xml b/core/designsystem/src/main/res/drawable/ic_arrow_back_gray.xml index 525b5c9e..084986a3 100644 --- a/core/designsystem/src/main/res/drawable/ic_arrow_back_gray.xml +++ b/core/designsystem/src/main/res/drawable/ic_arrow_back_gray.xml @@ -4,9 +4,10 @@ android:viewportWidth="9" android:viewportHeight="16"> From ac9ddb98caa20f33b2792e0cf6d92dede7d44d32 Mon Sep 17 00:00:00 2001 From: JI HUN LEE <51016231+easyhooon@users.noreply.github.com> Date: Thu, 11 Apr 2024 21:29:04 +0900 Subject: [PATCH 08/16] =?UTF-8?q?[feat]=20BoothItem=20=EC=9D=84=20?= =?UTF-8?q?=EB=88=8C=EB=9F=AC=EC=95=BC=20Booth=20=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=20=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/core/ui/component/BoothCard.kt | 7 ++++++- .../com/unifest/android/feature/map/MapScreen.kt | 16 +++++++--------- .../feature/map/viewmodel/MapViewModel.kt | 2 +- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/core/ui/src/main/kotlin/com/unifest/android/core/ui/component/BoothCard.kt b/core/ui/src/main/kotlin/com/unifest/android/core/ui/component/BoothCard.kt index fb9dc586..af360a58 100644 --- a/core/ui/src/main/kotlin/com/unifest/android/core/ui/component/BoothCard.kt +++ b/core/ui/src/main/kotlin/com/unifest/android/core/ui/component/BoothCard.kt @@ -1,5 +1,6 @@ package com.unifest.android.core.ui.component +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -33,10 +34,13 @@ import com.unifest.android.core.domain.entity.BoothDetailEntity @Composable fun BoothCard( boothInfo: BoothDetailEntity, + onNavigateToBooth: (Long) -> Unit, modifier: Modifier = Modifier, ) { Card( - modifier = modifier, + modifier = modifier.clickable { + onNavigateToBooth(boothInfo.id) + }, colors = CardDefaults.cardColors(containerColor = Color.White), shape = RoundedCornerShape(12.dp), elevation = CardDefaults.cardElevation(defaultElevation = 0.dp), @@ -100,6 +104,7 @@ fun BoothCardPreview() { longitude = 0f, menus = emptyList(), ), + onNavigateToBooth = {} ) } } diff --git a/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt b/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt index 8b35b8e6..bbb1ecf7 100644 --- a/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt +++ b/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt @@ -123,10 +123,7 @@ internal fun MapScreen( Marker( state = MarkerState(position = LatLng(spot.lat, spot.lng)), icon = OverlayImage.fromResource(R.drawable.ic_general), - onClick = { - onNavigateToBooth(spot.id) - true - }, + onClick = { true }, ) } } @@ -142,11 +139,12 @@ internal fun MapScreen( ) BoothCards( pagerState = pagerState, + boothList = uiState.boothList, + onNavigateToBooth = onNavigateToBooth, modifier = Modifier .align(Alignment.BottomCenter) .wrapContentHeight() .padding(bottom = 21.dp), - boothList = uiState.boothList, ) if (uiState.isFestivalSearchBottomSheetVisible) { FestivalSearchBottomSheet( @@ -169,7 +167,6 @@ internal fun MapScreen( } } -@OptIn(ExperimentalFoundationApi::class) @Composable fun MapTopAppBar( title: String, @@ -220,6 +217,7 @@ fun MapTopAppBar( fun BoothCards( pagerState: PagerState, boothList: ImmutableList, + onNavigateToBooth: (Long) -> Unit, modifier: Modifier = Modifier, ) { HorizontalPager( @@ -229,6 +227,7 @@ fun BoothCards( ) { page -> BoothCard( boothInfo = boothList[page], + onNavigateToBooth = onNavigateToBooth, modifier = Modifier .fillMaxWidth() .padding(horizontal = 12.dp), @@ -236,7 +235,6 @@ fun BoothCards( } } -@OptIn(ExperimentalFoundationApi::class) @DevicePreview @Composable fun MapScreenPreview() { @@ -282,7 +280,6 @@ fun MapScreenPreview() { } } -@OptIn(ExperimentalFoundationApi::class) @ComponentPreview @Composable fun MapTopAppBarPreview() { @@ -321,8 +318,9 @@ fun BoothCardsPreview() { UnifestTheme { BoothCards( pagerState = rememberPagerState(pageCount = { boothList.size }), - modifier = Modifier.height(116.dp), boothList = boothList.toImmutableList(), + onNavigateToBooth = {}, + modifier = Modifier.height(116.dp), ) } } diff --git a/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt b/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt index d70523ed..ac43a603 100644 --- a/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt +++ b/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt @@ -24,7 +24,7 @@ class MapViewModel @Inject constructor() : ViewModel() { repeat(5) { boothList.add( BoothDetailEntity( - id = 1L, + id = it.toLong(), name = "컴공 주점", category = "", description = "저희 주점은 일본 이자카야를 모티브로 만든 컴공인을 위한 주점입니다. 100번째 방문자에게 깜짝 선물 증정 이벤트를 하고 있으니 많은 관심 부탁드려요~!", From 36150dfa46ca92c5b1321d71a4e2190daf9b699b Mon Sep 17 00:00:00 2001 From: JI HUN LEE <51016231+easyhooon@users.noreply.github.com> Date: Thu, 11 Apr 2024 21:56:24 +0900 Subject: [PATCH 09/16] =?UTF-8?q?[feat]=20=EB=9E=AD=ED=82=B9=20=EC=88=9C?= =?UTF-8?q?=EC=9C=84=20=EB=B1=83=EC=A7=80=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/core/ui/component/BoothCard.kt | 110 -------------- .../unifest/android/feature/map/MapScreen.kt | 136 +++++++++++++++++- .../feature/map/viewmodel/MapViewModel.kt | 4 +- 3 files changed, 137 insertions(+), 113 deletions(-) delete mode 100644 core/ui/src/main/kotlin/com/unifest/android/core/ui/component/BoothCard.kt diff --git a/core/ui/src/main/kotlin/com/unifest/android/core/ui/component/BoothCard.kt b/core/ui/src/main/kotlin/com/unifest/android/core/ui/component/BoothCard.kt deleted file mode 100644 index af360a58..00000000 --- a/core/ui/src/main/kotlin/com/unifest/android/core/ui/component/BoothCard.kt +++ /dev/null @@ -1,110 +0,0 @@ -package com.unifest.android.core.ui.component - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.height -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.Card -import androidx.compose.material3.CardDefaults -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.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.vectorResource -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import com.unifest.android.core.designsystem.ComponentPreview -import com.unifest.android.core.designsystem.R -import com.unifest.android.core.designsystem.component.NetworkImage -import com.unifest.android.core.designsystem.theme.Content2 -import com.unifest.android.core.designsystem.theme.Title2 -import com.unifest.android.core.designsystem.theme.Title5 -import com.unifest.android.core.designsystem.theme.UnifestTheme -import com.unifest.android.core.domain.entity.BoothDetailEntity - -@Composable -fun BoothCard( - boothInfo: BoothDetailEntity, - onNavigateToBooth: (Long) -> Unit, - modifier: Modifier = Modifier, -) { - Card( - modifier = modifier.clickable { - onNavigateToBooth(boothInfo.id) - }, - colors = CardDefaults.cardColors(containerColor = Color.White), - shape = RoundedCornerShape(12.dp), - elevation = CardDefaults.cardElevation(defaultElevation = 0.dp), - ) { - Row( - modifier = Modifier.padding(15.dp), - ) { - NetworkImage( - imageUrl = "https://picsum.photos/86", - modifier = Modifier - .size(86.dp) - .clip(RoundedCornerShape(16.dp)), - ) - Column( - modifier = Modifier.padding(start = 15.dp), - ) { - Text( - text = boothInfo.name, - style = Title2, - ) - Spacer(modifier = Modifier.height(3.dp)) - Text( - text = boothInfo.description, - maxLines = 2, - overflow = TextOverflow.Ellipsis, - style = Content2, - ) - Spacer(modifier = Modifier.height(3.dp)) - Row( - verticalAlignment = Alignment.CenterVertically, - ) { - Icon( - imageVector = ImageVector.vectorResource(R.drawable.ic_location_green), - contentDescription = "Location Icon", - tint = Color.Unspecified, - ) - Spacer(modifier = Modifier.width(4.dp)) - Text( - text = boothInfo.location, - style = Title5, - ) - } - } - } - } -} - -@ComponentPreview -@Composable -fun BoothCardPreview() { - UnifestTheme { - BoothCard( - boothInfo = BoothDetailEntity( - id = 1L, - name = "컴공 주점", - category = "", - description = "저희 주점은 일본 이자카야를 모티브로 만든 컴공인을 위한 주점입니다. 100번째 방문자에게 깜짝 선물 증정 이벤트를 하고 있으니 많은 관심 부탁드려요~!", - warning = "", - location = "청심대 앞", - latitude = 0f, - longitude = 0f, - menus = emptyList(), - ), - onNavigateToBooth = {} - ) - } -} diff --git a/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt b/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt index bbb1ecf7..793e2ddf 100644 --- a/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt +++ b/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt @@ -2,28 +2,40 @@ package com.unifest.android.feature.map import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box 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.fillMaxSize 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.width import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.PagerState import androidx.compose.foundation.pager.rememberPagerState +import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -37,14 +49,17 @@ import com.naver.maps.map.compose.rememberCameraPositionState import com.naver.maps.map.overlay.OverlayImage import com.unifest.android.core.designsystem.ComponentPreview import com.unifest.android.core.designsystem.R +import com.unifest.android.core.designsystem.component.NetworkImage import com.unifest.android.core.designsystem.component.SearchTextField import com.unifest.android.core.designsystem.component.TopAppBarNavigationType import com.unifest.android.core.designsystem.component.UnifestTopAppBar +import com.unifest.android.core.designsystem.theme.Content2 +import com.unifest.android.core.designsystem.theme.Title2 +import com.unifest.android.core.designsystem.theme.Title5 import com.unifest.android.core.designsystem.theme.UnifestTheme import com.unifest.android.core.domain.entity.BoothDetailEntity import com.unifest.android.core.domain.entity.BoothSpot import com.unifest.android.core.ui.DevicePreview -import com.unifest.android.core.ui.component.BoothCard import com.unifest.android.core.ui.component.BoothFilterChips import com.unifest.android.core.ui.component.FestivalSearchBottomSheet import com.unifest.android.feature.map.viewmodel.MapUiState @@ -141,6 +156,7 @@ internal fun MapScreen( pagerState = pagerState, boothList = uiState.boothList, onNavigateToBooth = onNavigateToBooth, + isPopularMode = uiState.isPopularMode, modifier = Modifier .align(Alignment.BottomCenter) .wrapContentHeight() @@ -218,6 +234,7 @@ fun BoothCards( pagerState: PagerState, boothList: ImmutableList, onNavigateToBooth: (Long) -> Unit, + isPopularMode: Boolean, modifier: Modifier = Modifier, ) { HorizontalPager( @@ -228,6 +245,8 @@ fun BoothCards( BoothCard( boothInfo = boothList[page], onNavigateToBooth = onNavigateToBooth, + isPopularMode = isPopularMode, + ranking = page + 1, modifier = Modifier .fillMaxWidth() .padding(horizontal = 12.dp), @@ -235,6 +254,89 @@ fun BoothCards( } } +@Composable +fun BoothCard( + boothInfo: BoothDetailEntity, + onNavigateToBooth: (Long) -> Unit, + isPopularMode: Boolean, + ranking: Int, + modifier: Modifier = Modifier, +) { + Card( + modifier = modifier.clickable { + onNavigateToBooth(boothInfo.id) + }, + colors = CardDefaults.cardColors(containerColor = Color.White), + shape = RoundedCornerShape(12.dp), + elevation = CardDefaults.cardElevation(defaultElevation = 0.dp), + ) { + Box { + Row( + modifier = Modifier.padding(15.dp), + ) { + NetworkImage( + imageUrl = "https://picsum.photos/86", + modifier = Modifier + .size(86.dp) + .clip(RoundedCornerShape(16.dp)), + ) + Column( + modifier = Modifier.padding(start = 15.dp), + ) { + Text( + text = boothInfo.name, + style = Title2, + ) + Spacer(modifier = Modifier.height(3.dp)) + Text( + text = boothInfo.description, + maxLines = 2, + overflow = TextOverflow.Ellipsis, + style = Content2, + ) + Spacer(modifier = Modifier.height(3.dp)) + Row( + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + imageVector = ImageVector.vectorResource(R.drawable.ic_location_green), + contentDescription = "Location Icon", + tint = Color.Unspecified, + ) + Spacer(modifier = Modifier.width(4.dp)) + Text( + text = boothInfo.location, + style = Title5, + ) + } + } + } + if (isPopularMode) { + RankingBadge(ranking = ranking) + } + } + } +} + +@Composable +fun RankingBadge(ranking: Int) { + Box( + modifier = Modifier + .size(36.dp) + .clip(CircleShape) + .padding(start = 7.dp, top = 9.dp) + .background(Color(0xFFF5687E), CircleShape), + contentAlignment = Alignment.TopStart, + ) { + Text( + text = "${ranking}위", + color = Color.White, + style = Title5, + modifier = Modifier.align(Alignment.Center), + ) + } +} + @DevicePreview @Composable fun MapScreenPreview() { @@ -320,7 +422,39 @@ fun BoothCardsPreview() { pagerState = rememberPagerState(pageCount = { boothList.size }), boothList = boothList.toImmutableList(), onNavigateToBooth = {}, + isPopularMode = false, modifier = Modifier.height(116.dp), ) } } + +@ComponentPreview +@Composable +fun BoothCardPreview() { + UnifestTheme { + BoothCard( + boothInfo = BoothDetailEntity( + id = 1L, + name = "컴공 주점", + category = "", + description = "저희 주점은 일본 이자카야를 모티브로 만든 컴공인을 위한 주점입니다. 100번째 방문자에게 깜짝 선물 증정 이벤트를 하고 있으니 많은 관심 부탁드려요~!", + warning = "", + location = "청심대 앞", + latitude = 0f, + longitude = 0f, + menus = emptyList(), + ), + onNavigateToBooth = {}, + isPopularMode = true, + ranking = 1, + ) + } +} + +@ComponentPreview +@Composable +fun RankingBadgePreview() { + UnifestTheme { + RankingBadge(ranking = 1) + } +} diff --git a/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt b/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt index ac43a603..3d1cb0c8 100644 --- a/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt +++ b/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt @@ -105,9 +105,9 @@ class MapViewModel @Inject constructor() : ViewModel() { } } - fun setEnablePopularMode() { + fun setEnablePopularMode(flag: Boolean) { _uiState.update { - it.copy(isPopularMode = !_uiState.value.isPopularMode) + it.copy(isPopularMode = flag) } } From e5f395e9439dd1894eb9a8d330d127d0554cdfc7 Mon Sep 17 00:00:00 2001 From: JI HUN LEE <51016231+easyhooon@users.noreply.github.com> Date: Thu, 11 Apr 2024 22:29:25 +0900 Subject: [PATCH 10/16] =?UTF-8?q?[feat]=20=EC=9D=B8=EA=B8=B0=20=EB=B6=80?= =?UTF-8?q?=EC=8A=A4=20=ED=99=95=EC=9E=A5=20=EC=B6=95=EC=86=8C=20=EC=95=84?= =?UTF-8?q?=EC=9D=B4=EC=BD=98=20=EB=B2=84=ED=8A=BC=20=EB=B0=8F=20=EC=95=A0?= =?UTF-8?q?=EB=8B=88=EB=A9=94=EC=9D=B4=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/res/drawable/ic_dropdown.xml | 12 ++++ .../unifest/android/feature/map/MapScreen.kt | 70 ++++++++++++++++--- .../feature/map/viewmodel/MapViewModel.kt | 4 +- 3 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 core/designsystem/src/main/res/drawable/ic_dropdown.xml diff --git a/core/designsystem/src/main/res/drawable/ic_dropdown.xml b/core/designsystem/src/main/res/drawable/ic_dropdown.xml new file mode 100644 index 00000000..1026e595 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_dropdown.xml @@ -0,0 +1,12 @@ + + + diff --git a/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt b/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt index 793e2ddf..e180bc58 100644 --- a/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt +++ b/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt @@ -1,7 +1,10 @@ package com.unifest.android.feature.map +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background +import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -31,6 +34,7 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.rotate import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.vectorResource @@ -55,6 +59,7 @@ import com.unifest.android.core.designsystem.component.TopAppBarNavigationType import com.unifest.android.core.designsystem.component.UnifestTopAppBar import com.unifest.android.core.designsystem.theme.Content2 import com.unifest.android.core.designsystem.theme.Title2 +import com.unifest.android.core.designsystem.theme.Title4 import com.unifest.android.core.designsystem.theme.Title5 import com.unifest.android.core.designsystem.theme.UnifestTheme import com.unifest.android.core.domain.entity.BoothDetailEntity @@ -97,6 +102,7 @@ internal fun MapRoute( initSearchText = viewModel::initSearchText, setEnableSearchMode = viewModel::setEnableSearchMode, setEnableEditMode = viewModel::setEnableEditMode, + setEnablePopularMode = viewModel::setEnablePopularMode, setInterestedFestivalDeleteDialogVisible = viewModel::setInterestedFestivalDeleteDialogVisible, ) } @@ -116,8 +122,11 @@ internal fun MapScreen( initSearchText: () -> Unit, setEnableSearchMode: (Boolean) -> Unit, setEnableEditMode: () -> Unit, + setEnablePopularMode: () -> Unit, setInterestedFestivalDeleteDialogVisible: (Boolean) -> Unit, ) { + val rotationState by animateFloatAsState(targetValue = if (uiState.isPopularMode) 180f else 0f) + Column( modifier = Modifier .fillMaxSize() @@ -152,16 +161,58 @@ internal fun MapScreen( .fillMaxWidth() .align(Alignment.TopCenter), ) - BoothCards( - pagerState = pagerState, - boothList = uiState.boothList, - onNavigateToBooth = onNavigateToBooth, - isPopularMode = uiState.isPopularMode, + Column( modifier = Modifier - .align(Alignment.BottomCenter) - .wrapContentHeight() - .padding(bottom = 21.dp), - ) + .fillMaxWidth() + .align(Alignment.BottomCenter), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Box( + modifier = Modifier + .width(116.dp) + .height(36.dp) + .clip(RoundedCornerShape(39.dp)) + .background(Color.White) + .border( + width = 1.dp, + color = Color(0xFFF5687E), + shape = RoundedCornerShape(39.dp), + ) + .clickable { + setEnablePopularMode() + }, + ) { + Row( + modifier = Modifier.align(Alignment.Center), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Center, + ) { + Text( + text = "인기 부스", + color = Color(0xFFF5687E), + style = Title4, + ) + Spacer(modifier = Modifier.width(6.dp)) + Icon( + imageVector = ImageVector.vectorResource(R.drawable.ic_dropdown), + contentDescription = "Dropdown Icon", + tint = Color.Unspecified, + modifier = Modifier.rotate(rotationState), + ) + } + } + Spacer(modifier = Modifier.height(10.dp)) + AnimatedVisibility(uiState.isPopularMode) { + BoothCards( + pagerState = pagerState, + boothList = uiState.boothList, + onNavigateToBooth = onNavigateToBooth, + isPopularMode = uiState.isPopularMode, + modifier = Modifier.wrapContentHeight() + ) + } + Spacer(modifier = Modifier.height(21.dp)) + } if (uiState.isFestivalSearchBottomSheetVisible) { FestivalSearchBottomSheet( searchText = uiState.festivalSearchText, @@ -377,6 +428,7 @@ fun MapScreenPreview() { initSearchText = {}, setEnableSearchMode = {}, setEnableEditMode = {}, + setEnablePopularMode = {}, setInterestedFestivalDeleteDialogVisible = {}, ) } diff --git a/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt b/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt index 3d1cb0c8..ac43a603 100644 --- a/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt +++ b/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt @@ -105,9 +105,9 @@ class MapViewModel @Inject constructor() : ViewModel() { } } - fun setEnablePopularMode(flag: Boolean) { + fun setEnablePopularMode() { _uiState.update { - it.copy(isPopularMode = flag) + it.copy(isPopularMode = !_uiState.value.isPopularMode) } } From 0e32848970915ff8e4b66f78612f7cde00cfe2ad Mon Sep 17 00:00:00 2001 From: JI HUN LEE <51016231+easyhooon@users.noreply.github.com> Date: Fri, 12 Apr 2024 03:12:51 +0900 Subject: [PATCH 11/16] =?UTF-8?q?[feat]=20=EC=A7=80=EB=8F=84=20=ED=81=B4?= =?UTF-8?q?=EB=9F=AC=EC=8A=A4=ED=84=B0=EB=A7=81=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?=EB=B0=8F=20Marker=20=EC=99=80=20Booth=20HorizontalPager=20?= =?UTF-8?q?=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/core/domain/entity/BoothSpot.kt | 10 - .../feature/booth/viewmodel/BoothUiState.kt | 3 +- .../unifest/android/feature/map/MapScreen.kt | 110 +++++++---- .../feature/map/mapper/EntityToModel.kt | 28 +++ .../feature/map/model/BoothDetailModel.kt | 30 +++ .../feature/map/viewmodel/MapUiState.kt | 10 +- .../feature/map/viewmodel/MapViewModel.kt | 181 +++++++++++++++--- 7 files changed, 289 insertions(+), 83 deletions(-) delete mode 100644 core/domain/src/main/kotlin/com/unifest/android/core/domain/entity/BoothSpot.kt create mode 100644 feature/map/src/main/kotlin/com/unifest/android/feature/map/mapper/EntityToModel.kt create mode 100644 feature/map/src/main/kotlin/com/unifest/android/feature/map/model/BoothDetailModel.kt diff --git a/core/domain/src/main/kotlin/com/unifest/android/core/domain/entity/BoothSpot.kt b/core/domain/src/main/kotlin/com/unifest/android/core/domain/entity/BoothSpot.kt deleted file mode 100644 index 57b16a9c..00000000 --- a/core/domain/src/main/kotlin/com/unifest/android/core/domain/entity/BoothSpot.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.unifest.android.core.domain.entity - -import androidx.compose.runtime.Stable - -@Stable -data class BoothSpot( - val id: Long, - val lat: Double, - val lng: Double, -) diff --git a/feature/booth/src/main/kotlin/com/unifest/android/feature/booth/viewmodel/BoothUiState.kt b/feature/booth/src/main/kotlin/com/unifest/android/feature/booth/viewmodel/BoothUiState.kt index 8a5129c1..3967034b 100644 --- a/feature/booth/src/main/kotlin/com/unifest/android/feature/booth/viewmodel/BoothUiState.kt +++ b/feature/booth/src/main/kotlin/com/unifest/android/feature/booth/viewmodel/BoothUiState.kt @@ -1,7 +1,6 @@ package com.unifest.android.feature.booth.viewmodel import com.unifest.android.core.domain.entity.BoothDetailEntity -import com.unifest.android.core.domain.entity.BoothSpot import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf @@ -9,5 +8,5 @@ data class BoothUiState( val boothDetailInfo: BoothDetailEntity = BoothDetailEntity(), val bookmarkCount: Int = 0, val isBookmarked: Boolean = false, - val boothSpots: ImmutableList = persistentListOf(), + val boothSpots: ImmutableList = persistentListOf(), ) diff --git a/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt b/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt index e180bc58..06799f91 100644 --- a/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt +++ b/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt @@ -31,12 +31,16 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.rotate 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.text.input.TextFieldValue import androidx.compose.ui.text.style.TextOverflow @@ -45,11 +49,12 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.naver.maps.geometry.LatLng import com.naver.maps.map.CameraPosition +import com.naver.maps.map.compose.DisposableMapEffect import com.naver.maps.map.compose.ExperimentalNaverMapApi -import com.naver.maps.map.compose.Marker -import com.naver.maps.map.compose.MarkerState +import com.naver.maps.map.compose.MapUiSettings import com.naver.maps.map.compose.NaverMap import com.naver.maps.map.compose.rememberCameraPositionState +import com.naver.maps.map.overlay.Marker import com.naver.maps.map.overlay.OverlayImage import com.unifest.android.core.designsystem.ComponentPreview import com.unifest.android.core.designsystem.R @@ -62,17 +67,17 @@ import com.unifest.android.core.designsystem.theme.Title2 import com.unifest.android.core.designsystem.theme.Title4 import com.unifest.android.core.designsystem.theme.Title5 import com.unifest.android.core.designsystem.theme.UnifestTheme -import com.unifest.android.core.domain.entity.BoothDetailEntity -import com.unifest.android.core.domain.entity.BoothSpot import com.unifest.android.core.ui.DevicePreview import com.unifest.android.core.ui.component.BoothFilterChips import com.unifest.android.core.ui.component.FestivalSearchBottomSheet +import com.unifest.android.feature.map.model.BoothDetailModel import com.unifest.android.feature.map.viewmodel.MapUiState import com.unifest.android.feature.map.viewmodel.MapViewModel import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList import tech.thdev.compose.exteions.system.ui.controller.rememberExSystemUiController +import ted.gun0912.clustering.naver.TedNaverClustering @Composable internal fun MapRoute( @@ -103,6 +108,8 @@ internal fun MapRoute( setEnableSearchMode = viewModel::setEnableSearchMode, setEnableEditMode = viewModel::setEnableEditMode, setEnablePopularMode = viewModel::setEnablePopularMode, + setBoothSelectionMode = viewModel::setBoothSelectionMode, + updateSelectedBooths = viewModel::updateSelectedBooths, setInterestedFestivalDeleteDialogVisible = viewModel::setInterestedFestivalDeleteDialogVisible, ) } @@ -123,6 +130,8 @@ internal fun MapScreen( setEnableSearchMode: (Boolean) -> Unit, setEnableEditMode: () -> Unit, setEnablePopularMode: () -> Unit, + setBoothSelectionMode: (Boolean) -> Unit, + updateSelectedBooths: (List) -> Unit, setInterestedFestivalDeleteDialogVisible: (Boolean) -> Unit, ) { val rotationState by animateFloatAsState(targetValue = if (uiState.isPopularMode) 180f else 0f) @@ -137,18 +146,46 @@ internal fun MapScreen( val cameraPositionState = rememberCameraPositionState { position = CameraPosition(LatLng(37.540470588662664, 127.0765263757882), 14.0) } - val pagerState = rememberPagerState(pageCount = { uiState.boothList.size }) + val pagerState = rememberPagerState(pageCount = { uiState.selectedBooths.size }) Box { + // TODO 지도 중앙 위치 조정 + // TODO 같은 속성의 Marker 들만 클러스터링 되도록 구현 + // TODO 클러스터링 마커 커스텀 NaverMap( cameraPositionState = cameraPositionState, + uiSettings = MapUiSettings( + isZoomControlEnabled = false, + isScaleBarEnabled = false, + isLogoClickEnabled = false, + ), modifier = Modifier.fillMaxSize(), ) { - uiState.boothSpots.forEach { spot -> - Marker( - state = MarkerState(position = LatLng(spot.lat, spot.lng)), - icon = OverlayImage.fromResource(R.drawable.ic_general), - onClick = { true }, - ) + val context = LocalContext.current + var clusterManager by remember { mutableStateOf?>(null) } + DisposableMapEffect(uiState.booths) { map -> + if (clusterManager == null) { + clusterManager = TedNaverClustering.with(context, map) + .customMarker { + Marker().apply { + icon = OverlayImage.fromResource(R.drawable.ic_general) + } + } + .markerClickListener { booth -> + setBoothSelectionMode(true) + updateSelectedBooths(listOf(booth)) + } + .clusterClickListener { booths -> + setBoothSelectionMode(true) + updateSelectedBooths(booths.items.toList()) + } + // 마커를 클릭 했을 경우 지도의 가운데가 마커로 이동 비활성화 + .clickToCenter(false) + .make() + } + clusterManager?.addItems(uiState.booths) + onDispose { + clusterManager?.clearItems() + } } } MapTopAppBar( @@ -202,13 +239,13 @@ internal fun MapScreen( } } Spacer(modifier = Modifier.height(10.dp)) - AnimatedVisibility(uiState.isPopularMode) { + AnimatedVisibility(uiState.isPopularMode || uiState.isBoothSelectionMode) { BoothCards( pagerState = pagerState, - boothList = uiState.boothList, + booths = uiState.booths, onNavigateToBooth = onNavigateToBooth, isPopularMode = uiState.isPopularMode, - modifier = Modifier.wrapContentHeight() + modifier = Modifier.wrapContentHeight(), ) } Spacer(modifier = Modifier.height(21.dp)) @@ -283,7 +320,7 @@ fun MapTopAppBar( @Composable fun BoothCards( pagerState: PagerState, - boothList: ImmutableList, + booths: ImmutableList, onNavigateToBooth: (Long) -> Unit, isPopularMode: Boolean, modifier: Modifier = Modifier, @@ -294,7 +331,7 @@ fun BoothCards( contentPadding = PaddingValues(horizontal = 30.dp), ) { page -> BoothCard( - boothInfo = boothList[page], + boothInfo = booths[page], onNavigateToBooth = onNavigateToBooth, isPopularMode = isPopularMode, ranking = page + 1, @@ -307,7 +344,7 @@ fun BoothCards( @Composable fun BoothCard( - boothInfo: BoothDetailEntity, + boothInfo: BoothDetailModel, onNavigateToBooth: (Long) -> Unit, isPopularMode: Boolean, ranking: Int, @@ -391,33 +428,34 @@ fun RankingBadge(ranking: Int) { @DevicePreview @Composable fun MapScreenPreview() { - val boothList = mutableListOf() + val boothList = mutableListOf() repeat(5) { boothList.add( - BoothDetailEntity( + BoothDetailModel( id = 1L, name = "컴공 주점", category = "", description = "저희 주점은 일본 이자카야를 모티브로 만든 컴공인을 위한 주점입니다. 100번째 방문자에게 깜짝 선물 증정 이벤트를 하고 있으니 많은 관심 부탁드려요~!", warning = "", location = "청심대 앞", - latitude = 0f, - longitude = 0f, - menus = emptyList(), ), ) } + UnifestTheme { MapScreen( padding = PaddingValues(0.dp), uiState = MapUiState( selectedSchoolName = "건국대학교", - boothList = boothList.toImmutableList(), - boothSpots = persistentListOf( - BoothSpot( - lat = 37.540470588662664, - lng = 127.0765263757882, + booths = persistentListOf( + BoothDetailModel( id = 1L, + name = "컴공 주점", + category = "", + description = "저희 주점은 일본 이자카야를 모티브로 만든 컴공인을 위한 주점입니다. 100번째 방문자에게 깜짝 선물 증정 이벤트를 하고 있으니 많은 관심 부탁드려요~!", + location = "청심대 앞", + latitude = 37.540470588662664, + longitude = 127.0765263757882, ), ), ), @@ -429,6 +467,8 @@ fun MapScreenPreview() { setEnableSearchMode = {}, setEnableEditMode = {}, setEnablePopularMode = {}, + setBoothSelectionMode = {}, + updateSelectedBooths = {}, setInterestedFestivalDeleteDialogVisible = {}, ) } @@ -452,19 +492,18 @@ fun MapTopAppBarPreview() { @ComponentPreview @Composable fun BoothCardsPreview() { - val boothList = mutableListOf() + val boothList = mutableListOf() repeat(5) { boothList.add( - BoothDetailEntity( + BoothDetailModel( id = 1L, name = "컴공 주점", category = "", description = "저희 주점은 일본 이자카야를 모티브로 만든 컴공인을 위한 주점입니다. 100번째 방문자에게 깜짝 선물 증정 이벤트를 하고 있으니 많은 관심 부탁드려요~!", warning = "", location = "청심대 앞", - latitude = 0f, - longitude = 0f, - menus = emptyList(), + latitude = 0.toDouble(), + longitude = 0.toDouble(), ), ) } @@ -472,7 +511,7 @@ fun BoothCardsPreview() { UnifestTheme { BoothCards( pagerState = rememberPagerState(pageCount = { boothList.size }), - boothList = boothList.toImmutableList(), + booths = boothList.toImmutableList(), onNavigateToBooth = {}, isPopularMode = false, modifier = Modifier.height(116.dp), @@ -485,16 +524,13 @@ fun BoothCardsPreview() { fun BoothCardPreview() { UnifestTheme { BoothCard( - boothInfo = BoothDetailEntity( + boothInfo = BoothDetailModel( id = 1L, name = "컴공 주점", category = "", description = "저희 주점은 일본 이자카야를 모티브로 만든 컴공인을 위한 주점입니다. 100번째 방문자에게 깜짝 선물 증정 이벤트를 하고 있으니 많은 관심 부탁드려요~!", warning = "", location = "청심대 앞", - latitude = 0f, - longitude = 0f, - menus = emptyList(), ), onNavigateToBooth = {}, isPopularMode = true, diff --git a/feature/map/src/main/kotlin/com/unifest/android/feature/map/mapper/EntityToModel.kt b/feature/map/src/main/kotlin/com/unifest/android/feature/map/mapper/EntityToModel.kt new file mode 100644 index 00000000..1d5ef6e5 --- /dev/null +++ b/feature/map/src/main/kotlin/com/unifest/android/feature/map/mapper/EntityToModel.kt @@ -0,0 +1,28 @@ +package com.unifest.android.feature.map.mapper + +import com.unifest.android.core.domain.entity.BoothDetailEntity +import com.unifest.android.core.domain.entity.MenuEntity +import com.unifest.android.feature.map.model.BoothDetailModel +import com.unifest.android.feature.map.model.MenuModel +import kotlinx.collections.immutable.toImmutableList + +internal fun BoothDetailEntity.toModel() = + BoothDetailModel( + id = id, + name = name, + category = category, + description = description, + warning = warning, + location = location, + latitude = latitude.toDouble(), + longitude = longitude.toDouble(), + menus = menus.map { it.toModel() }.toImmutableList(), + ) + +internal fun MenuEntity.toModel() = + MenuModel( + id = id, + name = name, + price = price, + imgUrl = imgUrl, + ) diff --git a/feature/map/src/main/kotlin/com/unifest/android/feature/map/model/BoothDetailModel.kt b/feature/map/src/main/kotlin/com/unifest/android/feature/map/model/BoothDetailModel.kt new file mode 100644 index 00000000..2b6b2258 --- /dev/null +++ b/feature/map/src/main/kotlin/com/unifest/android/feature/map/model/BoothDetailModel.kt @@ -0,0 +1,30 @@ +package com.unifest.android.feature.map.model + +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf +import ted.gun0912.clustering.clustering.TedClusterItem +import ted.gun0912.clustering.geometry.TedLatLng +import java.io.Serializable + +data class BoothDetailModel( + val id: Long = 0L, + val name: String = "", + val category: String = "", + val description: String = "", + val warning: String = "", + val location: String = "", + val latitude: Double = 0.toDouble(), + val longitude: Double = 0.toDouble(), + val menus: ImmutableList = persistentListOf(), +): Serializable, TedClusterItem { + override fun getTedLatLng(): TedLatLng { + return TedLatLng(latitude, longitude) + } +} + +data class MenuModel( + val id: Long = 0L, + val name: String = "", + val price: Int = 0, + val imgUrl: String = "", +) diff --git a/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapUiState.kt b/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapUiState.kt index 28bfd673..6cb0cdc0 100644 --- a/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapUiState.kt +++ b/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapUiState.kt @@ -1,23 +1,23 @@ package com.unifest.android.feature.map.viewmodel import androidx.compose.ui.text.input.TextFieldValue -import com.unifest.android.core.domain.entity.BoothDetailEntity -import com.unifest.android.core.domain.entity.BoothSpot import com.unifest.android.core.domain.entity.Festival +import com.unifest.android.feature.map.model.BoothDetailModel import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf data class MapUiState( val selectedSchoolName: String = "", + val booths: ImmutableList = persistentListOf(), + val selectedBooths: ImmutableList = persistentListOf(), val boothSearchText: TextFieldValue = TextFieldValue(), val festivalSearchText: TextFieldValue = TextFieldValue(), - val boothSpots: ImmutableList = persistentListOf(), - val boothList: ImmutableList = persistentListOf(), - val isFestivalSearchBottomSheetVisible: Boolean = false, val interestedFestivals: MutableList = mutableListOf(), val festivalSearchResults: ImmutableList = persistentListOf(), val isSearchMode: Boolean = false, val isEditMode: Boolean = false, val isPopularMode: Boolean = false, + val isBoothSelectionMode: Boolean = false, + val isFestivalSearchBottomSheetVisible: Boolean = false, val isInterestedFestivalDeleteDialogVisible: Boolean = false, ) diff --git a/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt b/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt index ac43a603..c89ab9c9 100644 --- a/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt +++ b/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt @@ -3,8 +3,9 @@ package com.unifest.android.feature.map.viewmodel import androidx.compose.ui.text.input.TextFieldValue import androidx.lifecycle.ViewModel import com.unifest.android.core.domain.entity.BoothDetailEntity -import com.unifest.android.core.domain.entity.BoothSpot import com.unifest.android.core.domain.entity.Festival +import com.unifest.android.feature.map.mapper.toModel +import com.unifest.android.feature.map.model.BoothDetailModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList @@ -20,37 +21,89 @@ class MapViewModel @Inject constructor() : ViewModel() { val uiState: StateFlow = this._uiState.asStateFlow() init { - val boothList = mutableListOf() - repeat(5) { - boothList.add( - BoothDetailEntity( - id = it.toLong(), - name = "컴공 주점", - category = "", - description = "저희 주점은 일본 이자카야를 모티브로 만든 컴공인을 위한 주점입니다. 100번째 방문자에게 깜짝 선물 증정 이벤트를 하고 있으니 많은 관심 부탁드려요~!", - warning = "", - location = "청심대 앞", - latitude = 0f, - longitude = 0f, - menus = emptyList(), - ), - ) - } + val booths = listOf( + BoothDetailEntity( + id = 1L, + name = "컴공 주점", + category = "", + description = "저희 주점은 일본 이자카야를 모티브로 만든 컴공인을 위한 주점입니다. 100번째 방문자에게 깜짝 선물 증정 이벤트를 하고 있으니 많은 관심 부탁드려요~!", + warning = "", + location = "청심대 앞", + latitude = 37.54053013863604F, + longitude = 127.07505652524804F, + ), + BoothDetailEntity( + id = 2L, + name = "학생회 부스", + category = "", + description = "저희 주점은 일본 이자카야를 모티브로 만든 컴공인을 위한 주점입니다. 100번째 방문자에게 깜짝 선물 증정 이벤트를 하고 있으니 많은 관심 부탁드려요~!", + location = "청심대 앞", + latitude = 37.54111712868565F, + longitude = 127.07839319326257F, + ), + BoothDetailEntity( + id = 3L, + name = "컴공 주점", + category = "", + description = "저희 주점은 일본 이자카야를 모티브로 만든 컴공인을 위한 주점입니다. 100번째 방문자에게 깜짝 선물 증정 이벤트를 하고 있으니 많은 관심 부탁드려요~!", + location = "청심대 앞", + latitude = 37.5414744247141F, + longitude = 127.07779237844323F, + ), + BoothDetailEntity( + id = 4L, + name = "학생회 부스", + category = "", + description = "저희 주점은 일본 이자카야를 모티브로 만든 컴공인을 위한 주점입니다. 100번째 방문자에게 깜짝 선물 증정 이벤트를 하고 있으니 많은 관심 부탁드려요~!", + location = "청심대 앞", + latitude = 37.54224856023523F, + longitude = 127.07605430700158F, + ), + BoothDetailEntity( + id = 5L, + name = "컴공 주점", + category = "", + description = "저희 주점은 일본 이자카야를 모티브로 만든 컴공인을 위한 주점입니다. 100번째 방문자에게 깜짝 선물 증정 이벤트를 하고 있으니 많은 관심 부탁드려요~!", + location = "청심대 앞", + latitude = 37.54003672313541F, + longitude = 127.07653710462426F, + ), + BoothDetailEntity( + id = 6L, + name = "학생회 부스", + category = "", + description = "저희 주점은 일본 이자카야를 모티브로 만든 컴공인을 위한 주점입니다. 100번째 방문자에게 깜짝 선물 증정 이벤트를 하고 있으니 많은 관심 부탁드려요~!", + location = "청심대 앞", + latitude = 37.53998567996623F, + longitude = 37.53998567996623F, + ), + BoothDetailEntity( + id = 7L, + name = "컴공 주점", + category = "", + description = "저희 주점은 일본 이자카야를 모티브로 만든 컴공인을 위한 주점입니다. 100번째 방문자에게 깜짝 선물 증정 이벤트를 하고 있으니 많은 관심 부탁드려요~!", + location = "청심대 앞", + latitude = 37.54152546686414F, + longitude = 127.07353303052759F, + ), + BoothDetailEntity( + id = 8L, + name = "학생회 부스", + category = "", + description = "저희 주점은 일본 이자카야를 모티브로 만든 컴공인을 위한 주점입니다. 100번째 방문자에게 깜짝 선물 증정 이벤트를 하고 있으니 많은 관심 부탁드려요~!", + location = "청심대 앞", + latitude = 37.54047909580466F, + longitude = 127.07398364164209F, + ), + ) _uiState.update { it.copy( selectedSchoolName = "건국대학교", - boothSpots = persistentListOf( - BoothSpot(1L, 37.54053013863604, 127.07505652524804), - BoothSpot(2L, 37.54111712868565, 127.07839319326257), - BoothSpot(3L, 37.5414744247141, 127.07779237844323), - BoothSpot(4L, 37.54224856023523, 127.07605430700158), - BoothSpot(5L, 37.54003672313541, 127.07653710462426), - BoothSpot(6L, 37.53998567996623, 37.53998567996623), - BoothSpot(7L, 37.54152546686414, 127.07353303052759), - BoothSpot(8L, 37.54047909580466, 127.07398364164209), - ), - boothList = boothList.toImmutableList(), + booths = booths + .map { booth -> booth.toModel() } + .toImmutableList(), + selectedBooths = persistentListOf(), interestedFestivals = mutableListOf( Festival("https://picsum.photos/36", "서울대학교", "설대축제", "05.06-05.08"), Festival("https://picsum.photos/36", "연세대학교", "연대축제", "05.06-05.08"), @@ -106,8 +159,78 @@ class MapViewModel @Inject constructor() : ViewModel() { } fun setEnablePopularMode() { + val popularBooths = listOf( + BoothDetailEntity( + id = 1L, + name = "컴공 주점", + category = "", + description = "저희 주점은 일본 이자카야를 모티브로 만든 컴공인을 위한 주점입니다. 100번째 방문자에게 깜짝 선물 증정 이벤트를 하고 있으니 많은 관심 부탁드려요~!", + warning = "", + location = "청심대 앞", + latitude = 37.54053013863604F, + longitude = 127.07505652524804F, + ), + BoothDetailEntity( + id = 2L, + name = "학생회 부스", + category = "", + description = "저희 주점은 일본 이자카야를 모티브로 만든 컴공인을 위한 주점입니다. 100번째 방문자에게 깜짝 선물 증정 이벤트를 하고 있으니 많은 관심 부탁드려요~!", + location = "청심대 앞", + latitude = 37.54111712868565F, + longitude = 127.07839319326257F, + ), + BoothDetailEntity( + id = 3L, + name = "컴공 주점", + category = "", + description = "저희 주점은 일본 이자카야를 모티브로 만든 컴공인을 위한 주점입니다. 100번째 방문자에게 깜짝 선물 증정 이벤트를 하고 있으니 많은 관심 부탁드려요~!", + location = "청심대 앞", + latitude = 37.5414744247141F, + longitude = 127.07779237844323F, + ), + BoothDetailEntity( + id = 4L, + name = "학생회 부스", + category = "", + description = "저희 주점은 일본 이자카야를 모티브로 만든 컴공인을 위한 주점입니다. 100번째 방문자에게 깜짝 선물 증정 이벤트를 하고 있으니 많은 관심 부탁드려요~!", + location = "청심대 앞", + latitude = 37.54224856023523F, + longitude = 127.07605430700158F, + ), + BoothDetailEntity( + id = 5L, + name = "컴공 주점", + category = "", + description = "저희 주점은 일본 이자카야를 모티브로 만든 컴공인을 위한 주점입니다. 100번째 방문자에게 깜짝 선물 증정 이벤트를 하고 있으니 많은 관심 부탁드려요~!", + location = "청심대 앞", + latitude = 37.54003672313541F, + longitude = 127.07653710462426F, + ), + ) + + _uiState.update { + it.copy( + selectedBooths = popularBooths + .map { popularBooth -> popularBooth.toModel() } + .toImmutableList(), + isPopularMode = !_uiState.value.isPopularMode, + isBoothSelectionMode = false, + ) + } + } + + fun setBoothSelectionMode(flag: Boolean) { + _uiState.update { + it.copy( + isPopularMode = false, + isBoothSelectionMode = flag, + ) + } + } + + fun updateSelectedBooths(booths: List) { _uiState.update { - it.copy(isPopularMode = !_uiState.value.isPopularMode) + it.copy(selectedBooths = booths.toImmutableList()) } } From a8f7b41461423ac45fddb524fe6557a9bf44b336 Mon Sep 17 00:00:00 2001 From: JI HUN LEE <51016231+easyhooon@users.noreply.github.com> Date: Fri, 12 Apr 2024 03:22:19 +0900 Subject: [PATCH 12/16] [chore] code style check success --- .../core/designsystem/component/SearchTextField.kt | 2 +- .../core/designsystem/component/TopAppBar.kt | 2 +- .../com/unifest/android/feature/main/MainScreen.kt | 1 - feature/map/build.gradle.kts | 1 + .../android/feature/map/model/BoothDetailModel.kt | 13 +++++++------ 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/SearchTextField.kt b/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/SearchTextField.kt index 56de2c9a..137baef4 100644 --- a/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/SearchTextField.kt +++ b/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/SearchTextField.kt @@ -39,7 +39,7 @@ import com.unifest.android.core.designsystem.theme.UnifestTheme val unifestTextSelectionColors = TextSelectionColors( handleColor = Color(0xFFF5687E), - backgroundColor = Color(0xFFFAB3BE) + backgroundColor = Color(0xFFFAB3BE), ) @Composable diff --git a/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/TopAppBar.kt b/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/TopAppBar.kt index 547fd205..ddc25238 100644 --- a/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/TopAppBar.kt +++ b/core/designsystem/src/main/kotlin/com/unifest/android/core/designsystem/component/TopAppBar.kt @@ -66,7 +66,7 @@ fun UnifestTopAppBar( Icon( imageVector = imageVector, contentDescription = navigationIconContentDescription, - tint = Color.Unspecified + tint = Color.Unspecified, ) } } diff --git a/feature/main/src/main/kotlin/com/unifest/android/feature/main/MainScreen.kt b/feature/main/src/main/kotlin/com/unifest/android/feature/main/MainScreen.kt index df44cb9f..bb0c7615 100644 --- a/feature/main/src/main/kotlin/com/unifest/android/feature/main/MainScreen.kt +++ b/feature/main/src/main/kotlin/com/unifest/android/feature/main/MainScreen.kt @@ -111,7 +111,6 @@ internal fun MainScreen( } } - @Composable private fun MainBottomBar( visible: Boolean, diff --git a/feature/map/build.gradle.kts b/feature/map/build.gradle.kts index 497bfc96..768b2241 100644 --- a/feature/map/build.gradle.kts +++ b/feature/map/build.gradle.kts @@ -3,6 +3,7 @@ plugins { alias(libs.plugins.unifest.android.feature) alias(libs.plugins.compose.investigator) + id("kotlin-parcelize") } android { diff --git a/feature/map/src/main/kotlin/com/unifest/android/feature/map/model/BoothDetailModel.kt b/feature/map/src/main/kotlin/com/unifest/android/feature/map/model/BoothDetailModel.kt index 2b6b2258..3e553fd8 100644 --- a/feature/map/src/main/kotlin/com/unifest/android/feature/map/model/BoothDetailModel.kt +++ b/feature/map/src/main/kotlin/com/unifest/android/feature/map/model/BoothDetailModel.kt @@ -1,11 +1,11 @@ package com.unifest.android.feature.map.model -import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.persistentListOf +import android.os.Parcelable +import kotlinx.parcelize.Parcelize import ted.gun0912.clustering.clustering.TedClusterItem import ted.gun0912.clustering.geometry.TedLatLng -import java.io.Serializable +@Parcelize data class BoothDetailModel( val id: Long = 0L, val name: String = "", @@ -15,16 +15,17 @@ data class BoothDetailModel( val location: String = "", val latitude: Double = 0.toDouble(), val longitude: Double = 0.toDouble(), - val menus: ImmutableList = persistentListOf(), -): Serializable, TedClusterItem { + val menus: List = emptyList(), +) : Parcelable, TedClusterItem { override fun getTedLatLng(): TedLatLng { return TedLatLng(latitude, longitude) } } +@Parcelize data class MenuModel( val id: Long = 0L, val name: String = "", val price: Int = 0, val imgUrl: String = "", -) +) : Parcelable From 515e1d364612445f8a3de508f714d4505d7459a5 Mon Sep 17 00:00:00 2001 From: Jeong Sang Hoon Date: Fri, 12 Apr 2024 15:09:16 +0900 Subject: [PATCH 13/16] =?UTF-8?q?[fix]=20=EB=B6=80=EC=8A=A4=20=EC=9C=84?= =?UTF-8?q?=EC=B9=98=20=ED=99=94=EB=A9=B4=EC=97=90=20=EC=A7=84=EC=9E=85=20?= =?UTF-8?q?=ED=9B=84=20status=20bar=20=EC=98=81=EC=97=AD=EC=9D=98=20icon?= =?UTF-8?q?=20=EC=9D=B4=20=EB=B3=B4=EC=9D=B4=EC=A7=80=20=EC=95=8A=EB=8A=94?= =?UTF-8?q?=20=EC=9D=B4=EC=8A=88=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/feature/booth/BoothLocationScreen.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/feature/booth/src/main/kotlin/com/unifest/android/feature/booth/BoothLocationScreen.kt b/feature/booth/src/main/kotlin/com/unifest/android/feature/booth/BoothLocationScreen.kt index 2a3b2417..cf0a8ac6 100644 --- a/feature/booth/src/main/kotlin/com/unifest/android/feature/booth/BoothLocationScreen.kt +++ b/feature/booth/src/main/kotlin/com/unifest/android/feature/booth/BoothLocationScreen.kt @@ -17,6 +17,7 @@ import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -43,6 +44,7 @@ import com.unifest.android.core.designsystem.theme.UnifestTheme import com.unifest.android.core.domain.entity.BoothDetailEntity import com.unifest.android.feature.booth.viewmodel.BoothUiState import com.unifest.android.feature.booth.viewmodel.BoothViewModel +import tech.thdev.compose.exteions.system.ui.controller.rememberExSystemUiController @Composable fun BoothLocationRoute( @@ -50,6 +52,16 @@ fun BoothLocationRoute( viewModel: BoothViewModel = hiltViewModel(), ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() + val systemUiController = rememberExSystemUiController() + + DisposableEffect(systemUiController) { + systemUiController.setSystemBarsColor( + color = Color.White, + darkIcons = true, + isNavigationBarContrastEnforced = false, + ) + onDispose {} + } BoothLocationScreen( uiState = uiState, From 3c8264635c94de37fd4d6a210f223a96f699d87a Mon Sep 17 00:00:00 2001 From: Jeong Sang Hoon Date: Fri, 12 Apr 2024 15:26:41 +0900 Subject: [PATCH 14/16] =?UTF-8?q?[fix]=20=EB=B6=80=EC=8A=A4=20=EC=B9=B4?= =?UTF-8?q?=EB=93=9C=20=EC=B6=9C=ED=98=84=EC=9D=B4=20=EC=96=B4=EC=83=89?= =?UTF-8?q?=ED=95=98=EB=8D=98=20=EB=AC=B8=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/unifest/android/feature/map/viewmodel/MapViewModel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt b/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt index c89ab9c9..fbe99160 100644 --- a/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt +++ b/feature/map/src/main/kotlin/com/unifest/android/feature/map/viewmodel/MapViewModel.kt @@ -222,7 +222,7 @@ class MapViewModel @Inject constructor() : ViewModel() { fun setBoothSelectionMode(flag: Boolean) { _uiState.update { it.copy( - isPopularMode = false, + isPopularMode = flag, isBoothSelectionMode = flag, ) } From 2d8ddd66d41f995b4a8c68b854520687171905d6 Mon Sep 17 00:00:00 2001 From: JI HUN LEE <51016231+easyhooon@users.noreply.github.com> Date: Fri, 12 Apr 2024 15:31:08 +0900 Subject: [PATCH 15/16] =?UTF-8?q?[style]=20ranking=20badge=20design=20?= =?UTF-8?q?=EB=AF=B8=EC=84=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/unifest/android/feature/map/MapScreen.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt b/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt index 06799f91..e6f929c1 100644 --- a/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt +++ b/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt @@ -148,9 +148,9 @@ internal fun MapScreen( } val pagerState = rememberPagerState(pageCount = { uiState.selectedBooths.size }) Box { - // TODO 지도 중앙 위치 조정 // TODO 같은 속성의 Marker 들만 클러스터링 되도록 구현 // TODO 클러스터링 마커 커스텀 + // TODO 지도 중앙 위치 조정 NaverMap( cameraPositionState = cameraPositionState, uiSettings = MapUiSettings( @@ -410,9 +410,9 @@ fun BoothCard( fun RankingBadge(ranking: Int) { Box( modifier = Modifier - .size(36.dp) - .clip(CircleShape) + .size(width = 43.dp, height = 45.dp) .padding(start = 7.dp, top = 9.dp) + .clip(CircleShape) .background(Color(0xFFF5687E), CircleShape), contentAlignment = Alignment.TopStart, ) { From 3fd7140794493eaa4a2c9f0cc8486333a978b532 Mon Sep 17 00:00:00 2001 From: Jeong Sang Hoon Date: Fri, 12 Apr 2024 15:37:50 +0900 Subject: [PATCH 16/16] =?UTF-8?q?[design]=20=EB=B6=80=EC=8A=A4=20=ED=95=84?= =?UTF-8?q?=ED=84=B0=20=EC=B9=A9=EC=8A=A4=20=ED=8C=A8=EB=94=A9=20=EC=A1=B0?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/unifest/android/feature/map/MapScreen.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt b/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt index e6f929c1..ff19a19e 100644 --- a/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt +++ b/feature/map/src/main/kotlin/com/unifest/android/feature/map/MapScreen.kt @@ -309,7 +309,11 @@ fun MapTopAppBar( Spacer(modifier = Modifier.height(10.dp)) BoothFilterChips( onChipClick = {}, - modifier = Modifier.padding(start = 22.dp), + modifier = Modifier + .padding(horizontal = 10.dp) + .clip( + RoundedCornerShape(16.dp), + ), ) Spacer(modifier = Modifier.height(10.dp)) }