[Feat/#38] 프로필 취향 키워드 칩 컴포넌트 구현#82
Conversation
📝 WalkthroughWalkthrough나인-패치 드로어블을 렌더링하는 Modifier 확장 함수 추가, 키워드 표시용 타입 계층(KeywordType/PreferenceType) 도입, 그리고 소형/대형 변형을 지원하는 ProfileKeywordChip 컴포저블이 추가되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant App as 앱
participant PKC as ProfileKeywordChip
participant KT as KeywordType
participant PT as PreferenceType
participant ME as ModifierExt.draw9Patch
participant Canvas as Compose Canvas
App->>PKC: ProfileKeywordChip(keyword, keywordType)
PKC->>KT: keywordType 검사
alt Small
PKC->>ME: draw9Patch(gray_ninepatch)
ME->>Canvas: 나인-패치 렌더링(크기 기준 바운드)
PKC->>Canvas: 텍스트 렌더링
else Large
PKC->>PT: preferenceType.backgroundRes 조회
PKC->>ME: draw9Patch(preference_background)
ME->>Canvas: 나인-패치 렌더링
PKC->>Canvas: 이미지 렌더링 → 텍스트 렌더링
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧹 Recent nitpick comments
📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (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). (2)
🔇 Additional comments (1)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (6)
app/src/main/java/com/flint/core/common/extension/ModifierExt.kt (1)
85-97: Drawable 로딩 최적화 고려 필요현재 구현은
drawBehind람다가 실행될 때마다ContextCompat.getDrawable을 호출합니다. Drawable 캐싱을 통해 성능을 개선할 수 있습니다. 또한 drawable이 null인 경우 조용히 실패하므로 개발 중 디버깅이 어려울 수 있습니다.♻️ 개선된 구현 제안
-fun Modifier.draw9Patch( - context: Context, - @DrawableRes ninePatchRes: Int, -) = this.drawBehind { - drawIntoCanvas { - ContextCompat.getDrawable(context, ninePatchRes)?.let { ninePatch -> - ninePatch.run { - bounds = Rect(0, 0, size.width.toInt(), size.height.toInt()) - draw(it.nativeCanvas) +@Composable +fun Modifier.draw9Patch( + @DrawableRes ninePatchRes: Int, +): Modifier { + val context = LocalContext.current + val drawable = remember(ninePatchRes) { + ContextCompat.getDrawable(context, ninePatchRes) + } + return this.drawBehind { + drawIntoCanvas { canvas -> + drawable?.let { ninePatch -> + ninePatch.bounds = Rect(0, 0, size.width.toInt(), size.height.toInt()) + ninePatch.draw(canvas.nativeCanvas) } } } }참고:
@Composable로 변경하면LocalContext를 내부에서 가져올 수 있어 호출부에서 context를 전달할 필요가 없어집니다.app/src/main/java/com/flint/domain/type/PreferenceType.kt (3)
6-9: 주석 처리된 코드 제거 필요주석 처리된 이전 구현 코드는 정리되어야 합니다. 버전 관리 시스템에서 히스토리를 추적할 수 있으므로 불필요한 주석 코드는 삭제하는 것이 좋습니다.
20-28: Domain 레이어의 Android 리소스 의존성Domain 레이어(
com.flint.domain.type)에서@DrawableRes와R.drawable.*를 사용하고 있습니다. Clean Architecture 관점에서 Domain 레이어는 Android 프레임워크에 의존하지 않는 것이 이상적입니다.대안으로
PreferenceType을 presentation 레이어로 이동하거나, Domain에서는 타입만 정의하고 drawable 매핑은 presentation 레이어에서 처리하는 방법이 있습니다.프로젝트 규모와 팀 컨벤션에 따라 현재 구조를 유지해도 무방합니다.
14-17: 주석 처리된imageUrl프로퍼티PR 설명에 이미지 리소스가 서버에서 URL로 내려온다고 명시되어 있습니다. 향후 구현 예정이라면 TODO 주석으로 명시하거나, 당장 불필요하다면 삭제하는 것이 좋습니다.
app/src/main/java/com/flint/presentation/profile/component/ProfileKeywordChip.kt (2)
26-47: API 설계 개선 제안
keywordImageUrl파라미터는KeywordType.Large일 때만 사용됩니다. 현재 구조에서는Small타입 사용 시에도 불필요한 파라미터가 노출됩니다.♻️ 타입 안전한 API 제안
KeywordType.Large클래스에imageUrl을 포함시키는 방안:// PreferenceType.kt에서 data class Large( val preferenceType: PreferenceType, val imageUrl: String = "", ) : KeywordType()@Composable fun ProfileKeywordChip( keyword: String, keywordType: KeywordType, - keywordImageUrl: String = "", ) { when (keywordType) { is KeywordType.Small -> { ProfileSmallKeywordChip(keyword = keyword) } is KeywordType.Large -> { ProfileLargeKeywordChip( keyword = keyword, keywordType = keywordType, - imageUrl = keywordImageUrl, + imageUrl = keywordType.imageUrl, ) } } }이렇게 하면 Large 타입 생성 시 imageUrl을 함께 전달하게 되어 API가 더 명확해집니다.
104-125: Preview에 간격 추가 제안Preview Row에서 칩 간 간격이 없어 미리보기에서 두 칩이 붙어 보일 수 있습니다.
♻️ 간격 추가
Row( verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(8.dp), ) {
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (6)
app/src/main/res/drawable/bg_tag_blue.9.pngis excluded by!**/*.pngapp/src/main/res/drawable/bg_tag_gray.9.pngis excluded by!**/*.pngapp/src/main/res/drawable/bg_tag_green.9.pngis excluded by!**/*.pngapp/src/main/res/drawable/bg_tag_orange.9.pngis excluded by!**/*.pngapp/src/main/res/drawable/bg_tag_pink.9.pngis excluded by!**/*.pngapp/src/main/res/drawable/bg_tag_yellow.9.pngis excluded by!**/*.png
📒 Files selected for processing (3)
app/src/main/java/com/flint/core/common/extension/ModifierExt.ktapp/src/main/java/com/flint/domain/type/PreferenceType.ktapp/src/main/java/com/flint/presentation/profile/component/ProfileKeywordChip.kt
🧰 Additional context used
🧬 Code graph analysis (1)
app/src/main/java/com/flint/presentation/profile/component/ProfileKeywordChip.kt (2)
app/src/main/java/com/flint/core/designsystem/component/image/NetworkImage.kt (1)
NetworkImage(22-46)app/src/main/java/com/flint/core/designsystem/theme/Theme.kt (1)
FlintTheme(8-16)
⏰ 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: PR Lint Check
- GitHub Check: PR Build Check
🔇 Additional comments (2)
app/src/main/java/com/flint/presentation/profile/component/ProfileKeywordChip.kt (2)
49-68: LGTM!
ProfileSmallKeywordChip구현이 적절합니다. 9-patch 배경 적용과 최소 너비 제약이 잘 설정되어 있습니다.
70-102: Large 칩 구현 확인구현이 전반적으로 잘 되어 있습니다. 한 가지 확인 사항:
imageUrl이 빈 문자열인 경우NetworkImage가FlintTheme.colors.gray200색상의 error placeholder를 표시합니다. 의도된 동작인지 확인 부탁드립니다.
| fun Modifier.draw9Patch( | ||
| context: Context, | ||
| @DrawableRes ninePatchRes: Int, | ||
| ) = this.drawBehind { |
There was a problem hiding this comment.
p3: 위의 Modifier.dropShadow()처럼 this 명시 없이 해주셔도 될 것 같습니다! 👍
| @Composable | ||
| private fun ProfileLargeKeywordChip( | ||
| keyword: String, | ||
| keywordType: KeywordType.Large, | ||
| imageUrl: String, | ||
| ) { | ||
| Box( | ||
| Modifier | ||
| .draw9Patch(LocalContext.current, keywordType.preferenceType.backgroundRes) | ||
| .padding( | ||
| vertical = 12.dp, | ||
| horizontal = 28.dp, | ||
| ), | ||
| ) { | ||
| Row( | ||
| verticalAlignment = Alignment.CenterVertically, | ||
| horizontalArrangement = Arrangement.Center, | ||
| ) { | ||
| NetworkImage( | ||
| imageUrl = imageUrl, | ||
| contentDescription = null, | ||
| modifier = Modifier.size(20.dp), | ||
| ) |


📮 관련 이슈
📌 작업 내용
9-patch라는 친구로 이미지 저장했어요📸 스크린샷
😅 미구현
🫛 To. 리뷰어
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.