feat(creator): 채널 후원 버튼을 연결한다
This commit is contained in:
@@ -3,6 +3,7 @@ package kr.co.vividnext.sodalive.v2.creator.channel
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.View.MeasureSpec
|
||||
import android.widget.LinearLayout
|
||||
@@ -26,6 +27,7 @@ import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||
import kr.co.vividnext.sodalive.extensions.loadUrl
|
||||
import kr.co.vividnext.sodalive.extensions.moneyFormat
|
||||
import kr.co.vividnext.sodalive.live.room.detail.LiveRoomDetailFragment
|
||||
import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationDialog
|
||||
import kr.co.vividnext.sodalive.report.ProfileReportDialog
|
||||
import kr.co.vividnext.sodalive.report.UserReportDialog
|
||||
import kr.co.vividnext.sodalive.v2.common.CreatorActivityType
|
||||
@@ -302,6 +304,23 @@ class CreatorChannelActivity :
|
||||
updateViewPagerHeight()
|
||||
}
|
||||
|
||||
override fun onCreatorChannelDonationClicked() {
|
||||
val header = currentHeader ?: return
|
||||
if (header.isOwner) return
|
||||
|
||||
val dialog = LiveRoomDonationDialog(
|
||||
this,
|
||||
LayoutInflater.from(this),
|
||||
isLiveDonation = true,
|
||||
messageMaxLength = 100,
|
||||
secretToggleLabelResId = R.string.screen_user_profile_channel_donation_secret,
|
||||
applySecretMissionMessageHint = false
|
||||
) { can, message, isSecret ->
|
||||
homeActionDelegate?.postChannelDonation(can = can, isSecret = isSecret, message = message)
|
||||
}
|
||||
dialog.show(screenWidth - 26.7f.dpToPx().toInt())
|
||||
}
|
||||
|
||||
private fun updateViewPagerHeight() {
|
||||
binding.viewPager.post {
|
||||
val recyclerView = binding.viewPager.getChildAt(0) as? RecyclerView ?: return@post
|
||||
|
||||
@@ -18,7 +18,11 @@ class CreatorChannelHomeFragment : BaseFragment<FragmentCreatorChannelHomeBindin
|
||||
) {
|
||||
|
||||
private val viewModel: CreatorChannelHomeViewModel by viewModel()
|
||||
private val sectionAdapter = CreatorChannelHomeSectionAdapter(::onScheduleClicked, ::onAudioContentClicked)
|
||||
private val sectionAdapter = CreatorChannelHomeSectionAdapter(
|
||||
onScheduleClick = ::onScheduleClicked,
|
||||
onAudioContentClick = ::onAudioContentClicked,
|
||||
onDonationClick = ::onDonationClicked
|
||||
)
|
||||
private val creatorId: Long by lazy { arguments?.getLong(ARG_CREATOR_ID) ?: 0L }
|
||||
private val host: Host
|
||||
get() = requireActivity() as Host
|
||||
@@ -49,6 +53,10 @@ class CreatorChannelHomeFragment : BaseFragment<FragmentCreatorChannelHomeBindin
|
||||
override fun reportProfile() {
|
||||
viewModel.reportProfile()
|
||||
}
|
||||
|
||||
override fun postChannelDonation(can: Int, isSecret: Boolean, message: String) {
|
||||
viewModel.postChannelDonation(can = can, isSecret = isSecret, message = message)
|
||||
}
|
||||
}
|
||||
)
|
||||
if (creatorId > 0L) {
|
||||
@@ -97,6 +105,10 @@ class CreatorChannelHomeFragment : BaseFragment<FragmentCreatorChannelHomeBindin
|
||||
host.onCreatorChannelAudioContentClicked(audioContent)
|
||||
}
|
||||
|
||||
private fun onDonationClicked() {
|
||||
host.onCreatorChannelDonationClicked()
|
||||
}
|
||||
|
||||
interface Host {
|
||||
fun onCreatorChannelHeaderChanged(header: CreatorChannelHeaderUiModel)
|
||||
fun onCreatorChannelFollowProgressChanged(inProgress: Boolean)
|
||||
@@ -105,6 +117,7 @@ class CreatorChannelHomeFragment : BaseFragment<FragmentCreatorChannelHomeBindin
|
||||
fun onCreatorChannelAudioContentClicked(audioContent: CreatorChannelAudioContentResponse)
|
||||
fun onCreatorChannelHomeActionDelegateReady(delegate: HomeActionDelegate?)
|
||||
fun onCreatorChannelHomeContentChanged()
|
||||
fun onCreatorChannelDonationClicked()
|
||||
}
|
||||
|
||||
interface HomeActionDelegate {
|
||||
@@ -113,6 +126,7 @@ class CreatorChannelHomeFragment : BaseFragment<FragmentCreatorChannelHomeBindin
|
||||
fun blockUser()
|
||||
fun reportUser(reason: String)
|
||||
fun reportProfile()
|
||||
fun postChannelDonation(can: Int, isSecret: Boolean, message: String)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -17,6 +17,7 @@ import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import coil.transform.CircleCropTransformation
|
||||
import kr.co.vividnext.sodalive.common.formatUtcRelativeTimeText
|
||||
import kr.co.vividnext.sodalive.common.image.BlurTransformation
|
||||
import kr.co.vividnext.sodalive.extensions.loadUrl
|
||||
import kr.co.vividnext.sodalive.extensions.moneyFormat
|
||||
@@ -36,7 +37,8 @@ import kotlin.math.roundToInt
|
||||
class CreatorChannelHomeSectionAdapter(
|
||||
private val onScheduleClick: (CreatorChannelScheduleResponse) -> Unit = {},
|
||||
private val onAudioContentClick: (CreatorChannelAudioContentResponse) -> Unit = {},
|
||||
private val onSeriesClick: (CreatorChannelSeriesResponse) -> Unit = {}
|
||||
private val onSeriesClick: (CreatorChannelSeriesResponse) -> Unit = {},
|
||||
private val onDonationClick: () -> Unit = {}
|
||||
) : RecyclerView.Adapter<CreatorChannelHomeSectionAdapter.SectionViewHolder>() {
|
||||
|
||||
private var items: List<CreatorChannelHomeSection> = emptyList()
|
||||
@@ -50,7 +52,7 @@ class CreatorChannelHomeSectionAdapter(
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SectionViewHolder {
|
||||
val view = LayoutInflater.from(parent.context).inflate(viewType, parent, false)
|
||||
return SectionViewHolder(view, onScheduleClick, onAudioContentClick, onSeriesClick)
|
||||
return SectionViewHolder(view, onScheduleClick, onAudioContentClick, onSeriesClick, onDonationClick)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: SectionViewHolder, position: Int) {
|
||||
@@ -63,7 +65,8 @@ class CreatorChannelHomeSectionAdapter(
|
||||
view: View,
|
||||
private val onScheduleClick: (CreatorChannelScheduleResponse) -> Unit,
|
||||
private val onAudioContentClick: (CreatorChannelAudioContentResponse) -> Unit,
|
||||
private val onSeriesClick: (CreatorChannelSeriesResponse) -> Unit
|
||||
private val onSeriesClick: (CreatorChannelSeriesResponse) -> Unit,
|
||||
private val onDonationClick: () -> Unit
|
||||
) : RecyclerView.ViewHolder(view) {
|
||||
private val title: TextView? = view.findViewById(R.id.tv_section_title)
|
||||
private val currentLiveTitle: TextView? = view.findViewById(R.id.tv_current_live_title)
|
||||
@@ -75,7 +78,12 @@ class CreatorChannelHomeSectionAdapter(
|
||||
private val latestAudioPointTag: ImageView? = view.findViewById(R.id.iv_latest_audio_point_tag)
|
||||
private val latestAudioTitle: TextView? = view.findViewById(R.id.tv_latest_audio_title)
|
||||
private val latestAudioDuration: TextView? = view.findViewById(R.id.tv_latest_audio_duration)
|
||||
private val donationItemsScrollView: View? = view.findViewById(R.id.hsv_donation_items)
|
||||
private val donationItems: LinearLayout? = view.findViewById(R.id.ll_donation_items)
|
||||
private val donationEmpty: View? = view.findViewById(R.id.layout_donation_empty)
|
||||
private val donationEmptyButton: View? = view.findViewById(R.id.layout_donation_empty_button)
|
||||
private val donationButton: View? = view.findViewById(R.id.layout_donation_button)
|
||||
private val donationEmptyTitle: TextView? = view.findViewById(R.id.tv_donation_empty_title)
|
||||
private val noticeItems: LinearLayout? = view.findViewById(R.id.ll_notice_items)
|
||||
private val scheduleTimeline: LinearLayout? = view.findViewById(R.id.ll_schedule_timeline)
|
||||
private val scheduleItems: LinearLayout? = view.findViewById(R.id.ll_schedule_items)
|
||||
@@ -107,6 +115,7 @@ class CreatorChannelHomeSectionAdapter(
|
||||
}
|
||||
|
||||
fun bind(item: CreatorChannelHomeSection) {
|
||||
itemView.setOnClickListener(null)
|
||||
title?.setText(item.titleResId)
|
||||
donationItems?.removeAllViews()
|
||||
noticeItems?.removeAllViews()
|
||||
@@ -144,9 +153,26 @@ class CreatorChannelHomeSectionAdapter(
|
||||
latestAudioDuration?.text = item.audioContent.duration.orEmpty()
|
||||
latestAudioPointTag?.isVisible = item.audioContent.isPointAvailable
|
||||
latestAudioThumbnail?.loadUrl(item.audioContent.imageUrl)
|
||||
itemView.setOnClickListener { onAudioContentClick(item.audioContent) }
|
||||
}
|
||||
|
||||
private fun bindDonations(item: CreatorChannelHomeSection.Donations) {
|
||||
donationItems?.removeAllViews()
|
||||
donationItemsScrollView?.isVisible = item.donations.isNotEmpty()
|
||||
donationEmpty?.isVisible = item.donations.isEmpty()
|
||||
val isDonationButtonVisible = item.donations.isNotEmpty() && !item.isOwner
|
||||
val isDonationEmptyButtonVisible = !item.isOwner
|
||||
donationButton?.isVisible = isDonationButtonVisible
|
||||
donationEmptyButton?.isVisible = isDonationEmptyButtonVisible
|
||||
donationEmptyTitle?.setText(
|
||||
if (item.isOwner) {
|
||||
R.string.creator_channel_donation_empty_owner_title
|
||||
} else {
|
||||
R.string.creator_channel_donation_empty_title
|
||||
}
|
||||
)
|
||||
donationButton?.setOnClickListener(if (isDonationButtonVisible) View.OnClickListener { onDonationClick() } else null)
|
||||
donationEmptyButton?.setOnClickListener(if (isDonationEmptyButtonVisible) View.OnClickListener { onDonationClick() } else null)
|
||||
val visibleDonations = item.donations.take(MAX_DONATION_ITEM_COUNT)
|
||||
visibleDonations.forEachIndexed { index, donation ->
|
||||
val row = LayoutInflater.from(itemView.context).inflate(
|
||||
@@ -167,7 +193,8 @@ class CreatorChannelHomeSectionAdapter(
|
||||
transformations(CircleCropTransformation())
|
||||
}
|
||||
row.findViewById<TextView>(R.id.tv_donation_nickname).text = donation.nickname
|
||||
row.findViewById<TextView>(R.id.tv_donation_created_at).text = donation.createdAtUtc
|
||||
row.findViewById<TextView>(R.id.tv_donation_created_at).text =
|
||||
formatUtcRelativeTimeText(itemView.context, donation.createdAtUtc)
|
||||
row.findViewById<TextView>(R.id.tv_donation_can).text = itemView.context.getString(
|
||||
R.string.creator_channel_donation_can_format,
|
||||
donation.can.moneyFormat()
|
||||
@@ -198,7 +225,8 @@ class CreatorChannelHomeSectionAdapter(
|
||||
transformations(CircleCropTransformation())
|
||||
}
|
||||
row.findViewById<TextView>(R.id.tv_notice_creator_name).text = notice.creatorNickname
|
||||
row.findViewById<TextView>(R.id.tv_notice_created_at).text = notice.dateUtc
|
||||
row.findViewById<TextView>(R.id.tv_notice_created_at).text =
|
||||
formatUtcRelativeTimeText(itemView.context, notice.dateUtc)
|
||||
row.findViewById<TextView>(R.id.tv_notice_content).text = notice.content
|
||||
val noticeThumbnail = row.findViewById<ImageView>(R.id.iv_notice_thumbnail)
|
||||
noticeThumbnail.isVisible = !notice.imageUrl.isNullOrBlank()
|
||||
@@ -383,7 +411,7 @@ class CreatorChannelHomeSectionAdapter(
|
||||
postId = postId.toString(),
|
||||
bodyText = content,
|
||||
keywordText = "",
|
||||
createdAtText = dateUtc,
|
||||
createdAtText = formatUtcRelativeTimeText(itemView.context, dateUtc),
|
||||
commentCount = commentCount,
|
||||
likeCount = likeCount,
|
||||
imageUrl = imageUrl,
|
||||
|
||||
Reference in New Issue
Block a user