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] 위니 피드, 마이 피드 / 리디자인에 따른 기능 구현 #122

Merged
merged 15 commits into from
Aug 18, 2023
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -35,13 +35,17 @@ data class ResponseGetWineyFeedListDto(
@SerialName("isLiked")
val isLiked: Boolean,
@SerialName("likes")
val likes: Int,
val likes: Long,
@SerialName("nickName")
val nickName: String,
@SerialName("userId")
val userId: Int,
@SerialName("writerLevel")
val writerLevel: Int
val writerLevel: Int,
@SerialName("comments")
val comments: Long,
@SerialName("timeAgo")
val timeAgo: String
)

@Serializable
Expand All @@ -66,6 +70,8 @@ data class ResponseGetWineyFeedListDto(
nickName = feed.nickName,
userId = feed.userId,
writerLevel = feed.writerLevel,
comments = feed.comments,
timeAgo = feed.timeAgo,
totalPageSize = data.pageResponseDto.totalPageSize,
isEnd = data.pageResponseDto.isEnd
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ class FeedRepositoryImpl @Inject constructor(
private val feedService: FeedService
) : FeedRepository {
override suspend fun getWineyFeedList(): Flow<PagingData<WineyFeed>> =
Pager(PagingConfig(FEED_PAGE_SIZE, prefetchDistance = LOAD_DISTANCE)) {
Pager(PagingConfig(WINEYFEED_PAGE_SIZE, prefetchDistance = LOAD_DISTANCE)) {
WineyFeedPagingSource(feedService)
}.flow

override suspend fun getMyFeedList(): Flow<PagingData<WineyFeed>> =
Pager(PagingConfig(FEED_PAGE_SIZE, prefetchDistance = LOAD_DISTANCE)) {
Pager(PagingConfig(MYFEED_PAGE_SIZE, prefetchDistance = LOAD_DISTANCE)) {
MyFeedPagingSource(feedService)
}.flow

Expand All @@ -53,7 +53,8 @@ class FeedRepositoryImpl @Inject constructor(
}

companion object {
const val FEED_PAGE_SIZE = 20
const val WINEYFEED_PAGE_SIZE = 20
const val MYFEED_PAGE_SIZE = 10
const val LOAD_DISTANCE = 2
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ data class WineyFeed(
val feedMoney: Long,
val feedTitle: String,
var isLiked: Boolean,
var likes: Int,
var likes: Long,
val nickName: String,
val userId: Int,
val writerLevel: Int,
val totalPageSize: Int,
val isEnd: Boolean
val isEnd: Boolean,
val comments: Long,
val timeAgo: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ package com.android.go.sopt.winey.presentation.main.feed

import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.widget.PopupMenu
import android.view.WindowManager
import android.widget.PopupWindow
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
Expand All @@ -16,6 +20,7 @@ import com.android.go.sopt.winey.databinding.FragmentWineyFeedBinding
import com.android.go.sopt.winey.domain.entity.User
import com.android.go.sopt.winey.domain.entity.WineyFeed
import com.android.go.sopt.winey.domain.repository.DataStoreRepository
import com.android.go.sopt.winey.presentation.main.AlertDialogFragment
import com.android.go.sopt.winey.presentation.main.MainViewModel
import com.android.go.sopt.winey.presentation.main.feed.upload.UploadActivity
import com.android.go.sopt.winey.util.binding.BindingFragment
Expand Down Expand Up @@ -74,32 +79,70 @@ class WineyFeedFragment : BindingFragment<FragmentWineyFeedBinding>(R.layout.fra
}

private fun showPopupMenu(view: View, wineyFeed: WineyFeed) {
val popupMenu = PopupMenu(requireContext(), view)
popupMenu.menuInflater.inflate(R.menu.menu_wineyfeed, popupMenu.menu)
val menuDelete = popupMenu.menu.findItem(R.id.menu_delete)
val menuReport = popupMenu.menu.findItem(R.id.menu_report)
val inflater = LayoutInflater.from(requireContext())
val popupView = inflater.inflate(R.layout.menu_wineyfeed, null)
val popupWindow = PopupWindow(
popupView,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
true
)
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
} else {
menuDelete.isVisible = false
}
popupMenu.setOnMenuItemClickListener { menuItem ->
when (menuItem.itemId) {
R.id.menu_delete -> {
showDeleteDialog(wineyFeed.feedId, wineyFeed.writerLevel)
true
}
menuDelete.setOnSingleClickListener {
showDeleteDialog(wineyFeed.feedId, wineyFeed.writerLevel)
popupWindow.dismiss()
}
popupWindow.showAsDropDown(view)
}

else -> false
/* 신고 구현 : 앱잼 내에서는 없음 */
}
private fun refreshWineyFeed() {
val fragmentManager = parentFragmentManager
fragmentManager.beginTransaction().apply {
replace(R.id.fcv_main, WineyFeedFragment())
commit()
}
popupMenu.show()
}

private fun showDeleteDialog(feedId: Int, userLevel: Int) {
val wineyFeedDeleteDialogFragment = WineyFeedDeleteDialogFragment(feedId, userLevel)
wineyFeedDeleteDialogFragment.show(parentFragmentManager, TAG_DELETE_DIALOG)
val dialogSub: Int =
if (userLevel <= LV_KNIGHT) {
R.string.myfeed_dialog_lowlevel_sub
} else {
R.string.myfeed_dialog_highlevel_sub
}

val deleteDialog = AlertDialogFragment(
getString(R.string.wineyfeed_dialog_title),
getString(dialogSub),
getString(R.string.wineyfeed_dialog_cancel),
getString(R.string.myfeed_dialog_delete),
handleNegativeButton = { },
handlePositiveButton = { viewModel.deleteFeed(feedId) }
)
deleteDialog.show(parentFragmentManager, TAG_DELETE_DIALOG)
initDeleteFeedStateObserver()
}

private fun initDeleteFeedStateObserver() {
viewModel.deleteWineyFeedState.flowWithLifecycle(viewLifeCycle).onEach { state ->
when (state) {
is UiState.Success -> {
refreshWineyFeed()
}

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

else -> Timber.tag("failure").e(MSG_WINEYFEED_ERROR)
}
}.launchIn(viewLifeCycleScope)
}

private fun initGetFeedStateObserver() {
Expand Down Expand Up @@ -192,6 +235,7 @@ class WineyFeedFragment : BindingFragment<FragmentWineyFeedBinding>(R.layout.fra
}

companion object {
private const val LV_KNIGHT = 2
private const val TAG_WINEYFEED_DIALOG = "NO_GOAL_DIALOG"
private const val MSG_WINEYFEED_ERROR = "ERROR"
private const val TAG_DELETE_DIALOG = "DELETE_DIALOG"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.android.go.sopt.winey.presentation.main.mypage.myfeed

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.FragmentManager
import androidx.paging.ItemSnapshotList
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.RecyclerView
Expand All @@ -14,32 +14,28 @@ import com.android.go.sopt.winey.util.view.setOnSingleClickListener

class MyFeedAdapter(
private val likeButtonClick: (feedId: Int, isLiked: Boolean) -> Unit,
private val fragmentManager: FragmentManager,
private val deleteButtonClick: (feedId: Int, writerLevel: Int) -> Unit
) :
PagingDataAdapter<WineyFeed, MyFeedAdapter.MyFeedViewHolder>(diffUtil) {
private val showPopupMenu: (View, WineyFeed) -> Unit
) : PagingDataAdapter<WineyFeed, MyFeedAdapter.MyFeedViewHolder>(diffUtil) {
private val currentData: ItemSnapshotList<WineyFeed>
get() = snapshot()

class MyFeedViewHolder(
private val fragmentManager: FragmentManager,
private val binding: ItemMyfeedPostBinding,
private val onLikeButtonClick: (feedId: Int, isLiked: Boolean) -> Unit,
private val deleteButtonClick: (feedId: Int, writerLevel: Int) -> Unit
private val showPopupMenu: (View, WineyFeed) -> Unit
) : RecyclerView.ViewHolder(binding.root) {
fun onBind(data: WineyFeed?) {
binding.apply {
this.data = data
if (data != null) {
ivMyfeedProfilephoto.setImageResource(setUserProfile(data.writerLevel))
ivMyfeedLike.setOnSingleClickListener {
onLikeButtonClick(data.feedId, !data.isLiked)
}
tvMyfeedDelete.setOnSingleClickListener {
showDeleteDialog(data.feedId, data.writerLevel)
deleteButtonClick(data.feedId, data.writerLevel)
}
executePendingBindings()
if (data == null) {
return
}
ivMyfeedProfilephoto.setImageResource(setUserProfile(data.writerLevel))
ivMyfeedLike.setOnSingleClickListener {
onLikeButtonClick(data.feedId, !data.isLiked)
}
btnWineyfeedMore.setOnClickListener { view ->
showPopupMenu(view, data)
}
}
}
Expand All @@ -55,20 +51,14 @@ class MyFeedAdapter(
}
}
}

private fun showDeleteDialog(feedId: Int, userLevel: Int) {
val myFeedDeleteDialogFragment = MyFeedDeleteDialogFragment(feedId, userLevel)
myFeedDeleteDialogFragment.show(fragmentManager, TAG_WINEYFEED_DIALOG)
}
}

override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): MyFeedViewHolder {
val binding =
ItemMyfeedPostBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return MyFeedViewHolder(fragmentManager, binding, likeButtonClick, deleteButtonClick)
val binding = ItemMyfeedPostBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return MyFeedViewHolder(binding, likeButtonClick, showPopupMenu)
}

override fun onBindViewHolder(holder: MyFeedViewHolder, position: Int) {
Expand Down Expand Up @@ -97,6 +87,5 @@ class MyFeedAdapter(
onItemsTheSame = { old, new -> old.feedId == new.feedId },
onContentsTheSame = { old, new -> old == new }
)
private const val TAG_WINEYFEED_DIALOG = "NO_GOAL_DIALOG"
}
}
Loading