From 116dde1b7e1be5ae75f576644aa6b21858ab614c Mon Sep 17 00:00:00 2001 From: klaus Date: Sat, 23 Dec 2023 00:03:03 +0900 Subject: [PATCH] =?UTF-8?q?=EB=A9=94=EC=9D=B8=20=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=20=ED=83=AD=20-=20=EC=BB=A4=EB=AE=A4=EB=8B=88?= =?UTF-8?q?=ED=8B=B0=20=ED=8F=AC=EC=8A=A4=ED=8A=B8=20=EC=98=81=EC=97=AD=20?= =?UTF-8?q?=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 | 6 +- .../CreatorCommunityAdapter.kt | 58 +++++++++++++++++++ .../creator_community/CreatorCommunityApi.kt | 24 ++++++++ .../CreatorCommunityRepository.kt | 25 ++++++++ .../vividnext/sodalive/live/LiveFragment.kt | 56 ++++++++++++++++++ .../vividnext/sodalive/live/LiveViewModel.kt | 40 ++++++++++++- app/src/main/res/layout/fragment_live.xml | 6 ++ 7 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/CreatorCommunityAdapter.kt create mode 100644 app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/CreatorCommunityApi.kt create mode 100644 app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/CreatorCommunityRepository.kt 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 f869678..8839b2f 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 @@ -30,6 +30,8 @@ import kr.co.vividnext.sodalive.explorer.ExplorerApi import kr.co.vividnext.sodalive.explorer.ExplorerRepository import kr.co.vividnext.sodalive.explorer.ExplorerViewModel import kr.co.vividnext.sodalive.explorer.profile.UserProfileViewModel +import kr.co.vividnext.sodalive.explorer.profile.creator_community.CreatorCommunityApi +import kr.co.vividnext.sodalive.explorer.profile.creator_community.CreatorCommunityRepository import kr.co.vividnext.sodalive.explorer.profile.donation.UserProfileDonationAllViewModel import kr.co.vividnext.sodalive.explorer.profile.fantalk.UserProfileFantalkAllViewModel import kr.co.vividnext.sodalive.explorer.profile.follow.UserFollowerListViewModel @@ -154,6 +156,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) { single { ApiBuilder().build(get(), FaqApi::class.java) } single { ApiBuilder().build(get(), MemberTagApi::class.java) } single { ApiBuilder().build(get(), RouletteApi::class.java) } + single { ApiBuilder().build(get(), CreatorCommunityApi::class.java) } } private val viewModelModule = module { @@ -162,7 +165,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) { viewModel { TermsViewModel(get()) } viewModel { FindPasswordViewModel(get()) } viewModel { MainViewModel(get(), get(), get(), get()) } - viewModel { LiveViewModel(get(), get(), get()) } + viewModel { LiveViewModel(get(), get(), get(), get()) } viewModel { MyPageViewModel(get(), get()) } viewModel { CanStatusViewModel(get()) } viewModel { CanChargeViewModel(get()) } @@ -235,6 +238,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) { factory { MemberTagRepository(get()) } factory { UserProfileFantalkAllViewModel(get(), get()) } factory { RouletteRepository(get()) } + factory { CreatorCommunityRepository(get()) } } private val moduleList = listOf( diff --git a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/CreatorCommunityAdapter.kt b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/CreatorCommunityAdapter.kt new file mode 100644 index 0000000..1a8c872 --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/CreatorCommunityAdapter.kt @@ -0,0 +1,58 @@ +package kr.co.vividnext.sodalive.explorer.profile.creator_community + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import coil.transform.CircleCropTransformation +import coil.transform.RoundedCornersTransformation +import kr.co.vividnext.sodalive.R +import kr.co.vividnext.sodalive.databinding.ItemCreatorCommunityBinding +import kr.co.vividnext.sodalive.extensions.dpToPx +import kr.co.vividnext.sodalive.extensions.loadUrl + +class CreatorCommunityAdapter( + private val onClickItem: (Long) -> Unit +) : RecyclerView.Adapter() { + + val items = mutableListOf() + + inner class ViewHolder( + private val binding: ItemCreatorCommunityBinding + ) : RecyclerView.ViewHolder(binding.root) { + fun bind(item: GetCommunityPostListResponse) { + binding.ivCreatorProfile.loadUrl(item.creatorProfileUrl) { + crossfade(true) + placeholder(R.drawable.ic_place_holder) + transformations(CircleCropTransformation()) + } + binding.tvCreatorNickname.text = item.creatorNickname + binding.tvDate.text = item.date + + binding.tvContent.text = item.content + binding.ivPostImage.loadUrl(item.imageUrl) { + crossfade(true) + placeholder(R.drawable.ic_place_holder) + transformations(RoundedCornersTransformation(4.7f.dpToPx())) + } + + binding.tvLikeCount.text = "${item.likeCount}" + binding.tvCommentCount.text = "${item.commentCount}" + + binding.root.setOnClickListener { onClickItem(item.creatorId) } + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder( + ItemCreatorCommunityBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) + ) + + override fun getItemCount() = items.size + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.bind(items[position]) + } +} diff --git a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/CreatorCommunityApi.kt b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/CreatorCommunityApi.kt new file mode 100644 index 0000000..b4fd776 --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/CreatorCommunityApi.kt @@ -0,0 +1,24 @@ +package kr.co.vividnext.sodalive.explorer.profile.creator_community + +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 CreatorCommunityApi { + @GET("/creator-community") + fun getCommunityPostList( + @Query("creatorId") creatorId: Long, + @Query("page") page: Int, + @Query("size") size: Int, + @Query("timezone") timezone: String, + @Header("Authorization") authHeader: String + ): Single>> + + @GET("/creator-community/latest") + fun getLatestPostListFromCreatorsYouFollow( + @Query("timezone") timezone: String, + @Header("Authorization") authHeader: String + ): Single>> +} diff --git a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/CreatorCommunityRepository.kt b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/CreatorCommunityRepository.kt new file mode 100644 index 0000000..6b9e3bd --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/CreatorCommunityRepository.kt @@ -0,0 +1,25 @@ +package kr.co.vividnext.sodalive.explorer.profile.creator_community + +import java.util.TimeZone + +class CreatorCommunityRepository(private val api: CreatorCommunityApi) { + fun getCommunityPostList( + creatorId: Long, + page: Int, + size: Int, + token: String + ) = api.getCommunityPostList( + creatorId = creatorId, + page = page - 1, + size = size, + timezone = TimeZone.getDefault().id, + authHeader = token + ) + + fun getLatestPostListFromCreatorsYouFollow( + token: String + ) = api.getLatestPostListFromCreatorsYouFollow( + timezone = TimeZone.getDefault().id, + authHeader = token + ) +} diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/LiveFragment.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/LiveFragment.kt index 613439a..a5a09c5 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/live/LiveFragment.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/LiveFragment.kt @@ -27,6 +27,7 @@ import kr.co.vividnext.sodalive.common.LoadingDialog import kr.co.vividnext.sodalive.common.SharedPreferenceManager import kr.co.vividnext.sodalive.databinding.FragmentLiveBinding import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity +import kr.co.vividnext.sodalive.explorer.profile.creator_community.CreatorCommunityAdapter import kr.co.vividnext.sodalive.extensions.dpToPx import kr.co.vividnext.sodalive.extensions.moneyFormat import kr.co.vividnext.sodalive.following.FollowingCreatorActivity @@ -56,6 +57,7 @@ class LiveFragment : BaseFragment(FragmentLiveBinding::infl private lateinit var liveNowAdapter: LiveNowAdapter private lateinit var liveReservationAdapter: LiveReservationAdapter + private lateinit var creatorCommunityAdapter: CreatorCommunityAdapter private lateinit var liveRecommendChannelAdapter: LiveRecommendChannelAdapter private lateinit var loadingDialog: LoadingDialog @@ -91,6 +93,7 @@ class LiveFragment : BaseFragment(FragmentLiveBinding::infl setupLiveNow() setupLiveReservation() setupEvent() + setupCommunityPost() message = "라이브를 불러오고 있습니다." viewModel.getSummary() @@ -494,6 +497,59 @@ class LiveFragment : BaseFragment(FragmentLiveBinding::infl } } + @SuppressLint("NotifyDataSetChanged") + private fun setupCommunityPost() { + val recyclerView = binding.rvCommunityPost + + recyclerView.layoutManager = LinearLayoutManager( + requireContext(), + LinearLayoutManager.HORIZONTAL, + 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 = 13.3f.dpToPx().toInt() + outRect.right = 5.dpToPx().toInt() + } + + liveNowAdapter.itemCount - 1 -> { + outRect.left = 6.7f.dpToPx().toInt() + outRect.right = 13.3f.dpToPx().toInt() + } + + else -> { + outRect.left = 6.7f.dpToPx().toInt() + outRect.right = 6.7f.dpToPx().toInt() + } + } + } + }) + + creatorCommunityAdapter = CreatorCommunityAdapter {} + binding.rvCommunityPost.adapter = creatorCommunityAdapter + + viewModel.communityPostItemLiveData.observe(viewLifecycleOwner) { + if (it.isNotEmpty()) { + binding.rvCommunityPost.visibility = View.VISIBLE + creatorCommunityAdapter.items.clear() + creatorCommunityAdapter.items.addAll(it) + creatorCommunityAdapter.notifyDataSetChanged() + } else { + binding.rvCommunityPost.visibility = View.GONE + } + } + } + private fun startLive(roomId: Long) { val onEnterRoomSuccess = { viewModel.getSummary() diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/LiveViewModel.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/LiveViewModel.kt index f2cf4e5..612a085 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/live/LiveViewModel.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/LiveViewModel.kt @@ -8,6 +8,8 @@ import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.schedulers.Schedulers import kr.co.vividnext.sodalive.base.BaseViewModel import kr.co.vividnext.sodalive.common.SharedPreferenceManager +import kr.co.vividnext.sodalive.explorer.profile.creator_community.CreatorCommunityRepository +import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostListResponse import kr.co.vividnext.sodalive.live.recommend.GetRecommendLiveResponse import kr.co.vividnext.sodalive.live.recommend.LiveRecommendRepository import kr.co.vividnext.sodalive.live.recommend_channel.GetRecommendChannelResponse @@ -24,7 +26,8 @@ import kr.co.vividnext.sodalive.settings.event.EventRepository class LiveViewModel( private val repository: LiveRepository, private val eventRepository: EventRepository, - private val liveRecommendRepository: LiveRecommendRepository + private val liveRecommendRepository: LiveRecommendRepository, + private val creatorCommunityRepository: CreatorCommunityRepository ) : BaseViewModel() { private var _isLoading = MutableLiveData(false) val isLoading: LiveData @@ -60,6 +63,10 @@ class LiveViewModel( val eventLiveData: LiveData> get() = _eventLiveData + private val _communityPostItemLiveData = MutableLiveData>() + val communityPostItemLiveData: LiveData> + get() = _communityPostItemLiveData + var page = 1 var isLast = false private val pageSize = 10 @@ -135,6 +142,36 @@ class LiveViewModel( ) } + private fun getLatestPostListFromCreatorsYouFollow() { + compositeDisposable.add( + creatorCommunityRepository.getLatestPostListFromCreatorsYouFollow( + token = "Bearer ${SharedPreferenceManager.token}" + ) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + { + if (it.success && it.data != null) { + _communityPostItemLiveData.postValue(it.data!!) + } else { + if (it.message != null) { + _toastLiveData.postValue(it.message) + } else { + _toastLiveData.postValue( + "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요." + ) + } + } + }, + { + _isLoading.value = false + it.message?.let { message -> Logger.e(message) } + _toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.") + } + ) + ) + } + fun getSummary() { if (!_isLoading.value!!) { if (_isFollowedCreatorLive.value!!) { @@ -142,6 +179,7 @@ class LiveViewModel( } else { getRecommendChannelList() } + getLatestPostListFromCreatorsYouFollow() val liveNow = repository.roomList( status = LiveRoomStatus.NOW, diff --git a/app/src/main/res/layout/fragment_live.xml b/app/src/main/res/layout/fragment_live.xml index 566abc3..c3f8985 100644 --- a/app/src/main/res/layout/fragment_live.xml +++ b/app/src/main/res/layout/fragment_live.xml @@ -54,6 +54,12 @@ android:layout_gravity="center" android:layout_marginTop="6.7dp" /> + +