-
Notifications
You must be signed in to change notification settings - Fork 0
[feature/#40] 온보딩 NPC 대화 컴포넌트 수정 및 요정 등장 화면 개편 #45
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대화 말풍선 컴포넌트를 배경 이미지 기반에서 테마 기반 박스+보더 구조로 재구성하고, Dp→Sp 변환 유틸을 추가했습니다. 요정 등장 화면은 단계별 인터랙션과 타이핑 말풍선을 포함하는 새로운 레이아웃으로 개편되었습니다. 채팅 페이저는 고정 카드 폭과 동적 패딩으로 가운데 정렬되며, 편지 화면 이미지는 y 오프셋이 소폭 조정되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User as 사용자
participant FairyScreen as FairyScreen
participant TypingBubble as TypingAnimatedSpeechBubble
participant Nav as Navigator
User->>FairyScreen: 화면 진입
FairyScreen->>FairyScreen: currentStep = 0, 애니메이션/표시 준비
FairyScreen->>TypingBubble: stepTexts[currentStep]로 타이핑 시작
User-->>FairyScreen: 화면 탭
FairyScreen->>FairyScreen: currentStep 증가 (0→1→2)
FairyScreen->>TypingBubble: 표시 텍스트 갱신/재시작
User->>FairyScreen: 탭(최종 단계 이후)
FairyScreen->>Nav: onNavigateToLetter()
Note over TypingBubble: 타이핑: 공백 포함 시 단어 단위, 그 외 문자 단위
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Possibly related PRs
Suggested reviewers
Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ 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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
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
🧹 Nitpick comments (17)
core/designsystem/src/commonMain/kotlin/com/nexters/emotia/core/designsystem/util/DpExt.kt (2)
8-9: 함수명과 반환 단위 불일치: toTextPx는 SP(TextUnit)를 반환합니다.이름은 px를 연상시키지만 실제론
TextUnit.Sp를 반환합니다. 혼동을 줄이기 위해 새 이름으로 노출하거나, 기존 API는 Deprecated 처리 후 포워딩하는 걸 권장합니다.아래와 같이 리네이밍 + Deprecated 포워딩을 제안드립니다.
-@Composable -fun Dp.toTextPx(): TextUnit = with(LocalDensity.current) { [email protected]().toSp() } +@Deprecated("Use toSpText()", ReplaceWith("this.toSpText()")) +@Composable +fun Dp.toTextPx(): TextUnit = toSpText() + +@Composable +fun Dp.toSpText(): TextUnit = with(LocalDensity.current) { [email protected]().toSp() }
3-9: 타이포그래피 단위 일관성 재검토 제안DP→SP 변환 유틸은 사용처에서 의미가 모호해질 수 있습니다. 가능하면 텍스트 사이즈는
sp(예:14.sp) 또는 테마 타이포그래피 토큰을 직접 사용해 단위를 명확히 하세요. 유틸은 꼭 필요한 케이스(디자인 토큰 이관 등) 한정으로 사용 권장합니다.feature/chatting/src/commonMain/kotlin/com/nexters/emotia/feature/chatting/ChattingScreen.kt (2)
240-251: O(n) 인덱스 계산 제거: itemsIndexed 사용으로 비용 절감현재 각 아이템에서
indexOf로 인덱스를 구해 O(n^2) 패턴이 됩니다.itemsIndexed로 치환하면 불필요한 탐색을 제거할 수 있습니다.아래처럼 변경을 제안드립니다(상단에
import androidx.compose.foundation.lazy.itemsIndexed추가 필요).- items( - items = uiState.messages, - key = { message -> message.timestamp } - ) { message -> - val messageIndex = uiState.messages.indexOf(message) + itemsIndexed( + items = uiState.messages, + key = { _, message -> message.timestamp } + ) { index, message -> ChatBubble( text = message.text, type = message.type, messageId = message.timestamp.toString(), - skipTypewriterEffect = messageIndex <= 1 + skipTypewriterEffect = index <= 1 ) }추가 import:
import androidx.compose.foundation.lazy.itemsIndexed
425-458: 오버레이 접근성/세만틱스 보완 제안터치 차단을 위해 빈
clickable를 두신 점은 합리적이지만, 보조기기 탐색에서도 포커스가 가지 않도록 세만틱스 제외를 권장합니다.예:
Modifier.semantics { this.invisibleToUser() }또는clearAndSetSemantics { }추가를 고려해주세요.core/designsystem/src/commonMain/kotlin/com/nexters/emotia/core/designsystem/component/SpeechBubbleTextField.kt (6)
93-99: 장식용 폴리곤 이미지는 contentDescription 제거장식 목적의 아이콘은 스크린리더에 노출하지 않는 편이 접근성에 유리합니다.
contentDescription = null로 설정을 권장합니다.- Image( - painter = painterResource(Res.drawable.ic_polygon), - contentDescription = "Polygon icon", + Image( + painter = painterResource(Res.drawable.ic_polygon), + contentDescription = null, modifier = Modifier .align(Alignment.BottomEnd) .padding(end = 36.dp, bottom = 64.dp) )
101-108: 텍스트 사이즈는 sp로 직접 지정 권장
14.dp.toTextPx()대신14.sp로 명시하면 단위가 분명해지고 유틸 의존이 줄어듭니다. 또한 테마 토큰이 이미 sp를 포함한다면 override 자체가 필요 없을 수 있습니다.- style = typography.emotia14M.copy( - fontSize = 14.dp.toTextPx() - ), + style = typography.emotia14M.copy( + fontSize = 14.sp + ),
116-123: NPC 이미지는 의미가 있다면 대체 텍스트 구체화, 없다면 숨김 처리현재
"NPC character"는 정보 가치가 낮습니다. 의미가 없다면null, 있다면 역할/상태를 담은 한국어 설명으로 갱신해주세요.
125-139: 하드코딩 문자열 리소스화"요정여왕"은 리소스로 분리해 현지화와 일관된 관리가 가능하도록 해주세요. Compose Multiplatform의
stringResource사용을 권장합니다.예시:
- Text( - text = "요정여왕", + Text( + text = stringResource(Res.string.npc_queen), color = colors.white, style = typography.emotia14M.copy( - fontSize = 14.dp.toTextPx() + fontSize = 14.sp ),추가 필요:
import org.jetbrains.compose.resources.stringResourceemotia.core.designsystem.generated.resources에npc_queen문자열 추가
원하시면 리소스 추가 PR 패치도 제공하겠습니다.
141-158: 본문 텍스트도 sp 직접 지정 및 패딩/오프셋 상수화 제안
14.dp.toTextPx()→14.sp로 단위 명확화, 매직 넘버 패딩/오프셋(예:start = 136.dp)은 상수로 추출하면 유지보수성이 올라갑니다.- style = typography.emotia14M.copy( - fontSize = 14.dp.toTextPx() - ), + style = typography.emotia14M.copy( + fontSize = 14.sp + ),
50-69: 타이핑 애니메이션 토크나이징 개선 여지
split(' ')는 연속 공백/개행을 제대로 다루지 못합니다.Regex("\\s+")기반 분할 또는 개행 처리 보완을 고려해주세요. 또한 딜레이(150/100ms)를 파라미터로 노출하면 테스트 및 접근성(감속 모드) 대응이 용이합니다.feature/result/src/commonMain/kotlin/com/nexters/emotia/feature/result/letter/LetterScreen.kt (2)
131-147: 콘텐츠 설명 보강: URL 대신 요정 이름 사용
contentDescription = "$fairyImage image"는 URL/경로가 들어갈 수 있어 비직관적입니다. 접근성을 위해 요정 이름 기반으로 바꾸는 걸 권장합니다.- contentDescription = "$fairyImage image", + contentDescription = "$fairyName 이미지",또는 장식 목적이라면
null로 비노출 처리하세요.
170-185: 문구 문자열 리소스화 및 플레이스홀더 국제화
"${fairyName}에게 위로의 말을 건네보자."등 UI 문구는 리소스로 분리해 현지화/일관성을 확보하세요. placeholder도stringResource의 포맷 문자열을 활용하면 깔끔합니다.원하시면
Res.string항목 초안을 함께 제공하겠습니다.feature/result/src/commonMain/kotlin/com/nexters/emotia/feature/result/fairy/FairyScreen.kt (5)
90-96: 스텝 문구 하드코딩 → 문자열 리소스 전환
"앗...!","저 아이는... ${fairyName}이야!","${fairyName}에게 위로를 건네볼까?"는 리소스로 분리하고, 이름 치환은 포맷 문자열로 처리해 주세요.예:
Res.string.fairy_step_1,Res.string.fairy_step_2_with_name,Res.string.fairy_step_3_with_name
81-88: 매직 넘버 상수화: 반경 값 2000f/1800f애니메이션 최대 반경(2000f) 및 완료 임계값(1800f)을 상수로 추출하면 가독성과 조정 용이성이 높아집니다.
아래 상수 예시(파일 상단 또는
companion object):private const val EXPANSION_MAX_RADIUS = 2000f private const val EXPANSION_DONE_THRESHOLD = 1800f그리고 사용부:
targetValue = if (uiState.isExpanding) EXPANSION_MAX_RADIUS else 0f
97-112: 탭 진행 조건의 임계값도 상수 사용 권장
animatedRadius >= 1800f반복 사용은 상수로 대체하세요. 상기 제안한EXPANSION_DONE_THRESHOLD로 치환하면 일관성이 높아집니다.- if (animatedRadius >= 1800f) { + if (animatedRadius >= EXPANSION_DONE_THRESHOLD) {
122-137: 이미지 contentDescription 개선
"$fairyImage image"는 정보 전달력이 낮습니다. 사용자에게 의미 있는"${uiState.fairyName} 이미지"등으로 대체하거나, 장식이라면null로 처리해주세요.
182-194: AnimatedVisibility의 불필요한 visible=true 제거이미
if (stepTexts != null && animatedRadius >= 1800f)에 의해 표시 조건이 보장되므로visible = true는 중복입니다. 제거로 간결성 향상.- AnimatedVisibility( - visible = true, + AnimatedVisibility( enter = fadeIn(tween(300)), exit = fadeOut(tween(300)), modifier = Modifier.align(Alignment.BottomCenter) ) {또는
if제거 후visible = stepTexts != null && animatedRadius >= EXPANSION_DONE_THRESHOLD로 일원화하는 방법도 있습니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (2)
core/designsystem/src/commonMain/composeResources/drawable/ic_polygon.pngis excluded by!**/*.pngcore/designsystem/src/commonMain/composeResources/drawable/img_npc.pngis excluded by!**/*.png
📒 Files selected for processing (5)
core/designsystem/src/commonMain/kotlin/com/nexters/emotia/core/designsystem/component/SpeechBubbleTextField.kt(3 hunks)core/designsystem/src/commonMain/kotlin/com/nexters/emotia/core/designsystem/util/DpExt.kt(1 hunks)feature/chatting/src/commonMain/kotlin/com/nexters/emotia/feature/chatting/ChattingScreen.kt(3 hunks)feature/result/src/commonMain/kotlin/com/nexters/emotia/feature/result/fairy/FairyScreen.kt(5 hunks)feature/result/src/commonMain/kotlin/com/nexters/emotia/feature/result/letter/LetterScreen.kt(1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-07-27T10:25:59.389Z
Learnt from: CR
PR: Nexters/team-ace-client#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T10:25:59.389Z
Learning: Applies to composeApp/src/{commonMain,androidMain,iosMain}/kotlin/**/*.kt : Leverage Compose resources via Res.drawable.* and Res.string.*
Applied to files:
feature/result/src/commonMain/kotlin/com/nexters/emotia/feature/result/fairy/FairyScreen.ktcore/designsystem/src/commonMain/kotlin/com/nexters/emotia/core/designsystem/component/SpeechBubbleTextField.kt
📚 Learning: 2025-07-27T10:25:59.389Z
Learnt from: CR
PR: Nexters/team-ace-client#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T10:25:59.389Z
Learning: Applies to composeApp/src/{commonMain,androidMain,iosMain}/kotlin/**/*.kt : Use Compose Resources for strings, images, and other assets
Applied to files:
feature/result/src/commonMain/kotlin/com/nexters/emotia/feature/result/fairy/FairyScreen.ktcore/designsystem/src/commonMain/kotlin/com/nexters/emotia/core/designsystem/component/SpeechBubbleTextField.kt
📚 Learning: 2025-07-27T10:25:59.389Z
Learnt from: CR
PR: Nexters/team-ace-client#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T10:25:59.389Z
Learning: Applies to composeApp/src/commonMain/kotlin/**/*.kt : Use common state management patterns (ViewModel, StateFlow)
Applied to files:
feature/result/src/commonMain/kotlin/com/nexters/emotia/feature/result/fairy/FairyScreen.ktcore/designsystem/src/commonMain/kotlin/com/nexters/emotia/core/designsystem/component/SpeechBubbleTextField.ktfeature/chatting/src/commonMain/kotlin/com/nexters/emotia/feature/chatting/ChattingScreen.kt
🧬 Code graph analysis (2)
feature/result/src/commonMain/kotlin/com/nexters/emotia/feature/result/fairy/FairyScreen.kt (1)
core/designsystem/src/commonMain/kotlin/com/nexters/emotia/core/designsystem/component/SpeechBubbleTextField.kt (1)
TypingAnimatedSpeechBubble(42-161)
feature/chatting/src/commonMain/kotlin/com/nexters/emotia/feature/chatting/ChattingScreen.kt (1)
core/designsystem/src/commonMain/kotlin/com/nexters/emotia/core/designsystem/component/FairyCard.kt (1)
FairyCard(38-138)
⏰ 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). (2)
- GitHub Check: build
- GitHub Check: Firebase App Distribution
🔇 Additional comments (5)
feature/chatting/src/commonMain/kotlin/com/nexters/emotia/feature/chatting/ChattingScreen.kt (3)
302-318: 페이저 가운데 정렬 로직 👍
BoxWithConstraints로maxWidth대비cardWidth기반의 동적contentPadding을 계산해 가운데 정렬하는 접근이 깔끔합니다. 다양한 화면 폭에서 안정적으로 동작할 것으로 보입니다.
137-143: roomId의 Int 캐스팅 안전성 확인 필요
uiState.roomId?.toInt() ?: 0는 원본이 Long/BigInt일 경우 오버플로 우려가 있습니다. 네비게이션 파이프라인이 Int를 강제한다면 상한 검증 또는 타입 일치(가능하면 Long 유지)를 검토해주세요.잠재적 대응:
- onNavigateToFairy의
chatRoomId를Long으로 변경, 혹은- 안전 변환(범위 체크) 및 로깅 추가
319-367: 선택 카드 기준 스포트라이트 좌표 캡처 로직 적절선택된 카드에서만
onGloballyPositioned로 중심 좌표/반경을 갱신하는 방식이 불필요한 계산을 줄여줍니다. y축 보정(-50.dp)도 시각적 중심을 잘 맞춥니다.core/designsystem/src/commonMain/kotlin/com/nexters/emotia/core/designsystem/component/SpeechBubbleTextField.kt (1)
71-92: 고정 높이(150.dp) 박스: 작은 화면/다국어 줄바꿈 대응 검토고정 높이로 말풍선이 잘릴 수 있습니다. 최대 높이/스크롤 또는 적응형 높이 전략을 검토해주세요.
feature/result/src/commonMain/kotlin/com/nexters/emotia/feature/result/fairy/FairyScreen.kt (1)
113-153: 배경/그라데이션 레이아웃 구성 적절레터 배경 + 하단 그라데이션 영역으로 단계별 인터랙션을 유도하는 구조가 직관적입니다. 이후 단계에서 CTA 노출을 고려하기에도 확장성이 좋아 보입니다.
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
🧹 Nitpick comments (6)
feature/chatting/src/commonMain/kotlin/com/nexters/emotia/feature/chatting/ChattingScreen.kt (6)
302-368: 페이저 가운데 정렬 접근 훌륭합니다. 카드 치수 상수화 및 매직 넘버(50.dp) 정리 제안BoxWithConstraints + PageSize.Fixed로 가로 중앙 정렬을 안정적으로 맞추신 점 좋습니다. 다만 카드 폭/높이가 여기저기 중복(200.dp, 280.dp)되고, 스포트라이트 중심 보정값 50.dp가 매직 넘버로 남아 있어 유지보수성이 떨어집니다. 아래처럼 cardHeight와 spotlightYOffset을 상수로 두고 재사용하면 가독성과 변경 용이성이 올라갑니다.
BoxWithConstraints { - val cardWidth = 200.dp + val cardWidth = 200.dp + val cardHeight = 280.dp + val spotlightYOffset = 50.dp val horizontalPadding = maxOf( 0.dp, (maxWidth - cardWidth) / 2 ) HorizontalPager( state = pagerState, modifier = Modifier .fillMaxWidth() .padding(vertical = 28.dp), pageSize = PageSize.Fixed(cardWidth), pageSpacing = 24.dp, contentPadding = PaddingValues(horizontal = horizontalPadding) ) { page -> val fairy = uiState.fairies[page] val isSelected = page == pagerState.currentPage val yOffset by animateFloatAsState( targetValue = if (isSelected) 0f else 28f, animationSpec = tween( durationMillis = 300, easing = FastOutSlowInEasing ) ) FairyCard( name = fairy.name, image = fairy.silhouetteImage, emotion = fairy.emotion, emotionDescription = fairy.description, isSelected = isSelected, modifier = Modifier - .size( - width = 200.dp, - height = 280.dp - ) + .size( + width = cardWidth, + height = cardHeight + ) .offset(y = yOffset.dp) .then( if (isSelected) { Modifier.onGloballyPositioned { coordinates -> val position = coordinates.positionInRoot() val size = coordinates.size fairyCardCenter = Offset( x = position.x + size.width / 2, - y = position.y + size.height / 2 - with( - density - ) { 50.dp.toPx() } + y = position.y + size.height / 2 - with( + density + ) { spotlightYOffset.toPx() } ) fairyCardSize = minOf( size.width, size.height ) / 2f } } else { Modifier } ) ) } }
292-299: Pager ↔ ViewModel 선택 상태 동기화(양방향) 보강 권장현재는 Pager → VM(SelectFairy) 방향만 동기화됩니다. 외부 요인(복원, 딥링크, 서버 추천 등)으로 uiState.selectedFairyIndex가 바뀔 때 Pager가 그 페이지로 스크롤되지 않을 가능성이 있습니다. 아래 효과를 추가해 양방향 일관성을 확보하는 것을 권장합니다.
LaunchedEffect(pagerState.currentPage) { viewModel.handleIntent( ChattingIntent.SelectFairy( pagerState.currentPage ) ) } + +// VM -> UI 동기화: 외부에서 selectedFairyIndex가 변경되면 Pager도 맞춰줍니다. +LaunchedEffect(uiState.selectedFairyIndex) { + val target = uiState.selectedFairyIndex.coerceIn(0, pagerState.pageCount - 1) + if (pagerState.currentPage != target) { + pagerState.animateScrollToPage(target) + } +}
160-168: 스크롤 인덱스 계산이 타이핑 인디케이터/페이저 동시 노출 시 빗나갈 수 있음현재 showFairyPager가 true일 때 lastIndex를 messages.size로만 계산합니다. 동시에 isLoading이 true면 타이핑 인디케이터 아이템이 삽입되어 페이저까지 스크롤되지 않을 수 있습니다. 아래처럼 조건에 따른 추가 아이템 수를 반영해 정확한 마지막 인덱스로 스크롤하는 것을 권장합니다.
-LaunchedEffect(uiState.messages.size, uiState.showFairyPager) { +LaunchedEffect(uiState.messages.size, uiState.showFairyPager, uiState.isLoading) { if (uiState.messages.isNotEmpty()) { - val lastIndex = if (uiState.showFairyPager) { - uiState.messages.size - } else { - uiState.messages.size - 1 - } + val typingItemCount = if (uiState.isLoading && uiState.messages.isNotEmpty()) 1 else 0 + val pagerItemCount = if (uiState.showFairyPager) 1 else 0 + val lastIndex = uiState.messages.size + typingItemCount + pagerItemCount - 1 lazyListState.animateScrollToItem(lastIndex) } }
111-123: Spotlight 시작 반경 2000f 상수 — 초대형 화면에서 불충분할 수 있음애니메이션 시작 반경을 2000f로 고정하면 태블릿/데스크톱 초고해상도에서 화면 전체가 완전히 “비가려진 상태”로 시작하지 않을 수 있습니다. 최대 대각선 길이 기반의 동적 계산(예: hypot(width, height))으로 full-screen 반경을 산출해 시작값으로 쓰는 방식을 고려해 주세요. BoxWithConstraints 또는 Canvas의 size를 활용해 동적으로 반영하는 것이 안전합니다.
474-481: 하드코딩된 그라데이션 색상 → 디자인 토큰 사용 권장CreateRoom의 배경 그라데이션이 Hex로 하드코딩되어 있습니다. 상단 채팅 화면과 동일하게 LocalEmotiaColors를 사용하면 테마 일관성과 유지보수성이 좋아집니다.
- Column( - modifier = modifier + val colors = LocalEmotiaColors.current + Column( + modifier = modifier .fillMaxSize() .background( Brush.verticalGradient( - colors = listOf( - Color(0xFF171E2D), - Color(0xFF1A1A1B) - ) + colors = listOf( + colors.backgroundBlue, + Color.Black + ) ) )
542-542: 입력 영역 고정 padding(24.dp) — IME/세이프에어리어와 합쳐 과다 여백 가능성 점검상위 Column에 이미 imePadding이 적용되어 있어, 하단 Box의 vertical = 24.dp가 특정 기기에서 과도한 여백으로 보일 수 있습니다. 디자인 의도라면 OK지만, 필요 시 키보드 표시 여부에 따라 padding을 보정하거나 spacing을 Emotia 디자인 토큰으로 치환하는 것을 고려해 주세요.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
feature/chatting/src/commonMain/kotlin/com/nexters/emotia/feature/chatting/ChattingScreen.kt(5 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-27T10:25:59.389Z
Learnt from: CR
PR: Nexters/team-ace-client#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T10:25:59.389Z
Learning: Applies to composeApp/src/commonMain/kotlin/**/*.kt : Use common state management patterns (ViewModel, StateFlow)
Applied to files:
feature/chatting/src/commonMain/kotlin/com/nexters/emotia/feature/chatting/ChattingScreen.kt
🧬 Code graph analysis (1)
feature/chatting/src/commonMain/kotlin/com/nexters/emotia/feature/chatting/ChattingScreen.kt (1)
core/designsystem/src/commonMain/kotlin/com/nexters/emotia/core/designsystem/component/FairyCard.kt (1)
FairyCard(38-138)
⏰ 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: Firebase App Distribution
🔇 Additional comments (1)
feature/chatting/src/commonMain/kotlin/com/nexters/emotia/feature/chatting/ChattingScreen.kt (1)
487-487: 배경 이미지 컨테이너에서 fillMaxWidth + weight(1f) 조합 적절합니다상단 영역이 남는 공간을 유연하게 차지하도록 처리되어 레이아웃 안정성이 좋습니다.
작업 내용
이건 꼭 봐주세요
Summary by CodeRabbit
New Features
Style
Refactor