Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 댓글방 입장 기능, 본인이 총대인 방은 다르게 보이는 기능 구현 #99

Merged
merged 12 commits into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,14 @@ package com.zzang.chongdae
import androidx.fragment.app.testing.FragmentScenario
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.RecyclerViewActions
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.zzang.chongdae.domain.model.CommentRoom
import com.zzang.chongdae.presentation.view.comment.CommentRoomFragment
import com.zzang.chongdae.presentation.view.comment.adapter.CommentRoomViewHolder
import org.junit.Before
import org.junit.Test
import org.junit.jupiter.api.DisplayName
import org.junit.runner.RunWith
import java.time.LocalDateTime

@RunWith(AndroidJUnit4::class)
class CommentRoomFragmentTest {
Expand All @@ -27,26 +22,9 @@ class CommentRoomFragmentTest {
}

@Test
@DisplayName("댓글방이 하나도 없다면 그것을 알려주는 뷰가 보여야 한다")
fun `댓글방이_하나도_없다면_그것을_알려주는_뷰가_보여야_한다`() {
@DisplayName("댓글방 목록으로 이동하면 채팅이라는 텍스트뷰가 보여야 한다")
fun commentRoomTest1() {
// then
onView(withId(R.id.iv_empty_comment_room)).check(matches(isDisplayed()))
}

@Test
@DisplayName("댓글방이 있으면 댓글방의 뷰가 보여야 한다")
fun `댓글방이_있으면_댓글방의_뷰가_보여야_한다`() {
// given
scenario.onFragment {
it.viewModel.putCommentRooms(
listOf(CommentRoom(1, "알송", "알송이에용", LocalDateTime.now(), true)),
)
}
// when
onView(withId(R.id.rv_comment_room)).perform(
RecyclerViewActions.scrollToPosition<CommentRoomViewHolder>(0),
)
// then
onView(withText("알송")).check(matches(isDisplayed()))
onView(withId(R.id.tv_comment_text)).check(matches(isDisplayed()))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.zzang.chongdae.domain.model

enum class CommentRoomType(val separator: Int) {
PROPOSER(1),
NOT_PROPOSER(2),
}
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,14 @@ fun setLayoutHeightWithAnimation(
animator.start()
}

@BindingAdapter("formattedTime")
fun TextView.setTime(localDateTime: LocalDateTime) {
val aMOrPm = if (localDateTime.hour < 12) context.getString(R.string.am) else context.getString(R.string.pm)
val hour = if (aMOrPm == context.getString(R.string.am)) localDateTime.hour else localDateTime.hour - 12
val minute = localDateTime.format(DateTimeFormatter.ofPattern(context.getString(R.string.time)))
this.text = "$aMOrPm $hour:$minute"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"$aMOrPm $hour:$minute"이 부분을 strings로 빼주어서 관리하면 좋을 것 같아요!
그리고 고쳐도 되고 넘겨도 되는 부분인데요... amOrPm어떤가요..?
처음에 aMorPm을 보고 조금 흠칫 해서요..하하

}

private fun Int.toPx(context: Context): Int {
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.zzang.chongdae.presentation.view.comment

import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
Expand All @@ -11,13 +12,15 @@ import com.zzang.chongdae.data.remote.source.impl.CommentRoomDataSourceImpl
import com.zzang.chongdae.data.repository.remote.CommentRoomRepositoryImpl
import com.zzang.chongdae.databinding.FragmentCommentRoomBinding
import com.zzang.chongdae.presentation.view.comment.adapter.CommentRoomAdapter
import com.zzang.chongdae.presentation.view.comment.adapter.OnCommentRoomClickListener
import com.zzang.chongdae.presentation.view.commentdetail.CommentDetailActivity

class CommentRoomFragment : Fragment() {
class CommentRoomFragment : Fragment(), OnCommentRoomClickListener {
private var _binding: FragmentCommentRoomBinding? = null
private val binding get() = _binding!!

private val commentRoomAdapter: CommentRoomAdapter by lazy {
CommentRoomAdapter(viewModel)
CommentRoomAdapter(viewModel, this)
}

val viewModel by viewModels<CommentRoomViewModel> {
Expand Down Expand Up @@ -65,4 +68,13 @@ class CommentRoomFragment : Fragment() {
super.onDestroyView()
_binding = null
}

override fun onClick(id: Long) {
CommentDetailActivity.startActivity(
activity as Context,
id,
viewModel.commentRooms.value?.first { it.id == id }?.title
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요부분 click event할때 넘겨주면 더 효율적으로 코드를 관리할 수 있을 것 같아요!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 그런 방법이 있었네요 ㅎㅎ id만 가져오는 방법만 쓰다보니 그 생각을 못했서용 감사합니다 😆

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분을 혹시 xml에서 dataBinding하는 부분에서 id뿐만 아니라 title도 같이 넘겨주는 방식으로 수정하면 어떨까요?
그리면 viewModel에서 값을 따로 꺼내오지 않아도 될 것 같아서요!

?: throw IllegalArgumentException(),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@ class CommentRoomViewModel(
}
}

fun putCommentRooms(commentRooms: List<CommentRoom>) {
_commentRooms.value = commentRooms
}

companion object {
fun factory(commentRoomRepositoryImpl: CommentRoomRepository): ViewModelProvider.Factory {
return CommentRoomViewModelFactory(commentRoomRepositoryImpl)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,69 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import com.zzang.chongdae.databinding.ItemCommentRoomBinding
import com.zzang.chongdae.databinding.ItemCommentRoomProposerBinding
import com.zzang.chongdae.domain.model.CommentRoom
import com.zzang.chongdae.domain.model.CommentRoomType
import com.zzang.chongdae.presentation.view.comment.CommentRoomViewModel

class CommentRoomAdapter(
private val commentRoomViewModel: CommentRoomViewModel,
) : ListAdapter<CommentRoom, CommentRoomViewHolder.Representative>(productComparator) {
private val onClickListener: OnCommentRoomClickListener,
) : ListAdapter<CommentRoom, CommentRoomViewHolder>(productComparator) {
override fun getItemViewType(position: Int): Int {
return if (currentList[position].isProposer == true) {
CommentRoomType.PROPOSER.separator
} else {
CommentRoomType.NOT_PROPOSER.separator
}
}

override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int,
): CommentRoomViewHolder.Representative {
val binding =
ItemCommentRoomBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false,
)
return CommentRoomViewHolder.Representative(binding)
): CommentRoomViewHolder {
when (viewType) {
CommentRoomType.PROPOSER.separator -> {
val binding =
ItemCommentRoomProposerBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false,
)
return CommentRoomViewHolder.Proposer(binding)
}

CommentRoomType.NOT_PROPOSER.separator -> {
val binding =
ItemCommentRoomBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false,
)
return CommentRoomViewHolder.NotProposer(binding)
}

else -> error("Invalid view type")
}
}

override fun onBindViewHolder(
holder: CommentRoomViewHolder.Representative,
holder: CommentRoomViewHolder,
position: Int,
) {
holder.bind(currentList[position], commentRoomViewModel)
when (holder) {
is CommentRoomViewHolder.Proposer ->
holder.bind(
currentList[position],
onClickListener,
)

is CommentRoomViewHolder.NotProposer ->
holder.bind(
currentList[position],
onClickListener,
)
}
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,33 @@ package com.zzang.chongdae.presentation.view.comment.adapter
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import com.zzang.chongdae.databinding.ItemCommentRoomBinding
import com.zzang.chongdae.databinding.ItemCommentRoomProposerBinding
import com.zzang.chongdae.domain.model.CommentRoom
import com.zzang.chongdae.presentation.view.comment.CommentRoomViewModel

sealed class CommentRoomViewHolder(
view: View,
) : RecyclerView.ViewHolder(view) {
class Representative(
class Proposer(
private val binding: ItemCommentRoomProposerBinding,
) : CommentRoomViewHolder(binding.root) {
fun bind(
commentRoom: CommentRoom,
onClickListener: OnCommentRoomClickListener,
) {
binding.commentRoom = commentRoom
binding.clickListener = onClickListener
}
}

class NotProposer(
private val binding: ItemCommentRoomBinding,
) : CommentRoomViewHolder(binding.root) {
fun bind(
commentRoom: CommentRoom,
commentRoomViewModel: CommentRoomViewModel,
onClickListener: OnCommentRoomClickListener,
) {
binding.commentRoom = commentRoom
binding.clickListener = onClickListener
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.zzang.chongdae.presentation.view.comment.adapter

interface OnCommentRoomClickListener {
fun onClick(id: Long)
}
12 changes: 12 additions & 0 deletions android/app/src/main/res/drawable/ic_comment_room_proposer.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="48"
android:viewportHeight="48">
<path
android:pathData="M24,24m-24,0a24,24 0,1 1,48 0a24,24 0,1 1,-48 0"
android:fillColor="#F15642"/>
<path
android:pathData="M33.627,16.682C33.389,16.386 33.063,16.173 32.697,16.072C32.346,15.98 31.975,15.996 31.634,16.119C31.292,16.243 30.996,16.467 30.785,16.762L28.224,19.233L25.562,15.601C25.409,15.342 25.196,15.122 24.942,14.961C24.738,14.836 24.511,14.753 24.275,14.718C24.038,14.682 23.797,14.695 23.565,14.754C23.334,14.814 23.116,14.92 22.927,15.065C22.737,15.211 22.578,15.393 22.46,15.601L19.798,19.233L17.237,16.762C17.024,16.469 16.728,16.247 16.387,16.124C16.047,16.001 15.677,15.983 15.326,16.072C14.936,16.178 14.594,16.412 14.354,16.737C14.114,17.062 13.991,17.458 14.005,17.862L15.595,29.06C15.744,30.232 16.315,31.309 17.201,32.09C18.087,32.871 19.228,33.302 20.409,33.302H27.683C28.866,33.304 30.008,32.874 30.896,32.093C31.785,31.312 32.357,30.233 32.506,29.06L33.997,17.853C34.002,17.813 34.002,17.773 33.997,17.733C33.988,17.352 33.858,16.984 33.627,16.682ZM28.054,29.42H20.049C19.918,29.42 19.788,29.394 19.666,29.344C19.545,29.294 19.434,29.22 19.341,29.127C19.249,29.034 19.175,28.924 19.125,28.802C19.074,28.681 19.049,28.551 19.049,28.42C19.049,28.288 19.074,28.158 19.125,28.037C19.175,27.915 19.249,27.805 19.341,27.712C19.434,27.619 19.545,27.545 19.666,27.495C19.788,27.445 19.918,27.419 20.049,27.419H28.054C28.319,27.419 28.573,27.524 28.761,27.712C28.949,27.899 29.054,28.154 29.054,28.419C29.054,28.684 28.949,28.939 28.761,29.126C28.573,29.314 28.319,29.42 28.054,29.42Z"
android:fillColor="#ffffff"/>
</vector>
12 changes: 9 additions & 3 deletions android/app/src/main/res/layout/item_comment_room.xml
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

<data>

<variable
name="commentRoom"
type="com.zzang.chongdae.domain.model.CommentRoom" />

<variable
name="clickListener"
Copy link
Contributor

@Namyunsuk Namyunsuk Jul 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네이밍을 어떤 클릭리스너 인지 조금 더 구체적으로 해도 좋을 것 같아요!

type="com.zzang.chongdae.presentation.view.comment.adapter.OnCommentRoomClickListener" />
</data>


<androidx.constraintlayout.widget.ConstraintLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="80dp">
android:layout_height="80dp"
android:onClick="@{() -> clickListener.onClick(commentRoom.id)}">

<View
android:layout_width="match_parent"
Expand Down Expand Up @@ -63,6 +68,7 @@
android:layout_marginTop="14dp"
android:layout_marginEnd="4dp"
android:textColor="@color/gray_900"
app:formattedTime="@{commentRoom.latestCommentTime}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="오전 10:33" />
Expand Down
77 changes: 77 additions & 0 deletions android/app/src/main/res/layout/item_comment_room_proposer.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>

<variable
name="commentRoom"
type="com.zzang.chongdae.domain.model.CommentRoom" />

<variable
name="clickListener"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이것도 조금 더 구체적인 네이밍이면 좋을 것 같아요!
나중에 다른 리스너들도 생길 수 있으니깐요!

type="com.zzang.chongdae.presentation.view.comment.adapter.OnCommentRoomClickListener" />
</data>


<androidx.constraintlayout.widget.ConstraintLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="80dp"
android:onClick="@{() -> clickListener.onClick(commentRoom.id)}">

<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/gray_300"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />


<ImageView
android:id="@+id/iv_profile"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="25dp"
android:layout_marginTop="18dp"
android:src="@drawable/ic_comment_room_proposer"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/tv_offering_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="13dp"
android:layout_marginTop="14.25dp"
android:text="@{commentRoom.title}"
android:textColor="@color/black_900"
android:textSize="14sp"
app:layout_constraintStart_toEndOf="@id/iv_profile"
app:layout_constraintTop_toTopOf="parent"
tools:text="공구 제목 이름이 들어가요" />

<TextView
android:id="@+id/tv_offering_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3.25dp"
android:text="@{commentRoom.latestComment}"
android:textColor="@color/gray_500"
app:layout_constraintStart_toStartOf="@id/tv_offering_title"
app:layout_constraintTop_toBottomOf="@id/tv_offering_title"
tools:text="물품에 대해 설명 드릴게요." />

<TextView
android:id="@+id/tv_last_comment_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="14dp"
android:layout_marginEnd="4dp"
android:textColor="@color/gray_900"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="오전 10:33"
app:formattedTime="@{commentRoom.latestCommentTime}"/>

</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
3 changes: 3 additions & 0 deletions android/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@

<!-- comment_room-->
<string name="comment_text">채팅</string>
<string name="am">오전</string>
<string name="pm">오후</string>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오전, 오후 이런 strings는 다른 화면에서도 충분히 쓰일 수 있을 것 같아요! comment_room이 아니라 all로 옮기는 것도 생각해볼 수 있을 것 같아요!

<string name="time">"mm"</string>

<!-- offering_status-->
<string name="comment_detail">comment_detail</string>
Expand Down
Loading