feat: 메인 홈 - 인기 크리에이터

- 팔로우/언팔로우 기능 추가
This commit is contained in:
2025-07-21 18:44:59 +09:00
parent 58bc42cc0f
commit bdac7b7899
5 changed files with 81 additions and 19 deletions

View File

@@ -340,7 +340,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
viewModel { AlarmContentAllViewModel(get()) } viewModel { AlarmContentAllViewModel(get()) }
viewModel { SearchViewModel(get()) } viewModel { SearchViewModel(get()) }
viewModel { PointStatusViewModel(get()) } viewModel { PointStatusViewModel(get()) }
viewModel { HomeViewModel(get()) } viewModel { HomeViewModel(get(), get()) }
} }
private val repositoryModule = module { private val repositoryModule = module {

View File

@@ -23,5 +23,5 @@ data class GetExplorerSectionCreatorResponse(
@SerializedName("nickname") val nickname: String, @SerializedName("nickname") val nickname: String,
@SerializedName("tags") val tags: String, @SerializedName("tags") val tags: String,
@SerializedName("profileImageUrl") val profileImageUrl: String, @SerializedName("profileImageUrl") val profileImageUrl: String,
@SerializedName("followerCount") val followerCount: Int @SerializedName("follow") var follow: Boolean
) )

View File

@@ -14,7 +14,8 @@ import kr.co.vividnext.sodalive.databinding.ItemHomeCreatorBinding
import kr.co.vividnext.sodalive.explorer.GetExplorerSectionCreatorResponse import kr.co.vividnext.sodalive.explorer.GetExplorerSectionCreatorResponse
class CreatorRankingAdapter( class CreatorRankingAdapter(
private val onClickItem: (Long) -> Unit private val onClickItem: (Long) -> Unit,
private val onClickFollow: (Long, Boolean) -> Unit
) : RecyclerView.Adapter<CreatorRankingAdapter.ViewHolder>() { ) : RecyclerView.Adapter<CreatorRankingAdapter.ViewHolder>() {
private val items = mutableListOf<GetExplorerSectionCreatorResponse>() private val items = mutableListOf<GetExplorerSectionCreatorResponse>()
@@ -24,8 +25,6 @@ class CreatorRankingAdapter(
private val binding: ItemHomeCreatorBinding private val binding: ItemHomeCreatorBinding
) : RecyclerView.ViewHolder(binding.root) { ) : RecyclerView.ViewHolder(binding.root) {
fun bind(item: GetExplorerSectionCreatorResponse, index: Int) { fun bind(item: GetExplorerSectionCreatorResponse, index: Int) {
binding.root.setOnClickListener { onClickItem(item.id) }
Glide Glide
.with(context) .with(context)
.load(item.profileImageUrl) .load(item.profileImageUrl)
@@ -58,6 +57,20 @@ class CreatorRankingAdapter(
binding.ivCrown.visibility = View.GONE binding.ivCrown.visibility = View.GONE
} }
} }
if (item.follow) {
binding.tvFollow.text = "팔로잉"
} else {
binding.tvFollow.text = "팔로우"
}
binding.tvFollow.setOnClickListener {
item.follow = !item.follow
notifyItemChanged(index)
onClickFollow(item.id, item.follow)
}
binding.root.setOnClickListener { onClickItem(item.id) }
} }
} }

View File

@@ -277,7 +277,8 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>(FragmentHomeBinding::infl
) )
binding.tvFamousCreatorTitle.text = spSectionTitle binding.tvFamousCreatorTitle.text = spSectionTitle
creatorRankingAdapter = CreatorRankingAdapter { creatorRankingAdapter = CreatorRankingAdapter(
onClickItem = {
if (SharedPreferenceManager.token.isNotBlank()) { if (SharedPreferenceManager.token.isNotBlank()) {
startActivity( startActivity(
Intent( Intent(
@@ -290,7 +291,19 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>(FragmentHomeBinding::infl
} else { } else {
(requireActivity() as MainActivity).showLoginActivity() (requireActivity() as MainActivity).showLoginActivity()
} }
},
onClickFollow = { creatorId, follow ->
if (SharedPreferenceManager.token.isNotBlank()) {
if (follow) {
viewModel.follow(creatorId, follow = true, notify = true)
} else {
viewModel.follow(creatorId, follow = false, notify = false)
} }
} else {
(requireActivity() as MainActivity).showLoginActivity()
}
}
)
val recyclerView = binding.rvFamousCreator val recyclerView = binding.rvFamousCreator
recyclerView.layoutManager = LinearLayoutManager( recyclerView.layoutManager = LinearLayoutManager(

View File

@@ -9,13 +9,16 @@ import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentBannerResponse
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRankingItem import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRankingItem
import kr.co.vividnext.sodalive.audio_content.main.v2.GetContentCurationResponse import kr.co.vividnext.sodalive.audio_content.main.v2.GetContentCurationResponse
import kr.co.vividnext.sodalive.audio_content.series.GetSeriesListResponse import kr.co.vividnext.sodalive.audio_content.series.GetSeriesListResponse
import kr.co.vividnext.sodalive.audition.GetAuditionListItem
import kr.co.vividnext.sodalive.base.BaseViewModel import kr.co.vividnext.sodalive.base.BaseViewModel
import kr.co.vividnext.sodalive.common.SharedPreferenceManager import kr.co.vividnext.sodalive.common.SharedPreferenceManager
import kr.co.vividnext.sodalive.explorer.GetExplorerSectionCreatorResponse import kr.co.vividnext.sodalive.explorer.GetExplorerSectionCreatorResponse
import kr.co.vividnext.sodalive.live.GetRoomListResponse import kr.co.vividnext.sodalive.live.GetRoomListResponse
import kr.co.vividnext.sodalive.user.UserRepository
class HomeViewModel(private val repository: HomeRepository) : BaseViewModel() { class HomeViewModel(
private val repository: HomeRepository,
private val userRepository: UserRepository
) : BaseViewModel() {
private var _isLoading = MutableLiveData(false) private var _isLoading = MutableLiveData(false)
val isLoading: LiveData<Boolean> val isLoading: LiveData<Boolean>
@@ -172,4 +175,37 @@ class HomeViewModel(private val repository: HomeRepository) : BaseViewModel() {
) )
) )
} }
fun follow(creatorId: Long, follow: Boolean = true, notify: Boolean = true) {
_isLoading.value = true
compositeDisposable.add(
userRepository.creatorFollow(
creatorId = creatorId,
follow,
notify,
token = "Bearer ${SharedPreferenceManager.token}"
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{
_isLoading.value = false
if (!it.success || it.data == null) {
if (it.message != null) {
_toastLiveData.postValue(it.message)
} else {
_toastLiveData.postValue(
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
)
}
}
},
{
_isLoading.value = false
it.message?.let { message -> Logger.e(message) }
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
}
)
)
}
} }