Skip to content

Commit

Permalink
[UI] #60 마커 클릭 시 마커 확대 및 관련 스토어 표시
Browse files Browse the repository at this point in the history
  • Loading branch information
ows3090 committed May 4, 2024
1 parent 448f01d commit 0008bfd
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ private val PlaceModalSheetButtonRadius = 12.dp
fun PlaceModalSheet(
sheetState: SheetState = rememberModalBottomSheetState(),
location: String,
distance: Float,
distance: Double,
onSearchLocation: (String) -> Unit = {},
onCopyAddress: (String) -> Unit = {},
onDismiss: () -> Unit
onDismiss: () -> Unit = {}
) {
ModalBottomSheet(
onDismissRequest = onDismiss,
Expand Down Expand Up @@ -147,7 +147,7 @@ private fun PlaceModalSheetPreview() {
if (isShowModal) {
PlaceModalSheet(
location = "스타벅스 상봉점",
distance = 0.1f,
distance = 0.1,
onDismiss = { isShowModal = false }
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ data class GifticonCountResponse(

data class GifticonCountResponseBody(
val count: Int
)
)
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ data class SearchPlaceResponse(
val category_group_code: String,
val category_group_name: String,
val category_name: String,
val distance: String,
val distance: Int,
val id: String,
val phone: String,
val place_name: String,
Expand Down
95 changes: 62 additions & 33 deletions core/utility/src/main/java/com/yapp/buddycon/utility/Location.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.content.Context
import android.location.Location
import com.google.android.gms.location.LocationServices
import com.kakao.vectormap.LatLng
import com.kakao.vectormap.label.Label
import com.kakao.vectormap.label.LabelManager
import com.kakao.vectormap.label.LabelOptions
import com.kakao.vectormap.label.LabelStyle
Expand All @@ -25,44 +26,72 @@ fun getCurrentLocation(
}
}

// 지도 위 마커 추가
fun getLocationLabel(
// 지도 위 마커 추가 및 반환
fun getLocationLabels(
labelManager: LabelManager,
searchPlaceModels: List<SearchPlaceModel>
) {
fun GifticonStore?.getDrawableRes() = when (this) {
GifticonStore.STARBUCKS,
GifticonStore.TWOSOME_PLACE,
GifticonStore.ANGELINUS,
GifticonStore.MEGA_COFFEE,
GifticonStore.COFFEE_BEAN,
GifticonStore.GONG_CHA,
GifticonStore.BASKIN_ROBBINS -> {
R.drawable.ic_coffee
): Map<SearchPlaceModel, Label?> {
return searchPlaceModels.map { model ->
model to labelManager.layer?.addLabel(
LabelOptions.from(LatLng.from(model.y.toDouble(), model.x.toDouble()))
.setStyles(
labelManager.addLabelStyles(
LabelStyles.from(
LabelStyle.from(
GifticonStore.values().find { it.value == model.store }.getDrawableRes()
)
)
)
)
).apply {
this?.isClickable = true
}
}.toMap()
}

GifticonStore.MACDONALD -> {
R.drawable.ic_fastfood
}
fun scaleToLabel(
label: Label,
scale: Float
) {
label.scaleTo(scale, scale)
}

else -> {
R.drawable.ic_store
}
fun GifticonStore?.getDrawableRes() = when (this) {
GifticonStore.STARBUCKS,
GifticonStore.TWOSOME_PLACE,
GifticonStore.ANGELINUS,
GifticonStore.MEGA_COFFEE,
GifticonStore.COFFEE_BEAN,
GifticonStore.GONG_CHA,
GifticonStore.BASKIN_ROBBINS -> {
R.drawable.ic_coffee
}

labelManager.layer
?.addLabels(
searchPlaceModels.map { model ->
LabelOptions.from(LatLng.from(model.y.toDouble(), model.x.toDouble()))
.setStyles(
labelManager.addLabelStyles(
LabelStyles.from(
LabelStyle.from(
GifticonStore.values().find { it.value == model.store }.getDrawableRes()
)
)
)
)
}
)
GifticonStore.MACDONALD -> {
R.drawable.ic_fastfood
}

else -> {
R.drawable.ic_store
}
}

fun GifticonStore?.getExpandedDrawableRes() = when (this) {
GifticonStore.STARBUCKS,
GifticonStore.TWOSOME_PLACE,
GifticonStore.ANGELINUS,
GifticonStore.MEGA_COFFEE,
GifticonStore.COFFEE_BEAN,
GifticonStore.GONG_CHA,
GifticonStore.BASKIN_ROBBINS -> {
R.drawable.ic_location
}

GifticonStore.MACDONALD -> {
R.drawable.ic_location
}

else -> {
R.drawable.ic_location
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ data class GifticonModel(
val category: GifticonStore = GifticonStore.OTHERS,
val name: String = "",
val expirationTime: Long = 0L
)
)
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ data class SearchPlaceModel(
val category_group_code: String,
val category_group_name: String,
val category_name: String,
val distance: String,
val distance: Int,
val id: String,
val phone: String,
val place_name: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ import com.yapp.buddycon.domain.model.type.GifticonStore
import com.yapp.buddycon.utility.RequestLocationPermission
import com.yapp.buddycon.utility.checkLocationPermission
import com.yapp.buddycon.utility.getCurrentLocation
import com.yapp.buddycon.utility.getLocationLabel
import com.yapp.buddycon.utility.getLocationLabels
import timber.log.Timber
import java.text.SimpleDateFormat

Expand Down Expand Up @@ -337,7 +337,7 @@ private fun GifticonMap(
// 지도 노출과 동시에 라벨 표시
location?.let { location ->
kakaoMap.labelManager?.let { manager ->
getLocationLabel(
getLocationLabels(
labelManager = manager,
searchPlaceModels = searchPlaceModels
)
Expand Down
38 changes: 32 additions & 6 deletions feature/map/src/main/java/com/yapp/buddycon/map/MapScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ import com.kakao.vectormap.KakaoMapReadyCallback
import com.kakao.vectormap.LatLng
import com.kakao.vectormap.MapLifeCycleCallback
import com.kakao.vectormap.MapView
import com.kakao.vectormap.label.Label
import com.yapp.buddycon.designsystem.R
import com.yapp.buddycon.designsystem.component.appbar.TopAppBarWithNotification
import com.yapp.buddycon.designsystem.component.button.CategoryButton
import com.yapp.buddycon.designsystem.component.dialog.DefaultDialog
import com.yapp.buddycon.designsystem.component.modal.GifticonInfoListModalSheet
import com.yapp.buddycon.designsystem.component.modal.GifticonInfoModalSheetContent
import com.yapp.buddycon.designsystem.component.modal.PlaceModalSheet
import com.yapp.buddycon.designsystem.component.snackbar.BuddyConSnackbar
import com.yapp.buddycon.designsystem.component.snackbar.showBuddyConSnackBar
import com.yapp.buddycon.designsystem.theme.Black
Expand All @@ -68,8 +70,9 @@ import com.yapp.buddycon.domain.model.type.GifticonStore
import com.yapp.buddycon.utility.RequestLocationPermission
import com.yapp.buddycon.utility.checkLocationPermission
import com.yapp.buddycon.utility.getCurrentLocation
import com.yapp.buddycon.utility.getLocationLabel
import com.yapp.buddycon.utility.getLocationLabels
import com.yapp.buddycon.utility.isDeadLine
import com.yapp.buddycon.utility.scaleToLabel
import timber.log.Timber

// TopAppBarHeight(52) + BottomNavigationBarHeight(72) + MapCategoryTabHeight(60)
Expand Down Expand Up @@ -244,6 +247,7 @@ private fun MapBottomSheet(
}
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun MapContent(
modifier: Modifier = Modifier,
Expand All @@ -256,7 +260,7 @@ private fun MapContent(
val context = LocalContext.current
val coroutineScope = rememberCoroutineScope()

// 위치 권한
// 위치 권한
var isGrantedPermission by remember { mutableStateOf(checkLocationPermission(context)) }

// 위치 권한 유도 팝업
Expand All @@ -266,7 +270,9 @@ private fun MapContent(
var requestPermissionEvent by remember { mutableStateOf(false) }

val store by mapViewModel.store.collectAsStateWithLifecycle()
val placeLabels by mapViewModel.placeLabels.collectAsStateWithLifecycle()
var map by remember { mutableStateOf<KakaoMap?>(null) }
var clickedLabel by remember { mutableStateOf<Label?>(null) }

// 권한 있을 경우 -> 현재 위치 요청
LaunchedEffect(Unit) {
Expand All @@ -276,13 +282,33 @@ private fun MapContent(
}

LaunchedEffect(mapSearchPlace) {
Timber.d("mapSearchPlace ${mapSearchPlace.searchPlaceModels.size}")
// 지도가 노출되고 나서 라벨 표시, 라벨과 함께 표시하게되면 mapReady 오랜 시간 소요
map?.labelManager?.clearAll()
map?.labelManager?.let { manager ->
getLocationLabel(
labelManager = manager,
searchPlaceModels = mapSearchPlace.searchPlaceModels
mapViewModel.setPlaceLabels(
getLocationLabels(
labelManager = manager,
searchPlaceModels = mapSearchPlace.searchPlaceModels
)
)
}
map?.setOnLabelClickListener { kakaoMap, layer, label ->
clickedLabel = label
scaleToLabel(label, 1.5f)
}
}

if (clickedLabel != null) {
placeLabels.entries.find { it.value == clickedLabel }?.key?.let { model ->
PlaceModalSheet(
location = model.place_name,
distance = (model.distance / 1000.0),
onDismiss = {
clickedLabel?.let { label ->
scaleToLabel(label, 1f)
}
clickedLabel = null
}
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.PagingData
import androidx.paging.cachedIn
import com.kakao.vectormap.label.Label
import com.yapp.buddycon.domain.model.gifticon.AvailableGifticon
import com.yapp.buddycon.domain.model.kakao.SearchPlaceModel
import com.yapp.buddycon.domain.model.type.GifticonStore
import com.yapp.buddycon.domain.model.type.SortType
import com.yapp.buddycon.domain.repository.GifticonRepository
Expand Down Expand Up @@ -57,6 +59,9 @@ class MapViewModel @Inject constructor(
private val _gifticonExistStore = MutableStateFlow<List<GifticonStore>>(listOf())
val gifticonExistStore = _gifticonExistStore.asStateFlow()

private val _placeLabels = MutableStateFlow<Map<SearchPlaceModel, Label?>>(mapOf())
val placeLabels = _placeLabels.asStateFlow()

init {
fetchAvailableGifticon()
getGifticonCount()
Expand Down Expand Up @@ -124,4 +129,8 @@ class MapViewModel @Inject constructor(
_deadLineCount.value = deadLineCount
_gifticonExistStore.value = gifticonStores
}

fun setPlaceLabels(placeLabels: Map<SearchPlaceModel, Label?>) {
_placeLabels.value = placeLabels
}
}

0 comments on commit 0008bfd

Please sign in to comment.