Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat/#120] 게시물 떠먹기 API 연결 #123

Merged
merged 15 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -4,5 +4,6 @@ import com.spoony.spoony.data.dto.base.BaseResponse
import com.spoony.spoony.data.dto.response.GetPostResponseDto

interface PostRemoteDataSource {
suspend fun postScoopPost(postId: Int, userId: Int): BaseResponse<Boolean>
suspend fun getPostData(postId: Int, userId: Int): BaseResponse<GetPostResponseDto>
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,19 @@ package com.spoony.spoony.data.datasourceimpl

import com.spoony.spoony.data.datasource.PostRemoteDataSource
import com.spoony.spoony.data.dto.base.BaseResponse
import com.spoony.spoony.data.dto.request.PostScoopRequestDto
import com.spoony.spoony.data.dto.response.GetPostResponseDto
import com.spoony.spoony.data.service.PostService
import javax.inject.Inject

class PostRemoteDataSourceImpl @Inject constructor(
private val postService: PostService
) : PostRemoteDataSource {
override suspend fun getPostData(postId: Int, userId: Int): BaseResponse<GetPostResponseDto> = postService.getPost(userId = userId, postId = postId)
override suspend fun getPostData(postId: Int, userId: Int): BaseResponse<GetPostResponseDto> =
postService.getPost(userId = userId, postId = postId)

override suspend fun postScoopPost(postId: Int, userId: Int): BaseResponse<Boolean> =
postService.postScoopPost(
PostScoopRequestDto(postId = postId, userId = userId)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ data class BaseResponse<T>(
val error: ErrorResponse? = null,
@SerialName("data")
val data: T? = null
)

@Serializable
data class ErrorResponse(
@SerialName("message")
val message: String
)
) {
@Serializable
data class ErrorResponse(
@SerialName("message")
val message: String
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.spoony.spoony.data.dto.request

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

@Serializable
data class PostScoopRequestDto(
@SerialName("postId")
val postId: Int,
@SerialName("userId")
val userId: Int
)
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ class PostRepositoryImpl @Inject constructor(
}

override suspend fun postScoopPost(postId: Int, userId: Int): Result<Boolean> =
Result.success(
true
)
runCatching {
postRemoteDataSource.postScoopPost(postId = postId, userId = userId).success
}

override suspend fun postAddMap(postId: Int, userId: Int): Result<Boolean> =
Result.success(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.spoony.spoony.data.service

import com.spoony.spoony.data.dto.base.BaseResponse
import com.spoony.spoony.data.dto.request.PostScoopRequestDto
import com.spoony.spoony.data.dto.response.GetPostResponseDto
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Path

interface PostService {
Expand All @@ -11,4 +14,9 @@ interface PostService {
@Path("userId") userId: Int,
@Path("postId") postId: Int
): BaseResponse<GetPostResponseDto>

@POST("/api/v1/post/scoop")
suspend fun postScoopPost(
@Body postScoopRequestDto: PostScoopRequestDto
): BaseResponse<Boolean>
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ import com.spoony.spoony.core.state.UiState
import com.spoony.spoony.core.util.extension.hexToColor
import com.spoony.spoony.core.util.extension.toValidHexColor
import com.spoony.spoony.domain.entity.CategoryEntity
import com.spoony.spoony.domain.entity.PostEntity
import com.spoony.spoony.domain.entity.UserEntity
import com.spoony.spoony.presentation.main.SHOW_SNACKBAR_TIMEMILLIS
import com.spoony.spoony.presentation.placeDetail.component.IconDropdownMenu
Expand All @@ -53,6 +52,7 @@ import com.spoony.spoony.presentation.placeDetail.component.PlaceDetailImageLazy
import com.spoony.spoony.presentation.placeDetail.component.ScoopDialog
import com.spoony.spoony.presentation.placeDetail.component.StoreInfo
import com.spoony.spoony.presentation.placeDetail.component.UserProfileInfo
import com.spoony.spoony.presentation.placeDetail.model.PostModel
import com.spoony.spoony.presentation.placeDetail.type.DropdownOption
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
Expand Down Expand Up @@ -128,12 +128,12 @@ fun PlaceDetailRoute(
)
}

when (state.postEntity) {
when (state.postModel) {
is UiState.Empty -> {}
is UiState.Loading -> {}
is UiState.Failure -> {}
is UiState.Success -> {
with(state.postEntity as UiState.Success<PostEntity>) {
with(state.postModel as UiState.Success<PostModel>) {
Scaffold(
snackbarHost = {
SnackbarHost(hostState = snackBarHostState) { snackbarData ->
Expand All @@ -151,9 +151,9 @@ fun PlaceDetailRoute(
PlaceDetailBottomBar(
modifier = Modifier
.navigationBarsPadding(),
addMapCount = data.addMapCount,
isScooped = data.isScooped,
isAddMap = data.isAddMap,
addMapCount = state.addMapCount,
isScooped = state.isScooped,
isAddMap = state.isAddMap,
onScoopButtonClick = {
scoopDialogVisibility = true
},
Expand Down Expand Up @@ -183,7 +183,7 @@ fun PlaceDetailRoute(
date = data.date,
placeAddress = data.placeAddress,
placeName = data.placeName,
isScooped = data.isScooped,
isScooped = state.isScooped,
dropdownMenuList = state.dropDownMenuList,
onReportButtonClick = navigateToReport
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package com.spoony.spoony.presentation.placeDetail

import com.spoony.spoony.core.state.UiState
import com.spoony.spoony.domain.entity.PostEntity
import com.spoony.spoony.domain.entity.UserEntity
import com.spoony.spoony.presentation.placeDetail.model.PostModel
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf

data class PlaceDetailState(
val postId: UiState<Int> = UiState.Loading,
val userId: UiState<Int> = UiState.Loading,
val postEntity: UiState<PostEntity> = UiState.Loading,
val isScooped: Boolean = false,
val isAddMap: Boolean = false,
val addMapCount: Int = 0,
val postModel: UiState<PostModel> = UiState.Loading,
val userEntity: UiState<UserEntity> = UiState.Loading,
val spoonAmountEntity: UiState<Int> = UiState.Loading,
val dropDownMenuList: ImmutableList<String> = persistentListOf("신고하기")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.lifecycle.viewModelScope
import androidx.navigation.toRoute
import com.spoony.spoony.core.state.UiState
import com.spoony.spoony.domain.repository.PostRepository
import com.spoony.spoony.presentation.placeDetail.model.toModel
import com.spoony.spoony.presentation.placeDetail.navigation.PlaceDetail
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
Expand All @@ -15,6 +16,7 @@ import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import timber.log.Timber

@HiltViewModel
class PlaceDetailViewModel @Inject constructor(
Expand All @@ -38,45 +40,42 @@ class PlaceDetailViewModel @Inject constructor(
getPost(postArgs.postId, postArgs.userId)
}

fun getPost(postId: Int, userId: Int) {
private fun getPost(postId: Int, userId: Int) {
viewModelScope.launch {
postRepository.getPost(postId = postId, userId = userId)
.onSuccess { response ->
_state.update {
it.copy(
postEntity = UiState.Success(response)
postModel = UiState.Success(
response.toModel()
),
isScooped = response.isScooped,
isAddMap = response.isAddMap,
addMapCount = response.addMapCount
)
}
}
.onFailure {
_state.update {
it.copy(
postEntity = UiState.Failure("게시물 조회 실패")
postModel = UiState.Failure("게시물 조회 실패")
)
}
}
}
}

fun useSpoon(userId: Int, postId: Int) {
fun useSpoon(postId: Int, userId: Int) {
viewModelScope.launch {
postRepository.postScoopPost(userId = userId, postId = postId)
.onSuccess { response ->
(_state.value.postEntity as? UiState.Success)?.data?.let { currentPostEntity ->
with(currentPostEntity) {
_state.update {
it.copy(
postEntity = UiState.Success(
copy(isScooped = true)
)
)
}
}
postRepository.postScoopPost(postId = postId, userId = userId)
.onSuccess {
_state.update {
it.copy(
isScooped = true
)
}
}
.onFailure {
// 실패 했을 경우
}
.onFailure(Timber::e)
}
}

Expand All @@ -85,24 +84,14 @@ class PlaceDetailViewModel @Inject constructor(
postRepository.postAddMap(userId = userId, postId = postId)
.onSuccess { response ->
_sideEffect.emit(PlaceDetailSideEffect.ShowSnackbar("내 지도에 추가되었어요."))
(_state.value.postEntity as? UiState.Success)?.data?.let { currentPostEntity ->
with(currentPostEntity) {
_state.update {
it.copy(
postEntity = UiState.Success(
copy(
isAddMap = true,
addMapCount = currentPostEntity.addMapCount + 1
)
)
)
}
}
_state.update {
it.copy(
isAddMap = true,
addMapCount = it.addMapCount + 1
)
}
}
.onFailure {
// 실패 했을 경우
}
.onFailure(Timber::e)
}
}

Expand All @@ -111,24 +100,14 @@ class PlaceDetailViewModel @Inject constructor(
postRepository.deletePinMap(userId = userId, postId = postId)
.onSuccess { response ->
_sideEffect.emit(PlaceDetailSideEffect.ShowSnackbar("내 지도에서 삭제되었어요."))
(_state.value.postEntity as? UiState.Success)?.data?.let { currentPostEntity ->
with(currentPostEntity) {
_state.update {
it.copy(
postEntity = UiState.Success(
copy(
isAddMap = false,
addMapCount = currentPostEntity.addMapCount - 1
)
)
)
}
}
_state.update {
it.copy(
isAddMap = false,
addMapCount = it.addMapCount - 1
)
}
}
.onFailure {
// 실패 했을 경우
}
.onFailure(Timber::e)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.spoony.spoony.presentation.placeDetail.model

import com.spoony.spoony.domain.entity.CategoryEntity
import com.spoony.spoony.domain.entity.PostEntity
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList

data class PostModel(
val photoUrlList: ImmutableList<String>,
val title: String,
val date: String,
val menuList: ImmutableList<String>,
val description: String,
val placeName: String,
val placeAddress: String,
val latitude: Double,
val longitude: Double,
val category: CategoryEntity
)

fun PostEntity.toModel(): PostModel = PostModel(
photoUrlList = this.photoUrlList.toImmutableList(),
title = this.title,
date = this.date,
menuList = this.menuList.toImmutableList(),
description = this.description,
placeName = this.placeName,
placeAddress = this.placeAddress,
latitude = this.latitude,
longitude = this.longitude,
category = this.category
)
Loading