크리에이터 채널

- 시리즈 section 추가
This commit is contained in:
klaus 2024-04-25 17:14:19 +09:00
parent a5df8a1110
commit cd607425a0
11 changed files with 414 additions and 0 deletions

View File

@ -0,0 +1,24 @@
package kr.co.vividnext.sodalive.audio_content.series
data class GetSeriesListResponse(
val totalCount: Int,
val items: List<SeriesListItem>
) {
data class SeriesListItem(
val seriesId: Long,
val title: String,
val coverImage: String,
val publishedDaysOfWeek: String,
val isComplete: Boolean,
val creator: SeriesListItemCreator,
val numberOfContent: Int,
val isNew: Boolean,
val isPopular: Boolean
)
data class SeriesListItemCreator(
val creatorId: Long,
val nickname: String,
val profileImage: String
)
}

View File

@ -1,6 +1,7 @@
package kr.co.vividnext.sodalive.explorer.profile package kr.co.vividnext.sodalive.explorer.profile
import com.google.gson.annotations.SerializedName import com.google.gson.annotations.SerializedName
import kr.co.vividnext.sodalive.audio_content.series.GetSeriesListResponse
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostListResponse import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostListResponse
data class GetCreatorProfileResponse( data class GetCreatorProfileResponse(
@ -20,6 +21,8 @@ data class GetCreatorProfileResponse(
val cheers: GetCheersResponse, val cheers: GetCheersResponse,
@SerializedName("activitySummary") @SerializedName("activitySummary")
val activitySummary: GetCreatorActivitySummary, val activitySummary: GetCreatorActivitySummary,
@SerializedName("seriesList")
val seriesList: List<GetSeriesListResponse.SeriesListItem>,
@SerializedName("isBlock") @SerializedName("isBlock")
val isBlock: Boolean val isBlock: Boolean
) )

View File

@ -26,6 +26,7 @@ import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.audio_content.AudioContentActivity import kr.co.vividnext.sodalive.audio_content.AudioContentActivity
import kr.co.vividnext.sodalive.audio_content.AudioContentAdapter import kr.co.vividnext.sodalive.audio_content.AudioContentAdapter
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
import kr.co.vividnext.sodalive.audio_content.series.GetSeriesListResponse
import kr.co.vividnext.sodalive.audio_content.upload.AudioContentUploadActivity import kr.co.vividnext.sodalive.audio_content.upload.AudioContentUploadActivity
import kr.co.vividnext.sodalive.base.BaseActivity import kr.co.vividnext.sodalive.base.BaseActivity
import kr.co.vividnext.sodalive.base.SodaDialog import kr.co.vividnext.sodalive.base.SodaDialog
@ -42,6 +43,7 @@ import kr.co.vividnext.sodalive.explorer.profile.donation.UserProfileDonationAda
import kr.co.vividnext.sodalive.explorer.profile.donation.UserProfileDonationAllViewActivity import kr.co.vividnext.sodalive.explorer.profile.donation.UserProfileDonationAllViewActivity
import kr.co.vividnext.sodalive.explorer.profile.fantalk.UserProfileFantalkAllViewActivity import kr.co.vividnext.sodalive.explorer.profile.fantalk.UserProfileFantalkAllViewActivity
import kr.co.vividnext.sodalive.explorer.profile.follow.UserFollowerListActivity import kr.co.vividnext.sodalive.explorer.profile.follow.UserFollowerListActivity
import kr.co.vividnext.sodalive.explorer.profile.series.CreatorChannelSeriesAdapter
import kr.co.vividnext.sodalive.extensions.dpToPx import kr.co.vividnext.sodalive.extensions.dpToPx
import kr.co.vividnext.sodalive.extensions.loadUrl import kr.co.vividnext.sodalive.extensions.loadUrl
import kr.co.vividnext.sodalive.extensions.moneyFormat import kr.co.vividnext.sodalive.extensions.moneyFormat
@ -70,6 +72,7 @@ class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
private lateinit var loadingDialog: LoadingDialog private lateinit var loadingDialog: LoadingDialog
private lateinit var liveAdapter: UserProfileLiveAdapter private lateinit var liveAdapter: UserProfileLiveAdapter
private lateinit var audioContentAdapter: AudioContentAdapter private lateinit var audioContentAdapter: AudioContentAdapter
private lateinit var seriesAdapter: CreatorChannelSeriesAdapter
private lateinit var donationAdapter: UserProfileDonationAdapter private lateinit var donationAdapter: UserProfileDonationAdapter
private lateinit var cheersAdapter: UserProfileCheersAdapter private lateinit var cheersAdapter: UserProfileCheersAdapter
@ -117,6 +120,7 @@ class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
setupLiveView() setupLiveView()
setupDonationView() setupDonationView()
setupFanTalkView() setupFanTalkView()
setupSeriesListView()
setupAudioContentListView() setupAudioContentListView()
setupCreatorCommunityView() setupCreatorCommunityView()
} }
@ -415,6 +419,53 @@ class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
rvCheers.adapter = cheersAdapter rvCheers.adapter = cheersAdapter
} }
private fun setupSeriesListView() {
binding.layoutCreatorChannelSeries.tvAll.setOnClickListener { }
val recyclerView = binding.layoutCreatorChannelSeries.rvSeries
recyclerView.layoutManager = LinearLayoutManager(
applicationContext,
LinearLayoutManager.HORIZONTAL,
false
)
seriesAdapter = CreatorChannelSeriesAdapter(
onClickItem = {},
onClickCreator = {},
isVisibleCreator = false
)
recyclerView.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()
}
seriesAdapter.itemCount - 1 -> {
outRect.right = 0
outRect.left = 6.7f.dpToPx().toInt()
}
else -> {
outRect.left = 6.7f.dpToPx().toInt()
outRect.right = 6.7f.dpToPx().toInt()
}
}
}
})
recyclerView.adapter = seriesAdapter
}
private fun setupAudioContentListView() { private fun setupAudioContentListView() {
binding.layoutUserProfileAudioContent.tvAll.setOnClickListener { binding.layoutUserProfileAudioContent.tvAll.setOnClickListener {
val intent = Intent(applicationContext, AudioContentActivity::class.java) val intent = Intent(applicationContext, AudioContentActivity::class.java)
@ -517,6 +568,7 @@ class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
viewModel.creatorProfileLiveData.observe(this) { viewModel.creatorProfileLiveData.observe(this) {
setCheers(it.cheers) setCheers(it.cheers)
setSeriesList(it.seriesList)
setCreatorProfile(it.creator) setCreatorProfile(it.creator)
setAudioContentList(it.contentList) setAudioContentList(it.contentList)
setLiveRoomList(it.liveRoomList) setLiveRoomList(it.liveRoomList)
@ -550,6 +602,19 @@ class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
} }
} }
@SuppressLint("NotifyDataSetChanged")
private fun setSeriesList(seriesList: List<GetSeriesListResponse.SeriesListItem>) {
if (seriesList.isNotEmpty()) {
binding.layoutCreatorChannelSeries.root.visibility = View.VISIBLE
} else {
binding.layoutCreatorChannelSeries.root.visibility = View.GONE
}
seriesAdapter.items.clear()
seriesAdapter.items.addAll(seriesList)
seriesAdapter.notifyDataSetChanged()
}
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
private fun setCreatorProfile(creator: CreatorResponse) { private fun setCreatorProfile(creator: CreatorResponse) {
val layoutUserProfile = binding.layoutUserProfile val layoutUserProfile = binding.layoutUserProfile

View File

@ -0,0 +1,88 @@
package kr.co.vividnext.sodalive.explorer.profile.series
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import coil.load
import coil.transform.CircleCropTransformation
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.ItemSeriesListBinding
import kr.co.vividnext.sodalive.extensions.dpToPx
class CreatorChannelSeriesAdapter(
private val onClickItem: (Long) -> Unit,
private val onClickCreator: (Long) -> Unit,
private val isVisibleCreator: Boolean
) : RecyclerView.Adapter<CreatorChannelSeriesAdapter.ViewHolder>() {
val items = mutableListOf<GetSeriesListResponse.SeriesListItem>()
inner class ViewHolder(
private val binding: ItemSeriesListBinding
) : RecyclerView.ViewHolder(binding.root) {
@SuppressLint("SetTextI18n")
fun bind(item: GetSeriesListResponse.SeriesListItem) {
binding.ivCover.load(item.coverImage) {
crossfade(true)
placeholder(R.drawable.bg_placeholder)
transformations(RoundedCornersTransformation(5f.dpToPx()))
}
binding.tvTitle.text = item.title
binding.tvSeriesContentCount.text = "${item.numberOfContent}"
binding.tvPublishedDaysOfWeek.text = item.publishedDaysOfWeek
binding.tvNew.visibility = if (item.isNew) {
View.VISIBLE
} else {
View.GONE
}
binding.tvPopular.visibility = if (item.isPopular) {
View.VISIBLE
} else {
View.GONE
}
if (item.isComplete) {
binding.tvNew.visibility = View.GONE
binding.tvComplete.visibility = View.VISIBLE
} else {
binding.tvComplete.visibility = View.GONE
}
if (isVisibleCreator) {
binding.llCreator.visibility = View.VISIBLE
binding.tvCreator.text = item.creator.nickname
binding.ivCreator.load(item.creator.profileImage) {
crossfade(true)
placeholder(R.drawable.ic_place_holder)
transformations(CircleCropTransformation())
}
binding.llCreator.setOnClickListener { onClickCreator(item.creator.creatorId) }
} else {
binding.llCreator.visibility = View.GONE
}
binding.root.setOnClickListener { onClickItem(item.seriesId) }
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
ItemSeriesListBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(items[position])
}
override fun getItemCount() = items.count()
}

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/color_002abd" />
<corners android:radius="13.3dp" />
<stroke
android:width="1dp"
android:color="@color/color_002abd" />
</shape>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/color_3bb9f1" />
<corners android:radius="13.3dp" />
<stroke
android:width="1dp"
android:color="@color/color_3bb9f1" />
</shape>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/color_ec6033" />
<corners android:radius="13.3dp" />
<stroke
android:width="1dp"
android:color="@color/color_ec6033" />
</shape>

View File

@ -211,6 +211,15 @@
android:layout_marginHorizontal="13.3dp" android:layout_marginHorizontal="13.3dp"
android:layout_marginTop="26.7dp" /> android:layout_marginTop="26.7dp" />
<include
android:id="@+id/layout_creator_channel_series"
layout="@layout/layout_creator_channel_series"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="13.3dp"
android:layout_marginTop="26.7dp"
android:visibility="gone" />
<include <include
android:id="@+id/layout_user_profile_audio_content" android:id="@+id/layout_user_profile_audio_content"
layout="@layout/layout_user_profile_audio_content" layout="@layout/layout_user_profile_audio_content"

View File

@ -0,0 +1,161 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<FrameLayout
android:id="@+id/fl_cover"
android:layout_width="117dp"
android:layout_height="165dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/iv_cover"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@null"
android:scaleType="centerCrop"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/ic_launcher_background" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/gradient_live_room_item" />
</FrameLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="3.3dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="@+id/fl_cover"
app:layout_constraintStart_toStartOf="@+id/fl_cover"
app:layout_constraintTop_toTopOf="@+id/fl_cover">
<TextView
android:id="@+id/tv_new"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="3.3dp"
android:background="@drawable/bg_round_corner_13_3_3bb9f1"
android:fontFamily="@font/gmarket_sans_medium"
android:paddingHorizontal="5.3dp"
android:paddingVertical="3.7dp"
android:text="신작"
android:textColor="@color/white"
android:textSize="10.3sp"
android:visibility="gone"
tools:ignore="SmallSp" />
<TextView
android:id="@+id/tv_complete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="3.3dp"
android:background="@drawable/bg_round_corner_13_3_002abd"
android:fontFamily="@font/gmarket_sans_medium"
android:paddingHorizontal="5.3dp"
android:paddingVertical="3.7dp"
android:text="완결"
android:textColor="@color/white"
android:textSize="10.3sp"
android:visibility="gone"
tools:ignore="SmallSp" />
<TextView
android:id="@+id/tv_popular"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="3.3dp"
android:background="@drawable/bg_round_corner_13_3_ec6033"
android:fontFamily="@font/gmarket_sans_medium"
android:paddingHorizontal="5.3dp"
android:paddingVertical="3.7dp"
android:text="인기"
android:textColor="@color/white"
android:textSize="10.3sp"
android:visibility="gone"
tools:ignore="SmallSp" />
</LinearLayout>
<TextView
android:id="@+id/tv_series_content_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="3.3dp"
android:background="@drawable/bg_round_corner_13_3_b3333333"
android:fontFamily="@font/gmarket_sans_medium"
android:paddingHorizontal="5.3dp"
android:paddingVertical="2.7dp"
android:textColor="@color/white"
android:textSize="10.3sp"
app:layout_constraintBottom_toBottomOf="@+id/fl_cover"
app:layout_constraintEnd_toEndOf="@+id/fl_cover"
tools:ignore="SmallSp"
tools:text="총 24화" />
<TextView
android:id="@+id/tv_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/gmarket_sans_medium"
android:maxLines="2"
android:textColor="@color/color_eeeeee"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/fl_cover"
tools:text="제목, 관심사,프로필+방장, 참여인원(어딘가..)" />
<LinearLayout
android:id="@+id/ll_creator"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv_creator"
android:layout_width="16dp"
android:layout_height="16dp"
android:contentDescription="@null"
tools:src="@drawable/ic_launcher_background" />
<TextView
android:id="@+id/tv_creator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="3dp"
android:fontFamily="@font/gmarket_sans_medium"
android:lines="1"
android:maxLines="1"
android:textColor="@color/color_777777"
android:textSize="10sp"
tools:ignore="SmallSp"
tools:text="pgwkill" />
</LinearLayout>
<TextView
android:id="@+id/tv_published_days_of_week"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_777777"
android:textSize="11sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/ll_creator"
tools:text="매주 수, 토요일" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/gmarket_sans_bold"
android:text="시리즈"
android:textColor="@color/color_eeeeee"
android:textSize="18.3sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/gmarket_sans_light"
android:text="전체보기"
android:textColor="@color/color_eeeeee"
android:textSize="11.3sp"
app:layout_constraintBottom_toBottomOf="@+id/tv_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/tv_title" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_series"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="13.3dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -114,4 +114,6 @@
<color name="color_ffecf7">#FFECF7</color> <color name="color_ffecf7">#FFECF7</color>
<color name="color_ecf9ff">#ECF9FF</color> <color name="color_ecf9ff">#ECF9FF</color>
<color name="color_14262d">#14262D</color> <color name="color_14262d">#14262D</color>
<color name="color_ec6033">#EC6033</color>
<color name="color_002abd">#002ABD</color>
</resources> </resources>