Skip to content

[Feat] PeopleBottomSheet 구현#72

Merged
giovannijunseokim merged 9 commits into
developfrom
feat/#57-collection-people-bottomsheet
Jan 13, 2026
Merged

[Feat] PeopleBottomSheet 구현#72
giovannijunseokim merged 9 commits into
developfrom
feat/#57-collection-people-bottomsheet

Conversation

@giovannijunseokim

@giovannijunseokim giovannijunseokim commented Jan 13, 2026

Copy link
Copy Markdown
Contributor

📮 관련 이슈

📌 작업 내용

  • PeopleBottomSheet를 구현했습니다.

📸 스크린샷

스크린샷 스크린샷
short.mp4
long.mp4

🫛 To. 리뷰어

  • 힘냅시다 ~!

Summary by CodeRabbit

  • 새로운 기능
    • 컬렉션을 저장한 사람들을 표시하는 바텀시트 추가
    • 상단에 동적 총계(저장자 수) 표시
    • 각 사용자의 프로필 이미지, 닉네임, 역할에 따른 자격 배지 노출
    • 목록에서 사용자를 선택해 관련 동작으로 이동 가능

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

@giovannijunseokim giovannijunseokim self-assigned this Jan 13, 2026
@giovannijunseokim giovannijunseokim requested a review from a team as a code owner January 13, 2026 16:10
@giovannijunseokim giovannijunseokim added 🧩 Component feat - 공통 컴포넌트 작업 Feat ✨ 신규 기능을 추가하거나 기존 기능의 동작, 정책을 변경 labels Jan 13, 2026
@coderabbitai

coderabbitai Bot commented Jan 13, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

새로운 Compose 파일 PeopleBottomSheet.kt을 추가해 컬렉션을 저장한 사용자 목록을 FlintBasicBottomSheet로 표시하는 공개 컴포저블 PeopleBottomSheet와 내부 Author UI, 프리뷰 및 샘플 데이터를 제공합니다.

Changes

Cohort / File(s) 변경 요약
PeopleBottomSheet 컴포저블 UI
app/src/main/java/com/flint/core/designsystem/component/collection/PeopleBottomSheet.kt
새 파일 추가: 공개 API PeopleBottomSheet(people: List<AuthorModel>, onAuthorClick: (Long) -> Unit, onDismiss: () -> Unit, modifier: Modifier = Modifier, sheetState: SheetState = rememberModalBottomSheetState(...)) 구현, 헤더(동적 카운트) + LazyColumn으로 Author 목록 렌더링, 내부 Author 컴포저블(프로필 이미지, 닉네임, FLINER 배지), ProfileImage 및 리소스 사용, PreviewProviders 및 sampleAuthors 샘플 데이터 포함 (+207 라인)

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested reviewers

  • nahy-512

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 제목이 변경 사항의 주요 내용을 명확하게 설명합니다. PeopleBottomSheet 구현이 이 PR의 핵심 변경 사항입니다.
Description check ✅ Passed PR 설명이 관련 이슈(#57), 작업 내용, 스크린샷을 포함하여 템플릿의 주요 섹션을 충족합니다.
Linked Issues check ✅ Passed PR은 이슈 #57의 요구사항을 충족합니다. PeopleBottomSheet 컴포넌트를 구현하여 컬렉션을 저장한 사람들을 나열하는 바텀시트를 제공합니다.
Out of Scope Changes check ✅ Passed 모든 변경 사항이 이슈 #57의 범위 내에 있습니다. PeopleBottomSheet 구현만 포함되며 범위를 벗어난 변경이 없습니다.

✏️ 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 67e55d3 and 4e0cf2e.

📒 Files selected for processing (1)
  • app/src/main/java/com/flint/core/designsystem/component/collection/PeopleBottomSheet.kt
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/src/main/java/com/flint/core/designsystem/component/collection/PeopleBottomSheet.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

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

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 0

🧹 Nitpick comments (1)
app/src/main/java/com/flint/core/designsystem/component/collection/PeopleBottomSheet.kt (1)

84-102: LazyColumn itemskey 파라미터 추가를 권장합니다.

items(people) 호출에 key 파라미터가 없으면, 리스트가 변경되거나 재정렬될 때 아이템 재사용이 올바르게 동작하지 않을 수 있습니다. AuthorModel의 고유 식별자를 key로 사용하면 Compose가 아이템을 효율적으로 추적할 수 있습니다.

♻️ 권장 수정
 LazyColumn(
     modifier = Modifier.fillMaxWidth(),
     verticalArrangement = Arrangement.spacedBy(4.dp),
 ) {
-    items(people) { author: AuthorModel ->
+    items(people, key = { it.userId }) { author: AuthorModel ->
         Author(
             author = author,
             onClick = onClickPeople,
             modifier =
                 Modifier
                     .fillMaxWidth()
                     .padding(horizontal = 32.dp),
         )
     }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bab7c14 and dbd98da.

📒 Files selected for processing (2)
  • app/src/main/java/com/flint/core/designsystem/component/collection/PeopleBottomSheet.kt
  • app/src/main/res/drawable/ic_qualified.xml
🧰 Additional context used
🧬 Code graph analysis (1)
app/src/main/java/com/flint/core/designsystem/component/collection/PeopleBottomSheet.kt (3)
app/src/main/java/com/flint/core/designsystem/component/bottomsheet/FlintBasicBottomSheet.kt (1)
  • FlintBasicBottomSheet (32-82)
app/src/main/java/com/flint/core/designsystem/component/image/ProfileImage.kt (1)
  • ProfileImage (11-29)
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 (4)
app/src/main/java/com/flint/core/designsystem/component/collection/PeopleBottomSheet.kt (4)

1-42: LGTM!

파일 레벨 @OptIn 어노테이션과 import 구성이 적절합니다.


107-142: LGTM!

Author composable이 잘 구현되어 있습니다. ProfileImage, 닉네임, 그리고 조건부 FLINER 배지 표시 로직이 적절합니다.


144-172: LGTM!

Preview composable들이 FlintTheme으로 적절히 래핑되어 있고, PreviewParameter를 활용하여 다양한 상태를 미리보기할 수 있도록 잘 구성되어 있습니다.


186-206: 샘플 데이터 다양성 개선을 고려해 주세요.

모든 샘플 AuthorModel이 동일한 userId = 0UserRoleType.FLINER를 사용하고 있습니다. Preview에서 다양한 케이스를 테스트하려면 고유한 userId와 다른 userRole 타입(ADMIN, FLING 등)을 포함하는 것이 좋습니다.

♻️ 권장 수정
 private val sampleAuthors: List<AuthorModel> =
     listOf(
         AuthorModel(
-            userId = 0,
+            userId = 1,
             nickname = "사용자 이름",
             profileUrl = "",
             userRole = UserRoleType.FLINER,
         ),
         AuthorModel(
-            userId = 0,
-            nickname = "사용자 이름",
+            userId = 2,
+            nickname = "관리자",
             profileUrl = "",
-            userRole = UserRoleType.FLINER,
+            userRole = UserRoleType.ADMIN,
         ),
         AuthorModel(
-            userId = 0,
+            userId = 3,
             nickname = "사용자 이름",
             profileUrl = "",
-            userRole = UserRoleType.FLINER,
+            userRole = UserRoleType.FLING,
         ),
     )

Likely an incorrect or invalid review comment.

@nahy-512 nahy-512 left a comment

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.

작업 고생하셨습니다~!
리뷰 확인 부탁드립니다

@Composable
fun PeopleBottomSheet(
people: List<AuthorModel>,
onClickPeople: (AuthorModel) -> Unit,

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.

p2
onPeopleClick로 통일해보면 어떨지!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

실제로는 People(사람들)을 클릭했을 때가 아니라 Author(한 명의 사용자)를 선택했을 때라,
onAuthorClick으로 변경했습니다! 👍

refactor: onClickPeople -> onAuthorClick 파라미터명 변경

@Composable
fun PeopleBottomSheet(
people: List<AuthorModel>,
onClickPeople: (AuthorModel) -> Unit,

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.

p2
AuthorModel를 넘기는 이유가 있나요?
프로필 조회로 넘어갈 거면 userId만 넘겨받아도 되지 않을까 싶어서요!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Spacer(Modifier.width(10.dp))

Image(
painter = painterResource(R.drawable.ic_qualified),

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.

p2
painterResource 대신 ImageVector로 받아보는 건 어떨까요?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Comment on lines +188 to +205
AuthorModel(
userId = 0,
nickname = "사용자 이름",
profileUrl = "",
userRole = UserRoleType.FLINER,
),
AuthorModel(
userId = 0,
nickname = "사용자 이름",
profileUrl = "",
userRole = UserRoleType.FLINER,
),
AuthorModel(
userId = 0,
nickname = "사용자 이름",
profileUrl = "",
userRole = UserRoleType.FLINER,
),

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.

p2
데이터 들어있는 게 다 똑같은데.. PreviewParameterProvider를 쓰고 있는 이유가 있을까요?

@giovannijunseokim giovannijunseokim Jan 13, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

  1. AuthorModeluserRoleADMIN, FLINER, FLING을 의도했는데 누락했네요. 이 부분 수정했습니다!
    refactor: Preview용 샘플 데이터 변경
  2. PreviewParameterProvider 내부적으로 리스트 크기를 늘려 스크롤이 잘 되는지 확인할 수 있는 프리뷰를 추가했습니다.


Image(
painter = painterResource(R.drawable.ic_qualified),
contentDescription = "플리너",

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.

p3
contentDescription를 쓰고있는 이유가 있나요?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

접근성을 위함입니다.

contentDescriptionnull로 주게되면 Screen Reader 사용자들은 플리너 인증 뱃지가 있는 사용자와 그렇지 않은 사용자를 구분할 수 없게 됩니다. 😢

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In
@app/src/main/java/com/flint/core/designsystem/component/collection/PeopleBottomSheet.kt:
- Around line 186-206: The sampleAuthors list uses the same userId (0) for every
AuthorModel which will cause key collisions in LazyColumn previews; update the
sampleAuthors entries so each AuthorModel has a unique userId (e.g., 1, 2, 3)
and ensure any LazyColumn key selector (where you reference author.userId) will
now produce unique keys, keeping AuthorModel, sampleAuthors and the userId
property consistent.
- Around line 84-97: The LazyColumn items call (items(people) { ... }) lacks a
stable key, which can cause inefficient recompositions and broken
scroll/animation behavior; update the items call in PeopleBottomSheet to pass a
key parameter (e.g., items(people, key = { it.id })) using a stable unique
property from AuthorModel (such as id) so Compose can track Author entries
correctly while still rendering Author(author = author, onClick = onAuthorClick,
modifier = ...).
🧹 Nitpick comments (2)
app/src/main/java/com/flint/core/designsystem/component/collection/PeopleBottomSheet.kt (2)

60-60: 매직 넘버 543.dp를 상수로 추출하는 것을 고려하세요.

하드코딩된 높이 값의 의미를 명확히 하고 재사용성을 높이기 위해 상수로 추출하면 좋습니다.

private val BottomSheetMaxHeight = 543.dp

56-103: 빈 리스트 상태 처리를 고려해 보세요.

people 리스트가 비어있을 때 현재는 헤더에 "0"만 표시됩니다. 빈 상태에 대한 안내 메시지를 추가하면 사용자 경험이 향상될 수 있습니다.

if (people.isEmpty()) {
    Text(
        text = "아직 저장한 사람이 없습니다",
        color = FlintTheme.colors.gray400,
        style = FlintTheme.typography.body2R14,
        modifier = Modifier.padding(vertical = 24.dp),
    )
} else {
    LazyColumn(/* ... */)
}
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dbd98da and 67e55d3.

📒 Files selected for processing (1)
  • app/src/main/java/com/flint/core/designsystem/component/collection/PeopleBottomSheet.kt
🧰 Additional context used
🧬 Code graph analysis (1)
app/src/main/java/com/flint/core/designsystem/component/collection/PeopleBottomSheet.kt (3)
app/src/main/java/com/flint/core/designsystem/component/bottomsheet/FlintBasicBottomSheet.kt (1)
  • FlintBasicBottomSheet (32-82)
app/src/main/java/com/flint/core/designsystem/component/image/ProfileImage.kt (1)
  • ProfileImage (11-29)
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 (3)
app/src/main/java/com/flint/core/designsystem/component/collection/PeopleBottomSheet.kt (3)

1-41: LGTM!

파일 레벨 @OptIn 어노테이션과 패키지 구조가 적절합니다. ExperimentalMaterial3ApiSheetState 사용에 필요하며, import 목록도 깔끔하게 정리되어 있습니다.


107-142: LGTM!

Author 컴포저블이 잘 구현되어 있습니다. Private 접근 제한자로 적절히 캡슐화되었고, UserRoleType.FLINER 조건부 배지 표시와 접근성을 위한 contentDescription도 적절합니다.


144-172: LGTM!

PreviewParameter를 활용한 프리뷰 구현이 좋습니다. 다양한 케이스를 미리 확인할 수 있어 개발 효율성이 높아집니다.

@giovannijunseokim giovannijunseokim merged commit f3d7d6a into develop Jan 13, 2026
3 checks passed
@giovannijunseokim giovannijunseokim deleted the feat/#57-collection-people-bottomsheet branch January 13, 2026 17:10
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