Skip to content

Commit

Permalink
Merge pull request #304 from team-peekabook/feature/#298-duplicate-book
Browse files Browse the repository at this point in the history
#298 [feat] 중복 책 등록
  • Loading branch information
2zerozu authored Mar 3, 2024
2 parents 0502928 + 36c3d1b commit a668104
Show file tree
Hide file tree
Showing 23 changed files with 184 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.sopt.peekabookaos.data.entity.request

import kotlinx.serialization.Serializable

@Serializable
data class BookDuplicateRequest(
val bookTitle: String,
val author: String,
val publisher: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ package com.sopt.peekabookaos.data.entity.request
import kotlinx.serialization.Serializable

@Serializable
data class DuplicateRequest(
data class NicknameDuplicateRequest(
val nickname: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.sopt.peekabookaos.data.entity.response

import kotlinx.serialization.Serializable

@Serializable
data class BookDuplicateResponse(
val isDuplicate: Boolean
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ package com.sopt.peekabookaos.data.entity.response
import kotlinx.serialization.Serializable

@Serializable
data class DuplicateResponse(
data class NicknameDuplicateResponse(
val check: Int
)
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,14 @@ class BookRepositoryImpl @Inject constructor(
description: String?,
memo: String?
): Result<Unit> = kotlin.runCatching { bookDataSource.patchEditBook(bookId, description, memo) }

override suspend fun postBookDuplicate(
bookTitle: String,
author: String,
publisher: String
): Result<Boolean> =
kotlin.runCatching { bookDataSource.postBookDuplicate(bookTitle, author, publisher) }
.map { response ->
requireNotNull(response.data).isDuplicate
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import javax.inject.Inject
class UserInputRepositoryImpl @Inject constructor(
private val userInputDataSource: UserInputDataSource
) : UserInputRepository {
override suspend fun postDuplicate(
override suspend fun postNicknameDuplicate(
nickname: String
): Result<Int> =
kotlin.runCatching {
userInputDataSource.postDuplicate(
userInputDataSource.postNicknameDuplicate(
nickname
)
}.map { response -> requireNotNull(response.data).check }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package com.sopt.peekabookaos.data.service

import com.sopt.peekabookaos.data.entity.BaseResponse
import com.sopt.peekabookaos.data.entity.NoResponse
import com.sopt.peekabookaos.data.entity.request.BookDuplicateRequest
import com.sopt.peekabookaos.data.entity.request.CreateBookRequest
import com.sopt.peekabookaos.data.entity.request.EditBookRequest
import com.sopt.peekabookaos.data.entity.response.BookDuplicateResponse
import com.sopt.peekabookaos.data.entity.response.CreateBookResponse
import retrofit2.http.Body
import retrofit2.http.PATCH
Expand All @@ -21,4 +23,9 @@ interface BookService {
@Path("bookshelfId") bookId: Int,
@Body bookComment: EditBookRequest
): NoResponse

@POST("/bookshelf/duplicate")
suspend fun postBookDuplicate(
@Body bookDuplicateRequest: BookDuplicateRequest
): BaseResponse<BookDuplicateResponse>
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package com.sopt.peekabookaos.data.service

import com.sopt.peekabookaos.data.entity.BaseResponse
import com.sopt.peekabookaos.data.entity.NoResponse
import com.sopt.peekabookaos.data.entity.request.DuplicateRequest
import com.sopt.peekabookaos.data.entity.response.DuplicateResponse
import com.sopt.peekabookaos.data.entity.request.NicknameDuplicateRequest
import com.sopt.peekabookaos.data.entity.response.NicknameDuplicateResponse
import okhttp3.MultipartBody
import okhttp3.RequestBody
import retrofit2.http.Body
Expand All @@ -15,7 +15,7 @@ import retrofit2.http.PartMap

interface UserInputService {
@POST("user/duplicate")
suspend fun postDuplicate(@Body body: DuplicateRequest): BaseResponse<DuplicateResponse>
suspend fun postDuplicate(@Body body: NicknameDuplicateRequest): BaseResponse<NicknameDuplicateResponse>

@Multipart
@PATCH("auth/signup")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package com.sopt.peekabookaos.data.source.remote

import com.sopt.peekabookaos.data.entity.BaseResponse
import com.sopt.peekabookaos.data.entity.NoResponse
import com.sopt.peekabookaos.data.entity.request.BookDuplicateRequest
import com.sopt.peekabookaos.data.entity.request.CreateBookRequest
import com.sopt.peekabookaos.data.entity.request.EditBookRequest
import com.sopt.peekabookaos.data.entity.response.BookDuplicateResponse
import com.sopt.peekabookaos.data.entity.response.CreateBookResponse
import com.sopt.peekabookaos.data.service.BookService
import javax.inject.Inject
Expand Down Expand Up @@ -31,4 +33,12 @@ data class BookDataSource @Inject constructor(

suspend fun patchEditBook(bookId: Int, description: String?, memo: String?): NoResponse =
bookService.patchEditBook(bookId, EditBookRequest(description, memo))

suspend fun postBookDuplicate(
bookTitle: String,
author: String,
publisher: String
): BaseResponse<BookDuplicateResponse> = bookService.postBookDuplicate(
BookDuplicateRequest(bookTitle = bookTitle, author = author, publisher = publisher)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package com.sopt.peekabookaos.data.source.remote

import com.sopt.peekabookaos.data.entity.BaseResponse
import com.sopt.peekabookaos.data.entity.NoResponse
import com.sopt.peekabookaos.data.entity.request.DuplicateRequest
import com.sopt.peekabookaos.data.entity.response.DuplicateResponse
import com.sopt.peekabookaos.data.entity.request.NicknameDuplicateRequest
import com.sopt.peekabookaos.data.entity.response.NicknameDuplicateResponse
import com.sopt.peekabookaos.data.service.UserInputService
import okhttp3.MultipartBody
import okhttp3.RequestBody
Expand All @@ -12,10 +12,10 @@ import javax.inject.Inject
data class UserInputDataSource @Inject constructor(
private val userInputService: UserInputService
) {
suspend fun postDuplicate(
suspend fun postNicknameDuplicate(
nickname: String
): BaseResponse<DuplicateResponse> = userInputService.postDuplicate(
DuplicateRequest(
): BaseResponse<NicknameDuplicateResponse> = userInputService.postDuplicate(
NicknameDuplicateRequest(
nickname = nickname
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,10 @@ interface BookRepository {
): Result<Int>

suspend fun patchEditBook(bookId: Int, description: String?, memo: String?): Result<Unit>

suspend fun postBookDuplicate(
bookTitle: String,
author: String,
publisher: String
): Result<Boolean>
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import okhttp3.MultipartBody
import okhttp3.RequestBody

interface UserInputRepository {
suspend fun postDuplicate(
suspend fun postNicknameDuplicate(
nickname: String
): Result<Int>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.sopt.peekabookaos.domain.usecase

import com.sopt.peekabookaos.domain.repository.BookRepository
import javax.inject.Inject

class PostBookDuplicateUseCase @Inject constructor(
private val bookRepository: BookRepository
) {
suspend operator fun invoke(
bookTitle: String,
author: String,
publisher: String,
) = bookRepository.postBookDuplicate(bookTitle, author, publisher)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ package com.sopt.peekabookaos.domain.usecase
import com.sopt.peekabookaos.domain.repository.UserInputRepository
import javax.inject.Inject

class PostDuplicateUseCase @Inject constructor(
class PostNicknameDuplicateUseCase @Inject constructor(
private val userInputRepository: UserInputRepository
) {
suspend operator fun invoke(nickname: String) = userInputRepository.postDuplicate(nickname)
suspend operator fun invoke(nickname: String) =
userInputRepository.postNicknameDuplicate(nickname)
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ import com.sopt.peekabookaos.presentation.detail.DetailActivity
import com.sopt.peekabookaos.util.KeyBoardUtil
import com.sopt.peekabookaos.util.UiEvent
import com.sopt.peekabookaos.util.binding.BindingFragment
import com.sopt.peekabookaos.util.dialog.ConfirmClickListener
import com.sopt.peekabookaos.util.dialog.WarningDialogFragment
import com.sopt.peekabookaos.util.dialog.WarningType
import com.sopt.peekabookaos.util.extensions.getParcelableCompat
import com.sopt.peekabookaos.util.extensions.repeatOnStarted
import com.sopt.peekabookaos.util.extensions.withArgs
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
Expand All @@ -30,11 +34,38 @@ class CreateBookFragment :
super.onViewCreated(view, savedInstanceState)
binding.vm = createBookViewModel
initBookInfo()
checkBookDuplicate()
collectBookDuplicate()
initEditTextClearFocus()
initBackBtnOnClickListener()
collectUiEvent()
}

private fun checkBookDuplicate() = createBookViewModel.postBookDuplicate()

private fun collectBookDuplicate() {
repeatOnStarted {
createBookViewModel.isBookDuplicated.collect { isDuplicated ->
if (isDuplicated) {
showBookDuplicateDialog()
}
}
}
}

private fun showBookDuplicateDialog() {
WarningDialogFragment().withArgs {
putSerializable(
WarningDialogFragment.WARNING_TYPE,
WarningType.WARNING_BOOK_DUPLICATE
)
putParcelable(
WarningDialogFragment.CONFIRM_ACTION,
ConfirmClickListener(confirmAction = { requireActivity().finish() })
)
}.show(childFragmentManager, WarningDialogFragment.DIALOG_WARNING)
}

@SuppressLint("ClickableViewAccessibility")
private fun initEditTextClearFocus() {
binding.clCreateBook.setOnTouchListener { _, _ ->
Expand Down Expand Up @@ -65,6 +96,7 @@ class CreateBookFragment :
UiEvent.IDLE -> {
binding.btnCreateBookSave.isEnabled = false
}

UiEvent.SUCCESS -> {
startActivity(
Intent(requireActivity(), DetailActivity::class.java).apply {
Expand All @@ -74,6 +106,7 @@ class CreateBookFragment :
)
requireActivity().finish()
}

UiEvent.ERROR -> {
binding.btnCreateBookSave.isEnabled = true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.sopt.peekabookaos.presentation.createBook
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sopt.peekabookaos.domain.entity.Book
import com.sopt.peekabookaos.domain.usecase.PostBookDuplicateUseCase
import com.sopt.peekabookaos.domain.usecase.PostCreateBookUseCase
import com.sopt.peekabookaos.util.UiEvent
import dagger.hilt.android.lifecycle.HiltViewModel
Expand All @@ -16,14 +17,18 @@ import javax.inject.Inject

@HiltViewModel
class CreateBookViewModel @Inject constructor(
private val postCreateBookUseCase: PostCreateBookUseCase
private val postCreateBookUseCase: PostCreateBookUseCase,
private val postBookDuplicateUseCase: PostBookDuplicateUseCase
) : ViewModel() {
private val _bookInfo = MutableStateFlow(Book())
val bookInfo = _bookInfo.asStateFlow()

private val _uiEvent = MutableSharedFlow<UiEvent>()
val uiEvent = _uiEvent.asSharedFlow()

private val _isBookDuplicated = MutableSharedFlow<Boolean>()
val isBookDuplicated = _isBookDuplicated.asSharedFlow()

val comment = MutableStateFlow("")

val memo = MutableStateFlow("")
Expand Down Expand Up @@ -51,4 +56,18 @@ class CreateBookViewModel @Inject constructor(
fun initBookInfo(bookInfo: Book) {
_bookInfo.value = bookInfo
}

fun postBookDuplicate() {
viewModelScope.launch {
postBookDuplicateUseCase(
bookTitle = _bookInfo.value.bookTitle,
author = _bookInfo.value.author,
publisher = _bookInfo.value.publisher
).onSuccess { isDuplicated ->
_isBookDuplicated.emit(isDuplicated)
}.onFailure { throwable ->
Timber.e("$throwable")
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sopt.peekabookaos.domain.entity.User
import com.sopt.peekabookaos.domain.usecase.PatchProfileModifyUseCase
import com.sopt.peekabookaos.domain.usecase.PostDuplicateUseCase
import com.sopt.peekabookaos.domain.usecase.PostNicknameDuplicateUseCase
import com.sopt.peekabookaos.util.ContentUriRequestBody
import com.sopt.peekabookaos.util.ImageUtil
import dagger.hilt.android.lifecycle.HiltViewModel
Expand All @@ -24,7 +24,7 @@ import javax.inject.Inject
@HiltViewModel
class ProfileModifyViewModel @Inject constructor(
private val application: Application,
private val postDuplicateUseCase: PostDuplicateUseCase,
private val postNicknameDuplicateUseCase: PostNicknameDuplicateUseCase,
private val patchProfileModifyUseCase: PatchProfileModifyUseCase
) : ViewModel() {
private val _isNicknameInUse: MutableLiveData<Boolean> = MutableLiveData(true)
Expand Down Expand Up @@ -72,7 +72,7 @@ class ProfileModifyViewModel @Inject constructor(

fun getNickNameState() {
viewModelScope.launch {
postDuplicateUseCase(requireNotNull(nickname.value))
postNicknameDuplicateUseCase(requireNotNull(nickname.value))
.onSuccess { check ->
_isNicknameInUse.value = (check == 1)
updateNicknameMessage(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sopt.peekabookaos.domain.usecase.PatchSignUpUseCase
import com.sopt.peekabookaos.domain.usecase.PostDuplicateUseCase
import com.sopt.peekabookaos.domain.usecase.PostNicknameDuplicateUseCase
import com.sopt.peekabookaos.util.ContentUriRequestBody
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
Expand All @@ -22,7 +22,7 @@ import javax.inject.Inject
@HiltViewModel
class UserInputViewModel @Inject constructor(
private val application: Application,
private val postDuplicateUseCase: PostDuplicateUseCase,
private val postNicknameDuplicateUseCase: PostNicknameDuplicateUseCase,
private val patchSignUpUseCase: PatchSignUpUseCase
) : ViewModel() {
private val _isNickname: MutableLiveData<Boolean> = MutableLiveData(true)
Expand Down Expand Up @@ -68,7 +68,7 @@ class UserInputViewModel @Inject constructor(

fun getNickNameState() {
viewModelScope.launch {
postDuplicateUseCase(requireNotNull(nickname.value))
postNicknameDuplicateUseCase(requireNotNull(nickname.value))
.onSuccess { check ->
_isNickname.value = (check == 1)
updateNicknameMessage(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,18 @@ data class WarningDialogContent(
cancel = context.getString(R.string.warning_dialog_cancel),
confirm = context.getString(R.string.warning_dialog_delete)
)

fun getWarningUnfollow(context: Context, follower: String): WarningDialogContent =
WarningDialogContent(
title = context.getString(R.string.warning_dialog_unfollow_title, follower),
cancel = context.getString(R.string.warning_dialog_cancel),
confirm = context.getString(R.string.warning_dialog_unfollow)
)

fun getWarningDuplicateBook(context: Context): WarningDialogContent =
WarningDialogContent(
title = context.getString(R.string.warning_dialog_duplicate_book),
cancel = context.getString(R.string.warning_dialog_cancel),
confirm = context.getString(R.string.warning_dialog_add)
)
}
Loading

0 comments on commit a668104

Please sign in to comment.