From 91db6caec91fbc15c9add9d739c77f2eb5051014 Mon Sep 17 00:00:00 2001 From: klaus Date: Sat, 2 Dec 2023 00:23:36 +0900 Subject: [PATCH] =?UTF-8?q?=EB=9D=BC=EC=9D=B4=EB=B8=8C=20=EB=B0=A9=20?= =?UTF-8?q?=EB=A3=B0=EB=A0=9B=20-=20=EB=A6=AC=EC=8A=A4=EB=84=88=EC=9A=A9?= =?UTF-8?q?=20=EB=A3=B0=EB=A0=9B=20=EB=B2=84=ED=8A=BC=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=20-=20=EB=A3=B0=EB=A0=9B=20=EC=84=A4=EC=A0=95=20=EC=8B=9C=20?= =?UTF-8?q?=EB=A3=B0=EB=A0=9B=20=EB=B2=84=ED=8A=BC=20=ED=86=A0=EA=B8=80=20?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=EB=A5=BC=20=EB=B0=9C=EC=86=A1?= =?UTF-8?q?=ED=95=98=EC=97=AC=20=EB=A6=AC=EC=8A=A4=EB=84=88=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=EC=97=90=EC=84=9C=20=EB=A3=B0=EB=A0=9B=EC=9D=B4=20(?= =?UTF-8?q?=EB=B9=84)=ED=99=9C=EC=84=B1=ED=99=94=20=EB=90=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= 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/live/room/LiveRoomActivity.kt | 75 ++++++++++++++++--- .../sodalive/live/room/LiveRoomViewModel.kt | 61 ++++++++++++++- .../live/room/chat/LiveRoomChatRawMessage.kt | 17 +++-- .../live/room/info/GetRoomInfoResponse.kt | 1 + .../live/roulette/RoulettePreviewDialog.kt | 18 +++++ 6 files changed, 156 insertions(+), 18 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 73d918d..2c037bf 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 @@ -166,7 +166,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) { viewModel { LiveRoomCreateViewModel(get()) } viewModel { LiveTagViewModel(get()) } viewModel { LiveRoomEditViewModel(get()) } - viewModel { LiveRoomViewModel(get(), get(), get()) } + viewModel { LiveRoomViewModel(get(), get(), get(), get()) } viewModel { LiveRoomDonationMessageViewModel(get()) } viewModel { ExplorerViewModel(get()) } viewModel { UserProfileViewModel(get(), get(), get()) } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/room/LiveRoomActivity.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/room/LiveRoomActivity.kt index 43c848e..9cb8320 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/live/room/LiveRoomActivity.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/room/LiveRoomActivity.kt @@ -72,6 +72,7 @@ import kr.co.vividnext.sodalive.live.room.profile.LiveRoomProfileDialog import kr.co.vividnext.sodalive.live.room.profile.LiveRoomProfileListAdapter import kr.co.vividnext.sodalive.live.room.profile.LiveRoomUserProfileDialog import kr.co.vividnext.sodalive.live.room.update.LiveRoomInfoEditDialog +import kr.co.vividnext.sodalive.live.roulette.RoulettePreviewDialog import kr.co.vividnext.sodalive.live.roulette.config.RouletteConfigActivity import kr.co.vividnext.sodalive.report.ProfileReportDialog import kr.co.vividnext.sodalive.report.ReportType @@ -187,7 +188,17 @@ class LiveRoomActivity : BaseActivity(ActivityLiveRoomB val isActiveRoulette = result.data?.getBooleanExtra(Constants.EXTRA_RESULT_ROULETTE, false) if (resultCode == RESULT_OK && isActiveRoulette != null) { - // TODO 룰렛 활성화 / 비활성화 설정 리스너에게 알림 + agora.sendRawMessageToGroup( + rawMessage = Gson().toJson( + LiveRoomChatRawMessage( + type = LiveRoomChatRawMessageType.TOGGLE_ROULETTE, + message = "", + can = 0, + donationMessage = "", + isActiveRoulette = isActiveRoulette + ) + ).toByteArray() + ) } } @@ -672,16 +683,6 @@ class LiveRoomActivity : BaseActivity(ActivityLiveRoomB response.creatorId == SharedPreferenceManager.userId && SharedPreferenceManager.role == MemberRole.CREATOR.name ) { - binding.flRoulette.visibility = View.GONE - binding.flRouletteSettings.visibility = View.VISIBLE - binding.flRouletteSettings.setOnClickListener { - rouletteConfigResult.launch( - Intent( - applicationContext, - RouletteConfigActivity::class.java - ) - ) - } binding.flDonationMessageList.visibility = View.VISIBLE binding.flDonationMessageList.setOnClickListener { LiveRoomDonationMessageDialog( @@ -821,6 +822,12 @@ class LiveRoomActivity : BaseActivity(ActivityLiveRoomB binding.ivCreatorFollow.visibility = View.GONE } + initRouletteSettingButton(isHost = response.creatorId == SharedPreferenceManager.userId) + activatingRouletteButton( + isHost = response.creatorId == SharedPreferenceManager.userId, + isActiveRoulette = response.isActiveRoulette + ) + if (agora.rtmChannelIsNull()) { joinChannel(response) } @@ -849,6 +856,41 @@ class LiveRoomActivity : BaseActivity(ActivityLiveRoomB } } + private fun initRouletteSettingButton(isHost: Boolean) { + if (isHost) { + binding.flRouletteSettings.visibility = View.VISIBLE + binding.flRouletteSettings.setOnClickListener { + rouletteConfigResult.launch( + Intent( + applicationContext, + RouletteConfigActivity::class.java + ) + ) + } + } else { + binding.flRouletteSettings.visibility = View.GONE + } + } + + private fun activatingRouletteButton(isHost: Boolean, isActiveRoulette: Boolean) { + if (!isHost && isActiveRoulette) { + binding.flRoulette.visibility = View.VISIBLE + binding.flRoulette.setOnClickListener { + viewModel.showRoulette { + RoulettePreviewDialog( + activity = this, + preview = it, + onClickSpin = {}, + layoutInflater = layoutInflater + ).show() + } + } + + } else { + binding.flRoulette.visibility = View.GONE + } + } + private fun setNoticeAndClickableUrl(textView: TextView, text: String) { textView.text = text @@ -1277,6 +1319,17 @@ class LiveRoomActivity : BaseActivity(ActivityLiveRoomB invalidateChat() } } + + LiveRoomChatRawMessageType.TOGGLE_ROULETTE -> { + handler.post { + activatingRouletteButton( + isHost = viewModel + .roomInfoResponse + .creatorId == SharedPreferenceManager.userId, + isActiveRoulette = rawMessage.isActiveRoulette ?: false + ) + } + } } } else { val chat = message.text diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/room/LiveRoomViewModel.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/room/LiveRoomViewModel.kt index 5867d63..f71f7b1 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/live/room/LiveRoomViewModel.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/room/LiveRoomViewModel.kt @@ -20,6 +20,10 @@ import kr.co.vividnext.sodalive.live.room.donation.GetLiveRoomDonationStatusResp import kr.co.vividnext.sodalive.live.room.info.GetRoomInfoResponse import kr.co.vividnext.sodalive.live.room.profile.GetLiveRoomUserProfileResponse import kr.co.vividnext.sodalive.live.room.update.EditLiveRoomInfoRequest +import kr.co.vividnext.sodalive.live.roulette.RouletteItem +import kr.co.vividnext.sodalive.live.roulette.RoulettePreview +import kr.co.vividnext.sodalive.live.roulette.RoulettePreviewItem +import kr.co.vividnext.sodalive.live.roulette.RouletteRepository import kr.co.vividnext.sodalive.report.ReportRepository import kr.co.vividnext.sodalive.report.ReportRequest import kr.co.vividnext.sodalive.report.ReportType @@ -33,7 +37,8 @@ import java.io.File class LiveRoomViewModel( private val repository: LiveRepository, private val userRepository: UserRepository, - private val reportRepository: ReportRepository + private val reportRepository: ReportRepository, + private val rouletteRepository: RouletteRepository ) : BaseViewModel() { private val _roomInfoLiveData = MutableLiveData() val roomInfoLiveData: LiveData @@ -775,4 +780,58 @@ class LiveRoomViewModel( ) ) } + + fun showRoulette(complete: (RoulettePreview) -> Unit) { + if (!_isLoading.value!!) { + _isLoading.value = true + compositeDisposable.add( + rouletteRepository.getRoulette( + creatorId = roomInfoResponse.creatorId, + token = "Bearer ${SharedPreferenceManager.token}" + ) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + { + _isLoading.value = false + + val data = it.data + if ( + it.success && + data != null && + data.isActive && + data.items.isNotEmpty() + ) { + complete( + RoulettePreview( + data.can, + items = calculatePercentages(data.items) + ) + ) + } else { + val message = it.message ?: "룰렛을 사용할 수 없습니다. 다시 시도해 주세요." + _toastLiveData.postValue(message) + } + }, + { + _isLoading.value = false + it.message?.let { message -> Logger.e(message) } + _toastLiveData.postValue("룰렛을 사용할 수 없습니다. 다시 시도해 주세요.") + } + ) + ) + } + } + + private fun calculatePercentages(options: List): List { + val totalWeight = options.sumOf { it.weight } + val updatedOptions = options.asSequence().map { option -> + RoulettePreviewItem( + title = option.title, + percent = "${(option.weight.toDouble() / totalWeight * 100).toInt()}%" + ) + }.toList() + + return updatedOptions + } } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/room/chat/LiveRoomChatRawMessage.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/room/chat/LiveRoomChatRawMessage.kt index 26c32ac..7c23e2d 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/live/room/chat/LiveRoomChatRawMessage.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/room/chat/LiveRoomChatRawMessage.kt @@ -6,12 +6,19 @@ data class LiveRoomChatRawMessage( @SerializedName("type") val type: LiveRoomChatRawMessageType, @SerializedName("message") val message: String, @SerializedName("can") val can: Int, - @SerializedName("donationMessage") val donationMessage: String? + @SerializedName("donationMessage") val donationMessage: String?, + @SerializedName("isActiveRoulette") val isActiveRoulette: Boolean? = null ) enum class LiveRoomChatRawMessageType { - @SerializedName("DONATION") DONATION, - @SerializedName("SET_MANAGER") SET_MANAGER, - @SerializedName("EDIT_ROOM_INFO") EDIT_ROOM_INFO, - @SerializedName("DONATION_STATUS") DONATION_STATUS + @SerializedName("DONATION") + DONATION, + @SerializedName("SET_MANAGER") + SET_MANAGER, + @SerializedName("EDIT_ROOM_INFO") + EDIT_ROOM_INFO, + @SerializedName("DONATION_STATUS") + DONATION_STATUS, + @SerializedName("TOGGLE_ROULETTE") + TOGGLE_ROULETTE } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/room/info/GetRoomInfoResponse.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/room/info/GetRoomInfoResponse.kt index 41e2a28..8715d08 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/live/room/info/GetRoomInfoResponse.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/room/info/GetRoomInfoResponse.kt @@ -21,6 +21,7 @@ data class GetRoomInfoResponse( @SerializedName("listenerList") val listenerList: List, @SerializedName("managerList") val managerList: List, @SerializedName("donationRankingTop3UserIds") val donationRankingTop3UserIds: List, + @SerializedName("isActiveRoulette") val isActiveRoulette: Boolean, @SerializedName("isPrivateRoom") val isPrivateRoom: Boolean, @SerializedName("password") val password: String? = null ) diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/roulette/RoulettePreviewDialog.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/roulette/RoulettePreviewDialog.kt index b76a8e7..6960cdd 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/live/roulette/RoulettePreviewDialog.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/roulette/RoulettePreviewDialog.kt @@ -1,6 +1,7 @@ package kr.co.vividnext.sodalive.live.roulette import android.annotation.SuppressLint +import android.content.Intent import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.view.LayoutInflater @@ -11,8 +12,12 @@ import android.widget.TextView import androidx.appcompat.app.AlertDialog import androidx.fragment.app.FragmentActivity import kr.co.vividnext.sodalive.R +import kr.co.vividnext.sodalive.common.Constants +import kr.co.vividnext.sodalive.common.SharedPreferenceManager import kr.co.vividnext.sodalive.databinding.DialogRoulettePreviewBinding import kr.co.vividnext.sodalive.extensions.dpToPx +import kr.co.vividnext.sodalive.extensions.moneyFormat +import kr.co.vividnext.sodalive.mypage.can.charge.CanChargeActivity class RoulettePreviewDialog( private val activity: FragmentActivity, @@ -61,6 +66,19 @@ class RoulettePreviewDialog( } dialogView.tvTitle.text = title.ifBlank { "룰렛" } + if (onClickSpin != null) { + dialogView.tvCan.visibility = View.VISIBLE + dialogView.tvCan.text = SharedPreferenceManager.can.moneyFormat() + dialogView.tvCan.setOnClickListener { + alertDialog.dismiss() + + val intent = Intent(activity, CanChargeActivity::class.java) + intent.putExtra(Constants.EXTRA_GO_TO_PREV_PAGE, true) + activity.startActivity(intent) + } + } else { + dialogView.tvCan.visibility = View.GONE + } preview.items.forEachIndexed { index, item -> dialogView.llRouletteOptionContainer.addView(createOptionView(index, item))