feat(creator): 라이브 탭 화면을 연결한다
This commit is contained in:
@@ -55,6 +55,7 @@ import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelAudioConte
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelLiveResponse
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelScheduleResponse
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelSeriesResponse
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.live.CreatorChannelLiveFragment
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.model.CreatorChannelHeaderUiModel
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.model.CreatorChannelScrollState
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.model.CreatorChannelTab
|
||||
@@ -67,7 +68,8 @@ import org.koin.android.ext.android.inject
|
||||
|
||||
class CreatorChannelActivity :
|
||||
BaseActivity<ActivityCreatorChannelBinding>(ActivityCreatorChannelBinding::inflate),
|
||||
CreatorChannelHomeFragment.Host {
|
||||
CreatorChannelHomeFragment.Host,
|
||||
CreatorChannelLiveFragment.Host {
|
||||
|
||||
private val liveViewModel: LiveViewModel by inject()
|
||||
private val myPageViewModel: MyPageViewModel by inject()
|
||||
@@ -262,8 +264,25 @@ class CreatorChannelActivity :
|
||||
}
|
||||
|
||||
private fun setupScrollListener() {
|
||||
binding.nestedScrollView.setOnScrollChangeListener { _, _, scrollY, _, _ ->
|
||||
binding.nestedScrollView.setOnScrollChangeListener { _, _, scrollY, _, oldScrollY ->
|
||||
updateScrollState(scrollY)
|
||||
onCreatorChannelNestedScrollChanged(scrollY, oldScrollY)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onCreatorChannelNestedScrollChanged(scrollY: Int, oldScrollY: Int) {
|
||||
if (binding.viewPager.currentItem != CreatorChannelTab.Live.ordinal) return
|
||||
if (scrollY <= oldScrollY) return
|
||||
|
||||
val contentHeight = binding.nestedScrollView.getChildAt(0)?.height ?: return
|
||||
val threshold = CREATOR_CHANNEL_LIVE_LOAD_MORE_THRESHOLD_DP.dpToPx().toInt()
|
||||
val remainingScroll = calculateCreatorChannelLiveRemainingScroll(
|
||||
contentHeight = contentHeight,
|
||||
viewportHeight = binding.nestedScrollView.height,
|
||||
scrollY = scrollY
|
||||
)
|
||||
if (remainingScroll <= threshold) {
|
||||
findLiveFragment()?.onCreatorChannelLiveScrolledToBottom()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,6 +371,11 @@ class CreatorChannelActivity :
|
||||
}
|
||||
updateOwnerFabVisibility()
|
||||
updateViewPagerHeight()
|
||||
if (position == CreatorChannelTab.Live.ordinal) {
|
||||
binding.viewPager.post {
|
||||
findLiveFragment()?.onCreatorChannelLiveTabSelected()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pageChangeCallback = callback
|
||||
@@ -396,6 +420,11 @@ class CreatorChannelActivity :
|
||||
updateViewPagerHeight()
|
||||
}
|
||||
|
||||
override fun onCreatorChannelLiveContentChanged() {
|
||||
updateViewPagerHeight()
|
||||
postCheckCreatorChannelLiveNeedsMore()
|
||||
}
|
||||
|
||||
private fun setupOwnerFabInsets() {
|
||||
ViewCompat.setOnApplyWindowInsetsListener(binding.ownerFabButton) { _, insets ->
|
||||
val navigationBottomInset = insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom
|
||||
@@ -523,6 +552,15 @@ class CreatorChannelActivity :
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreatorChannelLiveReplayClicked(audioContentId: Long) {
|
||||
startAudioContentDetail(audioContentId)
|
||||
}
|
||||
|
||||
private fun findLiveFragment(): CreatorChannelLiveFragment? {
|
||||
val fragmentTag = "f${CreatorChannelTab.Live.ordinal}"
|
||||
return supportFragmentManager.findFragmentByTag(fragmentTag) as? CreatorChannelLiveFragment
|
||||
}
|
||||
|
||||
private fun ensureLoginAndAdultAuth(isAdult: Boolean, onAuthed: () -> Unit) {
|
||||
if (SharedPreferenceManager.token.isBlank()) {
|
||||
showLoginActivity()
|
||||
@@ -592,6 +630,7 @@ class CreatorChannelActivity :
|
||||
binding.viewPager.post {
|
||||
val recyclerView = binding.viewPager.getChildAt(0) as? RecyclerView ?: return@post
|
||||
val currentPage = recyclerView.layoutManager?.findViewByPosition(binding.viewPager.currentItem) ?: return@post
|
||||
currentPage.minimumHeight = calculateCreatorChannelTabViewportHeight()
|
||||
val widthSpec = MeasureSpec.makeMeasureSpec(binding.viewPager.width, MeasureSpec.EXACTLY)
|
||||
val heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
|
||||
currentPage.measure(widthSpec, heightSpec)
|
||||
@@ -604,6 +643,30 @@ class CreatorChannelActivity :
|
||||
}
|
||||
}
|
||||
|
||||
private fun postCheckCreatorChannelLiveNeedsMore() {
|
||||
binding.nestedScrollView.post {
|
||||
checkCreatorChannelLiveNeedsMore()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkCreatorChannelLiveNeedsMore() {
|
||||
if (binding.viewPager.currentItem != CreatorChannelTab.Live.ordinal) return
|
||||
|
||||
val contentHeight = binding.nestedScrollView.getChildAt(0)?.height ?: return
|
||||
val remainingScroll = calculateCreatorChannelLiveRemainingScroll(
|
||||
contentHeight = contentHeight,
|
||||
viewportHeight = binding.nestedScrollView.height,
|
||||
scrollY = binding.nestedScrollView.scrollY
|
||||
)
|
||||
if (remainingScroll <= 0) {
|
||||
findLiveFragment()?.onCreatorChannelLiveScrolledToBottom()
|
||||
}
|
||||
}
|
||||
|
||||
private fun calculateCreatorChannelTabViewportHeight(): Int {
|
||||
return (binding.nestedScrollView.height - binding.tabLayout.height).coerceAtLeast(0)
|
||||
}
|
||||
|
||||
private fun onScheduleClicked(schedule: CreatorChannelScheduleResponse) {
|
||||
when (schedule.type) {
|
||||
CreatorActivityType.Audio,
|
||||
@@ -620,9 +683,13 @@ class CreatorChannelActivity :
|
||||
}
|
||||
|
||||
private fun onAudioContentClicked(audioContent: CreatorChannelAudioContentResponse) {
|
||||
startAudioContentDetail(audioContent.audioContentId)
|
||||
}
|
||||
|
||||
private fun startAudioContentDetail(audioContentId: Long) {
|
||||
startActivity(
|
||||
Intent(this, AudioContentDetailActivity::class.java).apply {
|
||||
putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, audioContent.audioContentId)
|
||||
putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, audioContentId)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -671,6 +738,7 @@ class CreatorChannelActivity :
|
||||
private const val OWNER_FAB_SPRING_MASS = 1f
|
||||
private const val OWNER_FAB_SPRING_STIFFNESS = 256f
|
||||
private const val OWNER_FAB_SPRING_DAMPING = 24f
|
||||
private const val CREATOR_CHANNEL_LIVE_LOAD_MORE_THRESHOLD_DP = 200
|
||||
|
||||
fun newIntent(context: Context, creatorId: Long): Intent {
|
||||
return Intent(context, CreatorChannelActivity::class.java).apply {
|
||||
@@ -679,3 +747,9 @@ class CreatorChannelActivity :
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun calculateCreatorChannelLiveRemainingScroll(
|
||||
contentHeight: Int,
|
||||
viewportHeight: Int,
|
||||
scrollY: Int
|
||||
): Int = contentHeight - viewportHeight - scrollY
|
||||
|
||||
@@ -3,6 +3,7 @@ package kr.co.vividnext.sodalive.v2.creator.channel
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.live.CreatorChannelLiveFragment
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.model.CreatorChannelTab
|
||||
|
||||
class CreatorChannelPagerAdapter(
|
||||
@@ -17,6 +18,7 @@ class CreatorChannelPagerAdapter(
|
||||
val tab = tabs[position]
|
||||
return when (tab) {
|
||||
CreatorChannelTab.Home -> CreatorChannelHomeFragment.newInstance(creatorId)
|
||||
CreatorChannelTab.Live -> CreatorChannelLiveFragment.newInstance(creatorId)
|
||||
else -> CreatorChannelPlaceholderFragment.newInstance(tab)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user