-
Notifications
You must be signed in to change notification settings - Fork 0
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
[Chore] Change delete/modify/report modal #248
base: develop
Are you sure you want to change the base?
Changes from all commits
84390a3
628b1d5
87a92a1
7de6d1a
687a1c7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package com.eatssu.android.presentation.common | ||
|
||
import android.content.Intent | ||
import android.os.Bundle | ||
import android.view.LayoutInflater | ||
import android.view.View | ||
import android.view.ViewGroup | ||
import androidx.appcompat.app.AlertDialog | ||
import androidx.fragment.app.activityViewModels | ||
import androidx.lifecycle.lifecycleScope | ||
import com.eatssu.android.App | ||
import com.eatssu.android.R | ||
import com.eatssu.android.databinding.FragmentBottomsheetMyReviewBinding | ||
import com.eatssu.android.presentation.mypage.myreview.MyReviewViewModel | ||
import com.eatssu.android.presentation.review.modify.ModifyReviewActivity | ||
import com.eatssu.android.presentation.util.showToast | ||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment | ||
import dagger.hilt.android.AndroidEntryPoint | ||
import kotlinx.coroutines.flow.collectLatest | ||
import kotlinx.coroutines.launch | ||
import timber.log.Timber | ||
|
||
@AndroidEntryPoint | ||
class MyReviewBottomSheetFragment : BottomSheetDialogFragment() { | ||
private var _binding: FragmentBottomsheetMyReviewBinding? = null | ||
private val binding get() = _binding!! | ||
|
||
interface OnReviewDeletedListener { | ||
fun onReviewDeleted() | ||
} | ||
|
||
var onReviewDeletedListener: OnReviewDeletedListener? = null | ||
|
||
private val viewModel: MyReviewViewModel by activityViewModels() | ||
|
||
var reviewId = -1L | ||
var menu = "" | ||
var content = "" | ||
var mainGrade = -1 | ||
var amountGrade = -1 | ||
var tasteGrade = -1 | ||
|
||
override fun onCreateView( | ||
inflater: LayoutInflater, | ||
container: ViewGroup?, | ||
savedInstanceState: Bundle? | ||
): View { | ||
_binding = FragmentBottomsheetMyReviewBinding.inflate(inflater, container, false) | ||
return binding.root | ||
} | ||
|
||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||
super.onViewCreated(view, savedInstanceState) | ||
|
||
arguments?.let { | ||
reviewId = it.getLong("reviewId") | ||
menu = it.getString("menu").toString() | ||
content = it.getString("content").toString() | ||
mainGrade = it.getInt("mainGrade") | ||
amountGrade = it.getInt("amountGrade") | ||
tasteGrade = it.getInt("tasteGrade") | ||
} | ||
|
||
Timber.d("넘겨받은 리뷰 정보: $reviewId $menu $content $reviewId") | ||
|
||
binding.llModify.setOnClickListener { | ||
val intent = Intent(requireContext(), ModifyReviewActivity::class.java) | ||
|
||
intent.let { | ||
it.putExtra("reviewId", reviewId) | ||
it.putExtra("menu", menu) | ||
it.putExtra("content", content) | ||
it.putExtra("mainGrade", mainGrade) | ||
it.putExtra("amountGrade", amountGrade) | ||
it.putExtra("tasteGrade", tasteGrade) | ||
} | ||
|
||
startActivity(intent) | ||
dismiss() | ||
} | ||
|
||
binding.llDelete.setOnClickListener { | ||
AlertDialog.Builder(requireContext()).apply { | ||
setTitle(R.string.delete) | ||
setMessage(R.string.delete_description) | ||
setNegativeButton("취소") { _, _ -> | ||
activity?.showToast(App.appContext.getString(R.string.delete_undo)) | ||
} | ||
setPositiveButton("삭제") { _, _ -> | ||
viewModel.deleteReview(reviewId) | ||
lifecycleScope.launch { | ||
viewModel.uiState.collectLatest { | ||
if (it.isDeleted) { | ||
onReviewDeletedListener?.onReviewDeleted() // 콜백 호출 | ||
dismiss() | ||
} | ||
} | ||
} | ||
} | ||
}.create().show() | ||
} | ||
Comment on lines
+82
to
+101
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 삭제 로직 개선 필요 다음 사항들을 개선하면 좋을 것 같습니다:
- setNegativeButton("취소") { _, _ ->
- activity?.showToast(App.appContext.getString(R.string.delete_undo))
- }
- setPositiveButton("삭제") { _, _ ->
+ setNegativeButton(R.string.cancel) { _, _ ->
+ activity?.showToast(getString(R.string.delete_undo))
+ }
+ setPositiveButton(R.string.delete) { _, _ ->
viewModel.deleteReview(reviewId)
lifecycleScope.launch {
+ try {
viewModel.uiState.collectLatest {
if (it.isDeleted) {
onReviewDeletedListener?.onReviewDeleted() // 콜백 호출
dismiss()
+ } else if (it.error != null) {
+ activity?.showToast(getString(R.string.delete_error))
}
}
+ } catch (e: Exception) {
+ activity?.showToast(getString(R.string.unknown_error))
+ }
}
}
|
||
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package com.eatssu.android.presentation.common | ||
|
||
import android.content.Intent | ||
import android.os.Bundle | ||
import android.view.LayoutInflater | ||
import android.view.View | ||
import android.view.ViewGroup | ||
import com.eatssu.android.databinding.FragmentBottomsheetOthersBinding | ||
import com.eatssu.android.presentation.review.report.ReportActivity | ||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment | ||
import dagger.hilt.android.AndroidEntryPoint | ||
import timber.log.Timber | ||
|
||
@AndroidEntryPoint | ||
class OthersBottomSheetFragment : BottomSheetDialogFragment() { | ||
private var _binding: FragmentBottomsheetOthersBinding? = null | ||
private val binding get() = _binding!! | ||
|
||
var reviewId = -1L | ||
var menu = "" | ||
|
||
Comment on lines
+16
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 메모리 누수 방지를 위한 바인딩 정리 필요 바인딩 객체가 프래그먼트 수명주기 이후에도 유지될 수 있어 메모리 누수가 발생할 수 있습니다. 다음과 같이 수정해주세요: + override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ } 또한 reviewId와 menu를 데이터 클래스로 캡슐화하는 것을 고려해보세요.
|
||
override fun onCreateView( | ||
inflater: LayoutInflater, | ||
container: ViewGroup?, | ||
savedInstanceState: Bundle? | ||
): View { | ||
_binding = FragmentBottomsheetOthersBinding.inflate(inflater, container, false) | ||
return binding.root | ||
} | ||
|
||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||
super.onViewCreated(view, savedInstanceState) | ||
|
||
arguments?.let { | ||
reviewId = it.getLong("reviewId") | ||
menu = it.getString("menu").toString() | ||
} | ||
Comment on lines
+34
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Codebase verification 인자 검증 로직 개선 필요 arguments에서 reviewId와 menu를 가져올 때 다음과 같은 문제점들이 발견되었습니다:
수정이 필요한 부분:
🔗 Analysis chain인자 유효성 검사 추가 필요 reviewId가 유효하지 않은 경우(-1)에 대한 처리가 필요합니다. 또한 menu가 null이나 빈 문자열일 경우의 처리도 필요합니다. Let me check how these reviewId values are handled in the related files. Let me check how these fragments handle their lifecycle and any error cases. 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Check if there are any null checks for these arguments in other files
rg "reviewId.*-1|menu.*isEmpty" app/src/main/java/
Length of output: 786 Script: #!/bin/bash
# Check the implementation of these bottom sheet fragments and activities
ast-grep --pattern 'class $_ : BottomSheetDialogFragment {
$$$
reviewId $$$
$$$
}'
# Also check for menu parameter handling
rg "menu.*toString|getString.*menu" app/src/main/java/
Length of output: 1924 Script: #!/bin/bash
# Check implementation of these bottom sheet fragments
cat app/src/main/java/com/eatssu/android/presentation/common/OthersBottomSheetFragment.kt
cat app/src/main/java/com/eatssu/android/presentation/common/MyReviewBottomSheetFragment.kt
# Check if there's any error handling in parent classes
rg "class.*BottomSheetDialogFragment" app/src/main/java/
Length of output: 5925 |
||
|
||
Timber.d("넘겨받은 리뷰 정보: $reviewId $menu") | ||
|
||
binding.llReport.setOnClickListener { | ||
|
||
val intent = Intent(requireContext(), ReportActivity::class.java) | ||
intent.putExtra("reviewId", reviewId) | ||
Timber.d("reviewId $reviewId") | ||
startActivity(intent) | ||
dismiss() | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,69 +1,61 @@ | ||
package com.eatssu.android.presentation.mypage.myreview | ||
|
||
import android.content.Intent | ||
import android.view.LayoutInflater | ||
import android.view.View | ||
import android.view.ViewGroup | ||
import android.widget.ImageView | ||
import androidx.core.content.ContextCompat | ||
import androidx.recyclerview.widget.RecyclerView | ||
import androidx.recyclerview.widget.DiffUtil | ||
import androidx.recyclerview.widget.ListAdapter | ||
import com.bumptech.glide.Glide | ||
import com.eatssu.android.data.MySharedPreferences | ||
import com.eatssu.android.databinding.ItemReviewBinding | ||
import com.eatssu.android.domain.model.Review | ||
import com.eatssu.android.presentation.review.delete.MyReviewDialogActivity | ||
import timber.log.Timber | ||
|
||
class MyReviewAdapter : | ||
ListAdapter<Review, MyReviewAdapter.ViewHolder>(ReviewDiffCallback()) { | ||
|
||
class MyReviewAdapter(private val dataList: List<Review>) : | ||
RecyclerView.Adapter<MyReviewAdapter.ViewHolder>() { | ||
interface OnItemClickListener { | ||
fun onMyReviewClicked(view: View, reviewData: Review) | ||
} | ||
|
||
inner class ViewHolder(private val binding: ItemReviewBinding) : | ||
RecyclerView.ViewHolder(binding.root) { | ||
// 객체 저장 변수 | ||
private lateinit var mOnItemClickListener: OnItemClickListener | ||
|
||
fun bind(position: Int) { | ||
binding.tvReviewItemComment.text = dataList[position].content | ||
binding.tvReviewItemDate.text = dataList[position].writeDate | ||
binding.tvMenuName.text = dataList[position].menu | ||
// 객체 전달 메서드 | ||
fun setOnItemClickListener(onItemClickListener: OnItemClickListener) { | ||
mOnItemClickListener = onItemClickListener | ||
} | ||
Comment on lines
+23
to
+28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 클릭 리스너 설정 메서드의 안전성 강화 필요
예를 들어, |
||
|
||
binding.rbRate.rating = dataList[position].mainGrade.toFloat() | ||
inner class ViewHolder(private val binding: ItemReviewBinding) : | ||
androidx.recyclerview.widget.RecyclerView.ViewHolder(binding.root) { | ||
|
||
fun bind(data: Review) { | ||
binding.tvWriterNickname.text = MySharedPreferences.getUserName(binding.root.context) | ||
binding.tvReviewItemComment.text = data.content | ||
binding.tvReviewItemDate.text = data.writeDate | ||
binding.tvMenuName.text = data.menu | ||
binding.rbRate.rating = data.mainGrade.toFloat() | ||
|
||
val imageView: ImageView = binding.ivReviewPhoto | ||
|
||
if (dataList[position].imgUrl?.isEmpty() == true) { | ||
if (data.imgUrl?.isEmpty() == true || data.imgUrl?.get(0).isNullOrEmpty()) { | ||
imageView.visibility = View.GONE | ||
} else { | ||
Timber.d("사진 있다") | ||
Glide.with(itemView) | ||
.load(dataList[position].imgUrl?.get(0)) | ||
.load(data.imgUrl?.get(0)) | ||
.into(imageView) | ||
imageView.visibility = View.VISIBLE | ||
|
||
if (dataList[position].imgUrl?.get(0) == "" || dataList[position].imgUrl?.get(0) == null) { | ||
binding.ivReviewPhoto.visibility = View.GONE | ||
} | ||
} | ||
|
||
binding.btnDetail.setOnClickListener { | ||
val intent = Intent(binding.btnDetail.context, MyReviewDialogActivity::class.java) | ||
intent.putExtra("reviewId", dataList[position].reviewId) | ||
intent.putExtra("menu", dataList[position].menu) | ||
|
||
intent.putExtra("content", dataList[position].content) | ||
|
||
intent.putExtra("mainGrade", dataList[position].mainGrade) | ||
intent.putExtra("amountGrade", dataList[position].amountGrade) | ||
intent.putExtra("tasteGrade", dataList[position].tasteGrade) | ||
binding.btnDetail.setOnClickListener { v: View -> | ||
mOnItemClickListener.onMyReviewClicked(v, data) | ||
|
||
Timber.d( | ||
"리뷰 상세 정보 - ID: %d, 메뉴: %s, 내용: %s", | ||
dataList[position].reviewId, | ||
dataList[position].menu, | ||
dataList[position].content | ||
data.reviewId, | ||
data.menu, | ||
data.content | ||
) | ||
|
||
ContextCompat.startActivity(binding.btnDetail.context, intent, null) | ||
} | ||
} | ||
} | ||
|
@@ -75,8 +67,17 @@ class MyReviewAdapter(private val dataList: List<Review>) : | |
} | ||
|
||
override fun onBindViewHolder(holder: ViewHolder, position: Int) { | ||
holder.bind(position) | ||
val item = getItem(position) | ||
holder.bind(item) | ||
} | ||
} | ||
|
||
override fun getItemCount(): Int = dataList.size | ||
} | ||
class ReviewDiffCallback : DiffUtil.ItemCallback<Review>() { | ||
override fun areItemsTheSame(oldItem: Review, newItem: Review): Boolean { | ||
return oldItem.reviewId == newItem.reviewId | ||
} | ||
|
||
override fun areContentsTheSame(oldItem: Review, newItem: Review): Boolean { | ||
return oldItem == newItem | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
속성 유효성 검사 추가 필요
리뷰 데이터의 유효성 검사가 누락되어 있습니다:
📝 Committable suggestion