From bdac7b789954dab9e6bcd845efa1beece1fd85fc Mon Sep 17 00:00:00 2001 From: klaus Date: Mon, 21 Jul 2025 18:44:59 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=A9=94=EC=9D=B8=20=ED=99=88=20-=20?= =?UTF-8?q?=EC=9D=B8=EA=B8=B0=20=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20-=20=ED=8C=94=EB=A1=9C=EC=9A=B0/=EC=96=B8=ED=8C=94?= =?UTF-8?q?=EB=A1=9C=EC=9A=B0=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/kr/co/vividnext/sodalive/di/AppDI.kt | 2 +- .../sodalive/explorer/GetExplorerResponse.kt | 2 +- .../sodalive/home/CreatorRankingAdapter.kt | 19 +++++++-- .../vividnext/sodalive/home/HomeFragment.kt | 37 +++++++++++------ .../vividnext/sodalive/home/HomeViewModel.kt | 40 ++++++++++++++++++- 5 files changed, 81 insertions(+), 19 deletions(-) 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 c3eff15a..8cc92ad4 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 @@ -340,7 +340,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) { viewModel { AlarmContentAllViewModel(get()) } viewModel { SearchViewModel(get()) } viewModel { PointStatusViewModel(get()) } - viewModel { HomeViewModel(get()) } + viewModel { HomeViewModel(get(), get()) } } private val repositoryModule = module { diff --git a/app/src/main/java/kr/co/vividnext/sodalive/explorer/GetExplorerResponse.kt b/app/src/main/java/kr/co/vividnext/sodalive/explorer/GetExplorerResponse.kt index aedc1d6e..10b12be7 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/explorer/GetExplorerResponse.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/explorer/GetExplorerResponse.kt @@ -23,5 +23,5 @@ data class GetExplorerSectionCreatorResponse( @SerializedName("nickname") val nickname: String, @SerializedName("tags") val tags: String, @SerializedName("profileImageUrl") val profileImageUrl: String, - @SerializedName("followerCount") val followerCount: Int + @SerializedName("follow") var follow: Boolean ) diff --git a/app/src/main/java/kr/co/vividnext/sodalive/home/CreatorRankingAdapter.kt b/app/src/main/java/kr/co/vividnext/sodalive/home/CreatorRankingAdapter.kt index 857f92a4..a2b87c2f 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/home/CreatorRankingAdapter.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/home/CreatorRankingAdapter.kt @@ -14,7 +14,8 @@ import kr.co.vividnext.sodalive.databinding.ItemHomeCreatorBinding import kr.co.vividnext.sodalive.explorer.GetExplorerSectionCreatorResponse class CreatorRankingAdapter( - private val onClickItem: (Long) -> Unit + private val onClickItem: (Long) -> Unit, + private val onClickFollow: (Long, Boolean) -> Unit ) : RecyclerView.Adapter() { private val items = mutableListOf() @@ -24,8 +25,6 @@ class CreatorRankingAdapter( private val binding: ItemHomeCreatorBinding ) : RecyclerView.ViewHolder(binding.root) { fun bind(item: GetExplorerSectionCreatorResponse, index: Int) { - binding.root.setOnClickListener { onClickItem(item.id) } - Glide .with(context) .load(item.profileImageUrl) @@ -58,6 +57,20 @@ class CreatorRankingAdapter( 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) } } } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/home/HomeFragment.kt b/app/src/main/java/kr/co/vividnext/sodalive/home/HomeFragment.kt index c95a5640..0bab7675 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/home/HomeFragment.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/home/HomeFragment.kt @@ -277,20 +277,33 @@ class HomeFragment : BaseFragment(FragmentHomeBinding::infl ) binding.tvFamousCreatorTitle.text = spSectionTitle - creatorRankingAdapter = CreatorRankingAdapter { - if (SharedPreferenceManager.token.isNotBlank()) { - startActivity( - Intent( - requireActivity(), - UserProfileActivity::class.java - ).apply { - putExtra(Constants.EXTRA_USER_ID, it) + creatorRankingAdapter = CreatorRankingAdapter( + onClickItem = { + if (SharedPreferenceManager.token.isNotBlank()) { + startActivity( + Intent( + requireActivity(), + UserProfileActivity::class.java + ).apply { + putExtra(Constants.EXTRA_USER_ID, it) + } + ) + } else { + (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() + } else { + (requireActivity() as MainActivity).showLoginActivity() + } } - } + ) val recyclerView = binding.rvFamousCreator recyclerView.layoutManager = LinearLayoutManager( diff --git a/app/src/main/java/kr/co/vividnext/sodalive/home/HomeViewModel.kt b/app/src/main/java/kr/co/vividnext/sodalive/home/HomeViewModel.kt index 108cc7b3..3c3bda78 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/home/HomeViewModel.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/home/HomeViewModel.kt @@ -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.v2.GetContentCurationResponse 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.common.SharedPreferenceManager import kr.co.vividnext.sodalive.explorer.GetExplorerSectionCreatorResponse 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) val isLoading: LiveData @@ -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("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.") + } + ) + ) + } }