From 254a1e3381c44d4ba43ba8ecdce4398518280bc2 Mon Sep 17 00:00:00 2001 From: klaus Date: Tue, 7 May 2024 16:42:14 +0900 Subject: [PATCH] =?UTF-8?q?=EC=BD=98=ED=85=90=EC=B8=A0=20=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20-=20=EC=B6=94=EC=B2=9C=20=EC=8B=9C=EB=A6=AC?= =?UTF-8?q?=EC=A6=88=20UI=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/deploymentTargetSelector.xml | 10 + .../main/AudioContentMainFragment.kt | 80 +-- ...udioContentMainNewContentCreatorAdapter.kt | 53 -- ...dioContentMainRecommendSeriesViewModel.kt} | 30 +- .../audio_content/series/SeriesApi.kt | 5 + .../audio_content/series/SeriesRepository.kt | 2 + .../java/kr/co/vividnext/sodalive/di/AppDI.kt | 4 +- .../series/UserProfileSeriesListAdapter.kt | 1 - .../layout/fragment_audio_content_main.xml | 471 +++++++++--------- 9 files changed, 315 insertions(+), 341 deletions(-) create mode 100644 .idea/deploymentTargetSelector.xml delete mode 100644 app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/new_content_upload_creator/AudioContentMainNewContentCreatorAdapter.kt rename app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/{new_content_upload_creator/AudioContentMainNewContentCreatorViewModel.kt => recommend_series/AudioContentMainRecommendSeriesViewModel.kt} (59%) diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml new file mode 100644 index 0000000..b268ef3 --- /dev/null +++ b/.idea/deploymentTargetSelector.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/AudioContentMainFragment.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/AudioContentMainFragment.kt index 6d4d7a2..d1d3bf8 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/AudioContentMainFragment.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/AudioContentMainFragment.kt @@ -1,19 +1,18 @@ package kr.co.vividnext.sodalive.audio_content.main import android.annotation.SuppressLint -import android.app.Service import android.content.Intent import android.graphics.Rect import android.net.Uri import android.os.Bundle import android.view.View -import android.view.inputmethod.InputMethodManager import android.widget.LinearLayout import android.widget.Toast import androidx.core.content.ContextCompat import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.orhanobut.logger.Logger import com.zhpan.bannerview.BaseBannerAdapter import com.zhpan.indicator.enums.IndicatorSlideMode import com.zhpan.indicator.enums.IndicatorStyle @@ -29,18 +28,19 @@ import kr.co.vividnext.sodalive.audio_content.main.curation.AudioContentMainCura import kr.co.vividnext.sodalive.audio_content.main.curation.AudioContentMainCurationViewModel import kr.co.vividnext.sodalive.audio_content.main.new_content.AudioContentMainNewContentThemeAdapter import kr.co.vividnext.sodalive.audio_content.main.new_content.AudioContentMainNewContentViewModel -import kr.co.vividnext.sodalive.audio_content.main.new_content_upload_creator.AudioContentMainNewContentCreatorAdapter -import kr.co.vividnext.sodalive.audio_content.main.new_content_upload_creator.AudioContentMainNewContentCreatorViewModel import kr.co.vividnext.sodalive.audio_content.main.order.AudioContentMainOrderListViewModel import kr.co.vividnext.sodalive.audio_content.main.ranking.AudioContentMainRankingAdapter import kr.co.vividnext.sodalive.audio_content.main.ranking.AudioContentMainRankingViewModel +import kr.co.vividnext.sodalive.audio_content.main.recommend_series.AudioContentMainRecommendSeriesViewModel import kr.co.vividnext.sodalive.audio_content.order.AudioContentOrderListActivity +import kr.co.vividnext.sodalive.audio_content.series.detail.SeriesDetailActivity import kr.co.vividnext.sodalive.audio_content.upload.AudioContentUploadActivity import kr.co.vividnext.sodalive.base.BaseFragment import kr.co.vividnext.sodalive.common.Constants import kr.co.vividnext.sodalive.common.SharedPreferenceManager import kr.co.vividnext.sodalive.databinding.FragmentAudioContentMainBinding import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity +import kr.co.vividnext.sodalive.explorer.profile.series.UserProfileSeriesListAdapter import kr.co.vividnext.sodalive.extensions.dpToPx import kr.co.vividnext.sodalive.settings.event.EventDetailActivity import kr.co.vividnext.sodalive.settings.notification.MemberRole @@ -50,8 +50,8 @@ import kotlin.math.roundToInt class AudioContentMainFragment : BaseFragment( FragmentAudioContentMainBinding::inflate ) { - private val newContentCreatorViewModel: AudioContentMainNewContentCreatorViewModel by inject() - private lateinit var newContentCreatorAdapter: AudioContentMainNewContentCreatorAdapter + private val recommendSeriesViewModel: AudioContentMainRecommendSeriesViewModel by inject() + private lateinit var seriesAdapter: UserProfileSeriesListAdapter private val bannerViewModel: AudioContentMainBannerViewModel by inject() private lateinit var bannerAdapter: AudioContentMainBannerAdapter @@ -80,7 +80,7 @@ class AudioContentMainFragment : BaseFragment( newContentViewModel.getNewContentOfTheme("전체") contentRankingViewModel.getContentRanking() contentRankingViewModel.getContentRankingSortType() - newContentCreatorViewModel.getNewContentUploadCreatorList() + recommendSeriesViewModel.getRecommendSeriesList() } private fun setupView() { @@ -98,7 +98,7 @@ class AudioContentMainFragment : BaseFragment( binding.llUploadContent.visibility = View.GONE } - setupNewContentCreator() + setupRecommendSeries() setupBanner() setupOrderList() setupNewContentTheme() @@ -107,17 +107,6 @@ class AudioContentMainFragment : BaseFragment( setupContentRanking() setupCuration() - binding.swipeRefreshLayout.setOnRefreshListener { - binding.swipeRefreshLayout.isRefreshing = false - curationViewModel.refresh() - bannerViewModel.getMainBannerList() - newContentViewModel.getThemeList() - newContentViewModel.getNewContentOfTheme("전체") - contentRankingViewModel.getContentRanking() - contentRankingViewModel.getContentRankingSortType() - newContentCreatorViewModel.getNewContentUploadCreatorList() - } - binding.llShortPlay.setOnClickListener { startActivity( Intent(requireContext(), AudioContentAllByThemeActivity::class.java).apply { @@ -135,20 +124,33 @@ class AudioContentMainFragment : BaseFragment( } } - private fun setupNewContentCreator() { - newContentCreatorAdapter = AudioContentMainNewContentCreatorAdapter { - val intent = Intent(requireContext(), UserProfileActivity::class.java) - intent.putExtra(Constants.EXTRA_USER_ID, it) - startActivity(intent) - } + private fun setupRecommendSeries() { + seriesAdapter = UserProfileSeriesListAdapter( + onClickItem = { + startActivity( + Intent(requireContext(), SeriesDetailActivity::class.java).apply { + putExtra(Constants.EXTRA_SERIES_ID, it) + } + ) + }, + onClickCreator = { + startActivity( + Intent(requireContext(), UserProfileActivity::class.java).apply { + putExtra(Constants.EXTRA_USER_ID, it) + } + ) + }, + isVisibleCreator = true + ) - binding.rvNewContentCreator.layoutManager = LinearLayoutManager( - context, + val recyclerView = binding.rvRecommendSeries + recyclerView.layoutManager = LinearLayoutManager( + requireContext(), LinearLayoutManager.HORIZONTAL, false ) - binding.rvNewContentCreator.addItemDecoration(object : RecyclerView.ItemDecoration() { + recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() { override fun getItemOffsets( outRect: Rect, view: View, @@ -160,28 +162,28 @@ class AudioContentMainFragment : BaseFragment( when (parent.getChildAdapterPosition(view)) { 0 -> { outRect.left = 0 - outRect.right = 10.7f.dpToPx().toInt() + outRect.right = 6.7f.dpToPx().toInt() } - newContentCreatorAdapter.itemCount - 1 -> { - outRect.left = 10.7f.dpToPx().toInt() + seriesAdapter.itemCount - 1 -> { outRect.right = 0 + outRect.left = 6.7f.dpToPx().toInt() } else -> { - outRect.left = 10.7f.dpToPx().toInt() - outRect.right = 10.7f.dpToPx().toInt() + outRect.left = 6.7f.dpToPx().toInt() + outRect.right = 6.7f.dpToPx().toInt() } } } }) - binding.rvNewContentCreator.adapter = newContentCreatorAdapter + recyclerView.adapter = seriesAdapter - newContentCreatorViewModel.newContentUploadCreatorListLiveData.observe(viewLifecycleOwner) { - newContentCreatorAdapter.addItems(it) - binding.rvNewContentCreator.visibility = if ( - newContentCreatorAdapter.itemCount <= 0 && it.isEmpty() + recommendSeriesViewModel.seriesListLiveData.observe(viewLifecycleOwner) { + seriesAdapter.addItems(it) + binding.llRecommendSeries.visibility = if ( + seriesAdapter.itemCount <= 0 && it.isEmpty() ) { View.GONE } else { @@ -189,7 +191,7 @@ class AudioContentMainFragment : BaseFragment( } } - newContentCreatorViewModel.toastLiveData.observe(viewLifecycleOwner) { + recommendSeriesViewModel.toastLiveData.observe(viewLifecycleOwner) { it?.let { Toast.makeText(requireContext(), it, Toast.LENGTH_LONG).show() } } } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/new_content_upload_creator/AudioContentMainNewContentCreatorAdapter.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/new_content_upload_creator/AudioContentMainNewContentCreatorAdapter.kt deleted file mode 100644 index d620717..0000000 --- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/new_content_upload_creator/AudioContentMainNewContentCreatorAdapter.kt +++ /dev/null @@ -1,53 +0,0 @@ -package kr.co.vividnext.sodalive.audio_content.main.new_content_upload_creator - -import android.annotation.SuppressLint -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.recyclerview.widget.RecyclerView -import coil.load -import coil.transform.CircleCropTransformation -import kr.co.vividnext.sodalive.R -import kr.co.vividnext.sodalive.audio_content.main.GetNewContentUploadCreator -import kr.co.vividnext.sodalive.databinding.ItemAudioContentMainNewContentCreatorBinding - -class AudioContentMainNewContentCreatorAdapter( - private val onClickItem: (Long) -> Unit -) : RecyclerView.Adapter() { - - private val items = mutableListOf() - - inner class ViewHolder( - private val binding: ItemAudioContentMainNewContentCreatorBinding - ) : RecyclerView.ViewHolder(binding.root) { - fun bind(item: GetNewContentUploadCreator) { - binding.tvNewContentCreator.text = item.creatorNickname - binding.ivNewContentCreator.load(item.creatorProfileImageUrl) { - crossfade(true) - placeholder(R.drawable.ic_place_holder) - transformations(CircleCropTransformation()) - } - binding.root.setOnClickListener { onClickItem(item.creatorId) } - } - } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder( - ItemAudioContentMainNewContentCreatorBinding.inflate( - LayoutInflater.from(parent.context), - parent, - false - ) - ) - - override fun getItemCount() = items.size - - override fun onBindViewHolder(holder: ViewHolder, position: Int) { - holder.bind(items[position]) - } - - @SuppressLint("NotifyDataSetChanged") - fun addItems(items: List) { - this.items.clear() - this.items.addAll(items) - notifyDataSetChanged() - } -} diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/new_content_upload_creator/AudioContentMainNewContentCreatorViewModel.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/recommend_series/AudioContentMainRecommendSeriesViewModel.kt similarity index 59% rename from app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/new_content_upload_creator/AudioContentMainNewContentCreatorViewModel.kt rename to app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/recommend_series/AudioContentMainRecommendSeriesViewModel.kt index c152c61..497c599 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/new_content_upload_creator/AudioContentMainNewContentCreatorViewModel.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/main/recommend_series/AudioContentMainRecommendSeriesViewModel.kt @@ -1,44 +1,42 @@ -package kr.co.vividnext.sodalive.audio_content.main.new_content_upload_creator +package kr.co.vividnext.sodalive.audio_content.main.recommend_series import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData 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.AudioContentRepository -import kr.co.vividnext.sodalive.audio_content.main.GetNewContentUploadCreator +import kr.co.vividnext.sodalive.audio_content.series.GetSeriesListResponse +import kr.co.vividnext.sodalive.audio_content.series.SeriesRepository import kr.co.vividnext.sodalive.base.BaseViewModel import kr.co.vividnext.sodalive.common.SharedPreferenceManager -class AudioContentMainNewContentCreatorViewModel( - private val repository: AudioContentRepository +class AudioContentMainRecommendSeriesViewModel( + private val repository: SeriesRepository ) : BaseViewModel() { private val _toastLiveData = MutableLiveData() val toastLiveData: LiveData get() = _toastLiveData - private var _newContentUploadCreatorListLiveData = - MutableLiveData>() - val newContentUploadCreatorListLiveData: LiveData> - get() = _newContentUploadCreatorListLiveData + private var _seriesListLiveData = MutableLiveData>() + val seriesListLiveData: LiveData> + get() = _seriesListLiveData - fun getNewContentUploadCreatorList() { + fun getRecommendSeriesList() { compositeDisposable.add( - repository.getNewContentUploadCreatorList( - token = "Bearer ${SharedPreferenceManager.token}" - ) + repository + .getRecommendSeriesList(token = "Bearer ${SharedPreferenceManager.token}") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( { if (it.success && it.data != null) { - _newContentUploadCreatorListLiveData.postValue(it.data!!) + _seriesListLiveData.value = it.data!! } else { if (it.message != null) { _toastLiveData.postValue(it.message) } else { _toastLiveData.postValue( - "크리에이터 리스트를 불러오지 못했습니다. 다시 시도해 주세요.\n" + + "추천 시리즈를 불러오지 못했습니다. 다시 시도해 주세요.\n" + "계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." ) } @@ -47,7 +45,7 @@ class AudioContentMainNewContentCreatorViewModel( { it.message?.let { message -> Logger.e(message) } _toastLiveData.postValue( - "크리에이터 리스트를 불러오지 못했습니다. 다시 시도해 주세요.\n" + + "추천 시리즈를 불러오지 못했습니다. 다시 시도해 주세요.\n" + "계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." ) } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/series/SeriesApi.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/series/SeriesApi.kt index 7f258e5..77c582d 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/series/SeriesApi.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/series/SeriesApi.kt @@ -32,4 +32,9 @@ interface SeriesApi { @Query("size") size: Int, @Header("Authorization") authHeader: String ): Single> + + @GET("/audio-content/series/recommend") + fun getRecommendSeriesList( + @Header("Authorization") authHeader: String + ): Single>> } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/series/SeriesRepository.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/series/SeriesRepository.kt index 6b76289..a3de4b2 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/series/SeriesRepository.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/series/SeriesRepository.kt @@ -31,4 +31,6 @@ class SeriesRepository(private val api: SeriesApi) { size = size, authHeader = token ) + + fun getRecommendSeriesList(token: String) = api.getRecommendSeriesList(authHeader = token) } 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 208fff7..aa79f63 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 @@ -19,9 +19,9 @@ import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailViewModel import kr.co.vividnext.sodalive.audio_content.main.banner.AudioContentMainBannerViewModel import kr.co.vividnext.sodalive.audio_content.main.curation.AudioContentMainCurationViewModel import kr.co.vividnext.sodalive.audio_content.main.new_content.AudioContentMainNewContentViewModel -import kr.co.vividnext.sodalive.audio_content.main.new_content_upload_creator.AudioContentMainNewContentCreatorViewModel import kr.co.vividnext.sodalive.audio_content.main.order.AudioContentMainOrderListViewModel import kr.co.vividnext.sodalive.audio_content.main.ranking.AudioContentMainRankingViewModel +import kr.co.vividnext.sodalive.audio_content.main.recommend_series.AudioContentMainRecommendSeriesViewModel import kr.co.vividnext.sodalive.audio_content.modify.AudioContentModifyViewModel import kr.co.vividnext.sodalive.audio_content.order.AudioContentOrderListViewModel import kr.co.vividnext.sodalive.audio_content.series.SeriesApi @@ -220,7 +220,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) { viewModel { AudioContentMainCurationViewModel(get()) } viewModel { AudioContentMainOrderListViewModel(get()) } viewModel { AudioContentMainNewContentViewModel(get()) } - viewModel { AudioContentMainNewContentCreatorViewModel(get()) } + viewModel { AudioContentMainRecommendSeriesViewModel(get()) } viewModel { AudioContentViewModel(get()) } viewModel { AudioContentOrderListViewModel(get()) } viewModel { AudioContentUploadViewModel(get()) } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/series/UserProfileSeriesListAdapter.kt b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/series/UserProfileSeriesListAdapter.kt index 078ccf0..54ecee9 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/series/UserProfileSeriesListAdapter.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/series/UserProfileSeriesListAdapter.kt @@ -11,7 +11,6 @@ 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.ItemSeriesListBigBinding -import kr.co.vividnext.sodalive.databinding.ItemSeriesListBinding import kr.co.vividnext.sodalive.extensions.dpToPx class UserProfileSeriesListAdapter( diff --git a/app/src/main/res/layout/fragment_audio_content_main.xml b/app/src/main/res/layout/fragment_audio_content_main.xml index 18a84e4..c5fda03 100644 --- a/app/src/main/res/layout/fragment_audio_content_main.xml +++ b/app/src/main/res/layout/fragment_audio_content_main.xml @@ -4,289 +4,300 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + android:layout_height="match_parent" + android:clipToPadding="false" + android:paddingVertical="13.3dp"> - + android:orientation="vertical"> + + + android:layout_height="wrap_content" + android:layout_marginBottom="40dp" + android:orientation="vertical" + android:visibility="gone"> + android:paddingHorizontal="13.3dp" + android:text="추천 시리즈" + android:textColor="@color/color_eeeeee" + android:textSize="18.3sp" /> + android:paddingHorizontal="13.3dp" /> + - + - + + + + + + + + + + + + + + + + - + android:fontFamily="@font/gmarket_sans_bold" + android:text="내 보관함" + android:textColor="@color/color_eeeeee" + android:textSize="18.3sp" /> - - - - + android:layout_alignParentEnd="true" + android:layout_centerVertical="true" + android:fontFamily="@font/gmarket_sans_light" + android:text="전체보기" + android:textColor="@color/color_bbbbbb" + android:textSize="11.3sp" /> + - - - - - + android:layout_marginTop="13.3dp" + android:clipToPadding="false" + android:paddingHorizontal="13.3dp" /> + - + + + + + android:layout_marginStart="13.3dp" + android:fontFamily="@font/gmarket_sans_bold" + android:text="새로운 콘텐츠" + android:textColor="@color/color_eeeeee" + android:textSize="18.3sp" /> - - - - - - - + android:layout_alignParentEnd="true" + android:contentDescription="@null" + android:paddingHorizontal="13.3dp" + android:src="@drawable/ic_forward" /> + - + android:layout_marginTop="13.3dp" + android:clipToPadding="false" + android:paddingHorizontal="13.3dp" /> - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + android:paddingVertical="8dp"> - - - - - - - - + android:fontFamily="@font/gmarket_sans_bold" + android:textColor="@color/color_eeeeee" + android:textSize="14.7sp" /> - - - - - - - - + android:layout_marginTop="8dp" + android:fontFamily="@font/gmarket_sans_light" + android:text="※ 인기 콘텐츠의 순위는 매주 업데이트됩니다." + android:textColor="@color/color_bbbbbb" + android:textSize="13.3sp" /> + android:layout_marginTop="13.3dp" + android:clipToPadding="false" + android:paddingHorizontal="13.3dp" /> - + - - + + + + + +