fix(like-heart): 터치/클릭 충돌 해결 및 길이 기반 롱프레스 분기

- 1초 미만 터치 시 `handleHeartClick()` 실행되도록 수정
- 1초 경과 후에만 중앙 하트 표시 및 스케일 업데이트 시작
- ACTION_CANCEL 시 예약 러너블 취소, 중앙 하트 제거, 클릭/롱프레스 미실행
- 2초 이상 유지 시 기존 BIG HEART 트리거 로직 유지
- 가드 추가: `isLongPressBlockedByAvailability` 케이스 안전 처리
- 러너블/타이밍 추가: `showCenterHeartRunnable`, `longPressVisualStartTime`
This commit is contained in:
2025-11-03 19:00:09 +09:00
parent 6653ca2c11
commit 332bf3256c

View File

@@ -1879,12 +1879,26 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
// 롱프레스 트리거까지의 총 시간(2초 유지 시 BIG HEART) // 롱프레스 트리거까지의 총 시간(2초 유지 시 BIG HEART)
private val longPressDurationMs = 2000L private val longPressDurationMs = 2000L
private val centerHeartShowDelayMs = 500L
private val longPressScaleDurationMs get() = longPressDurationMs private val longPressScaleDurationMs get() = longPressDurationMs
private val longPressScaleStart = 1.0f private val longPressScaleStart = 1.0f
private val longPressScaleMax = 4.0f private val longPressScaleMax = 4.0f
// 0.5초 후 중앙 하트 표시 및 스케일 업데이트 시작을 위한 러너블
private val showCenterHeartRunnable = Runnable {
if (!isTrackingLongPress) return@Runnable
if (isLongPressBlockedByAvailability) return@Runnable
if (longPressCenterHeart != null) return@Runnable
showCenterHeartForLongPress()
longPressVisualStartTime = System.currentTimeMillis()
updateCenterHeartScale(longPressScaleStart)
handler.post(longPressScaleUpdateRunnable)
}
// 롱프레스 진행 중 스케일 업데이트 러너블 // 롱프레스 진행 중 스케일 업데이트 러너블
private var longPressVisualStartTime = 0L
private val longPressScaleUpdateRunnable = object : Runnable { private val longPressScaleUpdateRunnable = object : Runnable {
override fun run() { override fun run() {
if (!isTrackingLongPress) return if (!isTrackingLongPress) return
@@ -1939,23 +1953,37 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
isLongPressTriggered = false isLongPressTriggered = false
isTrackingLongPress = true isTrackingLongPress = true
pressStartTime = System.currentTimeMillis() pressStartTime = System.currentTimeMillis()
// 중앙 하트 생성 초기 스케일 설정 // 0.5초 후 중앙 하트 표시 및 스케일 업데이트 시작
showCenterHeartForLongPress() handler.postDelayed(showCenterHeartRunnable, centerHeartShowDelayMs)
updateCenterHeartScale(longPressScaleStart)
handler.post(longPressScaleUpdateRunnable)
true true
} }
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
// 이용 불가로 인해 즉시 안내를 띄운 케이스: 클릭 위임 없이 종료 // 이용 불가로 인해 즉시 안내를 띄운 케이스: 클릭/롱프레스 모두 미실행
if (isLongPressBlockedByAvailability) { if (isLongPressBlockedByAvailability) {
isLongPressBlockedByAvailability = false isLongPressBlockedByAvailability = false
handler.removeCallbacks(showCenterHeartRunnable)
handler.removeCallbacks(longPressScaleUpdateRunnable)
removeCenterHeartForLongPress(withFade = false)
return true return true
} }
val elapsed = System.currentTimeMillis() - pressStartTime
val wasTriggered = isLongPressTriggered val wasTriggered = isLongPressTriggered
isTrackingLongPress = false isTrackingLongPress = false
// 중앙 하트 제거
// 예약된 작업 및 진행 중 애니메이션 취소
handler.removeCallbacks(showCenterHeartRunnable)
handler.removeCallbacks(longPressScaleUpdateRunnable)
if (event.action == MotionEvent.ACTION_UP && !wasTriggered) {
if (elapsed < centerHeartShowDelayMs) {
// 1초 미만: 클릭 처리
handleHeartClick()
}
}
// 중앙 하트 제거 (표시되었을 수 있으므로)
removeCenterHeartForLongPress(withFade = !wasTriggered) removeCenterHeartForLongPress(withFade = !wasTriggered)
true true
} }