parent
eafb922ae9
commit
51b57a0b1d
|
@ -14,6 +14,8 @@ import androidx.core.content.ContextCompat
|
|||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kr.co.vividnext.sodalive.audio_content.category.AudioContentCategoryAdapter
|
||||
import kr.co.vividnext.sodalive.audio_content.category.GetCategoryListResponse
|
||||
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
|
||||
import kr.co.vividnext.sodalive.audio_content.upload.AudioContentUploadActivity
|
||||
import kr.co.vividnext.sodalive.base.BaseActivity
|
||||
|
@ -32,6 +34,7 @@ class AudioContentActivity : BaseActivity<ActivityAudioContentBinding>(
|
|||
|
||||
private lateinit var loadingDialog: LoadingDialog
|
||||
private lateinit var audioContentAdapter: AudioContentAdapter
|
||||
private lateinit var categoryAdapter: AudioContentCategoryAdapter
|
||||
|
||||
private var userId: Long = 0
|
||||
private lateinit var activityResultLauncher: ActivityResultLauncher<Intent>
|
||||
|
@ -55,6 +58,7 @@ class AudioContentActivity : BaseActivity<ActivityAudioContentBinding>(
|
|||
}
|
||||
|
||||
bindData()
|
||||
viewModel.getCategoryList(userId = userId)
|
||||
viewModel.getAudioContentList(userId = userId) { finish() }
|
||||
}
|
||||
|
||||
|
@ -71,6 +75,60 @@ class AudioContentActivity : BaseActivity<ActivityAudioContentBinding>(
|
|||
activityResultLauncher.launch(intent)
|
||||
}
|
||||
|
||||
categoryAdapter = AudioContentCategoryAdapter {
|
||||
viewModel.selectCategory(it, userId = userId)
|
||||
}
|
||||
|
||||
binding.rvCategory.layoutManager = LinearLayoutManager(
|
||||
applicationContext,
|
||||
LinearLayoutManager.HORIZONTAL,
|
||||
false
|
||||
)
|
||||
|
||||
binding.rvCategory.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)) {
|
||||
categoryAdapter.itemCount - 1 -> {
|
||||
outRect.right = 0
|
||||
}
|
||||
|
||||
else -> {
|
||||
outRect.right = 13.3f.dpToPx().toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
binding.rvCategory.adapter = categoryAdapter
|
||||
|
||||
binding.rvAudioContent.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)) {
|
||||
audioContentAdapter.itemCount - 1 -> {
|
||||
outRect.bottom = 0
|
||||
}
|
||||
|
||||
else -> {
|
||||
outRect.bottom = 13.3f.dpToPx().toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
binding.rvAudioContent.layoutManager = LinearLayoutManager(
|
||||
applicationContext,
|
||||
LinearLayoutManager.VERTICAL,
|
||||
|
@ -189,6 +247,17 @@ class AudioContentActivity : BaseActivity<ActivityAudioContentBinding>(
|
|||
)
|
||||
viewModel.getAudioContentList(userId = userId) { finish() }
|
||||
}
|
||||
|
||||
viewModel.categoryListLiveData.observe(this) {
|
||||
if (it.isNotEmpty()) {
|
||||
binding.rvCategory.visibility = View.VISIBLE
|
||||
val items = it as MutableList<GetCategoryListResponse>
|
||||
items.add(0, GetCategoryListResponse(0, "전체"))
|
||||
categoryAdapter.addItems(items = items)
|
||||
} else {
|
||||
binding.rvCategory.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun deselectSort() {
|
||||
|
|
|
@ -37,6 +37,7 @@ interface AudioContentApi {
|
|||
@GET("/audio-content")
|
||||
fun getAudioContentList(
|
||||
@Query("creator-id") id: Long,
|
||||
@Query("category-id") categoryId: Long,
|
||||
@Query("page") page: Int,
|
||||
@Query("size") size: Int,
|
||||
@Query("sort-type") sort: AudioContentViewModel.Sort,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package kr.co.vividnext.sodalive.audio_content
|
||||
|
||||
import kr.co.vividnext.sodalive.audio_content.category.CategoryApi
|
||||
import kr.co.vividnext.sodalive.audio_content.detail.PutAudioContentLikeRequest
|
||||
import kr.co.vividnext.sodalive.audio_content.donation.AudioContentDonationRequest
|
||||
import kr.co.vividnext.sodalive.audio_content.order.OrderRequest
|
||||
|
@ -12,7 +13,8 @@ import java.util.TimeZone
|
|||
|
||||
class AudioContentRepository(
|
||||
private val api: AudioContentApi,
|
||||
private val userApi: UserApi
|
||||
private val userApi: UserApi,
|
||||
private val categoryApi: CategoryApi
|
||||
) {
|
||||
fun getAudioContentListByCurationId(
|
||||
curationId: Long,
|
||||
|
@ -30,12 +32,14 @@ class AudioContentRepository(
|
|||
|
||||
fun getAudioContentList(
|
||||
id: Long,
|
||||
categoryId: Long,
|
||||
page: Int,
|
||||
size: Int,
|
||||
sort: AudioContentViewModel.Sort,
|
||||
token: String
|
||||
) = api.getAudioContentList(
|
||||
id = id,
|
||||
categoryId = categoryId,
|
||||
page = page - 1,
|
||||
size = size,
|
||||
sort = sort,
|
||||
|
@ -197,4 +201,9 @@ class AudioContentRepository(
|
|||
audioContentId: Long,
|
||||
token: String
|
||||
) = api.unpinContent(audioContentId, authHeader = token)
|
||||
|
||||
fun getCategoryList(
|
||||
creatorId: Long,
|
||||
token: String
|
||||
) = categoryApi.getCategoryList(creatorId, authHeader = token)
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import com.google.gson.annotations.SerializedName
|
|||
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.category.GetCategoryListResponse
|
||||
import kr.co.vividnext.sodalive.base.BaseViewModel
|
||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||
import kr.co.vividnext.sodalive.explorer.profile.GetAudioContentListResponse
|
||||
|
@ -24,6 +25,10 @@ class AudioContentViewModel(private val repository: AudioContentRepository) : Ba
|
|||
val audioContentListLiveData: LiveData<GetAudioContentListResponse>
|
||||
get() = _audioContentListLiveData
|
||||
|
||||
private var _categoryListLiveData = MutableLiveData<List<GetCategoryListResponse>>()
|
||||
val categoryListLiveData: LiveData<List<GetCategoryListResponse>>
|
||||
get() = _categoryListLiveData
|
||||
|
||||
private val _sort = MutableLiveData(Sort.NEWEST)
|
||||
val sort: LiveData<Sort>
|
||||
get() = _sort
|
||||
|
@ -42,6 +47,7 @@ class AudioContentViewModel(private val repository: AudioContentRepository) : Ba
|
|||
var isLast = false
|
||||
var page = 1
|
||||
private val size = 10
|
||||
private var selectedCategoryId = 0L
|
||||
|
||||
fun getAudioContentList(userId: Long, onFailure: (() -> Unit)? = null) {
|
||||
if (!_isLoading.value!! && !isLast) {
|
||||
|
@ -49,6 +55,7 @@ class AudioContentViewModel(private val repository: AudioContentRepository) : Ba
|
|||
compositeDisposable.add(
|
||||
repository.getAudioContentList(
|
||||
id = userId,
|
||||
categoryId = selectedCategoryId,
|
||||
page = page,
|
||||
size = size,
|
||||
token = "Bearer ${SharedPreferenceManager.token}",
|
||||
|
@ -59,12 +66,12 @@ class AudioContentViewModel(private val repository: AudioContentRepository) : Ba
|
|||
.subscribe(
|
||||
{
|
||||
if (it.success && it.data != null) {
|
||||
if (it.data.items.isNotEmpty()) {
|
||||
page += 1
|
||||
_audioContentListLiveData.postValue(it.data!!)
|
||||
} else {
|
||||
if (it.data.items.isEmpty()) {
|
||||
isLast = true
|
||||
}
|
||||
|
||||
page += 1
|
||||
_audioContentListLiveData.postValue(it.data!!)
|
||||
} else {
|
||||
if (it.message != null) {
|
||||
_toastLiveData.postValue(it.message)
|
||||
|
@ -99,4 +106,44 @@ class AudioContentViewModel(private val repository: AudioContentRepository) : Ba
|
|||
isLast = false
|
||||
_sort.postValue(sort)
|
||||
}
|
||||
|
||||
fun selectCategory(categoryId: Long, userId: Long) {
|
||||
isLast = false
|
||||
page = 1
|
||||
selectedCategoryId = categoryId
|
||||
getAudioContentList(userId = userId)
|
||||
}
|
||||
|
||||
fun getCategoryList(userId: Long) {
|
||||
compositeDisposable.add(
|
||||
repository.getCategoryList(
|
||||
creatorId = userId,
|
||||
token = "Bearer ${SharedPreferenceManager.token}",
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{
|
||||
if (it.success && it.data != null) {
|
||||
_categoryListLiveData.value = it.data!!
|
||||
} 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("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
package kr.co.vividnext.sodalive.audio_content.category
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kr.co.vividnext.sodalive.databinding.ItemContentCategoryBinding
|
||||
|
||||
class AudioContentCategoryAdapter(
|
||||
private val onClick: (Long) -> Unit
|
||||
) : RecyclerView.Adapter<AudioContentCategoryAdapter.ViewHolder>() {
|
||||
|
||||
private val items = mutableListOf<GetCategoryListResponse>()
|
||||
private var selectedCategory = ""
|
||||
|
||||
inner class ViewHolder(
|
||||
private val context: Context,
|
||||
private val binding: ItemContentCategoryBinding
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun bind(item: GetCategoryListResponse) {
|
||||
if (
|
||||
item.category == selectedCategory ||
|
||||
(selectedCategory == "" && item.category == "전체")
|
||||
) {
|
||||
binding.tvCategory.setBackgroundResource(
|
||||
R.drawable.bg_round_corner_16_7_transparent_3bb9f1
|
||||
)
|
||||
binding.tvCategory.setTextColor(
|
||||
ContextCompat.getColor(context, R.color.color_3bb9f1)
|
||||
)
|
||||
} else {
|
||||
binding.tvCategory.setBackgroundResource(
|
||||
R.drawable.bg_round_corner_16_7_transparent_777777
|
||||
)
|
||||
binding.tvCategory.setTextColor(
|
||||
ContextCompat.getColor(context, R.color.color_777777)
|
||||
)
|
||||
}
|
||||
|
||||
binding.tvCategory.text = item.category
|
||||
binding.root.setOnClickListener {
|
||||
onClick(item.categoryId)
|
||||
selectedCategory = item.category
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun addItems(items: List<GetCategoryListResponse>) {
|
||||
this.selectedCategory = ""
|
||||
this.items.clear()
|
||||
this.items.addAll(items)
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
|
||||
parent.context,
|
||||
ItemContentCategoryBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
)
|
||||
)
|
||||
|
||||
override fun getItemCount() = items.size
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
holder.bind(items[position])
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
this.items.clear()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package kr.co.vividnext.sodalive.audio_content.category
|
||||
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Header
|
||||
import retrofit2.http.Query
|
||||
|
||||
interface CategoryApi {
|
||||
@GET("/category")
|
||||
fun getCategoryList(
|
||||
@Query("creatorId") creatorId: Long,
|
||||
@Header("Authorization") authHeader: String
|
||||
): Single<ApiResponse<List<GetCategoryListResponse>>>
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package kr.co.vividnext.sodalive.audio_content.category
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class GetCategoryListResponse(
|
||||
@SerializedName("categoryId") val categoryId: Long,
|
||||
@SerializedName("category") val category: String
|
||||
)
|
|
@ -9,6 +9,7 @@ import kr.co.vividnext.sodalive.audio_content.AudioContentViewModel
|
|||
import kr.co.vividnext.sodalive.audio_content.PlaybackTrackingRepository
|
||||
import kr.co.vividnext.sodalive.audio_content.all.AudioContentNewAllViewModel
|
||||
import kr.co.vividnext.sodalive.audio_content.all.AudioContentRankingAllViewModel
|
||||
import kr.co.vividnext.sodalive.audio_content.category.CategoryApi
|
||||
import kr.co.vividnext.sodalive.audio_content.comment.AudioContentCommentListViewModel
|
||||
import kr.co.vividnext.sodalive.audio_content.comment.AudioContentCommentReplyViewModel
|
||||
import kr.co.vividnext.sodalive.audio_content.comment.AudioContentCommentRepository
|
||||
|
@ -162,6 +163,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
|
|||
single { ApiBuilder().build(get(), MemberTagApi::class.java) }
|
||||
single { ApiBuilder().build(get(), RouletteApi::class.java) }
|
||||
single { ApiBuilder().build(get(), CreatorCommunityApi::class.java) }
|
||||
single { ApiBuilder().build(get(), CategoryApi::class.java) }
|
||||
}
|
||||
|
||||
private val viewModelModule = module {
|
||||
|
@ -240,7 +242,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
|
|||
factory { ExplorerRepository(get()) }
|
||||
factory { MessageRepository(get()) }
|
||||
factory { NoticeRepository(get()) }
|
||||
factory { AudioContentRepository(get(), get()) }
|
||||
factory { AudioContentRepository(get(), get(), get()) }
|
||||
factory { AudioContentCommentRepository(get()) }
|
||||
factory { PlaybackTrackingRepository(get()) }
|
||||
factory { FollowingCreatorRepository(get(), get()) }
|
||||
|
|
|
@ -9,6 +9,15 @@
|
|||
android:id="@+id/toolbar"
|
||||
layout="@layout/detail_toolbar" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_category"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="13.3dp"
|
||||
android:clipToPadding="false"
|
||||
android:padding="13.3dp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_new_content"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_category"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_round_corner_16_7_transparent_777777"
|
||||
android:paddingHorizontal="13.3dp"
|
||||
android:paddingVertical="9dp"
|
||||
android:textColor="@color/color_777777"
|
||||
android:textSize="14.7sp"
|
||||
tools:text="남공여수" />
|
||||
</FrameLayout>
|
Loading…
Reference in New Issue