Skip to content

Commit

Permalink
#91 댓글 전송 시 로직을 BindingAdapter로 통합해 제작, 댓글 등록/수정/좋아요/삭제 비즈니스 로직 교체,
Browse files Browse the repository at this point in the history
  • Loading branch information
pknujsp committed May 31, 2023
1 parent 5531eed commit d8517f0
Show file tree
Hide file tree
Showing 44 changed files with 870 additions and 513 deletions.
21 changes: 20 additions & 1 deletion app/src/main/java/com/android/mediproject/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ package com.android.mediproject
import android.animation.ObjectAnimator
import android.os.Build
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import android.view.animation.AnticipateInterpolator
import androidx.activity.viewModels
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.animation.doOnEnd
import androidx.core.net.toUri
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.setupWithNavController
import com.android.mediproject.core.ui.WindowViewModel
import com.android.mediproject.core.ui.base.BaseActivity
import com.android.mediproject.databinding.ActivityMainBinding
import dagger.hilt.android.AndroidEntryPoint
Expand All @@ -21,6 +24,8 @@ import repeatOnStarted
class MainActivity :
BaseActivity<ActivityMainBinding, MainViewModel>(ActivityMainBinding::inflate) {

private val windowViewModel: WindowViewModel by viewModels()

companion object {
const val VISIBLE = 0
const val INVISIBLE = 1
Expand Down Expand Up @@ -60,10 +65,24 @@ class MainActivity :
viewModel = activityViewModel.apply {
repeatOnStarted { eventFlow.collect { handleEvent(it) } }
}

root.viewTreeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener {
override fun onPreDraw(): Boolean {
if (bottomAppBar.height > 0) {
root.viewTreeObserver.removeOnPreDrawListener(this)
val containerHeight = root.height - bottomAppBar.height
windowViewModel.setBottomNavHeight(containerHeight)
fragmentContainerView.layoutParams = CoordinatorLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, containerHeight
)
}
return true
}
})
}
}

override fun setSplash(){
override fun setSplash() {
installSplashScreen()
}

Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
</data>

<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/mainLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.android.mediproject.core.common.bindingadapter

import android.graphics.Bitmap
import android.text.Spanned
import android.view.View
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import androidx.core.text.PrecomputedTextCompat
Expand All @@ -26,22 +28,45 @@ object BindingAdapter {
@BindingAdapter("img")
@JvmStatic
fun loadImage(imageView: ImageView, img: String) {
GlideApp.with(imageView.context).load(img).centerInside().skipMemoryCache(false).into(imageView)
GlideApp.with(imageView.context).load(img).centerInside().skipMemoryCache(false)
.into(imageView)
}

@BindingAdapter("img")
@JvmStatic
fun loadImage(imageView: ImageView, img: Bitmap) {
GlideApp.with(imageView.context).load(img).centerInside().skipMemoryCache(false).into(imageView)
GlideApp.with(imageView.context).load(img).centerInside().skipMemoryCache(false)
.into(imageView)
}


/**
* TextView에 비동기적으로 텍스트를 설정합니다.
*/
@BindingAdapter("asyncText")
@JvmStatic
fun setAsyncText(textView: TextView, text: Spanned?) {
if (text != null) {
val precomputedText = PrecomputedTextCompat.create(text, TextViewCompat.getTextMetricsParams(textView))
val precomputedText =
PrecomputedTextCompat.create(text, TextViewCompat.getTextMetricsParams(textView))
TextViewCompat.setPrecomputedText(textView, precomputedText)
}
}

/**
* EditText의 텍스트를 전달받은 ViewModel의 onClickedSendButton 함수에 전달하고, EditText의 텍스트를 지웁니다.
*
* @param view 클릭 이벤트를 받을 View
* @param editText 텍스트를 전달받을 EditText
* @param iSendText 텍스트를 전달받을 ViewModel
*/
@BindingAdapter("onClickSend", "inputText")
@JvmStatic
fun setOnClick(view: View, iSendText: ISendText, editText: EditText) {
view.setOnClickListener {
iSendText.onClickedSendButton(editText.text)
editText.text.clear()
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.android.mediproject.core.common.bindingadapter

interface ISendText {
fun onClickedSendButton(text: CharSequence)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,21 @@ import com.google.android.material.progressindicator.CircularProgressIndicator
* @param emptyMsg 로딩 상태가 아닐 때 보여줄 메시지
*/
fun PagingDataAdapter<*, *>.setOnStateChangedListener(
msgTextView: TextView, listView: RecyclerView, progressBar: CircularProgressIndicator, emptyMsg: String
msgTextView: TextView,
listView: RecyclerView,
progressBar: CircularProgressIndicator,
emptyMsg: String
) {
var isFirstLoad = true
addLoadStateListener { loadState ->
isFirstLoad = loadState.refresh is LoadState.Loading
if (isFirstLoad) listView.scrollToPosition(0)

msgTextView.text = emptyMsg

progressBar.isVisible = isFirstLoad
listView.isVisible = (!isFirstLoad && loadState.source.refresh !is LoadState.Loading)
msgTextView.isVisible = !isFirstLoad && loadState.source.refresh !is LoadState.Loading && itemCount == 0
listView.isVisible = (!isFirstLoad && (loadState.source.refresh !is LoadState.Loading))
msgTextView.isVisible =
((!isFirstLoad && loadState.source.refresh !is LoadState.Loading) && itemCount == 0)
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,40 @@
package com.android.mediproject.core.data.remote.comments

import androidx.paging.PagingData
import com.android.mediproject.core.model.comments.EditedCommentDto
import com.android.mediproject.core.model.comments.MyCommentDto
import com.android.mediproject.core.model.comments.NewCommentDto
import com.android.mediproject.core.model.remote.comments.MedicineCommentsResponse
import kotlinx.coroutines.flow.Flow

interface CommentsRepository {
suspend fun getCommentsForAMedicine(
fun getCommentsForAMedicine(
itemSeq: String,
): Flow<PagingData<MedicineCommentsResponse>>

/**
* 내가 작성한 댓글을 가져오는 메서드입니다.
*/
fun getMyComments(userId: Int): Flow<PagingData<MyCommentDto>>

/**
* 댓글을 수정합니다.
*/
fun applyEditedComment(editedCommentDto: EditedCommentDto): Flow<Result<Unit>>


/**
* 댓글을 등록합니다.
*/
fun applyNewComment(newCommentDto: NewCommentDto): Flow<Result<Unit>>

/**
* 댓글 삭제 클릭
*/
fun deleteComment(commentId: Int): Flow<Result<Unit>>

/**
* 댓글 좋아요 클릭
*/
fun likeComment(commentId: Int): Flow<Result<Unit>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import com.android.mediproject.core.common.AWS_LOAD_PAGE_SIZE
import com.android.mediproject.core.model.comments.EditedCommentDto
import com.android.mediproject.core.model.comments.MyCommentDto
import com.android.mediproject.core.model.comments.NewCommentDto
import com.android.mediproject.core.model.remote.comments.MedicineCommentsResponse
import com.android.mediproject.core.network.datasource.comments.CommentsDataSource
import com.android.mediproject.core.network.datasource.comments.CommentsListDataSourceImpl
Expand All @@ -13,12 +16,23 @@ import javax.inject.Inject
class CommentsRepositoryImpl @Inject constructor(
private val commentsDataSource: CommentsDataSource
) : CommentsRepository {
override suspend fun getCommentsForAMedicine(itemSeq: String): Flow<PagingData<MedicineCommentsResponse>> =
override fun getCommentsForAMedicine(itemSeq: String): Flow<PagingData<MedicineCommentsResponse>> =
Pager(config = PagingConfig(pageSize = AWS_LOAD_PAGE_SIZE, prefetchDistance = 5), pagingSourceFactory = {
CommentsListDataSourceImpl(
commentsDataSource, itemSeq
)
CommentsListDataSourceImpl(commentsDataSource, itemSeq)
}).flow

override fun getMyComments(userId: Int): Flow<PagingData<MyCommentDto>> {
TODO("Not yet implemented")
}

override fun applyEditedComment(editedCommentDto: EditedCommentDto): Flow<Result<Unit>> =
commentsDataSource.applyEditedComment(editedCommentDto)

override fun applyNewComment(newCommentDto: NewCommentDto): Flow<Result<Unit>> = commentsDataSource.applyNewComment(newCommentDto)

override fun deleteComment(commentId: Int): Flow<Result<Unit>> = commentsDataSource.deleteComment(commentId)

override fun likeComment(commentId: Int): Flow<Result<Unit>> = commentsDataSource.likeComment(commentId)


}
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import com.android.mediproject.core.model.remote.recall.RecallSuspensionListResp
import kotlinx.coroutines.flow.Flow

interface RecallSuspensionRepository {
suspend fun getRecallDisposalList(
fun getRecallDisposalList(
): Flow<PagingData<RecallSuspensionListResponse.Body.Item.Item>>

suspend fun getRecentRecallDisposalList(
pageNo: Int = 1, numOfRows: Int = 15
): Result<List<RecallSuspensionListResponse.Body.Item.Item>>

suspend fun getDetailRecallSuspension(
fun getDetailRecallSuspension(
company: String?, product: String?
): Flow<Result<DetailRecallSuspensionResponse.Body.Item.Item>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,33 @@ class RecallSuspensionRepositoryImpl @Inject constructor(
private val recallSuspensionListDataSource: RecallSuspensionListDataSourceImpl,
) : RecallSuspensionRepository {

override suspend fun getRecallDisposalList(): Flow<PagingData<RecallSuspensionListResponse.Body.Item.Item>> =
override fun getRecallDisposalList(): Flow<PagingData<RecallSuspensionListResponse.Body.Item.Item>> =
Pager(config = PagingConfig(pageSize = DATA_GO_KR_PAGE_SIZE), pagingSourceFactory = {
recallSuspensionListDataSource
}).flow

override suspend fun getRecentRecallDisposalList(
pageNo: Int, numOfRows: Int
): Result<List<RecallSuspensionListResponse.Body.Item.Item>> = recallSuspensionDataSource.getRecallSuspensionList(
pageNo, numOfRows
).map {
it.body.items.map { item ->
item.item
): Result<List<RecallSuspensionListResponse.Body.Item.Item>> =
recallSuspensionDataSource.getRecallSuspensionList(
pageNo, numOfRows
).map {
it.body.items.map { item ->
item.item
}
}
}

override suspend fun getDetailRecallSuspension(
override fun getDetailRecallSuspension(
company: String?, product: String?
): Flow<Result<DetailRecallSuspensionResponse.Body.Item.Item>> = recallSuspensionDataSource.getDetailRecallSuspensionInfo(
company = company, product = product
).map { result ->
result.fold(onSuccess = {
Result.success(it.body.items.first().item)
}, onFailure = {
Result.failure(it)
})
}
): Flow<Result<DetailRecallSuspensionResponse.Body.Item.Item>> =
recallSuspensionDataSource.getDetailRecallSuspensionInfo(
company = company, product = product
).map { result ->
result.fold(onSuccess = {
Result.success(it.body.items.first().item)
}, onFailure = {
Result.failure(it)
})
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.android.mediproject.core.domain

import androidx.paging.PagingData
import androidx.paging.map
import com.android.mediproject.core.data.remote.comments.CommentsRepository
import com.android.mediproject.core.model.comments.CommentDto
import com.android.mediproject.core.model.comments.EditedCommentDto
import com.android.mediproject.core.model.comments.MyCommentDto
import com.android.mediproject.core.model.comments.NewCommentDto
import com.android.mediproject.core.model.comments.toDto
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import javax.inject.Inject

class CommentsUseCase @Inject constructor(
private val commentsRepository: CommentsRepository
) {

/**
* 약에 대한 댓글을 가져오는 메서드입니다.
*/
fun getCommentsForAMedicine(itemSeq: String): Flow<PagingData<CommentDto>> = commentsRepository.getCommentsForAMedicine(itemSeq).map {
it.map { response ->
response.toDto()
}
}

/**
* 내가 작성한 댓글을 가져오는 메서드입니다.
*/
fun getMyComments(userId: Int): Flow<PagingData<MyCommentDto>> {
TODO()
}


/**
* 댓글을 수정합니다.
*/
fun applyEditedComment(editedCommentDto: EditedCommentDto): Flow<Result<Unit>> = commentsRepository.applyEditedComment(editedCommentDto)


/**
* 댓글을 등록합니다.
*/
fun applyNewComment(newCommentDto: NewCommentDto): Flow<Result<Unit>> = commentsRepository.applyNewComment(newCommentDto)

/**
* 댓글 삭제 클릭
*/
fun deleteComment(commentId: Int): Flow<Result<Unit>> = commentsRepository.deleteComment(commentId)

/**
* 댓글 좋아요 클릭
*/
fun likeComment(commentId: Int): Flow<Result<Unit>> = commentsRepository.likeComment(commentId)
}
Loading

0 comments on commit d8517f0

Please sign in to comment.