-
Notifications
You must be signed in to change notification settings - Fork 0
[Refactor/#125] 감정구슬 리디자인 적용 #126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Walkthrough감정 구슬 화면 전면 리디자인: 스와이프/단순 선택/추천 루틴/로딩 템플릿과 아톰 컴포넌트 추가, Emotion 모델 재구성(이미지 타입 분리), MVI 확장(로딩·실패·토스트), ViewModel에 지연·로딩·오류 처리, DP↔PX 유틸 및 아이콘·타이포그래피 추가. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor U as 사용자
participant C as EmotionScreenContainer
participant UI_S as SwipeEmotionSelectionScreen
participant UI_L as SimpleEmotionSelectionScreen
participant VM as EmotionViewModel
participant MVI as State/Intent/SideEffect
participant T as Toast
rect rgba(224,236,255,0.35)
C->>C: BoxWithConstraints로 높이 판정 (px→dp 변환)
alt 높이 > 600.dp
C->>UI_S: Swipe 템플릿 표시
else
C->>UI_L: Simple 템플릿 표시
end
end
rect rgba(235,255,235,0.25)
U->>UI_S: 감정 드래그/선택
UI_S->>VM: selectEmotion(type, minimumDelay=1000)
VM->>MVI: Intent.RegisterEmotionLoading
MVI-->>UI_S: state.showLoadingView = true
VM->>VM: delay(minimumDelay)
alt 성공
VM-->>MVI: 성공 이벤트 → SideEffect.NavigateToBack
else 실패
VM-->>MVI: Intent.RegisterEmotionFailure(message)
MVI-->>T: SideEffect.ShowToast(message)
T-->>U: 경고 토스트 표시
MVI-->>C: SideEffect.NavigateToBack
end
MVI-->>UI_S: state.showLoadingView = false
end
sequenceDiagram
autonumber
participant EL as EmotionLoadingView
participant BG as BackgroundBox
participant MB as EmotionMarbleImage
EL->>BG: 데코 아이콘 배치 계산 및 렌더
EL->>MB: 감정 이미지 렌더(Url/Resource 분기)
EL->>EL: SpeechBubbleText 표시 (getRecommendRoutineText(emotion))
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Pre-merge checks (4 passed, 1 warning)❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Poem
Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
Please see the documentation for more information. Example: reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"
mode: "warning"
instructions: |
Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal). Please share your feedback with us on this Discord post. 📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
✨ Finishing touches
🧪 Generate unit tests
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 12
🧹 Nitpick comments (41)
core/designsystem/src/main/res/drawable/ic_double_down_arrow_24.xml (2)
6-14
: 패스 복잡도 감소를 고려(렌더/메모리 비용 절감).pathData가 곡선 세그먼트로 장문 구성되어 있습니다. 단순한 chevron(ˇ) 2개 형태라면 직선 기반 경로로 단순화해 벡터 파싱/렌더 비용을 낮출 수 있습니다. 디자인 변경 범위 내에서 가능한지 검토 바랍니다.
20-20
: EOF 개행 추가 권장.일부 툴링에서 마지막 개행이 없으면 경고가 발생합니다.
core/designsystem/src/main/res/drawable/ic_double_right_arrow_24.xml (3)
1-5
: RTL 대응: autoMirrored로 좌/우 리소스 통합 검토.우측 화살표는 android:autoMirrored="true"로 RTL 환경에서 자동 반전이 가능합니다. 좌/우를 하나의 리소스로 통합하면 중복을 줄일 수 있습니다(디자인이 완전 대칭일 경우에만).
가능한 변경 예시:
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" - android:viewportHeight="24"> + android:viewportHeight="24" + android:autoMirrored="true">
7-14
: pathData 단순화 여지.세그먼트가 많아 렌더 비용이 증가할 수 있습니다. 직선 기반 chevron 두 개로 단순화 가능하면 리소스 경량화에 도움이 됩니다.
20-20
: EOF 개행 추가 권장.core/designsystem/src/main/res/drawable/ic_double_left_arrow_24.xml (3)
1-5
: 리소스 네이밍 컨벤션 확인.프로젝트 내 다른 아이콘과의 일관성을 위해 chevron/arrow 네이밍 규칙(예: ic_chevron_double_left_24 vs ic_double_left_arrow_24)을 통일하세요.
6-14
: 경로 복잡도 최적화 검토.좌/우 아이콘 모두 단순 직선 chevron으로 표현 가능하면 pathData를 축약해 성능과 유지보수성을 개선할 수 있습니다.
20-20
: EOF 개행 추가 권장.presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/mvi/EmotionSideEffect.kt (1)
7-7
: 토스트 메시지는 String 대신 리소스 기반으로 전달하세요.i18n/테스트 용이성과 민감 정보 노출 방지를 위해 @stringres 또는 UiText 같은 래퍼를 권장합니다.
- data class ShowToast(val message: String) : EmotionSideEffect() + data class ShowToast(@androidx.annotation.StringRes val messageResId: Int, val formatArgs: List<Any> = emptyList()) : EmotionSideEffect()추가로, 소비부(EmotionScreen 등)에서
messageResId
와formatArgs
를 사용하도록 함께 변경해주세요.presentation/src/main/java/com/threegap/bitnagil/presentation/common/dimension/DpToPx.kt (1)
7-8
: 반환 타입과 KDoc을 명시해 가독성을 높이세요.의도 전달을 위해 반환 타입(Float)과 간단한 설명을 추가하는 것을 권장합니다.
-@Composable -fun Dp.dpToPx() = with(LocalDensity.current) { [email protected]() } +/** + * Density에 따라 Dp를 px(Float)로 변환합니다. + */ +@Composable +fun Dp.dpToPx(): Float = with(LocalDensity.current) { [email protected]() }core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/typography/Type.kt (1)
104-110
: 타이포그래피 명명 규칙 정리 제안(cafe24SsurroundAir2 → 보다 의도적인 이름).
...2
는 의미 전달이 약합니다. 예:cafe24SsurroundAirSmall
또는cafe24SsurroundAirBody
처럼 크기/용도를 반영하면 유지보수성이 좋아집니다. (현재 참조점이 많다면 리네이밍은 추후 일괄 반영도 OK)Also applies to: 173-173
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/mvi/EmotionState.kt (1)
17-18
: isLoading vs showLoadingView 역할·토글 일관성 확보
isLoading은 백그라운드 작업 중 입력 제어, showLoadingView는 전체 화면 오버레이 표시용으로 분리되어 있습니다. 하지만 EmotionIntent.RegisterRecommendRoutinesLoading/Success 시 showLoadingView가 토글되지 않아 UI 일관성이 깨질 수 있습니다. 의도된 분리라면 EmotionState와 Reducer에 KDoc/주석으로 역할 구분을 명확히 문서화하거나, RegisterRecommendRoutines 로직에서도 showLoadingView를 일관되게 토글하도록 수정하세요.presentation/src/main/java/com/threegap/bitnagil/presentation/common/dimension/PxToDp.kt (1)
7-10
: 반환 타입(Dp) 명시 및 간단 KDoc 추가 권장.가독성과 IDE 문서화 품질을 위해 타입/KDoc을 명시해 주세요.
-@Composable -fun Float.pxToDp() = with(LocalDensity.current) { [email protected]() } +/** Density에 따라 px(Float)을 Dp로 변환합니다. */ +@Composable +fun Float.pxToDp(): androidx.compose.ui.unit.Dp = with(LocalDensity.current) { [email protected]() } -@Composable -fun Int.pxToDp() = with(LocalDensity.current) { [email protected]() } +/** Density에 따라 px(Int)을 Dp로 변환합니다. */ +@Composable +fun Int.pxToDp(): androidx.compose.ui.unit.Dp = with(LocalDensity.current) { [email protected]() }presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/atom/SpeechBubbleText.kt (3)
3-19
: 말풍선 꼬리-본체 경계선(1px 틈) 가능성 — 살짝 겹치게 그려주세요Canvas가 별도 레이아웃이라 배경 Box와 경계가 미세하게 뜰 수 있습니다. 꼬리를 -1.dp 위로 올려 살짝 겹치면 시각적 이음새가 사라집니다.
적용 diff:
@@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width @@ Canvas( modifier = Modifier - .height(10.dp) + .height(10.dp) .width(24.dp), + .offset(y = (-1).dp), ) {Also applies to: 51-63
17-19
: 긴 텍스트 말줄임 처리 누락maxLines/minLines를 쓰는 경우 잘림 대신 말줄임표가 자연스럽습니다.
적용 diff:
@@ import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow @@ Text( text = text, style = BitnagilTheme.typography.cafe24SsurroundAir2.copy(color = Color(textColor)), textAlign = TextAlign.Center, maxLines = maxLines, minLines = minLines, + overflow = TextOverflow.Ellipsis, )Also applies to: 41-47
23-30
: Color를 직접 받는 오버로드 제공 권장현재 Long을 Color로 매번 감싸야 해 실수 여지가 있습니다. Color 파라미터 오버로드를 추가해 타입 안정성을 높여주세요.
예시:
@Composable fun SpeechBubbleText( text: String, backgroundColor: Color, textColor: Color, modifier: Modifier = Modifier, maxLines: Int = 2, minLines: Int = 2, ) { /* 내부는 Color 그대로 사용 */ } // 기존 Long API는 유지하되 Color 오버로드로 위 함수를 위임 @Composable fun SpeechBubbleText( text: String, backgroundColor: Long, textColor: Long, modifier: Modifier = Modifier, maxLines: Int = 2, minLines: Int = 2, ) = SpeechBubbleText( text = text, backgroundColor = Color(backgroundColor), textColor = Color(textColor), modifier = modifier, maxLines = maxLines, minLines = minLines, )presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/template/SimpleEmotionSelectionScreen.kt (4)
49-52
: Column 내부에서 fillMaxHeight 대신 weight 사용 권장Column 자식에 fillMaxHeight()를 쓰면 측정 제약과 충돌해 레이아웃 이슈가 날 수 있습니다. 나머지 영역만 차지하도록 weight(1f)로 교체하세요.
적용 diff:
- Box( - modifier = Modifier.fillMaxHeight(), + Box( + modifier = Modifier.weight(1f), contentAlignment = Alignment.Center, ) {
59-76
: LazyVerticalGrid 항목에 key 추가로 스크롤/애니메이션 안정성 확보안정 키가 없으면 재조합 시 포커스/상태 튀는 현상이 생길 수 있습니다.
적용 diff:
- ) { - items(state.emotionTypeUiModels) { emotion -> + ) { + items( + items = state.emotionTypeUiModels, + key = { it.emotionType }, + ) { emotion ->
65-68
: 이미지 접근성: contentDescription 전달보조기기 사용자를 위해 감정명으로 설명을 넘겨주세요.
적용 diff:
- EmotionMarbleImage( - modifier = Modifier.aspectRatio(1f), - image = emotion.image, - ) + EmotionMarbleImage( + modifier = Modifier.aspectRatio(1f), + image = emotion.image, + contentDescription = emotion.emotionMarbleName, + )
45-47
: 하드코딩 문자열 리소스화국제화/카피 수정을 위해 stringResource로 분리하세요.
예시 diff(리소스 키는 제안입니다):
- title = "오늘 감정 등록하기", + title = stringResource(id = R.string.emotion_select_title),필요 import:
import androidx.compose.ui.res.stringResource원하시면 strings.xml 스텁도 함께 드리겠습니다.
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/template/EmotionRecommendRoutineScreen.kt (2)
62-77
: 스크롤 목록은 LazyColumn 고려추천 루틴 수가 늘 경우 현재 Column+verticalScroll은 성능/메모리 비효율입니다. LazyColumn으로 전환을 권장합니다.
예시:
LazyColumn( modifier = Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(12.dp), ) { items(state.recommendRoutines, key = { it.id }) { recommendRoutine -> BitnagilSelectButton( title = recommendRoutine.name, description = recommendRoutine.description, onClick = { onClickRoutine(recommendRoutine.id) }, selected = recommendRoutine.selected, modifier = Modifier.fillMaxWidth(), ) } }
47-56
: 모든 사용자 노출 문자열 리소스화 권장헤더/본문/버튼 텍스트를 strings.xml로 이동하면 추후 카피 수정·다국어 대응이 쉬워집니다.
원하시면 리소스 키 제안과 일괄 패치 드리겠습니다.
Also applies to: 81-86, 90-101
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/EmotionUiModel.kt (2)
55-66
: 함수명 오타: “String” 접미사는 의미와 불일치색상 Long을 반환하므로 함수명을 간결하게 바꿔주세요. 호출부도 함께 교체 필요.
적용 diff:
- private fun getSymbolBackgroundColorString(emotionType: String): Long { + private fun getSymbolBackgroundColor(emotionType: String): Long { @@ - private fun getSymbolColorString(emotionType: String): Long { + private fun getSymbolColor(emotionType: String): Long {호출부:
- symbolBackgroundColor = getSymbolBackgroundColorString(emotion.emotionType), - symbolColor = getSymbolColorString(emotion.emotionType), + symbolBackgroundColor = getSymbolBackgroundColor(emotion.emotionType), + symbolColor = getSymbolColor(emotion.emotionType),Also applies to: 67-77, 26-29
19-29
: String 기반 타입 비교 최소화(선택사항)"CALM"/"VITALITY" 등 하드코딩 문자열은 오타/변경에 취약합니다. 도메인 Emotion이 enum/sealed 지원하면 그것을 직접 사용하거나, 최소한 상수(Companion const val)로 치환을 권장합니다.
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/EmotionScreen.kt (3)
41-43
: BoxWithConstraints 높이 계산 간소화 및 제약 확실화
- height 계산 시
constraints.maxHeight.pxToDp()
대신maxHeight
를 바로 쓰면 더 간결하고 안전합니다.- 화면 기준 분기라면 가로·세로 모두 제약을 받아야 합니다.
fillMaxWidth()
대신fillMaxSize()
권장.적용 예시:
- EmotionScreenStep.Emotion -> BoxWithConstraints(modifier = Modifier.fillMaxWidth()) { - val height = constraints.maxHeight.pxToDp() + EmotionScreenStep.Emotion -> BoxWithConstraints(modifier = Modifier.fillMaxSize()) { + val height = maxHeight
48-53
: 불필요한 remember 제거 및 매직 넘버 상수화
remember { { ... } }
로 람다를 캐시할 필요가 없습니다. 바로 람다 전달해도 재구성이 안전합니다.minimumDelay = 1000
은 상수로 분리하면 의도가 명확해집니다.적용 예시:
- onSelectEmotion = remember { - { emotionType -> - viewModel.selectEmotion(emotionType = emotionType, minimumDelay = 1000) - } - }, + onSelectEmotion = { emotionType -> + viewModel.selectEmotion(emotionType = emotionType, minimumDelay = MIN_LOADING_MS) + },파일 상단(또는 companion object)에:
private const val MIN_LOADING_MS = 1_000L
55-59
: 대·소 화면 간 로딩 UX 일관성 확인 필요큰 화면 스와이프 템플릿은 최소 1초 딜레이를 적용해 로딩뷰가 보이지만, 작은 화면 단순 선택 템플릿은 즉시 처리합니다. 의도된 차별이라면 OK이고, 아니라면 동일한 최소 표시 시간을 적용하는 편이 UX 일관성에 좋습니다.
선택적 수정 예시:
- onClickEmotion = viewModel::selectEmotion, + onClickEmotion = { emotionType -> + viewModel.selectEmotion(emotionType, minimumDelay = MIN_LOADING_MS) + },presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/EmotionViewModel.kt (2)
82-85
: 성공 시에도 isLoading 해제 필요
RegisterRecommendRoutinesSuccess
에서 바로 네비게이션만 보내고 상태를 갱신하지 않습니다. 화면이 남아있는 경우 로딩 상태가 유지될 수 있습니다.적용 예시:
- EmotionIntent.RegisterRecommendRoutinesSuccess -> { - sendSideEffect(EmotionSideEffect.NavigateToBack) - return null - } + EmotionIntent.RegisterRecommendRoutinesSuccess -> { + val newState = state.copy(isLoading = false) + sendSideEffect(EmotionSideEffect.NavigateToBack) + return newState + }
44-45
: 에러 처리 TODO 남음감정 목록 로드 실패 케이스가 미구현입니다. 사용자 피드백(토스트/리트라이)과 로딩 해제를 포함한 최소 처리가 필요합니다.
원하시면 실패시 토스트 + 재시도 인텐트/버튼 처리까지 포함한 패치를 제안드릴게요.
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/template/EmotionLoadingView.kt (3)
47-51
: 하드코딩 색상 → 테마 색상 사용 권장말풍선 배경/텍스트 색을 Hex로 고정하지 말고 디자인 시스템 색상으로 치환하면 다크모드/테마 대응이 쉬워집니다.
예시:
- SpeechBubbleText( - text = getRecommendRoutineText(emotion), - backgroundColor = 0xFF000000, - textColor = 0xFFFFFFFF, - ) + SpeechBubbleText( + text = getRecommendRoutineText(emotion), + backgroundColor = BitnagilTheme.colors.black.value, + textColor = BitnagilTheme.colors.white.value, + )
105-157
: 백그라운드 아이콘 오프셋 계산 단순화
constraints
(px)→pxToDp()
변환을 매번 호출하기보다maxWidth/maxHeight
(Dp) 기반 비율 연산으로 가독성과 오버헤드를 줄일 수 있습니다.예시:
- BoxWithConstraints(modifier = modifier) { - val height = constraints.maxHeight - val width = constraints.maxWidth + BoxWithConstraints(modifier = modifier) { + val height = maxHeight + val width = maxWidth @@ - offsetX = (width * 0.03f).pxToDp(), - offsetY = (height * 0.03f).pxToDp(), + offsetX = (width.value * 0.03f).dp, + offsetY = (height.value * 0.03f).dp,(이하 동일 패턴 적용)
84-92
: 접근성: 이미지 contentDescription 검토
EmotionMarbleImage
의contentDescription = null
은 장식 목적이면 OK입니다. 만약 현재 감정을 의미적으로 전달해야 한다면 텍스트 제공을 고려해 주세요.presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/template/SwipeEmotionSelectionScreen.kt (9)
389-399
: pageOffset 비교/사용 안정화 — 클램핑 및 임계치 비교로 플리커/오작동 방지pageOffset가 1을 초과하면 lerp가 역방향으로 과보정될 수 있고, 0f와의 완전 일치 비교는 부동소수 오차로 인해 드물게 드래그가 비활성화되지 않을 수 있습니다.
- val pageOffset = ( - (pagerState.currentPage - page) + pagerState.currentPageOffsetFraction - ).absoluteValue + val pageOffset = ( + (pagerState.currentPage - page) + pagerState.currentPageOffsetFraction + ).absoluteValue + val normalizedPageOffset = pageOffset.coerceIn(0f, 1f) @@ - .graphicsLayer { - translationY = lerp(start = centerItemYOffset * 1f, stop = 0f, pageOffset) - } + .graphicsLayer { + translationY = lerp(start = centerItemYOffset, stop = 0f, normalizedPageOffset) + } @@ - enabled = (pageOffset == 0f && enabled), + enabled = (pageOffset < 0.001f && enabled),
320-341
: 소형 화면 안전장치: 음수 pageSpacing/드래그 한계값 방지극단적 화면 폭/높이에서 음수 pageSpacing, 음수 maximumDraggableYOffset 가능성이 있습니다. 안전하게 클램프하세요.
- val pageSpacing = ((screenWidth - itemSize * 2) / 2) + val rawPageSpacing = (screenWidth - itemSize * 2) / 2 + val pageSpacing = if (rawPageSpacing < 0.dp) 0.dp else rawPageSpacing @@ - maximumDraggableYOffset = constraints.maxHeight - (itemSize + centerItemYOffset).dpToPx(), + maximumDraggableYOffset = (constraints.maxHeight - (itemSize + centerItemYOffset).dpToPx()).coerceAtLeast(0f),
111-115
: 하드코딩 문자열을 리소스로 이동문자열 리소스 사용으로 i18n/접근성/일관성 확보가 필요합니다.
- BitnagilTopBar( + BitnagilTopBar( showBackButton = true, - title = "오늘 감정 등록하기", + title = stringResource(R.string.emotion_register_today_title), onBackClick = onClickPreviousButton, )필요 import 및 string 리소스 추가:
+import androidx.compose.ui.res.stringResource
res/values/strings.xml:
- emotion_register_today_title: "오늘 감정 등록하기"
260-273
: 지시 문구 하드코딩 해제 및 다국어 개행 처리지시 문구도 string 리소스로 분리하고 개행은
\n
대신 리소스에서 관리하세요.- Text("선택한 감정 구슬을 아래로 놓아주세요", style = BitnagilTheme.typography.body2Medium.copy(color = BitnagilTheme.colors.coolGray50)) + Text( + stringResource(R.string.emotion_drag_down_instruction), + style = BitnagilTheme.typography.body2Medium.copy(color = BitnagilTheme.colors.coolGray50), + )strings.xml:
- emotion_drag_down_instruction: "선택한 감정 구슬을 아래로 놓아주세요"
285-289
: 지시 문구 하드코딩 해제 및 정렬 일관성다국어에서 줄바꿈/길이 차이를 고려해 리소스화하고, CenterHorizontally 유지.
- Text( - "좌우로 스와이프해\n감정 구슬을 골라주세요", + Text( + stringResource(R.string.emotion_swipe_select_instruction), style = BitnagilTheme.typography.body2Medium.copy(color = BitnagilTheme.colors.coolGray50), textAlign = TextAlign.Center, )strings.xml:
- emotion_swipe_select_instruction: "좌우로 스와이프해 감정 구슬을 골라주세요"
126-133
: 접근성: 썸네일 이미지에 contentDescription 전달상단 구슬 리스트 이미지에 이름을 전달해 스크린리더 접근성을 개선하세요.
- state.emotionTypeUiModels.forEach { emotion -> + state.emotionTypeUiModels.forEach { emotion -> EmotionMarbleImage( modifier = Modifier.size(40.dp), image = emotion.image, + contentDescription = emotion.emotionMarbleName, alpha = if (emotion.emotionType == currentItem.emotionType) 1f else 0.3f, ) }추가로 EmotionMarbleImage.kt의 Url 분기에서 contentDescription 파라미터가 무시되고 있습니다(AsyncImage에 null 전달). 해당 파일에서도 contentDescription을 전달하도록 수정이 필요합니다.
384-387
: 접근성: 중심 구슬에도 contentDescription 제공선택 대상 구슬 이미지에도 이름을 전달하세요.
EmotionMarbleImage( image = emotion.image, modifier = Modifier .size(size) + , + contentDescription = emotion.emotionMarbleName
92-99
: 세로 드래그 중 텍스트 표시 타이밍현재 showText는 가로 스크롤 진행 여부만으로 토글됩니다. 세로 드래그(선택 제스처) 중에도 텍스트를 숨기면 시각적 간섭이 줄어듭니다. offsetY>0일 때 숨기는 로직을 병행 검토해주세요.
425-462
: 프리뷰 네트워크 의존도 낮추기@Preview에서 외부 URL을 사용하면 오프라인/CI에서 로드 실패가 발생할 수 있습니다. 샘플은 리소스 기반 이미지로 대체 권장.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (30)
core/designsystem/src/main/res/drawable-hdpi/img_ground.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-hdpi/img_marble_pomo.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-hdpi/img_marble_pomo_left_hand.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-hdpi/img_marble_pomo_right_hand.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-hdpi/img_pomo_hand.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-hdpi/img_pomo_thumb.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-mdpi/img_ground.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-mdpi/img_marble_pomo.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-mdpi/img_marble_pomo_left_hand.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-mdpi/img_marble_pomo_right_hand.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-mdpi/img_pomo_hand.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-mdpi/img_pomo_thumb.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-xhdpi/img_ground.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-xhdpi/img_marble_pomo.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-xhdpi/img_marble_pomo_left_hand.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-xhdpi/img_marble_pomo_right_hand.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-xhdpi/img_pomo_hand.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-xhdpi/img_pomo_thumb.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-xxhdpi/img_ground.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-xxhdpi/img_marble_pomo.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-xxhdpi/img_marble_pomo_left_hand.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-xxhdpi/img_marble_pomo_right_hand.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-xxhdpi/img_pomo_hand.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-xxhdpi/img_pomo_thumb.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-xxxhdpi/img_ground.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-xxxhdpi/img_marble_pomo.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-xxxhdpi/img_marble_pomo_left_hand.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-xxxhdpi/img_marble_pomo_right_hand.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-xxxhdpi/img_pomo_hand.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-xxxhdpi/img_pomo_thumb.png
is excluded by!**/*.png
📒 Files selected for processing (19)
core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/typography/Type.kt
(2 hunks)core/designsystem/src/main/res/drawable/ic_double_down_arrow_24.xml
(1 hunks)core/designsystem/src/main/res/drawable/ic_double_left_arrow_24.xml
(1 hunks)core/designsystem/src/main/res/drawable/ic_double_right_arrow_24.xml
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/common/dimension/DpToPx.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/common/dimension/PxToDp.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/EmotionScreen.kt
(2 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/EmotionViewModel.kt
(3 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/atom/EmotionMarbleImage.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/atom/SpeechBubbleText.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/template/EmotionLoadingView.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/template/EmotionRecommendRoutineScreen.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/template/SimpleEmotionSelectionScreen.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/template/SwipeEmotionSelectionScreen.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/EmotionImageUiModel.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/EmotionUiModel.kt
(2 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/mvi/EmotionIntent.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/mvi/EmotionSideEffect.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/mvi/EmotionState.kt
(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (7)
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/template/EmotionRecommendRoutineScreen.kt (3)
core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/component/atom/BitnagilSelectButton.kt (1)
BitnagilSelectButton
(38-123)core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/component/atom/BitnagilTextButton.kt (1)
BitnagilTextButton
(34-85)core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/Theme.kt (1)
BitnagilTheme
(26-41)
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/atom/SpeechBubbleText.kt (1)
core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/Theme.kt (1)
BitnagilTheme
(26-41)
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/template/SimpleEmotionSelectionScreen.kt (3)
core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/component/block/BitnagilTopBar.kt (1)
BitnagilTopBar
(22-63)presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/atom/EmotionMarbleImage.kt (1)
EmotionMarbleImage
(13-41)core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/Theme.kt (1)
BitnagilTheme
(26-41)
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/template/EmotionLoadingView.kt (3)
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/atom/SpeechBubbleText.kt (1)
SpeechBubbleText
(22-65)presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/atom/EmotionMarbleImage.kt (1)
EmotionMarbleImage
(13-41)core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/Theme.kt (1)
BitnagilTheme
(26-41)
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/template/SwipeEmotionSelectionScreen.kt (3)
core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/component/block/BitnagilTopBar.kt (1)
BitnagilTopBar
(22-63)presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/atom/EmotionMarbleImage.kt (1)
EmotionMarbleImage
(13-41)presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/template/EmotionLoadingView.kt (1)
EmotionLoadingView
(32-102)
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/EmotionViewModel.kt (1)
presentation/src/main/java/com/threegap/bitnagil/presentation/common/mviviewmodel/MviViewModel.kt (2)
sendSideEffect
(23-23)sendIntent
(30-37)
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/EmotionScreen.kt (2)
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/template/SwipeEmotionSelectionScreen.kt (1)
SwipeEmotionSelectionScreen
(73-202)presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/template/SimpleEmotionSelectionScreen.kt (1)
SimpleEmotionSelectionScreen
(30-79)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (4)
core/designsystem/src/main/res/drawable/ic_double_down_arrow_24.xml (1)
2-5
: 사이즈/뷰포트 설정은 적절합니다.24dp 크기와 24x24 viewport 매핑, strokeWidth=2 설정이 스펙에 부합합니다.
core/designsystem/src/main/res/drawable/ic_double_right_arrow_24.xml (1)
2-5
: 기본 스펙은 적절합니다.24dp/viewport 24 구성과 stroke 설정 일관성 좋습니다.
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/template/EmotionRecommendRoutineScreen.kt (1)
44-45
: 상단 여백 54.dp 재확인 요청이미 statusBarsPadding + top=32.dp가 있어 Spacer(54.dp)가 과도할 수 있습니다. 디자인 기준 대비 중복 여부를 확인해주세요.
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/EmotionScreen.kt (1)
34-37
: 토스트 사이드 이펙트 처리 LGTM글로벌 토스트 경고 레벨 매핑이 명확하고, 백 네비게이션과 충돌도 없습니다.
...rc/main/java/com/threegap/bitnagil/presentation/emotion/component/atom/EmotionMarbleImage.kt
Show resolved
Hide resolved
...ain/java/com/threegap/bitnagil/presentation/emotion/component/template/EmotionLoadingView.kt
Show resolved
Hide resolved
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/EmotionViewModel.kt
Show resolved
Hide resolved
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/EmotionViewModel.kt
Show resolved
Hide resolved
...tation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/EmotionImageUiModel.kt
Show resolved
Hide resolved
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/EmotionUiModel.kt
Show resolved
Hide resolved
...entation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/mvi/EmotionIntent.kt
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/EmotionUiModel.kt (1)
43-53
: CALM 문구 경어 통일(“상태에요” → “상태예요”)이전 코멘트와 동일 이슈입니다. 다른 항목과 동일하게 경어·마침표를 맞춰주세요.
- "CALM" -> "평온함은 마음이 고요하고 편안해\n균형을 이루는 상태에요." + "CALM" -> "평온함은 마음이 고요하고 편안해\n균형을 이루는 상태예요."
🧹 Nitpick comments (4)
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/EmotionUiModel.kt (4)
12-16
: 색상 리터럴에 L 접미사 추가로 타입 명확화컨텍스트 기반 추론 대신 Long 리터럴임을 명시하면 오해·회귀를 줄일 수 있습니다.
적용 diff(이 범위):
- val symbolBackgroundColor: Long = 0xFFEAEBEC, - val symbolColor: Long = 0xFF878A93, + val symbolBackgroundColor: Long = 0xFFEAEBECL, + val symbolColor: Long = 0xFF878A93L,추가로 아래 범위에도 동일 적용 권장:
- 55-65, 67-77, 85-86 라인의 색상 리터럴들에 L 접미사 추가.
- "CALM" -> 0xFFEFECFF + "CALM" -> 0xFFEFECFFL - "VITALITY" -> 0xFFE9FAD0 + "VITALITY" -> 0xFFE9FAD0L - "LETHARGY" -> 0xFFEAEBEC + "LETHARGY" -> 0xFFEAEBECL - "ANXIETY" -> 0xFFFFEEE4 + "ANXIETY" -> 0xFFFFEEE4L - "SATISFACTION" -> 0xFFE2F3F6 + "SATISFACTION" -> 0xFFE2F3F6L - "FATIGUE" -> 0xFFFFE1E1 + "FATIGUE" -> 0xFFFFE1E1L - else -> 0xFFEAEBEC + else -> 0xFFEAEBECL- "CALM" -> 0xFF692BD0 + "CALM" -> 0xFF692BD0L - "VITALITY" -> 0xFF609F00 + "VITALITY" -> 0xFF609F00L - "LETHARGY" -> 0xFF5A5C63 + "LETHARGY" -> 0xFF5A5C63L - "ANXIETY" -> 0xFFFE7120 + "ANXIETY" -> 0xFFFE7120L - "SATISFACTION" -> 0xFF26A792 + "SATISFACTION" -> 0xFF26A792L - "FATIGUE" -> 0xFFFF5151 + "FATIGUE" -> 0xFFFF5151L - else -> 0xFF878A93 + else -> 0xFF878A93L- symbolBackgroundColor = 0xFFEAEBEC, - symbolColor = 0xFF171719, + symbolBackgroundColor = 0xFFEAEBECL, + symbolColor = 0xFF171719L,
22-29
: imageUrl 공백/누락 시 즉시 로컬 리소스로 폴백빈 문자열일 경우 네트워크 로더가 불필요한 시도를 할 수 있습니다. URL이 비어있으면 Resource를 바로 쓰도록 폴백하면 UX 안정적입니다.
- image = EmotionImageUiModel.Url( - url = emotion.imageUrl, - offlineBackupImageResourceId = getOfflineBackupImageResourceId(emotion.emotionType), - ), + image = if (emotion.imageUrl.isNullOrBlank()) { + EmotionImageUiModel.Resource( + getOfflineBackupImageResourceId(emotion.emotionType) ?: R.drawable.default_marble + ) + } else { + EmotionImageUiModel.Url( + url = emotion.imageUrl, + offlineBackupImageResourceId = getOfflineBackupImageResourceId(emotion.emotionType), + ) + },
55-65
: 함수명 오해 소지: “…ColorString” → “…Color”로 변경반환 타입이 Long인데 이름에 String이 포함되어 혼동을 줍니다. 함수명 및 호출부를 정리하세요.
-private fun getSymbolBackgroundColorString(emotionType: String): Long { +private fun getSymbolBackgroundColor(emotionType: String): Long {호출부(라인 27)도 함께 수정:
- symbolBackgroundColor = getSymbolBackgroundColorString(emotion.emotionType), + symbolBackgroundColor = getSymbolBackgroundColor(emotion.emotionType),
67-77
: 함수명 오해 소지(2): “…ColorString” → “…Color”위와 동일 맥락입니다.
-private fun getSymbolColorString(emotionType: String): Long { +private fun getSymbolColor(emotionType: String): Long {호출부(라인 28)도 함께 수정:
- symbolColor = getSymbolColorString(emotion.emotionType), + symbolColor = getSymbolColor(emotion.emotionType),
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/atom/EmotionMarbleImage.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/template/EmotionRecommendRoutineScreen.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/EmotionImageUiModel.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/EmotionUiModel.kt
(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/atom/EmotionMarbleImage.kt
- presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/EmotionImageUiModel.kt
- presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/component/template/EmotionRecommendRoutineScreen.kt
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-10T10:50:55.009Z
Learnt from: l5x5l
PR: YAPP-Github/Bitnagil-Android#126
File: presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/EmotionViewModel.kt:118-139
Timestamp: 2025-09-10T10:50:55.009Z
Learning: In EmotionViewModel.kt, the minimumDelay parameter in selectEmotion() is intentionally designed as a fixed pre-delay for animation effects, not as a minimum total duration guarantee. This is a deliberate UX decision to ensure proper animation timing.
Applied to files:
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/EmotionUiModel.kt
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (1)
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/EmotionUiModel.kt (1)
79-87
: Default 모델 구성 적절선택 불가 상태, 안내 문구, 기본 이미지/색상 세팅 모두 합리적입니다. 프리뷰/초기 상태에 그대로 사용 가능해 보입니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/EmotionUiModel.kt (1)
43-53
: CALM 문구 맞춤법: “상태에요.” → “상태예요.” (이전 코멘트 재반영)경어 통일을 위해 “예요”로 교정 부탁드립니다.
- "CALM" -> "평온함은 마음이 고요하고 편안해\n균형을 이루는 상태에요." + "CALM" -> "평온함은 마음이 고요하고 편안해\n균형을 이루는 상태예요."
🧹 Nitpick comments (4)
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/EmotionUiModel.kt (4)
12-16
: 색상 타입을 ULong/Color로 정렬해 타입 캐스팅·부호 이슈 예방Compose Color가 ULong 기반이라 Long 유지 시 toULong()/toLong() 캐스팅이 퍼질 수 있고, 0xFFxxxxxx가 Int로 축소·음수 취급되는 혼란도 유발합니다. ULong으로 두면 안전합니다.
적용 diff:
- val symbolBackgroundColor: Long = 0xFFEAEBEC, - val symbolColor: Long = 0xFF878A93, + val symbolBackgroundColor: ULong = 0xFFEAEBECu, + val symbolColor: ULong = 0xFF878A93u,아래 팔레트 함수 반환 타입도 함께 ULong으로 바꿔주세요(라인 55-77 제안 diff 참고).
43-53
: 하드코딩 문자열 → string 리소스로 이전 권장복수 언어/카피 개정 대응을 위해 메시지는 @stringres로 들고 UI 레이어에서 resolve하는 편이 안전합니다.
원하시면 message: Int?(@stringres)로 변경하는 마이그레이션 패치와 strings.xml 초안 만들어드릴게요.
55-65
: 배경 색상 팔레트도 ULong으로 통일상단 타입 변경과 일관성 있게 반환 타입/리터럴 접미사(u) 정리 바랍니다.
- private fun getSymbolBackgroundColor(emotionType: String): Long { + private fun getSymbolBackgroundColor(emotionType: String): ULong { return when (emotionType) { - "CALM" -> 0xFFEFECFF - "VITALITY" -> 0xFFE9FAD0 - "LETHARGY" -> 0xFFEAEBEC - "ANXIETY" -> 0xFFFFEEE4 - "SATISFACTION" -> 0xFFE2F3F6 - "FATIGUE" -> 0xFFFFE1E1 - else -> 0xFFEAEBEC + "CALM" -> 0xFFEFECFFu + "VITALITY" -> 0xFFE9FAD0u + "LETHARGY" -> 0xFFEAEBECu + "ANXIETY" -> 0xFFFFEEE4u + "SATISFACTION" -> 0xFFE2F3F6u + "FATIGUE" -> 0xFFFFE1E1u + else -> 0xFFEAEBECu } }
67-77
: 심볼 색상 팔레트 ULong 통일 + 맵 기반 축약 제안ULong 통일은 위와 동일. 또한 동일 키에 대해 메시지/배경색/심볼색/드로어블 매핑이 중복됩니다. 단일 spec 맵(or enum)으로 관리하면 추가/수정 시 누락 위험을 줄일 수 있습니다.
타입/리터럴 변경 diff:
- private fun getSymbolColor(emotionType: String): Long { + private fun getSymbolColor(emotionType: String): ULong { return when (emotionType) { - "CALM" -> 0xFF692BD0 - "VITALITY" -> 0xFF609F00 - "LETHARGY" -> 0xFF5A5C63 - "ANXIETY" -> 0xFFFE7120 - "SATISFACTION" -> 0xFF26A792 - "FATIGUE" -> 0xFFFF5151 - else -> 0xFF878A93 + "CALM" -> 0xFF692BD0u + "VITALITY" -> 0xFF609F00u + "LETHARGY" -> 0xFF5A5C63u + "ANXIETY" -> 0xFFFE7120u + "SATISFACTION" -> 0xFF26A792u + "FATIGUE" -> 0xFFFF5151u + else -> 0xFF878A93u } }중복 제거는 별 PR로 분리 권장합니다. 필요 시 enum 기반 스펙 초안 드릴게요.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/EmotionUiModel.kt
(2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (2)
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/EmotionUiModel.kt (2)
79-87
: Default 프리셋 구성 적절합니다초기 상태에서 비선택(selectable=false), 안내 문구, 기본 마블 리소스까지 일관되게 설정된 점 좋습니다.
12-16
: 불필요한 Parcelize 확인: EmotionImageUiModel은 이미 @parcelize로 Parcelable을 구현하고 있습니다.Likely an incorrect or invalid review comment.
presentation/src/main/java/com/threegap/bitnagil/presentation/emotion/model/EmotionUiModel.kt
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
복잡한 뷰,,, 고생많으셨습니담!
...m/threegap/bitnagil/presentation/emotion/component/template/EmotionRecommendRoutineScreen.kt
Outdated
Show resolved
Hide resolved
어렵겠다.. |
[ PR Content ]
감정구슬 화면에 2차 UI를 적용합니다.
Related issue
Screenshot 📸
select_emotion.mp4
under_600_dp.mp4
Work Description
To Reviewers 📢
Summary by CodeRabbit
신기능
UI/UX