Skip to content

Commit

Permalink
Merge pull request #24 from NOW-SOPT-APP4-KREAM/feat-view2-xml
Browse files Browse the repository at this point in the history
[feat] 추천 뷰 구현
  • Loading branch information
Hyobeen-Park authored May 23, 2024
2 parents fa77cef + 6eee5d2 commit 2c8b03b
Show file tree
Hide file tree
Showing 68 changed files with 1,591 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package org.sopt.kream.data.datasource

import org.sopt.kream.data.model.response.ResponseProductDetailDto
import org.sopt.kream.data.model.response.ResponseRecommendProductDto
import org.sopt.kream.data.model.response.ResponseSearchProductDto
import org.sopt.kream.util.base.BaseResponse

interface ProductRemoteDataSource {
suspend fun getSearchProduct(findName: String): BaseResponse<ResponseSearchProductDto>

suspend fun getProductDetail(productId: Int): BaseResponse<ResponseProductDetailDto>

suspend fun getRecommendProduct(memberId: Int): BaseResponse<ResponseRecommendProductDto>
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.sopt.kream.data.datasourceimpl
import org.sopt.kream.data.ServicePool
import org.sopt.kream.data.datasource.ProductRemoteDataSource
import org.sopt.kream.data.model.response.ResponseProductDetailDto
import org.sopt.kream.data.model.response.ResponseRecommendProductDto
import org.sopt.kream.data.model.response.ResponseSearchProductDto
import org.sopt.kream.util.base.BaseResponse

Expand All @@ -12,4 +13,6 @@ class ProductRemoteDataSourceImpl : ProductRemoteDataSource {
override suspend fun getSearchProduct(findName: String): BaseResponse<ResponseSearchProductDto> = productService.getSearchProduct(findName = findName)

override suspend fun getProductDetail(productId: Int): BaseResponse<ResponseProductDetailDto> = productService.getProductDetail(productId = productId)

override suspend fun getRecommendProduct(memberId: Int): BaseResponse<ResponseRecommendProductDto> = productService.getRecommendProduct(memberId = memberId)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.sopt.kream.data.mapper

import org.sopt.kream.data.model.response.ResponseRecommendProductDto.ResponseForYouProductDto
import org.sopt.kream.domain.model.RecommendForYouProductModel

fun ResponseForYouProductDto.toRecommendForYouProductModel() =
RecommendForYouProductModel(
thumbnailUrl = this.thumbnailUrl,
brandTitle = this.brandTitle,
engTitle = this.engTitle,
price = this.price,
transactionCount = this.transactionCount,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.sopt.kream.data.mapper

import org.sopt.kream.data.model.response.ResponseRecommendProductDto.ResponseJustDroppedProductDto
import org.sopt.kream.domain.model.RecommendJustDroppedProductModel

fun ResponseJustDroppedProductDto.toRecommendJustDroppedProductModel() =
RecommendJustDroppedProductModel(
thumbnailUrl = this.thumbnailUrl,
brandTitle = this.brandTitle,
engTitle = this.engTitle,
price = this.price,
transactionCount = this.transactionCount,
isScrap = this.isScrap,
isFast = this.isFast,
isFreeDeliver = this.isFreeDeliver,
isSave = this.isSave,
isCoupon = this.isCoupon,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.sopt.kream.data.mapper

import org.sopt.kream.data.model.response.ResponseRecommendProductDto
import org.sopt.kream.domain.model.RecommendProductModel

fun ResponseRecommendProductDto.toRecommendProductModel() =
RecommendProductModel(
recommendForYouProducts = this.forYouList.map { it.toRecommendForYouProductModel() },
recommendJustDroppedProducts = this.justDropList.map { it.toRecommendJustDroppedProductModel() },
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.sopt.kream.data.model.response

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

@Serializable
data class ResponseRecommendProductDto(
@SerialName("forYouList")
val forYouList: List<ResponseForYouProductDto>,
@SerialName("justDropList")
val justDropList: List<ResponseJustDroppedProductDto>,
) {
@Serializable
data class ResponseForYouProductDto(
@SerialName("thumbnailUrl")
val thumbnailUrl: String,
@SerialName("brandTitle")
val brandTitle: String,
@SerialName("engTitle")
val engTitle: String,
@SerialName("price")
val price: String,
@SerialName("transactionCount")
val transactionCount: String,
)

@Serializable
data class ResponseJustDroppedProductDto(
@SerialName("thumbnailUrl")
val thumbnailUrl: String,
@SerialName("brandTitle")
val brandTitle: String,
@SerialName("engTitle")
val engTitle: String,
@SerialName("price")
val price: String,
@SerialName("transactionCount")
val transactionCount: String,
@SerialName("isScrap")
val isScrap: Boolean,
@SerialName("isFast")
val isFast: Boolean,
@SerialName("isFreeDeliver")
val isFreeDeliver: Boolean,
@SerialName("isSave")
val isSave: Boolean,
@SerialName("isCoupon")
val isCoupon: Boolean,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package org.sopt.kream.data.repository

import org.sopt.kream.data.datasource.ProductRemoteDataSource
import org.sopt.kream.data.mapper.toProductDetailModel
import org.sopt.kream.data.mapper.toRecommendProductModel
import org.sopt.kream.data.mapper.toSearchProductModel
import org.sopt.kream.domain.model.ProductDetailModel
import org.sopt.kream.domain.model.RecommendProductModel
import org.sopt.kream.domain.model.SearchProductModel
import org.sopt.kream.domain.repository.ProductRepository

Expand All @@ -19,4 +21,9 @@ class ProductRepositoryImpl(
runCatching {
productRemoteDataSource.getProductDetail(productId = productId).data.toProductDetailModel()
}

override suspend fun getRecommendProduct(memberId: Int): Result<RecommendProductModel> =
runCatching {
productRemoteDataSource.getRecommendProduct(memberId = memberId).data.toRecommendProductModel()
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.sopt.kream.data.service

import org.sopt.kream.data.model.response.ResponseProductDetailDto
import org.sopt.kream.data.model.response.ResponseRecommendProductDto
import org.sopt.kream.data.model.response.ResponseReleaseProductDto
import org.sopt.kream.data.model.response.ResponseSearchProductDto
import org.sopt.kream.util.base.BaseResponse
Expand Down Expand Up @@ -35,4 +36,9 @@ interface ProductService {
companion object {
const val MEMBER_ID = 1
}

@GET("product/recommend")
suspend fun getRecommendProduct(
@Header("memberId") memberId: Int,
): BaseResponse<ResponseRecommendProductDto>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.sopt.kream.domain.model

data class RecommendForYouProductModel(
val thumbnailUrl: String,
val brandTitle: String,
val engTitle: String,
val price: String,
val transactionCount: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.sopt.kream.domain.model

data class RecommendJustDroppedProductModel(
val thumbnailUrl: String,
val brandTitle: String,
val engTitle: String,
val price: String,
val transactionCount: String,
val isScrap: Boolean,
val isFast: Boolean,
val isFreeDeliver: Boolean,
val isSave: Boolean,
val isCoupon: Boolean,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.sopt.kream.domain.model

data class RecommendProductModel(
val recommendForYouProducts: List<RecommendForYouProductModel>,
val recommendJustDroppedProducts: List<RecommendJustDroppedProductModel>,
)
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package org.sopt.kream.domain.repository

import org.sopt.kream.domain.model.ProductDetailModel
import org.sopt.kream.domain.model.RecommendProductModel
import org.sopt.kream.domain.model.SearchProductModel

interface ProductRepository {
suspend fun getSearchProduct(findName: String): Result<SearchProductModel>

suspend fun getProductDetail(productId: Int): Result<ProductDetailModel>

suspend fun getRecommendProduct(memberId: Int): Result<RecommendProductModel>
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import org.sopt.kream.data.datasourceimpl.ProductRemoteDataSourceImpl
import org.sopt.kream.data.repository.DummyRepositoryImpl
import org.sopt.kream.data.repository.ProductRepositoryImpl
import org.sopt.kream.presentation.ui.dummy.DummyViewModel
import org.sopt.kream.presentation.ui.main.home.recommend.RecommendViewModel
import org.sopt.kream.presentation.ui.productdetail.ProductDetailViewModel
import org.sopt.kream.presentation.ui.search.SearchViewModel

Expand All @@ -18,6 +19,8 @@ class ViewModelFactory : ViewModelProvider.Factory {
return SearchViewModel(ProductRepositoryImpl(ProductRemoteDataSourceImpl())) as T
} else if (modelClass.isAssignableFrom(ProductDetailViewModel::class.java)) {
return ProductDetailViewModel(ProductRepositoryImpl(ProductRemoteDataSourceImpl())) as T
} else if (modelClass.isAssignableFrom(RecommendViewModel::class.java)) {
return RecommendViewModel(ProductRepositoryImpl(ProductRemoteDataSourceImpl())) as T
}
throw IllegalArgumentException("Unknown ViewModel Class")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.sopt.kream.presentation.model

import androidx.annotation.DrawableRes

data class InstagramModel(
@DrawableRes val image: Int,
val id: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.sopt.kream.presentation.ui.main.home.recommend

import androidx.recyclerview.widget.RecyclerView
import org.sopt.kream.databinding.ItemRecommendAdvertisementBinding

class RecommendAdvertisementViewHolder(
private val binding: ItemRecommendAdvertisementBinding,
) : RecyclerView.ViewHolder(binding.root) {
fun onBind(
item: Int,
) {
with(binding) {
ivRecommendAdvertisement.setImageResource(item)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.sopt.kream.presentation.ui.main.home.recommend

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import org.sopt.kream.databinding.ItemRecommendAdvertisementBinding

class RecommendAdvertisementViewPagerAdapter(private val data: List<Int>) : RecyclerView.Adapter<RecommendAdvertisementViewHolder>() {
private val item = data

override fun getItemCount(): Int = item.size

override fun onBindViewHolder(
holder: RecommendAdvertisementViewHolder,
position: Int,
) {
holder.onBind(item[position])
}

override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int,
): RecommendAdvertisementViewHolder {
val binding = ItemRecommendAdvertisementBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return RecommendAdvertisementViewHolder(binding)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.sopt.kream.presentation.ui.main.home.recommend

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import org.sopt.kream.databinding.ItemRecommendCircleMenuBinding
import org.sopt.kream.presentation.ui.type.RecommendCircleMenuType
import kotlin.enums.EnumEntries

class RecommendCircleMenuAdapter(private val list: EnumEntries<RecommendCircleMenuType>) : RecyclerView.Adapter<RecommendCircleMenuViewHolder>() {
private val item = list

override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int,
): RecommendCircleMenuViewHolder {
val binding = ItemRecommendCircleMenuBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return RecommendCircleMenuViewHolder(binding)
}

override fun onBindViewHolder(
holder: RecommendCircleMenuViewHolder,
position: Int,
) {
holder.onBind(item.get(position))
}

override fun getItemCount(): Int = list.size
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.sopt.kream.presentation.ui.main.home.recommend

import androidx.recyclerview.widget.RecyclerView
import org.sopt.kream.databinding.ItemRecommendCircleMenuBinding
import org.sopt.kream.presentation.ui.type.RecommendCircleMenuType

class RecommendCircleMenuViewHolder(
private val binding: ItemRecommendCircleMenuBinding,
) : RecyclerView.ViewHolder(binding.root) {
fun onBind(
item: RecommendCircleMenuType,
) {
with(binding) {
ivCircleMenu.setImageResource(item.image)
tvCircleMenuTitle.setText(item.menu)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.sopt.kream.presentation.ui.main.home.recommend

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.ListAdapter
import org.sopt.kream.databinding.ItemRecommendForYouProductBinding
import org.sopt.kream.domain.model.RecommendForYouProductModel
import org.sopt.kream.util.view.ItemDiffCallback

class RecommendForYouAdapter(
private val navigateToProductDetail: (Int) -> Unit,
private val page: Int,
) : ListAdapter<
RecommendForYouProductModel,
RecommendForYouViewHolder,
>(
ItemDiffCallback<RecommendForYouProductModel>(
onContentsTheSame = { old, new -> old == new },
onItemsTheSame = { old, new -> old.engTitle == new.engTitle },
),
) {
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int,
): RecommendForYouViewHolder =
RecommendForYouViewHolder(
ItemRecommendForYouProductBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false,
),
navigateToProductDetail,
)

override fun onBindViewHolder(
holder: RecommendForYouViewHolder,
position: Int,
) {
holder.onBind(
recommendForYouProductModel = currentList[page * 6 + position],
position = position,
)
}
}
Loading

0 comments on commit 2c8b03b

Please sign in to comment.