diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 6343a53..6307490 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -86,7 +86,6 @@
-
@@ -153,6 +152,9 @@
+
+
+
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 c0bfc11..9e7c897 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
@@ -27,6 +27,7 @@ import kr.co.vividnext.sodalive.audio_content.main.v2.series.GetContentMainTabSe
import kr.co.vividnext.sodalive.audio_content.order.GetAudioContentOrderListResponse
import kr.co.vividnext.sodalive.audio_content.order.OrderRequest
import kr.co.vividnext.sodalive.audio_content.player.GenerateUrlResponse
+import kr.co.vividnext.sodalive.audio_content.series.GetSeriesListResponse
import kr.co.vividnext.sodalive.audio_content.upload.theme.GetAudioContentThemeResponse
import kr.co.vividnext.sodalive.common.ApiResponse
import kr.co.vividnext.sodalive.explorer.profile.GetAudioContentListResponse
@@ -262,6 +263,13 @@ interface AudioContentApi {
@Header("Authorization") authHeader: String
): Single>
+ @GET("/v2/audio-content/main/series/original")
+ fun getOriginalAudioDramaList(
+ @Query("page") page: Int,
+ @Query("size") size: Int,
+ @Header("Authorization") authHeader: String
+ ): Single>
+
@GET("/v2/audio-content/main/content")
fun getContentMainContent(
@Header("Authorization") authHeader: String
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/series/origianl_audio_drama/OriginalAudioDramaContentAllActivity.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/series/origianl_audio_drama/OriginalAudioDramaContentAllActivity.kt
new file mode 100644
index 0000000..e37923e
--- /dev/null
+++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/series/origianl_audio_drama/OriginalAudioDramaContentAllActivity.kt
@@ -0,0 +1,109 @@
+package kr.co.vividnext.sodalive.audio_content.main.v2.series.origianl_audio_drama
+
+import android.content.Intent
+import android.os.Bundle
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import kr.co.vividnext.sodalive.audio_content.series.SeriesListAdapter
+import kr.co.vividnext.sodalive.audio_content.series.detail.SeriesDetailActivity
+import kr.co.vividnext.sodalive.base.BaseActivity
+import kr.co.vividnext.sodalive.common.Constants
+import kr.co.vividnext.sodalive.common.DifferentSpacingItemDecoration
+import kr.co.vividnext.sodalive.common.LoadingDialog
+import kr.co.vividnext.sodalive.databinding.ActivityOriginalAudioDramaContentAllBinding
+import kr.co.vividnext.sodalive.extensions.dpToPx
+import org.koin.android.ext.android.inject
+import kotlin.math.roundToInt
+
+class OriginalAudioDramaContentAllActivity :
+ BaseActivity(
+ ActivityOriginalAudioDramaContentAllBinding::inflate
+ ) {
+ private val viewModel: OriginalAudioDramaContentAllViewModel by inject()
+
+ private lateinit var loadingDialog: LoadingDialog
+ private lateinit var adapter: SeriesListAdapter
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ bindData()
+
+ viewModel.getOriginalAudioDramaList()
+ }
+
+ override fun setupView() {
+ loadingDialog = LoadingDialog(this, layoutInflater)
+ binding.toolbar.tvBack.text = "오리지널 오디오 드라마"
+ binding.toolbar.tvBack.setOnClickListener { finish() }
+
+ setupOriginalAudioDramaListView()
+ }
+
+ private fun setupOriginalAudioDramaListView() {
+ val spacing = 13.3f.dpToPx().roundToInt()
+
+ adapter = SeriesListAdapter(
+ itemWidth = ((screenWidth - spacing * 3) / 2f).roundToInt(),
+ onClickItem = {
+ startActivity(
+ Intent(applicationContext, SeriesDetailActivity::class.java).apply {
+ putExtra(Constants.EXTRA_SERIES_ID, it)
+ }
+ )
+ },
+ onClickCreator = {},
+ isVisibleCreator = false
+ )
+
+ val spanCount = 2
+ val recyclerView = binding.rvSeries
+ recyclerView.layoutManager = GridLayoutManager(this, spanCount)
+
+ recyclerView.addItemDecoration(
+ DifferentSpacingItemDecoration(
+ spanCount = spanCount,
+ horizontalSpacing = spacing,
+ verticalSpacing = spacing,
+ includeEdge = true
+ )
+ )
+
+ recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
+ override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
+ super.onScrolled(recyclerView, dx, dy)
+
+ val lastVisibleItemPosition = (recyclerView.layoutManager as LinearLayoutManager?)!!
+ .findLastCompletelyVisibleItemPosition()
+ val itemTotalCount = recyclerView.adapter!!.itemCount - 1
+
+ // 스크롤이 끝에 도달했는지 확인
+ if (!recyclerView.canScrollVertically(1) &&
+ lastVisibleItemPosition == itemTotalCount
+ ) {
+ viewModel.getOriginalAudioDramaList()
+ }
+ }
+ })
+
+ recyclerView.adapter = adapter
+ }
+
+ private fun bindData() {
+ viewModel.toastLiveData.observe(this) {
+ it?.let { showToast(it) }
+ }
+
+ viewModel.isLoading.observe(this) {
+ if (it) {
+ loadingDialog.show(screenWidth)
+ } else {
+ loadingDialog.dismiss()
+ }
+ }
+
+ viewModel.originalAudioDramaLiveData.observe(this) {
+ adapter.addItems(it)
+ }
+ }
+}
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/series/origianl_audio_drama/OriginalAudioDramaContentAllRepository.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/series/origianl_audio_drama/OriginalAudioDramaContentAllRepository.kt
new file mode 100644
index 0000000..2028c77
--- /dev/null
+++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/series/origianl_audio_drama/OriginalAudioDramaContentAllRepository.kt
@@ -0,0 +1,15 @@
+package kr.co.vividnext.sodalive.audio_content.main.v2.series.origianl_audio_drama
+
+import kr.co.vividnext.sodalive.audio_content.AudioContentApi
+
+class OriginalAudioDramaContentAllRepository(private val api: AudioContentApi) {
+ fun getOriginalAudioDramaList(
+ page: Int,
+ size: Int,
+ token: String
+ ) = api.getOriginalAudioDramaList(
+ page = page - 1,
+ size = size,
+ authHeader = token
+ )
+}
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/series/origianl_audio_drama/OriginalAudioDramaContentAllViewModel.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/series/origianl_audio_drama/OriginalAudioDramaContentAllViewModel.kt
new file mode 100644
index 0000000..5a0fb79
--- /dev/null
+++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/v2/series/origianl_audio_drama/OriginalAudioDramaContentAllViewModel.kt
@@ -0,0 +1,74 @@
+package kr.co.vividnext.sodalive.audio_content.main.v2.series.origianl_audio_drama
+
+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.series.GetSeriesListResponse
+import kr.co.vividnext.sodalive.base.BaseViewModel
+import kr.co.vividnext.sodalive.common.SharedPreferenceManager
+
+class OriginalAudioDramaContentAllViewModel(
+ private val repository: OriginalAudioDramaContentAllRepository
+) : BaseViewModel() {
+ private val _toastLiveData = MutableLiveData()
+ val toastLiveData: LiveData
+ get() = _toastLiveData
+
+ private var _isLoading = MutableLiveData(false)
+ val isLoading: LiveData
+ get() = _isLoading
+
+ private var _originalAudioDramaLiveData =
+ MutableLiveData>()
+ val originalAudioDramaLiveData: LiveData>
+ get() = _originalAudioDramaLiveData
+
+ var isLast = false
+ var page = 1
+ private val size = 15
+
+ fun getOriginalAudioDramaList() {
+ if (!_isLoading.value!! && !isLast) {
+ _isLoading.value = true
+
+ compositeDisposable.add(
+ repository.getOriginalAudioDramaList(
+ page = page,
+ size = size,
+ token = "Bearer ${SharedPreferenceManager.token}"
+ )
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(
+ {
+ if (it.success && it.data != null) {
+ page += 1
+
+ if (it.data.items.isNotEmpty()) {
+ _originalAudioDramaLiveData.value = it.data.items
+ } else {
+ isLast = true
+ }
+ } else {
+ if (it.message != null) {
+ _toastLiveData.value = it.message
+ } else {
+ _toastLiveData.value = "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
+
+ }
+ }
+
+ _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/series/SeriesListAdapter.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/series/SeriesListAdapter.kt
index 7b7a294..1c54eb2 100644
--- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/series/SeriesListAdapter.kt
+++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/series/SeriesListAdapter.kt
@@ -4,7 +4,7 @@ import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.constraintlayout.widget.ConstraintLayout
+import android.widget.LinearLayout
import androidx.recyclerview.widget.RecyclerView
import coil.load
import coil.transform.CircleCropTransformation
@@ -27,10 +27,10 @@ class SeriesListAdapter(
) : RecyclerView.ViewHolder(binding.root) {
@SuppressLint("SetTextI18n")
fun bind(item: GetSeriesListResponse.SeriesListItem) {
- val lp = binding.ivCover.layoutParams as ConstraintLayout.LayoutParams
+ val lp = binding.clCover.layoutParams as LinearLayout.LayoutParams
lp.width = itemWidth
lp.height = itemWidth * 432 / 306
- binding.ivCover.layoutParams = lp
+ binding.clCover.layoutParams = lp
binding.ivCover.load(item.coverImage) {
crossfade(true)
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 7e42d3b..b2c0795 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
@@ -37,6 +37,8 @@ import kr.co.vividnext.sodalive.audio_content.main.v2.replay.AudioContentMainTab
import kr.co.vividnext.sodalive.audio_content.main.v2.replay.AudioContentMainTabReplayViewModel
import kr.co.vividnext.sodalive.audio_content.main.v2.series.AudioContentMainTabSeriesRepository
import kr.co.vividnext.sodalive.audio_content.main.v2.series.AudioContentMainTabSeriesViewModel
+import kr.co.vividnext.sodalive.audio_content.main.v2.series.origianl_audio_drama.OriginalAudioDramaContentAllRepository
+import kr.co.vividnext.sodalive.audio_content.main.v2.series.origianl_audio_drama.OriginalAudioDramaContentAllViewModel
import kr.co.vividnext.sodalive.audio_content.modify.AudioContentModifyViewModel
import kr.co.vividnext.sodalive.audio_content.order.AudioContentOrderListViewModel
import kr.co.vividnext.sodalive.audio_content.player.AudioContentGenerateUrlRepository
@@ -311,6 +313,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
viewModel { AudioContentMainTabAsmrViewModel(get()) }
viewModel { AudioContentMainTabReplayViewModel(get()) }
viewModel { AudioContentMainTabFreeViewModel(get()) }
+ viewModel { OriginalAudioDramaContentAllViewModel(get()) }
}
private val repositoryModule = module {
@@ -349,6 +352,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
factory { AudioContentMainTabAsmrRepository(get()) }
factory { AudioContentMainTabReplayRepository(get()) }
factory { AudioContentMainTabFreeRepository(get()) }
+ factory { OriginalAudioDramaContentAllRepository(get()) }
}
private val moduleList = listOf(
diff --git a/app/src/main/res/layout/activity_original_audio_drama_content_all.xml b/app/src/main/res/layout/activity_original_audio_drama_content_all.xml
new file mode 100644
index 0000000..b0f2ea1
--- /dev/null
+++ b/app/src/main/res/layout/activity_original_audio_drama_content_all.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/item_series_list.xml b/app/src/main/res/layout/item_series_list.xml
index 675d821..7db27d7 100644
--- a/app/src/main/res/layout/item_series_list.xml
+++ b/app/src/main/res/layout/item_series_list.xml
@@ -1,117 +1,119 @@
-
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
-
-
-
-
-
-
-
-
-
-
-
-
+ android:layout_height="wrap_content">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+