fix(live-room): 채팅 얼림 토글 UI와 안내 문구를 정렬한다

This commit is contained in:
2026-03-20 14:27:24 +09:00
parent a4ba3088b0
commit 3a14bad2a4
6 changed files with 92 additions and 60 deletions

View File

@@ -63,8 +63,8 @@ android {
applicationId "kr.co.vividnext.sodalive" applicationId "kr.co.vividnext.sodalive"
minSdk 23 minSdk 23
targetSdk 35 targetSdk 35
versionCode 227 versionCode 229
versionName "1.52.1" versionName "1.53.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }

View File

@@ -275,27 +275,13 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
} }
private fun updateChatFreezeToggleUi() { private fun updateChatFreezeToggleUi() {
if (isChatFrozen) { binding.tvChatFreezeSwitch.setBackgroundResource(
binding.tvChatFreezeSwitch.text = getString(R.string.screen_live_room_chat_freeze_on_label) if (isChatFrozen) {
binding.tvChatFreezeSwitch.setTextColor( R.drawable.bg_round_corner_10_803bb9f1
ContextCompat.getColor( } else {
applicationContext, R.drawable.bg_round_corner_10_99525252
R.color.color_3bb9f1 }
) )
)
binding.tvChatFreezeSwitch
.setBackgroundResource(R.drawable.bg_round_corner_5_3_transparent_3bb9f1)
} else {
binding.tvChatFreezeSwitch.text = getString(R.string.screen_live_room_chat_freeze_off_label)
binding.tvChatFreezeSwitch.setTextColor(
ContextCompat.getColor(
applicationContext,
R.color.color_eeeeee
)
)
binding.tvChatFreezeSwitch
.setBackgroundResource(R.drawable.bg_round_corner_5_3_transparent_bbbbbb)
}
} }
private fun showChatFreezeWarning() { private fun showChatFreezeWarning() {
@@ -306,15 +292,16 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
).show() ).show()
} }
private fun buildChatFreezeStatusMessage(isFrozen: Boolean, actorNickname: String): String { private fun buildChatFreezeStatusMessage(isFrozen: Boolean, isForHost: Boolean): String {
return getString( return if (isFrozen) {
if (isFrozen) { if (isForHost) {
R.string.screen_live_room_chat_freeze_started "“🧊 모두들 얼음!” 채팅창을 얼렸습니다."
} else { } else {
R.string.screen_live_room_chat_freeze_ended "“🧊 모두들 얼음!” 채팅창이 얼었습니다."
}, }
actorNickname } else {
) "“💧땡! “ 채팅창 얼리기가 해제되었습니다."
}
} }
private fun addChatFreezeStatusMessage(message: String) { private fun addChatFreezeStatusMessage(message: String) {
@@ -338,7 +325,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
val noticeMessage = buildChatFreezeStatusMessage( val noticeMessage = buildChatFreezeStatusMessage(
isFrozen = nextChatFrozen, isFrozen = nextChatFrozen,
actorNickname = SharedPreferenceManager.nickname isForHost = true
) )
addChatFreezeStatusMessage(noticeMessage) addChatFreezeStatusMessage(noticeMessage)
@@ -347,7 +334,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
rawMessage = Gson().toJson( rawMessage = Gson().toJson(
LiveRoomChatRawMessage( LiveRoomChatRawMessage(
type = LiveRoomChatRawMessageType.TOGGLE_CHAT_FREEZE, type = LiveRoomChatRawMessageType.TOGGLE_CHAT_FREEZE,
message = noticeMessage, message = "",
can = 0, can = 0,
donationMessage = "", donationMessage = "",
isChatFrozen = nextChatFrozen isChatFrozen = nextChatFrozen
@@ -1245,7 +1232,10 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
if (!isHost && response.isChatFrozen && !hasShownInitialChatFreezeNotice) { if (!isHost && response.isChatFrozen && !hasShownInitialChatFreezeNotice) {
addChatFreezeStatusMessage( addChatFreezeStatusMessage(
getString(R.string.screen_live_room_chat_freeze_started) buildChatFreezeStatusMessage(
isFrozen = true,
isForHost = false
)
) )
hasShownInitialChatFreezeNotice = true hasShownInitialChatFreezeNotice = true
} }
@@ -2342,16 +2332,10 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
val frozen = message.isChatFrozen ?: false val frozen = message.isChatFrozen ?: false
setChatFrozenState(frozen) setChatFrozenState(frozen)
val statusMessage = if (message.message.isNotBlank()) { val statusMessage = buildChatFreezeStatusMessage(
message.message isFrozen = frozen,
} else { isForHost = false
buildChatFreezeStatusMessage( )
isFrozen = frozen,
actorNickname = nickname.ifBlank {
viewModel.getManagerNickname()
}
)
}
addChatFreezeStatusMessage(statusMessage) addChatFreezeStatusMessage(statusMessage)
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 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="#803BB9F1" />
<corners android:radius="10dp" />
<stroke
android:width="1dp"
android:color="#803BB9F1" />
</shape>

View File

@@ -268,22 +268,6 @@
android:visibility="gone" android:visibility="gone"
tools:ignore="SmallSp" /> tools:ignore="SmallSp" />
<TextView
android:id="@+id/tv_chat_freeze_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:background="@drawable/bg_round_corner_5_3_transparent_bbbbbb"
android:fontFamily="@font/medium"
android:gravity="center"
android:paddingHorizontal="8dp"
android:paddingVertical="4.7dp"
android:text="@string/screen_live_room_chat_freeze_off_label"
android:textColor="@color/color_eeeeee"
android:textSize="12sp"
android:visibility="gone"
tools:ignore="SmallSp" />
<TextView <TextView
android:id="@+id/tv_signature_switch" android:id="@+id/tv_signature_switch"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -632,6 +616,24 @@
app:layout_constraintBottom_toTopOf="@+id/rl_input_chat" app:layout_constraintBottom_toTopOf="@+id/rl_input_chat"
app:layout_constraintEnd_toEndOf="parent"> app:layout_constraintEnd_toEndOf="parent">
<FrameLayout
android:id="@+id/tv_chat_freeze_switch"
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_chat_freeze"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:contentDescription="@null"
android:src="@drawable/ic_ice" />
</FrameLayout>
<FrameLayout <FrameLayout
android:id="@+id/fl_speaker_mute" android:id="@+id/fl_speaker_mute"
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@@ -0,0 +1,38 @@
# 20260320 채팅창 얼림 on/off 수정 계획
## 구현 체크리스트
- [x] 얼림 버튼 위치를 스피커 음소거 버튼 위로 이동하고 하단 마진을 13.3으로 적용한다. (QA: 레이아웃 속성 확인)
- [x] 얼림 OFF 상태 배경을 동일 위치의 기존 버튼 스타일과 동일하게 적용한다. (QA: 배경 리소스 확인)
- [x] 얼림 ON 상태 배경을 라운드 코너 10, `#3bb9f1` 50% 투명도로 적용하고 아이콘 `ic_ice`를 노출한다. (QA: 배경/아이콘 리소스 확인)
- [x] 얼림 버튼은 방장(크리에이터)에게만 보이도록 유지한다. (QA: `isHost` 분기 확인)
- [x] 얼림 ON/OFF 시스템 문구를 방장/일반 유저 조건에 맞게 변경한다. (QA: 메시지 생성/수신 분기 확인)
- [x] 수정 파일 진단, 테스트, 빌드를 실행하고 결과를 기록한다. (QA: 명령 실행 결과 확인)
## 검증 기록
- 2026-03-20
- 무엇: 얼림 버튼을 상단 텍스트 토글에서 우측 옵션 버튼 영역으로 이동하고, ON/OFF 배경 및 아이콘을 요구 조건으로 변경했다.
- 왜: 스피커 음소거 버튼 위 배치, `13.3dp` 하단 마진, OFF 동일 스타일/ON 50% 투명 `#3BB9F1` 스타일 요구사항을 충족하기 위해서다.
- 어떻게: `activity_live_room.xml`에서 `tv_chat_freeze_switch``ll_option_buttons` 최상단 `FrameLayout`로 재배치하고 `ic_ice` 아이콘을 적용했으며, `LiveRoomActivity.kt`에서 토글 UI 배경 리소스 분기를 `bg_round_corner_10_99525252`/`bg_round_corner_10_803bb9f1`로 변경했다.
- 2026-03-20
- 무엇: 얼림 ON/OFF 시스템 문구를 방장/리스너 조건으로 분기했다.
- 왜: 방장은 "채팅창을 얼렸습니다." 문구, 리스너는 "채팅창이 얼었습니다." 문구를 요구받았고 OFF 문구는 동일하게 맞춰야 했기 때문이다.
- 어떻게: `LiveRoomActivity.kt``buildChatFreezeStatusMessage`를 호스트 여부 기반으로 재작성하고, 토글 송신/수신 및 입장 시 초기 얼림 공지에서 각각 호스트/리스너 문구를 사용하도록 반영했다.
- 2026-03-20
- 무엇: 수정분 정합성 검증을 수행했다.
- 왜: 컴파일/테스트 성공 여부와 런타임 반영 가능성을 확인하기 위해서다.
- 어떻게:
- LSP 진단: `.kt`/`.xml`에 대한 로컬 LSP 서버 미구성으로 `lsp_diagnostics` 실행 불가 확인.
- 실행 명령: `./gradlew :app:testDebugUnitTest :app:assembleDebug`
- 결과: `BUILD SUCCESSFUL` (테스트 및 디버그 빌드 성공, 기존 경고만 출력)
- 2026-03-20
- 무엇: 요구사항 기반 수동 QA(소스 기준)를 수행했다.
- 왜: 얼림 버튼 위치/마진/배경/아이콘과 방장·리스너 문구가 요구 문자열과 정확히 일치하는지 최종 확인하기 위해서다.
- 어떻게:
- 실행 명령: `python3` 스크립트로 `activity_live_room.xml`의 뷰 순서·속성(`tv_chat_freeze_switch``fl_speaker_mute` 위, `13.3dp`, OFF 배경, `ic_ice`)과 `LiveRoomActivity.kt` 문구를 자동 검증
- 결과: `MANUAL QA PASS: Layout placement/style and freeze notice phrases verified from source.`
- 2026-03-20
- 무엇: 최종 빌드 재검증을 수행했다.
- 왜: 최종 응답 직전 변경 상태에서 디버그 조립 성공을 다시 확인하기 위해서다.
- 어떻게:
- 실행 명령: `./gradlew :app:assembleDebug`
- 결과: `BUILD SUCCESSFUL` (기존 경고만 출력)