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

♻ separate apis of recipe list and recipe detail #412

Merged
merged 6 commits into from
Oct 24, 2024
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 @@ -3,15 +3,15 @@ package net.pengcook.android.data.datasource
import androidx.paging.PagingSource
import androidx.paging.PagingState
import net.pengcook.android.data.repository.feed.FeedRepository
import net.pengcook.android.presentation.core.model.Recipe
import net.pengcook.android.presentation.core.model.RecipeForList

class FeedPagingSource(
private val feedRepository: FeedRepository,
private val initialPageNumber: Int = 0,
private val category: String? = null,
private val userId: Long? = null,
) : PagingSource<Int, Recipe>() {
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Recipe> {
) : PagingSource<Int, RecipeForList>() {
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, RecipeForList> {
val pageNumber = params.key ?: initialPageNumber
return runCatching {
val feeds =
Expand All @@ -24,11 +24,11 @@ class FeedPagingSource(
nextKey = nextKey,
)
}.onFailure { throwable ->
LoadResult.Error<Int, Recipe>(throwable)
LoadResult.Error<Int, RecipeForList>(throwable)
}.getOrThrow()
}

override fun getRefreshKey(state: PagingState<Int, Recipe>): Int? {
override fun getRefreshKey(state: PagingState<Int, RecipeForList>): Int? {
return state.anchorPosition?.let { anchorPosition ->
state.closestPageToPosition(anchorPosition)?.prevKey
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.pengcook.android.data.datasource.feed

import net.pengcook.android.data.model.feed.item.FeedItemResponse
import net.pengcook.android.data.model.feed.item.FeedItemResponse2
import net.pengcook.android.data.model.feed.item.FeedItemResponseForList
import net.pengcook.android.data.model.step.RecipeStepResponse
import net.pengcook.android.data.remote.api.FeedService
import retrofit2.Response
Expand All @@ -20,12 +21,26 @@ class DefaultFeedRemoteDataSource
category: String?,
keyword: String?,
userId: Long?,
): Response<List<FeedItemResponse>> = feedService.fetchRecipes(accessToken, pageNumber, pageSize, category, keyword, userId)
): Response<List<FeedItemResponseForList>> =
feedService.fetchRecipes2(
accessToken = accessToken,
accept = "application/vnd.pengcook.v1+json",
pageNumber = pageNumber,
pageSize = pageSize,
category = category,
keyword = keyword,
userId = userId,
)

override suspend fun fetchRecipeSteps(recipeId: Long): Response<List<RecipeStepResponse>> = feedService.fetchRecipeSteps(recipeId)

override suspend fun deleteRecipe(
accessToken: String,
recipeId: Long,
): Response<Unit> = feedService.deleteRecipe(accessToken, recipeId)

override suspend fun fetchRecipe(
accessToken: String,
recipeId: Long,
): Response<FeedItemResponse2> = feedService.fetchRecipe(accessToken, recipeId)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.pengcook.android.data.datasource.feed

import net.pengcook.android.data.model.feed.item.FeedItemResponse
import net.pengcook.android.data.model.feed.item.FeedItemResponse2
import net.pengcook.android.data.model.feed.item.FeedItemResponseForList
import net.pengcook.android.data.model.step.RecipeStepResponse
import retrofit2.Response

Expand All @@ -12,12 +13,17 @@ interface FeedRemoteDataSource {
category: String?,
keyword: String?,
userId: Long?,
): Response<List<FeedItemResponse>>
): Response<List<FeedItemResponseForList>>

suspend fun fetchRecipeSteps(recipeId: Long): Response<List<RecipeStepResponse>>

suspend fun deleteRecipe(
accessToken: String,
recipeId: Long,
): Response<Unit>

suspend fun fetchRecipe(
accessToken: String,
recipeId: Long,
): Response<FeedItemResponse2>
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package net.pengcook.android.data.datasource.profile

import net.pengcook.android.data.model.feed.item.FeedItemResponse
import net.pengcook.android.data.model.feed.item.FeedItemResponseForList
import net.pengcook.android.data.model.profile.UpdateProfileRequest
import net.pengcook.android.data.model.profile.UpdateProfileResponse
import net.pengcook.android.data.model.profile.UserProfileResponse
Expand Down Expand Up @@ -32,9 +32,10 @@ class DefaultProfileRemoteDataSource
userId: Long,
pageNumber: Int,
pageSize: Int,
): Response<List<FeedItemResponse>> =
feedService.fetchRecipes(
): Response<List<FeedItemResponseForList>> =
feedService.fetchRecipes2(
accessToken = accessToken,
accept = "application/vnd.pengcook.v1+json",
pageNumber = pageNumber,
pageSize = pageSize,
category = null,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package net.pengcook.android.data.datasource.profile

import net.pengcook.android.data.model.feed.item.FeedItemResponse
import net.pengcook.android.data.model.feed.item.FeedItemResponseForList
import net.pengcook.android.data.model.profile.UpdateProfileRequest
import net.pengcook.android.data.model.profile.UpdateProfileResponse
import net.pengcook.android.data.model.profile.UserProfileResponse
Expand All @@ -21,5 +21,5 @@ interface ProfileRemoteDataSource {
userId: Long,
pageNumber: Int,
pageSize: Int,
): Response<List<FeedItemResponse>>
): Response<List<FeedItemResponseForList>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,20 @@ data class FeedItemResponse(
val commentCount: Long,
val mine: Boolean,
)

data class FeedItemResponse2(
val author: AuthorResponse,
val category: List<CategoryResponse>,
val cookingTime: String,
val description: String,
val difficulty: Int,
val ingredient: List<IngredientResponse>,
val likeCount: Long,
val recipeId: Long,
val thumbnail: String,
val title: String,
val commentCount: Long,
val mine: Boolean,
// like 여부 수정
val isLike: Boolean,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package net.pengcook.android.data.model.feed.item

data class FeedItemResponseForList(
val author: AuthorResponse,
val commentCount: Long,
val createdAt: String,
val likeCount: Long,
val mine: Boolean,
val recipeId: Long,
val thumbnail: String,
val title: String,
)
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package net.pengcook.android.data.remote.api

import net.pengcook.android.data.model.feed.item.FeedItemResponse
import net.pengcook.android.data.model.feed.item.FeedItemResponse2
import net.pengcook.android.data.model.feed.item.FeedItemResponseForList
import net.pengcook.android.data.model.step.RecipeStepResponse
import retrofit2.Response
import retrofit2.http.DELETE
Expand All @@ -20,6 +22,17 @@ interface FeedService {
@Query("userId") userId: Long?,
): Response<List<FeedItemResponse>>

@GET("/recipes")
suspend fun fetchRecipes2(
@Header("Authorization") accessToken: String,
@Header("Accept") accept: String,
@Query("pageNumber") pageNumber: Int,
@Query("pageSize") pageSize: Int,
@Query("category") category: String?,
@Query("keyword") keyword: String?,
@Query("userId") userId: Long?,
): Response<List<FeedItemResponseForList>>

@GET("/recipes/{recipeId}/steps")
suspend fun fetchRecipeSteps(
@Path("recipeId") recipeId: Long,
Expand All @@ -30,4 +43,10 @@ interface FeedService {
@Header("Authorization") accessToken: String,
@Path("recipeId") recipeId: Long,
): Response<Unit>

@GET("/recipes/{recipeId}")
suspend fun fetchRecipe(
@Header("Authorization") accessToken: String,
@Path("recipeId") recipeId: Long,
): Response<FeedItemResponse2>
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ package net.pengcook.android.data.repository.feed
import kotlinx.coroutines.flow.first
import net.pengcook.android.data.datasource.auth.SessionLocalDataSource
import net.pengcook.android.data.datasource.feed.FeedRemoteDataSource
import net.pengcook.android.data.model.feed.item.FeedItemResponse
import net.pengcook.android.data.model.feed.item.FeedItemResponseForList
import net.pengcook.android.data.model.step.RecipeStepResponse
import net.pengcook.android.data.util.mapper.toRecipe
import net.pengcook.android.data.util.mapper.toRecipeForItem
import net.pengcook.android.data.util.mapper.toRecipeForList
import net.pengcook.android.data.util.mapper.toRecipeStep
import net.pengcook.android.data.util.network.NetworkResponseHandler
import net.pengcook.android.presentation.core.model.Recipe
import net.pengcook.android.presentation.core.model.RecipeForItem
import net.pengcook.android.presentation.core.model.RecipeForList
import net.pengcook.android.presentation.core.model.RecipeStep
import javax.inject.Inject
import javax.inject.Singleton
Expand All @@ -27,7 +29,7 @@ class DefaultFeedRepository
category: String?,
keyword: String?,
userId: Long?,
): Result<List<Recipe>> =
): Result<List<RecipeForList>> =
runCatching {
val accessToken =
sessionLocalDataSource.sessionData.first().accessToken ?: throw RuntimeException()
Expand All @@ -40,7 +42,7 @@ class DefaultFeedRepository
keyword,
userId,
)
body(response, RESPONSE_CODE_SUCCESS).map(FeedItemResponse::toRecipe)
body(response, RESPONSE_CODE_SUCCESS).map(FeedItemResponseForList::toRecipeForList)
}

override suspend fun fetchRecipeSteps(recipeId: Long): Result<List<RecipeStep>> =
Expand All @@ -57,6 +59,14 @@ class DefaultFeedRepository
body(response, RESPONSE_CODE_DELETED)
}

override suspend fun fetchRecipe(recipeId: Long): Result<RecipeForItem> =
runCatching {
val accessToken =
sessionLocalDataSource.sessionData.first().accessToken ?: throw RuntimeException()
val response = feedRemoteDataSource.fetchRecipe(accessToken, recipeId)
body(response, RESPONSE_CODE_SUCCESS).toRecipeForItem()
}

companion object {
private const val RESPONSE_CODE_SUCCESS = 200
private const val RESPONSE_CODE_DELETED = 204
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.pengcook.android.data.repository.feed

import net.pengcook.android.presentation.core.model.Recipe
import net.pengcook.android.presentation.core.model.RecipeForItem
import net.pengcook.android.presentation.core.model.RecipeForList
import net.pengcook.android.presentation.core.model.RecipeStep

interface FeedRepository {
Expand All @@ -10,9 +11,11 @@ interface FeedRepository {
category: String?,
keyword: String?,
userId: Long?,
): Result<List<Recipe>>
): Result<List<RecipeForList>>

suspend fun fetchRecipeSteps(recipeId: Long): Result<List<RecipeStep>>

suspend fun deleteRecipe(recipeId: Long): Result<Unit>

suspend fun fetchRecipe(recipeId: Long): Result<RecipeForItem>
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import kotlinx.coroutines.flow.first
import net.pengcook.android.data.datasource.auth.SessionLocalDataSource
import net.pengcook.android.data.datasource.profile.ProfileRemoteDataSource
import net.pengcook.android.data.model.profile.UpdateProfileRequest
import net.pengcook.android.data.util.mapper.toRecipe
import net.pengcook.android.data.util.mapper.toRecipeForList
import net.pengcook.android.data.util.mapper.toUserProfile
import net.pengcook.android.data.util.network.NetworkResponseHandler
import net.pengcook.android.domain.model.profile.UserProfile
import net.pengcook.android.presentation.core.model.Recipe
import net.pengcook.android.presentation.core.model.RecipeForList
import javax.inject.Inject
import javax.inject.Singleton

Expand Down Expand Up @@ -46,13 +46,13 @@ class DefaultProfileRepository
userId: Long,
pageNumber: Int,
pageSize: Int,
): Result<List<Recipe>> =
): Result<List<RecipeForList>> =
runCatching {
val accessToken =
sessionLocalDataSource.sessionData.first().accessToken ?: throw RuntimeException()
val response =
profileRemoteDataSource.fetchUserFeeds(accessToken, userId, pageNumber, pageSize)
body(response, CODE_SUCCESSFUL).map { recipeResponse -> recipeResponse.toRecipe() }
body(response, CODE_SUCCESSFUL).map { recipeResponse -> recipeResponse.toRecipeForList() }
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package net.pengcook.android.data.repository.profile

import net.pengcook.android.data.model.profile.UpdateProfileRequest
import net.pengcook.android.domain.model.profile.UserProfile
import net.pengcook.android.presentation.core.model.Recipe
import net.pengcook.android.presentation.core.model.RecipeForList

interface ProfileRepository {
suspend fun fetchUserInformation(userId: Long): Result<UserProfile>
Expand All @@ -15,5 +15,5 @@ interface ProfileRepository {
userId: Long,
pageNumber: Int,
pageSize: Int,
): Result<List<Recipe>>
): Result<List<RecipeForList>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,61 @@ package net.pengcook.android.data.util.mapper

import net.pengcook.android.data.model.feed.item.AuthorResponse
import net.pengcook.android.data.model.feed.item.CategoryResponse
import net.pengcook.android.data.model.feed.item.FeedItemResponse
import net.pengcook.android.data.model.feed.item.FeedItemResponse2
import net.pengcook.android.data.model.feed.item.FeedItemResponseForList
import net.pengcook.android.data.model.feed.item.IngredientResponse
import net.pengcook.android.data.model.step.RecipeStepResponse
import net.pengcook.android.presentation.core.model.Ingredient
import net.pengcook.android.presentation.core.model.Recipe
import net.pengcook.android.presentation.core.model.RecipeForItem
import net.pengcook.android.presentation.core.model.RecipeForList
import net.pengcook.android.presentation.core.model.RecipeStep
import net.pengcook.android.presentation.core.model.User

fun FeedItemResponse.toRecipe(): Recipe =
Recipe(
fun FeedItemResponseForList.toRecipeForList(): RecipeForList =
RecipeForList(
title = title,
recipeId = recipeId,
thumbnail = thumbnail,
user = author.toUser(),
likeCount = likeCount,
commentCount = commentCount,
mine = mine,
createdAt = createdAt,
)

fun FeedItemResponse2.toRecipeForItem(): RecipeForItem =
RecipeForItem(
title = title,
recipeId = recipeId,
category = category.map(CategoryResponse::toCategoryText),
cookingTime = cookingTime,
thumbnail = thumbnail,
user = author.toUser(),
likeCount = likeCount,
ingredients = ingredient.map(IngredientResponse::toIngredient),
difficulty = difficulty,
introduction = description,
commentCount = commentCount,
mine = mine,
cookingTime = cookingTime,
difficulty = difficulty,
category = category.map(CategoryResponse::toCategoryText),
ingredients = ingredient.map(IngredientResponse::toIngredient),
introduction = description,
isLiked = isLike,
)

// fun FeedItemResponse.toRecipe(): Recipe =
// Recipe(
// title = title,
// recipeId = recipeId,
// category = category.map(CategoryResponse::toCategoryText),
// cookingTime = cookingTime,
// thumbnail = thumbnail,
// user = author.toUser(),
// likeCount = likeCount,
// ingredients = ingredient.map(IngredientResponse::toIngredient),
// difficulty = difficulty,
// introduction = description,
// commentCount = commentCount,
// mine = mine,
// )

fun RecipeStepResponse.toRecipeStep(): RecipeStep =
RecipeStep(
stepId = stepId,
Expand Down
Loading
Loading