From c1012586ceac736d626ebe168f05dc76a8224214 Mon Sep 17 00:00:00 2001 From: klaus Date: Thu, 14 Aug 2025 18:50:32 +0900 Subject: [PATCH] =?UTF-8?q?fix(chat-room):=20=EC=A0=91=EA=B7=BC=EC=84=B1?= =?UTF-8?q?=20=EB=9D=BC=EB=B2=A8=20=EB=B0=8F=20=EB=8B=A4=EA=B5=AD=EC=96=B4?= =?UTF-8?q?=20=EB=AC=B8=EC=9E=90=EC=97=B4=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 레이아웃 contentDescription 하드코딩 제거 및 strings 리소스화 - ChatMessageAdapter 접근성 문구를 리소스 기반으로 변환 - values-en 추가로 안내/버튼/접근성/상태 문구 영문화 - 타이핑 인디케이터 접근성 라벨 추가 --- .../chat/talk/room/ChatMessageAdapter.kt | 19 +++++++++------ .../main/res/layout/activity_chat_room.xml | 12 +++++----- .../main/res/layout/item_chat_ai_message.xml | 2 +- .../res/layout/item_chat_typing_indicator.xml | 5 ++-- app/src/main/res/values-en/strings.xml | 24 +++++++++++++++++++ app/src/main/res/values/strings.xml | 15 ++++++++++++ 6 files changed, 61 insertions(+), 16 deletions(-) create mode 100644 app/src/main/res/values-en/strings.xml diff --git a/app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatMessageAdapter.kt b/app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatMessageAdapter.kt index b6d934aa..5864201e 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatMessageAdapter.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatMessageAdapter.kt @@ -323,11 +323,12 @@ class ChatMessageAdapter : RecyclerView.Adapter() { // 그룹 내부 간격 최소화 (상단 패딩 축소) adjustTopPadding(isGrouped) - // 접근성: 상태 포함 설명 + // 접근성: 상태 포함 설명 (리소스 기반) + val ctx = binding.root.context val statusDesc = when (data.status) { - MessageStatus.SENDING -> "전송 중" - MessageStatus.FAILED -> "전송 실패" - MessageStatus.SENT -> "전송 완료" + MessageStatus.SENDING -> ctx.getString(R.string.status_sending) + MessageStatus.FAILED -> ctx.getString(R.string.status_failed) + MessageStatus.SENT -> ctx.getString(R.string.status_sent) } val timeDesc = if (showTime) { @@ -336,8 +337,9 @@ class ChatMessageAdapter : RecyclerView.Adapter() { "" } + val myPrefix = ctx.getString(R.string.a11y_my_message_prefix) binding.root.contentDescription = - "내 메시지 ${binding.tvMessage.text}, $statusDesc, $timeDesc" + "$myPrefix ${binding.tvMessage.text}, $statusDesc, $timeDesc" } private fun adjustTopPadding(isGrouped: Boolean) { @@ -379,13 +381,16 @@ class ChatMessageAdapter : RecyclerView.Adapter() { // 그룹 내부 간격 최소화 (상단 패딩 축소) adjustTopPadding(isGrouped) - // 접근성 + // 접근성: 다국어 대응 + val ctx = itemView.context + val messageWord = ctx.getString(R.string.a11y_message_word) itemView.contentDescription = buildString { if (!isGrouped && !binding.tvName.text.isNullOrEmpty()) { append(binding.tvName.text) append(" ") } - append("메시지 ") + append(messageWord) + append(" ") append(binding.tvMessage.text) if (showTime) { append(", ") diff --git a/app/src/main/res/layout/activity_chat_room.xml b/app/src/main/res/layout/activity_chat_room.xml index edc98607..5bf71349 100644 --- a/app/src/main/res/layout/activity_chat_room.xml +++ b/app/src/main/res/layout/activity_chat_room.xml @@ -16,7 +16,7 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" - android:contentDescription="프로필 배경 이미지" /> + android:contentDescription="@string/a11y_profile_background" /> @@ -69,7 +69,7 @@ android:layout_height="36dp" android:layout_marginStart="12dp" android:src="@drawable/ic_placeholder_profile" - android:contentDescription="프로필 이미지" + android:contentDescription="@string/a11y_profile_image" app:layout_constraintStart_toEndOf="@id/iv_back" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" /> @@ -126,7 +126,7 @@ android:layout_height="20dp" android:src="@android:drawable/ic_dialog_info" app:tint="#FFFFFFFF" - android:contentDescription="안내" + android:contentDescription="@string/a11y_notice" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" /> @@ -139,7 +139,7 @@ android:layout_marginEnd="8dp" android:textColor="#FFFFFFFF" android:textSize="12sp" - android:text="AI Clone은 크리에이터의 정보를 기반으로 대화하지만, 모든 정보를 완벽하게 반영하거나 실제 대화와 일치하지 않을 수 있습니다." + android:text="@string/chat_notice_clone" app:layout_constraintStart_toEndOf="@id/iv_notice_icon" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" @@ -151,7 +151,7 @@ android:layout_height="20dp" android:src="@android:drawable/arrow_up_float" app:tint="#FFFFFFFF" - android:contentDescription="접기" + android:contentDescription="@string/a11y_collapse" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" /> diff --git a/app/src/main/res/layout/item_chat_ai_message.xml b/app/src/main/res/layout/item_chat_ai_message.xml index 832eb99f..80770847 100644 --- a/app/src/main/res/layout/item_chat_ai_message.xml +++ b/app/src/main/res/layout/item_chat_ai_message.xml @@ -23,7 +23,7 @@ android:layout_marginEnd="8dp" android:scaleType="centerCrop" android:src="@drawable/ic_placeholder_profile" - android:contentDescription="AI 프로필 이미지" + android:contentDescription="@string/a11y_ai_profile_image" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" /> diff --git a/app/src/main/res/layout/item_chat_typing_indicator.xml b/app/src/main/res/layout/item_chat_typing_indicator.xml index ee5e8421..5c3c3815 100644 --- a/app/src/main/res/layout/item_chat_typing_indicator.xml +++ b/app/src/main/res/layout/item_chat_typing_indicator.xml @@ -12,7 +12,8 @@ android:paddingStart="12dp" android:paddingEnd="12dp" android:paddingTop="6dp" - android:paddingBottom="6dp"> + android:paddingBottom="6dp" + android:contentDescription="@string/a11y_typing"> diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml new file mode 100644 index 00000000..0cfcdd4c --- /dev/null +++ b/app/src/main/res/values-en/strings.xml @@ -0,0 +1,24 @@ + + + AI Clone converses based on the creator\'s information, but it may not perfectly reflect all details or match real conversations. + VoiceOn AI Character Talk allows a high degree of freedom. You can be anyone in the conversation. Talk as a character in a universe or create your own story with a new persona together with the character.\nNote: AI Character Talk is in open beta; conversations may be awkward or incomplete. + Type a message + Send + Retry + + + Profile background image + Back + Profile image + Notice + Collapse + AI profile image + Typing… + + + My message + Message + Sending + Failed to send + Sent + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 82be643e..2b82738a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -19,4 +19,19 @@ 메세지를 입력하세요. 전송 다시 전송 + + 프로필 배경 이미지 + 뒤로가기 + 프로필 이미지 + 안내 + 접기 + AI 프로필 이미지 + 상대방이 입력 중 + + + 내 메시지 + 메시지 + 전송 중 + 전송 실패 + 전송 완료