fix(dm): 수신자 선택 라벨 표시를 정리한다

This commit is contained in:
2026-09-14 22:51:40 +09:00
parent a6c63b71b9
commit 7c2ea3a02b
3 changed files with 51 additions and 4 deletions
@@ -1,6 +1,10 @@
package kr.co.vividnext.sodalive.v2.main.chat.recipient
import android.text.SpannableString
import android.text.Spanned
import android.text.style.ForegroundColorSpan
import androidx.activity.viewModels
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.core.widget.doAfterTextChanged
import androidx.recyclerview.widget.LinearLayoutManager
@@ -45,12 +49,22 @@ class DmRecipientPickerActivity : BaseActivity<ActivityDmRecipientPickerBinding>
}
viewModel.recipientStateLiveData.observe(this) { state ->
adapter.submitItems(state.recipients)
binding.tvFollowers.isVisible = state.mode == DmRecipientPickerMode.FOLLOWERS
binding.tvFollowers.isVisible = state.mode == DmRecipientPickerMode.FOLLOWERS && state.recipients.isNotEmpty()
binding.tvSearchResultCount.isVisible = state.mode == DmRecipientPickerMode.SEARCH
binding.tvSearchResultCount.text = getString(
val searchResultCount = state.searchResultCount.toString()
val searchResultText = getString(
R.string.dm_recipient_search_result_count,
state.searchResultCount
)
binding.tvSearchResultCount.text = SpannableString(searchResultText).apply {
val start = searchResultText.lastIndexOf(searchResultCount)
setSpan(
ForegroundColorSpan(ContextCompat.getColor(this@DmRecipientPickerActivity, R.color.gray_500)),
start,
start + searchResultCount.length,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
}
binding.tvSearchEmpty.isVisible = state.isSearchEmpty
binding.rvRecipients.isVisible = !state.isSearchEmpty
if (state.isError) showToast(getString(R.string.common_error_request))
@@ -60,7 +60,7 @@
<TextView
android:id="@+id/tv_followers"
style="@style/Typography.Body2"
style="@style/Typography.Body1"
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center_vertical"
@@ -70,7 +70,7 @@
<TextView
android:id="@+id/tv_search_result_count"
style="@style/Typography.Caption2"
style="@style/Typography.Body1"
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center_vertical"
@@ -1,5 +1,6 @@
package kr.co.vividnext.sodalive.v2.main.chat.recipient
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertSame
import org.junit.Assert.assertTrue
@@ -33,6 +34,18 @@ class DmRecipientPickerSourceTest {
assertTrue(factory.contains("observeOn(AndroidSchedulers.mainThread())"))
}
@Test
fun `팔로워 라벨은 팔로워 모드이고 표시할 수신자가 있을 때만 보인다`() {
val source = source("main/chat/recipient/DmRecipientPickerActivity.kt")
assertTrue(
source.contains(
"binding.tvFollowers.isVisible = " +
"state.mode == DmRecipientPickerMode.FOLLOWERS && state.recipients.isNotEmpty()"
)
)
}
@Test
fun `수신자 선택은 공통 확인 팝업에서만 요청하고 취소는 부작용이 없다`() {
val source = source("main/chat/recipient/DmRecipientPickerActivity.kt")
@@ -86,6 +99,23 @@ class DmRecipientPickerSourceTest {
assertSame(content, list.parentNode)
}
@Test
fun `팔로워와 검색결과 라벨은 같은 문구 크기를 쓰고 검색결과 숫자만 gray500으로 보인다`() {
val document = DocumentBuilderFactory.newInstance().newDocumentBuilder()
.parse(file("app/src/main/res/layout/activity_dm_recipient_picker.xml"))
val followers = requireNotNull(document.findById("tv_followers"))
val searchResultCount = requireNotNull(document.findById("tv_search_result_count"))
val source = source("main/chat/recipient/DmRecipientPickerActivity.kt")
assertEquals(followers.attribute("style"), searchResultCount.attribute("style"))
assertTrue(
source.contains(
"ForegroundColorSpan(ContextCompat.getColor(this@DmRecipientPickerActivity, R.color.gray_500))"
)
)
assertTrue(source.contains("state.searchResultCount.toString()"))
}
@Test
fun `새 수신자 문구는 지원 언어 전체에 정의된다`() {
val names = listOf(
@@ -125,4 +155,7 @@ class DmRecipientPickerSourceTest {
value == "@+id/$id" || value == "@id/$id"
}
}
private fun org.w3c.dom.Node.attribute(name: String): String =
requireNotNull(attributes?.getNamedItem(name)?.nodeValue) { "missing $name" }
}