From c23ef771bee16a278546a0c7ca5d84ff38d56269 Mon Sep 17 00:00:00 2001 From: klaus Date: Mon, 29 Jan 2024 00:33:50 +0900 Subject: [PATCH] =?UTF-8?q?=EC=BD=98=ED=85=90=EC=B8=A0=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20-=20=EC=BD=98=ED=85=90=EC=B8=A0=20=EA=B3=A0?= =?UTF-8?q?=EC=A0=95/=ED=95=B4=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/audio_content/AudioContentApi.kt | 12 ++ .../audio_content/AudioContentRepository.kt | 9 ++ .../detail/AudioContentDetailActivity.kt | 90 +++++++------- ...AudioContentDetailMenuBottomSheetDialog.kt | 66 +++++++++++ .../detail/AudioContentDetailViewModel.kt | 70 +++++++++++ .../detail/GetAudioContentDetailResponse.kt | 2 + app/src/main/res/drawable-xxhdpi/ic_pin.png | Bin 0 -> 1315 bytes .../res/drawable-xxhdpi/ic_pin_cancel.png | Bin 0 -> 1553 bytes .../main/res/drawable-xxhdpi/ic_trash_can.png | Bin 0 -> 787 bytes .../dialog_audio_content_detail_menu.xml | 110 ++++++++++++++++++ 10 files changed, 310 insertions(+), 49 deletions(-) create mode 100644 app/src/main/java/kr/co/vividnext/sodalive/audio_content/detail/AudioContentDetailMenuBottomSheetDialog.kt create mode 100644 app/src/main/res/drawable-xxhdpi/ic_pin.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_pin_cancel.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_trash_can.png create mode 100644 app/src/main/res/layout/dialog_audio_content_detail_menu.xml diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/AudioContentApi.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/AudioContentApi.kt index 757857f..57f77cf 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/AudioContentApi.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/AudioContentApi.kt @@ -201,4 +201,16 @@ interface AudioContentApi { fun getMainOrderList( @Header("Authorization") authHeader: String ): Single>> + + @POST("/audio-content/pin-to-the-top/{id}") + fun pinContent( + @Path("id") audioContentId: Long, + @Header("Authorization") authHeader: String + ): Single> + + @PUT("/audio-content/unpin-at-the-top/{id}") + fun unpinContent( + @Path("id") audioContentId: Long, + @Header("Authorization") authHeader: String + ): Single> } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/AudioContentRepository.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/AudioContentRepository.kt index 6554426..7536911 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/AudioContentRepository.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/AudioContentRepository.kt @@ -188,4 +188,13 @@ class AudioContentRepository( fun getMainBannerList(token: String) = api.getMainBannerList(authHeader = token) fun getMainOrderList(token: String) = api.getMainOrderList(authHeader = token) + fun pinContent( + audioContentId: Long, + token: String + ) = api.pinContent(audioContentId, authHeader = token) + + fun unpinContent( + audioContentId: Long, + token: String + ) = api.unpinContent(audioContentId, authHeader = token) } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/detail/AudioContentDetailActivity.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/detail/AudioContentDetailActivity.kt index 2305932..6680a76 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/detail/AudioContentDetailActivity.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/detail/AudioContentDetailActivity.kt @@ -13,7 +13,6 @@ import android.view.View import android.widget.RelativeLayout import android.widget.SeekBar import android.widget.Toast -import androidx.appcompat.widget.PopupMenu import androidx.core.content.ContextCompat import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -30,6 +29,7 @@ import kr.co.vividnext.sodalive.audio_content.order.AudioContentOrderConfirmDial import kr.co.vividnext.sodalive.audio_content.order.AudioContentOrderFragment import kr.co.vividnext.sodalive.audio_content.order.OrderType import kr.co.vividnext.sodalive.base.BaseActivity +import kr.co.vividnext.sodalive.base.SodaDialog import kr.co.vividnext.sodalive.common.Constants import kr.co.vividnext.sodalive.common.LoadingDialog import kr.co.vividnext.sodalive.common.SharedPreferenceManager @@ -116,10 +116,7 @@ class AudioContentDetailActivity : BaseActivity { - refresh = true - setResult(RESULT_OK) - startActivity( - Intent(applicationContext, AudioContentModifyActivity::class.java) - .apply { - putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, audioContentId) - } - ) - } - - R.id.menu_delete -> { - showDeleteDialog() + private fun showOptionMenu() { + val dialog = AudioContentDetailMenuBottomSheetDialog( + isPin = viewModel.audioContentLiveData.value!!.isPin, + isCreator = viewModel.audioContentLiveData.value!! + .creator.creatorId == SharedPreferenceManager.userId, + onClickPin = { + if (viewModel.audioContentLiveData.value!!.isPin) { + viewModel.unPinContent(audioContentId) + } else { + if (viewModel.audioContentLiveData.value!!.isAvailablePin) { + viewModel.pinContent(audioContentId) + } else { + SodaDialog(this@AudioContentDetailActivity, + layoutInflater, + "고정 한도 도달", + "이 콘텐츠를 고정하시겠어요? " + + "채널에 콘텐츠를 최대 3개까지 고정할 수 있습니다." + + "이 콘텐츠를 고정하면 가장 오래된 콘텐츠가 대체됩니다.", + "확인", + { viewModel.pinContent(audioContentId) }, + "취소", + {} + ).show(screenWidth) } } - - true - } - } else { - inflater.inflate(R.menu.audio_content_detail_user_menu, popup.menu) - - popup.setOnMenuItemClickListener { - when (it.itemId) { - R.id.menu_report -> { - showReportDialog() - } - } - - true - } - } - - popup.show() + }, + onClickModify = { + refresh = true + setResult(RESULT_OK) + startActivity( + Intent(applicationContext, AudioContentModifyActivity::class.java) + .apply { + putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, audioContentId) + } + ) + }, + onClickDelete = { showDeleteDialog() }, + onClickReport = { showReportDialog() } + ) + dialog.show(supportFragmentManager, dialog.tag) } private fun showDeleteDialog() { diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/detail/AudioContentDetailMenuBottomSheetDialog.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/detail/AudioContentDetailMenuBottomSheetDialog.kt new file mode 100644 index 0000000..5e8a4e7 --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/detail/AudioContentDetailMenuBottomSheetDialog.kt @@ -0,0 +1,66 @@ +package kr.co.vividnext.sodalive.audio_content.detail + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import kr.co.vividnext.sodalive.R +import kr.co.vividnext.sodalive.databinding.DialogAudioContentDetailMenuBinding + +class AudioContentDetailMenuBottomSheetDialog( + private val isPin: Boolean, + private val isCreator: Boolean, + private val onClickPin: () -> Unit, + private val onClickModify: () -> Unit, + private val onClickDelete: () -> Unit, + private val onClickReport: () -> Unit +) : BottomSheetDialogFragment() { + private lateinit var dialog: DialogAudioContentDetailMenuBinding + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + dialog = DialogAudioContentDetailMenuBinding.inflate(inflater, container, false) + return dialog.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + if (isCreator) { + dialog.tvReport.visibility = View.GONE + dialog.llMenuCreator.visibility = View.VISIBLE + + if (isPin) { + dialog.ivPin.setImageResource(R.drawable.ic_pin_cancel) + dialog.tvPin.text = "내 채널에 고정 취소" + } else { + dialog.ivPin.setImageResource(R.drawable.ic_pin) + dialog.tvPin.text = "내 채널에 고정" + } + + dialog.llPin.setOnClickListener { + dismiss() + onClickPin() + } + dialog.llModify.setOnClickListener { + dismiss() + onClickModify() + } + dialog.llDelete.setOnClickListener { + dismiss() + onClickDelete() + } + } else { + dialog.llMenuCreator.visibility = View.GONE + dialog.tvReport.visibility = View.VISIBLE + dialog.tvReport.setOnClickListener { + dismiss() + onClickReport() + } + } + } +} diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/detail/AudioContentDetailViewModel.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/detail/AudioContentDetailViewModel.kt index 87dc2a0..49ca169 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/detail/AudioContentDetailViewModel.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/detail/AudioContentDetailViewModel.kt @@ -481,4 +481,74 @@ class AudioContentDetailViewModel( ) ) } + + fun pinContent(audioContentId: Long) { + isLoading.value = true + compositeDisposable.add( + repository.pinContent( + audioContentId, + token = "Bearer ${SharedPreferenceManager.token}" + ) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + { + isLoading.value = false + + if (it.success) { + _toastLiveData.postValue("고정되었습니다.") + getAudioContentDetail(audioContentId) + } 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 unPinContent(audioContentId: Long) { + isLoading.value = true + compositeDisposable.add( + repository.unpinContent( + audioContentId, + token = "Bearer ${SharedPreferenceManager.token}" + ) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + { + isLoading.value = false + + if (it.success) { + _toastLiveData.postValue("해제되었습니다.") + getAudioContentDetail(audioContentId) + } else { + if (it.message != null) { + _toastLiveData.postValue(it.message) + } else { + _toastLiveData.postValue( + "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요." + ) + } + } + }, + { + isLoading.value = false + it.message?.let { message -> Logger.e(message) } + _toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.") + } + ) + ) + } } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/detail/GetAudioContentDetailResponse.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/detail/GetAudioContentDetailResponse.kt index 402bb33..d271452 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/detail/GetAudioContentDetailResponse.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/detail/GetAudioContentDetailResponse.kt @@ -31,6 +31,8 @@ data class GetAudioContentDetailResponse( @SerializedName("likeCount") val likeCount: Int, @SerializedName("commentList") val commentList: List, @SerializedName("commentCount") val commentCount: Int, + @SerializedName("isPin") val isPin: Boolean, + @SerializedName("isAvailablePin") val isAvailablePin: Boolean, @SerializedName("creator") val creator: AudioContentCreator ) diff --git a/app/src/main/res/drawable-xxhdpi/ic_pin.png b/app/src/main/res/drawable-xxhdpi/ic_pin.png new file mode 100644 index 0000000000000000000000000000000000000000..088bb74576c91799eab63cc2bca5d4ba495c1577 GIT binary patch literal 1315 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 TuOAQsreOw8S3j3^P6 + + + + + + + + + + + + + + + + + + + + + + + + + + + +