Blocked Users screen UI based on Design QA#1095
Conversation
Walkthrough차단된 사용자 화면의 에러 상태 UI를 개선합니다. 새로운 BlockedUsersErrorLayout 컴포저블을 도입하여 에러 및 빈 상태를 처리하고, 헤더 타이포그래피를 조정하며, 에러 상태 아이콘을 단순화하고 재시도 문구를 갱신합니다. Changes
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan
Comment Tip You can disable the changed files summary in the walkthrough.Disable the |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
presentation/src/main/java/daily/dayo/presentation/view/TopNavigation.kt (1)
43-43: 공용 TopNavigation 타이포 변경은 화면 전반 회귀 위험이 있습니다.Line 43, Line 58 변경은
TopNavigation사용 화면 전체에 영향을 줍니다. 해당 화면만 요구된 변경이라면titleTextStyle파라미터로 화면별 오버라이드가 더 안전합니다.변경 범위 국소화를 위한 예시 diff
+import androidx.compose.ui.text.TextStyle ... fun TopNavigation( title: String = "", leftIcon: `@Composable` () -> Unit = {}, rightIcon: `@Composable` () -> Unit = {}, titleAlignment: TopNavigationAlign = TopNavigationAlign.LEFT, - windowInsets: WindowInsets = TopAppBarDefaults.windowInsets + windowInsets: WindowInsets = TopAppBarDefaults.windowInsets, + titleTextStyle: TextStyle = DayoTheme.typography.h3, ) { ... - Text(text = title, maxLines = 1, style = DayoTheme.typography.b3) + Text(text = title, maxLines = 1, style = titleTextStyle) ... - Text(text = title, maxLines = 1, style = DayoTheme.typography.b3) + Text(text = title, maxLines = 1, style = titleTextStyle)Also applies to: 58-58
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@presentation/src/main/java/daily/dayo/presentation/view/TopNavigation.kt` at line 43, The shared TopNavigation composable was changed to alter the global typography (the Text at both occurrences using DayoTheme.typography.b3), which risks regressions across all screens; instead add a new optional parameter titleTextStyle (type TextStyle) to TopNavigation with a default of DayoTheme.typography.b3 and replace the hard-coded DayoTheme.typography.b3 references in the Text(...) calls inside TopNavigation with this parameter so individual screens can override the title style without affecting other usages (update the TopNavigation function signature and both Text usages accordingly).presentation/src/main/java/daily/dayo/presentation/screen/settings/BlockedUsersScreen.kt (1)
187-208: 가중치 매직넘버(176f/336f)는 레이아웃 유지보수 리스크가 큽니다.Line 187, Line 208은 디바이스별 높이 편차에 취약합니다. 중앙 콘텐츠/하단 버튼 배치는
Box정렬로 표현하면 의도가 명확하고 안정적입니다.레이아웃 단순화 예시 diff
- Column( - modifier = Modifier - .fillMaxSize() - .padding(horizontal = 20.dp), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Spacer(modifier = Modifier.weight(176f)) - - Column( - modifier = Modifier.wrapContentHeight(), - horizontalAlignment = Alignment.CenterHorizontally, - ) { + Box( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 20.dp), + ) { + Column( + modifier = Modifier + .align(Alignment.Center) + .wrapContentHeight(), + horizontalAlignment = Alignment.CenterHorizontally, + ) { Image( painter = painterResource(id = R.drawable.ic_blocked_users_empty), contentDescription = null, modifier = Modifier .width(136.dp) .height(100.dp) ) Spacer(modifier = Modifier.height(20.dp)) Text( text = stringResource(R.string.blocked_users_error_description), style = DayoTheme.typography.h3.copy(color = Gray3_9FA5AE), modifier = Modifier.wrapContentSize() ) } - - Spacer(modifier = Modifier.weight(336f)) - FilledRoundedCornerButton( modifier = Modifier + .align(Alignment.BottomCenter) .fillMaxWidth() .height(52.dp) .padding(bottom = 20.dp), onClick = onRetry, label = stringResource(R.string.re_try), ) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@presentation/src/main/java/daily/dayo/presentation/screen/settings/BlockedUsersScreen.kt` around lines 187 - 208, The hardcoded Spacer weight magic numbers (176f/336f) around the Column with Image/Text should be replaced with a Box-based layout to avoid device-dependent spacing; wrap the Image/Text block inside a Box using contentAlignment = Alignment.Center and place the bottom button (or other bottom content) with Modifier.align(Alignment.BottomCenter) instead of Spacer, removing the two Spacer(...) calls and the Column-centered alignment approach; update references to the existing Column/Image/Text/Spacer usages in this composable to use Box, Modifier.fillMaxSize(), contentAlignment, and Modifier.align so the center content and bottom content are positioned declaratively and reliably across screen sizes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@presentation/src/main/java/daily/dayo/presentation/screen/settings/BlockedUsersScreen.kt`:
- Around line 108-113: The current UI branches only check Status.ERROR and
treats all other states the same, causing Status.LOADING to render the
empty-state LazyColumn; update the branching in BlockedUsersScreen (use a when
on blockedUsers.status) to explicitly handle Status.LOADING (render a loading
indicator), Status.ERROR (render BlockedUsersErrorLayout with onRetry calling
profileSettingViewModel.requestBlockList()), and Status.SUCCESS (render the
LazyColumn with the actual content), ensuring all NetworkResponse branches are
covered in one when expression.
---
Nitpick comments:
In
`@presentation/src/main/java/daily/dayo/presentation/screen/settings/BlockedUsersScreen.kt`:
- Around line 187-208: The hardcoded Spacer weight magic numbers (176f/336f)
around the Column with Image/Text should be replaced with a Box-based layout to
avoid device-dependent spacing; wrap the Image/Text block inside a Box using
contentAlignment = Alignment.Center and place the bottom button (or other bottom
content) with Modifier.align(Alignment.BottomCenter) instead of Spacer, removing
the two Spacer(...) calls and the Column-centered alignment approach; update
references to the existing Column/Image/Text/Spacer usages in this composable to
use Box, Modifier.fillMaxSize(), contentAlignment, and Modifier.align so the
center content and bottom content are positioned declaratively and reliably
across screen sizes.
In `@presentation/src/main/java/daily/dayo/presentation/view/TopNavigation.kt`:
- Line 43: The shared TopNavigation composable was changed to alter the global
typography (the Text at both occurrences using DayoTheme.typography.b3), which
risks regressions across all screens; instead add a new optional parameter
titleTextStyle (type TextStyle) to TopNavigation with a default of
DayoTheme.typography.b3 and replace the hard-coded DayoTheme.typography.b3
references in the Text(...) calls inside TopNavigation with this parameter so
individual screens can override the title style without affecting other usages
(update the TopNavigation function signature and both Text usages accordingly).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 659e26e2-74cd-4713-afb9-a52429875777
📒 Files selected for processing (4)
presentation/src/main/java/daily/dayo/presentation/screen/settings/BlockedUsersScreen.ktpresentation/src/main/java/daily/dayo/presentation/view/TopNavigation.ktpresentation/src/main/res/drawable/ic_blocked_users_empty.xmlpresentation/src/main/res/values/strings.xml
| if (blockedUsers.status == Status.ERROR) { | ||
| BlockedUsersErrorLayout( | ||
| onRetry = { profileSettingViewModel.requestBlockList() }, | ||
| ) | ||
| } else { | ||
| LazyColumn( |
There was a problem hiding this comment.
로딩 상태가 빈 상태로 오인 노출됩니다.
Line 108-113 로직에서는 Status.ERROR만 분기하고 나머지를 동일 처리해서, Status.LOADING일 때도 빈 상태 UI가 보일 수 있습니다. when으로 LOADING/ERROR/SUCCESS를 명시 분기해 주세요.
안전한 상태 분기 예시 diff
- if (blockedUsers.status == Status.ERROR) {
- BlockedUsersErrorLayout(
- onRetry = { profileSettingViewModel.requestBlockList() },
- )
- } else {
+ when (blockedUsers.status) {
+ Status.ERROR -> {
+ BlockedUsersErrorLayout(
+ onRetry = { profileSettingViewModel.requestBlockList() },
+ )
+ }
+ Status.LOADING -> {
+ // TODO: 로딩 상태 UI (progress/skeleton)
+ }
+ Status.SUCCESS -> {
LazyColumn(
modifier = Modifier
.fillMaxSize()
.padding(start = 20.dp, end = 20.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
contentPadding = PaddingValues(vertical = 16.dp)
) {
blockedUsers.data.orEmpty().let { blockedUsers ->
if (blockedUsers.isEmpty()) {
item {
Column(
...
)
}
} else {
itemsIndexed(
blockedUsers,
key = { _, user -> user.memberId }
) { _, user ->
...
}
}
}
}
- }
+ }
+ }As per coding guidelines "one when expression handles all NetworkResponse branches".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@presentation/src/main/java/daily/dayo/presentation/screen/settings/BlockedUsersScreen.kt`
around lines 108 - 113, The current UI branches only check Status.ERROR and
treats all other states the same, causing Status.LOADING to render the
empty-state LazyColumn; update the branching in BlockedUsersScreen (use a when
on blockedUsers.status) to explicitly handle Status.LOADING (render a loading
indicator), Status.ERROR (render BlockedUsersErrorLayout with onRetry calling
profileSettingViewModel.requestBlockList()), and Status.SUCCESS (render the
LazyColumn with the actual content), ensuring all NetworkResponse branches are
covered in one when expression.
작업 내용
참고
차단된 사용자 화면 UI 개선 (Design QA 적용)
1. 기능 및 사용자 영향
BlockedUsersScreen.kt - 레이아웃 및 상태 관리 개선
blockedUsers.status == Status.ERROR시 새로운BlockedUsersErrorLayout컴포저블로 전환하여 에러 UI를 독립적으로 관리TopNavigationAlign.CENTER를 적용하여 차단된 사용자 제목을 화면 중앙에 정렬ic_blocked_users_empty.xml - 에러 아이콘 교체
strings.xml - 재시도 텍스트 업데이트
TopNavigation.kt - 타이포그래피 통일 (부수 변경)
b3스타일로 통일하여 일관성 강화2. 리스크 포인트
에러 처리 및 상태 일관성
blockedUsers.status == Status.ERROR로의 상태 전환 로직이 ViewModel에서 올바르게 트리거되어야 함onRetry함수에서profileSettingViewModel.requestBlockList()호출 시 중복 요청 방지 필요 (로딩 중 상태 체크)레이아웃 스페이싱
wrapContentHeight()사용, ErrorLayout에서는 명시적height(100.dp)사용 → 두 상태 간 이미지 크기 일관성 확인Composable 재구성
blockedUsers상태 변화 시 전체 화면이 ERROR 또는 LIST 상태로 전환되는데, 빈 리스트에서 에러로의 상태 전이가 부자연스러울 수 있음3. 필수 검증 및 후속 테스트
UI/UX 검증
상태 관리 및 네트워크 테스트
다국어 및 호환성