From 304e6e166ac864e4d3e460b1161ababa95484022 Mon Sep 17 00:00:00 2001 From: klaus Date: Tue, 18 Feb 2025 02:08:06 +0900 Subject: [PATCH] =?UTF-8?q?=EC=BD=98=ED=85=90=EC=B8=A0=20=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EB=AC=B4=EB=A3=8C=20=ED=83=AD=20-=20=EC=B1=84?= =?UTF-8?q?=EB=84=90=EB=B3=84=20=EC=B6=94=EC=B2=9C=20=EB=AC=B4=EB=A3=8C=20?= =?UTF-8?q?=EC=BD=98=ED=85=90=EC=B8=A0=20UI=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/audio_content/AudioContentApi.kt | 6 + .../free/AudioContentMainTabFreeFragment.kt | 106 +++++++++++++++++- .../free/AudioContentMainTabFreeRepository.kt | 5 + .../free/AudioContentMainTabFreeViewModel.kt | 48 ++++++++ .../free/GetContentMainTabLiveFreeResponse.kt | 6 + .../fragment_audio_content_main_tab_free.xml | 68 ++++++++++- 6 files changed, 237 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/AudioContentApi.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/AudioContentApi.kt index 6c9a6ef..bf92495 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/AudioContentApi.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/AudioContentApi.kt @@ -368,4 +368,10 @@ interface AudioContentApi { @Query("size") size: Int, @Header("Authorization") authHeader: String ): Single>> + + @GET("/v2/audio-content/main/free/popular-content-by-creator") + fun getPopularFreeContentByCreator( + @Query("creatorId") creatorId: Long, + @Header("Authorization") authHeader: String + ): Single>> } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/free/AudioContentMainTabFreeFragment.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/free/AudioContentMainTabFreeFragment.kt index e62dbd7..a172b36 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/free/AudioContentMainTabFreeFragment.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/free/AudioContentMainTabFreeFragment.kt @@ -10,6 +10,7 @@ import android.widget.Toast import androidx.annotation.OptIn 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 @@ -23,11 +24,14 @@ import kr.co.vividnext.sodalive.audio_content.main.AudioContentMainContentAdapte import kr.co.vividnext.sodalive.audio_content.main.banner.AudioContentMainBannerAdapter import kr.co.vividnext.sodalive.audio_content.main.new_content.AudioContentMainNewContentThemeAdapter import kr.co.vividnext.sodalive.audio_content.main.v2.AudioContentMainContentCurationAdapter +import kr.co.vividnext.sodalive.audio_content.main.v2.ContentRankCreatorAdapter +import kr.co.vividnext.sodalive.audio_content.main.v2.PopularContentByCreatorAdapter import kr.co.vividnext.sodalive.audio_content.main.v2.free.introduce_creator.IntroduceCreatorActivity import kr.co.vividnext.sodalive.audio_content.main.v2.series.new_series.AudioContentMainNewSeriesAdapter import kr.co.vividnext.sodalive.audio_content.series.detail.SeriesDetailActivity import kr.co.vividnext.sodalive.base.BaseFragment import kr.co.vividnext.sodalive.common.Constants +import kr.co.vividnext.sodalive.common.GridSpacingItemDecoration import kr.co.vividnext.sodalive.common.LoadingDialog import kr.co.vividnext.sodalive.databinding.FragmentAudioContentMainTabFreeBinding import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity @@ -49,6 +53,8 @@ class AudioContentMainTabFreeFragment : BaseFragment { + outRect.left = 0 + outRect.right = 11f.dpToPx().toInt() + } + + contentRankCreatorAdapter.itemCount - 1 -> { + outRect.left = 11f.dpToPx().toInt() + outRect.right = 0 + } + + else -> { + outRect.left = 11f.dpToPx().toInt() + outRect.right = 11f.dpToPx().toInt() + } + } + } + }) + + binding.rvRankingCreator.adapter = contentRankCreatorAdapter + + viewModel.contentCreatorListLiveData.observe(viewLifecycleOwner) { + contentRankCreatorAdapter.addItems(it) + if (contentRankCreatorAdapter.itemCount <= 0 && it.isEmpty()) { + binding.llCreatorContentRanking.visibility = View.GONE + } else { + binding.llCreatorContentRanking.visibility = View.VISIBLE + } + } + } + + private fun setupPopularContentByCreator() { + popularContentByCreatorAdapter = PopularContentByCreatorAdapter( + itemWidth = ((screenWidth - 13.3f.dpToPx() * 3) / 2).toInt(), + onClickItem = { contentId -> + startActivity( + Intent(requireActivity(), AudioContentDetailActivity::class.java).apply { + putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, contentId) + } + ) + }, + onClickCreator = { creatorId -> + startActivity( + Intent(requireActivity(), UserProfileActivity::class.java).apply { + putExtra(Constants.EXTRA_USER_ID, creatorId) + } + ) + } + ) + + val recyclerView = binding.rvRankingPlayCount + recyclerView.layoutManager = GridLayoutManager(requireContext(), 2) + recyclerView.addItemDecoration( + GridSpacingItemDecoration( + 2, + 13.3f.dpToPx().toInt(), + false + ) + ) + + recyclerView.adapter = popularContentByCreatorAdapter + + viewModel.playCountRankContentListLiveData.observe(viewLifecycleOwner) { + if (it.isNotEmpty()) { + binding.llNoItems.visibility = View.GONE + recyclerView.visibility = View.VISIBLE + popularContentByCreatorAdapter.addItems(it) + } else { + binding.llNoItems.visibility = View.VISIBLE + recyclerView.visibility = View.GONE + } + } + } + private fun setupCuration() { curationAdapter = AudioContentMainContentCurationAdapter( onClickItem = { diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/free/AudioContentMainTabFreeRepository.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/free/AudioContentMainTabFreeRepository.kt index c4d00ab..44b3c15 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/free/AudioContentMainTabFreeRepository.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/free/AudioContentMainTabFreeRepository.kt @@ -21,4 +21,9 @@ class AudioContentMainTabFreeRepository(private val api: AudioContentApi) { size = size, authHeader = token ) + + fun getPopularContentByCreator( + creatorId: Long, + token: String + ) = api.getPopularFreeContentByCreator(creatorId, authHeader = token) } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/free/AudioContentMainTabFreeViewModel.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/free/AudioContentMainTabFreeViewModel.kt index a7b0292..8a733de 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/free/AudioContentMainTabFreeViewModel.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/free/AudioContentMainTabFreeViewModel.kt @@ -5,8 +5,10 @@ import androidx.lifecycle.MutableLiveData import com.orhanobut.logger.Logger import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.schedulers.Schedulers +import kr.co.vividnext.sodalive.audio_content.main.ContentCreatorResponse import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentBannerResponse import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentMainItem +import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRankingItem import kr.co.vividnext.sodalive.audio_content.main.v2.GetContentCurationResponse import kr.co.vividnext.sodalive.audio_content.main.v2.series.GetRecommendSeriesListResponse import kr.co.vividnext.sodalive.base.BaseViewModel @@ -45,6 +47,15 @@ class AudioContentMainTabFreeViewModel( val themeListLiveData: LiveData> get() = _themeListLiveData + private val _contentCreatorListLiveData = MutableLiveData>() + val contentCreatorListLiveData: LiveData> + get() = _contentCreatorListLiveData + + private val _playCountRankContentListLiveData = + MutableLiveData>() + val playCountRankContentListLiveData: LiveData> + get() = _playCountRankContentListLiveData + private var _curationListLiveData = MutableLiveData>() val curationListLiveData: LiveData> get() = _curationListLiveData @@ -71,6 +82,10 @@ class AudioContentMainTabFreeViewModel( val themeList = listOf("전체").union(data.themeList).toList() _themeListLiveData.value = themeList + _contentCreatorListLiveData.value = data.creatorList + _playCountRankContentListLiveData.value = + data.playCountRankContentList + _curationListLiveData.value = data.curationList } else { if (it.message != null) { @@ -130,4 +145,37 @@ class AudioContentMainTabFreeViewModel( ) ) } + + fun getPopularContentByCreator(creatorId: Long) { + _isLoading.value = true + compositeDisposable.add( + repository.getPopularContentByCreator( + creatorId = creatorId, + token = "Bearer ${SharedPreferenceManager.token}" + ) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + { + _isLoading.value = false + if (it.success && it.data != null) { + _playCountRankContentListLiveData.value = it.data!! + } else { + if (it.message != null) { + _toastLiveData.postValue(it.message) + } else { + _toastLiveData.postValue( + "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요." + ) + } + } + }, + { + _isLoading.value = false + it.message?.let { message -> Logger.e(message) } + _toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.") + } + ) + ) + } } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/free/GetContentMainTabLiveFreeResponse.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/free/GetContentMainTabLiveFreeResponse.kt index 4234027..6f17140 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/free/GetContentMainTabLiveFreeResponse.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/free/GetContentMainTabLiveFreeResponse.kt @@ -2,8 +2,10 @@ package kr.co.vividnext.sodalive.audio_content.main.v2.free import androidx.annotation.Keep import com.google.gson.annotations.SerializedName +import kr.co.vividnext.sodalive.audio_content.main.ContentCreatorResponse import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentBannerResponse import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentMainItem +import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRankingItem import kr.co.vividnext.sodalive.audio_content.main.v2.GetContentCurationResponse import kr.co.vividnext.sodalive.audio_content.main.v2.series.GetRecommendSeriesListResponse @@ -19,6 +21,10 @@ data class GetContentMainTabLiveFreeResponse( val themeList: List, @SerializedName("newFreeContentList") val newFreeContentList: List, + @SerializedName("creatorList") + val creatorList: List, + @SerializedName("playCountRankContentList") + val playCountRankContentList: List, @SerializedName("curationList") val curationList: List ) diff --git a/app/src/main/res/layout/fragment_audio_content_main_tab_free.xml b/app/src/main/res/layout/fragment_audio_content_main_tab_free.xml index 398c53b..d1ef90c 100644 --- a/app/src/main/res/layout/fragment_audio_content_main_tab_free.xml +++ b/app/src/main/res/layout/fragment_audio_content_main_tab_free.xml @@ -1,5 +1,6 @@ @@ -68,7 +69,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:orientation="vertical"> + android:orientation="vertical" + android:visibility="gone"> + + + + + + + + + + + + + + + +