From a375839506a9d95922f4bb851b2d253b6d146426 Mon Sep 17 00:00:00 2001 From: klaus Date: Thu, 13 Feb 2025 19:09:10 +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-=20=EC=84=A0=ED=83=9D=EB=90=9C=20=ED=83=AD?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=ED=83=AD=EC=9D=B4=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A1=A4=20=EB=90=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/audio_content/AudioContentApi.kt | 6 + .../AudioContentMainNewContentThemeAdapter.kt | 4 +- .../AudioContentMainContentCurationAdapter.kt | 97 +++++ .../main/v2/GetContentCurationResponse.kt | 11 + .../alarm/AudioContentMainTabAlarmFragment.kt | 385 ++++++++++++++++++ .../AudioContentMainTabAlarmRepository.kt | 7 + .../AudioContentMainTabAlarmViewModel.kt | 84 ++++ .../alarm/GetContentMainTabAlarmResponse.kt | 25 ++ .../AudioContentMainTabContentViewModel.kt | 1 - ...oContentMainRecommendSeriesGenreAdapter.kt | 1 - .../java/kr/co/vividnext/sodalive/di/AppDI.kt | 4 + .../fragment_audio_content_main_tab_alarm.xml | 69 ++++ 12 files changed, 690 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/AudioContentMainContentCurationAdapter.kt create mode 100644 app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/GetContentCurationResponse.kt create mode 100644 app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/alarm/AudioContentMainTabAlarmRepository.kt create mode 100644 app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/alarm/AudioContentMainTabAlarmViewModel.kt create mode 100644 app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/alarm/GetContentMainTabAlarmResponse.kt 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 559306f..8a5ccc4 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 @@ -17,6 +17,7 @@ import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentMainItem import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRanking import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRankingItem import kr.co.vividnext.sodalive.audio_content.main.v2.GetPopularContentByCreatorResponse +import kr.co.vividnext.sodalive.audio_content.main.v2.alarm.GetContentMainTabAlarmResponse import kr.co.vividnext.sodalive.audio_content.main.v2.content.GetContentMainTabContentResponse import kr.co.vividnext.sodalive.audio_content.main.v2.home.GetContentMainTabHomeResponse import kr.co.vividnext.sodalive.audio_content.main.v2.series.GetContentMainTabSeriesResponse @@ -282,4 +283,9 @@ interface AudioContentApi { @Query("creatorId") creatorId: Long, @Header("Authorization") authHeader: String ): Single> + + @GET("/v2/audio-content/main/alarm") + fun getContentMainAlarm( + @Header("Authorization") authHeader: String + ): Single> } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/new_content/AudioContentMainNewContentThemeAdapter.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/new_content/AudioContentMainNewContentThemeAdapter.kt index 3e80c47..c0aa457 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/new_content/AudioContentMainNewContentThemeAdapter.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/new_content/AudioContentMainNewContentThemeAdapter.kt @@ -48,8 +48,8 @@ class AudioContentMainNewContentThemeAdapter( } @SuppressLint("NotifyDataSetChanged") - fun addItems(themeList: List) { - this.selectedTheme = "" + fun addItems(themeList: List, selectedTheme: String = "") { + this.selectedTheme = selectedTheme this.themeList.clear() this.themeList.addAll(themeList) notifyDataSetChanged() diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/AudioContentMainContentCurationAdapter.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/AudioContentMainContentCurationAdapter.kt new file mode 100644 index 0000000..bac2c9d --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/AudioContentMainContentCurationAdapter.kt @@ -0,0 +1,97 @@ +package kr.co.vividnext.sodalive.audio_content.main.v2 + +import android.annotation.SuppressLint +import android.content.Context +import android.graphics.Rect +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import kr.co.vividnext.sodalive.audio_content.main.AudioContentMainContentAdapter +import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentMainItem +import kr.co.vividnext.sodalive.databinding.ItemAudioContentMainCurationBinding +import kr.co.vividnext.sodalive.extensions.dpToPx + +class AudioContentMainContentCurationAdapter( + private val onClickItem: (Long) -> Unit, + private val onClickCreator: (Long) -> Unit +) : RecyclerView.Adapter() { + + private val items = mutableListOf() + + inner class ViewHolder( + private val context: Context, + private val binding: ItemAudioContentMainCurationBinding + ) : RecyclerView.ViewHolder(binding.root) { + fun bind(item: GetContentCurationResponse) { + binding.tvTitle.text = item.title + binding.ivAll.visibility = View.GONE + binding.tvDesc.visibility = View.GONE + setAudioContentList(item.items) + } + + private fun setAudioContentList(audioContents: List) { + val adapter = AudioContentMainContentAdapter(onClickItem, onClickCreator) + + binding.rvCuration.layoutManager = LinearLayoutManager( + context, + LinearLayoutManager.HORIZONTAL, + false + ) + if (binding.rvCuration.itemDecorationCount == 0) { + binding.rvCuration.addItemDecoration(object : RecyclerView.ItemDecoration() { + override fun getItemOffsets( + outRect: Rect, + view: View, + parent: RecyclerView, + state: RecyclerView.State + ) { + super.getItemOffsets(outRect, view, parent, state) + + when (parent.getChildAdapterPosition(view)) { + 0 -> { + outRect.left = 0 + outRect.right = 6.7f.dpToPx().toInt() + } + + adapter.itemCount - 1 -> { + outRect.left = 6.7f.dpToPx().toInt() + outRect.right = 0 + } + + else -> { + outRect.left = 6.7f.dpToPx().toInt() + outRect.right = 6.7f.dpToPx().toInt() + } + } + } + }) + } + binding.rvCuration.adapter = adapter + adapter.addItems(audioContents) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder( + parent.context, + ItemAudioContentMainCurationBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) + ) + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.bind(items[position]) + } + + override fun getItemCount() = items.size + + @SuppressLint("NotifyDataSetChanged") + fun addItems(items: List) { + this.items.clear() + this.items.addAll(items) + notifyDataSetChanged() + } +} diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/GetContentCurationResponse.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/GetContentCurationResponse.kt new file mode 100644 index 0000000..fe39948 --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/GetContentCurationResponse.kt @@ -0,0 +1,11 @@ +package kr.co.vividnext.sodalive.audio_content.main.v2 + +import androidx.annotation.Keep +import com.google.gson.annotations.SerializedName +import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentMainItem + +@Keep +data class GetContentCurationResponse( + @SerializedName("title") val title: String, + @SerializedName("items") val items: List +) diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/alarm/AudioContentMainTabAlarmFragment.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/alarm/AudioContentMainTabAlarmFragment.kt index 289baa4..71d3304 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/alarm/AudioContentMainTabAlarmFragment.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/alarm/AudioContentMainTabAlarmFragment.kt @@ -1,9 +1,394 @@ package kr.co.vividnext.sodalive.audio_content.main.v2.alarm +import android.content.Intent +import android.graphics.Rect +import android.net.Uri +import android.os.Bundle +import android.view.View +import android.widget.LinearLayout +import android.widget.Toast +import androidx.annotation.OptIn +import androidx.core.content.ContextCompat +import androidx.media3.common.util.UnstableApi +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.zhpan.bannerview.BaseBannerAdapter +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.all.AudioContentNewAllActivity +import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity +import kr.co.vividnext.sodalive.audio_content.main.AudioContentBannerType +import kr.co.vividnext.sodalive.audio_content.main.AudioContentMainContentAdapter +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.series.detail.SeriesDetailActivity import kr.co.vividnext.sodalive.base.BaseFragment +import kr.co.vividnext.sodalive.common.Constants +import kr.co.vividnext.sodalive.common.LoadingDialog import kr.co.vividnext.sodalive.databinding.FragmentAudioContentMainTabAlarmBinding +import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity +import kr.co.vividnext.sodalive.extensions.dpToPx +import kr.co.vividnext.sodalive.live.event_banner.EventBannerAdapter +import kr.co.vividnext.sodalive.settings.event.EventDetailActivity +import org.koin.android.ext.android.inject +import kotlin.math.roundToInt +@OptIn(UnstableApi::class) class AudioContentMainTabAlarmFragment : BaseFragment( FragmentAudioContentMainTabAlarmBinding::inflate ) { + private val viewModel: AudioContentMainTabAlarmViewModel by inject() + + private lateinit var loadingDialog: LoadingDialog + private lateinit var contentBannerAdapter: AudioContentMainBannerAdapter + private lateinit var newContentThemeAdapter: AudioContentMainNewContentThemeAdapter + private lateinit var newContentAdapter: AudioContentMainContentAdapter + private lateinit var curationAdapter: AudioContentMainContentCurationAdapter + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setupView() + bindData() + + viewModel.fetchData() + } + + private fun setupView() { + loadingDialog = LoadingDialog(requireActivity(), layoutInflater) + + setupContentBanner() + setupNewContentTheme() + setupNewContent() + setupEventBanner() + setupCuration() + } + + private fun setupContentBanner() { + val layoutParams = binding + .rvBanner + .layoutParams as LinearLayout.LayoutParams + + val pagerWidth = screenWidth.toDouble() - 26.7f.dpToPx() + val pagerHeight = (pagerWidth * 0.53).roundToInt() + layoutParams.width = pagerWidth.roundToInt() + layoutParams.height = pagerHeight + + contentBannerAdapter = AudioContentMainBannerAdapter( + requireContext(), + pagerWidth.roundToInt(), + pagerHeight + ) { + when (it.type) { + AudioContentBannerType.EVENT -> { + startActivity( + Intent(requireContext(), EventDetailActivity::class.java).apply { + putExtra(Constants.EXTRA_EVENT, it.eventItem!!) + } + ) + } + + AudioContentBannerType.CREATOR -> { + startActivity( + Intent(requireContext(), UserProfileActivity::class.java).apply { + putExtra(Constants.EXTRA_USER_ID, it.creatorId!!) + } + ) + } + + AudioContentBannerType.SERIES -> { + startActivity( + Intent(requireContext(), SeriesDetailActivity::class.java).apply { + putExtra(Constants.EXTRA_SERIES_ID, it.seriesId!!) + } + ) + } + + AudioContentBannerType.LINK -> { + startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(it.link!!))) + } + } + } + + binding + .rvBanner + .layoutParams = layoutParams + + binding.rvBanner.apply { + adapter = contentBannerAdapter as BaseBannerAdapter + + setLifecycleRegistry(lifecycle) + setScrollDuration(1000) + setInterval(4 * 1000) + }.create() + + binding + .rvBanner + .setIndicatorView(binding.indicatorBanner) + .setIndicatorStyle(IndicatorStyle.ROUND_RECT) + .setIndicatorSlideMode(IndicatorSlideMode.SMOOTH) + .setIndicatorVisibility(View.GONE) + .setIndicatorSliderColor( + ContextCompat.getColor(requireContext(), R.color.color_909090), + ContextCompat.getColor(requireContext(), R.color.color_3bb9f1) + ) + .setIndicatorSliderWidth(4f.dpToPx().toInt(), 10f.dpToPx().toInt()) + .setIndicatorHeight(4f.dpToPx().toInt()) + + viewModel.contentBannerLiveData.observe(viewLifecycleOwner) { + if (contentBannerAdapter.itemCount <= 0 && it.isEmpty()) { + binding.rvBanner.visibility = View.GONE + binding.indicatorBanner.visibility = View.GONE + } else { + binding.rvBanner.visibility = View.VISIBLE + binding.indicatorBanner.visibility = View.VISIBLE + binding.rvBanner.refreshData(it) + } + } + } + + private fun setupNewContentTheme() { + newContentThemeAdapter = AudioContentMainNewContentThemeAdapter { + } + + binding.rvNewContentTheme.layoutManager = LinearLayoutManager( + context, + LinearLayoutManager.HORIZONTAL, + false + ) + + binding.rvNewContentTheme.addItemDecoration(object : RecyclerView.ItemDecoration() { + override fun getItemOffsets( + outRect: Rect, + view: View, + parent: RecyclerView, + state: RecyclerView.State + ) { + super.getItemOffsets(outRect, view, parent, state) + + when (parent.getChildAdapterPosition(view)) { + 0 -> { + outRect.left = 0 + outRect.right = 4f.dpToPx().toInt() + } + + newContentThemeAdapter.itemCount - 1 -> { + outRect.left = 4f.dpToPx().toInt() + outRect.right = 0 + } + + else -> { + outRect.left = 4f.dpToPx().toInt() + outRect.right = 4f.dpToPx().toInt() + } + } + } + }) + + binding.rvNewContentTheme.adapter = newContentThemeAdapter + + viewModel.themeListLiveData.observe(viewLifecycleOwner) { + binding.llNewContent.visibility = View.VISIBLE + newContentThemeAdapter.addItems( + it, + selectedTheme = if (it.isNotEmpty()) { + it[0] + } else { + "" + } + ) + } + } + + private fun setupNewContent() { + binding.ivNewContentAll.setOnClickListener { + startActivity(Intent(requireContext(), AudioContentNewAllActivity::class.java)) + } + + newContentAdapter = AudioContentMainContentAdapter( + onClickItem = { + startActivity( + Intent(requireContext(), AudioContentDetailActivity::class.java).apply { + putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, it) + } + ) + }, + onClickCreator = { + startActivity( + Intent(requireContext(), UserProfileActivity::class.java).apply { + putExtra(Constants.EXTRA_USER_ID, it) + } + ) + } + ) + + binding.rvNewContent.layoutManager = LinearLayoutManager( + context, + LinearLayoutManager.HORIZONTAL, + false + ) + + binding.rvNewContent.addItemDecoration(object : RecyclerView.ItemDecoration() { + override fun getItemOffsets( + outRect: Rect, + view: View, + parent: RecyclerView, + state: RecyclerView.State + ) { + super.getItemOffsets(outRect, view, parent, state) + + when (parent.getChildAdapterPosition(view)) { + 0 -> { + outRect.left = 0 + outRect.right = 6.7f.dpToPx().toInt() + } + + newContentAdapter.itemCount - 1 -> { + outRect.left = 6.7f.dpToPx().toInt() + outRect.right = 0 + } + + else -> { + outRect.left = 6.7f.dpToPx().toInt() + outRect.right = 6.7f.dpToPx().toInt() + } + } + } + }) + + binding.rvNewContent.adapter = newContentAdapter + + viewModel.newContentListLiveData.observe(viewLifecycleOwner) { + newContentAdapter.addItems(it) + } + } + + private fun setupEventBanner() { + val imageSliderLp = binding.eventBannerSlider.layoutParams + imageSliderLp.width = screenWidth + imageSliderLp.height = (screenWidth * 300) / 1000 + binding.eventBannerSlider.layoutParams = imageSliderLp + + binding.eventBannerSlider.apply { + adapter = EventBannerAdapter(requireContext()) { + if (it.detailImageUrl != null) { + val intent = Intent(requireActivity(), EventDetailActivity::class.java) + intent.putExtra(Constants.EXTRA_EVENT, it) + startActivity(intent) + } else if (!it.link.isNullOrBlank()) { + startActivity( + Intent( + Intent.ACTION_VIEW, + Uri.parse(it.link) + ) + ) + } + } as BaseBannerAdapter + setLifecycleRegistry(lifecycle) + setScrollDuration(800) + }.create() + + binding.eventBannerSlider + .setIndicatorView(binding.indicatorEventBanner) + .setIndicatorStyle(IndicatorStyle.ROUND_RECT) + .setIndicatorSlideMode(IndicatorSlideMode.SMOOTH) + .setIndicatorVisibility(View.GONE) + .setIndicatorSliderColor( + ContextCompat.getColor(requireContext(), R.color.color_909090), + ContextCompat.getColor(requireContext(), R.color.color_3bb9f1) + ) + .setIndicatorSliderWidth(4f.dpToPx().toInt(), 10f.dpToPx().toInt()) + .setIndicatorHeight(4f.dpToPx().toInt()) + + viewModel.eventLiveData.observe(viewLifecycleOwner) { + if (it.isNotEmpty()) { + binding.eventBannerSlider.visibility = View.VISIBLE + binding.indicatorEventBanner.visibility = View.VISIBLE + binding.eventBannerSlider.refreshData(it) + } else { + binding.eventBannerSlider.visibility = View.GONE + binding.indicatorEventBanner.visibility = View.GONE + } + } + } + + private fun setupCuration() { + curationAdapter = AudioContentMainContentCurationAdapter( + onClickItem = { + startActivity( + Intent(requireContext(), AudioContentDetailActivity::class.java).apply { + putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, it) + } + ) + }, + onClickCreator = { + startActivity( + Intent(requireContext(), UserProfileActivity::class.java).apply { + putExtra(Constants.EXTRA_USER_ID, it) + } + ) + } + ) + + binding.rvCuration.layoutManager = LinearLayoutManager( + context, + LinearLayoutManager.VERTICAL, + false + ) + + binding.rvCuration.addItemDecoration(object : RecyclerView.ItemDecoration() { + override fun getItemOffsets( + outRect: Rect, + view: View, + parent: RecyclerView, + state: RecyclerView.State + ) { + super.getItemOffsets(outRect, view, parent, state) + + when (parent.getChildAdapterPosition(view)) { + 0 -> { + outRect.top = 30f.dpToPx().toInt() + outRect.bottom = 15f.dpToPx().toInt() + } + + curationAdapter.itemCount - 1 -> { + outRect.top = 15f.dpToPx().toInt() + outRect.bottom = 30f.dpToPx().toInt() + } + + else -> { + outRect.top = 15f.dpToPx().toInt() + outRect.bottom = 15f.dpToPx().toInt() + } + } + } + }) + + binding.rvCuration.adapter = curationAdapter + + viewModel.curationListLiveData.observe(viewLifecycleOwner) { + curationAdapter.addItems(it) + + binding.rvCuration.visibility = if (curationAdapter.itemCount <= 0 && it.isEmpty()) { + View.GONE + } else { + View.VISIBLE + } + } + } + + private fun bindData() { + viewModel.toastLiveData.observe(viewLifecycleOwner) { + it?.let { Toast.makeText(requireContext(), it, Toast.LENGTH_LONG).show() } + } + + viewModel.isLoading.observe(viewLifecycleOwner) { + if (it) { + loadingDialog.show(screenWidth) + } else { + loadingDialog.dismiss() + } + } + } } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/alarm/AudioContentMainTabAlarmRepository.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/alarm/AudioContentMainTabAlarmRepository.kt new file mode 100644 index 0000000..b100da0 --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/alarm/AudioContentMainTabAlarmRepository.kt @@ -0,0 +1,7 @@ +package kr.co.vividnext.sodalive.audio_content.main.v2.alarm + +import kr.co.vividnext.sodalive.audio_content.AudioContentApi + +class AudioContentMainTabAlarmRepository(private val api: AudioContentApi) { + fun getContentMainAlarm(token: String) = api.getContentMainAlarm(authHeader = token) +} diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/alarm/AudioContentMainTabAlarmViewModel.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/alarm/AudioContentMainTabAlarmViewModel.kt new file mode 100644 index 0000000..b6dae5e --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/alarm/AudioContentMainTabAlarmViewModel.kt @@ -0,0 +1,84 @@ +package kr.co.vividnext.sodalive.audio_content.main.v2.alarm + +import androidx.lifecycle.LiveData +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.GetAudioContentBannerResponse +import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentMainItem +import kr.co.vividnext.sodalive.audio_content.main.v2.GetContentCurationResponse +import kr.co.vividnext.sodalive.base.BaseViewModel +import kr.co.vividnext.sodalive.common.SharedPreferenceManager +import kr.co.vividnext.sodalive.settings.event.EventItem + +class AudioContentMainTabAlarmViewModel( + private val repository: AudioContentMainTabAlarmRepository +) : BaseViewModel() { + private val _toastLiveData = MutableLiveData() + val toastLiveData: LiveData + get() = _toastLiveData + + private var _isLoading = MutableLiveData(false) + val isLoading: LiveData + get() = _isLoading + + private var _contentBannerLiveData = MutableLiveData>() + val contentBannerLiveData: LiveData> + get() = _contentBannerLiveData + + private var _newContentListLiveData = MutableLiveData>() + val newContentListLiveData: LiveData> + get() = _newContentListLiveData + + private var _themeListLiveData = MutableLiveData>() + val themeListLiveData: LiveData> + get() = _themeListLiveData + + private val _eventLiveData = MutableLiveData>() + val eventLiveData: LiveData> + get() = _eventLiveData + + private var _curationListLiveData = MutableLiveData>() + val curationListLiveData: LiveData> + get() = _curationListLiveData + + fun fetchData() { + _isLoading.value = true + compositeDisposable.add( + repository.getContentMainAlarm(token = "Bearer ${SharedPreferenceManager.token}") + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + { + if (it.success && it.data != null) { + val data = it.data + + Logger.e("data: $data") + _contentBannerLiveData.value = data.contentBannerList + + _themeListLiveData.value = data.alarmThemeList + _newContentListLiveData.value = data.newAlarmContentList + _eventLiveData.value = data.eventBannerList.eventList + _curationListLiveData.value = data.curationList + } else { + if (it.message != null) { + _toastLiveData.postValue(it.message) + } else { + _toastLiveData.postValue( + "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요." + ) + } + } + + _isLoading.value = false + }, + { + _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/alarm/GetContentMainTabAlarmResponse.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/alarm/GetContentMainTabAlarmResponse.kt new file mode 100644 index 0000000..764519d --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/alarm/GetContentMainTabAlarmResponse.kt @@ -0,0 +1,25 @@ +package kr.co.vividnext.sodalive.audio_content.main.v2.alarm + +import androidx.annotation.Keep +import com.google.gson.annotations.SerializedName +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.settings.event.GetEventResponse + +@Keep +data class GetContentMainTabAlarmResponse( + @SerializedName("contentBannerList") + val contentBannerList: List, + @SerializedName("alarmThemeList") + val alarmThemeList: List, + @SerializedName("newAlarmContentList") + val newAlarmContentList: List, + @SerializedName("rankAlarmContentList") + val rankAlarmContentList: List, + @SerializedName("eventBannerList") + val eventBannerList: GetEventResponse, + @SerializedName("curationList") + val curationList: List +) diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/content/AudioContentMainTabContentViewModel.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/content/AudioContentMainTabContentViewModel.kt index 79ac9a5..54f59d3 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/content/AudioContentMainTabContentViewModel.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/content/AudioContentMainTabContentViewModel.kt @@ -72,7 +72,6 @@ class AudioContentMainTabContentViewModel( if (it.success && it.data != null) { val data = it.data - Logger.e("data: $data") _contentBannerLiveData.value = data.bannerList val themeList = listOf("전체").union(data.contentThemeList).toList() diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/series/recommend_by_genre/AudioContentMainRecommendSeriesGenreAdapter.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/series/recommend_by_genre/AudioContentMainRecommendSeriesGenreAdapter.kt index 058f6ca..44149f7 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/series/recommend_by_genre/AudioContentMainRecommendSeriesGenreAdapter.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/series/recommend_by_genre/AudioContentMainRecommendSeriesGenreAdapter.kt @@ -6,7 +6,6 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView -import com.orhanobut.logger.Logger import kr.co.vividnext.sodalive.R import kr.co.vividnext.sodalive.audio_content.main.v2.series.GetSeriesGenreListResponse import kr.co.vividnext.sodalive.databinding.ItemAudioContentMainNewContentThemeBinding diff --git a/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt b/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt index 1078099..d3d0154 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt @@ -23,6 +23,8 @@ import kr.co.vividnext.sodalive.audio_content.main.order.AudioContentMainOrderLi import kr.co.vividnext.sodalive.audio_content.main.ranking.AudioContentMainCreatorRankingViewModel import kr.co.vividnext.sodalive.audio_content.main.ranking.AudioContentMainRankingViewModel import kr.co.vividnext.sodalive.audio_content.main.recommend_series.AudioContentMainRecommendSeriesViewModel +import kr.co.vividnext.sodalive.audio_content.main.v2.alarm.AudioContentMainTabAlarmRepository +import kr.co.vividnext.sodalive.audio_content.main.v2.alarm.AudioContentMainTabAlarmViewModel import kr.co.vividnext.sodalive.audio_content.main.v2.content.AudioContentMainTabContentRepository import kr.co.vividnext.sodalive.audio_content.main.v2.content.AudioContentMainTabContentViewModel import kr.co.vividnext.sodalive.audio_content.main.v2.home.AudioContentMainTabHomeRepository @@ -299,6 +301,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) { viewModel { AudioContentMainTabHomeViewModel(get(), get()) } viewModel { AudioContentMainTabSeriesViewModel(get()) } viewModel { AudioContentMainTabContentViewModel(get()) } + viewModel { AudioContentMainTabAlarmViewModel(get()) } } private val repositoryModule = module { @@ -333,6 +336,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) { factory { AudioContentMainTabHomeRepository(get()) } factory { AudioContentMainTabSeriesRepository(get()) } factory { AudioContentMainTabContentRepository(get()) } + factory { AudioContentMainTabAlarmRepository(get()) } } private val moduleList = listOf( diff --git a/app/src/main/res/layout/fragment_audio_content_main_tab_alarm.xml b/app/src/main/res/layout/fragment_audio_content_main_tab_alarm.xml index 1b31835..9f63cef 100644 --- a/app/src/main/res/layout/fragment_audio_content_main_tab_alarm.xml +++ b/app/src/main/res/layout/fragment_audio_content_main_tab_alarm.xml @@ -21,5 +21,74 @@ android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="6.7dp" /> + + + + + + + + + + + + + + + + + + + +