diff --git a/android/app/src/main/java/com/happy/friendogly/data/repository/PlaygroundRepositoryImpl.kt b/android/app/src/main/java/com/happy/friendogly/data/repository/PlaygroundRepositoryImpl.kt index 4ee6dbd58..677901e6f 100644 --- a/android/app/src/main/java/com/happy/friendogly/data/repository/PlaygroundRepositoryImpl.kt +++ b/android/app/src/main/java/com/happy/friendogly/data/repository/PlaygroundRepositoryImpl.kt @@ -1,6 +1,5 @@ package com.happy.friendogly.data.repository -import com.happy.friendogly.data.error.ApiExceptionDto import com.happy.friendogly.data.mapper.toDomain import com.happy.friendogly.data.source.PlaygroundDataSource import com.happy.friendogly.domain.DomainResult @@ -14,6 +13,8 @@ import com.happy.friendogly.presentation.ui.playground.model.PlaygroundInfo import com.happy.friendogly.presentation.ui.playground.model.PlaygroundJoin import com.happy.friendogly.presentation.ui.playground.model.PlaygroundMessage import com.happy.friendogly.presentation.ui.playground.model.PlaygroundSummary +import com.happy.friendogly.remote.error.ApiExceptionResponse +import com.happy.friendogly.remote.mapper.toData import com.happy.friendogly.remote.model.request.PatchPlaygroundArrivalRequest import com.happy.friendogly.remote.model.request.PatchPlaygroundMessageRequest import com.happy.friendogly.remote.model.request.PostPlaygroundRequest @@ -41,7 +42,11 @@ class PlaygroundRepositoryImpl }, onFailure = { throwable -> when (throwable) { - is ApiExceptionDto -> DomainResult.Error(throwable.error.data.errorCode.toDomain()) + is ApiExceptionResponse -> + DomainResult.Error( + throwable.error.data.errorCode.toData().toDomain(), + ) + is ConnectException -> DomainResult.Error(DataError.Network.NO_INTERNET) is UnknownHostException -> DomainResult.Error(DataError.Network.NO_INTERNET) else -> DomainResult.Error(DataError.Network.SERVER_ERROR) @@ -65,7 +70,11 @@ class PlaygroundRepositoryImpl }, onFailure = { throwable -> when (throwable) { - is ApiExceptionDto -> DomainResult.Error(throwable.error.data.errorCode.toDomain()) + is ApiExceptionResponse -> + DomainResult.Error( + throwable.error.data.errorCode.toData().toDomain(), + ) + is ConnectException -> DomainResult.Error(DataError.Network.NO_INTERNET) is UnknownHostException -> DomainResult.Error(DataError.Network.NO_INTERNET) else -> DomainResult.Error(DataError.Network.SERVER_ERROR) @@ -74,27 +83,110 @@ class PlaygroundRepositoryImpl ) } - override suspend fun getPetExistence(): Result = - source.getPetExistence().mapCatching { dto -> - dto.toDomain() - } + override suspend fun getPetExistence(): DomainResult = + source.getPetExistence() + .fold( + onSuccess = { dto -> + DomainResult.Success(dto.toDomain()) + }, + onFailure = { throwable -> + when (throwable) { + is ApiExceptionResponse -> + DomainResult.Error( + throwable.error.data.errorCode.toData().toDomain(), + ) + + is ConnectException -> DomainResult.Error(DataError.Network.NO_INTERNET) + is UnknownHostException -> DomainResult.Error(DataError.Network.NO_INTERNET) + else -> DomainResult.Error(DataError.Network.SERVER_ERROR) + } + }, + ) + + override suspend fun getPlaygrounds( + startLatitude: Double, + endLatitude: Double, + startLongitude: Double, + endLongitude: Double, + ): DomainResult, DataError.Network> = + source.getPlaygrounds(startLatitude, endLatitude, startLongitude, endLongitude) + .fold( + onSuccess = { dto -> + DomainResult.Success(dto.toDomain()) + }, + onFailure = { throwable -> + when (throwable) { + is ApiExceptionResponse -> + DomainResult.Error( + throwable.error.data.errorCode.toData().toDomain(), + ) + + is ConnectException -> DomainResult.Error(DataError.Network.NO_INTERNET) + is UnknownHostException -> DomainResult.Error(DataError.Network.NO_INTERNET) + else -> DomainResult.Error(DataError.Network.SERVER_ERROR) + } + }, + ) + + override suspend fun getMyPlayground(): DomainResult = + source.getMyPlayground() + .fold( + onSuccess = { dto -> + DomainResult.Success(dto.toDomain()) + }, + onFailure = { throwable -> + when (throwable) { + is ApiExceptionResponse -> + DomainResult.Error( + throwable.error.data.errorCode.toData().toDomain(), + ) - override suspend fun getPlaygrounds(): Result> = - source - .getNearPlaygrounds() - .mapCatching { dto -> - dto.toDomain() - } + is ConnectException -> DomainResult.Error(DataError.Network.NO_INTERNET) + is UnknownHostException -> DomainResult.Error(DataError.Network.NO_INTERNET) + else -> DomainResult.Error(DataError.Network.SERVER_ERROR) + } + }, + ) - override suspend fun getPlaygroundInfo(id: Long): Result = - source - .getPlaygroundInfo(id) - .mapCatching { dto -> dto.toDomain() } + override suspend fun getPlaygroundInfo(id: Long): DomainResult = + source.getPlaygroundInfo(id) + .fold( + onSuccess = { dto -> + DomainResult.Success(dto.toDomain()) + }, + onFailure = { throwable -> + when (throwable) { + is ApiExceptionResponse -> + DomainResult.Error( + throwable.error.data.errorCode.toData().toDomain(), + ) - override suspend fun getPlaygroundSummary(playgroundId: Long): Result = - source - .getPlaygroundSummary(playgroundId) - .mapCatching { dto -> dto.toDomain() } + is ConnectException -> DomainResult.Error(DataError.Network.NO_INTERNET) + is UnknownHostException -> DomainResult.Error(DataError.Network.NO_INTERNET) + else -> DomainResult.Error(DataError.Network.SERVER_ERROR) + } + }, + ) + + override suspend fun getPlaygroundSummary(playgroundId: Long): DomainResult = + source.getPlaygroundSummary(playgroundId) + .fold( + onSuccess = { dto -> + DomainResult.Success(dto.toDomain()) + }, + onFailure = { throwable -> + when (throwable) { + is ApiExceptionResponse -> + DomainResult.Error( + throwable.error.data.errorCode.toData().toDomain(), + ) + + is ConnectException -> DomainResult.Error(DataError.Network.NO_INTERNET) + is UnknownHostException -> DomainResult.Error(DataError.Network.NO_INTERNET) + else -> DomainResult.Error(DataError.Network.SERVER_ERROR) + } + }, + ) override suspend fun postPlaygroundJoin(playgroundId: Long): DomainResult { return source.postPlaygroundJoin(playgroundId).fold( @@ -103,7 +195,11 @@ class PlaygroundRepositoryImpl }, onFailure = { throwable -> when (throwable) { - is ApiExceptionDto -> DomainResult.Error(throwable.error.data.errorCode.toDomain()) + is ApiExceptionResponse -> + DomainResult.Error( + throwable.error.data.errorCode.toData().toDomain(), + ) + is ConnectException -> DomainResult.Error(DataError.Network.NO_INTERNET) is UnknownHostException -> DomainResult.Error(DataError.Network.NO_INTERNET) else -> DomainResult.Error(DataError.Network.SERVER_ERROR) @@ -112,12 +208,44 @@ class PlaygroundRepositoryImpl ) } - override suspend fun deletePlaygroundLeave(): Result = source.deletePlaygroundLeave() + override suspend fun deletePlaygroundLeave(): DomainResult = + source.deletePlaygroundLeave() + .fold( + onSuccess = { dto -> + DomainResult.Success(dto) + }, + onFailure = { throwable -> + when (throwable) { + is ApiExceptionResponse -> + DomainResult.Error( + throwable.error.data.errorCode.toData().toDomain(), + ) - override suspend fun patchPlaygroundMessage(message: String): Result = + is ConnectException -> DomainResult.Error(DataError.Network.NO_INTERNET) + is UnknownHostException -> DomainResult.Error(DataError.Network.NO_INTERNET) + else -> DomainResult.Error(DataError.Network.SERVER_ERROR) + } + }, + ) + + override suspend fun patchPlaygroundMessage(message: String): DomainResult = source.patchPlaygroundMessage( PatchPlaygroundMessageRequest(message), - ).mapCatching { dto -> - dto.toDomain() - } + ).fold( + onSuccess = { dto -> + DomainResult.Success(dto.toDomain()) + }, + onFailure = { throwable -> + when (throwable) { + is ApiExceptionResponse -> + DomainResult.Error( + throwable.error.data.errorCode.toData().toDomain(), + ) + + is ConnectException -> DomainResult.Error(DataError.Network.NO_INTERNET) + is UnknownHostException -> DomainResult.Error(DataError.Network.NO_INTERNET) + else -> DomainResult.Error(DataError.Network.SERVER_ERROR) + } + }, + ) } diff --git a/android/app/src/main/java/com/happy/friendogly/data/source/PlaygroundDataSource.kt b/android/app/src/main/java/com/happy/friendogly/data/source/PlaygroundDataSource.kt index 02b7cccb6..3d38aa5fc 100644 --- a/android/app/src/main/java/com/happy/friendogly/data/source/PlaygroundDataSource.kt +++ b/android/app/src/main/java/com/happy/friendogly/data/source/PlaygroundDataSource.kt @@ -19,7 +19,14 @@ interface PlaygroundDataSource { suspend fun getPetExistence(): Result - suspend fun getNearPlaygrounds(): Result> + suspend fun getPlaygrounds( + startLatitude: Double, + endLatitude: Double, + startLongitude: Double, + endLongitude: Double, + ): Result> + + suspend fun getMyPlayground(): Result suspend fun getPlaygroundInfo(id: Long): Result diff --git a/android/app/src/main/java/com/happy/friendogly/domain/repository/PlaygroundRepository.kt b/android/app/src/main/java/com/happy/friendogly/domain/repository/PlaygroundRepository.kt index 63fa70479..84abf2940 100644 --- a/android/app/src/main/java/com/happy/friendogly/domain/repository/PlaygroundRepository.kt +++ b/android/app/src/main/java/com/happy/friendogly/domain/repository/PlaygroundRepository.kt @@ -22,17 +22,24 @@ interface PlaygroundRepository { longitude: Double, ): DomainResult - suspend fun getPetExistence(): Result + suspend fun getPetExistence(): DomainResult - suspend fun getPlaygrounds(): Result> + suspend fun getPlaygrounds( + startLatitude: Double, + endLatitude: Double, + startLongitude: Double, + endLongitude: Double, + ): DomainResult, DataError.Network> - suspend fun getPlaygroundInfo(id: Long): Result + suspend fun getMyPlayground(): DomainResult - suspend fun getPlaygroundSummary(playgroundId: Long): Result + suspend fun getPlaygroundInfo(id: Long): DomainResult + + suspend fun getPlaygroundSummary(playgroundId: Long): DomainResult suspend fun postPlaygroundJoin(playgroundId: Long): DomainResult - suspend fun deletePlaygroundLeave(): Result + suspend fun deletePlaygroundLeave(): DomainResult - suspend fun patchPlaygroundMessage(message: String): Result + suspend fun patchPlaygroundMessage(message: String): DomainResult } diff --git a/android/app/src/main/java/com/happy/friendogly/domain/usecase/DeletePlaygroundLeaveUseCase.kt b/android/app/src/main/java/com/happy/friendogly/domain/usecase/DeletePlaygroundLeaveUseCase.kt index 40606e1da..a620f31ad 100644 --- a/android/app/src/main/java/com/happy/friendogly/domain/usecase/DeletePlaygroundLeaveUseCase.kt +++ b/android/app/src/main/java/com/happy/friendogly/domain/usecase/DeletePlaygroundLeaveUseCase.kt @@ -1,10 +1,12 @@ package com.happy.friendogly.domain.usecase +import com.happy.friendogly.domain.DomainResult +import com.happy.friendogly.domain.error.DataError import com.happy.friendogly.domain.repository.PlaygroundRepository import javax.inject.Inject class DeletePlaygroundLeaveUseCase @Inject constructor(private val repository: PlaygroundRepository) { - suspend operator fun invoke(): Result = repository.deletePlaygroundLeave() + suspend operator fun invoke(): DomainResult = repository.deletePlaygroundLeave() } diff --git a/android/app/src/main/java/com/happy/friendogly/domain/usecase/GetMyPlaygroundUseCase.kt b/android/app/src/main/java/com/happy/friendogly/domain/usecase/GetMyPlaygroundUseCase.kt new file mode 100644 index 000000000..82b418c06 --- /dev/null +++ b/android/app/src/main/java/com/happy/friendogly/domain/usecase/GetMyPlaygroundUseCase.kt @@ -0,0 +1,13 @@ +package com.happy.friendogly.domain.usecase + +import com.happy.friendogly.domain.DomainResult +import com.happy.friendogly.domain.error.DataError +import com.happy.friendogly.domain.repository.PlaygroundRepository +import com.happy.friendogly.presentation.ui.playground.model.MyPlayground +import javax.inject.Inject + +class GetMyPlaygroundUseCase + @Inject + constructor(private val repository: PlaygroundRepository) { + suspend operator fun invoke(): DomainResult = repository.getMyPlayground() + } diff --git a/android/app/src/main/java/com/happy/friendogly/domain/usecase/GetPetExistenceUseCase.kt b/android/app/src/main/java/com/happy/friendogly/domain/usecase/GetPetExistenceUseCase.kt index 75d001a93..23af76246 100644 --- a/android/app/src/main/java/com/happy/friendogly/domain/usecase/GetPetExistenceUseCase.kt +++ b/android/app/src/main/java/com/happy/friendogly/domain/usecase/GetPetExistenceUseCase.kt @@ -1,5 +1,7 @@ package com.happy.friendogly.domain.usecase +import com.happy.friendogly.domain.DomainResult +import com.happy.friendogly.domain.error.DataError import com.happy.friendogly.domain.repository.PlaygroundRepository import com.happy.friendogly.presentation.ui.playground.model.PetExistence import javax.inject.Inject @@ -7,5 +9,5 @@ import javax.inject.Inject class GetPetExistenceUseCase @Inject constructor(private val repository: PlaygroundRepository) { - suspend operator fun invoke(): Result = repository.getPetExistence() + suspend operator fun invoke(): DomainResult = repository.getPetExistence() } diff --git a/android/app/src/main/java/com/happy/friendogly/domain/usecase/GetPlaygroundInfoUseCase.kt b/android/app/src/main/java/com/happy/friendogly/domain/usecase/GetPlaygroundInfoUseCase.kt index ff6a99542..d9f66a521 100644 --- a/android/app/src/main/java/com/happy/friendogly/domain/usecase/GetPlaygroundInfoUseCase.kt +++ b/android/app/src/main/java/com/happy/friendogly/domain/usecase/GetPlaygroundInfoUseCase.kt @@ -1,5 +1,7 @@ package com.happy.friendogly.domain.usecase +import com.happy.friendogly.domain.DomainResult +import com.happy.friendogly.domain.error.DataError import com.happy.friendogly.domain.repository.PlaygroundRepository import com.happy.friendogly.presentation.ui.playground.model.PlaygroundInfo import javax.inject.Inject @@ -7,5 +9,5 @@ import javax.inject.Inject class GetPlaygroundInfoUseCase @Inject constructor(private val repository: PlaygroundRepository) { - suspend operator fun invoke(id: Long): Result = repository.getPlaygroundInfo(id) + suspend operator fun invoke(id: Long): DomainResult = repository.getPlaygroundInfo(id) } diff --git a/android/app/src/main/java/com/happy/friendogly/domain/usecase/GetPlaygroundSummaryUseCase.kt b/android/app/src/main/java/com/happy/friendogly/domain/usecase/GetPlaygroundSummaryUseCase.kt index 3b795c396..674968e32 100644 --- a/android/app/src/main/java/com/happy/friendogly/domain/usecase/GetPlaygroundSummaryUseCase.kt +++ b/android/app/src/main/java/com/happy/friendogly/domain/usecase/GetPlaygroundSummaryUseCase.kt @@ -1,5 +1,7 @@ package com.happy.friendogly.domain.usecase +import com.happy.friendogly.domain.DomainResult +import com.happy.friendogly.domain.error.DataError import com.happy.friendogly.domain.repository.PlaygroundRepository import com.happy.friendogly.presentation.ui.playground.model.PlaygroundSummary import javax.inject.Inject @@ -7,5 +9,6 @@ import javax.inject.Inject class GetPlaygroundSummaryUseCase @Inject constructor(private val repository: PlaygroundRepository) { - suspend operator fun invoke(playgroundId: Long): Result = repository.getPlaygroundSummary(playgroundId) + suspend operator fun invoke(playgroundId: Long): DomainResult = + repository.getPlaygroundSummary(playgroundId) } diff --git a/android/app/src/main/java/com/happy/friendogly/domain/usecase/GetPlaygroundsUseCase.kt b/android/app/src/main/java/com/happy/friendogly/domain/usecase/GetPlaygroundsUseCase.kt index 16c9577fc..1ea942413 100644 --- a/android/app/src/main/java/com/happy/friendogly/domain/usecase/GetPlaygroundsUseCase.kt +++ b/android/app/src/main/java/com/happy/friendogly/domain/usecase/GetPlaygroundsUseCase.kt @@ -1,5 +1,7 @@ package com.happy.friendogly.domain.usecase +import com.happy.friendogly.domain.DomainResult +import com.happy.friendogly.domain.error.DataError import com.happy.friendogly.domain.repository.PlaygroundRepository import com.happy.friendogly.presentation.ui.playground.model.Playground import javax.inject.Inject @@ -7,5 +9,11 @@ import javax.inject.Inject class GetPlaygroundsUseCase @Inject constructor(private val repository: PlaygroundRepository) { - suspend operator fun invoke(): Result> = repository.getPlaygrounds() + suspend operator fun invoke( + startLatitude: Double, + endLatitude: Double, + startLongitude: Double, + endLongitude: Double, + ): DomainResult, DataError.Network> = + repository.getPlaygrounds(startLatitude, endLatitude, startLongitude, endLongitude) } diff --git a/android/app/src/main/java/com/happy/friendogly/domain/usecase/PathPlaygroundMessageUseCase.kt b/android/app/src/main/java/com/happy/friendogly/domain/usecase/PatchPlaygroundMessageUseCase.kt similarity index 50% rename from android/app/src/main/java/com/happy/friendogly/domain/usecase/PathPlaygroundMessageUseCase.kt rename to android/app/src/main/java/com/happy/friendogly/domain/usecase/PatchPlaygroundMessageUseCase.kt index ecdec394a..c05ef5b49 100644 --- a/android/app/src/main/java/com/happy/friendogly/domain/usecase/PathPlaygroundMessageUseCase.kt +++ b/android/app/src/main/java/com/happy/friendogly/domain/usecase/PatchPlaygroundMessageUseCase.kt @@ -1,11 +1,14 @@ package com.happy.friendogly.domain.usecase +import com.happy.friendogly.domain.DomainResult +import com.happy.friendogly.domain.error.DataError import com.happy.friendogly.domain.repository.PlaygroundRepository import com.happy.friendogly.presentation.ui.playground.model.PlaygroundMessage import javax.inject.Inject -class PathPlaygroundMessageUseCase +class PatchPlaygroundMessageUseCase @Inject constructor(private val repository: PlaygroundRepository) { - suspend operator fun invoke(message: String): Result = repository.patchPlaygroundMessage(message) + suspend operator fun invoke(message: String): DomainResult = + repository.patchPlaygroundMessage(message) } diff --git a/android/app/src/main/java/com/happy/friendogly/presentation/ui/permission/LocationPermission.kt b/android/app/src/main/java/com/happy/friendogly/presentation/ui/permission/LocationPermission.kt index 93f69028e..16a39ab72 100644 --- a/android/app/src/main/java/com/happy/friendogly/presentation/ui/permission/LocationPermission.kt +++ b/android/app/src/main/java/com/happy/friendogly/presentation/ui/permission/LocationPermission.kt @@ -181,8 +181,6 @@ class LocationPermission private constructor( } else { (lifecycleOwner as Fragment).createGPSDialog() } - - println("createGPSDialog") } override fun shouldShowRequestPermissionRationale(): Boolean { diff --git a/android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/PlaygroundFragment.kt b/android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/PlaygroundFragment.kt index 6e404aa70..e562b9a23 100644 --- a/android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/PlaygroundFragment.kt +++ b/android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/PlaygroundFragment.kt @@ -13,8 +13,6 @@ import android.location.Location import android.location.LocationManager import android.os.Build import android.os.Bundle -import android.os.Handler -import android.os.Looper import android.view.Gravity import android.view.LayoutInflater import android.view.View @@ -25,6 +23,7 @@ import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.RecyclerView import com.google.android.material.bottomsheet.BottomSheetBehavior @@ -47,6 +46,7 @@ import com.happy.friendogly.presentation.ui.playground.action.PlaygroundAlertAct import com.happy.friendogly.presentation.ui.playground.action.PlaygroundAlertAction.AlertFailToCheckPetExistence import com.happy.friendogly.presentation.ui.playground.action.PlaygroundAlertAction.AlertFailToJoinPlaygroundSnackbar import com.happy.friendogly.presentation.ui.playground.action.PlaygroundAlertAction.AlertFailToLeavePlaygroundSnackbar +import com.happy.friendogly.presentation.ui.playground.action.PlaygroundAlertAction.AlertFailToLoadMyPlaygroundSnackbar import com.happy.friendogly.presentation.ui.playground.action.PlaygroundAlertAction.AlertFailToLoadPlaygroundInfoSnackbar import com.happy.friendogly.presentation.ui.playground.action.PlaygroundAlertAction.AlertFailToLoadPlaygroundSummarySnackbar import com.happy.friendogly.presentation.ui.playground.action.PlaygroundAlertAction.AlertFailToLoadPlaygroundsSnackbar @@ -66,6 +66,7 @@ import com.happy.friendogly.presentation.ui.playground.action.PlaygroundAlertAct import com.happy.friendogly.presentation.ui.playground.action.PlaygroundMapAction.ChangeBottomSheetBehavior import com.happy.friendogly.presentation.ui.playground.action.PlaygroundMapAction.ChangeTrackingMode import com.happy.friendogly.presentation.ui.playground.action.PlaygroundMapAction.HideRegisteringPlaygroundScreen +import com.happy.friendogly.presentation.ui.playground.action.PlaygroundMapAction.MakeMyPlayground import com.happy.friendogly.presentation.ui.playground.action.PlaygroundMapAction.MakePlaygrounds import com.happy.friendogly.presentation.ui.playground.action.PlaygroundMapAction.MoveCameraCenterPosition import com.happy.friendogly.presentation.ui.playground.action.PlaygroundMapAction.RegisterMyPlayground @@ -77,6 +78,7 @@ import com.happy.friendogly.presentation.ui.playground.action.PlaygroundNavigate import com.happy.friendogly.presentation.ui.playground.action.PlaygroundNavigateAction.NavigateToStateMessage import com.happy.friendogly.presentation.ui.playground.adapter.PetDetailAdapter import com.happy.friendogly.presentation.ui.playground.adapter.PetSummaryAdapter +import com.happy.friendogly.presentation.ui.playground.model.MyPlayground import com.happy.friendogly.presentation.ui.playground.model.Playground import com.happy.friendogly.presentation.ui.playground.service.PlaygroundLocationReceiver import com.happy.friendogly.presentation.ui.playground.service.PlaygroundLocationService @@ -109,6 +111,8 @@ import com.skydoves.balloon.Balloon import com.skydoves.balloon.BalloonAnimation import com.skydoves.balloon.BalloonSizeSpec import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch import java.util.Locale import javax.inject.Inject import kotlin.math.cos @@ -321,6 +325,8 @@ class PlaygroundFragment : Fragment(), OnMapReadyCallback { if (currentState is PlaygroundUiState.RegisteringPlayground) { currentState.circleOverlay.center = map.cameraPosition.target } + + viewModel.updateContentBounds(contentBounds = map.contentBounds) } map.addOnCameraIdleListener { @@ -388,18 +394,20 @@ class PlaygroundFragment : Fragment(), OnMapReadyCallback { makeNearPlaygrounds(event.nearPlaygrounds) } + is MakeMyPlayground -> { + makeMyPlayground(event.myPlayground) + } + is RegisterMyPlayground -> viewModel.registerMyPlayground(map.cameraPosition.target) is ShowRegisteringPlaygroundScreen -> { getAddress(map.cameraPosition.target) binding.layoutPlaygroundRegister.showViewAnimation() - Handler(Looper.getMainLooper()).postDelayed( - { - showHelpBalloon(textRestId = R.string.playground_register_help) - }, - ANIMATE_DURATION_MILLIS, - ) + lifecycleScope.launch { + delay(ANIMATE_DURATION_MILLIS) + showHelpBalloon(textRestId = R.string.playground_register_help) + } } is HideRegisteringPlaygroundScreen -> { @@ -555,13 +563,12 @@ class PlaygroundFragment : Fragment(), OnMapReadyCallback { val lastLocation = location ?: return@activate latLng = LatLng(lastLocation.latitude, lastLocation.longitude) moveCameraCenterPosition(latLng) - Handler(Looper.getMainLooper()).postDelayed( - { - map.locationTrackingMode = LocationTrackingMode.Follow - }, - ANIMATE_DURATION_MILLIS, - ) - viewModel.loadPlaygrounds() + + lifecycleScope.launch { + delay(ANIMATE_DURATION_MILLIS) + map.locationTrackingMode = LocationTrackingMode.Follow + viewModel.loadPlaygrounds() + } } } @@ -601,9 +608,9 @@ class PlaygroundFragment : Fragment(), OnMapReadyCallback { map.moveCamera(cameraUpdate) } - private fun makeMyPlayground(myPlayground: Playground?) { + private fun makeMyPlayground(myPlayground: MyPlayground?) { if (myPlayground != null) { - val marker = createMarker(playground = myPlayground) + val marker = createMyPlaygroundMarker(myPlayground = myPlayground) val circleOverlay = createCircleOverlay(position = marker.position) val pathOverlay = createPathOverlay(marker.position) viewModel.loadMyPlayground( @@ -620,7 +627,7 @@ class PlaygroundFragment : Fragment(), OnMapReadyCallback { nearPlaygrounds.map { playground -> PlaygroundUiModel( id = playground.id, - marker = createMarker(playground = playground), + marker = createPlaygroundMarker(playground = playground), circleOverlay = createCircleOverlay( position = @@ -631,14 +638,14 @@ class PlaygroundFragment : Fragment(), OnMapReadyCallback { ), ) } - viewModel.loadNearPlaygrounds(playgrounds) + viewModel.refreshNearPlaygrounds(playgrounds) } - private fun createMarker(playground: Playground): Marker { + private fun createPlaygroundMarker(playground: Playground): Marker { val marker = Marker() marker.apply { position = LatLng(playground.latitude, playground.longitude) - icon = OverlayImage.fromResource(markerIcon(playground)) + icon = OverlayImage.fromResource(R.drawable.ic_near_playground) width = MARKER_DEFAULT_WIDTH height = MARKER_DEFAULT_HEIGHT clickPlaygroundMarker(id = playground.id, marker = this) @@ -648,6 +655,20 @@ class PlaygroundFragment : Fragment(), OnMapReadyCallback { return marker } + private fun createMyPlaygroundMarker(myPlayground: MyPlayground): Marker { + val marker = Marker() + marker.apply { + position = LatLng(myPlayground.latitude, myPlayground.longitude) + icon = OverlayImage.fromResource(R.drawable.ic_my_playground) + width = MARKER_DEFAULT_WIDTH + height = MARKER_DEFAULT_HEIGHT + clickPlaygroundMarker(id = myPlayground.id, marker = this) + } + marker.map = map + + return marker + } + private fun createCircleOverlay(position: LatLng): CircleOverlay { val circleOverlay = CircleOverlay() circleOverlay.apply { @@ -690,9 +711,6 @@ class PlaygroundFragment : Fragment(), OnMapReadyCallback { } } - private fun markerIcon(playground: Playground): Int = - if (playground.isParticipating) R.drawable.ic_my_playground else R.drawable.ic_near_playground - private fun reduceMarkerSize() { val recentlyClickedMarker = viewModel.recentlyClickedPlayground.value ?: return recentlyClickedMarker.width = MARKER_DEFAULT_WIDTH @@ -884,6 +902,7 @@ class PlaygroundFragment : Fragment(), OnMapReadyCallback { is AlertFailToRegisterPlaygroundSnackbar -> R.string.playground_fail_to_register_playground is AlertFailToUpdatePlaygroundArrival -> R.string.playground_fail_to_update_playground_arrival is AlertFailToLeavePlaygroundSnackbar -> R.string.playground_fail_to_leave + is AlertFailToLoadMyPlaygroundSnackbar -> R.string.playground_fail_to_load_my_playground is AlertFailToLoadPlaygroundInfoSnackbar -> R.string.playground_fail_to_load_playground_info is AlertFailToLoadPlaygroundSummarySnackbar -> R.string.playground_fail_to_load_playground_summary is AlertFailToJoinPlaygroundSnackbar -> R.string.playground_fail_to_join_playground @@ -957,7 +976,7 @@ class PlaygroundFragment : Fragment(), OnMapReadyCallback { companion object { private const val PLAYGROUND_RADIUS = 150.0 private const val MIN_ZOOM = 7.0 - private const val DEFAULT_ZOOM = 15.0 + private const val DEFAULT_ZOOM = 14.0 private const val MARKER_DEFAULT_WIDTH = 96 private const val MARKER_DEFAULT_HEIGHT = 128 private const val MARKER_CLICKED_WIDTH = 144 diff --git a/android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/action/PlaygroundAlertAction.kt b/android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/action/PlaygroundAlertAction.kt index e74fa4274..b0aaac771 100644 --- a/android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/action/PlaygroundAlertAction.kt +++ b/android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/action/PlaygroundAlertAction.kt @@ -35,7 +35,7 @@ sealed interface PlaygroundAlertAction { data object AlertFailToLeavePlaygroundSnackbar : PlaygroundAlertAction - data object AlertFailToSwitchPlaygroundSnackbar : PlaygroundAlertAction + data object AlertFailToLoadMyPlaygroundSnackbar : PlaygroundAlertAction data object AlertFailToLoadPlaygroundInfoSnackbar : PlaygroundAlertAction diff --git a/android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/action/PlaygroundMapAction.kt b/android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/action/PlaygroundMapAction.kt index 8b3ace725..d1231acb3 100644 --- a/android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/action/PlaygroundMapAction.kt +++ b/android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/action/PlaygroundMapAction.kt @@ -1,14 +1,19 @@ package com.happy.friendogly.presentation.ui.playground.action +import com.happy.friendogly.presentation.ui.playground.model.MyPlayground import com.happy.friendogly.presentation.ui.playground.model.Playground import com.naver.maps.geometry.LatLng sealed interface PlaygroundMapAction { data class MakePlaygrounds( - val myPlayground: Playground?, + val myPlayground: MyPlayground?, val nearPlaygrounds: List, ) : PlaygroundMapAction + data class MakeMyPlayground( + val myPlayground: MyPlayground, + ) : PlaygroundMapAction + data object RegisterMyPlayground : PlaygroundMapAction data object ShowRegisteringPlaygroundScreen : PlaygroundMapAction diff --git a/android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/mapper/PlaygroundMapper.kt b/android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/mapper/PlaygroundMapper.kt new file mode 100644 index 000000000..2c8422d88 --- /dev/null +++ b/android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/mapper/PlaygroundMapper.kt @@ -0,0 +1,6 @@ +package com.happy.friendogly.presentation.ui.playground.mapper + +import com.happy.friendogly.presentation.ui.playground.model.MyPlayground +import com.happy.friendogly.presentation.ui.playground.model.Playground + +fun Playground.toMyPlayground(): MyPlayground = MyPlayground(id = id, latitude = latitude, longitude = longitude) diff --git a/android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/mapper/PetDetailUiMapper.kt b/android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/mapper/PlaygroundPetDetailUiMapper.kt similarity index 100% rename from android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/mapper/PetDetailUiMapper.kt rename to android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/mapper/PlaygroundPetDetailUiMapper.kt diff --git a/android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/viewmodel/PlaygroundViewModel.kt b/android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/viewmodel/PlaygroundViewModel.kt index afb8d0be7..710415e6b 100644 --- a/android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/viewmodel/PlaygroundViewModel.kt +++ b/android/app/src/main/java/com/happy/friendogly/presentation/ui/playground/viewmodel/PlaygroundViewModel.kt @@ -1,8 +1,6 @@ package com.happy.friendogly.presentation.ui.playground.viewmodel import android.location.Location -import android.os.Handler -import android.os.Looper import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope @@ -10,6 +8,7 @@ import com.happy.friendogly.R import com.happy.friendogly.domain.error.DataError import com.happy.friendogly.domain.fold import com.happy.friendogly.domain.usecase.DeletePlaygroundLeaveUseCase +import com.happy.friendogly.domain.usecase.GetMyPlaygroundUseCase import com.happy.friendogly.domain.usecase.GetPetExistenceUseCase import com.happy.friendogly.domain.usecase.GetPlaygroundInfoUseCase import com.happy.friendogly.domain.usecase.GetPlaygroundSummaryUseCase @@ -29,6 +28,7 @@ import com.happy.friendogly.presentation.ui.playground.action.PlaygroundAlertAct import com.happy.friendogly.presentation.ui.playground.action.PlaygroundAlertAction.AlertFailToCheckPetExistence import com.happy.friendogly.presentation.ui.playground.action.PlaygroundAlertAction.AlertFailToJoinPlaygroundSnackbar import com.happy.friendogly.presentation.ui.playground.action.PlaygroundAlertAction.AlertFailToLeavePlaygroundSnackbar +import com.happy.friendogly.presentation.ui.playground.action.PlaygroundAlertAction.AlertFailToLoadMyPlaygroundSnackbar import com.happy.friendogly.presentation.ui.playground.action.PlaygroundAlertAction.AlertFailToLoadPlaygroundInfoSnackbar import com.happy.friendogly.presentation.ui.playground.action.PlaygroundAlertAction.AlertFailToLoadPlaygroundSummarySnackbar import com.happy.friendogly.presentation.ui.playground.action.PlaygroundAlertAction.AlertFailToLoadPlaygroundsSnackbar @@ -49,6 +49,7 @@ import com.happy.friendogly.presentation.ui.playground.action.PlaygroundMapActio import com.happy.friendogly.presentation.ui.playground.action.PlaygroundMapAction.ChangeBottomSheetBehavior import com.happy.friendogly.presentation.ui.playground.action.PlaygroundMapAction.ChangeTrackingMode import com.happy.friendogly.presentation.ui.playground.action.PlaygroundMapAction.HideRegisteringPlaygroundScreen +import com.happy.friendogly.presentation.ui.playground.action.PlaygroundMapAction.MakeMyPlayground import com.happy.friendogly.presentation.ui.playground.action.PlaygroundMapAction.MakePlaygrounds import com.happy.friendogly.presentation.ui.playground.action.PlaygroundMapAction.MoveCameraCenterPosition import com.happy.friendogly.presentation.ui.playground.action.PlaygroundMapAction.RegisterMyPlayground @@ -59,6 +60,7 @@ import com.happy.friendogly.presentation.ui.playground.action.PlaygroundNavigate import com.happy.friendogly.presentation.ui.playground.action.PlaygroundNavigateAction.NavigateToOtherProfile import com.happy.friendogly.presentation.ui.playground.action.PlaygroundNavigateAction.NavigateToPetImage import com.happy.friendogly.presentation.ui.playground.action.PlaygroundNavigateAction.NavigateToStateMessage +import com.happy.friendogly.presentation.ui.playground.mapper.toMyPlayground import com.happy.friendogly.presentation.ui.playground.mapper.toPresentation import com.happy.friendogly.presentation.ui.playground.model.PlayStatus import com.happy.friendogly.presentation.ui.playground.model.PlaygroundPetDetail @@ -86,11 +88,13 @@ import com.happy.friendogly.presentation.utils.logPlaygroundSize import com.happy.friendogly.presentation.utils.logRegisterMarkerBtnClicked import com.happy.friendogly.presentation.utils.logStateMessageClicked import com.naver.maps.geometry.LatLng +import com.naver.maps.geometry.LatLngBounds import com.naver.maps.map.NaverMap import com.naver.maps.map.overlay.CircleOverlay import com.naver.maps.map.overlay.Marker import com.naver.maps.map.overlay.PathOverlay import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.delay import kotlinx.coroutines.launch import javax.inject.Inject @@ -102,6 +106,7 @@ class PlaygroundViewModel private val postPlaygroundUseCase: PostPlaygroundUseCase, private val patchPlaygroundArrivalUseCase: PatchPlaygroundArrivalUseCase, private val getPlaygroundsUseCase: GetPlaygroundsUseCase, + private val getMyPlaygroundUseCase: GetMyPlaygroundUseCase, private val getPetExistenceUseCase: GetPetExistenceUseCase, private val getPlaygroundInfoUseCase: GetPlaygroundInfoUseCase, private val getPlaygroundSummaryUseCase: GetPlaygroundSummaryUseCase, @@ -118,11 +123,12 @@ class PlaygroundViewModel MutableLiveData(PlayStatus.NO_PLAYGROUND) val myPlayStatus: LiveData get() = _myPlayStatus + private val contentsBounds: MutableLiveData = MutableLiveData() + private val _myPlayground: MutableLiveData = MutableLiveData() val myPlayground: LiveData get() = _myPlayground - private val _nearPlaygrounds: MutableLiveData> = MutableLiveData() - val nearPlaygrounds: LiveData> get() = _nearPlaygrounds + private val nearPlaygrounds: MutableLiveData> = MutableLiveData() private val _recentlyClickedPlayground: MutableLiveData = MutableLiveData() val recentlyClickedPlayground: LiveData get() = _recentlyClickedPlayground @@ -179,7 +185,7 @@ class PlaygroundViewModel override fun clickPlaygroundRefreshBtn() { analyticsHelper.logPlaygroundRefreshBtnClicked() runIfLocationPermissionGranted { - loadNearPlaygrounds() + refreshNearPlaygrounds() } } @@ -234,8 +240,8 @@ class PlaygroundViewModel private fun checkPetExistence() { analyticsHelper.logCheckPetExistenceClicked() viewModelScope.launch { - getPetExistenceUseCase() - .onSuccess { petExistence -> + getPetExistenceUseCase().fold( + onSuccess = { petExistence -> analyticsHelper.logPetExistence(petExistence.isExistPet) if (!petExistence.isExistPet) { _alertAction.emit(AlertHasNotPetDialog) @@ -244,9 +250,11 @@ class PlaygroundViewModel updateUiState(PlaygroundUiState.RegisteringPlayground()) _mapAction.value = ShowRegisteringPlaygroundScreen } - }.onFailure { + }, + onError = { _alertAction.emit(AlertFailToCheckPetExistence) - } + }, + ) } } @@ -266,15 +274,36 @@ class PlaygroundViewModel } } + private fun loadMyPlayground() { + viewModelScope.launch { + getMyPlaygroundUseCase().fold( + onSuccess = { myPlayground -> + _mapAction.value = MakeMyPlayground(myPlayground) + }, + onError = { error -> + when (error) { + DataError.Network.NO_PARTICIPATING_PLAYGROUND -> { + return@launch + } + + else -> { + _alertAction.emit(AlertFailToLoadMyPlaygroundSnackbar) + } + } + }, + ) + } + } + private fun loadPlaygroundSummary(id: Long) { viewModelScope.launch { getPlaygroundSummaryUseCase(id) - .onSuccess { playgroundSummary -> + .fold(onSuccess = { playgroundSummary -> _playgroundSummary.value = playgroundSummary updateUiState(PlaygroundUiState.ViewingPlaygroundSummary) - }.onFailure { + }, onError = { _alertAction.emit(AlertFailToLoadPlaygroundSummarySnackbar) - } + }) } } @@ -352,21 +381,16 @@ class PlaygroundViewModel private fun loadPlaygroundInfo(id: Long) { viewModelScope.launch { - getPlaygroundInfoUseCase(id) - .onSuccess { playgroundInfo -> - updateUiState(PlaygroundUiState.Loading) - _playgroundInfo.value = playgroundInfo.toPresentation() - insertRecentPet(playgroundInfo.playgroundPetDetails) - Handler(Looper.getMainLooper()).postDelayed( - { - _mapAction.value = ChangeBottomSheetBehavior - updateUiState(PlaygroundUiState.ViewingPlaygroundInfo) - }, - ANIMATE_DURATION_MILLIS, - ) - }.onFailure { - _alertAction.emit(AlertFailToLoadPlaygroundInfoSnackbar) + getPlaygroundInfoUseCase(id).fold(onSuccess = { playgroundInfo -> + updateUiState(PlaygroundUiState.Loading) + _playgroundInfo.value = playgroundInfo.toPresentation() + insertRecentPet(playgroundInfo.playgroundPetDetails) + viewModelScope.launch { + delay(ANIMATE_DURATION_MILLIS) + _mapAction.value = ChangeBottomSheetBehavior + updateUiState(PlaygroundUiState.ViewingPlaygroundInfo) } + }, onError = { _alertAction.emit(AlertFailToLoadPlaygroundInfoSnackbar) }) } } @@ -389,21 +413,29 @@ class PlaygroundViewModel return myPlayStatus == PlayStatus.PLAYING && distance > myPlayground.circleOverlay.radius } - private fun loadNearPlaygrounds() { + private fun refreshNearPlaygrounds() { + val contentsBounds = contentsBounds.value ?: return viewModelScope.launch { - getPlaygroundsUseCase() - .onSuccess { playgrounds -> - analyticsHelper.logPlaygroundSize(playgrounds.size) + getPlaygroundsUseCase( + contentsBounds.southLatitude, + contentsBounds.northLatitude, + contentsBounds.westLongitude, + contentsBounds.eastLongitude, + ).fold( + onSuccess = { playgrounds -> updateUiState(PlaygroundUiState.Loading) + analyticsHelper.logPlaygroundSize(playgrounds.size) clearNearPlaygrounds() val nearPlaygrounds = playgrounds.filter { playground -> !playground.isParticipating } _mapAction.value = MakePlaygrounds(null, nearPlaygrounds) - }.onFailure { + }, + onError = { updateUiState(PlaygroundUiState.FindingPlayground()) _alertAction.emit(AlertFailToLoadPlaygroundsSnackbar) - } + }, + ) } } @@ -480,23 +512,36 @@ class PlaygroundViewModel } fun loadPlaygrounds() { + val contentsBounds = contentsBounds.value ?: return viewModelScope.launch { - getPlaygroundsUseCase() - .onSuccess { playgrounds -> + getPlaygroundsUseCase( + contentsBounds.southLatitude, + contentsBounds.northLatitude, + contentsBounds.westLongitude, + contentsBounds.eastLongitude, + ).fold( + onSuccess = { playgrounds -> analyticsHelper.logPlaygroundSize(playgrounds.size) updateUiState(PlaygroundUiState.Loading) clearPlaygrounds() val myPlayground = playgrounds.firstOrNull { playground -> playground.isParticipating } + ?.toMyPlayground() + + if (myPlayground == null) { + loadMyPlayground() + } val nearPlaygrounds = playgrounds.filter { playground -> !playground.isParticipating } _mapAction.value = MakePlaygrounds(myPlayground, nearPlaygrounds) - }.onFailure { + }, + onError = { updateUiState(PlaygroundUiState.FindingPlayground()) _alertAction.emit(AlertFailToLoadPlaygroundsSnackbar) - } + }, + ) } } @@ -517,14 +562,12 @@ class PlaygroundViewModel _recentlyClickedPlayground.value = myPlayground.marker } - fun loadNearPlaygrounds(markers: List) { - _nearPlaygrounds.value = markers - Handler(Looper.getMainLooper()).postDelayed( - { - updateUiState(PlaygroundUiState.FindingPlayground()) - }, - ANIMATE_DURATION_MILLIS, - ) + fun refreshNearPlaygrounds(markers: List) { + nearPlaygrounds.value = markers + viewModelScope.launch { + delay(ANIMATE_DURATION_MILLIS) + updateUiState(PlaygroundUiState.FindingPlayground()) + } } fun showMyPlayground(map: NaverMap) { @@ -606,36 +649,40 @@ class PlaygroundViewModel fun leavePlayground() { viewModelScope.launch { - deletePlaygroundLeaveUseCase() - .onSuccess { + deletePlaygroundLeaveUseCase().fold( + onSuccess = { loadPlaygrounds() _alertAction.emit(AlertLeaveMyPlaygroundSnackbar) - }.onFailure { - _alertAction.emit(AlertFailToLeavePlaygroundSnackbar) - } + }, + onError = { _alertAction.emit(AlertFailToLeavePlaygroundSnackbar) }, + ) } } fun leaveAndRegisterPlayground() { viewModelScope.launch { - deletePlaygroundLeaveUseCase() - .onSuccess { + deletePlaygroundLeaveUseCase().fold( + onSuccess = { _mapAction.value = RegisterMyPlayground - }.onFailure { + }, + onError = { _alertAction.emit(AlertFailToLeavePlaygroundSnackbar) - } + }, + ) } } fun leaveAndJoinPlayground() { viewModelScope.launch { - deletePlaygroundLeaveUseCase() - .onSuccess { + deletePlaygroundLeaveUseCase().fold( + onSuccess = { updateUiState(PlaygroundUiState.Loading) joinPlayground() - }.onFailure { + }, + onError = { _alertAction.emit(AlertFailToLeavePlaygroundSnackbar) - } + }, + ) } } @@ -648,6 +695,10 @@ class PlaygroundViewModel } } + fun updateContentBounds(contentBounds: LatLngBounds) { + contentsBounds.value = contentBounds + } + fun updateAddressAndInKorea( address: String, inKorea: Boolean, diff --git a/android/app/src/main/java/com/happy/friendogly/presentation/ui/statemessage/viewmodel/StateViewModel.kt b/android/app/src/main/java/com/happy/friendogly/presentation/ui/statemessage/viewmodel/StateViewModel.kt index 7fa095513..62429057b 100644 --- a/android/app/src/main/java/com/happy/friendogly/presentation/ui/statemessage/viewmodel/StateViewModel.kt +++ b/android/app/src/main/java/com/happy/friendogly/presentation/ui/statemessage/viewmodel/StateViewModel.kt @@ -4,7 +4,8 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.happy.friendogly.domain.usecase.PathPlaygroundMessageUseCase +import com.happy.friendogly.domain.fold +import com.happy.friendogly.domain.usecase.PatchPlaygroundMessageUseCase import com.happy.friendogly.presentation.base.Event import com.happy.friendogly.presentation.base.emit import com.happy.friendogly.presentation.ui.statemessage.action.StateMessageActionHandler @@ -18,7 +19,7 @@ import javax.inject.Inject class StateViewModel @Inject constructor( - private val patchPlaygroundMessageUseCase: PathPlaygroundMessageUseCase, + private val patchPlaygroundMessageUseCase: PatchPlaygroundMessageUseCase, ) : ViewModel(), StateMessageActionHandler { private val _message: MutableLiveData = MutableLiveData() val message: LiveData get() = _message @@ -26,7 +27,8 @@ class StateViewModel private val _alertAction: MutableLiveData> = MutableLiveData() val alertAction: LiveData> get() = _alertAction - private val _navigateAction: MutableLiveData> = MutableLiveData() + private val _navigateAction: MutableLiveData> = + MutableLiveData() val navigateAction: LiveData> get() = _navigateAction override fun clickCancelBtn() { @@ -36,11 +38,18 @@ class StateViewModel override fun clickConfirmBtn() { viewModelScope.launch { val newMessage = message.value ?: return@launch - patchPlaygroundMessageUseCase(newMessage).onSuccess { - _navigateAction.emit(StateMessageNavigateAction.FinishStateMessageActivity(messageUpdated = true)) - }.onFailure { - _alertAction.emit(StateMessageAlertAction.AlertFailToPatchPlaygroundStateMessage) - } + patchPlaygroundMessageUseCase(newMessage).fold( + onSuccess = { + _navigateAction.emit( + StateMessageNavigateAction.FinishStateMessageActivity( + messageUpdated = true, + ), + ) + }, + onError = { + _alertAction.emit(StateMessageAlertAction.AlertFailToPatchPlaygroundStateMessage) + }, + ) } } diff --git a/android/app/src/main/java/com/happy/friendogly/remote/api/ApiClient.kt b/android/app/src/main/java/com/happy/friendogly/remote/api/ApiClient.kt index 50fb15b5d..6c0efb869 100644 --- a/android/app/src/main/java/com/happy/friendogly/remote/api/ApiClient.kt +++ b/android/app/src/main/java/com/happy/friendogly/remote/api/ApiClient.kt @@ -13,6 +13,7 @@ class ApiClient { const val POST_PLAYGROUND = BASE_URL const val PATCH_PLAYGROUND_ARRIVAL = "$BASE_URL/arrival" const val GET_PLAYGROUNDS = "$BASE_URL/locations" + const val GET_MY_PLAYGROUND = "$BASE_URL/locations/mine" const val GET_PLAYGROUND_INFO = "$BASE_URL/{id}" const val GET_PLAYGROUND_SUMMARY = "$BASE_URL/{playgroundId}/summary" const val POST_PLAYGROUND_JOIN = "$BASE_URL/{playgroundId}/join" diff --git a/android/app/src/main/java/com/happy/friendogly/remote/api/PlaygroundService.kt b/android/app/src/main/java/com/happy/friendogly/remote/api/PlaygroundService.kt index 826e5a891..9d77602a8 100644 --- a/android/app/src/main/java/com/happy/friendogly/remote/api/PlaygroundService.kt +++ b/android/app/src/main/java/com/happy/friendogly/remote/api/PlaygroundService.kt @@ -19,6 +19,7 @@ import retrofit2.http.GET import retrofit2.http.PATCH import retrofit2.http.POST import retrofit2.http.Path +import retrofit2.http.Query interface PlaygroundService { @POST(ApiClient.PlayGround.POST_PLAYGROUND) @@ -32,7 +33,15 @@ interface PlaygroundService { ): BaseResponse @GET(ApiClient.PlayGround.GET_PLAYGROUNDS) - suspend fun getPlaygrounds(): BaseResponse> + suspend fun getPlaygrounds( + @Query("startLatitude") startLatitude: Double, + @Query("endLatitude") endLatitude: Double, + @Query("startLongitude") startLongitude: Double, + @Query("endLongitude") endLongitude: Double, + ): BaseResponse> + + @GET(ApiClient.PlayGround.GET_MY_PLAYGROUND) + suspend fun getMyPlayground(): BaseResponse @GET(ApiClient.Pet.GET_PET_EXISTENCE) suspend fun getPetExistence(): BaseResponse diff --git a/android/app/src/main/java/com/happy/friendogly/remote/source/PlaygroundDataSourceImpl.kt b/android/app/src/main/java/com/happy/friendogly/remote/source/PlaygroundDataSourceImpl.kt index 7050b2609..229c5dd04 100644 --- a/android/app/src/main/java/com/happy/friendogly/remote/source/PlaygroundDataSourceImpl.kt +++ b/android/app/src/main/java/com/happy/friendogly/remote/source/PlaygroundDataSourceImpl.kt @@ -44,8 +44,26 @@ class PlaygroundDataSourceImpl return runCatching { service.getPetExistence().data.toData() } } - override suspend fun getNearPlaygrounds(): Result> { - return runCatching { service.getPlaygrounds().data.toData() } + override suspend fun getPlaygrounds( + startLatitude: Double, + endLatitude: Double, + startLongitude: Double, + endLongitude: Double, + ): Result> { + return runCatching { + service.getPlaygrounds( + startLatitude, + endLatitude, + startLongitude, + endLongitude, + ).data.toData() + } + } + + override suspend fun getMyPlayground(): Result { + return runCatching { + service.getMyPlayground().data.toData() + } } override suspend fun getPlaygroundInfo(id: Long): Result { diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 052da06f1..2dc87f5e0 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -262,7 +262,7 @@ 실시간으로 위치를 추적 중입니다. 정보 소개 - 새로고침 + 현 지도에서 조회 놀이터에 참여했어요! 놀이터에서 나갔습니다! 오랜 시간 자리를 비워 자동으로 놀이터에서 나갔습니다! @@ -285,6 +285,7 @@ 놀이터 등록에 실패했습니다! 놀이터 도착 여부를 업데이트하지 못했습니다! 놀이터 나가기에 실패했습니다! + 내가 참여한 놀이터를 불러오지 못했습니다! 놀이터 정보를 불러오지 못했습니다! 놀이터 요약 정보를 불러오지 못했습니다! 놀이터 참여하기에 실패했습니다!