Skip to content

[Feat] 프로필 키워드 그래프 컴포넌트 구현#89

Merged
nahy-512 merged 7 commits into
developfrom
feat/#83-profile-keyword-graph-component
Jan 14, 2026
Merged

[Feat] 프로필 키워드 그래프 컴포넌트 구현#89
nahy-512 merged 7 commits into
developfrom
feat/#83-profile-keyword-graph-component

Conversation

@nahy-512
Copy link
Copy Markdown
Contributor

@nahy-512 nahy-512 commented Jan 13, 2026

📮 관련 이슈

📌 작업 내용

  • 프로필 키워드 그래프 컴포넌트 구현했어요.

📸 스크린샷

스크린샷
image

😅 미구현

  • N/A

🫛 To. 리뷰어

  • ProgressBar를 Basic을 한번 만들어보면 좋을지?..

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능
    • 컬러 테마(초록, 주황, 노랑, 파랑, 분홍)가 적용된 키워드 선호도 시스템 추가
    • 프로필 화면에 키워드 선호도를 시각적 진행률 표시기와 함께 표시하는 UI 컴포넌트 추가

✏️ Tip: You can customize this high-level summary in your review settings.

@nahy-512 nahy-512 self-assigned this Jan 13, 2026
@nahy-512 nahy-512 requested a review from a team as a code owner January 13, 2026 23:11
@nahy-512 nahy-512 added 🧩 Component feat - 공통 컴포넌트 작업 Feat ✨ 신규 기능을 추가하거나 기존 기능의 동작, 정책을 변경 labels Jan 13, 2026
@nahy-512 nahy-512 linked an issue Jan 13, 2026 that may be closed by this pull request
2 tasks
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 13, 2026

📝 Walkthrough

Walkthrough

프로필 취향 키워드 그래프 표시를 위한 도메인 타입과 UI 컴포넌트를 추가합니다. 새로운 sealed class KeywordType과 enum PreferenceType을 정의하고, 색상별 키워드와 진행률을 표시하는 ProfileKeywordGraph 컴포넌트를 구현합니다.

Changes

Cohort / File(s) 변경 요약
도메인 타입 정의
app/src/main/java/com/flint/domain/type/PreferenceType.kt
sealed class KeywordType(Small, Large) 및 enum PreferenceType(Green, Orange, Yellow, Blue, Pink) 추가. 각 PreferenceType은 색상과 배경 drawable 리소스와 연결됨
UI 컴포넌트
app/src/main/java/com/flint/presentation/profile/component/ProfileKeywordGraph.kt
ProfileKeywordGraph 컴포넌트 구현. 색상 점, 키워드 라벨, 진행률 막대, 백분율 텍스트를 포함하는 행 레이아웃 구성. 내부 ProfileKeywordProgressBar 컴포넌트로 시각화

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10분

Possibly related PRs

Suggested reviewers

  • giovannijunseokim
  • ckals413

Poem

🐰 새로운 타입이 쏙 들어가고,

색색깔 키워드가 반짝반짝,

진행바까지 사르르 흘러내려,

프로필 취향, 한눈에 쏙!

🎨✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 제목이 PR의 주요 변경사항을 명확하게 반영하고 있으며, 프로필 키워드 그래프 컴포넌트 구현이라는 핵심 내용을 간결하게 표현하고 있습니다.
Description check ✅ Passed PR 설명이 저장소의 템플릿을 따르고 있으며 관련 이슈, 작업 내용, 스크린샷, 미구현 사항, 리뷰어 참고사항이 모두 포함되어 있습니다.
Linked Issues check ✅ Passed PR의 코드 변경사항이 이슈 #83의 모든 요구사항을 충족합니다: PreferenceType에 색상 추가(Green, Orange, Yellow, Blue, Pink) 및 ProfileKeywordGraph 컴포넌트 UI 구현 완료.
Out of Scope Changes check ✅ Passed 모든 변경사항이 이슈 #83의 범위 내에 있으며, 추가된 파일들(PreferenceType.kt, ProfileKeywordGraph.kt)은 모두 요구된 기능 구현에 직접적으로 필요한 것들입니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings


📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 28aacf7 and f4c7018.

📒 Files selected for processing (1)
  • app/src/main/java/com/flint/presentation/profile/component/ProfileKeywordGraph.kt
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/src/main/java/com/flint/presentation/profile/component/ProfileKeywordGraph.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). (2)
  • GitHub Check: PR Build Check
  • GitHub Check: PR Lint Check

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a 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

🤖 Fix all issues with AI agents
In
@app/src/main/java/com/flint/presentation/profile/component/ProfileKeywordChip.kt:
- Around line 26-47: Add a Modifier parameter to the public composable
ProfileKeywordChip (e.g., modifier: Modifier = Modifier) and forward it into the
child composables by passing modifier = modifier to ProfileSmallKeywordChip and
ProfileLargeKeywordChip; ensure you import androidx.compose.ui.Modifier and keep
the modifier as the last parameter with a default value so callers can customize
layout without breaking existing callers.
🧹 Nitpick comments (4)
app/src/main/java/com/flint/core/common/extension/ModifierExt.kt (1)

85-97: 성능 최적화 권장: drawable 및 Rect 캐싱 고려

현재 구현은 매 draw 호출마다 ContextCompat.getDrawable()을 호출하고 새로운 Rect 객체를 생성합니다. composed 모디파이어 패턴을 사용하면 drawable을 캐싱할 수 있습니다.

♻️ 성능 개선 제안
-fun Modifier.draw9Patch(
+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)
-            }
-        }
+) = composed {
+    val drawable = remember(ninePatchRes) {
+        ContextCompat.getDrawable(context, ninePatchRes)
+    }
+    drawBehind {
+        drawIntoCanvas { canvas ->
+            drawable?.apply {
+                bounds = Rect(0, 0, size.width.toInt(), size.height.toInt())
+                draw(canvas.nativeCanvas)
+            }
+        }
     }
 }
app/src/main/java/com/flint/presentation/profile/component/ProfileKeywordGraph.kt (1)

27-71: LGTM! 구조가 잘 구성되어 있습니다.

컴포넌트 구조와 레이아웃이 깔끔합니다. 다만, percent 파라미터에 대한 범위 검증을 추가하면 더 안전합니다. 현재 0 미만이나 100 초과 값이 전달되면 예기치 않은 UI가 표시될 수 있습니다.

💡 Optional: percent 범위 검증
 @Composable
 fun ProfileKeywordGraph(
     keyword: String,
     preferenceType: PreferenceType,
     percent: Int,
     modifier: Modifier = Modifier,
 ) {
+    val safePercent = percent.coerceIn(0, 100)
     Row(
         horizontalArrangement = Arrangement.SpaceBetween,
         modifier = modifier,
     ) {
         // ...
             ProfileKeywordProgressBar(
                 preferenceType = preferenceType,
-                percent = percent.toFloat() / 100,
+                percent = safePercent.toFloat() / 100,
                 modifier = Modifier.width(160.dp),
             )
             Text(
-                text = "${percent}%",
+                text = "${safePercent}%",
                 // ...
             )
         // ...
     }
 }
app/src/main/java/com/flint/domain/type/PreferenceType.kt (1)

1-40: 아키텍처 고려사항: 도메인 레이어에 UI 의존성 포함

domain 패키지에 Color (Compose UI)와 DrawableRes (Android 리소스)가 포함되어 있습니다. Clean Architecture 관점에서 도메인 레이어는 순수 Kotlin으로 유지하는 것이 권장됩니다.

현재 프로젝트 규모에서는 수용 가능할 수 있으나, 향후 확장성을 위해 presentation 레이어로 이동하거나 도메인과 UI 타입을 분리하는 것을 고려해볼 수 있습니다.

프로젝트의 아키텍처 방향성에 따라 결정해 주세요. 현재 구조를 유지해도 기능상 문제는 없습니다.

app/src/main/java/com/flint/presentation/profile/component/ProfileKeywordChip.kt (1)

70-102: 빈 imageUrl 처리 고려

imageUrl이 빈 문자열일 때도 NetworkImage가 렌더링되어 회색 placeholder가 표시됩니다. 의도된 동작이 아니라면 조건부 렌더링을 고려해 보세요.

💡 조건부 이미지 렌더링
         Row(
             verticalAlignment = Alignment.CenterVertically,
             horizontalArrangement = Arrangement.Center,
         ) {
-            NetworkImage(
-                imageUrl = imageUrl,
-                contentDescription = null,
-                modifier = Modifier.size(20.dp),
-            )
-            Spacer(modifier = Modifier.width(12.dp))
+            if (imageUrl.isNotBlank()) {
+                NetworkImage(
+                    imageUrl = imageUrl,
+                    contentDescription = null,
+                    modifier = Modifier.size(20.dp),
+                )
+                Spacer(modifier = Modifier.width(12.dp))
+            }
             Text(
                 text = keyword,
                 // ...
             )
         }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 64fb197 and 28aacf7.

⛔ Files ignored due to path filters (6)
  • app/src/main/res/drawable/bg_tag_blue.9.png is excluded by !**/*.png
  • app/src/main/res/drawable/bg_tag_gray.9.png is excluded by !**/*.png
  • app/src/main/res/drawable/bg_tag_green.9.png is excluded by !**/*.png
  • app/src/main/res/drawable/bg_tag_orange.9.png is excluded by !**/*.png
  • app/src/main/res/drawable/bg_tag_pink.9.png is excluded by !**/*.png
  • app/src/main/res/drawable/bg_tag_yellow.9.png is excluded by !**/*.png
📒 Files selected for processing (4)
  • app/src/main/java/com/flint/core/common/extension/ModifierExt.kt
  • app/src/main/java/com/flint/domain/type/PreferenceType.kt
  • app/src/main/java/com/flint/presentation/profile/component/ProfileKeywordChip.kt
  • app/src/main/java/com/flint/presentation/profile/component/ProfileKeywordGraph.kt
🧰 Additional context used
🧬 Code graph analysis (2)
app/src/main/java/com/flint/presentation/profile/component/ProfileKeywordGraph.kt (1)
app/src/main/java/com/flint/core/designsystem/theme/Theme.kt (1)
  • FlintTheme (8-16)
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 Build Check
  • GitHub Check: PR Lint Check
🔇 Additional comments (1)
app/src/main/java/com/flint/presentation/profile/component/ProfileKeywordGraph.kt (1)

73-95: LGTM!

프로그레스 바 구현이 깔끔합니다. fillMaxWidth(percent)를 사용한 진행률 표시와 RoundedCornerShape 적용이 적절합니다.

Comment on lines +26 to +47
@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,
)
}
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Public 컴포저블에 Modifier 파라미터 추가 권장

Compose 컨벤션에 따라 public 컴포저블은 modifier 파라미터를 받아 호출자가 레이아웃을 커스터마이징할 수 있도록 해야 합니다.

♻️ Modifier 파라미터 추가
 @Composable
 fun ProfileKeywordChip(
     keyword: String,
     keywordType: KeywordType,
     keywordImageUrl: String = "",
+    modifier: Modifier = Modifier,
 ) {
     when (keywordType) {
         is KeywordType.Small -> {
             ProfileSmallKeywordChip(
                 keyword = keyword,
+                modifier = modifier,
             )
         }

         is KeywordType.Large -> {
             ProfileLargeKeywordChip(
                 keyword = keyword,
                 keywordType = keywordType,
                 imageUrl = keywordImageUrl,
+                modifier = modifier,
             )
         }
     }
 }
🤖 Prompt for AI Agents
In
@app/src/main/java/com/flint/presentation/profile/component/ProfileKeywordChip.kt
around lines 26 - 47, Add a Modifier parameter to the public composable
ProfileKeywordChip (e.g., modifier: Modifier = Modifier) and forward it into the
child composables by passing modifier = modifier to ProfileSmallKeywordChip and
ProfileLargeKeywordChip; ensure you import androidx.compose.ui.Modifier and keep
the modifier as the last parameter with a default value so callers can customize
layout without breaking existing callers.

Copy link
Copy Markdown
Contributor

@giovannijunseokim giovannijunseokim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 💯

(ProfileKeywordGraph만 확인하면 될 것 같은데 맞을까요? 👀 )

Basic 만드는 것도 좋을 것 같습니다. 👍

@nahy-512 nahy-512 merged commit 1a380eb into develop Jan 14, 2026
3 checks passed
@nahy-512 nahy-512 deleted the feat/#83-profile-keyword-graph-component branch January 14, 2026 12:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🧩 Component feat - 공통 컴포넌트 작업 Feat ✨ 신규 기능을 추가하거나 기존 기능의 동작, 정책을 변경

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] 프로필 취향 키워드 그래프 컴포넌트 구현

2 participants