feat: 메인 라이브
- 라이브 다시 듣기 UI 추가
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package kr.co.vividnext.sodalive.audio_content
|
||||
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import kr.co.vividnext.sodalive.audio_content.all.GetNewContentAllResponse
|
||||
import kr.co.vividnext.sodalive.audio_content.all.by_theme.GetContentByThemeResponse
|
||||
@@ -56,6 +57,13 @@ interface AudioContentApi {
|
||||
@Header("Authorization") authHeader: String
|
||||
): Single<ApiResponse<GetAudioContentListResponse>>
|
||||
|
||||
@GET("/audio-content/replay-live")
|
||||
fun getAudioContentReplayLiveList(
|
||||
@Query("isAdultContentVisible") isAdultContentVisible: Boolean,
|
||||
@Query("contentType") contentType: ContentType,
|
||||
@Header("Authorization") authHeader: String
|
||||
): Flowable<ApiResponse<List<GetAudioContentMainItem>>>
|
||||
|
||||
@GET("/audio-content/theme")
|
||||
fun getAudioContentThemeList(
|
||||
@Header("Authorization") authHeader: String
|
||||
|
||||
@@ -50,6 +50,12 @@ class AudioContentRepository(
|
||||
authHeader = token
|
||||
)
|
||||
|
||||
fun getAudioContentReplayLiveList(token: String) = api.getAudioContentReplayLiveList(
|
||||
isAdultContentVisible = SharedPreferenceManager.isAdultContentVisible,
|
||||
contentType = ContentType.values()[SharedPreferenceManager.contentPreference],
|
||||
authHeader = token
|
||||
)
|
||||
|
||||
fun getAudioContentThemeList(token: String) = api.getAudioContentThemeList(token)
|
||||
|
||||
fun uploadAudioContent(
|
||||
|
||||
@@ -252,7 +252,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
|
||||
viewModel { TermsViewModel(get()) }
|
||||
viewModel { FindPasswordViewModel(get()) }
|
||||
viewModel { MainViewModel(get(), get(), get(), get(), get()) }
|
||||
viewModel { LiveViewModel(get(), get(), get(), get()) }
|
||||
viewModel { LiveViewModel(get(), get(), get(), get(), get()) }
|
||||
viewModel { MyPageViewModel(get(), get()) }
|
||||
viewModel { CanStatusViewModel(get()) }
|
||||
viewModel { CanChargePgViewModel(get()) }
|
||||
|
||||
@@ -15,6 +15,7 @@ import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.zhpan.bannerview.BaseBannerAdapter
|
||||
@@ -22,6 +23,7 @@ import com.zhpan.indicator.enums.IndicatorSlideMode
|
||||
import com.zhpan.indicator.enums.IndicatorStyle
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kr.co.vividnext.sodalive.audio_content.AudioContentPlayService
|
||||
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
|
||||
import kr.co.vividnext.sodalive.audio_content.player.AudioContentPlayerService
|
||||
import kr.co.vividnext.sodalive.base.BaseFragment
|
||||
import kr.co.vividnext.sodalive.common.Constants
|
||||
@@ -34,6 +36,8 @@ import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.CreatorCo
|
||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||
import kr.co.vividnext.sodalive.extensions.moneyFormat
|
||||
import kr.co.vividnext.sodalive.following.FollowingCreatorActivity
|
||||
import kr.co.vividnext.sodalive.home.AudioContentMainItem
|
||||
import kr.co.vividnext.sodalive.home.HomeContentAdapter
|
||||
import kr.co.vividnext.sodalive.live.now.LiveNowAdapter
|
||||
import kr.co.vividnext.sodalive.live.now.all.LiveNowAllActivity
|
||||
import kr.co.vividnext.sodalive.live.recommend.RecommendLiveAdapter
|
||||
@@ -162,6 +166,7 @@ class LiveFragment : BaseFragment<FragmentLiveBinding>(FragmentLiveBinding::infl
|
||||
setupRecommendLive()
|
||||
setupRecommendChannel()
|
||||
setupLatestFinishedLiveChannel()
|
||||
setupLiveReplay()
|
||||
setupLiveReservation()
|
||||
}
|
||||
|
||||
@@ -403,6 +408,83 @@ class LiveFragment : BaseFragment<FragmentLiveBinding>(FragmentLiveBinding::infl
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupLiveReplay() {
|
||||
val adapter = HomeContentAdapter {
|
||||
if (SharedPreferenceManager.token.isNotBlank()) {
|
||||
startActivity(
|
||||
Intent(requireContext(), AudioContentDetailActivity::class.java).apply {
|
||||
putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, it)
|
||||
}
|
||||
)
|
||||
} else {
|
||||
(requireActivity() as MainActivity).showLoginActivity()
|
||||
}
|
||||
}
|
||||
|
||||
val rvContent = binding.rvReplayLive
|
||||
rvContent.layoutManager = GridLayoutManager(context, 2, RecyclerView.HORIZONTAL, false)
|
||||
rvContent.addItemDecoration(object : RecyclerView.ItemDecoration() {
|
||||
override fun getItemOffsets(
|
||||
outRect: Rect,
|
||||
view: View,
|
||||
parent: RecyclerView,
|
||||
state: RecyclerView.State
|
||||
) {
|
||||
super.getItemOffsets(outRect, view, parent, state)
|
||||
outRect.top = 8f.dpToPx().toInt()
|
||||
outRect.bottom = 8f.dpToPx().toInt()
|
||||
|
||||
val position = parent.getChildAdapterPosition(view)
|
||||
|
||||
if (position == 0 || position == 1) {
|
||||
outRect.left = 0f.dpToPx().toInt()
|
||||
} else {
|
||||
outRect.left = 8f.dpToPx().toInt()
|
||||
}
|
||||
|
||||
outRect.right = 8f.dpToPx().toInt()
|
||||
}
|
||||
})
|
||||
rvContent.adapter = adapter
|
||||
|
||||
adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
||||
override fun onChanged() {
|
||||
if (adapter.itemCount < 2) {
|
||||
// 1개일 땐 단일 행
|
||||
rvContent.layoutManager =
|
||||
LinearLayoutManager(rvContent.context, RecyclerView.HORIZONTAL, false)
|
||||
} else {
|
||||
// 2개 이상일 땐 2행 바둑판
|
||||
rvContent.layoutManager =
|
||||
GridLayoutManager(rvContent.context, 2, RecyclerView.HORIZONTAL, false)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
viewModel.replayContentListLiveData.observe(viewLifecycleOwner) { contentList ->
|
||||
if (contentList.isNotEmpty()) {
|
||||
adapter.addItems(
|
||||
contentList.map {
|
||||
AudioContentMainItem(
|
||||
contentId = it.contentId,
|
||||
creatorId = it.creatorId,
|
||||
title = it.title,
|
||||
coverImageUrl = it.coverImageUrl,
|
||||
creatorNickname = it.creatorNickname,
|
||||
isPointAvailable = it.isPointAvailable
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
binding.llReplayLive.visibility = View.VISIBLE
|
||||
binding.rvReplayLive.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding.llReplayLive.visibility = View.GONE
|
||||
binding.rvReplayLive.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private fun setupLiveNow() {
|
||||
binding
|
||||
|
||||
@@ -2,6 +2,7 @@ package kr.co.vividnext.sodalive.live
|
||||
|
||||
import androidx.annotation.Keep
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentMainItem
|
||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||
import kr.co.vividnext.sodalive.live.recommend.GetRecommendLiveResponse
|
||||
import kr.co.vividnext.sodalive.settings.event.GetEventResponse
|
||||
@@ -17,5 +18,7 @@ data class LiveSummary(
|
||||
@SerializedName("recommendLive")
|
||||
val recommendLive: ApiResponse<List<GetRecommendLiveResponse>>,
|
||||
@SerializedName("latestFinishedLive")
|
||||
val latestFinishedLive: ApiResponse<List<GetLatestFinishedLiveResponse>>
|
||||
val latestFinishedLive: ApiResponse<List<GetLatestFinishedLiveResponse>>,
|
||||
@SerializedName("replayLive")
|
||||
val replayLive: ApiResponse<List<GetAudioContentMainItem>>
|
||||
)
|
||||
|
||||
@@ -6,10 +6,13 @@ import com.orhanobut.logger.Logger
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import kr.co.vividnext.sodalive.audio_content.AudioContentRepository
|
||||
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentMainItem
|
||||
import kr.co.vividnext.sodalive.base.BaseViewModel
|
||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.CreatorCommunityRepository
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostListResponse
|
||||
import kr.co.vividnext.sodalive.home.AudioContentMainItem
|
||||
import kr.co.vividnext.sodalive.live.recommend.GetRecommendLiveResponse
|
||||
import kr.co.vividnext.sodalive.live.recommend.LiveRecommendRepository
|
||||
import kr.co.vividnext.sodalive.live.recommend_channel.GetRecommendChannelResponse
|
||||
@@ -26,6 +29,7 @@ import kr.co.vividnext.sodalive.settings.event.EventRepository
|
||||
class LiveViewModel(
|
||||
private val repository: LiveRepository,
|
||||
private val eventRepository: EventRepository,
|
||||
private val contentRepository: AudioContentRepository,
|
||||
private val liveRecommendRepository: LiveRecommendRepository,
|
||||
private val creatorCommunityRepository: CreatorCommunityRepository
|
||||
) : BaseViewModel() {
|
||||
@@ -61,6 +65,10 @@ class LiveViewModel(
|
||||
val communityPostItemLiveData: LiveData<List<GetCommunityPostListResponse>>
|
||||
get() = _communityPostItemLiveData
|
||||
|
||||
private var _replayContentListLiveData = MutableLiveData<List<GetAudioContentMainItem>>()
|
||||
val replayContentListLiveData: LiveData<List<GetAudioContentMainItem>>
|
||||
get() = _replayContentListLiveData
|
||||
|
||||
private val _latestFinishedLiveListLiveData =
|
||||
MutableLiveData<List<GetLatestFinishedLiveResponse>>()
|
||||
val latestFinishedLiveListLiveData: LiveData<List<GetLatestFinishedLiveResponse>>
|
||||
@@ -166,6 +174,10 @@ class LiveViewModel(
|
||||
token = "Bearer ${SharedPreferenceManager.token}"
|
||||
)
|
||||
|
||||
val replayLive = contentRepository.getAudioContentReplayLiveList(
|
||||
token = "Bearer ${SharedPreferenceManager.token}"
|
||||
)
|
||||
|
||||
_isLoading.postValue(true)
|
||||
|
||||
compositeDisposable.add(
|
||||
@@ -174,8 +186,18 @@ class LiveViewModel(
|
||||
liveReservation,
|
||||
event,
|
||||
recommendLive,
|
||||
latestFinishedLive
|
||||
) { t1, t2, t3, t4, t5 -> LiveSummary(t1, t2, t3, t4, t5) }
|
||||
latestFinishedLive,
|
||||
replayLive
|
||||
) { t1, t2, t3, t4, t5, t6 ->
|
||||
LiveSummary(
|
||||
liveNow = t1,
|
||||
liveReservation = t2,
|
||||
event = t3,
|
||||
recommendLive = t4,
|
||||
latestFinishedLive = t5,
|
||||
replayLive = t6
|
||||
)
|
||||
}
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(
|
||||
{
|
||||
@@ -245,6 +267,12 @@ class LiveViewModel(
|
||||
_latestFinishedLiveListLiveData.postValue(emptyList())
|
||||
}
|
||||
|
||||
val replayLive = it.replayLive
|
||||
if (replayLive.success && replayLive.data != null) {
|
||||
val data = replayLive.data!!
|
||||
_replayContentListLiveData.postValue(data)
|
||||
}
|
||||
|
||||
_isLoading.postValue(false)
|
||||
},
|
||||
{
|
||||
|
||||
@@ -134,6 +134,38 @@
|
||||
android:clipToPadding="false"
|
||||
android:paddingHorizontal="24dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_replay_live"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/pretendard_bold"
|
||||
android:text="라이브 "
|
||||
android:textColor="@color/color_3bb9f1"
|
||||
android:textSize="26sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/pretendard_bold"
|
||||
android:text="다시 듣기"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="26sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_replay_live"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="48dp"
|
||||
android:clipToPadding="false"
|
||||
android:paddingHorizontal="24dp" />
|
||||
|
||||
<include
|
||||
android:id="@+id/layout_recommend_channel"
|
||||
|
||||
Reference in New Issue
Block a user