Skip to content

Commit

Permalink
Merge branch 'feature/feat-reflect-create-course-modification' into d…
Browse files Browse the repository at this point in the history
…evelop
  • Loading branch information
unam98 committed Feb 8, 2024
2 parents 33126ee + 6f557f4 commit fd25aa7
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ import kotlinx.serialization.Serializable

@Serializable
data class ResponsePostMyDrawCourse(
@SerialName("data")
val data: Data,
@SerialName("message")
val message: String,
@SerialName("status")
val status: Int,
@SerialName("success")
val success: Boolean,
@SerialName("message")
val message: String,
@SerialName("data")
val data: Data,
) {
@Serializable
data class Data(
@SerialName("createdAt")
val createdAt: String,
@SerialName("id")
val id: Int,
@SerialName("createdAt")
val createdAt: String,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ class CourseRepositoryImpl @Inject constructor(private val remoteCourseDataSourc

override suspend fun uploadCourse(
image: MultipartBody.Part,
courseCreateRequestDto: RequestBody
data: RequestBody
): Response<ResponsePostMyDrawCourse> {
return remoteCourseDataSource.uploadCourse(
image = image,
courseCreateRequestDto = courseCreateRequestDto
data = data
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ interface CourseService {

//코스 업로드
@Multipart
@POST("/api/course/v2")
@POST("/api/course")
suspend fun uploadCourse(
@Part image: MultipartBody.Part,
@Part("courseCreateRequestDto") courseCreateRequestDto: RequestBody,
@Part("data") data: RequestBody,
): Response<ResponsePostMyDrawCourse>
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,6 @@ class RemoteCourseDataSource @Inject constructor(

suspend fun postRecord(request: RequestPostRunningHistory) = courseService.postRecord(request)

suspend fun uploadCourse(image: MultipartBody.Part, courseCreateRequestDto: RequestBody) =
courseService.uploadCourse(image, courseCreateRequestDto)
suspend fun uploadCourse(image: MultipartBody.Part, data: RequestBody) =
courseService.uploadCourse(image, data)
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ interface CourseRepository {
suspend fun postRecord(request: RequestPostRunningHistory): Response<ResponsePostMyHistory>

suspend fun uploadCourse(
image: MultipartBody.Part, courseCreateRequestDto: RequestBody
image: MultipartBody.Part, data: RequestBody
): Response<ResponsePostMyDrawCourse>

suspend fun getCourseDetail(publicCourseId: Int): Result<CourseDetail?>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,12 @@ class DrawActivity : BindingActivity<ActivityDrawBinding>(R.layout.activity_draw
var isSearchLocationMode: Boolean = false
var isCurrentLocationMode: Boolean = false

var isBlockUpdateDeparture: Boolean = false


private lateinit var naverMap: NaverMap
private lateinit var departureLatLng: LatLng
private lateinit var customDepartureLatLng: LatLng
private lateinit var animDown: Animation
private lateinit var animUp: Animation
private lateinit var searchResult: SearchResultEntity
Expand Down Expand Up @@ -137,25 +141,26 @@ class DrawActivity : BindingActivity<ActivityDrawBinding>(R.layout.activity_draw
setCameraFinishedListener()
}

/**
* 출발지 mode 설정
*
* 검색/현위치/커스텀
*/
private fun initMode() {
when (searchResult.mode) {
DepartureSetMode.SEARCH.mode -> initSearchLocationMode()
DepartureSetMode.CURRENT.mode -> initCurrentLocationMode()
DepartureSetMode.CUSTOM.mode -> initCustomLocationMode()
else -> throw IllegalArgumentException("Unknown mode: ${searchResult.mode}")
else -> throw IllegalArgumentException("Unknown mode: ${searchResult.mode}") //todo 예외 처리 필요
}
}

private fun initSearchLocationMode() {
isSearchLocationMode = true

with(binding) {
tvGuide.isVisible = false
}

binding.tvGuide.isVisible = false
viewModel.searchResult.value = searchResult
viewModel.departureName.value =
searchResult.name //searchLocationMode일 땐 departureName 값 세팅해주는 부분이 따로 없어서 여기에 작성해놓음
viewModel.departureName.value = searchResult.name

setDepartureLatLng(
latLng = LatLng(
Expand Down Expand Up @@ -197,9 +202,15 @@ class DrawActivity : BindingActivity<ActivityDrawBinding>(R.layout.activity_draw
showDrawGuide()
hideDeparture()
showDrawCourse()
customDepartureLatLng = getCenterPosition()
isBlockUpdateDeparture = true
getCenterPosition().apply {
departureLatLng = this
}.let(::drawCourse)

//커스텀 모드 시 departureLatLng이 계속 현위치 좌표값으로 갱신되어 RunActivity로 path 넘길 때 잘못된 값이 넘어가서 대응 조치
//위의 방법으로도 한계가 있어서 putExtra 직전에 값을 한 번 더 갱신해주는 식으로 대응

hideFloatedDeparture()
}
}
Expand All @@ -218,10 +229,16 @@ class DrawActivity : BindingActivity<ActivityDrawBinding>(R.layout.activity_draw
)
}

/**
* Reverse Geocoding API 호출
*/
private fun getLocationInfoUsingLatLng(lat: Double, lon: Double) {
viewModel.getLocationInfoUsingLatLng(lat = lat, lon = lon)
}

/**
* 지도 줌 설정
*/
private fun setZoomControl() {
naverMap.maxZoom = 18.0
naverMap.minZoom = 10.0
Expand All @@ -230,36 +247,55 @@ class DrawActivity : BindingActivity<ActivityDrawBinding>(R.layout.activity_draw
uiSettings.isZoomControlEnabled = false
}

/**
* 현위치 커스텀 아이콘 설정
*/
private fun setCurrentLocationIcon() {
val locationOverlay = naverMap.locationOverlay
locationOverlay.icon = OverlayImage.fromResource(R.drawable.current_location)
}

/**
* 카메라 이동 종료 시 실행되는 리스너
*/
private fun setCameraFinishedListener() {
naverMap.addOnCameraIdleListener {
val centerLatLng = getCenterPosition()
if (::currentLocation.isInitialized) {
getLocationInfoUsingLatLng( //코스를 다 그린 후에도 계속 통신이 돌아서 리소스 낭비를 막기 위한 조치 필요
getLocationInfoUsingLatLng( //todo 코스를 다 그린 후에도 계속 통신이 돌아서 리소스 낭비를 막기 위한 조치 필요
lat = centerLatLng.latitude, lon = centerLatLng.longitude
)
}
Timber.tag("카메라-끝").d("$centerLatLng") //위에 통신이 비동기로 돌아서 이게 먼저 찍힘.
}
}

/**
* 지도 화면의 중앙 위경도 좌표값 반환
*/
private fun getCenterPosition(): LatLng {
val cameraPosition = naverMap.cameraPosition
return cameraPosition.target // 중심 좌표
return cameraPosition.target
}

/**
* 현위치 추척, 변동 시 위경도 좌표값 반환
*/
private fun setLocationChangedListener() {
naverMap.addOnLocationChangeListener { location ->
currentLocation = LatLng(location.latitude, location.longitude)

naverMap.locationOverlay.position = currentLocation
naverMap.locationOverlay.isVisible = false
setDepartureLatLng(latLng = LatLng(currentLocation.latitude, currentLocation.longitude))

if (!isBlockUpdateDeparture) {
setDepartureLatLng(
latLng = LatLng(
currentLocation.latitude,
currentLocation.longitude
)
)
}
//같은 scope 안에 넣었으니 setDepartureLatLng 다음에 drawCourse가 실행되는 것이 보장됨
//이때 isFirstInit의 초기값을 true로 줘서 최초 1회는 실행되게 하고 이후 drawCourse 내에서 isFirstInit 값을 false로 바꿔줌
//뒤의 조건을 안 달아주면 다른 mode에서는 버튼을 클릭하기도 전에 drawCourse()가 돌 거라 안 됨.
Expand All @@ -269,6 +305,9 @@ class DrawActivity : BindingActivity<ActivityDrawBinding>(R.layout.activity_draw
}
}

/**
* 지도에 실시간 현위치 아이콘 표시 여부 설정
*/
private fun setLocationTrackingMode() {
naverMap.locationSource = locationSource

Expand All @@ -288,6 +327,9 @@ class DrawActivity : BindingActivity<ActivityDrawBinding>(R.layout.activity_draw
}
}

/**
* 코스 이름 입력 받는 BottomSheet
*/
private fun requireCourseNameDialog(): BottomSheetDialog {
val bottomSheetBinding = BottomsheetRequireCourseNameBinding.inflate(layoutInflater)
val bottomSheetView = bottomSheetBinding.root
Expand Down Expand Up @@ -437,7 +479,7 @@ class DrawActivity : BindingActivity<ActivityDrawBinding>(R.layout.activity_draw
binding.indeterminateBar.isVisible = false
}

private fun observeDrawState() { //분기 처리를 더 해줘야 함. 서버에서 400 날아오는데 이게 success로 빠져서 '코스 생성 완료' 팝업이 뜨고 있음.
private fun observeDrawState() {
viewModel.drawState.observe(this) {
when (it) {
UiState.Empty -> hideLoadingBar()
Expand All @@ -454,7 +496,10 @@ class DrawActivity : BindingActivity<ActivityDrawBinding>(R.layout.activity_draw
}
}

private fun notifyCreateFinish() {
/**
* 코스 완성 시 뜨는 팝업 (보관함 가기 / 바로 달리기)
*/
private fun notifyCreateFinish() { //todo dialogFragment로 리팩토링
val (dialog, dialogLayout) = setActivityDialog(
layoutInflater = layoutInflater,
view = binding.root,
Expand All @@ -464,9 +509,11 @@ class DrawActivity : BindingActivity<ActivityDrawBinding>(R.layout.activity_draw

with(dialogLayout) {
this.btn_run.setOnClickListener {
if (isCustomLocationMode) departureLatLng = customDepartureLatLng

val courseData = CourseData(
courseId = viewModel.uploadResult.value?.data?.id,
publicCourseId = null,
publicCourseId = null, //직접 생성하는 코스는 publicCourseId가 없지만 코스 발견 -> 러닝 등의 루트로 넘어올 시 기록 업로드에서 requestBody에 필요함
touchList = touchList,
startLatLng = departureLatLng,
departure = viewModel.departureName.value,
Expand Down Expand Up @@ -512,7 +559,10 @@ class DrawActivity : BindingActivity<ActivityDrawBinding>(R.layout.activity_draw
}
}

private fun cameraUpdate(location: Any) {
/**
* 지도 카메라 갱신
*/
private fun updateCamera(location: Any) {
//맨 처음 지도 켤 때 startLocation으로 위치 옮길 때 사용
if (location is LatLng) {
val cameraUpdate = CameraUpdate.scrollTo(location).animate(CameraAnimation.Easing)
Expand All @@ -532,6 +582,9 @@ class DrawActivity : BindingActivity<ActivityDrawBinding>(R.layout.activity_draw
deleteRouteMarker()
}

/**
* 출발지 마커 생성
*/
private fun createDepartureMarker(departureLatLng: LatLng) {
setDepartureMarker(departureLatLng = departureLatLng)
addDepartureToCoords(departureLatLng = departureLatLng)
Expand All @@ -546,13 +599,16 @@ class DrawActivity : BindingActivity<ActivityDrawBinding>(R.layout.activity_draw
departureMarker.map = naverMap

if (isSearchLocationMode) {
cameraUpdate(
updateCamera(
LatLng(departureLatLng.latitude, departureLatLng.longitude)
) // 현위치에서 출발할 때 이것 때문에 트랙킹 모드 활성화 시 카메라 이동하는 게 묻혔음
}
setCustomInfoWindow(marker = departureMarker)
}

/**
* 출발지 정보창 설정
*/
private fun setCustomInfoWindow(marker: Marker) {
val infoWindow = InfoWindow()
infoWindow.adapter = object : InfoWindow.ViewAdapter() {
Expand All @@ -576,6 +632,9 @@ class DrawActivity : BindingActivity<ActivityDrawBinding>(R.layout.activity_draw
)
}

/**
* 경로 마커 생성
*/
private fun createRouteMarker() {
naverMap.setOnMapClickListener { _, coord ->
if (!isMarkerAvailable) return@setOnMapClickListener
Expand Down Expand Up @@ -612,6 +671,9 @@ class DrawActivity : BindingActivity<ActivityDrawBinding>(R.layout.activity_draw
markerList.add(routeMarker)
}

/**
* 경로선 그리기
*/
private fun generateRouteLine(coord: LatLng) {
coords.add(LatLng(coord.latitude, coord.longitude)) // coords에 터치로 받아온 좌표값 추가
path.coords = coords // 경로선 그리기
Expand All @@ -620,6 +682,9 @@ class DrawActivity : BindingActivity<ActivityDrawBinding>(R.layout.activity_draw
path.map = naverMap
}

/**
* 경로 마커 제거
*/
private fun deleteRouteMarker() {
binding.btnMarkerBack.setOnClickListener {
updateRouteMarkerData()
Expand Down Expand Up @@ -664,6 +729,9 @@ class DrawActivity : BindingActivity<ActivityDrawBinding>(R.layout.activity_draw
viewModel.distanceSum.value = distanceSum
}

/**
* 위경도 좌표 간 거리 합 계산
*/
private fun calcDistance() {
for (i in 0 until touchList.size) {
if (!calcDistanceList.contains(touchList[i])) {
Expand All @@ -687,14 +755,16 @@ class DrawActivity : BindingActivity<ActivityDrawBinding>(R.layout.activity_draw
}

/**
* MBR 생성 및 화면 캡쳐
*
* MBR : 남서쪽과 북동쪽 꼭지점 두 개의 좌표로 만드는 직사각형 영역
*/
private fun createMBR() {
val bounds = LatLngBounds.Builder()
.include(LatLng(departureLatLng.latitude, departureLatLng.longitude)).include(touchList)
.build()
naverMap.setContentPadding(100, 100, 100, 100)
cameraUpdate(bounds)
updateCamera(bounds)
captureMap()
}

Expand Down Expand Up @@ -728,9 +798,10 @@ class DrawActivity : BindingActivity<ActivityDrawBinding>(R.layout.activity_draw
isCurrentLocationMode || isCustomLocationMode -> {
viewModel.departureAddress.value =
viewModel.reverseGeocodingResult.value?.fullAddress
viewModel.departureName.value =
viewModel.reverseGeocodingResult.value?.buildingName ?: "내가 설정한 출발지"
}
}

}

// Get uri of images from camera function
Expand Down
Loading

0 comments on commit fd25aa7

Please sign in to comment.