parent
6c9ace146d
commit
e964679154
|
@ -35,8 +35,8 @@ android {
|
|||
applicationId "kr.co.vividnext.sodalive"
|
||||
minSdk 23
|
||||
targetSdk 34
|
||||
versionCode 117
|
||||
versionName "1.21.2"
|
||||
versionCode 118
|
||||
versionName "1.22.0"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
|
@ -159,4 +159,6 @@ dependencies {
|
|||
kapt "androidx.room:room-compiler:2.5.0"
|
||||
implementation "androidx.room:room-ktx:2.5.0"
|
||||
implementation "androidx.room:room-runtime:2.5.0"
|
||||
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"
|
||||
}
|
||||
|
|
|
@ -24,9 +24,9 @@ import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationRequest
|
|||
import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationResponse
|
||||
import kr.co.vividnext.sodalive.live.room.info.GetRoomInfoResponse
|
||||
import kr.co.vividnext.sodalive.live.room.kick_out.LiveRoomKickOutRequest
|
||||
import kr.co.vividnext.sodalive.live.room.like.LiveRoomLikeHeartRequest
|
||||
import kr.co.vividnext.sodalive.live.room.profile.GetLiveRoomUserProfileResponse
|
||||
import kr.co.vividnext.sodalive.live.room.tag.GetLiveTagResponse
|
||||
import kr.co.vividnext.sodalive.settings.ContentType
|
||||
import okhttp3.MultipartBody
|
||||
import okhttp3.RequestBody
|
||||
import retrofit2.http.Body
|
||||
|
@ -213,4 +213,10 @@ interface LiveApi {
|
|||
@Body request: CancelLiveReservationRequest,
|
||||
@Header("Authorization") authHeader: String
|
||||
): Single<ApiResponse<Any>>
|
||||
|
||||
@POST("/live/room/like-heart")
|
||||
fun likeHeart(
|
||||
@Body request: LiveRoomLikeHeartRequest,
|
||||
@Header("Authorization") authHeader: String
|
||||
): Single<ApiResponse<Any>>
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import kr.co.vividnext.sodalive.live.room.donation.DeleteLiveRoomDonationMessage
|
|||
import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationRequest
|
||||
import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationResponse
|
||||
import kr.co.vividnext.sodalive.live.room.kick_out.LiveRoomKickOutRequest
|
||||
import kr.co.vividnext.sodalive.live.room.like.LiveRoomLikeHeartRequest
|
||||
import kr.co.vividnext.sodalive.live.room.menu.MenuApi
|
||||
import kr.co.vividnext.sodalive.user.CreatorFollowRequestRequest
|
||||
import kr.co.vividnext.sodalive.user.UserApi
|
||||
|
@ -242,4 +243,12 @@ class LiveRepository(
|
|||
creatorId = creatorId,
|
||||
authHeader = token
|
||||
)
|
||||
|
||||
fun likeHeart(roomId: Long, token: String) = api.likeHeart(
|
||||
request = LiveRoomLikeHeartRequest(
|
||||
roomId = roomId,
|
||||
container = "aos"
|
||||
),
|
||||
authHeader = token
|
||||
)
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import androidx.activity.OnBackPressedCallback
|
|||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import coil.transform.CircleCropTransformation
|
||||
|
@ -53,6 +54,7 @@ import io.agora.rtm.RtmChannelMember
|
|||
import io.agora.rtm.RtmClientListener
|
||||
import io.agora.rtm.RtmMessage
|
||||
import io.agora.rtm.RtmMessageType
|
||||
import kotlinx.coroutines.launch
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kr.co.vividnext.sodalive.agora.Agora
|
||||
import kr.co.vividnext.sodalive.base.BaseActivity
|
||||
|
@ -124,6 +126,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
|||
private var isMicrophoneMute = false
|
||||
private var isSpeaker = false
|
||||
|
||||
private var isHost = false
|
||||
private var isNoChatting = false
|
||||
private var remainingNoChattingTime = noChattingTime
|
||||
|
||||
|
@ -530,8 +533,13 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
|||
return (second * 1000).toLong()
|
||||
}
|
||||
|
||||
private fun addHeartAnimation(button: View) {
|
||||
private fun addHeartAnimation() {
|
||||
// 버튼의 위치
|
||||
val button = if (isHost) {
|
||||
binding.flRouletteSettings
|
||||
} else {
|
||||
binding.flLikeHeart
|
||||
}
|
||||
val buttonPosition = IntArray(2)
|
||||
button.getLocationInWindow(buttonPosition)
|
||||
|
||||
|
@ -1004,12 +1012,10 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
|||
binding.ivCreatorFollow.visibility = View.GONE
|
||||
}
|
||||
|
||||
initLikeHeartButton(isHost = response.creatorId == SharedPreferenceManager.userId)
|
||||
initRouletteSettingButton(isHost = response.creatorId == SharedPreferenceManager.userId)
|
||||
activatingRouletteButton(
|
||||
isHost = response.creatorId == SharedPreferenceManager.userId,
|
||||
isActiveRoulette = response.isActiveRoulette
|
||||
)
|
||||
isHost = response.creatorId == SharedPreferenceManager.userId
|
||||
initLikeHeartButton()
|
||||
initRouletteSettingButton()
|
||||
activatingRouletteButton(isActiveRoulette = response.isActiveRoulette)
|
||||
|
||||
if (response.menuPan.isNotBlank()) {
|
||||
binding.tvMenuPan.visibility = View.VISIBLE
|
||||
|
@ -1094,16 +1100,51 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
|||
}
|
||||
}
|
||||
|
||||
private fun initLikeHeartButton(isHost: Boolean) {
|
||||
private fun initLikeHeartButton() {
|
||||
if (!isHost) {
|
||||
binding.flLikeHeart.visibility = View.VISIBLE
|
||||
binding.flLikeHeart.setOnClickListener { addHeartAnimation(it) }
|
||||
binding.flLikeHeart.setOnClickListener {
|
||||
binding.flLikeHeart.isEnabled = false
|
||||
viewModel.likeHeart(
|
||||
roomId = roomId,
|
||||
onSuccess = {
|
||||
val donationRawMessage = Gson().toJson(
|
||||
LiveRoomChatRawMessage(
|
||||
type = LiveRoomChatRawMessageType.HEART_DONATION,
|
||||
message = "",
|
||||
can = 1,
|
||||
signature = null,
|
||||
signatureImageUrl = null,
|
||||
donationMessage = null
|
||||
)
|
||||
)
|
||||
|
||||
agora.sendRawMessageToGroup(
|
||||
rawMessage = donationRawMessage.toByteArray(),
|
||||
onSuccess = {
|
||||
handler.post {
|
||||
addHeartAnimation()
|
||||
lifecycleScope.launch { viewModel.addHeartDonation() }
|
||||
}
|
||||
},
|
||||
onFailure = {
|
||||
viewModel.refundDonation(roomId)
|
||||
}
|
||||
)
|
||||
|
||||
binding.flLikeHeart.isEnabled = true
|
||||
},
|
||||
onFailure = {
|
||||
binding.flLikeHeart.isEnabled = true
|
||||
}
|
||||
)
|
||||
}
|
||||
} else {
|
||||
binding.flLikeHeart.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
private fun initRouletteSettingButton(isHost: Boolean) {
|
||||
private fun initRouletteSettingButton() {
|
||||
if (isHost) {
|
||||
binding.flRouletteSettings.visibility = View.VISIBLE
|
||||
binding.flRouletteSettings.setOnClickListener {
|
||||
|
@ -1119,7 +1160,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
|||
}
|
||||
}
|
||||
|
||||
private fun activatingRouletteButton(isHost: Boolean, isActiveRoulette: Boolean) {
|
||||
private fun activatingRouletteButton(isActiveRoulette: Boolean) {
|
||||
if (!isHost && isActiveRoulette) {
|
||||
binding.flRoulette.visibility = View.VISIBLE
|
||||
binding.flRoulette.setOnClickListener {
|
||||
|
@ -1533,7 +1574,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
|||
)
|
||||
)
|
||||
invalidateChat()
|
||||
viewModel.addDonationCan(can)
|
||||
lifecycleScope.launch { viewModel.addDonationCan(can) }
|
||||
addSignature(signature)
|
||||
}
|
||||
},
|
||||
|
@ -1574,7 +1615,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
|||
)
|
||||
)
|
||||
invalidateChat()
|
||||
viewModel.addDonationCan(can)
|
||||
lifecycleScope.launch { viewModel.addDonationCan(can) }
|
||||
}
|
||||
},
|
||||
onFailure = {
|
||||
|
@ -1641,7 +1682,9 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
|||
)
|
||||
)
|
||||
invalidateChat()
|
||||
viewModel.addDonationCan(rawMessage.can)
|
||||
lifecycleScope.launch {
|
||||
viewModel.addDonationCan(rawMessage.can)
|
||||
}
|
||||
|
||||
if (rawMessage.signature != null) {
|
||||
addSignature(rawMessage.signature)
|
||||
|
@ -1666,9 +1709,6 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
|||
LiveRoomChatRawMessageType.TOGGLE_ROULETTE -> {
|
||||
handler.post {
|
||||
activatingRouletteButton(
|
||||
isHost = viewModel
|
||||
.roomInfoResponse
|
||||
.creatorId == SharedPreferenceManager.userId,
|
||||
isActiveRoulette = rawMessage.isActiveRoulette ?: false
|
||||
)
|
||||
}
|
||||
|
@ -1684,7 +1724,16 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
|||
)
|
||||
)
|
||||
invalidateChat()
|
||||
viewModel.addDonationCan(rawMessage.can)
|
||||
lifecycleScope.launch {
|
||||
viewModel.addDonationCan(rawMessage.can)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LiveRoomChatRawMessageType.HEART_DONATION -> {
|
||||
handler.post {
|
||||
addHeartAnimation()
|
||||
lifecycleScope.launch { viewModel.addHeartDonation() }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2009,7 +2058,9 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
|||
)
|
||||
)
|
||||
invalidateChat()
|
||||
viewModel.addDonationCan(message.can)
|
||||
lifecycleScope.launch {
|
||||
viewModel.addDonationCan(message.can)
|
||||
}
|
||||
|
||||
if (message.signature != null) {
|
||||
addSignature(message.signature)
|
||||
|
|
|
@ -13,6 +13,8 @@ import com.google.gson.Gson
|
|||
import com.orhanobut.logger.Logger
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kr.co.vividnext.sodalive.base.BaseViewModel
|
||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||
import kr.co.vividnext.sodalive.live.LiveRepository
|
||||
|
@ -100,6 +102,8 @@ class LiveRoomViewModel(
|
|||
|
||||
private val blockedMemberIdList: MutableList<Long> = mutableListOf()
|
||||
|
||||
val mutex = Mutex()
|
||||
|
||||
fun getUserNickname(memberId: Int): String {
|
||||
for (manager in roomInfoResponse.managerList) {
|
||||
if (manager.id.toInt() == memberId) {
|
||||
|
@ -562,6 +566,36 @@ class LiveRoomViewModel(
|
|||
)
|
||||
}
|
||||
|
||||
fun likeHeart(roomId: Long, onSuccess: () -> Unit, onFailure: () -> Unit) {
|
||||
compositeDisposable.add(
|
||||
repository.likeHeart(roomId, token = "Bearer ${SharedPreferenceManager.token}")
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{
|
||||
if (it.success) {
|
||||
SharedPreferenceManager.can -= 1
|
||||
onSuccess()
|
||||
} else {
|
||||
if (it.message != null) {
|
||||
_toastLiveData.postValue(it.message)
|
||||
} else {
|
||||
_toastLiveData.postValue(
|
||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||
)
|
||||
}
|
||||
onFailure()
|
||||
}
|
||||
},
|
||||
{
|
||||
it.message?.let { message -> Logger.e(message) }
|
||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||
onFailure()
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun donation(
|
||||
roomId: Long,
|
||||
can: Int,
|
||||
|
@ -641,8 +675,16 @@ class LiveRoomViewModel(
|
|||
)
|
||||
}
|
||||
|
||||
fun addDonationCan(can: Int) {
|
||||
_totalDonationCan.postValue(totalDonationCan.value!! + can)
|
||||
suspend fun addDonationCan(can: Int) {
|
||||
mutex.withLock {
|
||||
_totalDonationCan.postValue(totalDonationCan.value!! + can)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun addHeartDonation() {
|
||||
mutex.withLock {
|
||||
_totalLikeHeart.postValue(totalLikeHeart.value!! + 1)
|
||||
}
|
||||
}
|
||||
|
||||
fun donationStatus(roomId: Long, onSuccess: (GetLiveRoomDonationStatusResponse) -> Unit) {
|
||||
|
|
|
@ -35,5 +35,8 @@ enum class LiveRoomChatRawMessageType {
|
|||
TOGGLE_ROULETTE,
|
||||
|
||||
@SerializedName("ROULETTE_DONATION")
|
||||
ROULETTE_DONATION
|
||||
ROULETTE_DONATION,
|
||||
|
||||
@SerializedName("HEART_DONATION")
|
||||
HEART_DONATION
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
package kr.co.vividnext.sodalive.live.room.like
|
||||
|
||||
import androidx.annotation.Keep
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
@Keep
|
||||
data class LiveRoomLikeHeartRequest(
|
||||
@SerializedName("roomId") val roomId: Long,
|
||||
@SerializedName("container") val container: String
|
||||
)
|
Loading…
Reference in New Issue