Conversation
…ANDROID into refactor#262-topbar-refactoring
Walkthrough탑바 컴포넌트들을 통합·추가하여 기존의 수동 아이콘/레이아웃을 공통 탑바( Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
시
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
app/src/main/java/com/byeboo/app/presentation/quest/review/common/personal/detail/MyDetailAnswerViewModel.kt (1)
7-7:⚠️ Potential issue | 🟡 Minor
jakarta.injectimport을javax.inject로 변경해주세요이 파일은
jakarta.inject.Inject를 사용하는 유일한 파일입니다. 프로젝트의 다른 모든 ViewModel과 클래스들은javax.inject.Inject를 사용하고 있으므로, 일관성을 위해jakarta.inject를javax.inject로 통일해야 합니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/com/byeboo/app/presentation/quest/review/common/personal/detail/MyDetailAnswerViewModel.kt` at line 7, Replace the Jakarta injection import with the javax variant: change the import statement that references jakarta.inject.Inject in MyDetailAnswerViewModel (the class annotated with `@Inject`) to use javax.inject.Inject so it matches the rest of the project; ensure any `@Inject` annotations in that file remain valid after switching the import.
🧹 Nitpick comments (8)
app/src/main/java/com/byeboo/app/presentation/quest/tip/QuestTipScreen.kt (1)
164-195: 사용되지 않는QuestTipHeader함수 제거 권장
CloseTopbar로 대체되어 더 이상 사용되지 않는 코드입니다. 데드 코드를 제거하면 코드베이스 유지보수성이 향상됩니다.♻️ 제거 제안
-@Composable -private fun QuestTipHeader( - onCloseClick: () -> Unit, - modifier: Modifier = Modifier, -) { - Box( - modifier = - modifier - .fillMaxWidth() - .padding(horizontal = screenWidthDp(24.dp)) - .padding(bottom = screenHeightDp(16.dp)), - ) { - Icon( - imageVector = ImageVector.vectorResource(id = R.drawable.ic_cancel), - contentDescription = "닫기", - tint = ByeBooTheme.colors.white, - modifier = - Modifier - .size(24.dp) - .align(Alignment.CenterEnd) - .noRippleClickable(onCloseClick), - ) - - Text( - text = "퀘스트 작성 TIP", - style = ByeBooTheme.typography.sub1, - color = ByeBooTheme.colors.white, - modifier = Modifier.align(Alignment.Center), - textAlign = TextAlign.Center, - ) - } -}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/com/byeboo/app/presentation/quest/tip/QuestTipScreen.kt` around lines 164 - 195, Remove the unused composable QuestTipHeader and replace its usages with the existing CloseTopbar; specifically delete the QuestTipHeader function declaration (the Composable named QuestTipHeader) and ensure any call sites reference CloseTopbar instead, removing imports and resources only tied to QuestTipHeader if they become unused.app/src/main/java/com/byeboo/app/presentation/quest/review/common/other/CommonOtherAnswerViewModel.kt (1)
48-50: TODO 플레이스홀더가 남아있습니다.
onBackClicked()함수가 빈 상태로 TODO 주석만 포함되어 있습니다. 네비게이션 로직이 구현되지 않으면 뒤로가기 버튼이 동작하지 않습니다.네비게이션 로직 구현을 도와드릴까요? 다른 ViewModel에서 사용하는 패턴(예:
_sideEffect.emit(...))을 참고하여 구현할 수 있습니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/com/byeboo/app/presentation/quest/review/common/other/CommonOtherAnswerViewModel.kt` around lines 48 - 50, The onBackClicked() function is a TODO placeholder and must emit the ViewModel side-effect used for navigation; implement onBackClicked() to call the existing side-effect channel (e.g., invoke _sideEffect.emit(...) or the same SideEffect type used elsewhere) with the "NavigateBack" / "Back" event so the UI can handle popping the back stack; locate onBackClicked in CommonOtherAnswerViewModel and mirror the pattern used in other ViewModels that call _sideEffect.emit(SideEffect.NavigateBack) (or the exact SideEffect enum/class your app uses).app/src/main/java/com/byeboo/app/presentation/quest/review/common/personal/MyAnswerViewModel.kt (1)
70-72: TODO 플레이스홀더가 남아있습니다.
CommonOtherAnswerViewModel과 동일하게 네비게이션 로직이 구현되지 않았습니다. 이 패턴이 여러 ViewModel에 반복되고 있으므로, 별도 이슈로 추적하여 일괄 구현하는 것이 좋을 수 있습니다.네비게이션 로직 일괄 구현을 위한 이슈를 생성해 드릴까요?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/com/byeboo/app/presentation/quest/review/common/personal/MyAnswerViewModel.kt` around lines 70 - 72, The onBackClicked() TODO in MyAnswerViewModel is a placeholder—implement the navigation behavior to match the existing pattern in CommonOtherAnswerViewModel by invoking the same navigator or navigation action used there (e.g., call the shared Navigator/route method or viewModel.back/navigation function used in CommonOtherAnswerViewModel), or extract the back-navigation into a common helper and call it from MyAnswerViewModel.onBackClicked(); if you prefer bulk changes, create a tracking issue to unify back-navigation across all similar ViewModels and reference MyAnswerViewModel::onBackClicked and CommonOtherAnswerViewModel for consistency.app/src/main/java/com/byeboo/app/presentation/offboarding/offboardingcompletedjourney/OffboardingCompletedJourneyScreen.kt (1)
118-118: 수평 간격에screenHeightDp대신screenWidthDp사용 검토
horizontalArrangement에screenHeightDp(8.dp)를 사용하고 있습니다. 수평 방향의 간격은 화면 너비 비율로 스케일링하는screenWidthDp를 사용하는 것이 더 적절할 수 있습니다.♻️ 제안 수정
- horizontalArrangement = Arrangement.spacedBy(screenHeightDp(8.dp)), + horizontalArrangement = Arrangement.spacedBy(screenWidthDp(8.dp)),🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/com/byeboo/app/presentation/offboarding/offboardingcompletedjourney/OffboardingCompletedJourneyScreen.kt` at line 118, The horizontal spacing uses screenHeightDp in the OffboardingCompletedJourneyScreen composable—replace screenHeightDp(8.dp) with screenWidthDp(8.dp) for horizontalArrangement to scale spacing by screen width; update the call site where horizontalArrangement = Arrangement.spacedBy(screenHeightDp(8.dp)) to use screenWidthDp instead (ensure the import/extension for screenWidthDp is available).app/src/main/java/com/byeboo/app/core/designsystem/component/topbar/BackTopbar.kt (1)
27-29: 접근성: 백 버튼 아이콘에contentDescription추가 권장백 버튼 아이콘의
contentDescription이null로 설정되어 있어 스크린 리더가 이 버튼의 용도를 설명할 수 없습니다. 접근성 개선을 위해 적절한 설명을 추가하는 것을 권장합니다.♻️ 제안 수정
Icon( imageVector = ImageVector.vectorResource(id = R.drawable.ic_left), - contentDescription = null, + contentDescription = "뒤로 가기", tint = ByeBooTheme.colors.gray50,🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/com/byeboo/app/core/designsystem/component/topbar/BackTopbar.kt` around lines 27 - 29, In BackTopbar (the Composable that renders the Icon with imageVector = ImageVector.vectorResource(id = R.drawable.ic_left)), replace the null contentDescription with a localized description (e.g. use stringResource(R.string.back) or a similar string key) so screen readers can announce the button; ensure you import androidx.compose.ui.res.stringResource and add the corresponding string resource (e.g. "Back" or its i18n equivalent) to your strings.xml.app/src/main/java/com/byeboo/app/presentation/quest/review/my/component/QuestReviewTopbar.kt (2)
26-27: 접근성: 아이콘에contentDescription추가 권장백 버튼과 편집 버튼 아이콘 모두
contentDescription이null입니다. 스크린 리더 사용자를 위해 적절한 설명을 추가하는 것을 권장합니다.♻️ 제안 수정
Icon( imageVector = ImageVector.vectorResource(id = R.drawable.ic_left), - contentDescription = null, + contentDescription = "뒤로 가기", tint = ByeBooTheme.colors.white, modifier = Modifier.clickable(onClick = onBackClick), ) }, actions = { Icon( imageVector = ImageVector.vectorResource(id = R.drawable.ic_edit), - contentDescription = null, + contentDescription = "편집", tint = ByeBooTheme.colors.white,Also applies to: 34-35
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/com/byeboo/app/presentation/quest/review/my/component/QuestReviewTopbar.kt` around lines 26 - 27, In QuestReviewTopbar, the Icon composables for the back and edit buttons currently set contentDescription = null; update those Icons to provide descriptive accessibility labels (e.g., use a string resource or literal like "Back" and "Edit") instead of null so screen readers can announce them; locate the Icon usages inside the QuestReviewTopbar composable (the back button Icon and the edit button Icon) and replace contentDescription = null with appropriate descriptive text (preferably via stringResource) to improve accessibility.
28-28: 클릭 수정자 일관성 검토:clickablevsnoRippleClickable
BackTopbar및CloseTopbar에서는noRippleClickable을 사용하는 반면, 이 컴포넌트에서는 표준clickable을 사용하고 있습니다. 디자인 시스템 전체에서 일관된 터치 피드백을 제공하려면 동일한 클릭 수정자를 사용하는 것이 좋습니다.♻️ 제안 수정
import com.byeboo.app.core.designsystem.component.topbar.ByeBooTopbar import com.byeboo.app.core.designsystem.ui.theme.ByeBooTheme import com.byeboo.app.core.util.screenWidthDp +import com.byeboo.app.core.util.noRippleClickable `@Composable` fun QuestReviewTopbar( onBackClick: () -> Unit, onEditClick: () -> Unit, modifier: Modifier = Modifier, ) { ByeBooTopbar( navigationIcon = { Icon( imageVector = ImageVector.vectorResource(id = R.drawable.ic_left), contentDescription = null, tint = ByeBooTheme.colors.white, - modifier = Modifier.clickable(onClick = onBackClick), + modifier = Modifier.noRippleClickable(onClick = onBackClick), ) }, actions = { Icon( imageVector = ImageVector.vectorResource(id = R.drawable.ic_edit), contentDescription = null, tint = ByeBooTheme.colors.white, - modifier = Modifier.clickable(onClick = onEditClick), + modifier = Modifier.noRippleClickable(onClick = onEditClick), ) },Also applies to: 36-36
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/com/byeboo/app/presentation/quest/review/my/component/QuestReviewTopbar.kt` at line 28, In QuestReviewTopbar replace the inconsistent Modifier.clickable usage with the design-system helper noRippleClickable to match BackTopbar and CloseTopbar; locate the Modifier.clickable(onClick = onBackClick) (and the similar clickable for the close action referencing onCloseClick) and swap them to Modifier.noRippleClickable(onClick = ...) so touch feedback is consistent across the topbar components.app/src/main/java/com/byeboo/app/presentation/quest/start/QuestStartScreen.kt (1)
83-100:verticalArrangement가 현재 구조에서는 간격을 만들지 못합니다.
Column내부에 자식이 1개라Arrangement.spacedBy(...)가 적용되지 않습니다. 버튼과의 간격 의도라면 같은Column에 포함시키는 쪽이 안전합니다.제안 패치
item { Column( modifier = Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(screenHeightDp(56.dp)), ) { GuideContent( userName = uiState.nickname, guideText = "님의 상황에 꼭 맞춘\n${uiState.journeyName} 여정의 퀘스트 30개를 드릴게요.\n\n제가 드리는 퀘스트와 함께\n이별을 극복해 나가요!", ) + + ByeBooButton( + onClick = onStartClick, + buttonText = "시작하기", + buttonStyle = ByeBooTheme.typography.body2, + buttonTextColor = ByeBooTheme.colors.white, + buttonBackgroundColor = ByeBooTheme.colors.primary300, + modifier = Modifier.padding(horizontal = screenWidthDp(24.dp)), + ) } - - ByeBooButton( - onClick = onStartClick, - buttonText = "시작하기", - buttonStyle = ByeBooTheme.typography.body2, - buttonTextColor = ByeBooTheme.colors.white, - buttonBackgroundColor = ByeBooTheme.colors.primary300, - modifier = Modifier.padding(horizontal = screenWidthDp(24.dp)), - ) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/com/byeboo/app/presentation/quest/start/QuestStartScreen.kt` around lines 83 - 100, The verticalArrangement on the Column doesn't take effect because the Column currently contains only GuideContent; move the ByeBooButton into the same Column (the Column that uses verticalArrangement = Arrangement.spacedBy(screenHeightDp(56.dp))) so the spacing applies between GuideContent and ByeBooButton, or alternatively add an explicit Spacer/weight inside that Column; update the container that wraps GuideContent and ByeBooButton (the Column with verticalArrangement) instead of leaving ByeBooButton outside, keeping onStartClick, GuideContent, ByeBooButton, and their existing modifiers intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@app/src/main/java/com/byeboo/app/core/designsystem/component/topbar/CloseTopbar.kt`:
- Around line 27-34: The Icon currently uses contentDescription = null despite
being interactive via Modifier.noRippleClickable with onCloseClick; update the
Icon to provide an appropriate accessibility label by setting contentDescription
to a string resource (e.g., close button text) or a localized prop so screen
readers announce its purpose, ensuring the interactive element (Icon in
CloseTopbar) has a non-null contentDescription tied to resources rather than
hard-coded text.
In `@app/src/main/java/com/byeboo/app/presentation/mypage/MyPageScreen.kt`:
- Around line 349-358: MyPageTopbar is calling ByeBooTopbar without a title so
the header text ("내 정보") no longer renders; update the ByeBooTopbar invocation
inside MyPageTopbar to pass the title parameter (e.g., title = "내 정보") while
keeping existing textColor, textStyle and modifier so the top bar regains the
original screen title.
In
`@app/src/main/java/com/byeboo/app/presentation/offboarding/offboardingquestreview/OffboardingQuestReviewScreen.kt`:
- Around line 195-201: The ByeBooButton in OffboardingQuestReviewScreen.kt
currently has a placeholder onClick; replace the TODO by invoking the actual
navigation or ViewModel action — e.g., call the screen's nav controller method
(navigateToReplyScreen or similar) or the OffboardingQuestReviewViewModel
function (requestAiReply / onReplyClicked) to trigger the reply flow, passing
any required questId/userId from the composable state; ensure onClick forwards
to that existing navigation function or viewModel method instead of leaving it
empty so the button performs the intended action.
- Around line 104-106: The CTA button is currently conditionally rendered based
on the derived state canScroll (val canScroll by remember { derivedStateOf {
listState.canScrollForward || listState.canScrollBackward } }), causing it to
disappear for short content; remove the canScroll gating in
OffboardingQuestReviewScreen so the "보리에게 답장 받기" CTA is always rendered
regardless of listState, and delete the unused canScroll variable if no longer
needed. Also replace the placeholder onClick (/*Todo: ai 버튼 연결 */) with the
actual handler implementation or a call to the existing AI-reply
function/dispatcher used in your codebase (connect to the ViewModel/event like
sendAiReply or similar) so the button performs the intended action when tapped.
In
`@app/src/main/java/com/byeboo/app/presentation/quest/review/common/component/AnswerDetailTopBar.kt`:
- Around line 21-39: The Icon contentDescription values are currently null in
AnswerDetailTopBar (the back and overflow icons) which breaks accessibility;
update the Icon calls used in AnswerDetailTopBar.kt to supply meaningful,
localized contentDescription strings (e.g., use string resources like
R.string.back and R.string.more_options or accept descriptions via parameters to
the AnswerDetailTopBar composable) for the ImageVector.vectorResource icons tied
to onBackClick and onClickMoreOptions so screen readers announce their purpose.
---
Outside diff comments:
In
`@app/src/main/java/com/byeboo/app/presentation/quest/review/common/personal/detail/MyDetailAnswerViewModel.kt`:
- Line 7: Replace the Jakarta injection import with the javax variant: change
the import statement that references jakarta.inject.Inject in
MyDetailAnswerViewModel (the class annotated with `@Inject`) to use
javax.inject.Inject so it matches the rest of the project; ensure any `@Inject`
annotations in that file remain valid after switching the import.
---
Nitpick comments:
In
`@app/src/main/java/com/byeboo/app/core/designsystem/component/topbar/BackTopbar.kt`:
- Around line 27-29: In BackTopbar (the Composable that renders the Icon with
imageVector = ImageVector.vectorResource(id = R.drawable.ic_left)), replace the
null contentDescription with a localized description (e.g. use
stringResource(R.string.back) or a similar string key) so screen readers can
announce the button; ensure you import androidx.compose.ui.res.stringResource
and add the corresponding string resource (e.g. "Back" or its i18n equivalent)
to your strings.xml.
In
`@app/src/main/java/com/byeboo/app/presentation/offboarding/offboardingcompletedjourney/OffboardingCompletedJourneyScreen.kt`:
- Line 118: The horizontal spacing uses screenHeightDp in the
OffboardingCompletedJourneyScreen composable—replace screenHeightDp(8.dp) with
screenWidthDp(8.dp) for horizontalArrangement to scale spacing by screen width;
update the call site where horizontalArrangement =
Arrangement.spacedBy(screenHeightDp(8.dp)) to use screenWidthDp instead (ensure
the import/extension for screenWidthDp is available).
In
`@app/src/main/java/com/byeboo/app/presentation/quest/review/common/other/CommonOtherAnswerViewModel.kt`:
- Around line 48-50: The onBackClicked() function is a TODO placeholder and must
emit the ViewModel side-effect used for navigation; implement onBackClicked() to
call the existing side-effect channel (e.g., invoke _sideEffect.emit(...) or the
same SideEffect type used elsewhere) with the "NavigateBack" / "Back" event so
the UI can handle popping the back stack; locate onBackClicked in
CommonOtherAnswerViewModel and mirror the pattern used in other ViewModels that
call _sideEffect.emit(SideEffect.NavigateBack) (or the exact SideEffect
enum/class your app uses).
In
`@app/src/main/java/com/byeboo/app/presentation/quest/review/common/personal/MyAnswerViewModel.kt`:
- Around line 70-72: The onBackClicked() TODO in MyAnswerViewModel is a
placeholder—implement the navigation behavior to match the existing pattern in
CommonOtherAnswerViewModel by invoking the same navigator or navigation action
used there (e.g., call the shared Navigator/route method or
viewModel.back/navigation function used in CommonOtherAnswerViewModel), or
extract the back-navigation into a common helper and call it from
MyAnswerViewModel.onBackClicked(); if you prefer bulk changes, create a tracking
issue to unify back-navigation across all similar ViewModels and reference
MyAnswerViewModel::onBackClicked and CommonOtherAnswerViewModel for consistency.
In
`@app/src/main/java/com/byeboo/app/presentation/quest/review/my/component/QuestReviewTopbar.kt`:
- Around line 26-27: In QuestReviewTopbar, the Icon composables for the back and
edit buttons currently set contentDescription = null; update those Icons to
provide descriptive accessibility labels (e.g., use a string resource or literal
like "Back" and "Edit") instead of null so screen readers can announce them;
locate the Icon usages inside the QuestReviewTopbar composable (the back button
Icon and the edit button Icon) and replace contentDescription = null with
appropriate descriptive text (preferably via stringResource) to improve
accessibility.
- Line 28: In QuestReviewTopbar replace the inconsistent Modifier.clickable
usage with the design-system helper noRippleClickable to match BackTopbar and
CloseTopbar; locate the Modifier.clickable(onClick = onBackClick) (and the
similar clickable for the close action referencing onCloseClick) and swap them
to Modifier.noRippleClickable(onClick = ...) so touch feedback is consistent
across the topbar components.
In
`@app/src/main/java/com/byeboo/app/presentation/quest/start/QuestStartScreen.kt`:
- Around line 83-100: The verticalArrangement on the Column doesn't take effect
because the Column currently contains only GuideContent; move the ByeBooButton
into the same Column (the Column that uses verticalArrangement =
Arrangement.spacedBy(screenHeightDp(56.dp))) so the spacing applies between
GuideContent and ByeBooButton, or alternatively add an explicit Spacer/weight
inside that Column; update the container that wraps GuideContent and
ByeBooButton (the Column with verticalArrangement) instead of leaving
ByeBooButton outside, keeping onStartClick, GuideContent, ByeBooButton, and
their existing modifiers intact.
In `@app/src/main/java/com/byeboo/app/presentation/quest/tip/QuestTipScreen.kt`:
- Around line 164-195: Remove the unused composable QuestTipHeader and replace
its usages with the existing CloseTopbar; specifically delete the QuestTipHeader
function declaration (the Composable named QuestTipHeader) and ensure any call
sites reference CloseTopbar instead, removing imports and resources only tied to
QuestTipHeader if they become unused.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (33)
app/src/main/java/com/byeboo/app/core/designsystem/component/topbar/BackTopbar.ktapp/src/main/java/com/byeboo/app/core/designsystem/component/topbar/ByeBooTopbar.ktapp/src/main/java/com/byeboo/app/core/designsystem/component/topbar/CloseTopbar.ktapp/src/main/java/com/byeboo/app/presentation/mypage/MyPageScreen.ktapp/src/main/java/com/byeboo/app/presentation/mypage/editprofile/EditProfileScreen.ktapp/src/main/java/com/byeboo/app/presentation/offboarding/offboardingcompletedguide/OffboardingCompletedGuideScreen.ktapp/src/main/java/com/byeboo/app/presentation/offboarding/offboardingcompletedjourney/OffboardingCompletedJourneyScreen.ktapp/src/main/java/com/byeboo/app/presentation/offboarding/offboardingnewjourney/OffboardingNewJourneyScreen.ktapp/src/main/java/com/byeboo/app/presentation/offboarding/offboardingquestcompleted/OffboardingQuestCompletedScreen.ktapp/src/main/java/com/byeboo/app/presentation/offboarding/offboardingquestreview/OffboardingQuestReviewScreen.ktapp/src/main/java/com/byeboo/app/presentation/offboarding/offboardingquestreview/OffboardingQuestReviewViewModel.ktapp/src/main/java/com/byeboo/app/presentation/quest/aianswer/QuestAiAnswerScreen.ktapp/src/main/java/com/byeboo/app/presentation/quest/aianswer/QuestAiAnswerStatusScreen.ktapp/src/main/java/com/byeboo/app/presentation/quest/behavior/complete/QuestBehaviorCompleteScreen.ktapp/src/main/java/com/byeboo/app/presentation/quest/behavior/writing/QuestBehaviorWritingScreen.ktapp/src/main/java/com/byeboo/app/presentation/quest/common/writing/QuestCommonWritingScreen.ktapp/src/main/java/com/byeboo/app/presentation/quest/component/topbar/QuestWritingTopbar.ktapp/src/main/java/com/byeboo/app/presentation/quest/record/complete/QuestRecordingCompleteScreen.ktapp/src/main/java/com/byeboo/app/presentation/quest/record/writing/QuestRecordingScreen.ktapp/src/main/java/com/byeboo/app/presentation/quest/review/common/component/AnswerDetailTopBar.ktapp/src/main/java/com/byeboo/app/presentation/quest/review/common/other/CommonOtherAnswerScreen.ktapp/src/main/java/com/byeboo/app/presentation/quest/review/common/other/CommonOtherAnswerState.ktapp/src/main/java/com/byeboo/app/presentation/quest/review/common/other/CommonOtherAnswerViewModel.ktapp/src/main/java/com/byeboo/app/presentation/quest/review/common/personal/MyAnswerScreen.ktapp/src/main/java/com/byeboo/app/presentation/quest/review/common/personal/MyAnswerViewModel.ktapp/src/main/java/com/byeboo/app/presentation/quest/review/common/personal/detail/MyDetailAnswerScreen.ktapp/src/main/java/com/byeboo/app/presentation/quest/review/common/personal/detail/MyDetailAnswerViewModel.ktapp/src/main/java/com/byeboo/app/presentation/quest/review/my/QuestReviewScreen.ktapp/src/main/java/com/byeboo/app/presentation/quest/review/my/component/QuestReviewTopbar.ktapp/src/main/java/com/byeboo/app/presentation/quest/start/QuestStartScreen.ktapp/src/main/java/com/byeboo/app/presentation/quest/tip/QuestTipScreen.ktapp/src/main/java/com/byeboo/app/presentation/tutorial/TutorialScreen.ktapp/src/main/java/com/byeboo/app/presentation/tutorial/TutorialViewModel.kt
app/src/main/java/com/byeboo/app/core/designsystem/component/topbar/CloseTopbar.kt
Show resolved
Hide resolved
| val canScroll by remember { | ||
| derivedStateOf { listState.canScrollForward || listState.canScrollBackward } | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
fd "OffboardingQuestReviewScreen.kt" --type fRepository: 36-APPJAM-HEARTZ/ByeBoo-ANDROID
Length of output: 187
🏁 Script executed:
wc -l app/src/main/java/com/byeboo/app/presentation/offboarding/offboardingquestreview/OffboardingQuestReviewScreen.ktRepository: 36-APPJAM-HEARTZ/ByeBoo-ANDROID
Length of output: 191
🏁 Script executed:
cat -n app/src/main/java/com/byeboo/app/presentation/offboarding/offboardingquestreview/OffboardingQuestReviewScreen.ktRepository: 36-APPJAM-HEARTZ/ByeBoo-ANDROID
Length of output: 10648
CTA 버튼 노출이 스크롤 가능 여부에 묶여 있습니다.
현재 조건(if (canScroll))으로 인해 스크롤이 필요 없는 짧은 콘텐츠에서는 "보리에게 답장 받기" 버튼이 렌더링되지 않습니다. 이는 핵심 액션이 콘텐츠 길이에 따라 무작위로 나타났다 사라지는 결과를 초래합니다. 버튼은 콘텐츠 길이와 무관하게 항상 노출해야 합니다.
제안 패치
- val canScroll by remember {
- derivedStateOf { listState.canScrollForward || listState.canScrollBackward }
- }
@@
- if (canScroll) {
- item {
- Spacer(modifier = Modifier.height(screenHeightDp(20.dp)))
-
- ByeBooButton(
- buttonText = "보리에게 답장 받기",
- buttonTextColor = ByeBooTheme.colors.white,
- buttonStyle = ByeBooTheme.typography.body2,
- buttonBackgroundColor = ByeBooTheme.colors.primary300,
- onClick = { /*Todo: ai 버튼 연결 */ },
- )
- }
- }
+ item {
+ Spacer(modifier = Modifier.height(screenHeightDp(20.dp)))
+
+ ByeBooButton(
+ buttonText = "보리에게 답장 받기",
+ buttonTextColor = ByeBooTheme.colors.white,
+ buttonStyle = ByeBooTheme.typography.body2,
+ buttonBackgroundColor = ByeBooTheme.colors.primary300,
+ onClick = { /*Todo: ai 버튼 연결 */ },
+ )
+ }또한 라인 200의 onClick 핸들러는 여전히 미구현(/*Todo: ai 버튼 연결 */) 상태이므로 함께 처리해야 합니다.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@app/src/main/java/com/byeboo/app/presentation/offboarding/offboardingquestreview/OffboardingQuestReviewScreen.kt`
around lines 104 - 106, The CTA button is currently conditionally rendered based
on the derived state canScroll (val canScroll by remember { derivedStateOf {
listState.canScrollForward || listState.canScrollBackward } }), causing it to
disappear for short content; remove the canScroll gating in
OffboardingQuestReviewScreen so the "보리에게 답장 받기" CTA is always rendered
regardless of listState, and delete the unused canScroll variable if no longer
needed. Also replace the placeholder onClick (/*Todo: ai 버튼 연결 */) with the
actual handler implementation or a call to the existing AI-reply
function/dispatcher used in your codebase (connect to the ViewModel/event like
sendAiReply or similar) so the button performs the intended action when tapped.
| ByeBooButton( | ||
| buttonText = "보리에게 답장 받기", | ||
| buttonTextColor = ByeBooTheme.colors.white, | ||
| buttonStyle = ByeBooTheme.typography.body2, | ||
| buttonBackgroundColor = ByeBooTheme.colors.primary300, | ||
| onClick = { /*Todo: ai 버튼 연결 */ }, | ||
| ) |
There was a problem hiding this comment.
버튼 클릭 핸들러가 TODO 상태라 현재 동작하지 않습니다.
UI가 노출되어도 사용자 탭에 대한 실제 액션이 없어 기능 미완료 상태입니다. 실제 네비게이션/이벤트 콜백을 연결해 주세요.
원하시면 Route-ViewModel까지 포함해서 이 버튼 액션 연결 패치안으로 정리해드릴게요.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@app/src/main/java/com/byeboo/app/presentation/offboarding/offboardingquestreview/OffboardingQuestReviewScreen.kt`
around lines 195 - 201, The ByeBooButton in OffboardingQuestReviewScreen.kt
currently has a placeholder onClick; replace the TODO by invoking the actual
navigation or ViewModel action — e.g., call the screen's nav controller method
(navigateToReplyScreen or similar) or the OffboardingQuestReviewViewModel
function (requestAiReply / onReplyClicked) to trigger the reply flow, passing
any required questId/userId from the composable state; ensure onClick forwards
to that existing navigation function or viewModel method instead of leaving it
empty so the button performs the intended action.
| Icon( | ||
| imageVector = ImageVector.vectorResource(id = R.drawable.ic_left), | ||
| contentDescription = null, | ||
| tint = ByeBooTheme.colors.gray50, | ||
| modifier = | ||
| Modifier.noRippleClickable( | ||
| onClick = onBackClick, | ||
| ), | ||
| ) | ||
| } | ||
| ) | ||
| }, | ||
| actions = { | ||
| Icon( | ||
| imageVector = ImageVector.vectorResource(id = R.drawable.ic_overflow_menu), | ||
| contentDescription = null, | ||
| tint = ByeBooTheme.colors.white, | ||
| modifier = | ||
| Modifier | ||
| .noRippleClickable( | ||
| onClick = onClickMoreOptions, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -type f -name "AnswerDetailTopBar.kt" 2>/dev/nullRepository: 36-APPJAM-HEARTZ/ByeBoo-ANDROID
Length of output: 174
🏁 Script executed:
cat -n app/src/main/java/com/byeboo/app/presentation/quest/review/common/component/AnswerDetailTopBar.ktRepository: 36-APPJAM-HEARTZ/ByeBoo-ANDROID
Length of output: 1899
뒤로가기/더보기 아이콘의 접근성 라벨이 모두 null로 설정되어 있습니다.
대화형 아이콘은 스크린리더 사용자를 위해 의미 있는 콘텐츠 설명이 필수입니다.
제안 패치
`@Composable`
fun AnswerDetailTopBar(
onBackClick: () -> Unit,
onClickMoreOptions: () -> Unit,
+ backContentDescription: String = "뒤로가기",
+ moreOptionsContentDescription: String = "더보기 옵션",
modifier: Modifier = Modifier,
) {
ByeBooTopbar(
navigationIcon = {
Icon(
imageVector = ImageVector.vectorResource(id = R.drawable.ic_left),
- contentDescription = null,
+ contentDescription = backContentDescription,
tint = ByeBooTheme.colors.gray50,
modifier =
Modifier.noRippleClickable(
onClick = onBackClick,
),
)
},
actions = {
Icon(
imageVector = ImageVector.vectorResource(id = R.drawable.ic_overflow_menu),
- contentDescription = null,
+ contentDescription = moreOptionsContentDescription,
tint = ByeBooTheme.colors.white,
modifier =
Modifier
.noRippleClickable(
onClick = onClickMoreOptions,
),
)
},
modifier = modifier,
)
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@app/src/main/java/com/byeboo/app/presentation/quest/review/common/component/AnswerDetailTopBar.kt`
around lines 21 - 39, The Icon contentDescription values are currently null in
AnswerDetailTopBar (the back and overflow icons) which breaks accessibility;
update the Icon calls used in AnswerDetailTopBar.kt to supply meaningful,
localized contentDescription strings (e.g., use string resources like
R.string.back and R.string.more_options or accept descriptions via parameters to
the AnswerDetailTopBar composable) for the ImageVector.vectorResource icons tied
to onBackClick and onClickMoreOptions so screen readers announce their purpose.
| Text( | ||
| text = "어떤 여정을 시작해 볼까요?", | ||
| color = ByeBooTheme.colors.gray50, | ||
| style = ByeBooTheme.typography.head1, |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
app/src/main/java/com/byeboo/app/presentation/offboarding/offboardingnewjourney/OffboardingNewJourneyScreen.kt (1)
153-174: Title 텍스트는stringResource분리 권장합니다.Line 161과 Line 169의 하드코딩 문자열은 다국어 지원 및 문구 변경 시 유지보수 비용이 커집니다. 현재 코드베이스에서는 설계 시스템 컴포넌트(QuestEmotionChip, MiddleTag 등)에서
stringResource를 활용하고 있으므로, 화면 레벨에도 같은 패턴을 적용하면 일관성 있는 리소스 관리가 가능합니다.♻️ 제안 diff
+import androidx.compose.ui.res.stringResource +import com.byeboo.app.R @@ Text( - text = "어떤 여정을 시작해 볼까요?", + text = stringResource(R.string.offboarding_new_journey_title), color = ByeBooTheme.colors.gray50, style = ByeBooTheme.typography.head2, ) @@ Text( - text = "각 여정 당 30개의 퀘스트를 제공해 드려요", + text = stringResource(R.string.offboarding_new_journey_subtitle), color = ByeBooTheme.colors.gray400, style = ByeBooTheme.typography.body6, )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/com/byeboo/app/presentation/offboarding/offboardingnewjourney/OffboardingNewJourneyScreen.kt` around lines 153 - 174, The Title composable currently uses hardcoded Korean strings; replace them with stringResource lookups to enable localization: create string resources (e.g., offboarding_title and offboarding_subtitle) in strings.xml, then update the Title function to call stringResource(R.string.offboarding_title) and stringResource(R.string.offboarding_subtitle) for the two Text components and import androidx.compose.ui.res.stringResource; keep the existing styling and colors unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@app/src/main/java/com/byeboo/app/presentation/offboarding/offboardingnewjourney/OffboardingNewJourneyScreen.kt`:
- Around line 93-95: BackTopbar 컴포넌트의 내부 Icon에서 contentDescription이 null로 하드코딩되어
있어 스크린리더 사용자가 버튼 목적을 알 수 없습니다; 수정 방법은 BackTopbar 함수 시그니처(BackTopbar)를 업데이트해
contentDescription:String? 매개변수를 추가하고 기본값을 "뒤로가기"로 설정하거나 호출부에서 전달하도록 변경한 뒤 Icon
호출부(contentDescription = ...)에 이 매개변수를 사용하도록 바꿔 접근성 라벨을 제공하세요.
---
Nitpick comments:
In
`@app/src/main/java/com/byeboo/app/presentation/offboarding/offboardingnewjourney/OffboardingNewJourneyScreen.kt`:
- Around line 153-174: The Title composable currently uses hardcoded Korean
strings; replace them with stringResource lookups to enable localization: create
string resources (e.g., offboarding_title and offboarding_subtitle) in
strings.xml, then update the Title function to call
stringResource(R.string.offboarding_title) and
stringResource(R.string.offboarding_subtitle) for the two Text components and
import androidx.compose.ui.res.stringResource; keep the existing styling and
colors unchanged.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
app/src/main/java/com/byeboo/app/presentation/mypage/MyPageScreen.ktapp/src/main/java/com/byeboo/app/presentation/offboarding/offboardingnewjourney/OffboardingNewJourneyScreen.kt
| BackTopbar( | ||
| onBackClick = onBackClick, | ||
| ) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find and read BackTopbar.kt
echo "=== BackTopbar.kt Implementation ==="
fd -t f 'BackTopbar\.kt' | head -1 | xargs -I {} cat -n {}
echo ""
echo "=== OffboardingNewJourneyScreen.kt around lines 93-95 ==="
fd -t f 'OffboardingNewJourneyScreen\.kt' | head -1 | xargs -I {} sh -c 'cat -n {} | sed -n "85,105p"'
echo ""
echo "=== Search for contentDescription patterns in BackTopbar ==="
fd -t f 'BackTopbar\.kt' | head -1 | xargs -I {} grep -n 'contentDescription' {}Repository: 36-APPJAM-HEARTZ/ByeBoo-ANDROID
Length of output: 2610
BackTopbar 컴포넌트에 접근성 라벨을 추가해야 합니다.
BackTopbar의 Icon 컴포넌트(line 29)에서 contentDescription = null이 하드코딩되어 있어 TalkBack 사용자가 뒤로가기 버튼의 목적을 알 수 없습니다. BackTopbar 함수 시그니처에 contentDescription 매개변수를 추가하거나, 기본값으로 "뒤로가기"와 같은 라벨을 설정하여 접근성을 개선해야 합니다.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@app/src/main/java/com/byeboo/app/presentation/offboarding/offboardingnewjourney/OffboardingNewJourneyScreen.kt`
around lines 93 - 95, BackTopbar 컴포넌트의 내부 Icon에서 contentDescription이 null로
하드코딩되어 있어 스크린리더 사용자가 버튼 목적을 알 수 없습니다; 수정 방법은 BackTopbar 함수 시그니처(BackTopbar)를
업데이트해 contentDescription:String? 매개변수를 추가하고 기본값을 "뒤로가기"로 설정하거나 호출부에서 전달하도록 변경한 뒤
Icon 호출부(contentDescription = ...)에 이 매개변수를 사용하도록 바꿔 접근성 라벨을 제공하세요.
Related issue 🛠
Work Description 📝
Screenshot 📸
Uncompleted Tasks 😅
PR Point 📌
저희 탑바를 몇몇 화면에서는 컴포넌트로 만들고 몇몇 화면에서는 그냥 만들어서 쓰고 있었던 상황이었는데요.
그래서 공통 탑바를 만든후 화면별 탑바를 만들어주는 방식으로 리팩토링 진행했습니다.
추가로 오프보딩 - 퀘스트 다시 보기 화면도 수정사항이 반영되어있어야 해서 바뀐 다시보기 화면 그대로 가져와 사용했습니다!
트러블 슈팅 💥
Summary by CodeRabbit
새로운 기능
개선사항