Skip to content

Commit

Permalink
Merge pull request #93 from FakeDevelopers/feature/BDBD-520
Browse files Browse the repository at this point in the history
FEAT : BDBD-520 상품 상세 페이지 모듈화
  • Loading branch information
re4rk authored Feb 2, 2023
2 parents 8372877 + 8ff34b0 commit e8a00bd
Show file tree
Hide file tree
Showing 18 changed files with 113 additions and 139 deletions.
13 changes: 13 additions & 0 deletions data/src/main/java/com/fakedevelopers/data/di/MainModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ package com.fakedevelopers.data.di
import android.content.Context
import com.fakedevelopers.data.repository.ImageRepositoryImpl
import com.fakedevelopers.data.repository.LocalStorageRepositoryImpl
import com.fakedevelopers.data.repository.ProductDetailRepositoryImpl
import com.fakedevelopers.data.repository.ProductEditorRepositoryImpl
import com.fakedevelopers.data.repository.ProductListRepositoryImpl
import com.fakedevelopers.data.service.ProductDetailService
import com.fakedevelopers.data.service.ProductEditorService
import com.fakedevelopers.data.service.ProductListService
import com.fakedevelopers.data.source.LocalStorageDataSource
import com.fakedevelopers.domain.repository.ImageRepository
import com.fakedevelopers.domain.repository.LocalStorageRepository
import com.fakedevelopers.domain.repository.ProductDetailRepository
import com.fakedevelopers.domain.repository.ProductEditorRepository
import com.fakedevelopers.domain.repository.ProductListRepository
import dagger.Module
Expand Down Expand Up @@ -44,6 +47,16 @@ object MainModule {
fun provideProductEditorRepository(service: ProductEditorService): ProductEditorRepository =
ProductEditorRepositoryImpl(service)

@Singleton
@Provides
fun provideProductDetailService(@DataObject retrofit: Retrofit): ProductDetailService =
retrofit.create(ProductDetailService::class.java)

@Singleton
@Provides
fun provideProductDetailRepository(service: ProductDetailService): ProductDetailRepository =
ProductDetailRepositoryImpl(service)

@Singleton
@Provides
fun provideImageRepository(@ApplicationContext context: Context): ImageRepository =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.fakedevelopers.data.repository

import com.fakedevelopers.data.service.ProductDetailService
import com.fakedevelopers.domain.model.ProductDetailInfo
import com.fakedevelopers.domain.repository.ProductDetailRepository
import javax.inject.Inject

class ProductDetailRepositoryImpl @Inject constructor(
private val service: ProductDetailService
) : ProductDetailRepository {

override suspend fun getProductDetail(productId: Long): Result<ProductDetailInfo> =
runCatching {
service.getProductDetail(productId)
}

override suspend fun postProductBid(
productId: Long,
userId: Long,
bid: Long
): Result<String> =
runCatching {
service.postProductBid(productId, userId, bid)
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
package com.fakedevelopers.presentation.api.service
package com.fakedevelopers.data.service

import com.fakedevelopers.presentation.ui.productDetail.ProductDetailDto
import retrofit2.Response
import com.fakedevelopers.domain.model.ProductDetailInfo
import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Path

interface ProductDetailService {

@GET("product/getProductInfo/{productId}")
suspend fun getProductDetail(
@Path("productId") productId: Long
): Response<ProductDetailDto>
): ProductDetailInfo

@FormUrlEncoded
@POST("product/{productId}/bid")
suspend fun postProductBid(
@Path("productId") productId: Long,
@Field("userId") userId: Long,
@Field("bid") bid: Long
): Response<String>
): String
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.fakedevelopers.presentation.ui.productDetail
package com.fakedevelopers.domain.model

data class BidInfo(
val bid: Long,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.fakedevelopers.presentation.ui.productDetail
package com.fakedevelopers.domain.model

data class ProductDetailDto(
data class ProductDetailInfo(
val bidderCount: Int = 0,
val bids: List<BidInfo> = emptyList(),
val createdDate: String = "",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.fakedevelopers.domain.repository

import com.fakedevelopers.domain.model.ProductDetailInfo

interface ProductDetailRepository {
suspend fun getProductDetail(
productId: Long
): Result<ProductDetailInfo>

suspend fun postProductBid(
productId: Long,
userId: Long,
bid: Long
): Result<String>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.fakedevelopers.domain.usecase

import com.fakedevelopers.domain.repository.ProductDetailRepository
import javax.inject.Inject

class GetProductDetailUseCase @Inject constructor(
private val repository: ProductDetailRepository
) {
suspend operator fun invoke(productId: Long) = repository.getProductDetail(productId)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.fakedevelopers.domain.usecase

import com.fakedevelopers.domain.repository.ProductDetailRepository
import javax.inject.Inject

class PostProductBidUseCase @Inject constructor(
private val repository: ProductDetailRepository
) {
suspend operator fun invoke(productId: Long, userId: Long, bid: Long) = repository.postProductBid(productId, userId, bid)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.fakedevelopers.presentation.api.di

import com.fakedevelopers.domain.secret.Constants.Companion.BASE_URL
import com.fakedevelopers.presentation.api.util.LoginAuthInterceptor
import com.google.firebase.auth.FirebaseAuth
import com.google.gson.Gson
import com.google.gson.GsonBuilder
Expand All @@ -19,18 +18,10 @@ import java.util.Locale
import javax.inject.Qualifier
import javax.inject.Singleton

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class AuthOkHttpClient

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class NormalOkHttpClient

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class AuthRetrofit

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class NormalRetrofit
Expand All @@ -42,22 +33,6 @@ object ApiModule {
@Provides
fun provideBaseUrl() = BASE_URL

@Singleton
@Provides
@AuthOkHttpClient
fun provideAuthOkHttpClient(authInterceptor: LoginAuthInterceptor) = if (BuildConfig.DEBUG.not()) {
val loggingInterceptor = HttpLoggingInterceptor()
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS)
OkHttpClient.Builder()
.addInterceptor(authInterceptor)
.addInterceptor(loggingInterceptor)
.build()
} else {
OkHttpClient.Builder()
.addInterceptor(authInterceptor)
.build()
}

@Singleton
@Provides
@NormalOkHttpClient
Expand All @@ -75,18 +50,6 @@ object ApiModule {
@Provides
fun provideGson(): Gson = GsonBuilder().setLenient().create()

@Singleton
@Provides
@AuthRetrofit
fun provideAuthRetrofit(@AuthOkHttpClient okHttpClient: OkHttpClient, gson: Gson, baseUrl: String): Retrofit {
return Retrofit.Builder()
.client(okHttpClient)
.baseUrl(baseUrl)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
}

@Singleton
@Provides
@NormalRetrofit
Expand All @@ -107,8 +70,4 @@ object ApiModule {
setLanguageCode(Locale.getDefault().language)
}
}

@Singleton
@Provides
fun provideAuthInterceptor(auth: FirebaseAuth) = LoginAuthInterceptor(auth)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ package com.fakedevelopers.presentation.api.di

import com.fakedevelopers.presentation.api.repository.ChatRepository
import com.fakedevelopers.presentation.api.repository.ProductCategoryRepository
import com.fakedevelopers.presentation.api.repository.ProductDetailRepository
import com.fakedevelopers.presentation.api.repository.ProductSearchRepository
import com.fakedevelopers.presentation.api.service.ChatService
import com.fakedevelopers.presentation.api.service.ProductCategoryService
import com.fakedevelopers.presentation.api.service.ProductDetailService
import com.fakedevelopers.presentation.api.service.ProductSearchService
import dagger.Module
import dagger.Provides
Expand All @@ -29,17 +27,6 @@ class MainModule {
fun provideProductCategoryRepository(service: ProductCategoryService): ProductCategoryRepository =
ProductCategoryRepository(service)

// 상품 상세 정보, 입찰
@ActivityRetainedScoped
@Provides
fun provideProductDetailService(@NormalRetrofit retrofit: Retrofit): ProductDetailService =
retrofit.create(ProductDetailService::class.java)

@ActivityRetainedScoped
@Provides
fun provideProductDetailRepository(service: ProductDetailService): ProductDetailRepository =
ProductDetailRepository(service)

// 스트림 유저 토큰
@ActivityRetainedScoped
@Provides
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.fakedevelopers.domain.model.BidInfo
import com.fakedevelopers.domain.secret.Constants.Companion.dec
import com.fakedevelopers.presentation.R
import com.fakedevelopers.presentation.databinding.RecyclerBidInfoBinding
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import androidx.viewpager2.widget.ViewPager2
import com.fakedevelopers.domain.model.ProductDetailInfo
import com.fakedevelopers.presentation.R
import com.fakedevelopers.presentation.databinding.FragmentProductDetailBinding
import com.fakedevelopers.presentation.model.RemainTime
Expand Down Expand Up @@ -72,14 +73,14 @@ class ProductDetailFragment : BaseFragment<FragmentProductDetailBinding>(
findNavController().popBackStack()
}
binding.toolbarProductDetail.buttonToolbarOption.setOnClickListener {
navigateEditProduct(viewModel.productDetailDto.value)
navigateEditProduct(viewModel.productDetailInfo.value)
}
}

private fun navigateEditProduct(productDetailDto: ProductDetailDto) {
private fun navigateEditProduct(productDetailInfo: ProductDetailInfo) {
findNavController().navigate(
ProductDetailFragmentDirections.actionProductDetailFragmentToProductModificationFragment(
ProductEditorDto(viewModel.productId, productDetailDto),
ProductEditorDto(viewModel.productId, productDetailInfo),
viewModel.productId
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ package com.fakedevelopers.presentation.ui.productDetail

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.fakedevelopers.presentation.api.repository.ProductDetailRepository
import com.fakedevelopers.domain.model.ProductDetailInfo
import com.fakedevelopers.domain.usecase.GetProductDetailUseCase
import com.fakedevelopers.presentation.model.RemainTime
import com.fakedevelopers.presentation.ui.util.ApiErrorHandler
import com.fakedevelopers.presentation.ui.util.DateUtil
import com.fakedevelopers.presentation.ui.util.ExpirationTimerTask
import com.fakedevelopers.presentation.ui.util.MutableEventFlow
import com.fakedevelopers.presentation.ui.util.asEventFlow
import dagger.hilt.android.lifecycle.HiltViewModel
import io.getstream.logging.helper.stringify
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
Expand All @@ -18,11 +20,11 @@ import javax.inject.Inject
@HiltViewModel
class ProductDetailViewModel @Inject constructor(
private val dateUtil: DateUtil,
private val repository: ProductDetailRepository
private val getProductDetailUseCase: GetProductDetailUseCase
) : ViewModel() {

private val _productDetailDto = MutableStateFlow(ProductDetailDto())
val productDetailDto: StateFlow<ProductDetailDto> get() = _productDetailDto
private val _productDetailInfo = MutableStateFlow(ProductDetailInfo())
val productDetailInfo: StateFlow<ProductDetailInfo> get() = _productDetailInfo

private val _eventFlow = MutableEventFlow<Event>()
val eventFlow = _eventFlow.asEventFlow()
Expand All @@ -38,10 +40,10 @@ class ProductDetailViewModel @Inject constructor(
fun productDetailRequest(productId: Long) {
this.productId = productId
viewModelScope.launch {
val result = repository.getProductDetail(productId)
if (result.isSuccessful) {
val detail = result.body() ?: ProductDetailDto()
_productDetailDto.emit(detail)
val result = getProductDetailUseCase(productId)
if (result.isSuccess) {
val detail = result.getOrDefault(ProductDetailInfo())
_productDetailInfo.emit(detail)
if (detail.images.isEmpty()) {
event(Event.ProductImages(listOf("")))
} else {
Expand All @@ -51,7 +53,7 @@ class ProductDetailViewModel @Inject constructor(
startTimerTask(detail.expirationDate)
bidInfoAdapter.submitList(detail.bids)
} else {
ApiErrorHandler.printErrorMessage(result.errorBody())
ApiErrorHandler.printMessage(result.exceptionOrNull()?.stringify().toString())
}
}
}
Expand Down
Loading

0 comments on commit e8a00bd

Please sign in to comment.