Skip to content

Commit

Permalink
Merge pull request #140 from team-winey/feature/feat-detail-deleteFeed
Browse files Browse the repository at this point in the history
  • Loading branch information
sxunea authored Aug 22, 2023
2 parents d8d57b8 + a085c47 commit 6e42056
Show file tree
Hide file tree
Showing 9 changed files with 211 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ import kotlinx.coroutines.flow.onEach
class MainActivity : BindingActivity<ActivityMainBinding>(R.layout.activity_main) {
private val mainViewModel by viewModels<MainViewModel>()
private val isUploadSuccess by lazy { intent.extras?.getBoolean(EXTRA_UPLOAD_KEY, false) }

private val isDeleteSuccess by lazy { intent.extras?.getBoolean(EXTRA_DELETE_KEY, false) }
private val isReportSuccess by lazy { intent.extras?.getBoolean(EXTRA_REPORT_KEY, false) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

Expand All @@ -39,7 +40,7 @@ class MainActivity : BindingActivity<ActivityMainBinding>(R.layout.activity_main
syncBottomNavigationSelection()

setupLogoutState()
showUploadSuccessSnackbar()
showSuccessSnackBar()
}

private fun initFragment() {
Expand All @@ -51,10 +52,16 @@ class MainActivity : BindingActivity<ActivityMainBinding>(R.layout.activity_main
}
}

private fun showUploadSuccessSnackbar() {
private fun showSuccessSnackBar() {
if (isUploadSuccess != null && isUploadSuccess == true) {
wineySnackbar(binding.root, true, stringOf(R.string.snackbar_upload_success))
}
if (isDeleteSuccess != null && isDeleteSuccess == true) {
wineySnackbar(binding.root, true, stringOf(R.string.snackbar_feed_delete_success))
}
if (isReportSuccess != null && isReportSuccess == true) {
wineySnackbar(binding.root, true, stringOf(R.string.snackbar_report_success))
}
}

private fun initBnvItemSelectedListener() {
Expand Down Expand Up @@ -119,5 +126,7 @@ class MainActivity : BindingActivity<ActivityMainBinding>(R.layout.activity_main

companion object {
private const val EXTRA_UPLOAD_KEY = "upload"
private const val EXTRA_DELETE_KEY = "delete"
private const val EXTRA_REPORT_KEY = "report"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import com.android.go.sopt.winey.util.view.setOnSingleClickListener
class WineyFeedAdapter(
private val likeButtonClick: (feedId: Int, isLiked: Boolean) -> Unit,
private val showPopupMenu: (View, WineyFeed) -> Unit,
private val toFeedDetail: (feedId: Int, writerLevel: Int) -> Unit
private val toFeedDetail: (feedId: Int, writerId: Int) -> Unit
) : PagingDataAdapter<WineyFeed, WineyFeedAdapter.WineyFeedViewHolder>(diffUtil) {
private val currentData: ItemSnapshotList<WineyFeed>
get() = snapshot()
Expand Down Expand Up @@ -72,24 +72,6 @@ class WineyFeedAdapter(
holder.onBind(getItem(position))
}

fun updateLikeStatus(feedId: Int, isLiked: Boolean) {
currentData.let { data ->
val index = data.indexOfFirst { it?.feedId == feedId }
if (index == -1) {
return
}
data[index]?.let { item ->
item.isLiked = isLiked
if (isLiked) {
item.likes++
} else {
item.likes--
}
notifyItemChanged(index)
}
}
}

companion object {
private val diffUtil = ItemDiffCallback<WineyFeed>(
onItemsTheSame = { old, new -> old.feedId == new.feedId },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.android.go.sopt.winey.presentation.main.feed

import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager
Expand Down Expand Up @@ -49,7 +50,8 @@ import timber.log.Timber
import javax.inject.Inject

@AndroidEntryPoint
class WineyFeedFragment : BindingFragment<FragmentWineyFeedBinding>(R.layout.fragment_winey_feed) {
class WineyFeedFragment :
BindingFragment<FragmentWineyFeedBinding>(R.layout.fragment_winey_feed) {
private val viewModel by viewModels<WineyFeedViewModel>()
private val mainViewModel by activityViewModels<MainViewModel>()
private lateinit var wineyFeedAdapter: WineyFeedAdapter
Expand All @@ -61,6 +63,7 @@ class WineyFeedFragment : BindingFragment<FragmentWineyFeedBinding>(R.layout.fra

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Log.d("Fragment Lifecycle", "onViewCreated 호출됨")
initAdapter()
setSwipeRefreshListener()
initFabClickListener()
Expand Down Expand Up @@ -105,8 +108,10 @@ class WineyFeedFragment : BindingFragment<FragmentWineyFeedBinding>(R.layout.fra
true
)

val menuDelete = popupView.findViewById<TextView>(R.id.tv_popup_delete)
val menuReport = popupView.findViewById<TextView>(R.id.tv_popup_report)
val menuDelete =
popupView.findViewById<TextView>(R.id.tv_popup_delete)
val menuReport =
popupView.findViewById<TextView>(R.id.tv_popup_report)

if (wineyFeed.userId == runBlocking { dataStoreRepository.getUserId().first() }) {
menuReport.isVisible = false
Expand Down Expand Up @@ -188,10 +193,7 @@ class WineyFeedFragment : BindingFragment<FragmentWineyFeedBinding>(R.layout.fra
when (state) {
is UiState.Success -> {
initGetFeedStateObserver()
wineyFeedAdapter.updateLikeStatus(
state.data.data.feedId,
state.data.data.isLiked
)
wineyFeedAdapter.refresh()
}

is UiState.Failure -> {
Expand Down Expand Up @@ -256,7 +258,8 @@ class WineyFeedFragment : BindingFragment<FragmentWineyFeedBinding>(R.layout.fra
parentFragmentManager.commit {
replace<T>(R.id.fcv_main, T::class.simpleName)
}
val bottomNav: BottomNavigationView = requireActivity().findViewById(R.id.bnv_main)
val bottomNav: BottomNavigationView =
requireActivity().findViewById(R.id.bnv_main)
bottomNav.selectedItemId = R.id.menu_mypage
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.android.go.sopt.winey.presentation.main.feed.detail

import CommentAdapter
import android.content.Intent
import android.os.Bundle
import android.view.Gravity
import android.view.View
Expand All @@ -13,9 +14,11 @@ import com.android.go.sopt.winey.databinding.ActivityDetailBinding
import com.android.go.sopt.winey.domain.entity.Comment
import com.android.go.sopt.winey.domain.entity.DetailFeed
import com.android.go.sopt.winey.domain.repository.DataStoreRepository
import com.android.go.sopt.winey.presentation.main.MainActivity
import com.android.go.sopt.winey.util.binding.BindingActivity
import com.android.go.sopt.winey.util.context.snackBar
import com.android.go.sopt.winey.util.context.stringOf
import com.android.go.sopt.winey.util.context.wineySnackbar
import com.android.go.sopt.winey.util.fragment.WineyDialogFragment
import com.android.go.sopt.winey.util.view.UiState
import com.android.go.sopt.winey.util.view.WineyPopupMenu
Expand Down Expand Up @@ -52,6 +55,7 @@ class DetailActivity : BindingActivity<ActivityDetailBinding>(R.layout.activity_
viewModel.getFeedDetail(feedId)
initGetFeedDetailObserver()
initBackButtonClickListener()
initPostLikeStateObserver()

initCommentAdapter()
initCommentCreateButtonClickListener()
Expand All @@ -61,27 +65,44 @@ class DetailActivity : BindingActivity<ActivityDetailBinding>(R.layout.activity_
private fun initCommentAdapter() {
_commentAdapter = CommentAdapter(
onPopupMenuClicked = { anchorView, commentAuthorId ->
showPopupMenu(anchorView, commentAuthorId)
showCommentPopupMenu(anchorView, commentAuthorId)
}
)
}

private fun showPopupMenu(anchorView: View, commentAuthorId: Int) {
private fun initDetailFeedAdapter(detailFeed: DetailFeed?) {
if (detailFeed == null) {
Timber.e("DETAIL FEED IS NULL")
return
}
_detailFeedAdapter =
DetailFeedAdapter(
detailFeed,
onLikeButtonClicked = { feedId, isLiked ->
viewModel.likeFeed(feedId, isLiked)
},
onPopupMenuClicked = { anchorView ->
showFeedPopupMenu(anchorView)
}
)
}

private fun showCommentPopupMenu(anchorView: View, commentAuthorId: Int) {
lifecycleScope.launch {
val currentUserId = dataStoreRepository.getUserId().first()

if (isMyFeed(currentUserId)) {
if (isMyComment(currentUserId, commentAuthorId)) {
// 내 댓글 삭제
showDeletePopupMenu(anchorView)
showCommentDeletePopupMenu(anchorView)
} else {
// 방문자 댓글 삭제/신고
showAllPopupMenu(anchorView)
}
} else {
if (isMyComment(currentUserId, commentAuthorId)) {
// 내 댓글 삭제
showDeletePopupMenu(anchorView)
showCommentDeletePopupMenu(anchorView)
} else {
// 다른 사람 댓글 신고
showReportPopupMenu(anchorView)
Expand All @@ -90,7 +111,18 @@ class DetailActivity : BindingActivity<ActivityDetailBinding>(R.layout.activity_
}
}

private fun showDeletePopupMenu(anchorView: View) {
private fun showFeedPopupMenu(anchorView: View) {
lifecycleScope.launch {
val currentUserId = dataStoreRepository.getUserId().first()
if (isMyFeed(currentUserId)) {
showFeedDeletePopupMenu(anchorView)
} else {
showReportPopupMenu(anchorView)
}
}
}

private fun showCommentDeletePopupMenu(anchorView: View) {
val deleteTitle = listOf(stringOf(R.string.popup_delete_title))
WineyPopupMenu(context = anchorView.context, titles = deleteTitle) { _, _, _ ->
showCommentDeleteDialog()
Expand All @@ -99,6 +131,15 @@ class DetailActivity : BindingActivity<ActivityDetailBinding>(R.layout.activity_
}
}

private fun showFeedDeletePopupMenu(anchorView: View) {
val deleteTitle = listOf(stringOf(R.string.popup_delete_title))
WineyPopupMenu(context = anchorView.context, titles = deleteTitle) { _, _, _ ->
showFeedDeleteDialog()
}.apply {
showCustomPosition(anchorView)
}
}

private fun showReportPopupMenu(anchorView: View) {
val reportTitle = listOf(stringOf(R.string.popup_report_title))
WineyPopupMenu(context = anchorView.context, titles = reportTitle) { _, _, _ ->
Expand Down Expand Up @@ -139,14 +180,27 @@ class DetailActivity : BindingActivity<ActivityDetailBinding>(R.layout.activity_
dialog.show(supportFragmentManager, TAG_COMMENT_DELETE_DIALOG)
}

private fun showFeedDeleteDialog() {
val dialog = WineyDialogFragment(
stringOf(R.string.feed_delete_dialog_title),
stringOf(R.string.feed_delete_dialog_subtitle),
stringOf(R.string.comment_delete_dialog_negative_button),
stringOf(R.string.comment_delete_dialog_positive_button),
handleNegativeButton = {},
handlePositiveButton = { viewModel.deleteFeed(feedId) }
)
dialog.show(supportFragmentManager, TAG_COMMENT_DELETE_DIALOG)
initDeleteFeedStateObserver()
}

private fun showCommentReportDialog() {
val dialog = WineyDialogFragment(
stringOf(R.string.report_dialog_title),
stringOf(R.string.report_dialog_subtitle),
stringOf(R.string.report_dialog_negative_button),
stringOf(R.string.report_dialog_positive_button),
handleNegativeButton = {},
handlePositiveButton = { /* todo: 댓글 신고하기 */ }
handlePositiveButton = { navigateToMain(EXTRA_REPORT_KEY) }
)
dialog.show(supportFragmentManager, TAG_COMMENT_REPORT_DIALOG)
}
Expand Down Expand Up @@ -178,8 +232,7 @@ class DetailActivity : BindingActivity<ActivityDetailBinding>(R.layout.activity_
snackBar(binding.root) { state.msg }
}

else -> {
}
else -> Timber.tag("failure").e(MSG_DETAIL_ERROR)
}
}.launchIn(lifecycleScope)
}
Expand All @@ -197,18 +250,25 @@ class DetailActivity : BindingActivity<ActivityDetailBinding>(R.layout.activity_
snackBar(binding.root) { state.msg }
}

else -> {
}
else -> Timber.tag("failure").e(MSG_DETAIL_ERROR)
}
}.launchIn(lifecycleScope)
}

private fun initDetailFeedAdapter(detailFeed: DetailFeed?) {
if (detailFeed == null) {
Timber.e("DETAIL FEED IS NULL")
return
}
_detailFeedAdapter = DetailFeedAdapter(detailFeed)
private fun initDeleteFeedStateObserver() {
viewModel.deleteFeedDetailState.flowWithLifecycle(lifecycle).onEach { state ->
when (state) {
is UiState.Success -> {
navigateToMain(EXTRA_DELETE_KEY)
}

is UiState.Failure -> {
wineySnackbar(binding.root, false, stringOf(R.string.snackbar_delete_fail))
}

else -> Timber.tag("failure").e(MSG_DETAIL_ERROR)
}
}.launchIn(lifecycleScope)
}

private fun switchCommentContainer(commentList: List<Comment>?) {
Expand All @@ -231,6 +291,30 @@ class DetailActivity : BindingActivity<ActivityDetailBinding>(R.layout.activity_
}
}

private fun initPostLikeStateObserver() {
viewModel.postFeedDetailLikeState.flowWithLifecycle(lifecycle).onEach { state ->
when (state) {
is UiState.Success -> {
viewModel.getFeedDetail(feedId)
}

is UiState.Failure -> {
snackBar(binding.root) { state.msg }
}

else -> Timber.tag("failure").e(MSG_DETAIL_ERROR)
}
}.launchIn(lifecycleScope)
}

private fun navigateToMain(extraKey: String) {
Intent(this, MainActivity::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
putExtra(extraKey, true)
startActivity(this)
}
}

companion object {
private const val KEY_FEED_ID = "feedId"
private const val KEY_FEED_WRITER_ID = "feedWriterId"
Expand All @@ -239,5 +323,10 @@ class DetailActivity : BindingActivity<ActivityDetailBinding>(R.layout.activity_
private const val TAG_COMMENT_REPORT_DIALOG = "COMMENT_REPORT_DIALOG"

private const val POPUP_MENU_OFFSET = 65

private const val MSG_DETAIL_ERROR = "ERROR"

private const val EXTRA_DELETE_KEY = "delete"
private const val EXTRA_REPORT_KEY = "report"
}
}
Loading

0 comments on commit 6e42056

Please sign in to comment.