diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
new file mode 100644
index 0000000..b268ef3
--- /dev/null
+++ b/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/AudioContentMainFragment.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/AudioContentMainFragment.kt
index 6d4d7a2..d1d3bf8 100644
--- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/AudioContentMainFragment.kt
+++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/AudioContentMainFragment.kt
@@ -1,19 +1,18 @@
package kr.co.vividnext.sodalive.audio_content.main
import android.annotation.SuppressLint
-import android.app.Service
import android.content.Intent
import android.graphics.Rect
import android.net.Uri
import android.os.Bundle
import android.view.View
-import android.view.inputmethod.InputMethodManager
import android.widget.LinearLayout
import android.widget.Toast
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
+import com.orhanobut.logger.Logger
import com.zhpan.bannerview.BaseBannerAdapter
import com.zhpan.indicator.enums.IndicatorSlideMode
import com.zhpan.indicator.enums.IndicatorStyle
@@ -29,18 +28,19 @@ import kr.co.vividnext.sodalive.audio_content.main.curation.AudioContentMainCura
import kr.co.vividnext.sodalive.audio_content.main.curation.AudioContentMainCurationViewModel
import kr.co.vividnext.sodalive.audio_content.main.new_content.AudioContentMainNewContentThemeAdapter
import kr.co.vividnext.sodalive.audio_content.main.new_content.AudioContentMainNewContentViewModel
-import kr.co.vividnext.sodalive.audio_content.main.new_content_upload_creator.AudioContentMainNewContentCreatorAdapter
-import kr.co.vividnext.sodalive.audio_content.main.new_content_upload_creator.AudioContentMainNewContentCreatorViewModel
import kr.co.vividnext.sodalive.audio_content.main.order.AudioContentMainOrderListViewModel
import kr.co.vividnext.sodalive.audio_content.main.ranking.AudioContentMainRankingAdapter
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.order.AudioContentOrderListActivity
+import kr.co.vividnext.sodalive.audio_content.series.detail.SeriesDetailActivity
import kr.co.vividnext.sodalive.audio_content.upload.AudioContentUploadActivity
import kr.co.vividnext.sodalive.base.BaseFragment
import kr.co.vividnext.sodalive.common.Constants
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
import kr.co.vividnext.sodalive.databinding.FragmentAudioContentMainBinding
import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity
+import kr.co.vividnext.sodalive.explorer.profile.series.UserProfileSeriesListAdapter
import kr.co.vividnext.sodalive.extensions.dpToPx
import kr.co.vividnext.sodalive.settings.event.EventDetailActivity
import kr.co.vividnext.sodalive.settings.notification.MemberRole
@@ -50,8 +50,8 @@ import kotlin.math.roundToInt
class AudioContentMainFragment : BaseFragment(
FragmentAudioContentMainBinding::inflate
) {
- private val newContentCreatorViewModel: AudioContentMainNewContentCreatorViewModel by inject()
- private lateinit var newContentCreatorAdapter: AudioContentMainNewContentCreatorAdapter
+ private val recommendSeriesViewModel: AudioContentMainRecommendSeriesViewModel by inject()
+ private lateinit var seriesAdapter: UserProfileSeriesListAdapter
private val bannerViewModel: AudioContentMainBannerViewModel by inject()
private lateinit var bannerAdapter: AudioContentMainBannerAdapter
@@ -80,7 +80,7 @@ class AudioContentMainFragment : BaseFragment(
newContentViewModel.getNewContentOfTheme("전체")
contentRankingViewModel.getContentRanking()
contentRankingViewModel.getContentRankingSortType()
- newContentCreatorViewModel.getNewContentUploadCreatorList()
+ recommendSeriesViewModel.getRecommendSeriesList()
}
private fun setupView() {
@@ -98,7 +98,7 @@ class AudioContentMainFragment : BaseFragment(
binding.llUploadContent.visibility = View.GONE
}
- setupNewContentCreator()
+ setupRecommendSeries()
setupBanner()
setupOrderList()
setupNewContentTheme()
@@ -107,17 +107,6 @@ class AudioContentMainFragment : BaseFragment(
setupContentRanking()
setupCuration()
- binding.swipeRefreshLayout.setOnRefreshListener {
- binding.swipeRefreshLayout.isRefreshing = false
- curationViewModel.refresh()
- bannerViewModel.getMainBannerList()
- newContentViewModel.getThemeList()
- newContentViewModel.getNewContentOfTheme("전체")
- contentRankingViewModel.getContentRanking()
- contentRankingViewModel.getContentRankingSortType()
- newContentCreatorViewModel.getNewContentUploadCreatorList()
- }
-
binding.llShortPlay.setOnClickListener {
startActivity(
Intent(requireContext(), AudioContentAllByThemeActivity::class.java).apply {
@@ -135,20 +124,33 @@ class AudioContentMainFragment : BaseFragment(
}
}
- private fun setupNewContentCreator() {
- newContentCreatorAdapter = AudioContentMainNewContentCreatorAdapter {
- val intent = Intent(requireContext(), UserProfileActivity::class.java)
- intent.putExtra(Constants.EXTRA_USER_ID, it)
- startActivity(intent)
- }
+ private fun setupRecommendSeries() {
+ seriesAdapter = UserProfileSeriesListAdapter(
+ onClickItem = {
+ startActivity(
+ Intent(requireContext(), SeriesDetailActivity::class.java).apply {
+ putExtra(Constants.EXTRA_SERIES_ID, it)
+ }
+ )
+ },
+ onClickCreator = {
+ startActivity(
+ Intent(requireContext(), UserProfileActivity::class.java).apply {
+ putExtra(Constants.EXTRA_USER_ID, it)
+ }
+ )
+ },
+ isVisibleCreator = true
+ )
- binding.rvNewContentCreator.layoutManager = LinearLayoutManager(
- context,
+ val recyclerView = binding.rvRecommendSeries
+ recyclerView.layoutManager = LinearLayoutManager(
+ requireContext(),
LinearLayoutManager.HORIZONTAL,
false
)
- binding.rvNewContentCreator.addItemDecoration(object : RecyclerView.ItemDecoration() {
+ recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
@@ -160,28 +162,28 @@ class AudioContentMainFragment : BaseFragment(
when (parent.getChildAdapterPosition(view)) {
0 -> {
outRect.left = 0
- outRect.right = 10.7f.dpToPx().toInt()
+ outRect.right = 6.7f.dpToPx().toInt()
}
- newContentCreatorAdapter.itemCount - 1 -> {
- outRect.left = 10.7f.dpToPx().toInt()
+ seriesAdapter.itemCount - 1 -> {
outRect.right = 0
+ outRect.left = 6.7f.dpToPx().toInt()
}
else -> {
- outRect.left = 10.7f.dpToPx().toInt()
- outRect.right = 10.7f.dpToPx().toInt()
+ outRect.left = 6.7f.dpToPx().toInt()
+ outRect.right = 6.7f.dpToPx().toInt()
}
}
}
})
- binding.rvNewContentCreator.adapter = newContentCreatorAdapter
+ recyclerView.adapter = seriesAdapter
- newContentCreatorViewModel.newContentUploadCreatorListLiveData.observe(viewLifecycleOwner) {
- newContentCreatorAdapter.addItems(it)
- binding.rvNewContentCreator.visibility = if (
- newContentCreatorAdapter.itemCount <= 0 && it.isEmpty()
+ recommendSeriesViewModel.seriesListLiveData.observe(viewLifecycleOwner) {
+ seriesAdapter.addItems(it)
+ binding.llRecommendSeries.visibility = if (
+ seriesAdapter.itemCount <= 0 && it.isEmpty()
) {
View.GONE
} else {
@@ -189,7 +191,7 @@ class AudioContentMainFragment : BaseFragment(
}
}
- newContentCreatorViewModel.toastLiveData.observe(viewLifecycleOwner) {
+ recommendSeriesViewModel.toastLiveData.observe(viewLifecycleOwner) {
it?.let { Toast.makeText(requireContext(), it, Toast.LENGTH_LONG).show() }
}
}
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/new_content_upload_creator/AudioContentMainNewContentCreatorAdapter.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/new_content_upload_creator/AudioContentMainNewContentCreatorAdapter.kt
deleted file mode 100644
index d620717..0000000
--- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/new_content_upload_creator/AudioContentMainNewContentCreatorAdapter.kt
+++ /dev/null
@@ -1,53 +0,0 @@
-package kr.co.vividnext.sodalive.audio_content.main.new_content_upload_creator
-
-import android.annotation.SuppressLint
-import android.view.LayoutInflater
-import android.view.ViewGroup
-import androidx.recyclerview.widget.RecyclerView
-import coil.load
-import coil.transform.CircleCropTransformation
-import kr.co.vividnext.sodalive.R
-import kr.co.vividnext.sodalive.audio_content.main.GetNewContentUploadCreator
-import kr.co.vividnext.sodalive.databinding.ItemAudioContentMainNewContentCreatorBinding
-
-class AudioContentMainNewContentCreatorAdapter(
- private val onClickItem: (Long) -> Unit
-) : RecyclerView.Adapter() {
-
- private val items = mutableListOf()
-
- inner class ViewHolder(
- private val binding: ItemAudioContentMainNewContentCreatorBinding
- ) : RecyclerView.ViewHolder(binding.root) {
- fun bind(item: GetNewContentUploadCreator) {
- binding.tvNewContentCreator.text = item.creatorNickname
- binding.ivNewContentCreator.load(item.creatorProfileImageUrl) {
- crossfade(true)
- placeholder(R.drawable.ic_place_holder)
- transformations(CircleCropTransformation())
- }
- binding.root.setOnClickListener { onClickItem(item.creatorId) }
- }
- }
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
- ItemAudioContentMainNewContentCreatorBinding.inflate(
- LayoutInflater.from(parent.context),
- parent,
- false
- )
- )
-
- override fun getItemCount() = items.size
-
- override fun onBindViewHolder(holder: ViewHolder, position: Int) {
- holder.bind(items[position])
- }
-
- @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/new_content_upload_creator/AudioContentMainNewContentCreatorViewModel.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/recommend_series/AudioContentMainRecommendSeriesViewModel.kt
similarity index 59%
rename from app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/new_content_upload_creator/AudioContentMainNewContentCreatorViewModel.kt
rename to app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/recommend_series/AudioContentMainRecommendSeriesViewModel.kt
index c152c61..497c599 100644
--- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/new_content_upload_creator/AudioContentMainNewContentCreatorViewModel.kt
+++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/recommend_series/AudioContentMainRecommendSeriesViewModel.kt
@@ -1,44 +1,42 @@
-package kr.co.vividnext.sodalive.audio_content.main.new_content_upload_creator
+package kr.co.vividnext.sodalive.audio_content.main.recommend_series
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.AudioContentRepository
-import kr.co.vividnext.sodalive.audio_content.main.GetNewContentUploadCreator
+import kr.co.vividnext.sodalive.audio_content.series.GetSeriesListResponse
+import kr.co.vividnext.sodalive.audio_content.series.SeriesRepository
import kr.co.vividnext.sodalive.base.BaseViewModel
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
-class AudioContentMainNewContentCreatorViewModel(
- private val repository: AudioContentRepository
+class AudioContentMainRecommendSeriesViewModel(
+ private val repository: SeriesRepository
) : BaseViewModel() {
private val _toastLiveData = MutableLiveData()
val toastLiveData: LiveData
get() = _toastLiveData
- private var _newContentUploadCreatorListLiveData =
- MutableLiveData>()
- val newContentUploadCreatorListLiveData: LiveData>
- get() = _newContentUploadCreatorListLiveData
+ private var _seriesListLiveData = MutableLiveData>()
+ val seriesListLiveData: LiveData>
+ get() = _seriesListLiveData
- fun getNewContentUploadCreatorList() {
+ fun getRecommendSeriesList() {
compositeDisposable.add(
- repository.getNewContentUploadCreatorList(
- token = "Bearer ${SharedPreferenceManager.token}"
- )
+ repository
+ .getRecommendSeriesList(token = "Bearer ${SharedPreferenceManager.token}")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{
if (it.success && it.data != null) {
- _newContentUploadCreatorListLiveData.postValue(it.data!!)
+ _seriesListLiveData.value = it.data!!
} else {
if (it.message != null) {
_toastLiveData.postValue(it.message)
} else {
_toastLiveData.postValue(
- "크리에이터 리스트를 불러오지 못했습니다. 다시 시도해 주세요.\n" +
+ "추천 시리즈를 불러오지 못했습니다. 다시 시도해 주세요.\n" +
"계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
)
}
@@ -47,7 +45,7 @@ class AudioContentMainNewContentCreatorViewModel(
{
it.message?.let { message -> Logger.e(message) }
_toastLiveData.postValue(
- "크리에이터 리스트를 불러오지 못했습니다. 다시 시도해 주세요.\n" +
+ "추천 시리즈를 불러오지 못했습니다. 다시 시도해 주세요.\n" +
"계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
)
}
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/series/SeriesApi.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/series/SeriesApi.kt
index 7f258e5..77c582d 100644
--- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/series/SeriesApi.kt
+++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/series/SeriesApi.kt
@@ -32,4 +32,9 @@ interface SeriesApi {
@Query("size") size: Int,
@Header("Authorization") authHeader: String
): Single>
+
+ @GET("/audio-content/series/recommend")
+ fun getRecommendSeriesList(
+ @Header("Authorization") authHeader: String
+ ): Single>>
}
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/series/SeriesRepository.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/series/SeriesRepository.kt
index 6b76289..a3de4b2 100644
--- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/series/SeriesRepository.kt
+++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/series/SeriesRepository.kt
@@ -31,4 +31,6 @@ class SeriesRepository(private val api: SeriesApi) {
size = size,
authHeader = token
)
+
+ fun getRecommendSeriesList(token: String) = api.getRecommendSeriesList(authHeader = token)
}
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 208fff7..aa79f63 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
@@ -19,9 +19,9 @@ import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailViewModel
import kr.co.vividnext.sodalive.audio_content.main.banner.AudioContentMainBannerViewModel
import kr.co.vividnext.sodalive.audio_content.main.curation.AudioContentMainCurationViewModel
import kr.co.vividnext.sodalive.audio_content.main.new_content.AudioContentMainNewContentViewModel
-import kr.co.vividnext.sodalive.audio_content.main.new_content_upload_creator.AudioContentMainNewContentCreatorViewModel
import kr.co.vividnext.sodalive.audio_content.main.order.AudioContentMainOrderListViewModel
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.modify.AudioContentModifyViewModel
import kr.co.vividnext.sodalive.audio_content.order.AudioContentOrderListViewModel
import kr.co.vividnext.sodalive.audio_content.series.SeriesApi
@@ -220,7 +220,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
viewModel { AudioContentMainCurationViewModel(get()) }
viewModel { AudioContentMainOrderListViewModel(get()) }
viewModel { AudioContentMainNewContentViewModel(get()) }
- viewModel { AudioContentMainNewContentCreatorViewModel(get()) }
+ viewModel { AudioContentMainRecommendSeriesViewModel(get()) }
viewModel { AudioContentViewModel(get()) }
viewModel { AudioContentOrderListViewModel(get()) }
viewModel { AudioContentUploadViewModel(get()) }
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/series/UserProfileSeriesListAdapter.kt b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/series/UserProfileSeriesListAdapter.kt
index 078ccf0..54ecee9 100644
--- a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/series/UserProfileSeriesListAdapter.kt
+++ b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/series/UserProfileSeriesListAdapter.kt
@@ -11,7 +11,6 @@ import coil.transform.RoundedCornersTransformation
import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.audio_content.series.GetSeriesListResponse
import kr.co.vividnext.sodalive.databinding.ItemSeriesListBigBinding
-import kr.co.vividnext.sodalive.databinding.ItemSeriesListBinding
import kr.co.vividnext.sodalive.extensions.dpToPx
class UserProfileSeriesListAdapter(
diff --git a/app/src/main/res/layout/fragment_audio_content_main.xml b/app/src/main/res/layout/fragment_audio_content_main.xml
index 18a84e4..c5fda03 100644
--- a/app/src/main/res/layout/fragment_audio_content_main.xml
+++ b/app/src/main/res/layout/fragment_audio_content_main.xml
@@ -4,289 +4,300 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
-
+ android:layout_height="match_parent"
+ android:clipToPadding="false"
+ android:paddingVertical="13.3dp">
-
+ android:orientation="vertical">
+
+
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="40dp"
+ android:orientation="vertical"
+ android:visibility="gone">
+ android:paddingHorizontal="13.3dp"
+ android:text="추천 시리즈"
+ android:textColor="@color/color_eeeeee"
+ android:textSize="18.3sp" />
+ android:paddingHorizontal="13.3dp" />
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+ android:fontFamily="@font/gmarket_sans_bold"
+ android:text="내 보관함"
+ android:textColor="@color/color_eeeeee"
+ android:textSize="18.3sp" />
-
-
-
-
+ android:layout_alignParentEnd="true"
+ android:layout_centerVertical="true"
+ android:fontFamily="@font/gmarket_sans_light"
+ android:text="전체보기"
+ android:textColor="@color/color_bbbbbb"
+ android:textSize="11.3sp" />
+
-
-
-
-
-
+ android:layout_marginTop="13.3dp"
+ android:clipToPadding="false"
+ android:paddingHorizontal="13.3dp" />
+
-
+
+
+
+
+ android:layout_marginStart="13.3dp"
+ android:fontFamily="@font/gmarket_sans_bold"
+ android:text="새로운 콘텐츠"
+ android:textColor="@color/color_eeeeee"
+ android:textSize="18.3sp" />
-
-
-
-
-
-
-
+ android:layout_alignParentEnd="true"
+ android:contentDescription="@null"
+ android:paddingHorizontal="13.3dp"
+ android:src="@drawable/ic_forward" />
+
-
+ android:layout_marginTop="13.3dp"
+ android:clipToPadding="false"
+ android:paddingHorizontal="13.3dp" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ android:paddingVertical="8dp">
-
-
-
-
-
-
-
-
+ android:fontFamily="@font/gmarket_sans_bold"
+ android:textColor="@color/color_eeeeee"
+ android:textSize="14.7sp" />
-
-
-
-
-
-
-
-
+ android:layout_marginTop="8dp"
+ android:fontFamily="@font/gmarket_sans_light"
+ android:text="※ 인기 콘텐츠의 순위는 매주 업데이트됩니다."
+ android:textColor="@color/color_bbbbbb"
+ android:textSize="13.3sp" />
+ android:layout_marginTop="13.3dp"
+ android:clipToPadding="false"
+ android:paddingHorizontal="13.3dp" />
-
+
-
-
+
+
+
+
+
+