Compare commits

...

23 Commits

Author SHA1 Message Date
klaus 5a37ba8be0 라이브방
- 룰렛설정, 룰렛, 후원 버튼 터치시 키보드가 내려가도록 설정
2024-10-30 15:21:59 +09:00
klaus 37d47efe2c 라이브 후원 - 비밀후원 체크박스
- 체크박스가 선택된 이미지로 변경되지 않던 버그 수정
2024-10-30 12:02:31 +09:00
klaus f6c5be24d8 콘텐츠, 커뮤니티 댓글 입력창
- 길게 입력하면 줄바꿈 되어 화면 내에서 입력한 글이 모두 보이도록 수정
2024-10-29 14:44:19 +09:00
klaus 0c8241fba7 콘텐츠 대여 가격
- 소장가격의 60%에서 70% 표기로 변경
2024-10-29 14:33:40 +09:00
klaus dc2cda58b2 라이브
- 우측 하단 옵션 버튼 순서 변경
2024-10-29 13:54:36 +09:00
klaus 936074081c 라이브 후원
- 비밀후원을 체크하면 힌트 메시지에 '비밀' 추가
- 후원메시지 최대 길이 50 -> 200 변경
2024-10-29 00:30:34 +09:00
klaus a556378ffe 라이브방 - 라이브 후원랭킹 리스트
- 방장은 일반후원 / 비밀후원 캔을 나눠서 보이도록 수정
2024-10-28 23:49:30 +09:00
klaus 960dda8d40 콘텐츠 상세 - 콘텐츠 설명글
- textSize: 14
- color: 909090
- font: gmarket_sans_medium
2024-10-28 13:54:13 +09:00
klaus a401a2e13a versionCode 120, versionName 1.22.2 2024-10-28 13:47:19 +09:00
klaus f51f7ef412 라이브방
- 하트 알림 바(채팅) 배경, 닉네임, 글자색 변경
- 하트 알림 바 위치 수정 : 채팅 -> 공지 밑
2024-10-27 23:36:28 +09:00
klaus 04151168ca 라이브방
- 채팅창 너비 화면 가득 채움
2024-10-27 21:51:13 +09:00
klaus 99a93001bc 알람 권한 설정
- 사용 하지 않는 권한을 런타임 권한으로 물어 문제가 생기는 버그 수정
2024-10-27 18:28:20 +09:00
klaus e6339bb4c2 개수 제한 콘텐츠
- 내 콘텐츠는 sold out 되더라도 재생이 가능하도록 수정
2024-10-24 23:52:50 +09:00
klaus 7209f972d2 라이브 방 - 채팅 EditText
- inputType에서 textMultiLine를 제거하여 imeOptions의 actionSend설정이 적용되도록 수정
2024-10-24 01:45:47 +09:00
klaus 0714918338 라이브 방 - 하트 후원 채팅
- 채팅 배경색 변경
2024-10-23 01:39:03 +09:00
klaus 94d581a4f3 라이브 방 - 하트 후원 애니메이션
- 룰렛의 활성화/비활성화시 키보드를 숨기고 하트 후원 애니메이션 시작 위치 재계산
2024-10-22 22:16:13 +09:00
klaus 577e864b6a 라이브 방 - 하트 후원 애니메이션
- 스피커/리스너 변경시 키보드를 숨기고 하트 후원 애니메이션 시작 위치 재계산
2024-10-22 21:43:56 +09:00
klaus 96a3ef44f6 라이브 방
- 하트 후원시 채팅으로 알림
2024-10-17 15:01:05 +09:00
klaus 3a33153361 라이브 방
- 하트 후원 안내 팝업 추가
2024-10-16 19:08:39 +09:00
klaus ad0c18dceb 라이브 방
- 하트 총 개수 조회 기능 추가
2024-10-16 18:31:14 +09:00
klaus e964679154 라이브 방
- 하트 후원 API 연결
- 하트 후원 성공시 하트 애니메이션 호출
2024-10-16 18:06:38 +09:00
klaus 6c9ace146d 라이브 방
- 하트 애니메이션 추가
2024-10-16 15:54:08 +09:00
klaus c7409e4dec 라이브 방
- 채팅창 너비 축소
- 오른쪽 하단 옵션 버튼 baseline이 채팅창 baseline과 동일하게 설정
- 좋아요(누르면 1캔 후원) 버튼 추가
- 좋아요 개수 UI - 후원 캔 왼쪽에 추가
2024-10-16 02:25:55 +09:00
29 changed files with 1412 additions and 757 deletions

View File

@ -256,6 +256,17 @@
<option name="screenX" value="1812" />
<option name="screenY" value="2176" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="samsung" />
<option name="codename" value="q6q" />
<option name="id" value="q6q" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="SM-F956B" />
<option name="screenDensity" value="420" />
<option name="screenX" value="1856" />
<option name="screenY" value="2160" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="30" />
<option name="brand" value="google" />
@ -312,17 +323,6 @@
<option name="screenX" value="1080" />
<option name="screenY" value="2424" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="29" />
<option name="brand" value="samsung" />
<option name="codename" value="x1q" />
<option name="id" value="x1q" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy S20" />
<option name="screenDensity" value="480" />
<option name="screenX" value="1440" />
<option name="screenY" value="3200" />
</PersistentDeviceSelectionData>
</list>
</option>
</component>

View File

@ -35,8 +35,8 @@ android {
applicationId "kr.co.vividnext.sodalive"
minSdk 23
targetSdk 34
versionCode 117
versionName "1.21.2"
versionCode 122
versionName "1.22.3"
}
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"
}

View File

@ -636,7 +636,7 @@ class AudioContentDetailActivity : BaseActivity<ActivityAudioContentDetailBindin
response.price > 0
if (
!response.existOrdered &&
response.creator.creatorId != SharedPreferenceManager.userId && !response.existOrdered &&
response.totalContentCount != null && response.remainingContentCount != null &&
response.remainingContentCount <= 0
) {
@ -948,7 +948,7 @@ class AudioContentDetailActivity : BaseActivity<ActivityAudioContentDetailBindin
putExtra(
"can",
if (orderType == OrderType.RENTAL) {
ceil(audioContent.price * 0.6).toInt()
ceil(audioContent.price * 0.7).toInt()
} else {
audioContent.price
}

View File

@ -65,14 +65,14 @@ class AudioContentOrderConfirmDialog(
if (SharedPreferenceManager.userId == 17958L) {
dialogView.ivCan.visibility = View.GONE
dialogView.tvPrice.text = if (orderType == OrderType.RENTAL && !isOnlyRental) {
"${(ceil(price * 0.6).toInt() * 110).moneyFormat()}"
"${(ceil(price * 0.7).toInt() * 110).moneyFormat()}"
} else {
"${(price * 110).moneyFormat()}"
}
} else {
dialogView.ivCan.visibility = View.VISIBLE
dialogView.tvPrice.text = if (orderType == OrderType.RENTAL && !isOnlyRental) {
ceil(price * 0.6).toInt().moneyFormat()
ceil(price * 0.7).toInt().moneyFormat()
} else {
price.moneyFormat()
}

View File

@ -53,10 +53,10 @@ class AudioContentOrderFragment(
} else {
if (SharedPreferenceManager.userId == 17958L) {
binding.tvKeep.text = "${(price * 110).moneyFormat()}"
binding.tvRental.text = "${(ceil(price * 0.6).toInt() * 110).moneyFormat()}"
binding.tvRental.text = "${(ceil(price * 0.7).toInt() * 110).moneyFormat()}"
} else {
binding.tvKeep.text = price.moneyFormat()
binding.tvRental.text = ceil(price * 0.6).toInt().moneyFormat()
binding.tvRental.text = ceil(price * 0.7).toInt().moneyFormat()
}
binding.rlKeep.visibility = View.VISIBLE

View File

@ -46,3 +46,11 @@ fun String.fontSpan(typeface: Typeface?, text: String): SpannableString {
return spannableString
}
fun String.prefix(length: Int): String {
return if (this.length >= length) {
this.substring(0, length)
} else {
this
}
}

View File

@ -24,9 +24,10 @@ 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.GetLiveRoomHeartTotalResponse
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 +214,16 @@ 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>>
@GET("/live/room/{id}/heart-total")
fun getTotalHeartCount(
@Path("id") id: Long,
@Header("Authorization") authHeader: String
): Single<ApiResponse<GetLiveRoomHeartTotalResponse>>
}

View File

@ -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,17 @@ class LiveRepository(
creatorId = creatorId,
authHeader = token
)
fun likeHeart(roomId: Long, token: String) = api.likeHeart(
request = LiveRoomLikeHeartRequest(
roomId = roomId,
container = "aos"
),
authHeader = token
)
fun getTotalHeartCount(roomId: Long, token: String) = api.getTotalHeartCount(
roomId,
authHeader = token
)
}

View File

@ -1,5 +1,6 @@
package kr.co.vividnext.sodalive.live.room
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.app.AlertDialog
import android.app.Service
@ -8,6 +9,7 @@ import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.graphics.Rect
import android.graphics.Typeface
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Build
@ -17,17 +19,25 @@ import android.os.Handler
import android.os.Looper
import android.text.Spannable
import android.text.SpannableString
import android.text.Spanned
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.text.style.ForegroundColorSpan
import android.text.style.StyleSpan
import android.view.LayoutInflater
import android.view.View
import android.view.animation.AccelerateDecelerateInterpolator
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
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
@ -48,6 +58,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
@ -89,6 +100,7 @@ import kr.co.vividnext.sodalive.report.UserReportDialog
import kr.co.vividnext.sodalive.settings.notification.MemberRole
import org.koin.android.ext.android.inject
import java.util.regex.Pattern
import kotlin.random.Random
class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomBinding::inflate) {
@ -118,8 +130,9 @@ 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
private var remainingNoChattingTime = NO_CHATTING_TIME
private val signatureImageUrlList = mutableListOf<String>()
private var signatureImageUrl = ""
@ -141,7 +154,26 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
}
}
private val heartNicknameList = mutableListOf<String>()
private var heartNickname = ""
set(value) {
field = value
if (field.isNotBlank()) {
showHeartMessage()
handler.postDelayed({
if (heartNicknameList.isNotEmpty()) {
heartNickname = heartNicknameList.removeAt(0)
} else {
hideHeartMessage()
}
}, 1000)
}
}
private var isShowSignatureImage = false
private var isAvailableLikeHeart = false
private var buttonPosition = IntArray(2)
private val countDownTimer = object : CountDownTimer(remainingNoChattingTime * 1000, 1000) {
override fun onTick(millisUntilFinished: Long) {
@ -150,7 +182,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
override fun onFinish() {
isNoChatting = false
remainingNoChattingTime = noChattingTime
remainingNoChattingTime = NO_CHATTING_TIME
removeNoChatRoom()
Toast.makeText(
applicationContext,
@ -256,17 +288,6 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
viewModel.getMemberCan()
viewModel.getRoomInfo(roomId)
viewModel.getBlockedMemberIdList()
binding.etChat.setOnFocusChangeListener { view, hasFocus ->
if (isNoChatting && hasFocus) {
Toast.makeText(
applicationContext,
"${remainingNoChattingTime}초 동안 채팅하실 수 없습니다",
Toast.LENGTH_SHORT
).show()
view.clearFocus()
}
}
}
override fun onStart() {
@ -448,6 +469,16 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
}
)
binding.etChat.setOnFocusChangeListener { view, hasFocus ->
if (isNoChatting && hasFocus) {
Toast.makeText(
applicationContext,
"${remainingNoChattingTime}초 동안 채팅하실 수 없습니다",
Toast.LENGTH_SHORT
).show()
view.clearFocus()
}
}
binding.tvQuit.setOnClickListener { onClickQuit() }
binding.flMicrophoneMute.setOnClickListener {
microphoneMute()
@ -467,8 +498,18 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
binding.ivSpeakerMute.setImageResource(R.drawable.ic_speaker_on)
}
}
binding.etChat.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE || actionId == EditorInfo.IME_ACTION_SEND) {
inputChat()
true
} else {
false
}
}
binding.ivSend.setOnClickListener { inputChat() }
binding.flDonation.setOnClickListener {
hideKeyboard {
val dialog = LiveRoomDonationDialog(
this,
LayoutInflater.from(this),
@ -483,6 +524,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
dialog.show(screenWidth)
}
}
binding.tvNotification.setOnClickListener { viewModel.toggleShowNotice() }
binding.tvMenuPan.setOnClickListener { viewModel.toggleShowMenuPan() }
@ -512,6 +554,120 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
super.onDestroy()
}
private fun setHeartButtonPosition() {
handler.postDelayed(
{
// 버튼의 위치
val button = if (isHost) {
binding.flRouletteSettings
} else {
binding.flLikeHeart
}
buttonPosition = IntArray(2)
button.getLocationInWindow(buttonPosition)
},
500
)
}
private fun secondToMillis(second: Float): Long {
return (second * 1000).toLong()
}
private fun addHeartAnimation() {
val button = if (isHost) {
binding.flRouletteSettings
} else {
binding.flLikeHeart
}
// 하트 이미지뷰 생성
val heart = ImageView(this).apply {
setImageResource(R.drawable.ic_heart_pink) // 투명한 하트 이미지
layoutParams = FrameLayout.LayoutParams(
33.3f.dpToPx().toInt(),
33.3f.dpToPx().toInt()
) // 하트 크기 설정
}
// 하트의 초기 위치를 버튼의 위치로 설정
heart.x = (buttonPosition[0] + button.width / 2f - 50) // X축 (가운데 정렬)
heart.y = (buttonPosition[1] - 100).toFloat() // Y축 (버튼 바로 위에 생성)
binding.flRoot.addView(heart)
// 하트가 위로 올라가는 애니메이션
val animateDuration = secondToMillis(2.5f)
val moveUpAnimator = ObjectAnimator.ofFloat(
heart,
"translationY",
heart.y,
heart.y - (screenHeight * 1000 / 2337)
).apply {
duration = animateDuration
interpolator = AccelerateDecelerateInterpolator()
}
val isNegativeFirst = Random.nextBoolean()
// 좌우 이동 범위를 랜덤으로 설정
val x = 13.3f
val startX = if (isNegativeFirst) (0 - x).dpToPx() else x.dpToPx()
val endX = if (isNegativeFirst) x.dpToPx() else (0 - x).dpToPx()
val moveAnimator = ObjectAnimator.ofFloat(
heart,
"translationX",
heart.x + startX,
heart.x + endX
).apply {
duration = secondToMillis(1.5f)
repeatCount = ObjectAnimator.INFINITE
repeatMode = ObjectAnimator.REVERSE
interpolator = AccelerateDecelerateInterpolator()
}
val scaleXAnimator = ObjectAnimator.ofFloat(
heart,
"scaleX",
0.5f,
1.0f
).apply {
duration = animateDuration
}
val scaleYAnimator = ObjectAnimator.ofFloat(
heart,
"scaleY",
0.5f,
1.0f
).apply {
duration = animateDuration
}
// 하트 투명도 애니메이션
val fadeOutAnimator = ObjectAnimator.ofFloat(
heart,
"alpha",
1f,
0f
).apply {
duration = animateDuration
}
// 애니메이션 실행
moveUpAnimator.start()
moveAnimator.start()
fadeOutAnimator.start()
scaleXAnimator.start()
scaleYAnimator.start()
// 애니메이션이 끝나면 하트 제거
handler.postDelayed({
binding.flRoot.removeView(heart)
}, animateDuration)
}
private fun showOptionMenu(
context: Context,
userId: Long,
@ -738,6 +894,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
}
binding.flDonationMessageList.setOnClickListener {
hideKeyboard {
LiveRoomDonationMessageDialog(
layoutInflater = LayoutInflater.from(this),
creatorId = response.creatorId,
@ -767,6 +924,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
}
).show()
}
}
speakerListAdapter.managerId = response.creatorId
speakerListAdapter.updateList(
@ -894,11 +1052,10 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
binding.ivCreatorFollow.visibility = View.GONE
}
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
@ -974,15 +1131,80 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
binding.tvTotalCan.text = it.moneyFormat()
}
viewModel.totalHeartCount.observe(this) {
binding.tvTotalHeart.text = it.moneyFormat()
}
viewModel.coverImageUrlLiveData.observe(this) {
binding.ivCover.loadUrl(it)
}
}
private fun initRouletteSettingButton(isHost: Boolean) {
private fun initLikeHeartButton() {
if (!isHost) {
binding.flLikeHeart.visibility = View.VISIBLE
binding.flLikeHeart.setOnClickListener {
if (isAvailableLikeHeart) {
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 = {
val nickname = viewModel.getUserNickname(
SharedPreferenceManager.userId.toInt()
)
handler.post {
addHeartMessage(nickname)
addHeartAnimation()
lifecycleScope.launch { viewModel.addHeartDonation() }
}
},
onFailure = {
viewModel.refundDonation(roomId)
}
)
binding.flLikeHeart.isEnabled = true
},
onFailure = {
binding.flLikeHeart.isEnabled = true
}
)
} else {
SodaDialog(
activity = this@LiveRoomActivity,
layoutInflater = layoutInflater,
title = "안내",
desc = "'좋아해요'는 유료 후원입니다.\n" +
"클릭시 1캔이 소진됩니다.",
confirmButtonTitle = "확인",
confirmButtonClick = { isAvailableLikeHeart = true }
).show(screenWidth)
}
}
} else {
binding.flLikeHeart.visibility = View.GONE
}
}
private fun initRouletteSettingButton() {
if (isHost) {
binding.flRouletteSettings.visibility = View.VISIBLE
binding.flRouletteSettings.setOnClickListener {
hideKeyboard {
rouletteConfigResult.launch(
Intent(
applicationContext,
@ -990,15 +1212,19 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
)
)
}
}
} else {
binding.flRouletteSettings.visibility = View.GONE
}
}
private fun activatingRouletteButton(isHost: Boolean, isActiveRoulette: Boolean) {
private fun activatingRouletteButton(isActiveRoulette: Boolean) {
handler.postDelayed(
{
if (!isHost && isActiveRoulette) {
binding.flRoulette.visibility = View.VISIBLE
binding.flRoulette.setOnClickListener {
hideKeyboard {
viewModel.showRoulette {
RoulettePreviewDialog(
activity = this,
@ -1010,10 +1236,14 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
).show()
}
}
}
} else {
binding.flRoulette.visibility = View.GONE
}
},
500
)
}
private fun setNoticeAndClickableUrl(textView: TextView, text: String) {
@ -1409,7 +1639,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
)
)
invalidateChat()
viewModel.addDonationCan(can)
lifecycleScope.launch { viewModel.addDonationCan(can) }
addSignature(signature)
}
},
@ -1450,7 +1680,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
)
)
invalidateChat()
viewModel.addDonationCan(can)
lifecycleScope.launch { viewModel.addDonationCan(can) }
}
},
onFailure = {
@ -1517,7 +1747,9 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
)
)
invalidateChat()
lifecycleScope.launch {
viewModel.addDonationCan(rawMessage.can)
}
if (rawMessage.signature != null) {
addSignature(rawMessage.signature)
@ -1540,15 +1772,10 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
}
LiveRoomChatRawMessageType.TOGGLE_ROULETTE -> {
handler.post {
activatingRouletteButton(
isHost = viewModel
.roomInfoResponse
.creatorId == SharedPreferenceManager.userId,
isActiveRoulette = rawMessage.isActiveRoulette ?: false
)
}
}
LiveRoomChatRawMessageType.ROULETTE_DONATION -> {
handler.post {
@ -1560,9 +1787,19 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
)
)
invalidateChat()
lifecycleScope.launch {
viewModel.addDonationCan(rawMessage.can)
}
}
}
LiveRoomChatRawMessageType.HEART_DONATION -> {
handler.post {
addHeartMessage(nickname)
addHeartAnimation()
lifecycleScope.launch { viewModel.addHeartDonation() }
}
}
else -> {}
}
@ -1630,6 +1867,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
if (containNoChatRoom()) {
startNoChatting()
}
setHeartButtonPosition()
},
rtmChannelJoinFail = {
agoraConnectFail()
@ -1885,7 +2123,6 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
)
)
invalidateChat()
viewModel.addDonationCan(message.can)
if (message.signature != null) {
addSignature(message.signature)
@ -1898,6 +2135,46 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
}
}
private fun addHeartMessage(nickname: String) {
if (heartNickname.isBlank()) {
heartNickname = nickname
} else {
heartNicknameList.add(nickname)
}
}
private fun showHeartMessage() {
val str = "'${heartNickname}'님이 마음을 전했습니다 : \uD83D\uDC95"
val spStr = SpannableString(str)
spStr.setSpan(
ForegroundColorSpan(
ContextCompat.getColor(
applicationContext,
R.color.color_f0c030
)
),
str.indexOf("'") + 1,
str.indexOf("'님"),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
spStr.setSpan(
StyleSpan(Typeface.BOLD),
str.indexOf("'"),
str.indexOf("'님"),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
binding.tvHeartMessage.text = spStr
binding.tvHeartMessage.visibility = View.VISIBLE
}
private fun hideHeartMessage() {
heartNickname = ""
binding.tvHeartMessage.text = ""
binding.tvHeartMessage.visibility = View.GONE
}
private fun addSignatureImage(imageUrl: String) {
if (imageUrl.isNotBlank()) {
if (!isShowSignatureImage) {
@ -2006,6 +2283,6 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
}
companion object {
private const val noChattingTime = 180L
private const val NO_CHATTING_TIME = 180L
}
}

View File

@ -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
@ -64,6 +66,10 @@ class LiveRoomViewModel(
val totalDonationCan: LiveData<Int>
get() = _totalDonationCan
private val _totalHeartCount = MutableLiveData(0)
val totalHeartCount: LiveData<Int>
get() = _totalHeartCount
private val _userProfileLiveData = MutableLiveData<GetLiveRoomUserProfileResponse>()
val userProfileLiveData: LiveData<GetLiveRoomUserProfileResponse>
get() = _userProfileLiveData
@ -96,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) {
@ -215,6 +223,7 @@ class LiveRoomViewModel(
}
getTotalDonationCan(roomId = roomId)
getTotalHeart(roomId = roomId)
if (it.data.isAdult && !SharedPreferenceManager.isAuth) {
_changeIsAdultLiveData.value = true
@ -558,6 +567,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,
@ -637,9 +676,17 @@ class LiveRoomViewModel(
)
}
fun addDonationCan(can: Int) {
suspend fun addDonationCan(can: Int) {
mutex.withLock {
_totalDonationCan.postValue(totalDonationCan.value!! + can)
}
}
suspend fun addHeartDonation() {
mutex.withLock {
_totalHeartCount.postValue(totalHeartCount.value!! + 1)
}
}
fun donationStatus(roomId: Long, onSuccess: (GetLiveRoomDonationStatusResponse) -> Unit) {
_isLoading.value = true
@ -682,6 +729,27 @@ class LiveRoomViewModel(
}
}
private fun getTotalHeart(roomId: Long) {
compositeDisposable.add(
repository.getTotalHeartCount(
roomId = roomId,
token = "Bearer ${SharedPreferenceManager.token}"
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{
if (it.success && it.data != null) {
_totalHeartCount.postValue(it.data.totalHeartCount)
}
},
{
_totalHeartCount.postValue(0)
}
)
)
}
private fun getTotalDonationCan(roomId: Long) {
compositeDisposable.add(
repository.getTotalDonationCan(

View File

@ -53,6 +53,9 @@ data class LiveRoomJoinChat(
) : LiveRoomChat() {
override var type = LiveRoomChatType.JOIN
override fun bind(context: Context, binding: ViewBinding, onClickProfile: ((Long) -> Unit)?) {
(binding as ItemLiveRoomJoinChatBinding).tvJoin.setTextColor(
ContextCompat.getColor(context, R.color.color_eeeeee)
)
val str = "'$nickname'님이 입장하셨습니다."
val spStr = SpannableString(str)
@ -76,6 +79,7 @@ data class LiveRoomJoinChat(
)
(binding as ItemLiveRoomJoinChatBinding).tvJoin.text = spStr
binding.root.setBackgroundResource(R.drawable.bg_round_corner_4_7_cc004462)
}
}

View File

@ -35,5 +35,8 @@ enum class LiveRoomChatRawMessageType {
TOGGLE_ROULETTE,
@SerializedName("ROULETTE_DONATION")
ROULETTE_DONATION
ROULETTE_DONATION,
@SerializedName("HEART_DONATION")
HEART_DONATION
}

View File

@ -7,7 +7,8 @@ import com.google.gson.annotations.SerializedName
data class GetLiveRoomDonationStatusResponse(
@SerializedName("donationList") val donationList: List<GetLiveRoomDonationItem>,
@SerializedName("totalCount") val totalCount: Int,
@SerializedName("totalCan") val totalCan: Int
@SerializedName("totalCan") val totalCan: Int,
@SerializedName("totalSecretCan") val totalSecretCan: Int
)
@Keep
@ -15,5 +16,6 @@ data class GetLiveRoomDonationItem(
@SerializedName("profileImage") val profileImage: String,
@SerializedName("nickname") val nickname: String,
@SerializedName("userId") val userId: Long,
@SerializedName("can") val can: Int
@SerializedName("can") val can: Int,
@SerializedName("secretCan") val secretCan: Int
)

View File

@ -19,6 +19,7 @@ import kr.co.vividnext.sodalive.common.Constants
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
import kr.co.vividnext.sodalive.databinding.DialogLiveRoomDonationBinding
import kr.co.vividnext.sodalive.extensions.moneyFormat
import kr.co.vividnext.sodalive.extensions.prefix
import kr.co.vividnext.sodalive.mypage.can.charge.CanChargeActivity
class LiveRoomDonationDialog(
@ -50,11 +51,11 @@ class LiveRoomDonationDialog(
dialogView.tvDonation.setOnClickListener {
try {
val can = dialogView.etDonationCan.text.toString().toInt()
val message = dialogView.etDonationMessage.text.toString()
val message = dialogView.etDonationMessage.text.toString().prefix(200)
if (can > 0) {
bottomSheetDialog.dismiss()
onClickDonation(can, message, dialogView.chkSecret.isChecked)
onClickDonation(can, message, dialogView.tvSecret.isSelected)
} else {
Toast.makeText(
activity,
@ -71,10 +72,20 @@ class LiveRoomDonationDialog(
}
}
dialogView.rlSecret.visibility = if (isLiveDonation) {
View.VISIBLE
if (isLiveDonation) {
dialogView.rlSecret.visibility = View.VISIBLE
dialogView.tvSecret.setOnClickListener {
val isSelected = dialogView.tvSecret.isSelected
dialogView.tvSecret.isSelected = !isSelected
dialogView.etDonationMessage.hint = if (!isSelected) {
"함께 보낼 비밀 메시지 입력(최대 200자)"
} else {
View.GONE
"함께 보낼 메시지 입력(최대 200자)"
}
}
dialogView.tvSecret.isSelected = false
} else {
dialogView.rlSecret.visibility = View.GONE
}
setupView()

View File

@ -50,6 +50,12 @@ class LiveRoomDonationRankingAdapter :
}
binding.tvDonationCan.text = item.can.moneyFormat()
binding.tvDonationSecretCan.text = item.secretCan.moneyFormat()
binding.llDonationSecret.visibility = if (item.secretCan > 0) {
View.VISIBLE
} else {
View.GONE
}
val lp = binding.rlDonationRanking.layoutParams as FrameLayout.LayoutParams

View File

@ -37,6 +37,17 @@ class LiveRoomDonationRankingDialog(
adapter.notifyDataSetChanged()
dialogView.tvTotalCan.text = it.totalCan.moneyFormat()
dialogView.tvTotalCount.text = it.totalCount.moneyFormat()
dialogView.tvTotalSecretCan.text = it.totalSecretCan.moneyFormat()
if (it.totalSecretCan > 0) {
dialogView.llTotalCanSubTitle.visibility = View.VISIBLE
dialogView.tvTotalSecretCan.visibility = View.VISIBLE
dialogView.tvTotalCanSlash.visibility = View.VISIBLE
} else {
dialogView.llTotalCanSubTitle.visibility = View.GONE
dialogView.tvTotalSecretCan.visibility = View.GONE
dialogView.tvTotalCanSlash.visibility = View.GONE
}
}
}

View File

@ -0,0 +1,9 @@
package kr.co.vividnext.sodalive.live.room.like
import androidx.annotation.Keep
import com.google.gson.annotations.SerializedName
@Keep
data class GetLiveRoomHeartTotalResponse(
@SerializedName("totalHeartCount") val totalHeartCount: Int
)

View File

@ -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
)

View File

@ -195,7 +195,6 @@ class AlarmListActivity : BaseActivity<ActivityAlarmListBinding>(
val permissions = mutableListOf<String>()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
permissions.add(Manifest.permission.USE_FULL_SCREEN_INTENT)
permissions.add(Manifest.permission.POST_NOTIFICATIONS)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/color_fedc00" />
<corners android:radius="2.7dp" />
<stroke
android:width="1dp"
android:color="@color/color_fedc00" />
</shape>

View File

@ -479,8 +479,10 @@
android:layout_marginTop="8dp"
android:ellipsize="end"
android:maxLines="2"
android:textColor="@color/color_777777"
android:textSize="13.3sp"
android:fontFamily="@font/gmarket_sans_medium"
android:lineSpacingExtra="5dp"
android:textColor="@color/color_909090"
android:textSize="14sp"
tools:text="작품설명 작품설명 작품설명 작품설명 작품설명 작품설명 작품설명 작품설명 작품설명 작품설명 작품설명 작품설명 작품설명 작품설명 작품설명 작품설명" />
</LinearLayout>
@ -677,7 +679,7 @@
android:background="@drawable/bg_round_corner_10_13181b_3bb9f1"
android:hint="댓글을 입력해 보세요"
android:importantForAutofill="no"
android:inputType="text"
android:inputType="text|textMultiLine"
android:paddingVertical="13.3dp"
android:paddingStart="13.3dp"
android:paddingEnd="50.7dp"

View File

@ -1,11 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fl_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
tools:background="@color/black">
android:background="@color/black"
android:keepScreenOn="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/iv_cover"
@ -37,7 +42,7 @@
android:paddingStart="20dp"
android:paddingEnd="0dp"
app:layout_constraintBottom_toTopOf="@+id/rl_input_chat"
app:layout_constraintEnd_toStartOf="@+id/rl_option_buttons"
app:layout_constraintEnd_toStartOf="@+id/ll_option_buttons"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/fl_margin"
app:layout_goneMarginEnd="0dp" />
@ -51,6 +56,21 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/ll_top" />
<TextView
android:id="@+id/tv_heart_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/color_cc777777"
android:gravity="center"
android:paddingVertical="6.7dp"
android:text="dsfjkldfsjfsdkl"
android:textColor="@color/white"
android:textSize="12sp"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="@+id/fl_margin"
app:layout_constraintStart_toStartOf="@+id/fl_margin"
app:layout_constraintTop_toBottomOf="@+id/fl_margin" />
<LinearLayout
android:id="@+id/ll_notice"
android:layout_width="0dp"
@ -403,7 +423,7 @@
android:paddingVertical="5.3dp"
android:text="공지"
android:textColor="@color/color_bbbbbb"
android:textSize="12sp"
android:textSize="11sp"
tools:ignore="SmallSp" />
<TextView
@ -419,8 +439,7 @@
android:paddingVertical="5.3dp"
android:text="메뉴판"
android:textColor="@color/color_bbbbbb"
android:textSize="12sp"
android:visibility="gone"
android:textSize="11sp"
tools:ignore="SmallSp" />
<LinearLayout
@ -431,12 +450,42 @@
tools:ignore="RelativeOverlap">
<LinearLayout
android:id="@+id/ll_donation"
android:id="@+id/ll_heart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_round_corner_5_3_transparent_bbbbbb"
android:gravity="center"
android:paddingHorizontal="10dp"
android:paddingHorizontal="8dp"
android:paddingVertical="5.3dp"
tools:ignore="RelativeOverlap">
<ImageView
android:layout_width="14dp"
android:layout_height="14dp"
android:contentDescription="@null"
android:src="@drawable/ic_heart_pink" />
<TextView
android:id="@+id/tv_total_heart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6.7dp"
android:fontFamily="@font/gmarket_sans_medium"
android:gravity="center_vertical"
android:textColor="@color/color_bbbbbb"
android:textSize="11sp"
tools:ignore="SmallSp"
tools:text="999,999" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_donation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5.3dp"
android:background="@drawable/bg_round_corner_5_3_transparent_bbbbbb"
android:gravity="center"
android:paddingHorizontal="8dp"
android:paddingVertical="5.3dp"
tools:ignore="RelativeOverlap">
@ -454,9 +503,9 @@
android:fontFamily="@font/gmarket_sans_medium"
android:gravity="center_vertical"
android:textColor="@color/color_bbbbbb"
android:textSize="12sp"
android:textSize="11sp"
tools:ignore="SmallSp"
tools:text="999,999,999,999" />
tools:text="999,999" />
</LinearLayout>
<LinearLayout
@ -466,7 +515,7 @@
android:layout_marginStart="5.3dp"
android:background="@drawable/bg_round_corner_5_3_transparent_bbbbbb"
android:orientation="horizontal"
android:paddingHorizontal="11dp"
android:paddingHorizontal="8dp"
android:paddingVertical="5.3dp"
tools:ignore="RelativeOverlap">
@ -476,7 +525,7 @@
android:fontFamily="@font/gmarket_sans_medium"
android:text="참여자"
android:textColor="@color/color_bbbbbb"
android:textSize="12sp"
android:textSize="11sp"
tools:ignore="SmallSp" />
<TextView
@ -486,9 +535,9 @@
android:layout_marginStart="6.7dp"
android:fontFamily="@font/gmarket_sans_bold"
android:textColor="@color/color_bbbbbb"
android:textSize="12sp"
android:textSize="11sp"
tools:ignore="RelativeOverlap,SmallSp"
tools:text="18" />
tools:text="777" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
@ -506,21 +555,15 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<RelativeLayout
android:id="@+id/rl_option_buttons"
<LinearLayout
android:id="@+id/ll_option_buttons"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:orientation="vertical"
android:paddingStart="6.7dp"
android:paddingEnd="13.3dp"
app:layout_constraintBottom_toTopOf="@+id/rl_input_chat"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/fl_margin">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="vertical">
app:layout_constraintEnd_toEndOf="parent">
<FrameLayout
android:id="@+id/fl_speaker_mute"
@ -539,40 +582,6 @@
android:src="@drawable/ic_speaker_on" />
</FrameLayout>
<FrameLayout
android:id="@+id/fl_roulette"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="13.3dp"
android:background="@drawable/bg_round_corner_10_99525252"
android:padding="10dp"
android:visibility="gone">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:contentDescription="@null"
android:src="@drawable/ic_roulette" />
</FrameLayout>
<FrameLayout
android:id="@+id/fl_roulette_settings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="13.3dp"
android:background="@drawable/bg_round_corner_10_99525252"
android:padding="10dp"
android:visibility="gone">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:contentDescription="@null"
android:src="@drawable/ic_roulette_settings" />
</FrameLayout>
<FrameLayout
android:id="@+id/fl_microphone_mute"
android:layout_width="wrap_content"
@ -608,13 +617,48 @@
android:src="@drawable/ic_donation_message_list" />
</FrameLayout>
<FrameLayout
android:id="@+id/fl_roulette"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="13.3dp"
android:background="@drawable/bg_round_corner_10_99525252"
android:padding="10dp"
android:visibility="gone">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:contentDescription="@null"
android:src="@drawable/ic_roulette" />
</FrameLayout>
<FrameLayout
android:id="@+id/fl_roulette_settings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="13.3dp"
android:background="@drawable/bg_round_corner_10_99525252"
android:padding="10dp"
android:visibility="gone">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:contentDescription="@null"
android:src="@drawable/ic_roulette_settings" />
</FrameLayout>
<FrameLayout
android:id="@+id/fl_donation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="13.3dp"
android:background="@drawable/bg_round_corner_10_99525252"
android:padding="10dp">
android:padding="10dp"
android:visibility="gone">
<ImageView
android:layout_width="24dp"
@ -623,8 +667,25 @@
android:contentDescription="@null"
android:src="@drawable/ic_donation" />
</FrameLayout>
<FrameLayout
android:id="@+id/fl_like_heart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="13.3dp"
android:background="@drawable/bg_round_corner_10_99525252"
android:padding="10dp"
android:visibility="gone">
<ImageView
android:id="@+id/iv_like_heart"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:contentDescription="@null"
android:src="@drawable/ic_heart_pink" />
</FrameLayout>
</LinearLayout>
</RelativeLayout>
<TextView
android:id="@+id/tv_new_chat"
@ -661,8 +722,9 @@
android:fontFamily="@font/gmarket_sans_medium"
android:gravity="center_vertical"
android:hint="채팅을 입력하세요"
android:imeOptions="actionSend"
android:importantForAutofill="no"
android:inputType="text|textMultiLine"
android:inputType="text"
android:paddingVertical="16.7dp"
android:paddingStart="13.3dp"
android:paddingEnd="45dp"
@ -695,4 +757,5 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>

View File

@ -78,16 +78,19 @@
android:layout_marginBottom="13.3dp"
android:visibility="gone">
<CheckBox
android:id="@+id/chk_secret"
<TextView
android:id="@+id/tv_secret"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:button="@drawable/ic_select_square"
android:button="@null"
android:drawablePadding="8dp"
android:fontFamily="@font/gmarket_sans_medium"
android:gravity="center"
android:paddingHorizontal="8dp"
android:text="비밀후원"
android:textColor="@color/color_check_secret" />
android:textColor="@color/color_check_secret"
app:drawableStartCompat="@drawable/ic_select_square" />
</RelativeLayout>
<EditText
@ -104,7 +107,7 @@
android:textColor="@color/color_eeeeee"
android:textColorHint="@color/color_777777"
android:textCursorDrawable="@drawable/edit_text_cursor"
android:textSize="14.7sp"
android:textSize="13.3sp"
tools:ignore="LabelFor" />
<LinearLayout
@ -195,16 +198,16 @@
android:layout_marginStart="10.3dp"
android:background="@drawable/bg_round_corner_6_7_88333333"
android:fontFamily="@font/gmarket_sans_medium"
android:hint="함께 보낼 메시지 입력(최대 50자)"
android:hint="함께 보낼 메시지 입력(최대 200자)"
android:importantForAutofill="no"
android:inputType="text"
android:maxLength="50"
android:maxLength="200"
android:maxLines="1"
android:padding="13.3dp"
android:textColor="@color/color_eeeeee"
android:textColorHint="@color/color_777777"
android:textCursorDrawable="@drawable/edit_text_cursor"
android:textSize="14.7sp"
android:textSize="13.3sp"
tools:ignore="LabelFor" />
</LinearLayout>

View File

@ -41,31 +41,113 @@
android:paddingHorizontal="18.7dp"
android:paddingVertical="10.7dp">
<TextView
android:id="@+id/tv_total_can_title"
<LinearLayout
android:id="@+id/ll_total_can_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/gmarket_sans_bold"
android:text="합계"
android:textColor="@color/color_d2d2d2"
android:textSize="13.3sp" />
<LinearLayout
android:id="@+id/ll_total_can_sub_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone">
<TextView
android:id="@+id/tv_total_can"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/gmarket_sans_bold"
android:text=" ("
android:textColor="@color/color_d2d2d2"
android:textSize="13.3sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/gmarket_sans_medium"
android:text="일반"
android:textColor="@color/color_3bb9f1"
android:textSize="13.3sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/gmarket_sans_medium"
android:text="/"
android:textColor="@color/color_d2d2d2"
android:textSize="13.3sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/gmarket_sans_medium"
android:text="비밀"
android:textColor="@color/color_fedc00"
android:textSize="13.3sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/gmarket_sans_bold"
android:text=")"
android:textColor="@color/color_d2d2d2"
android:textSize="13.3sp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="2.7dp"
android:layout_toStartOf="@+id/tv_total_can_unit"
android:layout_toEndOf="@+id/tv_total_can_title"
android:layout_toEndOf="@+id/ll_total_can_title"
android:gravity="end">
<TextView
android:id="@+id/tv_total_can"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/gmarket_sans_medium"
android:gravity="end"
android:textColor="@color/color_80d8ff"
android:textSize="16sp"
android:textSize="14sp"
tools:text="1,999,999" />
<TextView
android:id="@+id/tv_total_can_slash"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/gmarket_sans_medium"
android:gravity="end"
android:text="/"
android:textColor="@color/white"
android:textSize="14sp"
android:visibility="gone" />
<TextView
android:id="@+id/tv_total_secret_can"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/gmarket_sans_medium"
android:gravity="end"
android:textColor="@color/color_fedc00"
android:textSize="14sp"
android:visibility="gone"
tools:text="1,999,999" />
</LinearLayout>
<TextView
android:id="@+id/tv_total_can_unit"
android:layout_width="wrap_content"
@ -110,7 +192,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/gmarket_sans_medium"
android:text="명"
android:text=" 명"
android:textColor="@color/color_777777"
android:textSize="12sp" />
</LinearLayout>

View File

@ -111,7 +111,7 @@
android:background="@drawable/bg_round_corner_10_232323_3bb9f1"
android:hint="댓글을 입력해 보세요"
android:importantForAutofill="no"
android:inputType="text"
android:inputType="text|textMultiLine"
android:paddingVertical="13.3dp"
android:paddingStart="13.3dp"
android:paddingEnd="50.7dp"

View File

@ -193,7 +193,7 @@
android:background="@drawable/bg_round_corner_10_232323_3bb9f1"
android:hint="댓글을 입력해 보세요"
android:importantForAutofill="no"
android:inputType="text"
android:inputType="text|textMultiLine"
android:paddingVertical="13.3dp"
android:paddingStart="13.3dp"
android:paddingEnd="50.7dp"

View File

@ -2,7 +2,8 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
tools:background="@color/black">
<RelativeLayout
android:id="@+id/rl_donation_ranking"
@ -69,14 +70,26 @@
android:textSize="13.3sp"
tools:text="Remix" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginHorizontal="13.3dp"
android:layout_toEndOf="@+id/tv_nickname"
android:gravity="end|center_vertical"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_donation_can"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="4dp"
android:layout_toStartOf="@+id/tv_donation_can_unit"
android:layout_toEndOf="@+id/tv_nickname"
android:fontFamily="@font/gmarket_sans_medium"
android:gravity="end"
android:textColor="@color/color_3bb9f1"
@ -87,14 +100,56 @@
android:id="@+id/tv_donation_can_unit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="13.3dp"
android:fontFamily="@font/gmarket_sans_medium"
android:gravity="end"
android:text="캔"
android:textColor="@color/color_eeeeee"
android:textSize="10.7sp"
tools:ignore="SmallSp" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_donation_secret"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_round_corner_2_7_fedc00"
android:fontFamily="@font/gmarket_sans_medium"
android:gravity="end"
android:paddingHorizontal="3.33dp"
android:paddingVertical="2.67dp"
android:text="비밀"
android:textColor="@color/color_111111"
android:textSize="12sp"
tools:ignore="SmallSp" />
<TextView
android:id="@+id/tv_donation_secret_can"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="4dp"
android:fontFamily="@font/gmarket_sans_medium"
android:gravity="end"
android:textColor="@color/color_fedc00"
android:textSize="13.3sp"
tools:text="1000" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/gmarket_sans_medium"
android:gravity="end"
android:text="캔"
android:textColor="@color/color_eeeeee"
android:textSize="10.7sp"
tools:ignore="SmallSp" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</FrameLayout>

View File

@ -33,6 +33,7 @@
<color name="color_a285eb">#A285EB</color>
<color name="color_3d2a6c">#3D2A6C</color>
<color name="color_ffdc00">#FFDC00</color>
<color name="color_fedc00">#FEDC00</color>
<color name="color_4999e3">#4999E3</color>
<color name="color_35c2ff">#35C2FF</color>
<color name="color_97aeff">#97AEFF</color>
@ -125,4 +126,8 @@
<color name="color_ff14d9">#FF14D9</color>
<color name="color_333bb9f1">#333BB9F1</color>
<color name="color_672bff">#672BFF</color>
<color name="color_ccffffff">#CCFFFFFF</color>
<color name="color_cc777777">#CC777777</color>
<color name="color_ec3aa6">#EC3AA6</color>
<color name="color_f0c030">#F0C030</color>
</resources>