Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
94f40ca
[feat] #52 feature:map:impl data-api 의존성 추가
Ojongseok Jan 25, 2026
a04b90e
[feat] #52 네컷 사진 브랜드 API 연동
Ojongseok Jan 25, 2026
7dc286f
[feat] #52 특정 좌표 기준 가까운 브랜드 조회 API 연동
Ojongseok Jan 25, 2026
b71e35f
[feat] #52 Service, Repository 네이밍 변경
Ojongseok Jan 25, 2026
a30876d
[feat] #52 다각형 영역에 대한 포토부스 조회 API 연동
Ojongseok Jan 25, 2026
38b4008
[feat] #52 API Response 지도 내 UI 컴포넌트 연결
Ojongseok Jan 25, 2026
2cbfa0a
[feat] #52 현위치와 특정 좌표 사이 거리 계산하는 확장함수 추가
Ojongseok Jan 25, 2026
3dfb4fe
Merge branch 'develop' of https://github.com/YAPP-Github/27th-App-Tea…
Ojongseok Jan 26, 2026
27dcf14
[feat] #52 좌표 기반 포토부스 조회 API 위경도 필드 nullable하게 수정
Ojongseok Jan 26, 2026
e97b365
[feat] #52 마커 내 포토부스 이미지가 렌더링되지 않고 PlaceHolder 이미지로 노출되는 현상 수정
Ojongseok Jan 26, 2026
4822016
[feat] #52 위치 권한 없을 경우 기본 카메라 위치 강남역으로 설정
Ojongseok Jan 26, 2026
daa8feb
[feat] #52 가까운 브랜드 선택 시 마커 생기도록 수정
Ojongseok Jan 26, 2026
2067c87
[feat] #52 1km 이내 포토부스 없을 경우 텍스트 노출
Ojongseok Jan 26, 2026
54a4985
[feat] #52 현위치 조회중, API 응답 중 LoadingDialog 노출
Ojongseok Jan 26, 2026
8034cbf
[feat] #52 위치 권한 수동 허용 후 앱 복귀 시 현위치로 카메라 이동 추가
Ojongseok Jan 26, 2026
6d38d13
[feat] #52 PhotoBooth.kt 내 isFocused 필드 추가 및 불필요한 uiState 제거
Ojongseok Jan 26, 2026
3307817
[feat] #52 카드 상세 터치 시 마커로 카메라 이동
Ojongseok Jan 26, 2026
8d19f7a
[feat] #52 거리 계산 확장함수 추가 및 포맷 변경
Ojongseok Jan 26, 2026
d2a301b
[feat] #52 카드 상세의 현위치 터치 시 카메라 이동 및 패널 DragLevel.FIRST로 변경
Ojongseok Jan 26, 2026
230ebb9
[feat] #52 네이버 지도 렌더링 및 Intent 처리 로직 개선
Ojongseok Jan 26, 2026
08d7712
[feat] #52 권한 허용 여부 네이밍 변경
Ojongseok Jan 26, 2026
0f7f1c8
[feat] #52 길찾기 로직 개선
Ojongseok Jan 26, 2026
c391b17
[feat] #52 초기 진입 시 권한 여부에 따른 사각형 포토부스 API 요청 로직 추가
Ojongseok Jan 26, 2026
509791d
[feat] #52 불필요한 가까운 포토부스 조회 API 호출 제거
Ojongseok Jan 26, 2026
2095118
[build] #52 detekt 룰 적용
Ojongseok Jan 26, 2026
e635dc3
[feat] #52 브랜드 체크 시 지도 마커/가까운 포토부스 노출 로직 통일
Ojongseok Jan 26, 2026
52b2e33
[feat] #52 네이밍 통일, 불필요한 분기 제거
Ojongseok Jan 26, 2026
4bb5f88
[feat] #52 뷰모델 코드 단축
Ojongseok Jan 26, 2026
a50c236
[feat] #52 불필요한 coroutineScope 제거
Ojongseok Jan 27, 2026
497d75e
[feat] #52 불필요한 상수 제거
Ojongseok Jan 27, 2026
48e42da
[feat] #52 트래킹 상태에 따른 카메라 전환 로직 개선
Ojongseok Jan 27, 2026
c644b4c
[feat] #52 불필요한 코드 제거 및 네이밍 변경
Ojongseok Jan 27, 2026
7d1556b
[feat] #52 브랜드 이미지 비트맵 변환 로직 분리
Ojongseok Jan 27, 2026
3a37a96
[build] #52 detekt 룰 적용
Ojongseok Jan 27, 2026
1fd3c33
[feat] #52 위치 권한 없을경우 초기 다각형 조회 로직 수정
Ojongseok Jan 27, 2026
c8228e2
[build] #52 detekt 룰 적용
Ojongseok Jan 27, 2026
141e926
[chore] #52 불필요한 코드블럭 제거
Ojongseok Jan 27, 2026
298d9ca
[design] #52 BottomNavigationBar 디자인 변경사항 반영
Ojongseok Jan 27, 2026
c7490cc
[design] #52 BottomNavigationBar 디자인 변경사항 다시 반영
Ojongseok Jan 27, 2026
d50eed1
[fix] #52 위치 권한 요청 Effect 네이밍 변경
Ojongseok Jan 27, 2026
4c8f5b1
[fix] #60 '카드 상세' PhotoBoothDetailContent, PhotoBoothDetailCard 네이밍 변경
Ojongseok Jan 28, 2026
dbca263
[fix] #60 getPlaceName() internal 키워드 추가
Ojongseok Jan 28, 2026
c65ae2d
[fix] #60 :feature:map:impl data-api 의존성 제거
Ojongseok Jan 28, 2026
d2a1637
[fix] #60 위치 권한 영구거부 체크에 사용되는 불필요한 변수 제거
Ojongseok Jan 28, 2026
5def27d
[feat] #60 MapViewModel @ApplicationContext 주입
Ojongseok Jan 28, 2026
d6f327a
[feat] #60 feature:map:impl services-location 의존성 추가
Ojongseok Jan 28, 2026
f5ad66f
[feat] #60 현위치 조회 및 카메라 이동 로직 수정
Ojongseok Jan 28, 2026
445a373
[feat] #60 onIntent 내에서 내부 함수로 전달하는 파라미터 수정
Ojongseok Jan 28, 2026
989516f
[fix] #60 위치 권한 상태에 따른 현위치 이동 로직 수정
Ojongseok Jan 28, 2026
daba28e
[fix] #60 네트워크 브랜드 이미지 캐싱 로직 변경
Ojongseok Jan 28, 2026
61ad8a0
[fix] #60 getFusedLocationProviderClient 위치 조회 함수 분리
Ojongseok Jan 28, 2026
a29e9e4
[fix] #60 이미지 비트맵 변환 코루틴 launch -> async로 병렬 수행되도록 변경
Ojongseok Jan 28, 2026
42f6ab1
[fix] #60 cont -> coroutine 네이밍 수정
Ojongseok Jan 28, 2026
0bfdecb
[fix] #60 handleClickBrand() 변수명 수정
Ojongseok Jan 28, 2026
a2ed3f7
[fix] #60 '현 위치에서 탐색' 버튼 선택 시 안보이도록 수정
Ojongseok Jan 29, 2026
a02b8ba
[build] #60 detekt 룰 적용
Ojongseok Jan 29, 2026
7460bd7
Merge pull request #68 from YAPP-Github/refactor/#65-map-refactor
Ojongseok Jan 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ fun BottomNavigationBar(
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 20.dp),
.padding(horizontal = 19.5.dp, vertical = 2.dp),
horizontalArrangement = Arrangement.spacedBy(16.dp),
) {
tabs.forEach { tab ->
Expand Down Expand Up @@ -86,12 +86,12 @@ fun BottomNavigationBarItem(
color = NekiTheme.colorScheme.white,
) {
Column(
modifier = Modifier.padding(vertical = 4.dp),
modifier = Modifier.padding(vertical = 1.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(4.dp),
) {
Icon(
modifier = Modifier.size(24.dp),
modifier = Modifier.size(26.dp),
imageVector = ImageVector.vectorResource(icon),
contentDescription = stringResource(tab.iconStringRes),
tint = iconColor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ object LocationPermissionManager {
Manifest.permission.ACCESS_COARSE_LOCATION,
)

fun hasLocationPermission(context: Context): Boolean {
fun isGrantedLocationPermission(context: Context): Boolean {
return ContextCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.neki.android.core.dataapi.repository

import com.neki.android.core.model.Brand
import com.neki.android.core.model.PhotoBooth

interface MapRepository {
suspend fun getBrands(): Result<List<Brand>>

suspend fun getPhotoBoothsByPoint(
longitude: Double?,
latitude: Double?,
radiusInMeters: Int,
brandIds: List<Long>,
): Result<List<PhotoBooth>>

suspend fun getPhotoBoothsByPolygon(
coordinates: List<Pair<Double, Double>>,
brandIds: List<Long>,
): Result<List<PhotoBooth>>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.neki.android.core.data.remote.api

import com.neki.android.core.data.remote.model.request.PhotoBoothPointRequest
import com.neki.android.core.data.remote.model.request.PhotoBoothPolygonRequest
import com.neki.android.core.data.remote.model.response.BasicResponse
import com.neki.android.core.data.remote.model.response.BrandResponse
import com.neki.android.core.data.remote.model.response.PhotoBoothPointResponse
import com.neki.android.core.data.remote.model.response.PhotoBoothPolygonResponse
import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.request.get
import io.ktor.client.request.post
import io.ktor.client.request.setBody
import javax.inject.Inject

class MapService @Inject constructor(
private val client: HttpClient,
) {
suspend fun getBrands(): BasicResponse<List<BrandResponse>> {
return client.get("/api/photo-booths/brand").body()
}

suspend fun getPhotoBoothsByPoint(
request: PhotoBoothPointRequest,
): BasicResponse<PhotoBoothPointResponse> {
return client.post("/api/photo-booths/point") {
setBody(request)
}.body()
}

suspend fun getPhotoBoothsByPolygon(
request: PhotoBoothPolygonRequest,
): BasicResponse<PhotoBoothPolygonResponse> {
return client.post("/api/photo-booths/polygon") {
setBody(request)
}.body()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.neki.android.core.data.remote.model.request

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class PhotoBoothPointRequest(
@SerialName("longitude") val longitude: Double?,
@SerialName("latitude") val latitude: Double?,
@SerialName("radiusInMeters") val radiusInMeters: Int,
@SerialName("brandIds") val brandIds: List<Long>,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.neki.android.core.data.remote.model.request

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class PhotoBoothPolygonRequest(
@SerialName("coordinates") val coordinates: List<Coordinate>,
@SerialName("brandIds") val brandIds: List<Long>,
)

@Serializable
data class Coordinate(
@SerialName("longitude") val longitude: Double,
@SerialName("latitude") val latitude: Double,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.neki.android.core.data.remote.model.response

import com.neki.android.core.model.Brand
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class BrandResponse(
@SerialName("id") val id: Long,
@SerialName("name") val name: String,
@SerialName("code") val code: String,
@SerialName("imageUrl") val imageUrl: String,
) {
internal fun toModel(): Brand = Brand(
id = id,
name = name,
code = code,
imageUrl = imageUrl,
)
}

internal fun List<BrandResponse>.toModels(): List<Brand> = map { it.toModel() }
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.neki.android.core.data.remote.model.response

import com.neki.android.core.model.PhotoBooth
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class PhotoBoothPointResponse(
@SerialName("items") val items: List<Item>,
) {
@Serializable
data class Item(
@SerialName("id") val id: Long,
@SerialName("brandName") val brandName: String,
@SerialName("branchName") val branchName: String,
@SerialName("address") val address: String,
@SerialName("longitude") val longitude: Double,
@SerialName("latitude") val latitude: Double,
@SerialName("distance") val distance: Int,
) {
internal fun toModel(): PhotoBooth = PhotoBooth(
id = id,
brandName = brandName,
branchName = branchName,
address = address,
longitude = longitude,
latitude = latitude,
distance = distance,
)
}

internal fun toModels(): List<PhotoBooth> = items.map { it.toModel() }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.neki.android.core.data.remote.model.response

import com.neki.android.core.model.PhotoBooth
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class PhotoBoothPolygonResponse(
@SerialName("items") val items: List<Item>,
) {
@Serializable
data class Item(
@SerialName("id") val id: Long,
@SerialName("brandName") val brandName: String,
@SerialName("branchName") val branchName: String,
@SerialName("address") val address: String,
@SerialName("longitude") val longitude: Double,
@SerialName("latitude") val latitude: Double,
) {
internal fun toModel(): PhotoBooth = PhotoBooth(
id = id,
brandName = brandName,
branchName = branchName,
address = address,
longitude = longitude,
latitude = latitude,
)
}

internal fun toModels(): List<PhotoBooth> = items.map { it.toModel() }
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import com.neki.android.core.data.auth.AuthEventManagerImpl
import com.neki.android.core.data.repository.impl.AuthRepositoryImpl
import com.neki.android.core.data.repository.impl.DataStoreRepositoryImpl
import com.neki.android.core.data.repository.impl.MediaUploadRepositoryImpl
import com.neki.android.core.data.repository.impl.MapRepositoryImpl
import com.neki.android.core.data.repository.impl.PhotoRepositoryImpl
import com.neki.android.core.data.repository.impl.TokenRepositoryImpl
import com.neki.android.core.dataapi.auth.AuthEventManager
import com.neki.android.core.dataapi.repository.AuthRepository
import com.neki.android.core.dataapi.repository.DataStoreRepository
import com.neki.android.core.dataapi.repository.MediaUploadRepository
import com.neki.android.core.dataapi.repository.MapRepository
import com.neki.android.core.dataapi.repository.PhotoRepository
import com.neki.android.core.dataapi.repository.TokenRepository
import dagger.Binds
Expand Down Expand Up @@ -57,4 +59,10 @@ internal interface RepositoryModule {
fun bindPhotoRepositoryImpl(
photoRepositoryImpl: PhotoRepositoryImpl,
): PhotoRepository

@Binds
@Singleton
fun bindMapRepositoryImpl(
mapRepositoryImpl: MapRepositoryImpl,
): MapRepository
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.neki.android.core.data.repository.impl

import com.neki.android.core.data.remote.api.MapService
import com.neki.android.core.data.remote.model.request.Coordinate
import com.neki.android.core.data.remote.model.request.PhotoBoothPointRequest
import com.neki.android.core.data.remote.model.request.PhotoBoothPolygonRequest
import com.neki.android.core.data.remote.model.response.toModels
import com.neki.android.core.data.util.runSuspendCatching
import com.neki.android.core.dataapi.repository.MapRepository
import com.neki.android.core.model.Brand
import com.neki.android.core.model.PhotoBooth
import javax.inject.Inject

class MapRepositoryImpl @Inject constructor(
private val mapService: MapService,
) : MapRepository {
override suspend fun getBrands(): Result<List<Brand>> = runSuspendCatching {
mapService.getBrands().data.toModels()
}

override suspend fun getPhotoBoothsByPoint(
longitude: Double?,
latitude: Double?,
radiusInMeters: Int,
brandIds: List<Long>,
): Result<List<PhotoBooth>> = runSuspendCatching {
mapService.getPhotoBoothsByPoint(
request = PhotoBoothPointRequest(
longitude = longitude,
latitude = latitude,
radiusInMeters = radiusInMeters,
brandIds = brandIds,
),
).data.toModels()
}

override suspend fun getPhotoBoothsByPolygon(
coordinates: List<Pair<Double, Double>>,
brandIds: List<Long>,
): Result<List<PhotoBooth>> = runSuspendCatching {
mapService.getPhotoBoothsByPolygon(
request = PhotoBoothPolygonRequest(
coordinates = coordinates.map { (longitude, latitude) ->
Coordinate(longitude = longitude, latitude = latitude)
},
brandIds = brandIds,
),
).data.toModels()
}
}
6 changes: 4 additions & 2 deletions core/model/src/main/java/com/neki/android/core/model/Brand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.neki.android.core.model

data class Brand(
val isChecked: Boolean = false,
val brandName: String = "",
val brandImageRes: Int = 0,
val id: Long = 0L,
val name: String = "",
val code: String = "",
val imageUrl: String = "",
)
10 changes: 0 additions & 10 deletions core/model/src/main/java/com/neki/android/core/model/BrandInfo.kt

This file was deleted.

14 changes: 14 additions & 0 deletions core/model/src/main/java/com/neki/android/core/model/PhotoBooth.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.neki.android.core.model

data class PhotoBooth(
val isFocused: Boolean = false,
val isCheckedBrand: Boolean = true,
val id: Long = 0L,
val brandName: String = "",
val branchName: String = "",
val address: String = "",
val longitude: Double = 0.0,
val latitude: Double = 0.0,
val distance: Int = 0,
val imageUrl: String = "",
)
1 change: 1 addition & 0 deletions feature/map/impl/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ dependencies {
implementation(projects.feature.map.api)
api(libs.map.sdk)
implementation(libs.naver.map.compose)
implementation(libs.play.services.location)

implementation(libs.kotlinx.collections.immutable)
implementation(libs.coil.compose)
Expand Down
Loading