Skip to content

Commit

Permalink
Merge branch 'develop' into feature/544-offering-detail-skeleton-ui
Browse files Browse the repository at this point in the history
  • Loading branch information
Namyunsuk committed Oct 21, 2024
2 parents 04624c6 + b805065 commit 9d3fc23
Show file tree
Hide file tree
Showing 15 changed files with 153 additions and 91 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.zzang.chongdae.presentation.util

import java.time.LocalDate
import java.time.LocalTime
import java.time.format.DateTimeFormatter
import java.util.Locale

fun LocalDate.toFormattedDate(): String {
return this.format(DateTimeFormatter.ofPattern("yyyy년 M월 d일"))
}

fun LocalTime.toFormattedTime(): String {
return this.format(DateTimeFormatter.ofPattern(("a h:mm"), Locale.KOREAN))
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class CommentDetailActivity : AppCompatActivity(), OnUpdateStatusClickListener {

private fun observeComments() {
viewModel.comments.observe(this) { comments ->
commentAdapter.submitComments(comments)
commentAdapter.submitList(comments)
binding.rvComments.doOnPreDraw {
binding.rvComments.scrollToPosition(comments.size - 1)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import com.zzang.chongdae.domain.repository.OfferingRepository
import com.zzang.chongdae.domain.repository.ParticipantRepository
import com.zzang.chongdae.presentation.util.Event
import com.zzang.chongdae.presentation.view.commentdetail.event.CommentDetailEvent
import com.zzang.chongdae.presentation.view.commentdetail.model.comment.CommentUiModel
import com.zzang.chongdae.presentation.view.commentdetail.model.comment.CommentUiModel.Companion.toUiModel
import com.zzang.chongdae.presentation.view.commentdetail.model.comment.CommentUiModel.Companion.toUiModelListWithSeparators
import com.zzang.chongdae.presentation.view.commentdetail.model.information.CommentOfferingInfoUiModel
import com.zzang.chongdae.presentation.view.commentdetail.model.information.CommentOfferingInfoUiModel.Companion.toUiModel
import com.zzang.chongdae.presentation.view.commentdetail.model.meeting.MeetingsUiModel
Expand Down Expand Up @@ -53,8 +56,8 @@ class CommentDetailViewModel

val commentContent = MutableLiveData("")

private val _comments: MutableLiveData<List<Comment>> = MutableLiveData()
val comments: LiveData<List<Comment>> get() = _comments
private val _comments: MutableLiveData<List<CommentUiModel>> = MutableLiveData()
val comments: LiveData<List<CommentUiModel>> get() = _comments
private var cachedComments: List<Comment> = emptyList()

private val _commentOfferingInfo = MutableLiveData<CommentOfferingInfoUiModel>()
Expand Down Expand Up @@ -144,15 +147,11 @@ class CommentDetailViewModel
is Result.Success -> {
val newComments = result.data
if (cachedComments != newComments) {
_comments.value = newComments
_comments.value = newComments.toUiModelListWithSeparators()
cachedComments = newComments
}
}

is Result.Error ->
handleNetworkError(result.error) {
loadComments()
}
is Result.Error -> handleNetworkError(result.error) { loadComments() }
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,48 +8,37 @@ import androidx.recyclerview.widget.RecyclerView
import com.zzang.chongdae.databinding.ItemDateSeparatorBinding
import com.zzang.chongdae.databinding.ItemMyCommentBinding
import com.zzang.chongdae.databinding.ItemOtherCommentBinding
import com.zzang.chongdae.domain.model.Comment

class CommentAdapter : ListAdapter<CommentViewType, RecyclerView.ViewHolder>(DIFF_CALLBACK) {
fun submitComments(comments: List<Comment>) {
val newItems = mutableListOf<CommentViewType>()

for (i in comments.indices) {
val currentComment = comments[i]
val previousComment = if (i > 0) comments[i - 1] else null

if (previousComment == null || isDifferentDates(currentComment, previousComment)) {
newItems.add(CommentViewType.DateSeparator(currentComment))
}

newItems.add(CommentViewType.fromComment(currentComment))
}

submitList(newItems)
}

private fun isDifferentDates(
currentComment: Comment,
previousComment: Comment,
) = currentComment.commentCreatedAt.date != previousComment.commentCreatedAt.date
import com.zzang.chongdae.presentation.view.commentdetail.model.comment.CommentUiModel

class CommentAdapter : ListAdapter<CommentUiModel, RecyclerView.ViewHolder>(DIFF_CALLBACK) {
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int,
): RecyclerView.ViewHolder {
return when (viewType) {
VIEW_TYPE_MY_COMMENT -> {
val binding = ItemMyCommentBinding.inflate(LayoutInflater.from(parent.context), parent, false)
val binding =
ItemMyCommentBinding.inflate(LayoutInflater.from(parent.context), parent, false)
MyCommentViewHolder(binding)
}

VIEW_TYPE_OTHER_COMMENT -> {
val binding = ItemOtherCommentBinding.inflate(LayoutInflater.from(parent.context), parent, false)
val binding =
ItemOtherCommentBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false,
)
OtherCommentViewHolder(binding)
}

VIEW_TYPE_DATE_SEPARATOR -> {
val binding = ItemDateSeparatorBinding.inflate(LayoutInflater.from(parent.context), parent, false)
val binding =
ItemDateSeparatorBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false,
)
DateSeparatorViewHolder(binding)
}

Expand All @@ -61,18 +50,18 @@ class CommentAdapter : ListAdapter<CommentViewType, RecyclerView.ViewHolder>(DIF
holder: RecyclerView.ViewHolder,
position: Int,
) {
when (val item = getItem(position)) {
is CommentViewType.MyComment -> (holder as MyCommentViewHolder).bind(item.comment)
is CommentViewType.OtherComment -> (holder as OtherCommentViewHolder).bind(item.comment)
is CommentViewType.DateSeparator -> (holder as DateSeparatorViewHolder).bind(item.comment)
when (holder) {
is MyCommentViewHolder -> holder.bind(getItem(position))
is OtherCommentViewHolder -> holder.bind(getItem(position))
is DateSeparatorViewHolder -> holder.bind(getItem(position))
}
}

override fun getItemViewType(position: Int): Int {
return when (getItem(position)) {
is CommentViewType.MyComment -> VIEW_TYPE_MY_COMMENT
is CommentViewType.OtherComment -> VIEW_TYPE_OTHER_COMMENT
is CommentViewType.DateSeparator -> VIEW_TYPE_DATE_SEPARATOR
return when (getItem(position).commentViewType) {
CommentViewType.MyComment -> VIEW_TYPE_MY_COMMENT
CommentViewType.OtherComment -> VIEW_TYPE_OTHER_COMMENT
CommentViewType.DateSeparator -> VIEW_TYPE_DATE_SEPARATOR
}
}

Expand All @@ -82,28 +71,18 @@ class CommentAdapter : ListAdapter<CommentViewType, RecyclerView.ViewHolder>(DIF
private const val VIEW_TYPE_DATE_SEPARATOR = 3

private val DIFF_CALLBACK =
object : DiffUtil.ItemCallback<CommentViewType>() {
object : DiffUtil.ItemCallback<CommentUiModel>() {
override fun areItemsTheSame(
oldItem: CommentViewType,
newItem: CommentViewType,
oldItem: CommentUiModel,
newItem: CommentUiModel,
): Boolean {
return when {
oldItem is CommentViewType.MyComment && newItem is CommentViewType.MyComment ->
oldItem.comment == newItem.comment

oldItem is CommentViewType.OtherComment && newItem is CommentViewType.OtherComment ->
oldItem.comment == newItem.comment

oldItem is CommentViewType.DateSeparator && newItem is CommentViewType.DateSeparator ->
oldItem.comment == newItem.comment

else -> false
}
return oldItem.commentViewType == newItem.commentViewType &&
oldItem.date == newItem.date && oldItem.time == newItem.time
}

override fun areContentsTheSame(
oldItem: CommentViewType,
newItem: CommentViewType,
oldItem: CommentUiModel,
newItem: CommentUiModel,
): Boolean {
return oldItem == newItem
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
package com.zzang.chongdae.presentation.view.commentdetail.adapter.comment

import com.zzang.chongdae.domain.model.Comment

sealed class CommentViewType {
data class MyComment(val comment: Comment) : CommentViewType()

data class OtherComment(val comment: Comment) : CommentViewType()
data object MyComment : CommentViewType()

data class DateSeparator(val comment: Comment) : CommentViewType()
data object OtherComment : CommentViewType()

companion object {
fun fromComment(comment: Comment): CommentViewType {
return if (comment.isMine) {
MyComment(comment)
} else {
OtherComment(comment)
}
}
}
data object DateSeparator : CommentViewType()
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package com.zzang.chongdae.presentation.view.commentdetail.adapter.comment

import androidx.recyclerview.widget.RecyclerView
import com.zzang.chongdae.databinding.ItemDateSeparatorBinding
import com.zzang.chongdae.domain.model.Comment
import com.zzang.chongdae.presentation.view.commentdetail.model.comment.CommentUiModel

class DateSeparatorViewHolder(
private val binding: ItemDateSeparatorBinding,
) : RecyclerView.ViewHolder(binding.root) {
fun bind(comment: Comment) {
fun bind(comment: CommentUiModel) {
binding.comment = comment
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package com.zzang.chongdae.presentation.view.commentdetail.adapter.comment

import androidx.recyclerview.widget.RecyclerView
import com.zzang.chongdae.databinding.ItemMyCommentBinding
import com.zzang.chongdae.domain.model.Comment
import com.zzang.chongdae.presentation.view.commentdetail.model.comment.CommentUiModel

class MyCommentViewHolder(
private val binding: ItemMyCommentBinding,
) : RecyclerView.ViewHolder(binding.root) {
fun bind(comment: Comment) {
fun bind(comment: CommentUiModel) {
binding.comment = comment
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package com.zzang.chongdae.presentation.view.commentdetail.adapter.comment

import androidx.recyclerview.widget.RecyclerView
import com.zzang.chongdae.databinding.ItemOtherCommentBinding
import com.zzang.chongdae.domain.model.Comment
import com.zzang.chongdae.presentation.view.commentdetail.model.comment.CommentUiModel

class OtherCommentViewHolder(
private val binding: ItemOtherCommentBinding,
) : RecyclerView.ViewHolder(binding.root) {
fun bind(comment: Comment) {
fun bind(comment: CommentUiModel) {
binding.comment = comment
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.zzang.chongdae.presentation.view.commentdetail.model.comment

import com.zzang.chongdae.domain.model.Comment
import com.zzang.chongdae.presentation.util.toFormattedDate
import com.zzang.chongdae.presentation.util.toFormattedTime
import com.zzang.chongdae.presentation.view.commentdetail.adapter.comment.CommentViewType

data class CommentUiModel(
val content: String,
val date: String,
val time: String,
val isMine: Boolean,
val isProposer: Boolean,
val nickname: String,
val commentViewType: CommentViewType,
) {
companion object {
fun Comment.toUiModel(): CommentUiModel {
val viewType = if (this.isMine) CommentViewType.MyComment else CommentViewType.OtherComment
return CommentUiModel(
content = this.content,
date = this.commentCreatedAt.date.toFormattedDate(),
time = this.commentCreatedAt.time.toFormattedTime(),
isMine = this.isMine,
isProposer = this.isProposer,
nickname = this.nickname,
commentViewType = viewType,
)
}

fun createDateSeparator(date: String): CommentUiModel {
return CommentUiModel(
content = "",
date = date,
time = "",
isMine = false,
isProposer = false,
nickname = "",
commentViewType = CommentViewType.DateSeparator,
)
}

fun List<Comment>.toUiModelListWithSeparators(): List<CommentUiModel> {
val uiModels = mutableListOf<CommentUiModel>()
var currentDate: String? = null

for (comment in this) {
val commentDate = comment.commentCreatedAt.date.toFormattedDate()
if (commentDate != currentDate) {
uiModels.add(CommentUiModel.createDateSeparator(commentDate))
currentDate = commentDate
}
uiModels.add(comment.toUiModel())
}

return uiModels
}
}
}
4 changes: 2 additions & 2 deletions android/app/src/main/res/layout/item_date_separator.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<variable
name="comment"
type="com.zzang.chongdae.domain.model.Comment" />
type="com.zzang.chongdae.presentation.view.commentdetail.model.comment.CommentUiModel" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
Expand All @@ -21,7 +21,7 @@
android:gravity="center"
android:textColor="@color/gray_font"
android:textSize="@dimen/size_12"
app:formattedOnlyDate="@{comment.commentCreatedAt.date}"
android:text="@{comment.date}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
Expand Down
4 changes: 2 additions & 2 deletions android/app/src/main/res/layout/item_my_comment.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<variable
name="comment"
type="com.zzang.chongdae.domain.model.Comment" />
type="com.zzang.chongdae.presentation.view.commentdetail.model.comment.CommentUiModel" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
Expand Down Expand Up @@ -54,7 +54,7 @@
android:layout_marginEnd="@dimen/margin_10"
android:fontFamily="@font/suit_medium"
android:textSize="@dimen/size_10"
app:formattedCommentTime="@{comment.commentCreatedAt.time}"
android:text="@{comment.time}"
app:layout_constraintBottom_toBottomOf="@id/tv_comment"
app:layout_constraintEnd_toStartOf="@id/tv_comment"
tools:text="오전 10:30" />
Expand Down
4 changes: 2 additions & 2 deletions android/app/src/main/res/layout/item_other_comment.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<variable
name="comment"
type="com.zzang.chongdae.domain.model.Comment" />
type="com.zzang.chongdae.presentation.view.commentdetail.model.comment.CommentUiModel" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
Expand Down Expand Up @@ -77,7 +77,7 @@
android:layout_marginStart="@dimen/margin_10"
android:fontFamily="@font/suit_medium"
android:textSize="@dimen/size_10"
app:formattedCommentTime="@{comment.commentCreatedAt.time}"
android:text="@{comment.time}"
app:layout_constraintBottom_toBottomOf="@id/tv_comment"
app:layout_constraintStart_toEndOf="@id/tv_comment"
tools:text="오전 10:30" />
Expand Down
Loading

0 comments on commit 9d3fc23

Please sign in to comment.